Bumping manifests a=b2g-bump
[gecko.git] / layout / base / nsChangeHint.h
blobfb9b3a36b4ab7bf98b2713f5601ff78b3191afd7
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /* constants for what needs to be recomputed in response to style changes */
8 #ifndef nsChangeHint_h___
9 #define nsChangeHint_h___
11 #include "nsDebug.h"
12 #include "mozilla/Types.h"
14 // Defines for various style related constants
16 enum nsChangeHint {
17 // change was visual only (e.g., COLOR=)
18 // Invalidates all descendant frames (including following
19 // placeholders to out-of-flow frames).
20 nsChangeHint_RepaintFrame = 0x01,
22 // For reflow, we want flags to give us arbitrary FrameNeedsReflow behavior.
23 // just do a FrameNeedsReflow.
24 nsChangeHint_NeedReflow = 0x02,
26 // Invalidate intrinsic widths on the frame's ancestors. Must not be set
27 // without setting nsChangeHint_NeedReflow.
28 nsChangeHint_ClearAncestorIntrinsics = 0x04,
30 // Invalidate intrinsic widths on the frame's descendants. Must not be set
31 // without also setting nsChangeHint_ClearAncestorIntrinsics.
32 nsChangeHint_ClearDescendantIntrinsics = 0x08,
34 // Force unconditional reflow of all descendants. Must not be set without
35 // setting nsChangeHint_NeedReflow, but is independent of both the
36 // Clear*Intrinsics flags.
37 nsChangeHint_NeedDirtyReflow = 0x10,
39 // change requires view to be updated, if there is one (e.g., clip:).
40 // Updates all descendants (including following placeholders to out-of-flows).
41 nsChangeHint_SyncFrameView = 0x20,
43 // The currently shown mouse cursor needs to be updated
44 nsChangeHint_UpdateCursor = 0x40,
46 /**
47 * Used when the computed value (a URI) of one or more of an element's
48 * filter/mask/clip/etc CSS properties changes, causing the element's frame
49 * to start/stop referencing (or reference different) SVG resource elements.
50 * (_Not_ used to handle changes to referenced resource elements.) Using this
51 * hint results in nsSVGEffects::UpdateEffects being called on the element's
52 * frame.
54 nsChangeHint_UpdateEffects = 0x80,
56 /**
57 * Visual change only, but the change can be handled entirely by
58 * updating the layer(s) for the frame.
59 * Updates all descendants (including following placeholders to out-of-flows).
61 nsChangeHint_UpdateOpacityLayer = 0x100,
62 /**
63 * Updates all descendants. Any placeholder descendants' out-of-flows
64 * are also descendants of the transformed frame, so they're updated.
66 nsChangeHint_UpdateTransformLayer = 0x200,
68 /**
69 * Change requires frame change (e.g., display:).
70 * This subsumes all the above. Reconstructs all frame descendants,
71 * including following placeholders to out-of-flows.
73 nsChangeHint_ReconstructFrame = 0x400,
75 /**
76 * The frame's overflow area has changed. Does not update any descendant
77 * frames.
79 nsChangeHint_UpdateOverflow = 0x800,
81 /**
82 * The overflow area of the frame and all of its descendants has changed. This
83 * can happen through a text-decoration change.
85 nsChangeHint_UpdateSubtreeOverflow = 0x1000,
87 /**
88 * The frame's overflow area has changed, through a change in its transform.
89 * Does not update any descendant frames.
91 nsChangeHint_UpdatePostTransformOverflow = 0x2000,
93 /**
94 * The children-only transform of an SVG frame changed, requiring the
95 * overflow rects of the frame's immediate children to be updated.
97 nsChangeHint_ChildrenOnlyTransform = 0x4000,
99 /**
100 * The frame's offsets have changed, while its dimensions might have
101 * changed as well. This hint is used for positioned frames if their
102 * offset changes. If we decide that the dimensions are likely to
103 * change, this will trigger a reflow.
105 * Note that this should probably be used in combination with
106 * nsChangeHint_UpdateOverflow in order to get the overflow areas of
107 * the ancestors updated as well.
109 nsChangeHint_RecomputePosition = 0x8000,
112 * Behaves like ReconstructFrame, but only if the frame has descendants
113 * that are absolutely or fixed position. Use this hint when a style change
114 * has changed whether the frame is a container for fixed-pos or abs-pos
115 * elements, but reframing is otherwise not needed.
117 nsChangeHint_AddOrRemoveTransform = 0x10000,
120 * This change hint has *no* change handling behavior. However, it
121 * exists to be a non-inherited hint, because when the border-style
122 * changes, and it's inherited by a child, that might require a reflow
123 * due to the border-width change on the child.
125 nsChangeHint_BorderStyleNoneChange = 0x20000,
128 * SVG textPath needs to be recomputed because the path has changed.
129 * This means that the glyph positions of the text need to be recomputed.
131 nsChangeHint_UpdateTextPath = 0x40000,
134 * This will schedule an invalidating paint. This is useful if something
135 * has changed which will be invalidated by DLBI.
137 nsChangeHint_SchedulePaint = 0x80000,
140 * A hint reflecting that style data changed with no change handling
141 * behavior. We need to return this, rather than NS_STYLE_HINT_NONE,
142 * so that certain optimizations that manipulate the style context tree are
143 * correct.
145 * nsChangeHint_NeutralChange must be returned by CalcDifference on a given
146 * style struct if the data in the style structs are meaningfully different
147 * and if no other change hints are returned. If any other change hints are
148 * set, then nsChangeHint_NeutralChange need not also be included, but it is
149 * safe to do so. (An example of style structs having non-meaningfully
150 * different data would be cached information that would be re-calculated
151 * to the same values, such as nsStyleBorder::mSubImages.)
153 nsChangeHint_NeutralChange = 0x100000,
156 * This will cause rendering observers to be invalidated.
158 nsChangeHint_InvalidateRenderingObservers = 0x200000
160 // IMPORTANT NOTE: When adding new hints, consider whether you need to
161 // add them to NS_HintsNotHandledForDescendantsIn() below. Please also
162 // add them to RestyleManager::ChangeHintToString.
165 // Redefine these operators to return nothing. This will catch any use
166 // of these operators on hints. We should not be using these operators
167 // on nsChangeHints
168 inline void operator<(nsChangeHint s1, nsChangeHint s2) {}
169 inline void operator>(nsChangeHint s1, nsChangeHint s2) {}
170 inline void operator!=(nsChangeHint s1, nsChangeHint s2) {}
171 inline void operator==(nsChangeHint s1, nsChangeHint s2) {}
172 inline void operator<=(nsChangeHint s1, nsChangeHint s2) {}
173 inline void operator>=(nsChangeHint s1, nsChangeHint s2) {}
175 // Operators on nsChangeHints
177 // Merge two hints, taking the union
178 inline nsChangeHint NS_CombineHint(nsChangeHint aH1, nsChangeHint aH2) {
179 return (nsChangeHint)(aH1 | aH2);
182 // Merge two hints, taking the union
183 inline nsChangeHint NS_SubtractHint(nsChangeHint aH1, nsChangeHint aH2) {
184 return (nsChangeHint)(aH1 & ~aH2);
187 // Merge the "src" hint into the "dst" hint
188 // Returns true iff the destination changed
189 inline bool NS_UpdateHint(nsChangeHint& aDest, nsChangeHint aSrc) {
190 nsChangeHint r = (nsChangeHint)(aDest | aSrc);
191 bool changed = (int)r != (int)aDest;
192 aDest = r;
193 return changed;
196 // Returns true iff the second hint contains all the hints of the first hint
197 inline bool NS_IsHintSubset(nsChangeHint aSubset, nsChangeHint aSuperSet) {
198 return (aSubset & aSuperSet) == aSubset;
202 * We have an optimization when processing change hints which prevents
203 * us from visiting the descendants of a node when a hint on that node
204 * is being processed. This optimization does not apply in some of the
205 * cases where applying a hint to an element does not necessarily result
206 * in the same hint being handled on the descendants.
209 // The most hints that NS_HintsNotHandledForDescendantsIn could possibly return:
210 #define nsChangeHint_Hints_NotHandledForDescendants nsChangeHint( \
211 nsChangeHint_UpdateTransformLayer | \
212 nsChangeHint_UpdateEffects | \
213 nsChangeHint_InvalidateRenderingObservers | \
214 nsChangeHint_UpdateOpacityLayer | \
215 nsChangeHint_UpdateOverflow | \
216 nsChangeHint_UpdatePostTransformOverflow | \
217 nsChangeHint_ChildrenOnlyTransform | \
218 nsChangeHint_RecomputePosition | \
219 nsChangeHint_AddOrRemoveTransform | \
220 nsChangeHint_BorderStyleNoneChange | \
221 nsChangeHint_NeedReflow | \
222 nsChangeHint_ClearAncestorIntrinsics)
224 inline nsChangeHint NS_HintsNotHandledForDescendantsIn(nsChangeHint aChangeHint) {
225 nsChangeHint result = nsChangeHint(aChangeHint & (
226 nsChangeHint_UpdateTransformLayer |
227 nsChangeHint_UpdateEffects |
228 nsChangeHint_InvalidateRenderingObservers |
229 nsChangeHint_UpdateOpacityLayer |
230 nsChangeHint_UpdateOverflow |
231 nsChangeHint_UpdatePostTransformOverflow |
232 nsChangeHint_ChildrenOnlyTransform |
233 nsChangeHint_RecomputePosition |
234 nsChangeHint_AddOrRemoveTransform |
235 nsChangeHint_BorderStyleNoneChange));
237 if (!NS_IsHintSubset(nsChangeHint_NeedDirtyReflow, aChangeHint) &&
238 NS_IsHintSubset(nsChangeHint_NeedReflow, aChangeHint)) {
239 // If NeedDirtyReflow is *not* set, then NeedReflow is a
240 // non-inherited hint.
241 NS_UpdateHint(result, nsChangeHint_NeedReflow);
244 if (!NS_IsHintSubset(nsChangeHint_ClearDescendantIntrinsics, aChangeHint) &&
245 NS_IsHintSubset(nsChangeHint_ClearAncestorIntrinsics, aChangeHint)) {
246 // If ClearDescendantIntrinsics is *not* set, then
247 // ClearAncestorIntrinsics is a non-inherited hint.
248 NS_UpdateHint(result, nsChangeHint_ClearAncestorIntrinsics);
251 NS_ABORT_IF_FALSE(NS_IsHintSubset(result,
252 nsChangeHint_Hints_NotHandledForDescendants),
253 "something is inconsistent");
255 return result;
258 // Redefine the old NS_STYLE_HINT constants in terms of the new hint structure
259 #define NS_STYLE_HINT_NONE \
260 nsChangeHint(0)
261 #define NS_STYLE_HINT_VISUAL \
262 nsChangeHint(nsChangeHint_RepaintFrame | nsChangeHint_SyncFrameView | \
263 nsChangeHint_SchedulePaint)
264 #define nsChangeHint_AllReflowHints \
265 nsChangeHint(nsChangeHint_NeedReflow | \
266 nsChangeHint_ClearAncestorIntrinsics | \
267 nsChangeHint_ClearDescendantIntrinsics | \
268 nsChangeHint_NeedDirtyReflow)
269 #define NS_STYLE_HINT_REFLOW \
270 nsChangeHint(NS_STYLE_HINT_VISUAL | nsChangeHint_AllReflowHints)
271 #define NS_STYLE_HINT_FRAMECHANGE \
272 nsChangeHint(NS_STYLE_HINT_REFLOW | nsChangeHint_ReconstructFrame)
275 * |nsRestyleHint| is a bitfield for the result of
276 * |HasStateDependentStyle| and |HasAttributeDependentStyle|. When no
277 * restyling is necessary, use |nsRestyleHint(0)|.
279 * Without eRestyle_Force or eRestyle_ForceDescendants, the restyling process
280 * can stop processing at a frame when it detects no style changes and it is
281 * known that the styles of the subtree beneath it will not change, leaving
282 * the old style context on the frame. eRestyle_Force can be used to skip this
283 * optimization on a frame, and to force its new style context to be used.
285 * Similarly, eRestyle_ForceDescendants will cause the frame and all of its
286 * descendants to be traversed and for the new style contexts that are created
287 * to be set on the frames.
289 * NOTE: When adding new restyle hints, please also add them to
290 * RestyleManager::RestyleHintToString.
292 enum nsRestyleHint {
293 // Rerun selector matching on the element. If a new style context
294 // results, update the style contexts of descendants. (Irrelevant if
295 // eRestyle_Subtree is also set, since that implies a superset of the
296 // work.)
297 eRestyle_Self = (1<<0),
299 // Rerun selector matching on the element and all of its descendants.
300 // (Implies eRestyle_ForceDescendants, which ensures that we continue
301 // the restyling process for all descendants, but doesn't cause
302 // selector matching.)
303 eRestyle_Subtree = (1<<1),
305 // Rerun selector matching on all later siblings of the element and
306 // all of their descendants.
307 eRestyle_LaterSiblings = (1<<2),
309 // Replace the style data coming from CSS transitions without updating
310 // any other style data. If a new style context results, update style
311 // contexts on the descendants. (Irrelevant if eRestyle_Self or
312 // eRestyle_Subtree is also set, since those imply a superset of the
313 // work.)
314 eRestyle_CSSTransitions = (1<<3),
316 // Replace the style data coming from CSS animations without updating
317 // any other style data. If a new style context results, update style
318 // contexts on the descendants. (Irrelevant if eRestyle_Self or
319 // eRestyle_Subtree is also set, since those imply a superset of the
320 // work.)
321 eRestyle_CSSAnimations = (1<<4),
323 // Replace the style data coming from SVG animations (SMIL Animations)
324 // without updating any other style data. If a new style context
325 // results, update style contexts on the descendants. (Irrelevant if
326 // eRestyle_Self or eRestyle_Subtree is also set, since those imply a
327 // superset of the work.)
328 eRestyle_SVGAttrAnimations = (1<<5),
330 // Replace the style data coming from inline style without updating
331 // any other style data. If a new style context results, update style
332 // contexts on the descendants. (Irrelevant if eRestyle_Self or
333 // eRestyle_Subtree is also set, since those imply a superset of the
334 // work.) Supported only for element style contexts and not for
335 // pseudo-elements or anonymous boxes, on which it converts to
336 // eRestyle_Self.
337 eRestyle_StyleAttribute = (1<<6),
339 // Additional restyle hint to be used along with CSSTransitions,
340 // CSSAnimations, SVGAttrAnimations, or StyleAttribute. This
341 // indicates that along with the replacement given, appropriate
342 // switching between the style with animation and style without
343 // animation should be performed by adding or removing rules that
344 // should be present only in the style with animation.
345 // This is implied by eRestyle_Self or eRestyle_Subtree.
346 // FIXME: Remove this as part of bug 960465.
347 eRestyle_ChangeAnimationPhase = (1 << 7),
349 // Same as the previous, except this applies to the entire subtree.
350 // FIXME: Remove this as part of bug 960465.
351 eRestyle_ChangeAnimationPhaseDescendants = (1 << 8),
353 // Continue the restyling process to the current frame's children even
354 // if this frame's restyling resulted in no style changes.
355 eRestyle_Force = (1<<9),
357 // Continue the restyling process to all of the current frame's
358 // descendants, even if any frame's restyling resulted in no style
359 // changes. (Implies eRestyle_Force.) Note that this is weaker than
360 // eRestyle_Subtree, which makes us rerun selector matching on all
361 // descendants rather than just continuing the restyling process.
362 eRestyle_ForceDescendants = (1<<10),
365 // The functions below need an integral type to cast to to avoid
366 // infinite recursion.
367 typedef decltype(nsRestyleHint(0) + nsRestyleHint(0)) nsRestyleHint_size_t;
369 inline nsRestyleHint operator|(nsRestyleHint aLeft, nsRestyleHint aRight)
371 return nsRestyleHint(nsRestyleHint_size_t(aLeft) |
372 nsRestyleHint_size_t(aRight));
375 inline nsRestyleHint operator&(nsRestyleHint aLeft, nsRestyleHint aRight)
377 return nsRestyleHint(nsRestyleHint_size_t(aLeft) &
378 nsRestyleHint_size_t(aRight));
381 inline nsRestyleHint& operator|=(nsRestyleHint& aLeft, nsRestyleHint aRight)
383 return aLeft = aLeft | aRight;
386 inline nsRestyleHint& operator&=(nsRestyleHint& aLeft, nsRestyleHint aRight)
388 return aLeft = aLeft & aRight;
391 inline nsRestyleHint operator~(nsRestyleHint aArg)
393 return nsRestyleHint(~nsRestyleHint_size_t(aArg));
396 inline nsRestyleHint operator^(nsRestyleHint aLeft, nsRestyleHint aRight)
398 return nsRestyleHint(nsRestyleHint_size_t(aLeft) ^
399 nsRestyleHint_size_t(aRight));
402 inline nsRestyleHint operator^=(nsRestyleHint& aLeft, nsRestyleHint aRight)
404 return aLeft = aLeft ^ aRight;
407 #endif /* nsChangeHint_h___ */