diff --git a/components/selectors/context.rs b/components/selectors/context.rs index 3ecd4dd82d5..95caa4055d7 100644 --- a/components/selectors/context.rs +++ b/components/selectors/context.rs @@ -279,13 +279,13 @@ where /// Runs F with a given shadow host which is the root of the tree whose /// rules we're matching. #[inline] - pub fn with_shadow_host(&mut self, host: Option, f: F) -> R + pub fn with_shadow_host(&mut self, host: E, f: F) -> R where E: Element, F: FnOnce(&mut Self) -> R, { let original_host = self.current_host.take(); - self.current_host = host.map(|h| h.opaque()); + self.current_host = Some(host.opaque()); let result = f(self); self.current_host = original_host; result diff --git a/components/style/author_styles.rs b/components/style/author_styles.rs index eff64ed6c1e..58d9bda423a 100644 --- a/components/style/author_styles.rs +++ b/components/style/author_styles.rs @@ -3,7 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! A set of author stylesheets and their computed representation, such as the -//! ones used for ShadowRoot and XBL. +//! ones used for ShadowRoot. use crate::context::QuirksMode; use crate::dom::TElement; @@ -17,7 +17,7 @@ use crate::stylesheets::StylesheetInDocument; use crate::stylist::CascadeData; /// A set of author stylesheets and their computed representation, such as the -/// ones used for ShadowRoot and XBL. +/// ones used for ShadowRoot. #[derive(MallocSizeOf)] pub struct AuthorStyles where @@ -28,9 +28,6 @@ where pub stylesheets: AuthorStylesheetSet, /// The actual cascade data computed from the stylesheets. pub data: CascadeData, - /// The quirks mode of the last stylesheet flush, used because XBL sucks and - /// we should really fix it, see bug 1406875. - pub quirks_mode: QuirksMode, } impl AuthorStyles @@ -43,7 +40,6 @@ where Self { stylesheets: AuthorStylesheetSet::new(), data: CascadeData::new(), - quirks_mode: QuirksMode::NoQuirks, } } @@ -65,10 +61,6 @@ where .stylesheets .flush::(/* host = */ None, /* snapshot_map = */ None); - if flusher.sheets.dirty() { - self.quirks_mode = quirks_mode; - } - // Ignore OOM. let _ = self .data diff --git a/components/style/dom.rs b/components/style/dom.rs index 967b978bad4..9a81e2ec774 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -761,7 +761,7 @@ pub trait TElement: /// Returns the anonymous content for the current element's XBL binding, /// given if any. /// - /// This is used in Gecko for XBL and shadow DOM. + /// This is used in Gecko for XBL. fn xbl_binding_anonymous_content(&self) -> Option { None } @@ -772,11 +772,6 @@ pub trait TElement: /// The shadow root which roots the subtree this element is contained in. fn containing_shadow(&self) -> Option<::ConcreteShadowRoot>; - /// XBL hack for style sharing. :( - fn has_same_xbl_proto_binding_as(&self, _other: Self) -> bool { - true - } - /// Return the element which we can use to look up rules in the selector /// maps. /// @@ -792,56 +787,34 @@ pub trait TElement: } } - /// Implements Gecko's `nsBindingManager::WalkRules`. - /// - /// Returns whether to cut off the binding inheritance, that is, whether - /// document rules should _not_ apply. - fn each_xbl_cascade_data<'a, F>(&self, _: F) -> bool - where - Self: 'a, - F: FnMut(&'a CascadeData, QuirksMode), - { - false - } - /// Executes the callback for each applicable style rule data which isn't /// the main document's data (which stores UA / author rules). /// /// The element passed to the callback is the containing shadow host for the - /// data if it comes from Shadow DOM, None if it comes from XBL. + /// data if it comes from Shadow DOM. /// /// Returns whether normal document author rules should apply. fn each_applicable_non_document_style_rule_data<'a, F>(&self, mut f: F) -> bool where Self: 'a, - F: FnMut(&'a CascadeData, QuirksMode, Option), + F: FnMut(&'a CascadeData, Self), { use rule_collector::containing_shadow_ignoring_svg_use; - let mut doc_rules_apply = !self.each_xbl_cascade_data(|data, quirks_mode| { - f(data, quirks_mode, None); - }); + let mut doc_rules_apply = self.matches_user_and_author_rules(); // 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) { doc_rules_apply = false; if let Some(data) = shadow.style_data() { - f( - data, - self.as_node().owner_doc().quirks_mode(), - Some(shadow.host()), - ); + f(data, shadow.host()); } } if let Some(shadow) = self.shadow_root() { if let Some(data) = shadow.style_data() { - f( - data, - self.as_node().owner_doc().quirks_mode(), - Some(shadow.host()), - ); + f(data, shadow.host()); } } @@ -850,11 +823,7 @@ pub trait TElement: // Slots can only have assigned nodes when in a shadow tree. let shadow = slot.containing_shadow().unwrap(); if let Some(data) = shadow.style_data() { - f( - data, - self.as_node().owner_doc().quirks_mode(), - Some(shadow.host()), - ); + f(data, shadow.host()); } current = slot.assigned_slot(); } diff --git a/components/style/gecko/data.rs b/components/style/gecko/data.rs index ead7d88502b..0ce43bca46d 100644 --- a/components/style/gecko/data.rs +++ b/components/style/gecko/data.rs @@ -145,11 +145,6 @@ impl PerDocumentStyleData { /// Create a `PerDocumentStyleData`. pub fn new(document: *const structs::Document) -> Self { let device = Device::new(document); - - // FIXME(emilio, tlin): How is this supposed to work with XBL? This is - // right now not always honored, see bug 1405543... - // - // Should we just force XBL Stylists to be NoQuirks? let quirks_mode = device.document().mCompatMode; PerDocumentStyleData(AtomicRefCell::new(PerDocumentStyleDataImpl { diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 0fa354fb139..c295b795fdc 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -172,15 +172,7 @@ impl<'lr> TShadowRoot for GeckoShadowRoot<'lr> { Self: 'a, { let author_styles = unsafe { self.0.mServoStyles.mPtr.as_ref()? }; - let author_styles = AuthorStyles::::from_ffi(author_styles); - - debug_assert!( - author_styles.quirks_mode == self.as_node().owner_doc().quirks_mode() || - author_styles.stylesheets.is_empty() || - author_styles.stylesheets.dirty() - ); - Some(&author_styles.data) } @@ -536,11 +528,6 @@ impl<'lb> GeckoXBLBinding<'lb> { self.0.mContent.raw::() } - #[inline] - fn inherits_style(&self) -> bool { - unsafe { bindings::Gecko_XBLBinding_InheritsStyle(self.0) } - } - // This duplicates the logic in Gecko's // nsBindingManager::GetBindingWithContent. fn binding_with_content(&self) -> Option { @@ -552,22 +539,6 @@ impl<'lb> GeckoXBLBinding<'lb> { binding = binding.base_binding()?; } } - - fn each_xbl_cascade_data(&self, f: &mut F) - where - F: FnMut(&'lb CascadeData, QuirksMode), - { - if let Some(base) = self.base_binding() { - base.each_xbl_cascade_data(f); - } - - let data = unsafe { bindings::Gecko_XBLBinding_GetRawServoStyles(self.0).as_ref() }; - - if let Some(data) = data { - let data: &'lb _ = AuthorStyles::::from_ffi(data); - f(&data.data, data.quirks_mode) - } - } } /// A simple wrapper over a non-null Gecko `Element` pointer. @@ -1250,14 +1221,6 @@ impl<'le> TElement for GeckoElement<'le> { } } - fn has_same_xbl_proto_binding_as(&self, other: Self) -> bool { - match (self.xbl_binding(), other.xbl_binding()) { - (None, None) => true, - (Some(a), Some(b)) => a.0.mPrototypeBinding == b.0.mPrototypeBinding, - _ => false, - } - } - fn each_anonymous_content_child(&self, mut f: F) where F: FnMut(Self), @@ -1436,7 +1399,7 @@ impl<'le> TElement for GeckoElement<'le> { #[inline] fn matches_user_and_author_rules(&self) -> bool { - !self.is_in_native_anonymous_subtree() + !self.rule_hash_target().is_in_native_anonymous_subtree() } #[inline] @@ -1599,43 +1562,6 @@ impl<'le> TElement for GeckoElement<'le> { self.may_have_animations() && unsafe { Gecko_ElementHasCSSTransitions(self.0) } } - fn each_xbl_cascade_data<'a, F>(&self, mut f: F) -> bool - where - 'le: 'a, - F: FnMut(&'a CascadeData, QuirksMode), - { - // Walk the binding scope chain, starting with the binding attached to - // our content, up till we run out of scopes or we get cut off. - // - // If we are a NAC pseudo-element, we want to get rules from our - // rule_hash_target, that is, our originating element. - let mut current = Some(self.rule_hash_target()); - while let Some(element) = current { - if let Some(binding) = element.xbl_binding() { - binding.each_xbl_cascade_data(&mut f); - - // If we're not looking at our original element, allow the - // binding to cut off style inheritance. - if element != *self && !binding.inherits_style() { - // Go no further; we're not inheriting style from - // anything above here. - break; - } - } - - if element.is_root_of_native_anonymous_subtree() { - // Deliberately cut off style inheritance here. - break; - } - - current = element.xbl_binding_parent(); - } - - // If current has something, this means we cut off inheritance at some - // point in the loop. - current.is_some() - } - fn xbl_binding_anonymous_content(&self) -> Option> { self.xbl_binding_with_content() .map(|b| unsafe { GeckoNode::from_content(&*b.anon_content()) }) diff --git a/components/style/invalidation/element/state_and_attributes.rs b/components/style/invalidation/element/state_and_attributes.rs index e4555bb9a70..a49bb6306c5 100644 --- a/components/style/invalidation/element/state_and_attributes.rs +++ b/components/style/invalidation/element/state_and_attributes.rs @@ -224,8 +224,8 @@ where let mut shadow_rule_datas = SmallVec::<[_; 3]>::new(); let matches_document_author_rules = - element.each_applicable_non_document_style_rule_data(|data, quirks_mode, host| { - shadow_rule_datas.push((data, quirks_mode, host.map(|h| h.opaque()))) + element.each_applicable_non_document_style_rule_data(|data, host| { + shadow_rule_datas.push((data, host.opaque())) }); let invalidated_self = { @@ -258,12 +258,8 @@ where } } - for &(ref data, quirks_mode, ref host) in &shadow_rule_datas { - // FIXME(emilio): Replace with assert / remove when we figure - // out what to do with the quirks mode mismatches - // (that is, when bug 1406875 is properly fixed). - collector.matching_context.set_quirks_mode(quirks_mode); - collector.matching_context.current_host = host.clone(); + for &(ref data, ref host) in &shadow_rule_datas { + collector.matching_context.current_host = Some(host.clone()); collector.collect_dependencies_in_invalidation_map(data.invalidation_map()); } diff --git a/components/style/rule_collector.rs b/components/style/rule_collector.rs index ba602ddca83..e87a86c5e47 100644 --- a/components/style/rule_collector.rs +++ b/components/style/rule_collector.rs @@ -98,7 +98,7 @@ where flags_setter: &'a mut F, ) -> Self { let rule_hash_target = element.rule_hash_target(); - let matches_user_and_author_rules = rule_hash_target.matches_user_and_author_rules(); + let matches_user_and_author_rules = element.matches_user_and_author_rules(); // Gecko definitely has pseudo-elements with style attributes, like // ::-moz-color-swatch. @@ -198,7 +198,7 @@ where let rules = &mut self.rules; let flags_setter = &mut self.flags_setter; let shadow_cascade_order = self.shadow_cascade_order; - self.context.with_shadow_host(Some(shadow_host), |context| { + self.context.with_shadow_host(shadow_host, |context| { map.get_all_matching_rules( element, rule_hash_target, @@ -303,42 +303,6 @@ where self.collect_stylist_rules(Origin::Author); } - fn collect_xbl_rules(&mut self) { - let element = self.element; - let cut_xbl_binding_inheritance = - element.each_xbl_cascade_data(|cascade_data, quirks_mode| { - let map = match cascade_data.normal_rules(self.pseudo_element) { - Some(m) => m, - None => return, - }; - - // NOTE(emilio): This is needed because the XBL stylist may - // think it has a different quirks mode than the document. - let mut matching_context = MatchingContext::new( - self.context.matching_mode(), - self.context.bloom_filter, - self.context.nth_index_cache.as_mut().map(|s| &mut **s), - quirks_mode, - ); - matching_context.pseudo_element_matching_fn = - self.context.pseudo_element_matching_fn; - - // SameTreeAuthorNormal instead of InnerShadowNormal to - // preserve behavior, though that's kinda fishy... - map.get_all_matching_rules( - self.element, - self.rule_hash_target, - self.rules, - &mut matching_context, - self.flags_setter, - CascadeLevel::SameTreeAuthorNormal, - self.shadow_cascade_order, - ); - }); - - self.matches_document_author_rules &= !cut_xbl_binding_inheritance; - } - fn collect_style_attribute_and_animation_rules(&mut self) { if let Some(sa) = self.style_attribute { self.rules @@ -396,7 +360,6 @@ where self.collect_host_rules(); self.collect_slotted_rules(); self.collect_normal_rules_from_containing_shadow_tree(); - self.collect_xbl_rules(); self.collect_document_author_rules(); self.collect_style_attribute_and_animation_rules(); } diff --git a/components/style/sharing/mod.rs b/components/style/sharing/mod.rs index 0675359ed77..3ce2a717dc8 100644 --- a/components/style/sharing/mod.rs +++ b/components/style/sharing/mod.rs @@ -727,27 +727,6 @@ impl StyleSharingCache { return None; } - // Note that in theory we shouldn't need this XBL check. However, XBL is - // absolutely broken in all sorts of ways. - // - // A style change that changes which XBL binding applies to an element - // arrives there, with the element still having the old prototype - // binding attached. And thus we try to match revalidation selectors - // with the old XBL binding, because we can't look at the new ones of - // course. And that causes us to revalidate with the wrong selectors and - // hit assertions. - // - // Other than this, we don't need anything else like the containing XBL - // binding parent or what not, since two elements with different XBL - // bindings will necessarily end up with different style. - if !target - .element - .has_same_xbl_proto_binding_as(candidate.element) - { - trace!("Miss: Different proto bindings"); - return None; - } - // If the elements are not assigned to the same slot they could match // different ::slotted() rules in the slot scope. // diff --git a/components/style/stylesheet_set.rs b/components/style/stylesheet_set.rs index 5e72f7a219f..d8c21d5494c 100644 --- a/components/style/stylesheet_set.rs +++ b/components/style/stylesheet_set.rs @@ -546,7 +546,7 @@ where } } -/// The set of stylesheets effective for a given XBL binding or Shadow Root. +/// The set of stylesheets effective for a given Shadow Root. #[derive(MallocSizeOf)] pub struct AuthorStylesheetSet where diff --git a/components/style/stylist.rs b/components/style/stylist.rs index a22d850468e..08f3cee0464 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -636,7 +636,7 @@ impl Stylist { let mut maybe = false; let doc_author_rules_apply = - element.each_applicable_non_document_style_rule_data(|data, _, _| { + element.each_applicable_non_document_style_rule_data(|data, _| { maybe = maybe || f(&*data); }); @@ -1072,12 +1072,6 @@ impl Stylist { /// Returns whether, given a media feature change, any previously-applicable /// style has become non-applicable, or vice-versa for each origin, using /// `device`. - /// - /// Passing `device` is needed because this is used for XBL in Gecko, which - /// can be stale in various ways, so we need to pass the device of the - /// document itself, which is what is kept up-to-date. - /// - /// Arguably XBL should use something more lightweight than a Stylist. pub fn media_features_change_changed_style( &self, guards: &StylesheetGuards, @@ -1261,11 +1255,11 @@ impl Stylist { let mut results = SmallBitVec::new(); let matches_document_rules = - element.each_applicable_non_document_style_rule_data(|data, quirks_mode, host| { + element.each_applicable_non_document_style_rule_data(|data, host| { matching_context.with_shadow_host(host, |matching_context| { data.selectors_for_cache_revalidation.lookup( element, - quirks_mode, + self.quirks_mode, |selector_and_hashes| { results.push(matches_selector( &selector_and_hashes.selector,