mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 11:55:49 +00:00
Bug 1505489 - Add plumbing code to invalidate shadow parts. r=heycam
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. Depends on D32641 Differential Revision: https://phabricator.services.mozilla.com/D32642 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
c4dbe4893c
commit
103cf22ede
@ -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…
Reference in New Issue
Block a user