Bug 1104435 part 2 - Make AnimationPlayer derive from nsISupports; r=smaug
[gecko.git] / layout / base / RestyleManager.h
blob3627d59849f2a0d4ff7d4facc62bdc83b639beeb
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/. */
6 /**
7 * Code responsible for managing style changes: tracking what style
8 * changes need to happen, scheduling them, and doing them.
9 */
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"
23 class nsIFrame;
24 class nsStyleChangeList;
25 struct TreeMatchContext;
27 namespace mozilla {
28 class EventStates;
29 struct UndisplayedNode;
31 namespace dom {
32 class Element;
33 } // namespace dom
35 class RestyleManager MOZ_FINAL
37 public:
38 friend class ::nsRefreshDriver;
39 friend class RestyleTracker;
41 typedef mozilla::dom::Element Element;
43 explicit RestyleManager(nsPresContext* aPresContext);
45 private:
46 // Private destructor, to discourage deletion outside of Release():
47 ~RestyleManager()
49 MOZ_ASSERT(!mReframingStyleContexts,
50 "temporary member should be nulled out before destruction");
53 public:
54 NS_INLINE_DECL_REFCOUNTING(mozilla::RestyleManager)
56 void Disconnect() {
57 mPresContext = nullptr;
60 nsPresContext* PresContext() const {
61 MOZ_ASSERT(mPresContext);
62 return 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,
79 int32_t aNameSpaceID,
80 nsIAtom* aAttribute,
81 int32_t aModType);
82 // Forwarded nsIMutationObserver method, to handle restyling (and
83 // passing the notification to the frame).
84 void AttributeChanged(Element* aElement,
85 int32_t aNameSpaceID,
86 nsIAtom* aAttribute,
87 int32_t aModType);
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
103 // has changed.
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);
142 private:
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,
150 Element* aElement,
151 nsChangeHint aMinChange,
152 RestyleTracker& aRestyleTracker,
153 nsRestyleHint aRestyleHint);
155 public:
157 #ifdef DEBUG
159 * DEBUG ONLY method to verify integrity of style tree versus frame tree
161 void DebugVerifyStyleTree(nsIFrame* aFrame);
162 #endif
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
168 // itself.
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
180 * context.
182 typedef nsRefPtrHashtable<nsRefPtrHashKey<nsIContent>, nsStyleContext>
183 ReframingStyleContextTable;
184 class ReframingStyleContexts {
185 public:
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");
215 return nullptr;
217 private:
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.
239 static void
240 TryStartingTransition(nsPresContext* aPresContext, nsIContent* aContent,
241 nsStyleContext* aOldStyleContext,
242 nsRefPtr<nsStyleContext>* aNewStyleContext /* inout */);
244 private:
245 void RestyleForEmptyChange(Element* aContainer);
247 public:
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
272 // itself.
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
287 // out-of-date.
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
326 // own reasons.)
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)
341 if (mPresContext) {
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();
365 #ifdef DEBUG
366 static nsCString RestyleHintToString(nsRestyleHint aHint);
367 static nsCString ChangeHintToString(nsChangeHint aHint);
368 #endif
370 private:
372 * Notify the frame constructor that an element needs to have its
373 * style recomputed.
374 * @param aElement: The element to be restyled.
375 * @param aRestyleHint: Which nodes need to have selector matching run
376 * on them.
377 * @param aMinChangeHint: A minimum change hint for aContent and its
378 * descendants.
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,
389 bool aForAnimation);
390 void PostRestyleEventInternal(bool aForLazyConstruction);
392 public:
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;
430 return enabled;
433 static bool AnimationRestyleLoggingEnabled() {
434 static bool animations = getenv("MOZ_DEBUG_RESTYLE_ANIMATIONS") != 0;
435 return animations;
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; }
447 #endif
449 private:
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);
468 private:
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;
503 #ifdef DEBUG
504 bool mIsProcessingRestyles;
505 #endif
507 #ifdef RESTYLE_LOGGING
508 int32_t mLoggingDepth;
509 #endif
513 * An ElementRestyler is created for *each* element in a subtree that we
514 * recompute styles for.
516 class ElementRestyler MOZ_FINAL
518 public:
519 typedef mozilla::dom::Element Element;
521 // Construct for the root of the subtree that we're restyling.
522 ElementRestyler(nsPresContext* aPresContext,
523 nsIFrame* aFrame,
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,
535 nsIFrame* aFrame,
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,
547 nsIFrame* aFrame);
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);
602 #endif
604 private:
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.
610 enum RestyleResult {
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,
662 nsIContent* aParent,
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,
671 nsIFrame* aFrame,
672 nsIContent* aContent,
673 nsStyleContext* aStyleContext);
674 void MaybeReframeForAfterPseudo(nsIFrame* aFrame);
675 void MaybeReframeForAfterPseudo(nsIFrame* aGenConParentFrame,
676 nsIFrame* aFrame,
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 {
685 eSkipNotifications,
686 eSendAllNotifications,
687 eNotifyIfShown
690 enum A11yNotificationType {
691 eDontNotify,
692 eNotifyShown,
693 eNotifyHidden
696 #ifdef RESTYLE_LOGGING
697 int32_t& LoggingDepth() { return mLoggingDepth; }
698 #endif
700 #ifdef DEBUG
701 static nsCString RestyleResultToString(RestyleResult aRestyleResult);
702 #endif
704 private:
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
726 #ifdef ACCESSIBILITY
727 const DesiredA11yNotifications mDesiredA11yNotifications;
728 DesiredA11yNotifications mKidsDesiredA11yNotifications;
729 A11yNotificationType mOurA11yNotification;
730 nsTArray<nsIContent*>& mVisibleKidsOfHiddenElement;
731 bool mWasFrameVisible;
732 #endif
734 #ifdef RESTYLE_LOGGING
735 int32_t mLoggingDepth;
736 #endif
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
747 public:
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; }
754 private:
755 TreeMatchContext& mTreeMatchContext;
756 nsPresContext* const mPresContext;
757 nsAutoTArray<mozilla::dom::Element*, 4> mAncestors;
760 } // namespace mozilla
762 #endif /* mozilla_RestyleManager_h */