mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Use "slot" attribute for slottable name (#35191)
* Implement Element::slot attribute Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Simplify slottable name update Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Update WPT expectations Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> --------- Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This commit is contained in:
parent
c633ca1cde
commit
f6d1b30e97
9 changed files with 18 additions and 98 deletions
|
@ -2241,6 +2241,12 @@ impl ElementMethods<crate::DomTypeHolder> for Element {
|
|||
.or_init(|| DOMTokenList::new(self, &local_name!("class"), None))
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-element-slot
|
||||
make_getter!(Slot, "slot");
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-element-slot
|
||||
make_setter!(SetSlot, "slot");
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-element-attributes
|
||||
fn Attributes(&self) -> DomRoot<NamedNodeMap> {
|
||||
self.attr_list
|
||||
|
@ -3666,7 +3672,12 @@ impl VirtualMethods for Element {
|
|||
// Update slottable data
|
||||
let cx = GlobalScope::get_cx();
|
||||
rooted!(in(*cx) let slottable = Slottable::Element(Dom::from_ref(self)));
|
||||
slottable.update_slot_name(attr, mutation, CanGc::note())
|
||||
|
||||
// Slottable name change steps from https://dom.spec.whatwg.org/#light-tree-slotables
|
||||
if let Some(assigned_slot) = slottable.assigned_slot() {
|
||||
assigned_slot.assign_slottables();
|
||||
}
|
||||
slottable.assign_a_slot();
|
||||
},
|
||||
_ => {
|
||||
// FIXME(emilio): This is pretty dubious, and should be done in
|
||||
|
|
|
@ -8,8 +8,6 @@ use dom_struct::dom_struct;
|
|||
use html5ever::{local_name, namespace_url, ns, LocalName, Prefix};
|
||||
use js::gc::{RootedGuard, RootedVec};
|
||||
use js::rust::HandleObject;
|
||||
use servo_atoms::Atom;
|
||||
use style::attr::AttrValue;
|
||||
|
||||
use crate::dom::attr::Attr;
|
||||
use crate::dom::bindings::codegen::Bindings::HTMLSlotElementBinding::{
|
||||
|
@ -382,58 +380,6 @@ impl Slottable {
|
|||
None
|
||||
}
|
||||
|
||||
/// Slottable name change steps from <https://dom.spec.whatwg.org/#light-tree-slotables>
|
||||
pub(crate) fn update_slot_name(&self, attr: &Attr, mutation: AttributeMutation, can_gc: CanGc) {
|
||||
debug_assert!(matches!(self, Self::Element(_)));
|
||||
|
||||
// Step 1. If localName is slot and namespace is null:
|
||||
// NOTE: This is done by the caller
|
||||
let old_value = if let AttributeMutation::Set(old_name) = mutation {
|
||||
old_name.and_then(|attr| match attr {
|
||||
AttrValue::String(s) => Some(s.clone()),
|
||||
_ => None,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let value = mutation.new_value(attr).and_then(|attr| match &*attr {
|
||||
AttrValue::String(s) => Some(s.clone()),
|
||||
_ => None,
|
||||
});
|
||||
|
||||
// Step 1.1 If value is oldValue, then return.
|
||||
if value == old_value {
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 1.2 If value is null and oldValue is the empty string, then return.
|
||||
if value.is_none() && old_value.as_ref().is_some_and(|s| s.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 1.3 If value is the empty string and oldValue is null, then return.
|
||||
if old_value.is_none() && value.as_ref().is_some_and(|s| s.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 1.4 If value is null or the empty string, then set element’s name to the empty string.
|
||||
if value.as_ref().is_none_or(|s| s.is_empty()) {
|
||||
self.set_name(DOMString::new(), can_gc);
|
||||
}
|
||||
// Step 1.5 Otherwise, set element’s name to value.
|
||||
else {
|
||||
self.set_name(DOMString::from(value.unwrap_or_default()), can_gc);
|
||||
}
|
||||
|
||||
// Step 1.6 If element is assigned, then run assign slottables for element’s assigned slot.
|
||||
if let Some(assigned_slot) = self.assigned_slot() {
|
||||
assigned_slot.assign_slottables();
|
||||
}
|
||||
|
||||
// Step 1.7 Run assign a slot for element.
|
||||
self.assign_a_slot();
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#assign-a-slot>
|
||||
pub(crate) fn assign_a_slot(&self) {
|
||||
// Step 1. Let slot be the result of finding a slot with slottable.
|
||||
|
@ -452,7 +398,7 @@ impl Slottable {
|
|||
}
|
||||
}
|
||||
|
||||
fn assigned_slot(&self) -> Option<DomRoot<HTMLSlotElement>> {
|
||||
pub(crate) fn assigned_slot(&self) -> Option<DomRoot<HTMLSlotElement>> {
|
||||
match self {
|
||||
Self::Element(element) => element.assigned_slot(),
|
||||
Self::Text(text) => {
|
||||
|
@ -501,30 +447,13 @@ impl Slottable {
|
|||
}
|
||||
}
|
||||
|
||||
fn set_name(&self, name: DOMString, can_gc: CanGc) {
|
||||
// NOTE: Only elements have non-empty names
|
||||
let Self::Element(element) = self else {
|
||||
return;
|
||||
};
|
||||
let element = element.as_rooted();
|
||||
element.set_attribute(
|
||||
&local_name!("name"),
|
||||
AttrValue::Atom(Atom::from(name)),
|
||||
can_gc,
|
||||
);
|
||||
}
|
||||
|
||||
fn name(&self) -> DOMString {
|
||||
// NOTE: Only elements have non-empty names
|
||||
let Self::Element(element) = self else {
|
||||
return DOMString::new();
|
||||
};
|
||||
|
||||
element
|
||||
.name_attribute()
|
||||
.map(|a| DOMString::from(a.as_ref()))
|
||||
.unwrap_or_default()
|
||||
.clone()
|
||||
element.get_string_attribute(&local_name!("slot"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ interface Element : Node {
|
|||
attribute DOMString className;
|
||||
[SameObject, PutForwards=value]
|
||||
readonly attribute DOMTokenList classList;
|
||||
[CEReactions, Unscopable] attribute DOMString slot;
|
||||
|
||||
[Pure]
|
||||
boolean hasAttributes();
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
[Element.html]
|
||||
[slot on Element must enqueue an attributeChanged reaction when adding slot content attribute]
|
||||
expected: FAIL
|
||||
|
||||
[slot on Element must enqueue an attributeChanged reaction when replacing an existing attribute]
|
||||
expected: FAIL
|
3
tests/wpt/meta/dom/idlharness.window.js.ini
vendored
3
tests/wpt/meta/dom/idlharness.window.js.ini
vendored
|
@ -56,9 +56,6 @@
|
|||
[CharacterData interface: operation remove()]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: element must inherit property "slot" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[AbortController interface: new AbortController() must inherit property "signal" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -8,15 +8,6 @@
|
|||
[assignedNodes({"flattened":true}) must return the list of assigned nodes when none of the assigned nodes themselves are slots]
|
||||
expected: FAIL
|
||||
|
||||
[assignedNodes() must update when slot and name attributes are modified]
|
||||
expected: FAIL
|
||||
|
||||
[assignedNodes({"flattened":false}) must update when slot and name attributes are modified]
|
||||
expected: FAIL
|
||||
|
||||
[assignedNodes({"flattened":true}) must update when slot and name attributes are modified]
|
||||
expected: FAIL
|
||||
|
||||
[assignedNodes() must update when slot elements are inserted or removed]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
[Slottable-mixin.html]
|
||||
[assignedSlot must return the assigned slot]
|
||||
expected: FAIL
|
|
@ -3,8 +3,5 @@
|
|||
[slotchange event: Append a child to a host.]
|
||||
expected: TIMEOUT
|
||||
|
||||
[slotchange event: A slot is assigned to another slot.]
|
||||
expected: TIMEOUT
|
||||
|
||||
[slotchange event: Child content is added to nested slots.]
|
||||
expected: TIMEOUT
|
||||
|
|
3
tests/wpt/meta/shadow-dom/slots.html.ini
vendored
3
tests/wpt/meta/shadow-dom/slots.html.ini
vendored
|
@ -31,3 +31,6 @@
|
|||
|
||||
[Slots: Mutation: Change slot slot= attribute.]
|
||||
expected: FAIL
|
||||
|
||||
[Slots: Mutation: Remove a slot.]
|
||||
expected: FAIL
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue