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___ */
|