mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
style: Invalidate parts in nested shadow trees correctly.
Differential Revision: https://phabricator.services.mozilla.com/D54010
This commit is contained in:
parent
e3009a4de9
commit
f8ceb5cb84
6 changed files with 104 additions and 43 deletions
|
@ -62,6 +62,12 @@ pub trait ElementSnapshot: Sized {
|
|||
/// called if `has_attrs()` returns true.
|
||||
fn is_part(&self, name: &Atom) -> bool;
|
||||
|
||||
/// See Element::exported_part.
|
||||
fn exported_part(&self, name: &Atom) -> Option<Atom>;
|
||||
|
||||
/// See Element::imported_part.
|
||||
fn imported_part(&self, name: &Atom) -> Option<Atom>;
|
||||
|
||||
/// A callback that should be called for each class of the snapshot. Should
|
||||
/// only be called if `has_attrs()` returns true.
|
||||
fn each_class<F>(&self, _: F)
|
||||
|
@ -366,13 +372,17 @@ where
|
|||
}
|
||||
|
||||
fn exported_part(&self, name: &Atom) -> Option<Atom> {
|
||||
// FIXME(emilio): Implement for proper invalidation.
|
||||
self.element.exported_part(name)
|
||||
match self.snapshot() {
|
||||
Some(snapshot) if snapshot.has_attrs() => snapshot.exported_part(name),
|
||||
_ => self.element.exported_part(name),
|
||||
}
|
||||
}
|
||||
|
||||
fn imported_part(&self, name: &Atom) -> Option<Atom> {
|
||||
// FIXME(emilio): Implement for proper invalidation.
|
||||
self.element.imported_part(name)
|
||||
match self.snapshot() {
|
||||
Some(snapshot) if snapshot.has_attrs() => snapshot.imported_part(name),
|
||||
_ => self.element.imported_part(name),
|
||||
}
|
||||
}
|
||||
|
||||
fn has_class(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool {
|
||||
|
|
|
@ -129,6 +129,10 @@ enum InvalidationKind {
|
|||
pub struct Invalidation<'a> {
|
||||
selector: &'a Selector<SelectorImpl>,
|
||||
/// The right shadow host from where the rule came from, if any.
|
||||
///
|
||||
/// This is needed to ensure that we match the selector with the right
|
||||
/// state, as whether some selectors like :host and ::part() match depends
|
||||
/// on it.
|
||||
scope: Option<OpaqueElement>,
|
||||
/// The offset of the selector pointing to a compound selector.
|
||||
///
|
||||
|
@ -479,6 +483,47 @@ where
|
|||
any_descendant
|
||||
}
|
||||
|
||||
fn invalidate_parts_in_shadow_tree(
|
||||
&mut self,
|
||||
shadow: <E::ConcreteNode as TNode>::ConcreteShadowRoot,
|
||||
invalidations: &[Invalidation<'b>],
|
||||
) -> bool {
|
||||
debug_assert!(!invalidations.is_empty());
|
||||
|
||||
let mut any = false;
|
||||
let mut sibling_invalidations = InvalidationVector::new();
|
||||
|
||||
for node in shadow.as_node().dom_descendants() {
|
||||
let element = match node.as_element() {
|
||||
Some(e) => e,
|
||||
None => continue,
|
||||
};
|
||||
|
||||
if element.has_part_attr() {
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(shadow) = element.shadow_root() {
|
||||
if element.exports_any_part() {
|
||||
any |= self.invalidate_parts_in_shadow_tree(shadow, invalidations)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
any
|
||||
}
|
||||
|
||||
fn invalidate_parts(&mut self, invalidations: &[Invalidation<'b>]) -> bool {
|
||||
if invalidations.is_empty() {
|
||||
return false;
|
||||
|
@ -489,26 +534,7 @@ where
|
|||
None => return false,
|
||||
};
|
||||
|
||||
let mut any = false;
|
||||
let mut sibling_invalidations = InvalidationVector::new();
|
||||
|
||||
// FIXME(emilio): We also need to invalidate parts in descendant shadow
|
||||
// hosts that have exportparts attributes.
|
||||
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
|
||||
self.invalidate_parts_in_shadow_tree(shadow, invalidations)
|
||||
}
|
||||
|
||||
fn invalidate_slotted_elements(&mut self, invalidations: &[Invalidation<'b>]) -> bool {
|
||||
|
@ -733,7 +759,7 @@ where
|
|||
);
|
||||
|
||||
let matching_result = {
|
||||
let mut context = self.processor.matching_context();
|
||||
let context = self.processor.matching_context();
|
||||
context.current_host = invalidation.scope;
|
||||
|
||||
matches_compound_selector_from(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue