Coverage Report

Created: 2018-09-25 14:53

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