From d82e6926fca842992c06a899520cae4000a9acf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 27 Sep 2017 13:27:01 +0200 Subject: [PATCH 1/2] style: Do not optimize out lazy pseudo rules if the main stylist doesn't have rules for it. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This could prevent an XBL binding to use some pseudo-elements fairly randomly. MozReview-Commit-ID: b44DO8qcfD Signed-off-by: Emilio Cobos Álvarez --- components/style/stylist.rs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/components/style/stylist.rs b/components/style/stylist.rs index 7e89db40957..b5e76a6d44d 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -964,12 +964,6 @@ impl Stylist { ) } - fn has_rules_for_pseudo(&self, pseudo: &PseudoElement) -> bool { - self.cascade_data - .iter_origins() - .any(|(d, _)| d.has_rules_for_pseudo(pseudo)) - } - /// Computes the cascade inputs for a lazily-cascaded pseudo-element. /// /// See the documentation on lazy pseudo-elements in @@ -988,10 +982,6 @@ impl Stylist { let pseudo = pseudo.canonical(); debug_assert!(pseudo.is_lazy()); - if !self.has_rules_for_pseudo(&pseudo) { - return CascadeInputs::default() - } - // Apply the selector flags. We should be in sequential mode // already, so we can directly apply the parent flags. let mut set_selector_flags = |element: &E, flags: ElementSelectorFlags| { @@ -2195,10 +2185,6 @@ impl CascadeData { } } - fn has_rules_for_pseudo(&self, pseudo: &PseudoElement) -> bool { - self.pseudos_map.get(pseudo).is_some() - } - /// Clears the cascade data, but not the invalidation data. fn clear_cascade_data(&mut self) { self.element_map.clear(); From 19d34b96e5175574383c0a4e1c911daf7a1a3954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 27 Sep 2017 13:27:51 +0200 Subject: [PATCH 2/2] style: Fix various issues with XBL rule matching. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We were using the wrong MatchingMode and flags setter just because we didn't bother threading them down. This patch fixes the issue seen with the video controls. MozReview-Commit-ID: Il1WOzRDxI1 Signed-off-by: Emilio Cobos Álvarez --- components/style/dom.rs | 19 ----------- components/style/stylist.rs | 63 +++++++++++++------------------------ 2 files changed, 21 insertions(+), 61 deletions(-) diff --git a/components/style/dom.rs b/components/style/dom.rs index f8157f3c844..2b3ce58c74f 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -26,7 +26,6 @@ use selectors::matching::{ElementSelectorFlags, VisitedHandlingMode}; use selectors::sink::Push; use servo_arc::{Arc, ArcBorrow}; use shared_lock::Locked; -use smallvec::VecLike; use std::fmt; #[cfg(feature = "gecko")] use hash::HashMap; use std::fmt::Debug; @@ -648,24 +647,6 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone + false } - /// Gets declarations from XBL bindings from the element. - fn get_declarations_from_xbl_bindings( - &self, - pseudo_element: Option<&PseudoElement>, - applicable_declarations: &mut V - ) -> bool - where - V: Push + VecLike - { - self.each_xbl_stylist(|stylist| { - stylist.push_applicable_declarations_as_xbl_only_stylist( - self, - pseudo_element, - applicable_declarations - ); - }) - } - /// Gets the current existing CSS transitions, by |property, end value| pairs in a HashMap. #[cfg(feature = "gecko")] fn get_css_transitions_info(&self) diff --git a/components/style/stylist.rs b/components/style/stylist.rs index b5e76a6d44d..7bf735955b9 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -1015,10 +1015,12 @@ impl Stylist { let mut inputs = CascadeInputs::default(); let mut declarations = ApplicableDeclarationList::new(); let mut matching_context = - MatchingContext::new(MatchingMode::ForStatelessPseudoElement, - None, - None, - self.quirks_mode); + MatchingContext::new( + MatchingMode::ForStatelessPseudoElement, + None, + None, + self.quirks_mode, + ); self.push_applicable_declarations( element, @@ -1181,39 +1183,6 @@ impl Stylist { self.quirks_mode = quirks_mode; } - /// Returns the applicable CSS declarations for the given element by - /// treating us as an XBL stylesheet-only stylist. - pub fn push_applicable_declarations_as_xbl_only_stylist( - &self, - element: &E, - pseudo_element: Option<&PseudoElement>, - applicable_declarations: &mut V - ) - where - E: TElement, - V: Push + VecLike, - { - let mut matching_context = - MatchingContext::new(MatchingMode::Normal, None, None, self.quirks_mode); - let mut dummy_flag_setter = |_: &E, _: ElementSelectorFlags| {}; - - let rule_hash_target = element.rule_hash_target(); - - // nsXBLPrototypeResources::LoadResources() loads Chrome XBL style - // sheets under eAuthorSheetFeatures level. - if let Some(map) = self.cascade_data.author.borrow_for_pseudo(pseudo_element) { - map.get_all_matching_rules( - element, - &rule_hash_target, - applicable_declarations, - &mut matching_context, - self.quirks_mode, - &mut dummy_flag_setter, - CascadeLevel::XBL, - ); - } - } - /// Returns the applicable CSS declarations for the given element. /// /// This corresponds to `ElementRuleCollector` in WebKit. @@ -1303,11 +1272,21 @@ impl Stylist { } // Step 3b: XBL rules. - let cut_off_inheritance = - element.get_declarations_from_xbl_bindings( - pseudo_element, - applicable_declarations, - ); + let cut_off_inheritance = element.each_xbl_stylist(|stylist| { + // ServoStyleSet::CreateXBLServoStyleSet() loads XBL style sheets + // under eAuthorSheetFeatures level. + if let Some(map) = stylist.cascade_data.author.borrow_for_pseudo(pseudo_element) { + map.get_all_matching_rules( + element, + &rule_hash_target, + applicable_declarations, + context, + self.quirks_mode, + flags_setter, + CascadeLevel::XBL, + ); + } + }); if rule_hash_target.matches_user_and_author_rules() && !only_default_rules { // Gecko skips author normal rules if cutting off inheritance.