mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
style: Don't share style with an element that has a different proto binding than us.
See the lengthy comment about why... XBL sucks. MozReview-Commit-ID: 8UgeJAVkj6a
This commit is contained in:
parent
c338745b17
commit
9364cd21b8
3 changed files with 31 additions and 6 deletions
|
@ -739,6 +739,9 @@ pub trait TElement
|
||||||
/// The shadow root which roots the subtree this element is contained in.
|
/// The shadow root which roots the subtree this element is contained in.
|
||||||
fn containing_shadow(&self) -> Option<<Self::ConcreteNode as TNode>::ConcreteShadowRoot>;
|
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
|
/// Return the element which we can use to look up rules in the selector
|
||||||
/// maps.
|
/// maps.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1092,8 +1092,16 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
unsafe { slots._base.mContainingShadow.mRawPtr.as_ref().map(GeckoShadowRoot) }
|
unsafe { slots._base.mContainingShadow.mRawPtr.as_ref().map(GeckoShadowRoot) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Execute `f` for each anonymous content child element (apart from
|
fn has_same_xbl_proto_binding_as(&self, other: Self) -> bool {
|
||||||
/// ::before and ::after) whose originating element is `self`.
|
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)
|
fn each_anonymous_content_child<F>(&self, mut f: F)
|
||||||
where
|
where
|
||||||
F: FnMut(Self),
|
F: FnMut(Self),
|
||||||
|
|
|
@ -681,15 +681,29 @@ impl<E: TElement> StyleSharingCache<E> {
|
||||||
|
|
||||||
// If two elements belong to different shadow trees, different rules may
|
// If two elements belong to different shadow trees, different rules may
|
||||||
// apply to them, from the respective trees.
|
// apply to them, from the respective trees.
|
||||||
//
|
|
||||||
// Note that we don't need the same for XBL case, since two elements
|
|
||||||
// with different XBL bindings need to necessarily have different style
|
|
||||||
// (and thus children of them would never pass the parent check).
|
|
||||||
if target.element.containing_shadow() != candidate.element.containing_shadow() {
|
if target.element.containing_shadow() != candidate.element.containing_shadow() {
|
||||||
trace!("Miss: Different containing shadow roots");
|
trace!("Miss: Different containing shadow roots");
|
||||||
return None;
|
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
|
// If the elements are not assigned to the same slot they could match
|
||||||
// different ::slotted() rules in the slot scope.
|
// different ::slotted() rules in the slot scope.
|
||||||
//
|
//
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue