style/properties/computed_value_flags.rs
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5//! Misc information about a given computed style.
6
7use crate::derives::MallocSizeOf;
8
9/// Misc information about a given computed style.
10///
11/// All flags are currently inherited for text, pseudo elements, and
12/// anonymous boxes, see StyleBuilder::for_inheritance and its callsites.
13/// If we ever want to add some flags that shouldn't inherit for them,
14/// we might want to add a function to handle this.
15#[repr(C)]
16#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq)]
17pub struct ComputedValueFlags(u32);
18
19bitflags! {
20 impl ComputedValueFlags: u32 {
21 /// Whether the style or any of the ancestors has a text-decoration-line
22 /// property that should get propagated to descendants.
23 ///
24 /// text-decoration-line is a reset property, but gets propagated in the
25 /// frame/box tree.
26 const HAS_TEXT_DECORATION_LINES = 1 << 0;
27
28 /// Whether line break inside should be suppressed.
29 ///
30 /// If this flag is set, the line should not be broken inside,
31 /// which means inlines act as if nowrap is set, <br> element is
32 /// suppressed, and blocks are inlinized.
33 ///
34 /// This bit is propagated to all children of line participants.
35 /// It is currently used by ruby to make its content unbreakable.
36 const SHOULD_SUPPRESS_LINEBREAK = 1 << 1;
37
38 /// A flag used to mark text that that has text-combine-upright.
39 ///
40 /// This is used from Gecko's layout engine.
41 const IS_TEXT_COMBINED = 1 << 2;
42
43 /// A flag used to mark styles under a relevant link that is also
44 /// visited.
45 const IS_RELEVANT_LINK_VISITED = 1 << 3;
46
47 /// A flag used to mark styles which are a ::first-line or under one.
48 const IS_IN_FIRST_LINE_SUBTREE = 1 << 4;
49
50 /// A flag used to mark styles which have contain:style or under one.
51 const SELF_OR_ANCESTOR_HAS_CONTAIN_STYLE = 1 << 5;
52
53 /// Whether this style's `display` or `content`property depends on our parent style.
54 ///
55 /// This is important because it may affect our optimizations to avoid
56 /// computing the style of pseudo-elements, given whether the
57 /// pseudo-element is generated depends on the `display` (or `content`) value.
58 const DISPLAY_OR_CONTENT_DEPEND_ON_INHERITED_STYLE = 1 << 6;
59
60 /// Whether the child explicitly inherits any reset property.
61 const INHERITS_RESET_STYLE = 1 << 7;
62
63 /// Whether any value on our style is font-metric-dependent on our
64 /// primary font.
65 const DEPENDS_ON_SELF_FONT_METRICS = 1 << 8;
66
67 /// Whether any value on our style is font-metric-dependent on the
68 /// primary font of our parent.
69 const DEPENDS_ON_INHERITED_FONT_METRICS = 1 << 9;
70
71 /// Whether this style is the style of the document element.
72 const IS_ROOT_ELEMENT_STYLE = 1 << 10;
73
74 /// Whether this element is inside an `opacity: 0` subtree.
75 const IS_IN_OPACITY_ZERO_SUBTREE = 1 << 11;
76
77 /// Whether there are author-specified rules for border-* properties
78 /// (except border-image-*), background-color, or background-image.
79 ///
80 /// TODO(emilio): Maybe do include border-image, see:
81 ///
82 /// https://github.com/w3c/csswg-drafts/issues/4777#issuecomment-604424845
83 const HAS_AUTHOR_SPECIFIED_BORDER_BACKGROUND = 1 << 12;
84
85 /// Whether the style depends on viewport units.
86 const USES_VIEWPORT_UNITS = 1 << 13;
87
88 /// Whether the style depends on viewport units on container queries.
89 ///
90 /// This needs to be a separate flag from `USES_VIEWPORT_UNITS` because
91 /// it causes us to re-match the style (rather than re-cascascading it,
92 /// which is enough for other uses of viewport units).
93 const USES_VIEWPORT_UNITS_ON_CONTAINER_QUERIES = 1 << 14;
94
95 /// A flag used to mark styles which have `container-type` of `size` or
96 /// `inline-size`, or under one.
97 const SELF_OR_ANCESTOR_HAS_SIZE_CONTAINER_TYPE = 1 << 15;
98
99 /// Whether the style uses container query units, in which case the style depends on the
100 /// container's size and we can't reuse it across cousins (without double-checking the
101 /// container at least).
102 const USES_CONTAINER_UNITS = 1 << 16;
103
104 /// Whether there are author-specific rules for text `color`.
105 const HAS_AUTHOR_SPECIFIED_TEXT_COLOR = 1 << 17;
106
107 /// Whether this style considered a scope style rule.
108 const CONSIDERED_NONTRIVIAL_SCOPED_STYLE = 1 << 18;
109
110 /// Whether this style is that of a `display: contents` element that is either a direct
111 /// child of an item container or another `display: contents` element, the style of which
112 /// has this flag set, marked in order to cascade beyond them to the descendants of the
113 /// the item container that do generate a box.
114 const DISPLAY_CONTENTS_IN_ITEM_CONTAINER = 1 << 19;
115
116 /// Whether there are author-specific rules for `text-shadow`.
117 const HAS_AUTHOR_SPECIFIED_TEXT_SHADOW = 1 << 20;
118
119 /// Whether this style depends on container style query.
120 const DEPENDS_ON_CONTAINER_STYLE_QUERY = 1 << 21;
121
122 /// Whether this style is in an appearance: base subtree
123 const IS_IN_APPEARANCE_BASE_SUBTREE = 1 << 22;
124
125 /// Whether grid-auto-flow is author-specified.
126 const HAS_AUTHOR_SPECIFIED_GRID_AUTO_FLOW = 1 << 23;
127
128 /// Whether this style has used font relative units. Note that this is different than the
129 /// FONT_METRICS bits, which don't include rem / em etc.
130 const USES_FONT_RELATIVE_UNITS = 1 << 24;
131
132 /// Whether this style depends on font relative units in container queries.
133 const USES_FONT_RELATIVE_UNITS_ON_CONTAINER_QUERIES = 1 << 25;
134
135 /// Whether this style uses `sibling-count()`.
136 const USES_SIBLING_COUNT = 1 << 26;
137
138 /// Whether this style uses `sibling-index()`.
139 const USES_SIBLING_INDEX = 1 << 27;
140 }
141}
142
143impl Default for ComputedValueFlags {
144 #[inline]
145 fn default() -> Self {
146 Self::empty()
147 }
148}
149
150impl ComputedValueFlags {
151 /// Flags that are unconditionally propagated to descendants.
152 #[inline]
153 fn inherited_flags() -> Self {
154 Self::IS_RELEVANT_LINK_VISITED
155 | Self::IS_IN_FIRST_LINE_SUBTREE
156 | Self::HAS_TEXT_DECORATION_LINES
157 | Self::IS_IN_OPACITY_ZERO_SUBTREE
158 | Self::SELF_OR_ANCESTOR_HAS_CONTAIN_STYLE
159 | Self::SELF_OR_ANCESTOR_HAS_SIZE_CONTAINER_TYPE
160 | Self::IS_IN_APPEARANCE_BASE_SUBTREE
161 }
162
163 /// Flags that may be propagated to descendants.
164 #[inline]
165 fn maybe_inherited_flags() -> Self {
166 Self::inherited_flags()
167 | Self::SHOULD_SUPPRESS_LINEBREAK
168 | Self::DISPLAY_CONTENTS_IN_ITEM_CONTAINER
169 }
170
171 /// Flags that are an input to the cascade.
172 #[inline]
173 fn cascade_input_flags() -> Self {
174 Self::USES_VIEWPORT_UNITS_ON_CONTAINER_QUERIES
175 | Self::CONSIDERED_NONTRIVIAL_SCOPED_STYLE
176 | Self::DEPENDS_ON_CONTAINER_STYLE_QUERY
177 | Self::USES_FONT_RELATIVE_UNITS_ON_CONTAINER_QUERIES
178 }
179
180 /// Flags corresponding to usage of tree-counting functions.
181 #[inline]
182 pub fn tree_counting_function_flags() -> Self {
183 Self::USES_SIBLING_COUNT | Self::USES_SIBLING_INDEX
184 }
185
186 /// Returns the flags that are always propagated to descendants.
187 ///
188 /// See StyleAdjuster::set_bits and StyleBuilder.
189 #[inline]
190 pub fn inherited(self) -> Self {
191 self & Self::inherited_flags()
192 }
193
194 /// Flags that are conditionally propagated to descendants, just to handle
195 /// properly style invalidation.
196 #[inline]
197 pub fn maybe_inherited(self) -> Self {
198 self & Self::maybe_inherited_flags()
199 }
200
201 /// Flags that are an input to the cascade.
202 #[inline]
203 pub fn for_cascade_inputs(self) -> Self {
204 self & Self::cascade_input_flags()
205 }
206}