css_ast/selector/
moz.rs

1use crate::{CssAtomSet, CssDiagnostic, DirValue};
2use css_parse::{
3	Cursor, Diagnostic, Parse, Parser, Result as ParserResult, T, pseudo_class, pseudo_element, syntax::CommaSeparated,
4};
5use csskit_derives::{Parse, Peek, SemanticEq, ToCursors, ToSpan};
6
7pseudo_element!(
8	/// https://developer.mozilla.org/en-US/docs/Web/CSS/Mozilla_Extensions#pseudo-elements_and_pseudo-classes
9	#[derive(ToCursors, ToSpan, SemanticEq, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
10	#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
11	#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
12#[derive(csskit_derives::NodeWithMetadata)]
13	pub enum MozPseudoElement {
14		AnonymousBlock: CssAtomSet::_MozAnonymousBlock,
15		AnonymousItem: CssAtomSet::_MozAnonymousItem,
16		AnonymousPositionedBlock: CssAtomSet::_MozAnonymousPositionedBlock,
17		BlockInsideInlineWrapper: CssAtomSet::_MozBlockInsideInlineWrapper,
18		BlockRubyContent: CssAtomSet::_MozBlockRubyContent,
19		ButtonContent: CssAtomSet::_MozButtonContent,
20		Canvas: CssAtomSet::_MozCanvas,
21		CellContent: CssAtomSet::_MozCellContent,
22		ColorSwatch: CssAtomSet::_MozColorSwatch,
23		ColumnContent: CssAtomSet::_MozColumnContent,
24		ColumnSet: CssAtomSet::_MozColumnSet,
25		ColumnSpanWrapper: CssAtomSet::_MozColumnSpanWrapper,
26		DropdownList: CssAtomSet::_MozDropdownList,
27		FieldsetContent: CssAtomSet::_MozFieldsetContent,
28		FirstLetterContinuation: CssAtomSet::_MozFirstLetterContinuation,
29		FocusInner: CssAtomSet::_MozFocusInner,
30		FocusOuter: CssAtomSet::_MozFocusOuter,
31		FramesetBlank: CssAtomSet::_MozFramesetBlank,
32		HframesetBorder: CssAtomSet::_MozHframesetBorder,
33		HtmlCanvasContent: CssAtomSet::_MozHtmlCanvasContent,
34		InlineTable: CssAtomSet::_MozInlineTable,
35		LineFrame: CssAtomSet::_MozLineFrame,
36		ListBullet: CssAtomSet::_MozListBullet,
37		ListNumber: CssAtomSet::_MozListNumber,
38		MathmlAnonymousBlock: CssAtomSet::_MozMathmlAnonymousBlock,
39		NumberSpinBox: CssAtomSet::_MozNumberSpinBox,
40		NumberSpinDown: CssAtomSet::_MozNumberSpinDown,
41		NumberSpinUp: CssAtomSet::_MozNumberSpinUp,
42		OofPlaceholder: CssAtomSet::_MozOofPlaceholder,
43		Page: CssAtomSet::_MozPage,
44		PageBreak: CssAtomSet::_MozPageBreak,
45		PageContent: CssAtomSet::_MozPageContent,
46		PageSequence: CssAtomSet::_MozPageSequence,
47		Pagebreak: CssAtomSet::_MozPagebreak,
48		Pagecontent: CssAtomSet::_MozPagecontent,
49		Placeholder: CssAtomSet::_MozPlaceholder,
50		PrintedSheet: CssAtomSet::_MozPrintedSheet,
51		ProgressBar: CssAtomSet::_MozProgressBar,
52		RangeProgress: CssAtomSet::_MozRangeProgress,
53		RangeThumb: CssAtomSet::_MozRangeThumb,
54		RangeTrack: CssAtomSet::_MozRangeTrack,
55		Reveal: CssAtomSet::_MozReveal,
56		Ruby: CssAtomSet::_MozRuby,
57		RubyBase: CssAtomSet::_MozRubyBase,
58		RubyBaseContainer: CssAtomSet::_MozRubyBaseContainer,
59		RubyText: CssAtomSet::_MozRubyText,
60		RubyTextContainer: CssAtomSet::_MozRubyTextContainer,
61		ScrolledCanvas: CssAtomSet::_MozScrolledCanvas,
62		ScrolledContent: CssAtomSet::_MozScrolledContent,
63		ScrolledPageSequence: CssAtomSet::_MozScrolledPageSequence,
64		SearchClearButton: CssAtomSet::_MozSearchClearButton,
65		Selection: CssAtomSet::_MozSelection,
66		SvgForeignContent: CssAtomSet::_MozSvgForeignContent,
67		SvgMarkerAnonChild: CssAtomSet::_MozSvgMarkerAnonChild,
68		SvgMarkerOuterSvgAnonChild: CssAtomSet::_MozSvgMarkerOuterSvgAnonChild,
69		SvgText: CssAtomSet::_MozSvgText,
70		Table: CssAtomSet::_MozTable,
71		TableCell: CssAtomSet::_MozTableCell,
72		TableColumn: CssAtomSet::_MozTableColumn,
73		TableColumnGroup: CssAtomSet::_MozTableColumnGroup,
74		TableOuter: CssAtomSet::_MozTableOuter,
75		TableRow: CssAtomSet::_MozTableRow,
76		TableRowGroup: CssAtomSet::_MozTableRowGroup,
77		TableWrapper: CssAtomSet::_MozTableWrapper,
78		TextControlEditingRoot: CssAtomSet::_MozTextControlEditingRoot,
79		TextControlPreview: CssAtomSet::_MozTextControlPreview,
80		TreeCell: CssAtomSet::_MozTreeCell,
81		TreeCheckbox: CssAtomSet::_MozTreeCheckbox,
82		TreeDropFeedback: CssAtomSet::_MozTreeDropFeedback,
83		TreeIndentation: CssAtomSet::_MozTreeIndentation,
84		TreeSeparator: CssAtomSet::_MozTreeSeparator,
85		VframesetBorder: CssAtomSet::_MozVframesetBorder,
86		Viewport: CssAtomSet::_MozViewport,
87		ViewportScroll: CssAtomSet::_MozViewportScroll,
88	}
89);
90
91#[derive(ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
92#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
93#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
94#[derive(csskit_derives::NodeWithMetadata)]
95pub enum MozFunctionalPseudoElement<'a> {
96	TreeCell(T![::], T![Function], CommaSeparated<'a, T![Ident]>, T![')']),
97	TreeCellText(T![::], T![Function], CommaSeparated<'a, T![Ident]>, T![')']),
98	TreeCheckbox(T![::], T![Function], CommaSeparated<'a, T![Ident]>, T![')']),
99	TreeColumn(T![::], T![Function], CommaSeparated<'a, T![Ident]>, T![')']),
100	TreeImage(T![::], T![Function], CommaSeparated<'a, T![Ident]>, T![')']),
101	TreeLine(T![::], T![Function], CommaSeparated<'a, T![Ident]>, T![')']),
102	TreeRow(T![::], T![Function], CommaSeparated<'a, T![Ident]>, T![')']),
103	TreeSeparator(T![::], T![Function], CommaSeparated<'a, T![Ident]>, T![')']),
104	TreeTwisty(T![::], T![Function], CommaSeparated<'a, T![Ident]>, T![')']),
105}
106
107#[derive(Parse, Peek, ToCursors, ToSpan, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
108#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
109#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(skip))]
110#[derive(csskit_derives::NodeWithMetadata)]
111pub enum MozFunctionalPseudoElementKeyword {
112	#[atom(CssAtomSet::_MozTreeCell)]
113	TreeCell(T![Function]),
114	#[atom(CssAtomSet::_MozTreeCellText)]
115	TreeCellText(T![Function]),
116	#[atom(CssAtomSet::_MozTreeCheckbox)]
117	TreeCheckbox(T![Function]),
118	#[atom(CssAtomSet::_MozTreeColumn)]
119	TreeColumn(T![Function]),
120	#[atom(CssAtomSet::_MozTreeImage)]
121	TreeImage(T![Function]),
122	#[atom(CssAtomSet::_MozTreeLine)]
123	TreeLine(T![Function]),
124	#[atom(CssAtomSet::_MozTreeRow)]
125	TreeRow(T![Function]),
126	#[atom(CssAtomSet::_MozTreeSeparator)]
127	TreeSeparator(T![Function]),
128	#[atom(CssAtomSet::_MozTreeTwisty)]
129	TreeTwisty(T![Function]),
130}
131
132impl<'a> Parse<'a> for MozFunctionalPseudoElement<'a> {
133	fn parse<I>(p: &mut Parser<'a, I>) -> ParserResult<Self>
134	where
135		I: Iterator<Item = Cursor> + Clone,
136	{
137		let colons = p.parse::<T![::]>()?;
138		let keyword = p.parse::<MozFunctionalPseudoElementKeyword>()?;
139		let items = p.parse::<CommaSeparated<'a, T![Ident]>>()?;
140		let close = p.parse::<T![')']>()?;
141		Ok(match keyword {
142			MozFunctionalPseudoElementKeyword::TreeCell(function) => Self::TreeCell(colons, function, items, close),
143			MozFunctionalPseudoElementKeyword::TreeCellText(function) => {
144				Self::TreeCellText(colons, function, items, close)
145			}
146			MozFunctionalPseudoElementKeyword::TreeCheckbox(function) => {
147				Self::TreeCheckbox(colons, function, items, close)
148			}
149			MozFunctionalPseudoElementKeyword::TreeColumn(function) => Self::TreeColumn(colons, function, items, close),
150			MozFunctionalPseudoElementKeyword::TreeImage(function) => Self::TreeImage(colons, function, items, close),
151			MozFunctionalPseudoElementKeyword::TreeLine(function) => Self::TreeLine(colons, function, items, close),
152			MozFunctionalPseudoElementKeyword::TreeRow(function) => Self::TreeRow(colons, function, items, close),
153			MozFunctionalPseudoElementKeyword::TreeSeparator(function) => {
154				Self::TreeSeparator(colons, function, items, close)
155			}
156			MozFunctionalPseudoElementKeyword::TreeTwisty(function) => Self::TreeTwisty(colons, function, items, close),
157		})
158	}
159}
160
161pseudo_class!(
162	/// <https://developer.mozilla.org/en-US/docs/Web/CSS/Mozilla_Extensions#pseudo-elements_and_pseudo-classes>
163	#[derive(ToCursors, ToSpan, SemanticEq, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
164	#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
165	#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
166#[derive(csskit_derives::NodeWithMetadata)]
167	pub enum MozPseudoClass {
168		Any: CssAtomSet::_MozAny,
169		AnyLink: CssAtomSet::_MozAnyLink,
170		Broken: CssAtomSet::_MozBroken,
171		DragOver: CssAtomSet::_MozDragOver,
172		FirstNode: CssAtomSet::_MozFirstNode,
173		FocusRing: CssAtomSet::_MozFocusring,
174		FullScreen: CssAtomSet::_MozFullScreen,
175		FullScreenAncestor: CssAtomSet::_MozFullScreenAncestor,
176		HandlerBlocked: CssAtomSet::_MozHandlerBlocked,
177		HandlerCrashed: CssAtomSet::_MozHandlerCrashed,
178		HandlerDisabled: CssAtomSet::_MozHandlerDisabled,
179		LastNode: CssAtomSet::_MozLastNode,
180		Loading: CssAtomSet::_MozLoading,
181		LwTheme: CssAtomSet::_MozLwtheme,
182		LwThemeBrighttext: CssAtomSet::_MozLwthemeBrighttext,
183		LwThemeDarktext: CssAtomSet::_MozLwthemeDarktext,
184		NativeAnonymous: CssAtomSet::_MozNativeAnonymous,
185		OnlyWhitespace: CssAtomSet::_MozOnlyWhitespace,
186		PlaceholderShown: CssAtomSet::_MozPlaceholderShown,
187		ReadOnly: CssAtomSet::_MozReadOnly,
188		ReadWrite: CssAtomSet::_MozReadWrite,
189		SubmitInvalid: CssAtomSet::_MozSubmitInvalid,
190		Suppressed: CssAtomSet::_MozSuppressed,
191		UiInvalid: CssAtomSet::_MozUiInvalid,
192		UiValid: CssAtomSet::_MozUiValid,
193		UserDisabled: CssAtomSet::_MozUserDisabled,
194		WindowInactive: CssAtomSet::_MozWindowInactive,
195	}
196);
197
198#[derive(ToCursors, ToSpan, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
199#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
200#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
201#[derive(csskit_derives::NodeWithMetadata)]
202pub enum MozFunctionalPseudoClass {
203	LocaleDir(MozLocaleDirFunctionalPseudoClass),
204}
205
206impl<'a> Parse<'a> for MozFunctionalPseudoClass {
207	fn parse<I>(p: &mut Parser<'a, I>) -> ParserResult<Self>
208	where
209		I: Iterator<Item = Cursor> + Clone,
210	{
211		let colon = p.parse::<T![:]>()?;
212		let function = p.parse::<T![Function]>()?;
213		let c: Cursor = function.into();
214		if p.equals_atom(c, &CssAtomSet::_MozLocaleDir) {
215			let value = p.parse::<DirValue>()?;
216			let close = p.parse_if_peek::<T![')']>()?;
217			Ok(Self::LocaleDir(MozLocaleDirFunctionalPseudoClass { colon, function, value, close }))
218		} else {
219			Err(Diagnostic::new(c, Diagnostic::unexpected_function))?
220		}
221	}
222}
223
224#[derive(ToCursors, ToSpan, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
225#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
226#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
227#[derive(csskit_derives::NodeWithMetadata)]
228pub struct MozLocaleDirFunctionalPseudoClass {
229	pub colon: T![:],
230	pub function: T![Function],
231	pub value: DirValue,
232	pub close: Option<T![')']>,
233}
234
235#[cfg(test)]
236mod tests {
237	use super::*;
238	use crate::CssAtomSet;
239	use css_parse::assert_parse;
240
241	#[test]
242	fn size_test() {
243		assert_eq!(std::mem::size_of::<MozPseudoElement>(), 40);
244		assert_eq!(std::mem::size_of::<MozFunctionalPseudoElement>(), 88);
245		assert_eq!(std::mem::size_of::<MozPseudoClass>(), 28);
246		assert_eq!(std::mem::size_of::<MozFunctionalPseudoClass>(), 56);
247	}
248
249	#[test]
250	fn test_writes() {
251		assert_parse!(CssAtomSet::ATOMS, MozPseudoElement, "::-moz-anonymous-block");
252		assert_parse!(CssAtomSet::ATOMS, MozFunctionalPseudoElement, "::-moz-tree-twisty(selected,focus)");
253	}
254}