1use {
5 super::{
6 DeduplicatedSelectors,
7 LanguageRange,
8 OurSelectorExt,
9 VendorPrefixablePseudoClassName,
10 },
11 crate::{
12 domain::{
13 selectors::{
14 LanguageRanges,
15 OurSelectorImpl,
16 SystemMetric,
17 TextDirectionality,
18 TreeHover,
19 },
20 Atom,
21 VendorPrefix::{self, *},
22 },
23 parsers::OurSelectorParser,
24 CustomParseError,
25 },
26 cssparser::{CowRcStr, ParseError, Parser, ToCss},
27 selectors::parser::NonTSPseudoClass,
28 std::{collections::HashMap, fmt},
29};
30
31#[derive(Clone, Debug, Eq, PartialEq)]
35#[allow(missing_docs)]
36pub enum NonTreeStructuralPseudoClass {
37 active,
38 any(Option<VendorPrefix>, DeduplicatedSelectors),
39 any_link(Option<VendorPrefix>),
40 checked,
41 default,
42 dir(Option<VendorPrefix>, TextDirectionality),
43 disabled,
44 enabled,
45 first,
47 focus,
48 focus_within,
49 in_range,
50 invalid,
51 is(DeduplicatedSelectors),
52 fullscreen(Option<VendorPrefix>),
53 hover,
54 indeterminate,
55 lang(LanguageRanges),
56 left,
58 link,
59 optional,
60 out_of_range,
61 placeholder_shown(Option<VendorPrefix>),
63 read_only(Option<VendorPrefix>),
64 read_write(Option<VendorPrefix>),
65 required,
66 right,
68 target,
69 valid,
70 visited,
71 where_(DeduplicatedSelectors),
72
73 case_sensitive_type_attr(Option<VendorPrefix>, Atom),
75
76 non_zero_border(Option<VendorPrefix>),
78
79 broken(Option<VendorPrefix>),
81
82 drag_over(Option<VendorPrefix>),
84
85 first_node(Option<VendorPrefix>),
87
88 focusring(Option<VendorPrefix>),
90
91 full_screen_ancestor(Option<VendorPrefix>),
93
94 handler_blocked(Option<VendorPrefix>),
96
97 handler_crashed(Option<VendorPrefix>),
99
100 handler_disabled(Option<VendorPrefix>),
102
103 last_node(Option<VendorPrefix>),
105
106 list_bullet(Option<VendorPrefix>),
108
109 list_number(Option<VendorPrefix>),
111
112 loading(Option<VendorPrefix>),
114
115 locale_dir(Option<VendorPrefix>, TextDirectionality),
117
118 lwtheme(Option<VendorPrefix>),
120
121 lwtheme_brighttext(Option<VendorPrefix>),
123
124 lwtheme_darktext(Option<VendorPrefix>),
126
127 native_anonymous(Option<VendorPrefix>),
129
130 only_whitespace(Option<VendorPrefix>),
132
133 submit_invalid(Option<VendorPrefix>),
135
136 suppressed(Option<VendorPrefix>),
138
139 system_metric(Option<VendorPrefix>, SystemMetric),
141
142 tree_cell(Option<VendorPrefix>),
144
145 tree_cell_text(Option<VendorPrefix>, TreeHover),
148
149 tree_checkbox(Option<VendorPrefix>),
151
152 tree_column(Option<VendorPrefix>),
154
155 tree_drop_feedback(Option<VendorPrefix>),
157
158 tree_image(Option<VendorPrefix>),
160
161 tree_indentation(Option<VendorPrefix>),
163
164 tree_line(Option<VendorPrefix>),
166
167 tree_progressmeter(Option<VendorPrefix>),
169
170 tree_row(Option<VendorPrefix>, TreeHover),
173
174 tree_separator(Option<VendorPrefix>),
176
177 tree_twisty(Option<VendorPrefix>),
179
180 ui_invalid(Option<VendorPrefix>),
182
183 ui_valid(Option<VendorPrefix>),
185
186 user_disabled(Option<VendorPrefix>),
188
189 window_inactive(Option<VendorPrefix>),
191
192 autofill(Option<VendorPrefix>),
194}
195
196impl NonTSPseudoClass for NonTreeStructuralPseudoClass {
197 type Impl = OurSelectorImpl;
198
199 fn is_active_or_hover(&self) -> bool {
200 matches!(self, Self::active | Self::hover)
201 }
202
203 fn is_user_action_state(&self) -> bool {
204 matches!(
205 self,
206 Self::active
207 | Self::hover
208 | Self::visited
209 | Self::link
210 | Self::focus
211 )
212 }
213}
214
215impl ToCss for NonTreeStructuralPseudoClass {
216 fn to_css<W: fmt::Write>(&self, dest: &mut W) -> fmt::Result {
218 #[inline(always)]
219 fn write<W: fmt::Write>(
220 dest: &mut W,
221 classWithColon: &str,
222 ) -> fmt::Result {
223 dest.write_str(classWithColon)
224 }
225
226 #[inline(always)]
227 fn write_with_vendor_prefix<W: fmt::Write>(
228 dest: &mut W,
229 vendorPrefix: &Option<VendorPrefix>,
230 classWithoutColon: &str,
231 ) -> fmt::Result {
232 dest.write_char(':')?;
233 if let &Some(ref vendorPrefix) = vendorPrefix {
234 vendorPrefix.to_css(dest)?;
235 }
236 dest.write_str(classWithoutColon)
237 }
238
239 #[inline(always)]
240 fn write_with_vendor_prefix_value<W: fmt::Write, T: ToCss>(
241 dest: &mut W,
242 vendorPrefix: &Option<VendorPrefix>,
243 classWithoutColon: &str,
244 value: &T,
245 ) -> fmt::Result {
246 dest.write_char(':')?;
247 if let &Some(ref vendorPrefix) = vendorPrefix {
248 vendorPrefix.to_css(dest)?;
249 }
250 dest.write_str(classWithoutColon)?;
251 dest.write_char('(')?;
252 value.to_css(dest)?;
253 dest.write_char(')')
254 }
255
256 #[inline(always)]
257 fn write_with_value<W: fmt::Write, T: ToCss>(
258 dest: &mut W,
259 classWithoutColon: &str,
260 value: &T,
261 ) -> fmt::Result {
262 dest.write_char(':')?;
263 dest.write_str(classWithoutColon)?;
264 dest.write_char('(')?;
265 value.to_css(dest)?;
266 dest.write_char(')')
267 }
268
269 match &*self {
270 Self::active => write(dest, ":active"),
271
272 Self::any(ref vendorPrefix, ref value) => {
273 write_with_vendor_prefix_value(dest, vendorPrefix, "any", value)
274 }
275
276 Self::any_link(ref vendorPrefix) => {
277 write_with_vendor_prefix(dest, vendorPrefix, "any-link")
278 }
279
280 Self::checked => write(dest, ":checked"),
281
282 Self::default => write(dest, ":default"),
283
284 Self::disabled => write(dest, ":disabled"),
285
286 Self::dir(ref vendorPrefix, ref value) => {
287 write_with_vendor_prefix_value(dest, vendorPrefix, "dir", value)
288 }
289
290 Self::enabled => write(dest, ":enabled"),
291
292 Self::first => write(dest, ":first"),
293
294 Self::focus => write(dest, ":focus"),
295
296 Self::focus_within => write(dest, ":focus-within"),
297
298 Self::fullscreen(ref vendorPrefix) => {
299 dest.write_char(':')?;
300 let name = if let &Some(ref vendorPrefix) = vendorPrefix {
301 vendorPrefix.to_css(dest)?;
302
303 match *vendorPrefix {
304 moz => "full-screen",
305 webkit => "full-screen",
306 _ => "fullscreen",
307 }
308 } else {
309 "fullscreen"
310 };
311 dest.write_str(name)
312 }
313
314 Self::hover => write(dest, ":hover"),
315
316 Self::indeterminate => write(dest, ":indeterminate"),
317
318 Self::in_range => write(dest, ":in-range"),
319
320 Self::invalid => write(dest, ":invalid"),
321
322 Self::is(ref value) => write_with_value(dest, "is", value),
323
324 Self::lang(ref languages) => {
325 dest.write_str(":lang(")?;
326 languages.to_css(dest)?;
327 dest.write_char(')')
328 }
329
330 Self::left => write(dest, ":left"),
331
332 Self::link => write(dest, ":link"),
333
334 Self::optional => write(dest, ":optional"),
335
336 Self::out_of_range => write(dest, ":out-of-range"),
337
338 Self::placeholder_shown(ref vendorPrefix) => {
339 write_with_vendor_prefix(
340 dest,
341 vendorPrefix,
342 "placeholder-shown",
343 )
344 }
345
346 Self::read_only(ref vendorPrefix) => {
347 write_with_vendor_prefix(dest, vendorPrefix, "read-only")
348 }
349
350 Self::read_write(ref vendorPrefix) => {
351 write_with_vendor_prefix(dest, vendorPrefix, "read-write")
352 }
353
354 Self::required => write(dest, ":required"),
355
356 Self::right => write(dest, ":right"),
357
358 Self::target => write(dest, ":target"),
359
360 Self::valid => write(dest, ":valid"),
361
362 Self::visited => write(dest, ":visited"),
363
364 Self::where_(ref value) => write_with_value(dest, "where", value),
365
366 Self::case_sensitive_type_attr(ref vendorPrefix, ref value) => {
368 write_with_vendor_prefix_value(
369 dest,
370 vendorPrefix,
371 "case-sensitive-type-attr",
372 value,
373 )
374 }
375
376 Self::non_zero_border(ref vendorPrefix) => {
377 write_with_vendor_prefix(dest, vendorPrefix, "non-zero-border")
378 }
379
380 Self::broken(ref vendorPrefix) => {
382 write_with_vendor_prefix(dest, vendorPrefix, "broken")
383 }
384
385 Self::drag_over(ref vendorPrefix) => {
386 write_with_vendor_prefix(dest, vendorPrefix, "drag-over")
387 }
388
389 Self::first_node(ref vendorPrefix) => {
390 write_with_vendor_prefix(dest, vendorPrefix, "first-node")
391 }
392
393 Self::focusring(ref vendorPrefix) => {
394 write_with_vendor_prefix(dest, vendorPrefix, "focusring")
395 }
396
397 Self::full_screen_ancestor(ref vendorPrefix) => {
398 write_with_vendor_prefix(
399 dest,
400 vendorPrefix,
401 "full-screen-ancestor",
402 )
403 }
404
405 Self::handler_blocked(ref vendorPrefix) => {
406 write_with_vendor_prefix(dest, vendorPrefix, "handler-blocked")
407 }
408
409 Self::handler_crashed(ref vendorPrefix) => {
410 write_with_vendor_prefix(dest, vendorPrefix, "handler-crashed")
411 }
412
413 Self::handler_disabled(ref vendorPrefix) => {
414 write_with_vendor_prefix(dest, vendorPrefix, "handler-disabled")
415 }
416
417 Self::last_node(ref vendorPrefix) => {
418 write_with_vendor_prefix(dest, vendorPrefix, "last-node")
419 }
420
421 Self::list_bullet(ref vendorPrefix) => {
422 write_with_vendor_prefix(dest, vendorPrefix, "list-bullet")
423 }
424
425 Self::list_number(ref vendorPrefix) => {
426 write_with_vendor_prefix(dest, vendorPrefix, "list-number")
427 }
428
429 Self::loading(ref vendorPrefix) => {
430 write_with_vendor_prefix(dest, vendorPrefix, "loading")
431 }
432
433 Self::locale_dir(ref vendorPrefix, ref value) => {
434 write_with_vendor_prefix_value(
435 dest,
436 vendorPrefix,
437 "locale-dir",
438 value,
439 )
440 }
441
442 Self::lwtheme(ref vendorPrefix) => {
443 write_with_vendor_prefix(dest, vendorPrefix, "lwtheme")
444 }
445
446 Self::lwtheme_brighttext(ref vendorPrefix) => {
447 write_with_vendor_prefix(
448 dest,
449 vendorPrefix,
450 "lwtheme-brighttext",
451 )
452 }
453
454 Self::lwtheme_darktext(ref vendorPrefix) => {
455 write_with_vendor_prefix(dest, vendorPrefix, "lwtheme-darktext")
456 }
457
458 Self::native_anonymous(ref vendorPrefix) => {
459 write_with_vendor_prefix(dest, vendorPrefix, "native-anonymous")
460 }
461
462 Self::only_whitespace(ref vendorPrefix) => {
463 write_with_vendor_prefix(dest, vendorPrefix, "only-whitespace")
464 }
465
466 Self::submit_invalid(ref vendorPrefix) => {
467 write_with_vendor_prefix(dest, vendorPrefix, "submit-invalid")
468 }
469
470 Self::suppressed(ref vendorPrefix) => {
471 write_with_vendor_prefix(dest, vendorPrefix, "suppressed")
472 }
473
474 Self::system_metric(ref vendorPrefix, ref value) => {
475 write_with_vendor_prefix_value(
476 dest,
477 vendorPrefix,
478 "system-metric",
479 value,
480 )
481 }
482
483 Self::tree_cell(ref vendorPrefix) => {
484 write_with_vendor_prefix(dest, vendorPrefix, "tree-cell")
485 }
486
487 Self::tree_cell_text(ref vendorPrefix, ref value) => {
488 write_with_vendor_prefix_value(
489 dest,
490 vendorPrefix,
491 "tree-cell-text",
492 value,
493 )
494 }
495
496 Self::tree_checkbox(ref vendorPrefix) => {
497 write_with_vendor_prefix(dest, vendorPrefix, "tree-checkbox")
498 }
499
500 Self::tree_column(ref vendorPrefix) => {
501 write_with_vendor_prefix(dest, vendorPrefix, "tree-column")
502 }
503
504 Self::tree_drop_feedback(ref vendorPrefix) => {
505 write_with_vendor_prefix(
506 dest,
507 vendorPrefix,
508 "tree-drop-feedback",
509 )
510 }
511
512 Self::tree_image(ref vendorPrefix) => {
513 write_with_vendor_prefix(dest, vendorPrefix, "tree-image")
514 }
515
516 Self::tree_indentation(ref vendorPrefix) => {
517 write_with_vendor_prefix(dest, vendorPrefix, "tree-indentation")
518 }
519
520 Self::tree_line(ref vendorPrefix) => {
521 write_with_vendor_prefix(dest, vendorPrefix, "tree-line")
522 }
523
524 Self::tree_progressmeter(ref vendorPrefix) => {
525 write_with_vendor_prefix(
526 dest,
527 vendorPrefix,
528 "tree-progressmeter",
529 )
530 }
531
532 Self::tree_row(ref vendorPrefix, ref value) => {
533 write_with_vendor_prefix_value(
534 dest,
535 vendorPrefix,
536 "tree-row",
537 value,
538 )
539 }
540
541 Self::tree_separator(ref vendorPrefix) => {
542 write_with_vendor_prefix(dest, vendorPrefix, "tree-separator")
543 }
544
545 Self::tree_twisty(ref vendorPrefix) => {
546 write_with_vendor_prefix(dest, vendorPrefix, "tree-twisty")
547 }
548
549 Self::ui_invalid(ref vendorPrefix) => {
550 write_with_vendor_prefix(dest, vendorPrefix, "ui-invalid")
551 }
552
553 Self::ui_valid(ref vendorPrefix) => {
554 write_with_vendor_prefix(dest, vendorPrefix, "ui-valid")
555 }
556
557 Self::user_disabled(ref vendorPrefix) => {
558 write_with_vendor_prefix(dest, vendorPrefix, "user-disabled")
559 }
560
561 Self::window_inactive(ref vendorPrefix) => {
562 write_with_vendor_prefix(dest, vendorPrefix, "window-inactive")
563 }
564
565 Self::autofill(ref vendorPrefix) => {
566 write_with_vendor_prefix(dest, vendorPrefix, "autofill")
567 }
568 }
569 }
570}
571
572impl NonTreeStructuralPseudoClass {
573 pub fn is_attr_based(&self) -> bool {
575 use self::NonTreeStructuralPseudoClass::*;
576
577 matches!(*self, lang(..))
578 }
579
580 pub fn is_safe_user_action_state(&self) -> bool {
584 use self::NonTreeStructuralPseudoClass::*;
585
586 matches!(*self, active | focus | hover)
587 }
588
589 #[inline(always)]
590 fn applyVendorPrefix(
591 pseudoClassName: VendorPrefixablePseudoClassName,
592 applyVendorPrefixToPseudoClasses: &HashMap<
593 VendorPrefixablePseudoClassName,
594 VendorPrefix,
595 >,
596 ) -> Option<VendorPrefix> {
597 applyVendorPrefixToPseudoClasses
598 .get(&pseudoClassName)
599 .cloned()
600 }
601
602 #[inline(always)]
604 pub(crate) fn parse_without_arguments<'i>(
605 applyVendorPrefixToPseudoClasses: &HashMap<
606 VendorPrefixablePseudoClassName,
607 VendorPrefix,
608 >,
609 name: CowRcStr<'i>,
610 ) -> Result<Self, ParseError<'i, CustomParseError<'i>>> {
611 match_ignore_ascii_case! {
612 &name,
613
614 "active" => Ok(Self::active),
615
616 "any-link" => Ok(Self::any_link(Self::applyVendorPrefix(VendorPrefixablePseudoClassName::any_link, applyVendorPrefixToPseudoClasses))),
617
618 "-moz-any-link" => Ok(Self::any_link(Some(moz))),
619
620 "-webkit-any-link" => Ok(Self::any_link(Some(webkit))),
621
622 "checked" => Ok(Self::checked),
623
624 "default" => Ok(Self::default),
625
626 "disabled" => Ok(Self::disabled),
627
628 "enabled" => Ok(Self::enabled),
629
630 "first" => Ok(Self::first),
631
632 "focus" => Ok(Self::focus),
633
634 "focus-within" => Ok(Self::focus_within),
635
636 "fullscreen" => Ok(Self::fullscreen(Self::applyVendorPrefix(VendorPrefixablePseudoClassName::fullscreen, applyVendorPrefixToPseudoClasses))),
637
638 "-ms-fullscreen" => Ok(Self::fullscreen(Some(ms))),
639
640 "-moz-full-screen" => Ok(Self::fullscreen(Some(moz))),
641
642 "-webkit-full-screen" => Ok(Self::fullscreen(Some(webkit))),
643
644 "hover" => Ok(Self::hover),
645
646 "indeterminate" => Ok(Self::indeterminate),
647
648 "in-range" => Ok(Self::in_range),
649
650 "invalid" => Ok(Self::invalid),
651
652 "left" => Ok(Self::left),
653
654 "link" => Ok(Self::link),
655
656 "optional" => Ok(Self::optional),
657
658 "out-of-range" => Ok(Self::out_of_range),
659
660 "placeholder-shown" => Ok(Self::placeholder_shown(Self::applyVendorPrefix(VendorPrefixablePseudoClassName::placeholder_shown, applyVendorPrefixToPseudoClasses))),
661
662 "-moz-placeholder-shown" => Ok(Self::placeholder_shown(Some(moz))),
663
664 "-moz-placeholder" => Ok(Self::placeholder_shown(Self::applyVendorPrefix(VendorPrefixablePseudoClassName::placeholder_shown, applyVendorPrefixToPseudoClasses))),
666
667 "read-only" => Ok(Self::read_only(Self::applyVendorPrefix(VendorPrefixablePseudoClassName::read_only, applyVendorPrefixToPseudoClasses))),
668
669 "-moz-read-only" => Ok(Self::read_only(Some(moz))),
670
671 "read-write" => Ok(Self::read_write(Self::applyVendorPrefix(VendorPrefixablePseudoClassName::read_write, applyVendorPrefixToPseudoClasses))),
672
673 "-moz-read-write" => Ok(Self::read_write(Some(moz))),
674
675 "required" => Ok(Self::required),
676
677 "right" => Ok(Self::right),
678
679 "scope" => Err(ParseError::from(CustomParseError::NonTreeStructuralPseudoClassScopeIsObsoleteAsOfFirefox55)),
680
681 "target" => Ok(Self::target),
682
683 "valid" => Ok(Self::valid),
684
685 "visited" => Ok(Self::visited),
686
687
688 "-servo-non-zero-border" => Ok(Self::non_zero_border(Some(servo))),
691
692
693 "-moz-broken" => Ok(Self::broken(Some(moz))),
696
697 "-moz-drag-over" => Ok(Self::drag_over(Some(moz))),
698
699 "-moz-first-node" => Ok(Self::first_node(Some(moz))),
700
701 "-moz-focusring" => Ok(Self::focusring(Some(moz))),
702
703 "-moz-full-screen-ancestor" => Ok(Self::full_screen_ancestor(Some(moz))),
704
705 "-moz-handler-blocked" => Ok(Self::handler_blocked(Some(moz))),
706
707 "-moz-handler-crashed" => Ok(Self::handler_crashed(Some(moz))),
708
709 "-moz-handler-disabled" => Ok(Self::handler_disabled(Some(moz))),
710
711 "-moz-last-node" => Ok(Self::last_node(Some(moz))),
712
713 "-moz-list-bullet" => Ok(Self::list_bullet(Some(moz))),
714
715 "-moz-list-number" => Ok(Self::list_number(Some(moz))),
716
717 "-moz-loading" => Ok(Self::loading(Some(moz))),
718
719 "-moz-lwtheme" => Ok(Self::lwtheme(Some(moz))),
720
721 "-moz-lwtheme-brighttext" => Ok(Self::lwtheme_brighttext(Some(moz))),
722
723 "-moz-lwtheme-darktext" => Ok(Self::lwtheme_darktext(Some(moz))),
724
725 "-moz-native-anonymous" => Ok(Self::native_anonymous(Some(moz))),
726
727 "-moz-only-whitespace" => Ok(Self::only_whitespace(Some(moz))),
728
729 "-moz-submit-invalid" => Ok(Self::submit_invalid(Some(moz))),
730
731 "-moz-suppressed" => Ok(Self::suppressed(Some(moz))),
732
733 "-moz-tree-cell" => Ok(Self::tree_cell(Some(moz))),
734
735 "-moz-tree-checkbox" => Ok(Self::tree_checkbox(Some(moz))),
736
737 "-moz-tree-column" => Ok(Self::tree_column(Some(moz))),
738
739 "-moz-tree-drop-feedback" => Ok(Self::tree_drop_feedback(Some(moz))),
740
741 "-moz-tree-image" => Ok(Self::tree_image(Some(moz))),
742
743 "-moz-tree-indentation" => Ok(Self::tree_indentation(Some(moz))),
744
745 "-moz-tree-line" => Ok(Self::tree_line(Some(moz))),
746
747 "-moz-tree-progressmeter" => Ok(Self::tree_progressmeter(Some(moz))),
748
749 "-moz-tree-separator" => Ok(Self::tree_separator(Some(moz))),
750
751 "-moz-tree-twisty" => Ok(Self::tree_twisty(Some(moz))),
752
753 "-moz-ui-invalid" => Ok(Self::ui_invalid(Some(moz))),
754
755 "-moz-ui-valid" => Ok(Self::ui_valid(Some(moz))),
756
757 "-moz-user-disabled" => Ok(Self::user_disabled(Some(moz))),
758
759 "-moz-window-inactive" => Ok(Self::window_inactive(Some(moz))),
760
761
762 "-webkit-autofill" => Ok(Self::autofill(Some(webkit))),
765
766 "-moz-autofill" => Ok(Self::autofill(Some(moz))),
767
768
769 _ => Err(ParseError::from(CustomParseError::UnsupportedPseudoClassOrElement(name.to_string()))),
770 }
771 }
772
773 #[inline(always)]
774 pub(crate) fn parse_with_arguments<'i, 't>(
775 applyVendorPrefixToPseudoClasses: &HashMap<
776 VendorPrefixablePseudoClassName,
777 VendorPrefix,
778 >,
779 name: CowRcStr<'i>,
780 input: &mut Parser<'i, 't>,
781 ourSelectorParser: &OurSelectorParser,
782 ) -> Result<Self, ParseError<'i, CustomParseError<'i>>> {
783 use self::{NonTreeStructuralPseudoClass::*, VendorPrefix::*};
784
785 match_ignore_ascii_case! {
786 &name,
787
788 "any" => Ok(any(Self::applyVendorPrefix(VendorPrefixablePseudoClassName::any, applyVendorPrefixToPseudoClasses), Self::parse_any(input, ourSelectorParser)?)),
789
790 "-moz-any" => Ok(any(Some(moz), Self::parse_any(input, ourSelectorParser)?)),
791
792 "-webkit-any" => Ok(any(Some(webkit), Self::parse_any(input, ourSelectorParser)?)),
793
794 "dir" => Ok(dir(Self::applyVendorPrefix(VendorPrefixablePseudoClassName::dir, applyVendorPrefixToPseudoClasses), Self::parse_text_directionality(input)?)),
795
796 "-moz-dir" => Ok(dir(Some(moz), Self::parse_text_directionality(input)?)),
797
798 "lang" => Ok(lang(Self::parse_lang(input)?)),
799
800 "where" => Ok(Self::where_(ourSelectorParser.parse_internal(input, OurSelectorExt::is_false_if_any_selector_is_simple_and_only_uses_the_descendant_combinator)?)),
801
802 "is" => Ok(Self::is(ourSelectorParser.parse_internal(input, OurSelectorExt::is_false_if_any_selector_is_simple_and_only_uses_the_descendant_combinator)?)),
803
804 "-servo-case-sensitive-type-attr" => Ok(case_sensitive_type_attr(Some(servo), Atom::from(input.expect_ident()?))),
807
808
809 "-moz-locale-dir" => Ok(locale_dir(Some(moz), Self::parse_text_directionality(input)?)),
812
813 "-moz-system-metric" => Ok(system_metric(Some(moz), Self::parse_system_metric(input)?)),
814
815 "-moz-tree-cell-text" => Ok(tree_cell_text(Some(moz), Self::parse_tree_hover(input)?)),
816
817 "-moz-tree-row" => Ok(tree_row(Some(moz), Self::parse_tree_hover(input)?)),
818
819
820 _ => Err(ParseError::from(CustomParseError::UnsupportedPseudoClassOrElement(name.to_string()))),
821 }
822 }
823
824 #[inline(always)]
825 pub(crate) fn parse_any<'i, 't>(
826 input: &mut Parser<'i, 't>,
827 ourSelectorParser: &OurSelectorParser,
828 ) -> Result<DeduplicatedSelectors, ParseError<'i, CustomParseError<'i>>>
829 {
830 ourSelectorParser
831 .parse_internal(
832 input,
833 OurSelectorExt::is_false_if_any_selector_is_simple_and_only_uses_the_descendant_combinator
834 )
835 }
836
837 #[inline(always)]
838 pub(crate) fn parse_text_directionality<'i, 't>(
839 input: &mut Parser<'i, 't>,
840 ) -> Result<TextDirectionality, ParseError<'i, CustomParseError<'i>>> {
841 TextDirectionality::parse(input)
842 }
843
844 #[inline(always)]
845 pub(crate) fn parse_system_metric<'i, 't>(
846 input: &mut Parser<'i, 't>,
847 ) -> Result<SystemMetric, ParseError<'i, CustomParseError<'i>>> {
848 SystemMetric::parse(input)
849 }
850
851 #[inline(always)]
852 pub(crate) fn parse_tree_hover<'i, 't>(
853 input: &mut Parser<'i, 't>,
854 ) -> Result<TreeHover, ParseError<'i, CustomParseError<'i>>> {
855 TreeHover::parse(input)
856 }
857
858 #[inline(always)]
859 pub(crate) fn parse_lang<'i, 't>(
860 input: &mut Parser<'i, 't>,
861 ) -> Result<LanguageRanges, ParseError<'i, CustomParseError<'i>>> {
862 let languages = input.parse_comma_separated(|input| {
864 Ok(LanguageRange(Atom::from(
865 input.expect_ident_or_string()?.as_ref(),
866 )))
867 })?;
868 Ok(LanguageRanges(languages))
869 }
871}