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