css_ast/traits/
declaration_metadata.rs

1use bitmask_enum::bitmask;
2
3use crate::CssAtomSet;
4
5/// The CSS specification/module that a property belongs to.
6#[bitmask(u64)]
7#[bitmask_config(vec_debug)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9pub enum PropertyGroup {
10	Align,
11	AnchorPosition,
12	Animations,
13	Backgrounds,
14	Borders,
15	Box,
16	Break,
17	Cascade,
18	Color,
19	ColorAdjust,
20	ColorHdr,
21	Conditional,
22	Contain,
23	Content,
24	Display,
25	Exclusions,
26	Flexbox,
27	Fonts,
28	Forms,
29	Gaps,
30	Gcpm,
31	Grid,
32	Images,
33	Inline,
34	LineGrid,
35	LinkParams,
36	Lists,
37	Logical,
38	Multicol,
39	Nav,
40	Overflow,
41	Overscroll,
42	Page,
43	PageFloats,
44	Position,
45	Regions,
46	Rhythm,
47	RoundDisplay,
48	Ruby,
49	ScrollAnchoring,
50	ScrollSnap,
51	Scrollbars,
52	Shapes,
53	SizeAdjust,
54	Sizing,
55	Speech,
56	Tables,
57	Text,
58	TextDecor,
59	Transforms,
60	Transitions,
61	Ui,
62	Values,
63	Variables,
64	ViewTransitions,
65	Viewport,
66	WillChange,
67	WritingModes,
68}
69
70pub enum Inherits {
71	False,
72	True,
73	Unknown,
74}
75
76impl Inherits {
77	pub fn to_bool(self, unknown: bool) -> bool {
78		match self {
79			Self::False => false,
80			Self::True => true,
81			Self::Unknown => unknown,
82		}
83	}
84}
85
86pub enum Percentages {
87	/// This style value has no way of expressing values as a percentage.
88	None,
89	/// Any percentage expressed in this value pertains to the size of the containing block.
90	ContainingBlock,
91	/// Any percentage expressed in this value pertains to the size of the border box.
92	BorderBox,
93	/// Any percentage expressed in this value is a syntax affordance; a Number token would be the equivalent value.
94	Number,
95	/// Relative to the 1em Font-Size
96	FontSize,
97	/// Relative to the Font-Size of the parent element
98	ParentFontSize,
99	/// Relative to the scroll container's scrollport
100	Scrollport,
101	/// Relative to the content area dimension
102	ContentArea,
103	/// Relative to the border-edge side length
104	BorderEdge,
105	/// Relative to the background positioning area
106	BackgroundPositioningArea,
107	/// Relative to the reference box size
108	ReferenceBox,
109	/// Relative to the element's own dimensions
110	SelfSize,
111	/// Relative to the line box
112	LineBox,
113	/// Relative to the flex container
114	FlexContainer,
115	/// Relative to the border image area
116	BorderImageArea,
117	/// Map to a normalized range (e.g., `[0,1]`)
118	NormalizedRange,
119	/// Unknown or complex percentage resolution
120	Unknown,
121}
122
123/// The type of element or container this style value applies to.
124#[bitmask(u16)]
125#[bitmask_config(vec_debug)]
126#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
127pub enum AppliesTo {
128	/// Any element which is `display: block` or equivalent.
129	Block,
130	/// Any element which is `display: grid` or equivalent.
131	Grid,
132	/// Any element which is `display: flex` or equivalent.
133	Flex,
134	/// Any inline-level box.
135	Inline,
136	/// Any floated element.
137	Float,
138	/// Any Ruby container
139	Ruby,
140	/// Any absolutely positioned element.
141	AbsPos,
142	/// Any text node.
143	Text,
144	/// Any Pseudo Elements
145	PseudoElements,
146	/// Any Element
147	Elements,
148	/// What this applies to still needs to be established.
149	Unknown,
150}
151
152pub enum AnimationType {
153	/// This property is not animatable.
154	None,
155	/// This property animates between discrete values.
156	Discrete,
157	/// Animates by interpolating computed values
158	ByComputedValue,
159	/// Each item in a list animates independently
160	RepeatableList,
161	/// Animates as a transform list
162	TransformList,
163	/// Animates as a shadow list
164	ShadowList,
165	/// Animates as a length value
166	Length,
167	/// Animates as a number value
168	Number,
169	/// Unknown or complex animation behavior
170	Unknown,
171}
172
173/// How the computed value is calculated from the specified value
174pub enum ComputedValueType {
175	/// The computed value is the same as the specified value
176	AsSpecified,
177	/// Computed to an absolute length
178	AbsoluteLength,
179	/// Computed to an absolute length or percentage
180	AbsoluteLengthOrPercentage,
181	/// Computed to an absolute length or 'none'
182	AbsoluteLengthOrNone,
183	/// A specified keyword plus an absolute length
184	SpecifiedKeywordPlusAbsoluteLength,
185	/// Two absolute lengths (e.g., for background-position)
186	TwoAbsoluteLengths,
187	/// A list of absolute lengths
188	ListOfAbsoluteLengths,
189	/// Computed as specified, but with relative lengths converted to absolute
190	SpecifiedWithAbsoluteLengths,
191	/// Computed as specified, but with relative URLs converted to absolute
192	SpecifiedWithAbsoluteUrls,
193	/// Special computation rules - see spec
194	SeeIndividualProperties,
195	/// Computed value calculation is complex or spec-specific
196	Complex,
197	/// Not yet categorized
198	Unknown,
199}
200
201/// Which side(s) of the box a property applies to.
202/// This is a bitmask so properties can apply to multiple sides.
203#[bitmask(u8)]
204#[bitmask_config(vec_debug)]
205#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
206pub enum BoxSide {
207	/// Applies to the physical top side
208	Top,
209	/// Applies to the physical bottom side
210	Bottom,
211	/// Applies to the physical left side
212	Left,
213	/// Applies to the physical right side
214	Right,
215	/// Applies to the logical block-start side
216	BlockStart,
217	/// Applies to the logical block-end side
218	BlockEnd,
219	/// Applies to the logical inline-start side
220	InlineStart,
221	/// Applies to the logical inline-end side
222	InlineEnd,
223}
224
225/// Which portion(s) of the box model a property affects.
226/// This is a bitmask so properties can affect multiple portions.
227#[bitmask(u8)]
228#[bitmask_config(vec_debug)]
229#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
230pub enum BoxPortion {
231	/// Affects the content size (width/height)
232	Size,
233	/// Affects the margin area
234	Margin,
235	/// Affects the padding area
236	Padding,
237	/// Affects the border area
238	Border,
239	/// Affects the position/placement of the box
240	Position,
241}
242
243pub trait DeclarationMetadata: PartialEq + Sized + Clone {
244	/// Returns the initial value of this property, as a string
245	fn initial() -> &'static str;
246
247	/// Determines if this style value inherits from parent rules
248	fn inherits() -> Inherits {
249		// Most properties do not inherit, so this is a sensible default
250		Inherits::False
251	}
252
253	/// Determines what types of frames this rule applies to
254	fn applies_to() -> AppliesTo {
255		AppliesTo::none()
256	}
257
258	/// Determines how this style value resolves percentages, if they are allowed as values
259	fn percentages() -> Percentages {
260		Percentages::None
261	}
262
263	/// Returns how this style value animates
264	fn animation_type() -> AnimationType {
265		// Most properties do not animate, so this is a sensible default
266		AnimationType::None
267	}
268
269	/// Determines if this style value is a "shorthand" value, meaning it is comprised of other "longhand" style values.
270	fn is_shorthand() -> bool {
271		false
272	}
273
274	/// Determines if this style value is a "longhand" value, meaning a "shorthand" style value exists that could also
275	/// express this.
276	fn is_longhand() -> bool {
277		Self::shorthand_group() == CssAtomSet::_None
278	}
279
280	/// Returns the declaration ID of the shorthand that this property is part of.
281	/// If this is not a longhand then it will be `CssAtomSet::_None`.
282	fn shorthand_group() -> CssAtomSet {
283		CssAtomSet::_None
284	}
285
286	/// Returns which CSS specification(s) this property belongs to.
287	/// This allows tracking which CSS modules are used in a stylesheet.
288	fn property_group() -> PropertyGroup {
289		PropertyGroup::none()
290	}
291
292	/// Returns how the computed value is calculated from the specified value.
293	fn computed_value_type() -> ComputedValueType {
294		ComputedValueType::Unknown
295	}
296
297	/// Returns the canonical order for serialization (e.g., "per grammar", "unique").
298	/// Returns None if not specified or not applicable.
299	fn canonical_order() -> Option<&'static str> {
300		None
301	}
302
303	/// Returns the logical property group this property belongs to (e.g., "Margin", "Border").
304	/// This groups related logical/physical properties together.
305	/// Returns None if this is not part of a logical property group.
306	fn logical_property_group() -> Option<CssAtomSet> {
307		None
308	}
309
310	/// Returns which side(s) of the box this property applies to.
311	/// For example, `margin-top` returns BoxSide::Top, while `margin` returns all sides.
312	/// Returns BoxSide::none() if the property doesn't apply to a specific side.
313	fn box_side() -> BoxSide {
314		BoxSide::none()
315	}
316
317	/// Returns which portion(s) of the box model this property affects.
318	/// For example, `margin-top` returns BoxPortion::Margin, `border-width` returns BoxPortion::Border.
319	/// Returns BoxPortion::none() if the property doesn't affect the box model.
320	fn box_portion() -> BoxPortion {
321		BoxPortion::none()
322	}
323}