From 22b62e091313824c8ca283f093d6dcc01a090a0c Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Thu, 24 Nov 2016 10:18:20 +0800 Subject: [PATCH] Don't match native anonymous content to user/author rules. --- components/style/gecko/wrapper.rs | 6 ++ components/style/matching.rs | 5 + components/style/selector_parser.rs | 2 + components/style/servo/selector_parser.rs | 5 + components/style/stylist.rs | 119 +++++++++++----------- 5 files changed, 80 insertions(+), 57 deletions(-) diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 36712a99be64..3d178a5ab897 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -28,6 +28,7 @@ use gecko_bindings::bindings::Gecko_StoreStyleDifference; use gecko_bindings::structs; use gecko_bindings::structs::{NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO, NODE_IS_DIRTY_FOR_SERVO}; use gecko_bindings::structs::{nsIAtom, nsIContent, nsStyleContext}; +use gecko_bindings::structs::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE; use parking_lot::RwLock; use parser::ParserContextExtraData; use properties::{ComputedValues, parse_style_attribute}; @@ -624,4 +625,9 @@ impl<'le> ElementExt for GeckoElement<'le> { fn is_link(&self) -> bool { self.match_non_ts_pseudo_class(NonTSPseudoClass::AnyLink) } + + #[inline] + fn matches_user_and_author_rules(&self) -> bool { + self.flags() & (NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE as u32) == 0 + } } diff --git a/components/style/matching.rs b/components/style/matching.rs index f4ed47e64d6b..442e2c3fffaa 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -106,6 +106,7 @@ pub enum CacheMiss { LocalName, Namespace, Link, + UserAndAuthorRules, State, IdAttr, StyleAttr, @@ -143,6 +144,10 @@ fn element_matches_candidate(element: &E, miss!(Link) } + if element.matches_user_and_author_rules() != candidate_element.matches_user_and_author_rules() { + miss!(UserAndAuthorRules) + } + if element.get_state() != candidate_element.get_state() { miss!(State) } diff --git a/components/style/selector_parser.rs b/components/style/selector_parser.rs index 98dc5a3e57d5..1c2814392565 100644 --- a/components/style/selector_parser.rs +++ b/components/style/selector_parser.rs @@ -101,6 +101,8 @@ impl PseudoElementCascadeType { pub trait ElementExt: Element { fn is_link(&self) -> bool; + + fn matches_user_and_author_rules(&self) -> bool; } impl SelectorImpl { diff --git a/components/style/servo/selector_parser.rs b/components/style/servo/selector_parser.rs index 493710debfba..8dc844456bdd 100644 --- a/components/style/servo/selector_parser.rs +++ b/components/style/servo/selector_parser.rs @@ -398,4 +398,9 @@ impl> ElementExt for E { fn is_link(&self) -> bool { self.match_non_ts_pseudo_class(NonTSPseudoClass::AnyLink) } + + #[inline] + fn matches_user_and_author_rules(&self) -> bool { + true + } } diff --git a/components/style/stylist.rs b/components/style/stylist.rs index 294b1b4cece4..2f756717869b 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -330,9 +330,9 @@ impl Stylist { pseudo: &PseudoElement, parent: &Arc) -> Option<(Arc, StrongRuleNode)> - where E: Element + - fmt::Debug + - PresentationalHintsSynthetizer + where E: ElementExt + + fmt::Debug + + PresentationalHintsSynthetizer { debug_assert!(SelectorImpl::pseudo_element_cascade_type(pseudo).is_lazy()); if self.pseudos_map.get(pseudo).is_none() { @@ -418,7 +418,7 @@ impl Stylist { pseudo_element: Option<&PseudoElement>, applicable_declarations: &mut V, reason: MatchingReason) -> StyleRelations - where E: Element + + where E: ElementExt + fmt::Debug + PresentationalHintsSynthetizer, V: Push + VecLike @@ -456,66 +456,71 @@ impl Stylist { } debug!("preshints: {:?}", relations); - // Step 3: User and author normal rules. - map.user.get_all_matching_rules(element, - parent_bf, - applicable_declarations, - &mut relations, - reason, - Importance::Normal); - debug!("user normal: {:?}", relations); - map.author.get_all_matching_rules(element, - parent_bf, - applicable_declarations, - &mut relations, - reason, - Importance::Normal); - debug!("author normal: {:?}", relations); - - // Step 4: Normal style attributes. - if let Some(sa) = style_attribute { - if sa.read().any_normal() { - relations |= AFFECTED_BY_STYLE_ATTRIBUTE; - Push::push( - applicable_declarations, - ApplicableDeclarationBlock::from_declarations(sa.clone(), Importance::Normal)); + if element.matches_user_and_author_rules() { + // Step 3: User and author normal rules. + map.user.get_all_matching_rules(element, + parent_bf, + applicable_declarations, + &mut relations, + reason, + Importance::Normal); + debug!("user normal: {:?}", relations); + map.author.get_all_matching_rules(element, + parent_bf, + applicable_declarations, + &mut relations, + reason, + Importance::Normal); + debug!("author normal: {:?}", relations); + + // Step 4: Normal style attributes. + if let Some(sa) = style_attribute { + if sa.read().any_normal() { + relations |= AFFECTED_BY_STYLE_ATTRIBUTE; + Push::push( + applicable_declarations, + ApplicableDeclarationBlock::from_declarations(sa.clone(), Importance::Normal)); + } } - } - debug!("style attr: {:?}", relations); - - // Step 5: Author-supplied `!important` rules. - map.author.get_all_matching_rules(element, - parent_bf, - applicable_declarations, - &mut relations, - reason, - Importance::Important); - - debug!("author important: {:?}", relations); - - // Step 6: `!important` style attributes. - if let Some(sa) = style_attribute { - if sa.read().any_important() { - relations |= AFFECTED_BY_STYLE_ATTRIBUTE; - Push::push( - applicable_declarations, - ApplicableDeclarationBlock::from_declarations(sa.clone(), Importance::Important)); + debug!("style attr: {:?}", relations); + + // Step 5: Author-supplied `!important` rules. + map.author.get_all_matching_rules(element, + parent_bf, + applicable_declarations, + &mut relations, + reason, + Importance::Important); + + debug!("author important: {:?}", relations); + + // Step 6: `!important` style attributes. + if let Some(sa) = style_attribute { + if sa.read().any_important() { + relations |= AFFECTED_BY_STYLE_ATTRIBUTE; + Push::push( + applicable_declarations, + ApplicableDeclarationBlock::from_declarations(sa.clone(), Importance::Important)); + } } - } - debug!("style attr important: {:?}", relations); + debug!("style attr important: {:?}", relations); - // Step 7: User and UA `!important` rules. - map.user.get_all_matching_rules(element, - parent_bf, - applicable_declarations, - &mut relations, - reason, - Importance::Important); + // Step 7: User `!important` rules. + map.user.get_all_matching_rules(element, + parent_bf, + applicable_declarations, + &mut relations, + reason, + Importance::Important); - debug!("user important: {:?}", relations); + debug!("user important: {:?}", relations); + } else { + debug!("skipping non-agent rules"); + } + // Step 8: UA `!important` rules. map.user_agent.get_all_matching_rules(element, parent_bf, applicable_declarations,