From e74fad6259cc954cef8dc08e74f131ee88e7a621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 18 Jan 2018 14:47:30 +0100 Subject: [PATCH 1/3] style: Handle correctly document state invalidation inside negation. --- components/selectors/context.rs | 27 +++++++++++++++++++++++++++ components/selectors/matching.rs | 4 +++- components/style/gecko/wrapper.rs | 4 ++-- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/components/selectors/context.rs b/components/selectors/context.rs index 75abfea9f18..f61823a626d 100644 --- a/components/selectors/context.rs +++ b/components/selectors/context.rs @@ -127,6 +127,9 @@ where /// MatchingContext immutable again. nesting_level: usize, + /// Whether we're inside a negation or not. + in_negation: bool, + /// An optional hook function for checking whether a pseudo-element /// should match when matching_mode is ForStatelessPseudoElement. pub pseudo_element_matching_fn: Option<&'a Fn(&Impl::PseudoElement) -> bool>, @@ -176,6 +179,7 @@ where classes_and_ids_case_sensitivity: quirks_mode.classes_and_ids_case_sensitivity(), scope_element: None, nesting_level: 0, + in_negation: false, pseudo_element_matching_fn: None, extra_data: Default::default(), _impl: ::std::marker::PhantomData, @@ -188,6 +192,12 @@ where self.nesting_level != 0 } + /// Whether we're matching inside a :not(..) selector. + #[inline] + pub fn in_negation(&self) -> bool { + self.in_negation + } + /// The quirks mode of the document. #[inline] pub fn quirks_mode(&self) -> QuirksMode { @@ -212,6 +222,23 @@ where result } + /// Runs F with a deeper nesting level, and marking ourselves in a negation, + /// for a :not(..) selector, for example. + #[inline] + pub fn nest_for_negation(&mut self, f: F) -> R + where + F: FnOnce(&mut Self) -> R, + { + debug_assert!( + !self.in_negation, + "Someone messed up parsing?" + ); + self.in_negation = true; + let result = self.nest(f); + self.in_negation = false; + result + } + #[inline] pub fn visited_handling(&self) -> VisitedHandlingMode { self.visited_handling diff --git a/components/selectors/matching.rs b/components/selectors/matching.rs index 6b1fae8cc32..d52b51d7270 100644 --- a/components/selectors/matching.rs +++ b/components/selectors/matching.rs @@ -625,6 +625,8 @@ where E: Element, F: FnMut(&E, ElementSelectorFlags), { + debug_assert!(context.shared.is_nested() || !context.shared.in_negation()); + match *selector { Component::Combinator(_) => unreachable!(), Component::Slotted(ref selector) => { @@ -777,7 +779,7 @@ where matches_generic_nth_child(element, context, 0, 1, true, true, flags_setter) } Component::Negation(ref negated) => { - context.shared.nest(|context| { + context.shared.nest_for_negation(|context| { let mut local_context = LocalMatchingContext { matches_hover_and_active_quirk: MatchesHoverAndActiveQuirk::No, shared: context, diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index cdfd8258536..de4855c4ed4 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -2111,7 +2111,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { NonTSPseudoClass::MozWindowInactive => { let state_bit = DocumentState::NS_DOCUMENT_STATE_WINDOW_INACTIVE; if context.extra_data.document_state.intersects(state_bit) { - return true; + return !context.in_negation(); } self.document_state().contains(state_bit) @@ -2132,7 +2132,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { if context.extra_data.document_state.intersects(state_bit) { // NOTE(emilio): We could still return false for // Direction::Other(..), but we don't bother. - return true; + return !context.in_negation(); } let doc_is_rtl = self.document_state().contains(state_bit); From c49434726e22ba0ffedd505601c7001ea397f7f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 18 Jan 2018 14:52:48 +0100 Subject: [PATCH 2/3] style: Skip a function for the static tests. --- ports/geckolib/tests/build.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/ports/geckolib/tests/build.rs b/ports/geckolib/tests/build.rs index 7712698c4b8..bfb20d5af4e 100644 --- a/ports/geckolib/tests/build.rs +++ b/ports/geckolib/tests/build.rs @@ -39,6 +39,21 @@ fn main() { for line in r.lines() { let s = line.unwrap(); for cap in matcher.captures_iter(&s) { + // This causes a mismatch in old libclangs (the ones that are + // used in linux32 mozilla-central) because it generates: + // + // *const nsTArray<*const RawServoStyleSet> + // + // Instead of: + // + // *const nsTArray + // + // Which is not a problem, but would cause this to not compile. + // + // Skip this until libclang is updated there. + if &cap[1] == "InvalidateStyleForDocStateChanges" { + continue; + } w.write_all(format!(" [ Servo_{0}, bindings::Servo_{0} ];\n", &cap[1]).as_bytes()).unwrap(); } } From d14c979fb2a5d7ce8f2bf20d82b999a936d75fbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 18 Jan 2018 14:53:17 +0100 Subject: [PATCH 3/3] Revert "style: Remove new function added to the build from bindings.rs" This reverts commit 8c0e455d9ec50711980a5fc89384b634981764dc. --- components/style/gecko/generated/bindings.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/style/gecko/generated/bindings.rs b/components/style/gecko/generated/bindings.rs index 301aba806f5..a7597a98ca4 100644 --- a/components/style/gecko/generated/bindings.rs +++ b/components/style/gecko/generated/bindings.rs @@ -1151,6 +1151,8 @@ extern "C" { pub fn Servo_Element_IsDisplayNone ( element : RawGeckoElementBorrowed , ) -> bool ; } extern "C" { pub fn Servo_Element_IsPrimaryStyleReusedViaRuleNode ( element : RawGeckoElementBorrowed , ) -> bool ; +} extern "C" { + pub fn Servo_InvalidateStyleForDocStateChanges ( root : RawGeckoElementBorrowed , sets : * const nsTArray < RawServoStyleSetBorrowed > , aStatesChanged : u64 , ) ; } extern "C" { pub fn Servo_StyleSheet_FromUTF8Bytes ( loader : * mut Loader , gecko_stylesheet : * mut ServoStyleSheet , data : * const u8 , data_len : usize , parsing_mode : SheetParsingMode , extra_data : * mut RawGeckoURLExtraData , line_number_offset : u32 , quirks_mode : nsCompatibility , reusable_sheets : * mut LoaderReusableStyleSheets , ) -> RawServoStyleSheetContentsStrong ; } extern "C" { @@ -1595,4 +1597,4 @@ extern "C" { pub fn Gecko_IsInServoTraversal ( ) -> bool ; } extern "C" { pub fn Gecko_IsMainThread ( ) -> bool ; -} +} \ No newline at end of file