mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
style: Remove support for XBL resources.
So much unsound code going away :-) Differential Revision: https://phabricator.services.mozilla.com/D28380
This commit is contained in:
parent
50312e1457
commit
e5b5cd78a9
10 changed files with 22 additions and 208 deletions
|
@ -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<F, E, R>(&mut self, host: Option<E>, f: F) -> R
|
||||
pub fn with_shadow_host<F, E, R>(&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
|
||||
|
|
|
@ -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<S>
|
||||
where
|
||||
|
@ -28,9 +28,6 @@ where
|
|||
pub stylesheets: AuthorStylesheetSet<S>,
|
||||
/// 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<S> AuthorStyles<S>
|
||||
|
@ -43,7 +40,6 @@ where
|
|||
Self {
|
||||
stylesheets: AuthorStylesheetSet::new(),
|
||||
data: CascadeData::new(),
|
||||
quirks_mode: QuirksMode::NoQuirks,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,10 +61,6 @@ where
|
|||
.stylesheets
|
||||
.flush::<E>(/* host = */ None, /* snapshot_map = */ None);
|
||||
|
||||
if flusher.sheets.dirty() {
|
||||
self.quirks_mode = quirks_mode;
|
||||
}
|
||||
|
||||
// Ignore OOM.
|
||||
let _ = self
|
||||
.data
|
||||
|
|
|
@ -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<Self::ConcreteNode> {
|
||||
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<<Self::ConcreteNode as TNode>::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<Self>),
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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::<GeckoStyleSheet>::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::<nsIContent>()
|
||||
}
|
||||
|
||||
#[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<Self> {
|
||||
|
@ -552,22 +539,6 @@ impl<'lb> GeckoXBLBinding<'lb> {
|
|||
binding = binding.base_binding()?;
|
||||
}
|
||||
}
|
||||
|
||||
fn each_xbl_cascade_data<F>(&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::<GeckoStyleSheet>::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<F>(&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<GeckoNode<'le>> {
|
||||
self.xbl_binding_with_content()
|
||||
.map(|b| unsafe { GeckoNode::from_content(&*b.anon_content()) })
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -727,27 +727,6 @@ impl<E: TElement> StyleSharingCache<E> {
|
|||
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.
|
||||
//
|
||||
|
|
|
@ -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<S>
|
||||
where
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue