diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2018-01-26 14:13:14 +0100 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2018-02-05 13:05:26 +0100 |
commit | b76bbdf5019b247a308ecf72fc98524879a49b30 (patch) | |
tree | ef55acaea45cdb758cdae2de257524486daa3f3b | |
parent | f2df3052d904c2a3e6f1a78185ab82653263bffd (diff) | |
download | servo-b76bbdf5019b247a308ecf72fc98524879a49b30.tar.gz servo-b76bbdf5019b247a308ecf72fc98524879a49b30.zip |
style: Make input[type=number] pseudo-elements accessible to chrome.
Bug: 1433389
Reviewed-by: jwatt
MozReview-Commit-ID: 2ycajPYd3CV
-rw-r--r-- | components/style/gecko/pseudo_element.rs | 20 | ||||
-rw-r--r-- | components/style/gecko/pseudo_element_definition.mako.rs | 23 | ||||
-rw-r--r-- | components/style/gecko/selector_parser.rs | 47 |
3 files changed, 62 insertions, 28 deletions
diff --git a/components/style/gecko/pseudo_element.rs b/components/style/gecko/pseudo_element.rs index ab38bdff798..a9960609aca 100644 --- a/components/style/gecko/pseudo_element.rs +++ b/components/style/gecko/pseudo_element.rs @@ -124,16 +124,26 @@ impl PseudoElement { !self.is_eager() && !self.is_precomputed() } - /// Whether this pseudo-element is web-exposed. - pub fn exposed_in_non_ua_sheets(&self) -> bool { - (self.flags() & structs::CSS_PSEUDO_ELEMENT_UA_SHEET_ONLY) == 0 - } - /// Whether this pseudo-element supports user action selectors. pub fn supports_user_action_state(&self) -> bool { (self.flags() & structs::CSS_PSEUDO_ELEMENT_SUPPORTS_USER_ACTION_STATE) != 0 } + /// Whether this pseudo-element is enabled for all content. + pub fn enabled_in_content(&self) -> bool { + (self.flags() & structs::CSS_PSEUDO_ELEMENT_ENABLED_IN_UA_SHEETS_AND_CHROME) == 0 + } + + /// Whether this pseudo is enabled explicitly in UA sheets. + pub fn enabled_in_ua_sheets(&self) -> bool { + (self.flags() & structs::CSS_PSEUDO_ELEMENT_ENABLED_IN_UA_SHEETS) != 0 + } + + /// Whether this pseudo is enabled explicitly in chrome sheets. + pub fn enabled_in_chrome(&self) -> bool { + (self.flags() & structs::CSS_PSEUDO_ELEMENT_ENABLED_IN_CHROME) != 0 + } + /// Whether this pseudo-element skips flex/grid container display-based /// fixup. #[inline] diff --git a/components/style/gecko/pseudo_element_definition.mako.rs b/components/style/gecko/pseudo_element_definition.mako.rs index 393fbf92895..0069469c6f1 100644 --- a/components/style/gecko/pseudo_element_definition.mako.rs +++ b/components/style/gecko/pseudo_element_definition.mako.rs @@ -114,7 +114,7 @@ impl PseudoElement { % if pseudo.is_tree_pseudo_element(): 0, % elif pseudo.is_anon_box(): - structs::CSS_PSEUDO_ELEMENT_UA_SHEET_ONLY, + structs::CSS_PSEUDO_ELEMENT_ENABLED_IN_UA_SHEETS, % else: structs::SERVO_CSS_PSEUDO_ELEMENT_FLAGS_${pseudo.original_ident}, % endif @@ -224,19 +224,24 @@ impl PseudoElement { /// /// Returns `None` if the pseudo-element is not recognised. #[inline] - pub fn from_slice(s: &str, in_ua_stylesheet: bool) -> Option<Self> { - #[allow(unused_imports)] use std::ascii::AsciiExt; - + pub fn from_slice(name: &str) -> Option<Self> { // We don't need to support tree pseudos because functional // pseudo-elements needs arguments, and thus should be created // via other methods. - % for pseudo in SIMPLE_PSEUDOS: - if in_ua_stylesheet || ${pseudo_element_variant(pseudo)}.exposed_in_non_ua_sheets() { - if s.eq_ignore_ascii_case("${pseudo.value[1:]}") { - return Some(${pseudo_element_variant(pseudo)}); + match_ignore_ascii_case! { name, + % for pseudo in SIMPLE_PSEUDOS: + "${pseudo.value[1:]}" => { + return Some(${pseudo_element_variant(pseudo)}) + } + % endfor + _ => { + // FIXME: -moz-tree check should probably be + // ascii-case-insensitive. + if name.starts_with("-moz-tree-") { + return PseudoElement::tree_pseudo_element(name, Box::new([])) } } - % endfor + } None } diff --git a/components/style/gecko/selector_parser.rs b/components/style/gecko/selector_parser.rs index 985bd453b4c..c009dc6b65e 100644 --- a/components/style/gecko/selector_parser.rs +++ b/components/style/gecko/selector_parser.rs @@ -159,10 +159,10 @@ impl NonTSPseudoClass { /// Returns whether the pseudo-class is enabled in content sheets. fn is_enabled_in_content(&self) -> bool { use gecko_bindings::structs::mozilla; - match self { + match *self { // For pseudo-classes with pref, the availability in content // depends on the pref. - &NonTSPseudoClass::Fullscreen => + NonTSPseudoClass::Fullscreen => unsafe { mozilla::StylePrefs_sUnprefixedFullscreenApiEnabled }, // Otherwise, a pseudo-class is enabled in content when it // doesn't have any enabled flag. @@ -322,6 +322,25 @@ impl<'a> SelectorParser<'a> { return false; } + + fn is_pseudo_element_enabled( + &self, + pseudo_element: &PseudoElement, + ) -> bool { + if pseudo_element.enabled_in_content() { + return true; + } + + if self.in_user_agent_stylesheet() && pseudo_element.enabled_in_ua_sheets() { + return true; + } + + if self.chrome_rules_enabled() && pseudo_element.enabled_in_chrome() { + return true; + } + + return false; + } } impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { @@ -418,17 +437,15 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { location: SourceLocation, name: CowRcStr<'i>, ) -> Result<PseudoElement, ParseError<'i>> { - PseudoElement::from_slice(&name, self.in_user_agent_stylesheet()) - .or_else(|| { - // FIXME: -moz-tree check should probably be - // ascii-case-insensitive. - if name.starts_with("-moz-tree-") { - PseudoElement::tree_pseudo_element(&name, Box::new([])) - } else { - None - } - }) - .ok_or(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone()))) + if let Some(pseudo) = PseudoElement::from_slice(&name) { + if self.is_pseudo_element_enabled(&pseudo) { + return Ok(pseudo); + } + } + + Err(location.new_custom_error( + SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name) + )) } fn parse_functional_pseudo_element<'t>( @@ -456,7 +473,9 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { return Ok(pseudo); } } - Err(parser.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone()))) + Err(parser.new_custom_error( + SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name) + )) } fn default_namespace(&self) -> Option<Namespace> { |