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