diff --git a/components/style/dom.rs b/components/style/dom.rs index 9a81e2ec774..633dce83655 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -801,24 +801,29 @@ pub trait TElement: { use rule_collector::containing_shadow_ignoring_svg_use; - let mut doc_rules_apply = self.matches_user_and_author_rules(); + let target = self.rule_hash_target(); + if !target.matches_user_and_author_rules() { + return false; + } + + let mut doc_rules_apply = true; // Use the same rules to look for the containing host as we do for rule // collection. - if let Some(shadow) = containing_shadow_ignoring_svg_use(*self) { + if let Some(shadow) = containing_shadow_ignoring_svg_use(target) { doc_rules_apply = false; if let Some(data) = shadow.style_data() { f(data, shadow.host()); } } - if let Some(shadow) = self.shadow_root() { + if let Some(shadow) = target.shadow_root() { if let Some(data) = shadow.style_data() { f(data, shadow.host()); } } - let mut current = self.assigned_slot(); + let mut current = target.assigned_slot(); while let Some(slot) = current { // Slots can only have assigned nodes when in a shadow tree. let shadow = slot.containing_shadow().unwrap(); diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 9d987c56308..cec55130c4a 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -1405,7 +1405,7 @@ impl<'le> TElement for GeckoElement<'le> { #[inline] fn matches_user_and_author_rules(&self) -> bool { - !self.rule_hash_target().is_in_native_anonymous_subtree() + !self.is_in_native_anonymous_subtree() } #[inline] diff --git a/components/style/rule_collector.rs b/components/style/rule_collector.rs index e87a86c5e47..2e8ffe5d858 100644 --- a/components/style/rule_collector.rs +++ b/components/style/rule_collector.rs @@ -13,7 +13,7 @@ use crate::selector_parser::PseudoElement; use crate::shared_lock::Locked; use crate::stylesheets::Origin; use crate::stylist::{AuthorStylesEnabled, Rule, RuleInclusion, Stylist}; -use selectors::matching::{ElementSelectorFlags, MatchingContext}; +use selectors::matching::{ElementSelectorFlags, MatchingContext, MatchingMode}; use servo_arc::ArcBorrow; use smallvec::SmallVec; @@ -97,8 +97,16 @@ where context: &'a mut MatchingContext<'b, E::Impl>, flags_setter: &'a mut F, ) -> Self { - let rule_hash_target = element.rule_hash_target(); - let matches_user_and_author_rules = element.matches_user_and_author_rules(); + // When we're matching with matching_mode = + // `ForStatelessPseudoeElement`, the "target" for the rule hash is the + // element itself, since it's what's generating the pseudo-element. + let rule_hash_target = match context.matching_mode() { + MatchingMode::ForStatelessPseudoElement => element, + MatchingMode::Normal => element.rule_hash_target(), + }; + + let matches_user_and_author_rules = + rule_hash_target.matches_user_and_author_rules(); // Gecko definitely has pseudo-elements with style attributes, like // ::-moz-color-swatch. @@ -120,8 +128,8 @@ where context, flags_setter, rules, - matches_user_and_author_rules, shadow_cascade_order: 0, + matches_user_and_author_rules, matches_document_author_rules: matches_user_and_author_rules, } } diff --git a/components/style/stylist.rs b/components/style/stylist.rs index 2953e3f0671..cba1cbac524 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -1195,6 +1195,10 @@ impl Stylist { // See [3] for the bug to implement whatever gets resolved, and related // bugs for a bit more context. // + // FIXME(emilio): This should probably work for pseudo-elements (i.e., + // use rule_hash_target().shadow_root() instead of + // element.shadow_root()). + // // [1]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/ // core/css/resolver/style_resolver.cc?l=1267&rcl=90f9f8680ebb4a87d177f3b0833372ae4e0c88d8 // [2]: https://github.com/w3c/csswg-drafts/issues/1995