зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1854658 - Fix the part combinator to deal with exportparts correctly. r=zrhoffman
We need to jump to an element in the correct scope just like ::slotted() does. Factor that code to its own function both so that it's easier to reason about and so that the code for that function remains small. At the end of the day other combinators like descendant or sibling get executed a ton of times (while pseudo-elements only jump once). Differential Revision: https://phabricator.services.mozilla.com/D189478
This commit is contained in:
Родитель
338171a737
Коммит
0e00ba901b
|
@ -646,6 +646,37 @@ enum Rightmost {
|
|||
No,
|
||||
}
|
||||
|
||||
fn host_for_part<E>(element: &E, context: &MatchingContext<E::Impl>) -> Option<E>
|
||||
where
|
||||
E: Element,
|
||||
{
|
||||
let scope = context.current_host;
|
||||
let mut curr = element.containing_shadow_host()?;
|
||||
if scope == Some(curr.opaque()) {
|
||||
return Some(curr);
|
||||
}
|
||||
loop {
|
||||
let parent = curr.containing_shadow_host();
|
||||
if parent.as_ref().map(|h| h.opaque()) == scope {
|
||||
return Some(curr);
|
||||
}
|
||||
curr = parent?;
|
||||
}
|
||||
}
|
||||
|
||||
fn assigned_slot<E>(element: &E, context: &MatchingContext<E::Impl>) -> Option<E>
|
||||
where
|
||||
E: Element,
|
||||
{
|
||||
debug_assert!(element.assigned_slot().map_or(true, |s| s.is_html_slot_element()));
|
||||
let scope = context.current_host?;
|
||||
let mut current_slot = element.assigned_slot()?;
|
||||
while current_slot.containing_shadow_host().unwrap().opaque() != scope {
|
||||
current_slot = current_slot.assigned_slot()?;
|
||||
}
|
||||
Some(current_slot)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn next_element_for_combinator<E>(
|
||||
element: &E,
|
||||
|
@ -690,18 +721,8 @@ where
|
|||
|
||||
element.containing_shadow_host()
|
||||
},
|
||||
Combinator::Part => element.containing_shadow_host(),
|
||||
Combinator::SlotAssignment => {
|
||||
debug_assert!(element
|
||||
.assigned_slot()
|
||||
.map_or(true, |s| s.is_html_slot_element()));
|
||||
let scope = context.current_host?;
|
||||
let mut current_slot = element.assigned_slot()?;
|
||||
while current_slot.containing_shadow_host().unwrap().opaque() != scope {
|
||||
current_slot = current_slot.assigned_slot()?;
|
||||
}
|
||||
Some(current_slot)
|
||||
},
|
||||
Combinator::Part => host_for_part(element, context),
|
||||
Combinator::SlotAssignment => assigned_slot(element, context),
|
||||
Combinator::PseudoElement => element.pseudo_element_originating_element(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
<!doctype html>
|
||||
<title>CSS Test Reference</title>
|
||||
<span style="color: green">Should be green</span>
|
|
@ -0,0 +1,31 @@
|
|||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
|
||||
<link rel="author" href="https://mozilla.org" title="Mozilla">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-shadow-parts/">
|
||||
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1854658">
|
||||
<link rel="match" href="exportparts-different-scope-ref.html">
|
||||
<style>
|
||||
my-foo::part(text) { color: green; }
|
||||
my-bar::part(text) { color: red; background-color: red; }
|
||||
</style>
|
||||
<my-foo></my-foo>
|
||||
<script>
|
||||
customElements.define('my-foo', class extends HTMLElement {
|
||||
constructor(){
|
||||
super()
|
||||
this.attachShadow({mode: 'closed'}).innerHTML = `
|
||||
<my-bar exportparts="text"></my-bar>
|
||||
`;
|
||||
}
|
||||
})
|
||||
|
||||
customElements.define('my-bar', class extends HTMLElement {
|
||||
constructor(){
|
||||
super()
|
||||
this.attachShadow({mode: 'closed'}).innerHTML = `
|
||||
<span part="text">Should be green</span>
|
||||
`;
|
||||
}
|
||||
})
|
||||
</script>
|
Загрузка…
Ссылка в новой задаче