mirror of
https://github.com/servo/servo.git
synced 2025-08-02 20:20:14 +01:00
style: Add plumbing code to invalidate shadow parts.
Still does nothing, since we still do not collect part rules, but this is all the plumbing that should allow us to invalidate parts when attributes or state change on their ancestors. Differential Revision: https://phabricator.services.mozilla.com/D32642
This commit is contained in:
parent
a4690ce158
commit
f0bf7d6481
5 changed files with 72 additions and 4 deletions
|
@ -346,6 +346,14 @@ pub trait TShadowRoot: Sized + Copy + Clone + PartialEq {
|
|||
where
|
||||
Self: 'a;
|
||||
|
||||
/// Get the list of shadow parts for this shadow root.
|
||||
fn parts<'a>(&self) -> &[<Self::ConcreteNode as TNode>::ConcreteElement]
|
||||
where
|
||||
Self: 'a
|
||||
{
|
||||
&[]
|
||||
}
|
||||
|
||||
/// Get a list of elements with a given ID in this shadow root, sorted by
|
||||
/// tree position.
|
||||
///
|
||||
|
|
|
@ -185,6 +185,21 @@ impl<'lr> TShadowRoot for GeckoShadowRoot<'lr> {
|
|||
bindings::Gecko_ShadowRoot_GetElementsWithId(self.0, id.as_ptr())
|
||||
}))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn parts<'a>(&self) -> &[<Self::ConcreteNode as TNode>::ConcreteElement]
|
||||
where
|
||||
Self: 'a
|
||||
{
|
||||
let slice: &[*const RawGeckoElement] = &*self.0.mParts;
|
||||
|
||||
#[allow(dead_code)]
|
||||
unsafe fn static_assert() {
|
||||
mem::transmute::<*const RawGeckoElement, GeckoElement<'static>>(0xbadc0de as *const _);
|
||||
}
|
||||
|
||||
unsafe { mem::transmute(slice) }
|
||||
}
|
||||
}
|
||||
|
||||
/// A simple wrapper over a non-null Gecko node (`nsINode`) pointer.
|
||||
|
|
|
@ -66,6 +66,8 @@ pub enum DependencyInvalidationKind {
|
|||
Siblings,
|
||||
/// This dependency may affect slotted elements of the element that changed.
|
||||
SlottedElements,
|
||||
/// This dependency may affect parts of the element that changed.
|
||||
Parts,
|
||||
}
|
||||
|
||||
impl Dependency {
|
||||
|
@ -98,7 +100,7 @@ impl Dependency {
|
|||
// an eager pseudo, and return only Descendants here if not.
|
||||
Some(Combinator::PseudoElement) => DependencyInvalidationKind::ElementAndDescendants,
|
||||
Some(Combinator::SlotAssignment) => DependencyInvalidationKind::SlottedElements,
|
||||
Some(Combinator::Part) => unimplemented!("Need to add invalidation for shadow parts"),
|
||||
Some(Combinator::Part) => DependencyInvalidationKind::Parts,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,11 +72,14 @@ pub struct DescendantInvalidationLists<'a> {
|
|||
pub dom_descendants: InvalidationVector<'a>,
|
||||
/// Invalidations for slotted children of an element.
|
||||
pub slotted_descendants: InvalidationVector<'a>,
|
||||
/// Invalidations for ::part()s of an element.
|
||||
pub parts: InvalidationVector<'a>,
|
||||
}
|
||||
|
||||
impl<'a> DescendantInvalidationLists<'a> {
|
||||
fn is_empty(&self) -> bool {
|
||||
self.dom_descendants.is_empty() && self.slotted_descendants.is_empty()
|
||||
self.dom_descendants.is_empty() && self.slotted_descendants.is_empty() &&
|
||||
self.parts.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,6 +107,8 @@ enum DescendantInvalidationKind {
|
|||
Dom,
|
||||
/// A ::slotted() descendant invalidation.
|
||||
Slotted,
|
||||
/// A ::part() descendant invalidation.
|
||||
Part,
|
||||
}
|
||||
|
||||
/// The kind of invalidation we're processing.
|
||||
|
@ -175,7 +180,7 @@ impl<'a> Invalidation<'a> {
|
|||
InvalidationKind::Descendant(DescendantInvalidationKind::Dom)
|
||||
},
|
||||
Combinator::Part => {
|
||||
unimplemented!("Need to add invalidation for shadow parts");
|
||||
InvalidationKind::Descendant(DescendantInvalidationKind::Part)
|
||||
},
|
||||
Combinator::SlotAssignment => {
|
||||
InvalidationKind::Descendant(DescendantInvalidationKind::Slotted)
|
||||
|
@ -472,6 +477,36 @@ where
|
|||
any_descendant
|
||||
}
|
||||
|
||||
fn invalidate_parts(&mut self, invalidations: &[Invalidation<'b>]) -> bool {
|
||||
if invalidations.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let shadow = match self.element.shadow_root() {
|
||||
Some(s) => s,
|
||||
None => return false,
|
||||
};
|
||||
|
||||
let mut any = false;
|
||||
let mut sibling_invalidations = InvalidationVector::new();
|
||||
for element in shadow.parts() {
|
||||
any |= self.invalidate_child(
|
||||
*element,
|
||||
invalidations,
|
||||
&mut sibling_invalidations,
|
||||
DescendantInvalidationKind::Part,
|
||||
);
|
||||
debug_assert!(
|
||||
sibling_invalidations.is_empty(),
|
||||
"::part() shouldn't have sibling combinators to the right, \
|
||||
this makes no sense! {:?}",
|
||||
sibling_invalidations
|
||||
);
|
||||
}
|
||||
any
|
||||
}
|
||||
|
||||
|
||||
fn invalidate_slotted_elements(&mut self, invalidations: &[Invalidation<'b>]) -> bool {
|
||||
if invalidations.is_empty() {
|
||||
return false;
|
||||
|
@ -598,6 +633,7 @@ where
|
|||
|
||||
any_descendant |= self.invalidate_non_slotted_descendants(&invalidations.dom_descendants);
|
||||
any_descendant |= self.invalidate_slotted_elements(&invalidations.slotted_descendants);
|
||||
any_descendant |= self.invalidate_parts(&invalidations.parts);
|
||||
|
||||
any_descendant
|
||||
}
|
||||
|
@ -672,7 +708,7 @@ where
|
|||
debug_assert_eq!(
|
||||
descendant_invalidation_kind,
|
||||
DescendantInvalidationKind::Dom,
|
||||
"Slotted invalidations don't propagate."
|
||||
"Slotted or part invalidations don't propagate."
|
||||
);
|
||||
descendant_invalidations.dom_descendants.push(invalidation);
|
||||
}
|
||||
|
@ -860,6 +896,9 @@ where
|
|||
.dom_descendants
|
||||
.push(next_invalidation);
|
||||
},
|
||||
InvalidationKind::Descendant(DescendantInvalidationKind::Part) => {
|
||||
descendant_invalidations.parts.push(next_invalidation);
|
||||
},
|
||||
InvalidationKind::Descendant(DescendantInvalidationKind::Slotted) => {
|
||||
descendant_invalidations
|
||||
.slotted_descendants
|
||||
|
|
|
@ -472,6 +472,9 @@ where
|
|||
DependencyInvalidationKind::Siblings => {
|
||||
self.sibling_invalidations.push(invalidation);
|
||||
},
|
||||
DependencyInvalidationKind::Parts => {
|
||||
self.descendant_invalidations.parts.push(invalidation);
|
||||
},
|
||||
DependencyInvalidationKind::SlottedElements => {
|
||||
self.descendant_invalidations
|
||||
.slotted_descendants
|
||||
|
@ -486,6 +489,7 @@ where
|
|||
match dependency.invalidation_kind() {
|
||||
DependencyInvalidationKind::Element => !self.invalidates_self,
|
||||
DependencyInvalidationKind::SlottedElements => self.element.is_html_slot_element(),
|
||||
DependencyInvalidationKind::Parts => self.element.shadow_root().is_some(),
|
||||
DependencyInvalidationKind::ElementAndDescendants |
|
||||
DependencyInvalidationKind::Siblings |
|
||||
DependencyInvalidationKind::Descendants => true,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue