1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 * Code responsible for managing style changes: tracking what style
8 * changes need to happen, scheduling them, and doing them.
11 #ifndef mozilla_RestyleManager_h
12 #define mozilla_RestyleManager_h
14 #include "mozilla/RestyleLogging.h"
15 #include "nsISupportsImpl.h"
16 #include "nsChangeHint.h"
17 #include "RestyleTracker.h"
18 #include "nsPresContext.h"
19 #include "nsRefreshDriver.h"
20 #include "nsRefPtrHashtable.h"
21 #include "nsCSSPseudoElements.h"
24 class nsStyleChangeList
;
25 struct TreeMatchContext
;
29 struct UndisplayedNode
;
35 class RestyleManager MOZ_FINAL
38 friend class ::nsRefreshDriver
;
39 friend class RestyleTracker
;
41 typedef mozilla::dom::Element Element
;
43 explicit RestyleManager(nsPresContext
* aPresContext
);
46 // Private destructor, to discourage deletion outside of Release():
49 MOZ_ASSERT(!mReframingStyleContexts
,
50 "temporary member should be nulled out before destruction");
54 NS_INLINE_DECL_REFCOUNTING(mozilla::RestyleManager
)
57 mPresContext
= nullptr;
60 nsPresContext
* PresContext() const {
61 MOZ_ASSERT(mPresContext
);
65 nsCSSFrameConstructor
* FrameConstructor() const
66 { return PresContext()->FrameConstructor(); }
68 // Should be called when a frame is going to be destroyed and
69 // WillDestroyFrameTree hasn't been called yet.
70 void NotifyDestroyingFrame(nsIFrame
* aFrame
);
72 // Forwarded nsIDocumentObserver method, to handle restyling (and
73 // passing the notification to the frame).
74 nsresult
ContentStateChanged(nsIContent
* aContent
,
75 EventStates aStateMask
);
77 // Forwarded nsIMutationObserver method, to handle restyling.
78 void AttributeWillChange(Element
* aElement
,
82 // Forwarded nsIMutationObserver method, to handle restyling (and
83 // passing the notification to the frame).
84 void AttributeChanged(Element
* aElement
,
89 // Get an integer that increments every time there is a style change
90 // as a result of a change to the :hover content state.
91 uint32_t GetHoverGeneration() const { return mHoverGeneration
; }
93 // Get a counter that increments on every style change, that we use to
94 // track whether off-main-thread animations are up-to-date.
95 uint64_t GetAnimationGeneration() const { return mAnimationGeneration
; }
97 // A workaround until bug 847286 lands that gets the maximum of the animation
98 // generation counters stored on the set of animations and transitions
99 // respectively for |aFrame|.
100 static uint64_t GetMaxAnimationGenerationForFrame(nsIFrame
* aFrame
);
102 // Update the animation generation count to mark that animation state
105 // This is normally performed automatically by ProcessPendingRestyles
106 // but it is also called when we have out-of-band changes to animations
107 // such as changes made through the Web Animations API.
108 void IncrementAnimationGeneration() { ++mAnimationGeneration
; }
110 // Whether rule matching should skip styles associated with animation
111 bool SkipAnimationRules() const {
112 MOZ_ASSERT(mSkipAnimationRules
|| !mPostAnimationRestyles
,
113 "inconsistent state");
114 return mSkipAnimationRules
;
117 // Whether rule matching should post animation restyles when it skips
118 // styles associated with animation. Only true when
119 // SkipAnimationRules() is also true.
120 bool PostAnimationRestyles() const {
121 MOZ_ASSERT(mSkipAnimationRules
|| !mPostAnimationRestyles
,
122 "inconsistent state");
123 return mPostAnimationRestyles
;
126 // Whether we're currently in the animation phase of restyle
127 // processing (to be eliminated in bug 960465)
128 bool IsProcessingAnimationStyleChange() const {
129 return mIsProcessingAnimationStyleChange
;
133 * Reparent the style contexts of this frame subtree. The parent frame of
134 * aFrame must be changed to the new parent before this function is called;
135 * the new parent style context will be automatically computed based on the
136 * new position in the frame tree.
138 * @param aFrame the root of the subtree to reparent. Must not be null.
140 nsresult
ReparentStyleContext(nsIFrame
* aFrame
);
143 // Used when restyling an element with a frame.
144 void ComputeAndProcessStyleChange(nsIFrame
* aFrame
,
145 nsChangeHint aMinChange
,
146 RestyleTracker
& aRestyleTracker
,
147 nsRestyleHint aRestyleHint
);
148 // Used when restyling a display:contents element.
149 void ComputeAndProcessStyleChange(nsStyleContext
* aNewContext
,
151 nsChangeHint aMinChange
,
152 RestyleTracker
& aRestyleTracker
,
153 nsRestyleHint aRestyleHint
);
159 * DEBUG ONLY method to verify integrity of style tree versus frame tree
161 void DebugVerifyStyleTree(nsIFrame
* aFrame
);
164 // Note: It's the caller's responsibility to make sure to wrap a
165 // ProcessRestyledFrames call in a view update batch and a script blocker.
166 // This function does not call ProcessAttachedQueue() on the binding manager.
167 // If the caller wants that to happen synchronously, it needs to handle that
169 nsresult
ProcessRestyledFrames(nsStyleChangeList
& aRestyleArray
);
172 * In order to start CSS transitions on elements that are being
173 * reframed, we need to stash their style contexts somewhere during
174 * the reframing process.
176 * In all cases, the content node in the hash table is the real
177 * content node, not the anonymous content node we create for ::before
178 * or ::after. The content node passed to the Get and Put methods is,
179 * however, the content node to be associate with the frame's style
182 typedef nsRefPtrHashtable
<nsRefPtrHashKey
<nsIContent
>, nsStyleContext
>
183 ReframingStyleContextTable
;
184 class ReframingStyleContexts
{
186 void Put(nsIContent
* aContent
, nsStyleContext
* aStyleContext
) {
187 MOZ_ASSERT(aContent
);
188 nsCSSPseudoElements::Type pseudoType
= aStyleContext
->GetPseudoType();
189 if (pseudoType
== nsCSSPseudoElements::ePseudo_NotPseudoElement
) {
190 mElementContexts
.Put(aContent
, aStyleContext
);
191 } else if (pseudoType
== nsCSSPseudoElements::ePseudo_before
) {
192 MOZ_ASSERT(aContent
->Tag() == nsGkAtoms::mozgeneratedcontentbefore
);
193 mBeforePseudoContexts
.Put(aContent
->GetParent(), aStyleContext
);
194 } else if (pseudoType
== nsCSSPseudoElements::ePseudo_after
) {
195 MOZ_ASSERT(aContent
->Tag() == nsGkAtoms::mozgeneratedcontentafter
);
196 mAfterPseudoContexts
.Put(aContent
->GetParent(), aStyleContext
);
200 nsStyleContext
* Get(nsIContent
* aContent
,
201 nsCSSPseudoElements::Type aPseudoType
) {
202 MOZ_ASSERT(aContent
);
203 if (aPseudoType
== nsCSSPseudoElements::ePseudo_NotPseudoElement
) {
204 return mElementContexts
.GetWeak(aContent
);
206 if (aPseudoType
== nsCSSPseudoElements::ePseudo_before
) {
207 MOZ_ASSERT(aContent
->Tag() == nsGkAtoms::mozgeneratedcontentbefore
);
208 return mBeforePseudoContexts
.GetWeak(aContent
->GetParent());
210 if (aPseudoType
== nsCSSPseudoElements::ePseudo_after
) {
211 MOZ_ASSERT(aContent
->Tag() == nsGkAtoms::mozgeneratedcontentafter
);
212 return mAfterPseudoContexts
.GetWeak(aContent
->GetParent());
214 MOZ_ASSERT(false, "unexpected aPseudoType");
218 ReframingStyleContextTable mElementContexts
;
219 ReframingStyleContextTable mBeforePseudoContexts
;
220 ReframingStyleContextTable mAfterPseudoContexts
;
224 * Return the current ReframingStyleContexts struct, or null if we're
225 * not currently in a restyling operation.
227 ReframingStyleContexts
* GetReframingStyleContexts() {
228 return mReframingStyleContexts
;
232 * Try starting a transition for an element or a ::before or ::after
233 * pseudo-element, given an old and new style context. This may
234 * change the new style context if a transition is started.
236 * For the pseudo-elements, aContent must be the anonymous content
237 * that we're creating for that pseudo-element, not the real element.
240 TryStartingTransition(nsPresContext
* aPresContext
, nsIContent
* aContent
,
241 nsStyleContext
* aOldStyleContext
,
242 nsRefPtr
<nsStyleContext
>* aNewStyleContext
/* inout */);
245 void RestyleForEmptyChange(Element
* aContainer
);
248 // Restyling for a ContentInserted (notification after insertion) or
249 // for a CharacterDataChanged. |aContainer| must be non-null; when
250 // the container is null, no work is needed.
251 void RestyleForInsertOrChange(Element
* aContainer
, nsIContent
* aChild
);
253 // This would be the same as RestyleForInsertOrChange if we got the
254 // notification before the removal. However, we get it after, so we need the
255 // following sibling in addition to the old child. |aContainer| must be
256 // non-null; when the container is null, no work is needed. aFollowingSibling
257 // is the sibling that used to come after aOldChild before the removal.
258 void RestyleForRemove(Element
* aContainer
,
259 nsIContent
* aOldChild
,
260 nsIContent
* aFollowingSibling
);
262 // Same for a ContentAppended. |aContainer| must be non-null; when
263 // the container is null, no work is needed.
264 void RestyleForAppend(Element
* aContainer
, nsIContent
* aFirstNewContent
);
266 // Process any pending restyles. This should be called after
267 // CreateNeededFrames.
268 // Note: It's the caller's responsibility to make sure to wrap a
269 // ProcessPendingRestyles call in a view update batch and a script blocker.
270 // This function does not call ProcessAttachedQueue() on the binding manager.
271 // If the caller wants that to happen synchronously, it needs to handle that
273 void ProcessPendingRestyles();
275 // Returns whether there are any pending restyles.
276 bool HasPendingRestyles() { return mPendingRestyles
.Count() != 0; }
278 // ProcessPendingRestyles calls into one of our RestyleTracker
279 // objects. It then calls back to these functions at the beginning
280 // and end of its work.
281 void BeginProcessingRestyles();
282 void EndProcessingRestyles();
284 // Update styles for animations that are running on the compositor and
285 // whose updating is suppressed on the main thread (to save
286 // unnecessary work), while leaving all other aspects of style
289 // Performs an animation-only style flush to make styles from
290 // throttled transitions up-to-date prior to processing an unrelated
291 // style change, so that any transitions triggered by that style
292 // change produce correct results.
294 // In more detail: when we're able to run animations on the
295 // compositor, we sometimes "throttle" these animations by skipping
296 // updating style data on the main thread. However, whenever we
297 // process a normal (non-animation) style change, any changes in
298 // computed style on elements that have transition-* properties set
299 // may need to trigger new transitions; this process requires knowing
300 // both the old and new values of the property. To do this correctly,
301 // we need to have an up-to-date *old* value of the property on the
302 // primary frame. So the purpose of the mini-flush is to update the
303 // style for all throttled transitions and animations to the current
304 // animation state without making any other updates, so that when we
305 // process the queued style updates we'll have correct old data to
306 // compare against. When we do this, we don't bother touching frames
307 // other than primary frames.
308 void UpdateOnlyAnimationStyles();
310 bool ThrottledAnimationStyleIsUpToDate() const {
311 return mLastUpdateForThrottledAnimations
==
312 mPresContext
->RefreshDriver()->MostRecentRefresh();
315 // Rebuilds all style data by throwing out the old rule tree and
316 // building a new one, and additionally applying aExtraHint (which
317 // must not contain nsChangeHint_ReconstructFrame) to the root frame.
319 // aRestyleHint says which restyle hint to use for the computation;
320 // the only sensible values to use are eRestyle_Subtree (which says
321 // that the rebuild must run selector matching) and nsRestyleHint(0)
322 // (which says that rerunning selector matching is not required. (The
323 // method adds eRestyle_ForceDescendants internally, and including it
324 // in the restyle hint is harmless; some callers (e.g.,
325 // nsPresContext::MediaFeatureValuesChanged) might do this for their
327 void RebuildAllStyleData(nsChangeHint aExtraHint
,
328 nsRestyleHint aRestyleHint
);
330 // Helper that does part of the work of RebuildAllStyleData, shared by
331 // RestyleElement for 'rem' handling.
332 void DoRebuildAllStyleData(RestyleTracker
& aRestyleTracker
,
333 nsChangeHint aExtraHint
,
334 nsRestyleHint aRestyleHint
);
336 // See PostRestyleEventCommon below.
337 void PostRestyleEvent(Element
* aElement
,
338 nsRestyleHint aRestyleHint
,
339 nsChangeHint aMinChangeHint
)
342 PostRestyleEventCommon(aElement
, aRestyleHint
, aMinChangeHint
,
343 IsProcessingAnimationStyleChange());
347 // See PostRestyleEventCommon below.
348 void PostAnimationRestyleEvent(Element
* aElement
,
349 nsRestyleHint aRestyleHint
,
350 nsChangeHint aMinChangeHint
)
352 PostRestyleEventCommon(aElement
, aRestyleHint
, aMinChangeHint
, true);
355 void PostRestyleEventForLazyConstruction()
357 PostRestyleEventInternal(true);
360 void FlushOverflowChangedTracker()
362 mOverflowChangedTracker
.Flush();
366 static nsCString
RestyleHintToString(nsRestyleHint aHint
);
367 static nsCString
ChangeHintToString(nsChangeHint aHint
);
372 * Notify the frame constructor that an element needs to have its
374 * @param aElement: The element to be restyled.
375 * @param aRestyleHint: Which nodes need to have selector matching run
377 * @param aMinChangeHint: A minimum change hint for aContent and its
379 * @param aForAnimation: Whether the style should be computed with or
380 * without animation data. Animation code
381 * sometimes needs to pass true; other code
382 * should generally pass the the pres context's
383 * IsProcessingAnimationStyleChange() value
384 * (which is the default value).
386 void PostRestyleEventCommon(Element
* aElement
,
387 nsRestyleHint aRestyleHint
,
388 nsChangeHint aMinChangeHint
,
390 void PostRestyleEventInternal(bool aForLazyConstruction
);
394 * Asynchronously clear style data from the root frame downwards and ensure
395 * it will all be rebuilt. This is safe to call anytime; it will schedule
396 * a restyle and take effect next time style changes are flushed.
397 * This method is used to recompute the style data when some change happens
398 * outside of any style rules, like a color preference change or a change
399 * in a system font size, or to fix things up when an optimization in the
400 * style data has become invalid. We assume that the root frame will not
401 * need to be reframed.
403 * For parameters, see RebuildAllStyleData.
405 void PostRebuildAllStyleDataEvent(nsChangeHint aExtraHint
,
406 nsRestyleHint aRestyleHint
);
408 #ifdef RESTYLE_LOGGING
410 * Returns whether a restyle event currently being processed by this
411 * RestyleManager should be logged.
413 bool ShouldLogRestyle() {
414 return ShouldLogRestyle(mPresContext
);
418 * Returns whether a restyle event currently being processed for the
419 * document with the specified nsPresContext should be logged.
421 static bool ShouldLogRestyle(nsPresContext
* aPresContext
) {
422 return aPresContext
->RestyleLoggingEnabled() &&
423 (!aPresContext
->RestyleManager()->
424 IsProcessingAnimationStyleChange() ||
425 AnimationRestyleLoggingEnabled());
428 static bool RestyleLoggingInitiallyEnabled() {
429 static bool enabled
= getenv("MOZ_DEBUG_RESTYLE") != 0;
433 static bool AnimationRestyleLoggingEnabled() {
434 static bool animations
= getenv("MOZ_DEBUG_RESTYLE_ANIMATIONS") != 0;
438 // Set MOZ_DEBUG_RESTYLE_STRUCTS to a comma-separated string of
439 // style struct names -- such as "Font,SVGReset" -- to log the style context
440 // tree and those cached struct pointers before each restyle. This
441 // function returns a bitfield of the structs named in the
442 // environment variable.
443 static uint32_t StructsToLog();
445 static nsCString
StructNamesToString(uint32_t aSIDs
);
446 int32_t& LoggingDepth() { return mLoggingDepth
; }
450 /* aMinHint is the minimal change that should be made to the element */
451 // XXXbz do we really need the aPrimaryFrame argument here?
452 void RestyleElement(Element
* aElement
,
453 nsIFrame
* aPrimaryFrame
,
454 nsChangeHint aMinHint
,
455 RestyleTracker
& aRestyleTracker
,
456 nsRestyleHint aRestyleHint
);
458 void StyleChangeReflow(nsIFrame
* aFrame
, nsChangeHint aHint
);
460 // Recursively add all the given frame and all children to the tracker.
461 void AddSubtreeToOverflowTracker(nsIFrame
* aFrame
);
463 // Returns true if this function managed to successfully move a frame, and
464 // false if it could not process the position change, and a reflow should
465 // be performed instead.
466 bool RecomputePosition(nsIFrame
* aFrame
);
469 nsPresContext
* mPresContext
; // weak, disconnected in Disconnect
471 bool mRebuildAllStyleData
: 1;
472 // True if we're already waiting for a refresh notification
473 bool mObservingRefreshDriver
: 1;
474 // True if we're in the middle of a nsRefreshDriver refresh
475 bool mInStyleRefresh
: 1;
476 // Whether rule matching should skip styles associated with animation
477 bool mSkipAnimationRules
: 1;
478 // Whether rule matching should post animation restyles when it skips
479 // styles associated with animation. Only true when
480 // mSkipAnimationRules is also true.
481 bool mPostAnimationRestyles
: 1;
482 // Whether we're currently in the animation phase of restyle
483 // processing (to be eliminated in bug 960465)
484 bool mIsProcessingAnimationStyleChange
: 1;
486 uint32_t mHoverGeneration
;
487 nsChangeHint mRebuildAllExtraHint
;
488 nsRestyleHint mRebuildAllRestyleHint
;
490 mozilla::TimeStamp mLastUpdateForThrottledAnimations
;
492 OverflowChangedTracker mOverflowChangedTracker
;
494 // The total number of animation flushes by this frame constructor.
495 // Used to keep the layer and animation manager in sync.
496 uint64_t mAnimationGeneration
;
498 ReframingStyleContexts
* mReframingStyleContexts
;
500 RestyleTracker mPendingRestyles
;
501 RestyleTracker mPendingAnimationRestyles
;
504 bool mIsProcessingRestyles
;
507 #ifdef RESTYLE_LOGGING
508 int32_t mLoggingDepth
;
513 * An ElementRestyler is created for *each* element in a subtree that we
514 * recompute styles for.
516 class ElementRestyler MOZ_FINAL
519 typedef mozilla::dom::Element Element
;
521 // Construct for the root of the subtree that we're restyling.
522 ElementRestyler(nsPresContext
* aPresContext
,
524 nsStyleChangeList
* aChangeList
,
525 nsChangeHint aHintsHandledByAncestors
,
526 RestyleTracker
& aRestyleTracker
,
527 TreeMatchContext
& aTreeMatchContext
,
528 nsTArray
<nsIContent
*>& aVisibleKidsOfHiddenElement
);
530 // Construct for an element whose parent is being restyled.
531 enum ConstructorFlags
{
532 FOR_OUT_OF_FLOW_CHILD
= 1<<0
534 ElementRestyler(const ElementRestyler
& aParentRestyler
,
536 uint32_t aConstructorFlags
);
538 // Construct for a frame whose parent is being restyled, but whose
539 // style context is the parent style context for its parent frame.
540 // (This is only used for table frames, whose style contexts are used
541 // as the parent style context for their outer table frame (table
542 // wrapper frame). We should probably try to get rid of this
543 // exception and have the inheritance go the other way.)
544 enum ParentContextFromChildFrame
{ PARENT_CONTEXT_FROM_CHILD_FRAME
};
545 ElementRestyler(ParentContextFromChildFrame
,
546 const ElementRestyler
& aParentFrameRestyler
,
549 // For restyling undisplayed content only (mFrame==null).
550 ElementRestyler(nsPresContext
* aPresContext
,
551 nsIContent
* aContent
,
552 nsStyleChangeList
* aChangeList
,
553 nsChangeHint aHintsHandledByAncestors
,
554 RestyleTracker
& aRestyleTracker
,
555 TreeMatchContext
& aTreeMatchContext
,
556 nsTArray
<nsIContent
*>& aVisibleKidsOfHiddenElement
);
559 * Restyle our frame's element and its subtree.
561 * Use eRestyle_Self for the aRestyleHint argument to mean
562 * "reresolve our style context but not kids", use eRestyle_Subtree
563 * to mean "reresolve our style context and kids", and use
564 * nsRestyleHint(0) to mean recompute a new style context for our
565 * current parent and existing rulenode, and the same for kids.
567 void Restyle(nsRestyleHint aRestyleHint
);
570 * mHintsHandled changes over time; it starts off as the hints that
571 * have been handled by ancestors, and by the end of Restyle it
572 * represents the hints that have been handled for this frame. This
573 * method is intended to be called after Restyle, to find out what
574 * hints have been handled for this frame.
576 nsChangeHint
HintsHandledForFrame() { return mHintsHandled
; }
579 * Called from RestyleManager::ComputeAndProcessStyleChange to restyle
580 * children of a display:contents element.
582 void RestyleChildrenOfDisplayContentsElement(nsIFrame
* aParentFrame
,
583 nsStyleContext
* aNewContext
,
584 nsChangeHint aMinHint
,
585 RestyleTracker
& aRestyleTracker
,
586 nsRestyleHint aRestyleHint
);
589 * Re-resolve the style contexts for a frame tree, building aChangeList
590 * based on the resulting style changes, plus aMinChange applied to aFrame.
592 static void ComputeStyleChangeFor(nsIFrame
* aFrame
,
593 nsStyleChangeList
* aChangeList
,
594 nsChangeHint aMinChange
,
595 RestyleTracker
& aRestyleTracker
,
596 nsRestyleHint aRestyleHint
);
598 #ifdef RESTYLE_LOGGING
599 bool ShouldLogRestyle() {
600 return RestyleManager::ShouldLogRestyle(mPresContext
);
605 // Enum for the result of RestyleSelf, which indicates whether the
606 // restyle procedure should continue to the children, and how.
608 // These values must be ordered so that later values imply that all
609 // the work of the earlier values is also done.
612 // do not restyle children
613 eRestyleResult_Stop
= 1,
615 // continue restyling children
616 eRestyleResult_Continue
,
618 // continue restyling children with eRestyle_ForceDescendants set
619 eRestyleResult_ContinueAndForceDescendants
623 * First half of Restyle().
625 RestyleResult
RestyleSelf(nsIFrame
* aSelf
,
626 nsRestyleHint aRestyleHint
,
627 uint32_t* aSwappedStructs
);
630 * Restyle the children of this frame (and, in turn, their children).
632 * Second half of Restyle().
634 void RestyleChildren(nsRestyleHint aChildRestyleHint
);
637 * Helpers for Restyle().
639 void AddLayerChangesForAnimation();
642 * Helpers for RestyleSelf().
644 void CaptureChange(nsStyleContext
* aOldContext
,
645 nsStyleContext
* aNewContext
,
646 nsChangeHint aChangeToAssume
,
647 uint32_t* aEqualStructs
);
648 RestyleResult
ComputeRestyleResultFromFrame(nsIFrame
* aSelf
);
649 RestyleResult
ComputeRestyleResultFromNewContext(nsIFrame
* aSelf
,
650 nsStyleContext
* aNewContext
);
653 * Helpers for RestyleChildren().
655 void RestyleUndisplayedDescendants(nsRestyleHint aChildRestyleHint
);
657 * In the following two methods, aParentStyleContext is either
658 * mFrame->StyleContext() if we have a frame, or a display:contents
659 * style context if we don't.
661 void DoRestyleUndisplayedDescendants(nsRestyleHint aChildRestyleHint
,
663 nsStyleContext
* aParentStyleContext
);
664 void RestyleUndisplayedNodes(nsRestyleHint aChildRestyleHint
,
665 UndisplayedNode
* aUndisplayed
,
666 nsIContent
* aUndisplayedParent
,
667 nsStyleContext
* aParentStyleContext
,
668 const uint8_t aDisplay
);
669 void MaybeReframeForBeforePseudo();
670 void MaybeReframeForBeforePseudo(nsIFrame
* aGenConParentFrame
,
672 nsIContent
* aContent
,
673 nsStyleContext
* aStyleContext
);
674 void MaybeReframeForAfterPseudo(nsIFrame
* aFrame
);
675 void MaybeReframeForAfterPseudo(nsIFrame
* aGenConParentFrame
,
677 nsIContent
* aContent
,
678 nsStyleContext
* aStyleContext
);
679 void RestyleContentChildren(nsIFrame
* aParent
,
680 nsRestyleHint aChildRestyleHint
);
681 void InitializeAccessibilityNotifications(nsStyleContext
* aNewContext
);
682 void SendAccessibilityNotifications();
684 enum DesiredA11yNotifications
{
686 eSendAllNotifications
,
690 enum A11yNotificationType
{
696 #ifdef RESTYLE_LOGGING
697 int32_t& LoggingDepth() { return mLoggingDepth
; }
701 static nsCString
RestyleResultToString(RestyleResult aRestyleResult
);
705 nsPresContext
* const mPresContext
;
706 nsIFrame
* const mFrame
;
707 nsIContent
* const mParentContent
;
708 // |mContent| is the node that we used for rule matching of
709 // normal elements (not pseudo-elements) and for which we generate
710 // framechange hints if we need them.
711 nsIContent
* const mContent
;
712 nsStyleChangeList
* const mChangeList
;
713 // We have already generated change list entries for hints listed in
714 // mHintsHandled (initially it's those handled by ancestors, but by
715 // the end of Restyle it is those handled for this frame as well). We
716 // need to generate a new change list entry for the frame when its
717 // style comparision returns a hint other than one of these hints.
718 nsChangeHint mHintsHandled
;
719 // See nsStyleContext::CalcStyleDifference
720 nsChangeHint mParentFrameHintsNotHandledForDescendants
;
721 nsChangeHint mHintsNotHandledForDescendants
;
722 RestyleTracker
& mRestyleTracker
;
723 TreeMatchContext
& mTreeMatchContext
;
724 nsIFrame
* mResolvedChild
; // child that provides our parent style context
727 const DesiredA11yNotifications mDesiredA11yNotifications
;
728 DesiredA11yNotifications mKidsDesiredA11yNotifications
;
729 A11yNotificationType mOurA11yNotification
;
730 nsTArray
<nsIContent
*>& mVisibleKidsOfHiddenElement
;
731 bool mWasFrameVisible
;
734 #ifdef RESTYLE_LOGGING
735 int32_t mLoggingDepth
;
740 * This pushes any display:contents nodes onto a TreeMatchContext.
741 * Use it before resolving style for kids of aParent where aParent
742 * (and further ancestors) may be display:contents nodes which have
743 * not yet been pushed onto TreeMatchContext.
745 class MOZ_STACK_CLASS AutoDisplayContentsAncestorPusher MOZ_FINAL
748 typedef mozilla::dom::Element Element
;
749 AutoDisplayContentsAncestorPusher(TreeMatchContext
& aTreeMatchContext
,
750 nsPresContext
* aPresContext
,
751 nsIContent
* aParent
);
752 ~AutoDisplayContentsAncestorPusher();
753 bool IsEmpty() const { return mAncestors
.Length() == 0; }
755 TreeMatchContext
& mTreeMatchContext
;
756 nsPresContext
* const mPresContext
;
757 nsAutoTArray
<mozilla::dom::Element
*, 4> mAncestors
;
760 } // namespace mozilla
762 #endif /* mozilla_RestyleManager_h */