style: Allow to share style across elements with similar XBL bindings.

This commit is contained in:
Emilio Cobos Álvarez 2018-03-07 02:04:56 +01:00
parent af12284b6a
commit c338745b17
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
4 changed files with 21 additions and 42 deletions

View file

@ -151,10 +151,10 @@ impl<'ln> NodeInfo for ServoLayoutNode<'ln> {
}
}
#[derive(Clone, Copy)]
#[derive(Clone, Copy, PartialEq)]
enum Impossible { }
#[derive(Clone, Copy)]
#[derive(Clone, Copy, PartialEq)]
pub struct ShadowRoot<'lr>(Impossible, PhantomData<&'lr ()>);
impl<'lr> TShadowRoot for ShadowRoot<'lr> {

View file

@ -321,7 +321,7 @@ fn fmt_subtree<F, N: TNode>(f: &mut fmt::Formatter, stringify: &F, n: N, indent:
}
/// The ShadowRoot trait.
pub trait TShadowRoot : Sized + Copy + Clone {
pub trait TShadowRoot : Sized + Copy + Clone + PartialEq {
/// The concrete node type.
type ConcreteNode: TNode<ConcreteShadowRoot = Self>;
@ -390,15 +390,6 @@ pub trait TElement
depth
}
/// The style scope of this element is a node that represents which rules
/// apply to the element.
///
/// In Servo, where we don't know about Shadow DOM or XBL, the style scope
/// is always the document.
fn style_scope(&self) -> Self::ConcreteNode {
self.as_node().owner_doc().as_node()
}
/// Get this node's parent element from the perspective of a restyle
/// traversal.
fn traversal_parent(&self) -> Option<Self> {

View file

@ -135,6 +135,13 @@ impl<'ld> TDocument for GeckoDocument<'ld> {
#[derive(Clone, Copy)]
pub struct GeckoShadowRoot<'lr>(pub &'lr structs::ShadowRoot);
impl<'lr> PartialEq for GeckoShadowRoot<'lr> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.0 as *const _ == other.0 as *const _
}
}
impl<'lr> TShadowRoot for GeckoShadowRoot<'lr> {
type ConcreteNode = GeckoNode<'lr>;
@ -1040,29 +1047,6 @@ impl<'le> TElement for GeckoElement<'le> {
self.before_or_after_pseudo(/* is_before = */ false)
}
/// Ensure this accurately represents the rules that an element may ever
/// match, even in the native anonymous content case.
fn style_scope(&self) -> Self::ConcreteNode {
if self.implemented_pseudo_element().is_some() {
return self.closest_non_native_anonymous_ancestor().unwrap().style_scope();
}
if self.is_in_native_anonymous_subtree() {
return self.as_node().owner_doc().as_node();
}
if self.xbl_binding().is_some() || self.shadow_root().is_some() {
return self.as_node();
}
if let Some(parent) = self.xbl_binding_parent() {
return parent.as_node();
}
self.as_node().owner_doc().as_node()
}
#[inline]
fn is_html_element(&self) -> bool {
self.namespace_id() == (structs::root::kNameSpaceID_XHTML as i32)

View file

@ -679,12 +679,14 @@ impl<E: TElement> StyleSharingCache<E> {
return None;
}
// Note that in the XBL case, we should be able to assert that the
// scopes are different, 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.style_scope() != candidate.element.style_scope() {
trace!("Miss: Different style scopes");
// If two elements belong to different shadow trees, different rules may
// 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() {
trace!("Miss: Different containing shadow roots");
return None;
}
@ -695,7 +697,9 @@ impl<E: TElement> StyleSharingCache<E> {
// shadow root, they could match different rules, due to the slot being
// assigned to yet another slot in another shadow root.
if target.element.assigned_slot() != candidate.element.assigned_slot() {
trace!("Miss: Different style scopes");
// TODO(emilio): We could have a look at whether the shadow roots
// actually have slotted rules and such.
trace!("Miss: Different assigned slots");
return None;
}