diff options
Diffstat (limited to 'components')
-rw-r--r-- | components/style/dom.rs | 3 | ||||
-rw-r--r-- | components/style/gecko/wrapper.rs | 9 | ||||
-rw-r--r-- | components/style/stylist.rs | 72 |
3 files changed, 58 insertions, 26 deletions
diff --git a/components/style/dom.rs b/components/style/dom.rs index 5a6cc5ea980..795eb51c247 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -573,7 +573,8 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone + /// Gets declarations from XBL bindings from the element. Only gecko element could have this. fn get_declarations_from_xbl_bindings<V>(&self, - _: &mut V) + _pseudo_element: Option<&PseudoElement>, + _applicable_declarations: &mut V) -> bool where V: Push<ApplicableDeclarationBlock> + VecLike<ApplicableDeclarationBlock> { false diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 461b96e0f90..961ed2d45f7 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -382,17 +382,19 @@ impl<'lb> GeckoXBLBinding<'lb> { // Implements Gecko's nsXBLBinding::WalkRules(). fn get_declarations_for<E, V>(&self, element: &E, + pseudo_element: Option<&PseudoElement>, applicable_declarations: &mut V) where E: TElement, V: Push<ApplicableDeclarationBlock> + VecLike<ApplicableDeclarationBlock> { if let Some(base_binding) = self.base_binding() { - base_binding.get_declarations_for(element, applicable_declarations); + base_binding.get_declarations_for(element, pseudo_element, applicable_declarations); } let raw_data = unsafe { bindings::Gecko_XBLBinding_GetRawServoStyleSet(self.0) }; if let Some(raw_data) = raw_data { let data = PerDocumentStyleData::from_ffi(&*raw_data).borrow(); data.stylist.push_applicable_declarations_as_xbl_only_stylist(element, + pseudo_element, applicable_declarations); } } @@ -942,6 +944,7 @@ impl<'le> TElement for GeckoElement<'le> { // Implements Gecko's nsBindingManager::WalkRules(). Returns whether to cut off the // inheritance. fn get_declarations_from_xbl_bindings<V>(&self, + pseudo_element: Option<&PseudoElement>, applicable_declarations: &mut V) -> bool where V: Push<ApplicableDeclarationBlock> + VecLike<ApplicableDeclarationBlock> { @@ -951,7 +954,9 @@ impl<'le> TElement for GeckoElement<'le> { while let Some(element) = current { if let Some(binding) = element.get_xbl_binding() { - binding.get_declarations_for(self, applicable_declarations); + binding.get_declarations_for(self, + pseudo_element, + applicable_declarations); // If we're not looking at our original element, allow the binding to cut off // style inheritance. diff --git a/components/style/stylist.rs b/components/style/stylist.rs index 9421daf0f5e..35a257dcabe 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -933,10 +933,38 @@ impl Stylist { self.quirks_mode = quirks_mode; } + /// Returns the correspond PerPseudoElementSelectorMap given PseudoElement. + fn get_map(&self, + pseudo_element: Option<&PseudoElement>) -> Option<&PerPseudoElementSelectorMap> + { + match pseudo_element { + Some(pseudo) => self.pseudos_map.get(pseudo), + None => Some(&self.element_map), + } + } + + /// Returns the rule hash target given an element. + fn rule_hash_target<E>(&self, element: E) -> E + where E: TElement + { + let is_implemented_pseudo = + element.implemented_pseudo_element().is_some(); + + // NB: This causes use to rule has pseudo selectors based on the + // properties of the originating element (which is fine, given the + // find_first_from_right usage). + if is_implemented_pseudo { + element.closest_non_native_anonymous_ancestor().unwrap() + } else { + element + } + } + /// 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<E, V>(&self, element: &E, + pseudo_element: Option<&PseudoElement>, applicable_declarations: &mut V) where E: TElement, V: Push<ApplicableDeclarationBlock> + VecLike<ApplicableDeclarationBlock>, @@ -945,13 +973,21 @@ impl Stylist { MatchingContext::new(MatchingMode::Normal, None, self.quirks_mode); let mut dummy_flag_setter = |_: &E, _: ElementSelectorFlags| {}; - self.element_map.author.get_all_matching_rules(element, - element, - applicable_declarations, - &mut matching_context, - self.quirks_mode, - &mut dummy_flag_setter, - CascadeLevel::XBL); + let map = match self.get_map(pseudo_element) { + Some(map) => map, + None => return, + }; + let rule_hash_target = self.rule_hash_target(*element); + + // nsXBLPrototypeResources::ComputeServoStyleSet() added XBL stylesheets under author + // (doc) level. + map.author.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. @@ -983,22 +1019,11 @@ impl Stylist { "Style attributes do not apply to pseudo-elements"); debug_assert!(pseudo_element.map_or(true, |p| !p.is_precomputed())); - let map = match pseudo_element { - Some(pseudo) => self.pseudos_map.get(pseudo).unwrap(), - None => &self.element_map, - }; - - let is_implemented_pseudo = - element.implemented_pseudo_element().is_some(); - - // NB: This causes use to rule has pseudo selectors based on the - // properties of the originating element (which is fine, given the - // find_first_from_right usage). - let rule_hash_target = if is_implemented_pseudo { - element.closest_non_native_anonymous_ancestor().unwrap() - } else { - *element + let map = match self.get_map(pseudo_element) { + Some(map) => map, + None => return, }; + let rule_hash_target = self.rule_hash_target(*element); debug!("Determining if style is shareable: pseudo: {}", pseudo_element.is_some()); @@ -1060,7 +1085,8 @@ impl Stylist { // Step 3b: XBL rules. let cut_off_inheritance = - rule_hash_target.get_declarations_from_xbl_bindings(applicable_declarations); + rule_hash_target.get_declarations_from_xbl_bindings(pseudo_element, + applicable_declarations); debug!("XBL: {:?}", context.relations); if rule_hash_target.matches_user_and_author_rules() && !only_default_rules { |