LCOV - code coverage report
Current view: top level - layout/base - nsChangeHint.h (source / functions) Hit Total Coverage
Test: output.info Lines: 45 45 100.0 %
Date: 2017-07-14 16:53:18 Functions: 18 18 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       5             : 
       6             : /* constants for what needs to be recomputed in response to style changes */
       7             : 
       8             : #ifndef nsChangeHint_h___
       9             : #define nsChangeHint_h___
      10             : 
      11             : #include "mozilla/Types.h"
      12             : #include "nsDebug.h"
      13             : #include "nsTArray.h"
      14             : 
      15             : struct nsCSSSelector;
      16             : 
      17             : // Defines for various style related constants
      18             : 
      19             : enum nsChangeHint : uint32_t {
      20             :   nsChangeHint_Empty = 0,
      21             : 
      22             :   // change was visual only (e.g., COLOR=)
      23             :   // Invalidates all descendant frames (including following
      24             :   // placeholders to out-of-flow frames).
      25             :   nsChangeHint_RepaintFrame = 1 << 0,
      26             : 
      27             :   // For reflow, we want flags to give us arbitrary FrameNeedsReflow behavior.
      28             :   // just do a FrameNeedsReflow.
      29             :   nsChangeHint_NeedReflow = 1 << 1,
      30             : 
      31             :   // Invalidate intrinsic widths on the frame's ancestors.  Must not be set
      32             :   // without setting nsChangeHint_NeedReflow.
      33             :   nsChangeHint_ClearAncestorIntrinsics = 1 << 2,
      34             : 
      35             :   // Invalidate intrinsic widths on the frame's descendants.  Must not be set
      36             :   // without also setting nsChangeHint_ClearAncestorIntrinsics,
      37             :   // nsChangeHint_NeedDirtyReflow and nsChangeHint_NeedReflow.
      38             :   nsChangeHint_ClearDescendantIntrinsics = 1 << 3,
      39             : 
      40             :   // Force unconditional reflow of all descendants.  Must not be set without
      41             :   // setting nsChangeHint_NeedReflow, but can be set regardless of whether the
      42             :   // Clear*Intrinsics flags are set.
      43             :   nsChangeHint_NeedDirtyReflow = 1 << 4,
      44             : 
      45             :   // change requires view to be updated, if there is one (e.g., clip:).
      46             :   // Updates all descendants (including following placeholders to out-of-flows).
      47             :   nsChangeHint_SyncFrameView = 1 << 5,
      48             : 
      49             :   // The currently shown mouse cursor needs to be updated
      50             :   nsChangeHint_UpdateCursor = 1 << 6,
      51             : 
      52             :   /**
      53             :    * Used when the computed value (a URI) of one or more of an element's
      54             :    * filter/mask/clip/etc CSS properties changes, causing the element's frame
      55             :    * to start/stop referencing (or reference different) SVG resource elements.
      56             :    * (_Not_ used to handle changes to referenced resource elements.) Using this
      57             :    * hint results in nsSVGEffects::UpdateEffects being called on the element's
      58             :    * frame.
      59             :    */
      60             :   nsChangeHint_UpdateEffects = 1 << 7,
      61             : 
      62             :   /**
      63             :    * Visual change only, but the change can be handled entirely by
      64             :    * updating the layer(s) for the frame.
      65             :    * Updates all descendants (including following placeholders to out-of-flows).
      66             :    */
      67             :   nsChangeHint_UpdateOpacityLayer = 1 << 8,
      68             :   /**
      69             :    * Updates all descendants. Any placeholder descendants' out-of-flows
      70             :    * are also descendants of the transformed frame, so they're updated.
      71             :    */
      72             :   nsChangeHint_UpdateTransformLayer = 1 << 9,
      73             : 
      74             :   /**
      75             :    * Change requires frame change (e.g., display:).
      76             :    * Reconstructs all frame descendants, including following placeholders
      77             :    * to out-of-flows.
      78             :    *
      79             :    * Note that this subsumes all the other change hints. (see
      80             :    * RestyleManager::ProcessRestyledFrames for details).
      81             :    */
      82             :   nsChangeHint_ReconstructFrame = 1 << 10,
      83             : 
      84             :   /**
      85             :    * The frame's overflow area has changed. Does not update any descendant
      86             :    * frames.
      87             :    */
      88             :   nsChangeHint_UpdateOverflow = 1 << 11,
      89             : 
      90             :   /**
      91             :    * The overflow area of the frame and all of its descendants has changed. This
      92             :    * can happen through a text-decoration change.
      93             :    */
      94             :   nsChangeHint_UpdateSubtreeOverflow = 1 << 12,
      95             : 
      96             :   /**
      97             :    * The frame's overflow area has changed, through a change in its transform.
      98             :    * In other words, the frame's pre-transform overflow is unchanged, but
      99             :    * its post-transform overflow has changed, and thus its effect on its
     100             :    * parent's overflow has changed.  If the pre-transform overflow has
     101             :    * changed, see nsChangeHint_UpdateOverflow.
     102             :    * Does not update any descendant frames.
     103             :    */
     104             :   nsChangeHint_UpdatePostTransformOverflow = 1 << 13,
     105             : 
     106             :   /**
     107             :    * This frame's effect on its parent's overflow area has changed.
     108             :    * (But neither its pre-transform nor post-transform overflow have
     109             :    * changed; if those are the case, see
     110             :    * nsChangeHint_UpdatePostTransformOverflow.)
     111             :    */
     112             :   nsChangeHint_UpdateParentOverflow = 1 << 14,
     113             : 
     114             :   /**
     115             :    * The children-only transform of an SVG frame changed, requiring the
     116             :    * overflow rects of the frame's immediate children to be updated.
     117             :    */
     118             :   nsChangeHint_ChildrenOnlyTransform = 1 << 15,
     119             : 
     120             :   /**
     121             :    * The frame's offsets have changed, while its dimensions might have
     122             :    * changed as well.  This hint is used for positioned frames if their
     123             :    * offset changes.  If we decide that the dimensions are likely to
     124             :    * change, this will trigger a reflow.
     125             :    *
     126             :    * Note that this should probably be used in combination with
     127             :    * nsChangeHint_UpdateOverflow in order to get the overflow areas of
     128             :    * the ancestors updated as well.
     129             :    */
     130             :   nsChangeHint_RecomputePosition = 1 << 16,
     131             : 
     132             :   /**
     133             :    * Behaves like ReconstructFrame, but only if the frame has descendants
     134             :    * that are absolutely or fixed position. Use this hint when a style change
     135             :    * has changed whether the frame is a container for fixed-pos or abs-pos
     136             :    * elements, but reframing is otherwise not needed.
     137             :    *
     138             :    * Note that nsStyleContext::CalcStyleDifference adjusts results
     139             :    * returned by style struct CalcDifference methods to return this hint
     140             :    * only if there was a change to whether the element's overall style
     141             :    * indicates that it establishes a containing block.
     142             :    */
     143             :   nsChangeHint_UpdateContainingBlock = 1 << 17,
     144             : 
     145             :   /**
     146             :    * This change hint has *no* change handling behavior.  However, it
     147             :    * exists to be a non-inherited hint, because when the border-style
     148             :    * changes, and it's inherited by a child, that might require a reflow
     149             :    * due to the border-width change on the child.
     150             :    */
     151             :   nsChangeHint_BorderStyleNoneChange = 1 << 18,
     152             : 
     153             :   /**
     154             :    * SVG textPath needs to be recomputed because the path has changed.
     155             :    * This means that the glyph positions of the text need to be recomputed.
     156             :    */
     157             :   nsChangeHint_UpdateTextPath = 1 << 19,
     158             : 
     159             :   /**
     160             :    * This will schedule an invalidating paint. This is useful if something
     161             :    * has changed which will be invalidated by DLBI.
     162             :    */
     163             :   nsChangeHint_SchedulePaint = 1 << 20,
     164             : 
     165             :   /**
     166             :    * A hint reflecting that style data changed with no change handling
     167             :    * behavior.  We need to return this, rather than nsChangeHint(0),
     168             :    * so that certain optimizations that manipulate the style context tree are
     169             :    * correct.
     170             :    *
     171             :    * nsChangeHint_NeutralChange must be returned by CalcDifference on a given
     172             :    * style struct if the data in the style structs are meaningfully different
     173             :    * and if no other change hints are returned.  If any other change hints are
     174             :    * set, then nsChangeHint_NeutralChange need not also be included, but it is
     175             :    * safe to do so.  (An example of style structs having non-meaningfully
     176             :    * different data would be cached information that would be re-calculated
     177             :    * to the same values, such as nsStyleBorder::mSubImages.)
     178             :    */
     179             :   nsChangeHint_NeutralChange = 1 << 21,
     180             : 
     181             :   /**
     182             :    * This will cause rendering observers to be invalidated.
     183             :    */
     184             :   nsChangeHint_InvalidateRenderingObservers = 1 << 22,
     185             : 
     186             :   /**
     187             :    * Indicates that the reflow changes the size or position of the
     188             :    * element, and thus the reflow must start from at least the frame's
     189             :    * parent.  Must be not be set without also setting nsChangeHint_NeedReflow
     190             :    * and nsChangeHint_ClearAncestorIntrinsics.
     191             :    */
     192             :   nsChangeHint_ReflowChangesSizeOrPosition = 1 << 23,
     193             : 
     194             :   /**
     195             :    * Indicates that the style changes the computed BSize --- e.g. 'height'.
     196             :    * Must not be set without also setting nsChangeHint_NeedReflow.
     197             :    */
     198             :   nsChangeHint_UpdateComputedBSize = 1 << 24,
     199             : 
     200             :   /**
     201             :    * Indicates that the 'opacity' property changed between 1 and non-1.
     202             :    *
     203             :    * Used as extra data for handling UpdateOpacityLayer hints.
     204             :    *
     205             :    * Note that we do not send this hint if the non-1 value was 0.99 or
     206             :    * greater, since in that case we send a RepaintFrame hint instead.
     207             :    */
     208             :   nsChangeHint_UpdateUsesOpacity = 1 << 25,
     209             : 
     210             :   /**
     211             :    * Indicates that the 'background-position' property changed.
     212             :    * Regular frames can invalidate these changes using DLBI, but
     213             :    * for some frame types we need to repaint the whole frame because
     214             :    * the frame does not build individual background image display items
     215             :    * for each background layer.
     216             :    */
     217             :   nsChangeHint_UpdateBackgroundPosition = 1 << 26,
     218             : 
     219             :   /**
     220             :    * Indicates that a frame has changed to or from having the CSS
     221             :    * transform property set.
     222             :    */
     223             :   nsChangeHint_AddOrRemoveTransform = 1 << 27,
     224             : 
     225             :   /**
     226             :    * Indicates that the overflow-x and/or overflow-y property changed.
     227             :    *
     228             :    * In most cases, this is equivalent to nsChangeHint_ReconstructFrame. But
     229             :    * in some special cases where the change is really targeting the viewport's
     230             :    * scrollframe, this is instead equivalent to nsChangeHint_AllReflowHints
     231             :    * (because the viewport always has an associated scrollframe).
     232             :    */
     233             :   nsChangeHint_CSSOverflowChange = 1 << 28,
     234             : 
     235             :   /**
     236             :    * Indicates that nsIFrame::UpdateWidgetProperties needs to be called.
     237             :    * This is used for -moz-window-* properties.
     238             :    */
     239             :   nsChangeHint_UpdateWidgetProperties = 1 << 29,
     240             : 
     241             :   // IMPORTANT NOTE: When adding a new hint, you will need to add it to
     242             :   // one of:
     243             :   //
     244             :   //   * nsChangeHint_Hints_NeverHandledForDescendants
     245             :   //   * nsChangeHint_Hints_AlwaysHandledForDescendants
     246             :   //   * nsChangeHint_Hints_SometimesHandledForDescendants
     247             :   //
     248             :   // and you also may need to handle it in NS_HintsNotHandledForDescendantsIn.
     249             :   //
     250             :   // Please also add it to RestyleManager::ChangeHintToString and
     251             :   // modify nsChangeHint_AllHints below accordingly.
     252             : 
     253             :   /**
     254             :    * Dummy hint value for all hints. It exists for compile time check.
     255             :    */
     256             :   nsChangeHint_AllHints = (1 << 30) - 1,
     257             : };
     258             : 
     259             : // Redefine these operators to return nothing. This will catch any use
     260             : // of these operators on hints. We should not be using these operators
     261             : // on nsChangeHints
     262             : inline void operator<(nsChangeHint s1, nsChangeHint s2) {}
     263             : inline void operator>(nsChangeHint s1, nsChangeHint s2) {}
     264             : inline void operator!=(nsChangeHint s1, nsChangeHint s2) {}
     265             : inline void operator==(nsChangeHint s1, nsChangeHint s2) {}
     266             : inline void operator<=(nsChangeHint s1, nsChangeHint s2) {}
     267             : inline void operator>=(nsChangeHint s1, nsChangeHint s2) {}
     268             : 
     269             : // Operators on nsChangeHints
     270             : 
     271             : // Returns true iff the second hint contains all the hints of the first hint
     272        5763 : inline bool NS_IsHintSubset(nsChangeHint aSubset, nsChangeHint aSuperSet) {
     273        5763 :   return (aSubset & aSuperSet) == aSubset;
     274             : }
     275             : 
     276             : // The functions below need an integral type to cast to to avoid
     277             : // infinite recursion.
     278             : typedef decltype(nsChangeHint(0) + nsChangeHint(0)) nsChangeHint_size_t;
     279             : 
     280             : inline nsChangeHint constexpr
     281       43885 : operator|(nsChangeHint aLeft, nsChangeHint aRight)
     282             : {
     283       43885 :   return nsChangeHint(nsChangeHint_size_t(aLeft) | nsChangeHint_size_t(aRight));
     284             : }
     285             : 
     286             : inline nsChangeHint constexpr
     287       19244 : operator&(nsChangeHint aLeft, nsChangeHint aRight)
     288             : {
     289       19244 :   return nsChangeHint(nsChangeHint_size_t(aLeft) & nsChangeHint_size_t(aRight));
     290             : }
     291             : 
     292        7214 : inline nsChangeHint& operator|=(nsChangeHint& aLeft, nsChangeHint aRight)
     293             : {
     294        7214 :   return aLeft = aLeft | aRight;
     295             : }
     296             : 
     297          74 : inline nsChangeHint& operator&=(nsChangeHint& aLeft, nsChangeHint aRight)
     298             : {
     299          74 :   return aLeft = aLeft & aRight;
     300             : }
     301             : 
     302             : inline nsChangeHint constexpr
     303        3461 : operator~(nsChangeHint aArg)
     304             : {
     305        3461 :   return nsChangeHint(~nsChangeHint_size_t(aArg));
     306             : }
     307             : 
     308             : inline nsChangeHint constexpr
     309             : operator^(nsChangeHint aLeft, nsChangeHint aRight)
     310             : {
     311             :   return nsChangeHint(nsChangeHint_size_t(aLeft) ^ nsChangeHint_size_t(aRight));
     312             : }
     313             : 
     314             : inline nsChangeHint operator^=(nsChangeHint& aLeft, nsChangeHint aRight)
     315             : {
     316             :   return aLeft = aLeft ^ aRight;
     317             : }
     318             : 
     319             : /**
     320             :  * We have an optimization when processing change hints which prevents
     321             :  * us from visiting the descendants of a node when a hint on that node
     322             :  * is being processed.  This optimization does not apply in some of the
     323             :  * cases where applying a hint to an element does not necessarily result
     324             :  * in the same hint being handled on the descendants.
     325             :  */
     326             : 
     327             : // The change hints that are always handled for descendants.
     328             : #define nsChangeHint_Hints_AlwaysHandledForDescendants (   \
     329             :   nsChangeHint_ClearDescendantIntrinsics |                 \
     330             :   nsChangeHint_NeedDirtyReflow |                           \
     331             :   nsChangeHint_NeutralChange |                             \
     332             :   nsChangeHint_ReconstructFrame |                          \
     333             :   nsChangeHint_RepaintFrame |                              \
     334             :   nsChangeHint_SchedulePaint |                             \
     335             :   nsChangeHint_SyncFrameView |                             \
     336             :   nsChangeHint_UpdateCursor |                              \
     337             :   nsChangeHint_UpdateSubtreeOverflow |                     \
     338             :   nsChangeHint_UpdateTextPath                              \
     339             : )
     340             : 
     341             : // The change hints that are never handled for descendants.
     342             : #define nsChangeHint_Hints_NeverHandledForDescendants (    \
     343             :   nsChangeHint_BorderStyleNoneChange |                     \
     344             :   nsChangeHint_ChildrenOnlyTransform |                     \
     345             :   nsChangeHint_CSSOverflowChange |                         \
     346             :   nsChangeHint_InvalidateRenderingObservers |              \
     347             :   nsChangeHint_RecomputePosition |                         \
     348             :   nsChangeHint_UpdateBackgroundPosition |                  \
     349             :   nsChangeHint_UpdateComputedBSize |                       \
     350             :   nsChangeHint_UpdateContainingBlock |                     \
     351             :   nsChangeHint_UpdateEffects |                             \
     352             :   nsChangeHint_UpdateOpacityLayer |                        \
     353             :   nsChangeHint_UpdateOverflow |                            \
     354             :   nsChangeHint_UpdateParentOverflow |                      \
     355             :   nsChangeHint_UpdatePostTransformOverflow |               \
     356             :   nsChangeHint_UpdateTransformLayer |                      \
     357             :   nsChangeHint_UpdateUsesOpacity |                         \
     358             :   nsChangeHint_AddOrRemoveTransform |                      \
     359             :   nsChangeHint_UpdateWidgetProperties                      \
     360             : )
     361             : 
     362             : // The change hints that are sometimes considered to be handled for descendants.
     363             : #define nsChangeHint_Hints_SometimesHandledForDescendants (\
     364             :   nsChangeHint_ClearAncestorIntrinsics |                   \
     365             :   nsChangeHint_NeedReflow |                                \
     366             :   nsChangeHint_ReflowChangesSizeOrPosition                 \
     367             : )
     368             : 
     369             : static_assert(!(nsChangeHint_Hints_AlwaysHandledForDescendants &
     370             :                 nsChangeHint_Hints_NeverHandledForDescendants) &&
     371             :               !(nsChangeHint_Hints_AlwaysHandledForDescendants &
     372             :                 nsChangeHint_Hints_SometimesHandledForDescendants) &&
     373             :               !(nsChangeHint_Hints_NeverHandledForDescendants &
     374             :                 nsChangeHint_Hints_SometimesHandledForDescendants) &&
     375             :               !(nsChangeHint_AllHints ^
     376             :                 nsChangeHint_Hints_AlwaysHandledForDescendants ^
     377             :                 nsChangeHint_Hints_NeverHandledForDescendants ^
     378             :                 nsChangeHint_Hints_SometimesHandledForDescendants),
     379             :               "change hints must be present in exactly one of "
     380             :               "nsChangeHint_Hints_{Always,Never,Sometimes}"
     381             :               "HandledForDescendants");
     382             : 
     383             : // The most hints that NS_HintsNotHandledForDescendantsIn could possibly return:
     384             : #define nsChangeHint_Hints_NotHandledForDescendants (      \
     385             :   nsChangeHint_Hints_NeverHandledForDescendants |          \
     386             :   nsChangeHint_Hints_SometimesHandledForDescendants        \
     387             : )
     388             : 
     389             : // Redefine the old NS_STYLE_HINT constants in terms of the new hint structure
     390             : #define NS_STYLE_HINT_VISUAL \
     391             :   nsChangeHint(nsChangeHint_RepaintFrame | nsChangeHint_SyncFrameView | \
     392             :                nsChangeHint_SchedulePaint)
     393             : #define nsChangeHint_AllReflowHints                     \
     394             :   nsChangeHint(nsChangeHint_NeedReflow |                \
     395             :                nsChangeHint_ReflowChangesSizeOrPosition|\
     396             :                nsChangeHint_ClearAncestorIntrinsics |   \
     397             :                nsChangeHint_ClearDescendantIntrinsics | \
     398             :                nsChangeHint_NeedDirtyReflow)
     399             : 
     400             : // Below are the change hints that we send for ISize & BSize changes.
     401             : // Each is similar to nsChangeHint_AllReflowHints with a few changes.
     402             : 
     403             : // * For an ISize change, we send nsChangeHint_AllReflowHints, with two bits
     404             : // excluded: nsChangeHint_ClearDescendantIntrinsics (because an ancestor's
     405             : // inline-size change can't affect descendant intrinsic sizes), and
     406             : // nsChangeHint_NeedDirtyReflow (because ISize changes don't need to *force*
     407             : // all descendants to reflow).
     408             : #define nsChangeHint_ReflowHintsForISizeChange            \
     409             :   nsChangeHint(nsChangeHint_AllReflowHints &              \
     410             :                ~(nsChangeHint_ClearDescendantIntrinsics | \
     411             :                  nsChangeHint_NeedDirtyReflow))
     412             : 
     413             : // * For a BSize change, we send almost the same hints as for ISize changes,
     414             : // with one extra: nsChangeHint_UpdateComputedBSize.  We need this hint because
     415             : // BSize changes CAN affect descendant intrinsic sizes, due to replaced
     416             : // elements with percentage BSizes in descendants which also have percentage
     417             : // BSizes. nsChangeHint_UpdateComputedBSize clears intrinsic sizes for frames
     418             : // that have such replaced elements. (We could instead send
     419             : // nsChangeHint_ClearDescendantIntrinsics, but that's broader than we need.)
     420             : //
     421             : // NOTE: You might think that BSize changes could exclude
     422             : // nsChangeHint_ClearAncestorIntrinsics (which is inline-axis specific), but we
     423             : // do need to send it, to clear cached results from CSS Flex measuring reflows.
     424             : #define nsChangeHint_ReflowHintsForBSizeChange            \
     425             :   nsChangeHint((nsChangeHint_AllReflowHints |             \
     426             :                 nsChangeHint_UpdateComputedBSize) &       \
     427             :                ~(nsChangeHint_ClearDescendantIntrinsics | \
     428             :                  nsChangeHint_NeedDirtyReflow))
     429             : 
     430             : #define NS_STYLE_HINT_REFLOW \
     431             :   nsChangeHint(NS_STYLE_HINT_VISUAL | nsChangeHint_AllReflowHints)
     432             : 
     433             : #define nsChangeHint_Hints_CanIgnoreIfNotVisible   \
     434             :   nsChangeHint(NS_STYLE_HINT_VISUAL |              \
     435             :                nsChangeHint_NeutralChange |        \
     436             :                nsChangeHint_UpdateOpacityLayer |   \
     437             :                nsChangeHint_UpdateTransformLayer | \
     438             :                nsChangeHint_UpdateUsesOpacity)
     439             : 
     440             : // NB: Once we drop support for the old style system, this logic should be
     441             : // inlined in the Servo style system to eliminate the FFI call.
     442         759 : inline nsChangeHint NS_HintsNotHandledForDescendantsIn(nsChangeHint aChangeHint) {
     443             :   nsChangeHint result =
     444         759 :     aChangeHint & nsChangeHint_Hints_NeverHandledForDescendants;
     445             : 
     446         759 :   if (!NS_IsHintSubset(nsChangeHint_NeedDirtyReflow, aChangeHint)) {
     447         662 :     if (NS_IsHintSubset(nsChangeHint_NeedReflow, aChangeHint)) {
     448             :       // If NeedDirtyReflow is *not* set, then NeedReflow is a
     449             :       // non-inherited hint.
     450          44 :       result |= nsChangeHint_NeedReflow;
     451             :     }
     452             : 
     453         662 :     if (NS_IsHintSubset(nsChangeHint_ReflowChangesSizeOrPosition,
     454             :                         aChangeHint)) {
     455             :       // If NeedDirtyReflow is *not* set, then ReflowChangesSizeOrPosition is a
     456             :       // non-inherited hint.
     457          44 :       result |= nsChangeHint_ReflowChangesSizeOrPosition;
     458             :     }
     459             :   }
     460             : 
     461        1432 :   if (!NS_IsHintSubset(nsChangeHint_ClearDescendantIntrinsics, aChangeHint) &&
     462         673 :       NS_IsHintSubset(nsChangeHint_ClearAncestorIntrinsics, aChangeHint)) {
     463             :     // If ClearDescendantIntrinsics is *not* set, then
     464             :     // ClearAncestorIntrinsics is a non-inherited hint.
     465          44 :     result |= nsChangeHint_ClearAncestorIntrinsics;
     466             :   }
     467             : 
     468         759 :   MOZ_ASSERT(NS_IsHintSubset(result,
     469             :                              nsChangeHint_Hints_NotHandledForDescendants),
     470             :              "something is inconsistent");
     471             : 
     472         759 :   return result;
     473             : }
     474             : 
     475             : inline nsChangeHint
     476         759 : NS_HintsHandledForDescendantsIn(nsChangeHint aChangeHint)
     477             : {
     478         759 :   return aChangeHint & ~NS_HintsNotHandledForDescendantsIn(aChangeHint);
     479             : }
     480             : 
     481             : // Returns the change hints in aOurChange that are not subsumed by those
     482             : // in aHintsHandled (which are hints that have been handled by an ancestor).
     483             : inline nsChangeHint
     484         759 : NS_RemoveSubsumedHints(nsChangeHint aOurChange, nsChangeHint aHintsHandled)
     485             : {
     486             :   nsChangeHint result =
     487         759 :     aOurChange & ~NS_HintsHandledForDescendantsIn(aHintsHandled);
     488             : 
     489         759 :   if (result & (nsChangeHint_ClearAncestorIntrinsics |
     490             :                 nsChangeHint_ClearDescendantIntrinsics |
     491             :                 nsChangeHint_NeedDirtyReflow |
     492             :                 nsChangeHint_ReflowChangesSizeOrPosition |
     493             :                 nsChangeHint_UpdateComputedBSize)) {
     494          31 :     result |= nsChangeHint_NeedReflow;
     495             :   }
     496             : 
     497         759 :   if (result & (nsChangeHint_ClearDescendantIntrinsics)) {
     498          25 :     MOZ_ASSERT(result & nsChangeHint_ClearAncestorIntrinsics);
     499             :     result |= // nsChangeHint_ClearAncestorIntrinsics |
     500          25 :               nsChangeHint_NeedDirtyReflow;
     501             :   }
     502             : 
     503         759 :   return result;
     504             : }
     505             : 
     506             : /**
     507             :  * |nsRestyleHint| is a bitfield for the result of
     508             :  * |HasStateDependentStyle| and |HasAttributeDependentStyle|.  When no
     509             :  * restyling is necessary, use |nsRestyleHint(0)|.
     510             :  *
     511             :  * Without eRestyle_Force or eRestyle_ForceDescendants, the restyling process
     512             :  * can stop processing at a frame when it detects no style changes and it is
     513             :  * known that the styles of the subtree beneath it will not change, leaving
     514             :  * the old style context on the frame.  eRestyle_Force can be used to skip this
     515             :  * optimization on a frame, and to force its new style context to be used.
     516             :  *
     517             :  * Similarly, eRestyle_ForceDescendants will cause the frame and all of its
     518             :  * descendants to be traversed and for the new style contexts that are created
     519             :  * to be set on the frames.
     520             :  *
     521             :  * NOTE: When adding new restyle hints, please also add them to
     522             :  * RestyleManager::RestyleHintToString.
     523             :  */
     524             : enum nsRestyleHint : uint32_t {
     525             :   // Rerun selector matching on the element.  If a new style context
     526             :   // results, update the style contexts of descendants.  (Irrelevant if
     527             :   // eRestyle_Subtree is also set, since that implies a superset of the
     528             :   // work.)
     529             :   eRestyle_Self = 1 << 0,
     530             : 
     531             :   // Rerun selector matching on descendants of the element that match
     532             :   // a given selector.
     533             :   eRestyle_SomeDescendants = 1 << 1,
     534             : 
     535             :   // Rerun selector matching on the element and all of its descendants.
     536             :   // (Implies eRestyle_ForceDescendants, which ensures that we continue
     537             :   // the restyling process for all descendants, but doesn't cause
     538             :   // selector matching.)
     539             :   eRestyle_Subtree = 1 << 2,
     540             : 
     541             :   // Rerun selector matching on all later siblings of the element and
     542             :   // all of their descendants.
     543             :   eRestyle_LaterSiblings = 1 << 3,
     544             : 
     545             :   // Replace the style data coming from CSS transitions without updating
     546             :   // any other style data.  If a new style context results, update style
     547             :   // contexts on the descendants.  (Irrelevant if eRestyle_Self or
     548             :   // eRestyle_Subtree is also set, since those imply a superset of the
     549             :   // work.)
     550             :   eRestyle_CSSTransitions = 1 << 4,
     551             : 
     552             :   // Replace the style data coming from CSS animations without updating
     553             :   // any other style data.  If a new style context results, update style
     554             :   // contexts on the descendants.  (Irrelevant if eRestyle_Self or
     555             :   // eRestyle_Subtree is also set, since those imply a superset of the
     556             :   // work.)
     557             :   eRestyle_CSSAnimations = 1 << 5,
     558             : 
     559             :   // Replace the style data coming from inline style without updating
     560             :   // any other style data.  If a new style context results, update style
     561             :   // contexts on the descendants.  (Irrelevant if eRestyle_Self or
     562             :   // eRestyle_Subtree is also set, since those imply a superset of the
     563             :   // work.)  Supported only for element style contexts and not for
     564             :   // pseudo-elements or anonymous boxes, on which it converts to
     565             :   // eRestyle_Self.
     566             :   // If the change is for the advance of a declarative animation, use
     567             :   // the value below instead.
     568             :   eRestyle_StyleAttribute = 1 << 6,
     569             : 
     570             :   // Same as eRestyle_StyleAttribute, but for when the change results
     571             :   // from the advance of a declarative animation.
     572             :   eRestyle_StyleAttribute_Animations = 1 << 7,
     573             : 
     574             :   // Continue the restyling process to the current frame's children even
     575             :   // if this frame's restyling resulted in no style changes.
     576             :   eRestyle_Force = 1 << 8,
     577             : 
     578             :   // Continue the restyling process to all of the current frame's
     579             :   // descendants, even if any frame's restyling resulted in no style
     580             :   // changes.  (Implies eRestyle_Force.)  Note that this is weaker than
     581             :   // eRestyle_Subtree, which makes us rerun selector matching on all
     582             :   // descendants rather than just continuing the restyling process.
     583             :   eRestyle_ForceDescendants = 1 << 9,
     584             : 
     585             :   // Useful unions:
     586             :   eRestyle_AllHintsWithAnimations = eRestyle_CSSTransitions |
     587             :                                     eRestyle_CSSAnimations |
     588             :                                     eRestyle_StyleAttribute_Animations,
     589             : };
     590             : 
     591             : // The functions below need an integral type to cast to to avoid
     592             : // infinite recursion.
     593             : typedef decltype(nsRestyleHint(0) + nsRestyleHint(0)) nsRestyleHint_size_t;
     594             : 
     595       27305 : inline constexpr nsRestyleHint operator|(nsRestyleHint aLeft,
     596             :                                              nsRestyleHint aRight)
     597             : {
     598             :   return nsRestyleHint(nsRestyleHint_size_t(aLeft) |
     599       27305 :                        nsRestyleHint_size_t(aRight));
     600             : }
     601             : 
     602       51302 : inline constexpr nsRestyleHint operator&(nsRestyleHint aLeft,
     603             :                                              nsRestyleHint aRight)
     604             : {
     605             :   return nsRestyleHint(nsRestyleHint_size_t(aLeft) &
     606       51302 :                        nsRestyleHint_size_t(aRight));
     607             : }
     608             : 
     609           6 : inline nsRestyleHint& operator|=(nsRestyleHint& aLeft, nsRestyleHint aRight)
     610             : {
     611           6 :   return aLeft = aLeft | aRight;
     612             : }
     613             : 
     614          72 : inline nsRestyleHint& operator&=(nsRestyleHint& aLeft, nsRestyleHint aRight)
     615             : {
     616          72 :   return aLeft = aLeft & aRight;
     617             : }
     618             : 
     619       34870 : inline constexpr nsRestyleHint operator~(nsRestyleHint aArg)
     620             : {
     621       34870 :   return nsRestyleHint(~nsRestyleHint_size_t(aArg));
     622             : }
     623             : 
     624             : inline constexpr nsRestyleHint operator^(nsRestyleHint aLeft,
     625             :                                              nsRestyleHint aRight)
     626             : {
     627             :   return nsRestyleHint(nsRestyleHint_size_t(aLeft) ^
     628             :                        nsRestyleHint_size_t(aRight));
     629             : }
     630             : 
     631             : inline nsRestyleHint operator^=(nsRestyleHint& aLeft, nsRestyleHint aRight)
     632             : {
     633             :   return aLeft = aLeft ^ aRight;
     634             : }
     635             : 
     636             : namespace mozilla {
     637             : 
     638             : /**
     639             :  * Additional data used in conjunction with an nsRestyleHint to control the
     640             :  * restyle process.
     641             :  */
     642        6176 : struct RestyleHintData
     643             : {
     644             :   // When eRestyle_SomeDescendants is used, this array contains the selectors
     645             :   // that identify which descendants will be restyled.
     646             :   nsTArray<nsCSSSelector*> mSelectorsForDescendants;
     647             : };
     648             : 
     649             : } // namespace mozilla
     650             : 
     651             : #endif /* nsChangeHint_h___ */

Generated by: LCOV version 1.13