From bb15111dabd5f86fbef4dfd2aad924d41f994db0 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Wed, 28 Mar 2018 09:45:24 +1100 Subject: [PATCH 1/4] Use Servo to implement GetStatesForPseudoClass function in InspectorUtils. --- components/style/gecko/selector_parser.rs | 35 +++++++++++++---------- ports/geckolib/glue.rs | 13 ++++++++- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/components/style/gecko/selector_parser.rs b/components/style/gecko/selector_parser.rs index b6e99b2083f..ea0ae646d20 100644 --- a/components/style/gecko/selector_parser.rs +++ b/components/style/gecko/selector_parser.rs @@ -133,6 +133,22 @@ impl Visit for NonTSPseudoClass { impl NonTSPseudoClass { + /// Parses the name and returns a non-ts-pseudo-class if succeeds. + /// None otherwise. It doesn't check whether the pseudo-class is enabled + /// in a particular state. + pub fn parse_non_functional(name: &str) -> Option { + macro_rules! pseudo_class_parse { + (bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*], + string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*]) => { + match_ignore_ascii_case! { &name, + $($css => Some(NonTSPseudoClass::$name),)* + _ => None, + } + } + } + apply_non_ts_list!(pseudo_class_parse) + } + /// Returns true if this pseudo-class has any of the given flags set. fn has_any_flag(&self, flags: NonTSPseudoClassFlag) -> bool { macro_rules! check_flag { @@ -373,23 +389,12 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { location: SourceLocation, name: CowRcStr<'i>, ) -> Result> { - macro_rules! pseudo_class_parse { - (bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*], - string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*]) => { - match_ignore_ascii_case! { &name, - $($css => NonTSPseudoClass::$name,)* - _ => return Err(location.new_custom_error( - SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone()) - )) - } + if let Some(pseudo_class) = NonTSPseudoClass::parse_non_functional(&name) { + if self.is_pseudo_class_enabled(&pseudo_class) { + return Ok(pseudo_class); } } - let pseudo_class = apply_non_ts_list!(pseudo_class_parse); - if self.is_pseudo_class_enabled(&pseudo_class) { - Ok(pseudo_class) - } else { - Err(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name))) - } + Err(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name))) } fn parse_non_ts_functional_pseudo_class<'t>( diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 3381da47e0b..4d5cbc87fdd 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -31,7 +31,7 @@ use style::font_metrics::{FontMetricsProvider, get_metrics_provider_for_product} use style::gecko::data::{GeckoStyleSheet, PerDocumentStyleData, PerDocumentStyleDataImpl}; use style::gecko::global_style_data::{GLOBAL_STYLE_DATA, GlobalStyleData, STYLE_THREAD_POOL}; use style::gecko::restyle_damage::GeckoRestyleDamage; -use style::gecko::selector_parser::PseudoElement; +use style::gecko::selector_parser::{NonTSPseudoClass, PseudoElement}; use style::gecko::traversal::RecalcStyleOnly; use style::gecko::wrapper::{GeckoElement, GeckoNode}; use style::gecko_bindings::bindings; @@ -5115,3 +5115,14 @@ pub extern "C" fn Servo_ParseCounterStyleDescriptor( result, ).is_ok() } + +#[no_mangle] +pub unsafe extern "C" fn Servo_PseudoClass_GetStates(name: *const nsACString) -> u64 { + let name = name.as_ref().unwrap().as_str_unchecked(); + match NonTSPseudoClass::parse_non_functional(name) { + None => 0, + // Ignore :any-link since it contains both visited and unvisited state. + Some(NonTSPseudoClass::AnyLink) => 0, + Some(pseudo_class) => pseudo_class.state_flag().bits(), + } +} From 911f174b708fd5b880998a1b2e23787ca3b223d7 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Wed, 28 Mar 2018 09:45:25 +1100 Subject: [PATCH 2/4] Make :-moz-native-anonymous and :-moz-use-shadow-tree-root matches in Rust code. --- components/style/gecko/wrapper.rs | 43 +++++++++++++++++++------------ 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index ace76867217..f4081ed7aa5 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -814,6 +814,21 @@ impl<'le> GeckoElement<'le> { (!self.as_node().is_in_shadow_tree() && self.has_xbl_binding_parent()) } + /// Returns true if this node is the shadow root of an use-element shadow tree. + #[inline] + fn is_root_of_use_element_shadow_tree(&self) -> bool { + if !self.is_root_of_anonymous_subtree() { + return false + } + match self.parent_element() { + Some(e) => { + e.local_name() == &*local_name!("use") && + e.namespace() == &*ns!("http://www.w3.org/2000/svg") + }, + None => false, + } + } + fn css_transitions_info(&self) -> FnvHashMap> { use gecko_bindings::bindings::Gecko_ElementTransitions_EndValueAt; use gecko_bindings::bindings::Gecko_ElementTransitions_Length; @@ -2103,10 +2118,14 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { } true } + NonTSPseudoClass::MozNativeAnonymous => { + self.is_in_native_anonymous_subtree() + } + NonTSPseudoClass::MozUseShadowTreeRoot => { + self.is_root_of_use_element_shadow_tree() + } NonTSPseudoClass::MozTableBorderNonzero | - NonTSPseudoClass::MozBrowserFrame | - NonTSPseudoClass::MozNativeAnonymous | - NonTSPseudoClass::MozUseShadowTreeRoot => unsafe { + NonTSPseudoClass::MozBrowserFrame => unsafe { Gecko_MatchesElement(pseudo_class.to_gecko_pseudoclasstype().unwrap(), self.0) }, NonTSPseudoClass::MozIsHTML => { @@ -2235,20 +2254,10 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { #[inline] fn blocks_ancestor_combinators(&self) -> bool { - if !self.is_root_of_anonymous_subtree() { - return false - } - - match self.parent_element() { - Some(e) => { - // If this element is the shadow root of an use-element shadow - // tree, according to the spec, we should not match rules - // cross the shadow DOM boundary. - e.local_name() == &*local_name!("use") && - e.namespace() == &*ns!("http://www.w3.org/2000/svg") - }, - None => false, - } + // If this element is the shadow root of an use-element shadow tree, + // according to the spec, we should not match rules cross the shadow + // DOM boundary. + self.is_root_of_use_element_shadow_tree() } } From e57b6c65a0b8041cc06aaebf314a48de1a404938 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Wed, 28 Mar 2018 09:45:28 +1100 Subject: [PATCH 3/4] Move matching logic of :-moz-table-border-nonzero and :-moz-browser-frame into individual binding functions. --- components/style/gecko/generated/bindings.rs | 13 ++++++------- components/style/gecko/wrapper.rs | 9 +++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/components/style/gecko/generated/bindings.rs b/components/style/gecko/generated/bindings.rs index 4e76b4679e0..02401664525 100644 --- a/components/style/gecko/generated/bindings.rs +++ b/components/style/gecko/generated/bindings.rs @@ -54,7 +54,6 @@ use gecko_bindings::structs::RawServoSelectorList; use gecko_bindings::structs::RawServoSourceSizeList; use gecko_bindings::structs::RefPtr; use gecko_bindings::structs::RustString; -use gecko_bindings::structs::CSSPseudoClassType; use gecko_bindings::structs::CSSPseudoElementType; use gecko_bindings::structs::ServoTraversalFlags; use gecko_bindings::structs::ComputedTimingFunction_BeforeFlag; @@ -627,12 +626,6 @@ extern "C" { extern "C" { pub fn Gecko_IsRootElement(element: RawGeckoElementBorrowed) -> bool; } -extern "C" { - pub fn Gecko_MatchesElement( - type_: CSSPseudoClassType, - element: RawGeckoElementBorrowed, - ) -> bool; -} extern "C" { pub fn Gecko_MatchLang( element: RawGeckoElementBorrowed, @@ -647,6 +640,12 @@ extern "C" { extern "C" { pub fn Gecko_GetDocumentLWTheme(aDocument: *const nsIDocument) -> nsIDocument_DocumentTheme; } +extern "C" { + pub fn Gecko_IsTableBorderNonzero(element: RawGeckoElementBorrowed) -> bool; +} +extern "C" { + pub fn Gecko_IsBrowserFrame(element: RawGeckoElementBorrowed) -> bool; +} extern "C" { pub fn Gecko_AtomAttrValue( element: RawGeckoElementBorrowed, diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index f4081ed7aa5..9c32d301c13 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -32,7 +32,6 @@ use gecko_bindings::bindings; use gecko_bindings::bindings::{Gecko_ConstructStyleChildrenIterator, Gecko_DestroyStyleChildrenIterator}; use gecko_bindings::bindings::{Gecko_ElementState, Gecko_GetDocumentLWTheme}; use gecko_bindings::bindings::{Gecko_GetLastChild, Gecko_GetNextStyleChild}; -use gecko_bindings::bindings::{Gecko_IsRootElement, Gecko_MatchesElement}; use gecko_bindings::bindings::{Gecko_SetNodeFlags, Gecko_UnsetNodeFlags}; use gecko_bindings::bindings::Gecko_ClassOrClassList; use gecko_bindings::bindings::Gecko_ElementHasAnimations; @@ -1996,7 +1995,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { } unsafe { - Gecko_IsRootElement(self.0) + bindings::Gecko_IsRootElement(self.0) } } @@ -2124,9 +2123,11 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { NonTSPseudoClass::MozUseShadowTreeRoot => { self.is_root_of_use_element_shadow_tree() } - NonTSPseudoClass::MozTableBorderNonzero | + NonTSPseudoClass::MozTableBorderNonzero => unsafe { + bindings::Gecko_IsTableBorderNonzero(self.0) + } NonTSPseudoClass::MozBrowserFrame => unsafe { - Gecko_MatchesElement(pseudo_class.to_gecko_pseudoclasstype().unwrap(), self.0) + bindings::Gecko_IsBrowserFrame(self.0) }, NonTSPseudoClass::MozIsHTML => { self.is_html_element_in_html_document() From 688fb23d25e72fe434ebb5b927bee619f56d4f61 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Wed, 28 Mar 2018 09:45:36 +1100 Subject: [PATCH 4/4] Remove nsCSSPseudoClasses.{h,cpp} and nsCSSPseudoClassList.h. --- components/style/gecko/generated/structs.rs | 91 ------------------- .../style/gecko/non_ts_pseudo_class_list.rs | 3 - components/style/gecko/selector_parser.rs | 24 +---- 3 files changed, 1 insertion(+), 117 deletions(-) diff --git a/components/style/gecko/generated/structs.rs b/components/style/gecko/generated/structs.rs index 923b16f41d4..874568e7d19 100644 --- a/components/style/gecko/generated/structs.rs +++ b/components/style/gecko/generated/structs.rs @@ -12267,97 +12267,6 @@ pub mod root { ) ); } - pub type CSSPseudoClassTypeBase = u8; - #[repr(u8)] - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum CSSPseudoClassType { - empty = 0, - mozOnlyWhitespace = 1, - lang = 2, - root = 3, - any = 4, - firstChild = 5, - firstNode = 6, - lastChild = 7, - lastNode = 8, - onlyChild = 9, - firstOfType = 10, - lastOfType = 11, - onlyOfType = 12, - nthChild = 13, - nthLastChild = 14, - nthOfType = 15, - nthLastOfType = 16, - mozIsHTML = 17, - mozNativeAnonymous = 18, - mozUseShadowTreeRoot = 19, - mozLocaleDir = 20, - mozLWTheme = 21, - mozLWThemeBrightText = 22, - mozLWThemeDarkText = 23, - mozWindowInactive = 24, - mozTableBorderNonzero = 25, - mozBrowserFrame = 26, - scope = 27, - negation = 28, - dir = 29, - link = 30, - mozAnyLink = 31, - anyLink = 32, - visited = 33, - active = 34, - checked = 35, - disabled = 36, - enabled = 37, - focus = 38, - focusWithin = 39, - hover = 40, - mozDragOver = 41, - target = 42, - indeterminate = 43, - mozDevtoolsHighlighted = 44, - mozStyleeditorTransitioning = 45, - fullscreen = 46, - mozFullScreen = 47, - mozFocusRing = 48, - mozBroken = 49, - mozLoading = 50, - mozUserDisabled = 51, - mozSuppressed = 52, - mozHandlerClickToPlay = 53, - mozHandlerVulnerableUpdatable = 54, - mozHandlerVulnerableNoUpdate = 55, - mozHandlerDisabled = 56, - mozHandlerBlocked = 57, - mozHandlerCrashed = 58, - mozMathIncrementScriptLevel = 59, - mozHasDirAttr = 60, - mozDirAttrLTR = 61, - mozDirAttrRTL = 62, - mozDirAttrLikeAuto = 63, - mozAutofill = 64, - mozAutofillPreview = 65, - required = 66, - optional = 67, - valid = 68, - invalid = 69, - inRange = 70, - outOfRange = 71, - defaultPseudo = 72, - placeholderShown = 73, - mozReadOnly = 74, - mozReadWrite = 75, - mozSubmitInvalid = 76, - mozUIInvalid = 77, - mozUIValid = 78, - mozMeterOptimum = 79, - mozMeterSubOptimum = 80, - mozMeterSubSubOptimum = 81, - mozPlaceholder = 82, - Count = 83, - NotPseudo = 84, - MAX = 85, - } #[repr(C)] pub struct GeckoFont { pub gecko: root::nsStyleFont, diff --git a/components/style/gecko/non_ts_pseudo_class_list.rs b/components/style/gecko/non_ts_pseudo_class_list.rs index 0a5fe00be02..b02e21fbf8a 100644 --- a/components/style/gecko/non_ts_pseudo_class_list.rs +++ b/components/style/gecko/non_ts_pseudo_class_list.rs @@ -28,9 +28,6 @@ * * :scope ->