mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Check whether an element is custom in the spec-compliant way (#35960)
* Check whether element is custom in spec-compliant way Signed-off-by: Xiaocheng Hu <xiaochengh.work@gmail.com> * Update tests Signed-off-by: Xiaocheng Hu <xiaochengh.work@gmail.com> --------- Signed-off-by: Xiaocheng Hu <xiaochengh.work@gmail.com>
This commit is contained in:
parent
ea35353e9a
commit
62d6759106
6 changed files with 71 additions and 13 deletions
|
@ -166,7 +166,7 @@ impl Attr {
|
|||
|
||||
MutationObserver::queue_a_mutation_record(owner.upcast::<Node>(), mutation);
|
||||
|
||||
if owner.get_custom_element_definition().is_some() {
|
||||
if owner.is_custom() {
|
||||
let reaction = CallbackReaction::AttributeChanged(
|
||||
name,
|
||||
Some(old_value),
|
||||
|
|
|
@ -371,6 +371,11 @@ impl Element {
|
|||
CustomElementState::Uncustomized
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#concept-element-custom>
|
||||
pub(crate) fn is_custom(&self) -> bool {
|
||||
self.get_custom_element_state() == CustomElementState::Custom
|
||||
}
|
||||
|
||||
pub(crate) fn set_custom_element_definition(&self, definition: Rc<CustomElementDefinition>) {
|
||||
self.ensure_rare_data().custom_element_definition = Some(definition);
|
||||
}
|
||||
|
@ -1580,7 +1585,7 @@ impl Element {
|
|||
|
||||
MutationObserver::queue_a_mutation_record(&self.node, mutation);
|
||||
|
||||
if self.get_custom_element_definition().is_some() {
|
||||
if self.is_custom() {
|
||||
let value = DOMString::from(&**attr.value());
|
||||
let reaction = CallbackReaction::AttributeChanged(name, None, Some(value), namespace);
|
||||
ScriptThread::enqueue_callback_reaction(self, reaction, None);
|
||||
|
@ -1772,9 +1777,11 @@ impl Element {
|
|||
|
||||
MutationObserver::queue_a_mutation_record(&self.node, mutation);
|
||||
|
||||
let reaction =
|
||||
CallbackReaction::AttributeChanged(name, Some(old_value), None, namespace);
|
||||
ScriptThread::enqueue_callback_reaction(self, reaction, None);
|
||||
if self.is_custom() {
|
||||
let reaction =
|
||||
CallbackReaction::AttributeChanged(name, Some(old_value), None, namespace);
|
||||
ScriptThread::enqueue_callback_reaction(self, reaction, None);
|
||||
}
|
||||
|
||||
self.attrs.borrow_mut().remove(idx);
|
||||
attr.set_owner(None);
|
||||
|
@ -2453,7 +2460,7 @@ impl ElementMethods<crate::DomTypeHolder> for Element {
|
|||
}
|
||||
|
||||
// Step 4.
|
||||
if self.get_custom_element_definition().is_some() {
|
||||
if self.is_custom() {
|
||||
let old_name = old_attr.local_name().clone();
|
||||
let old_value = DOMString::from(&**old_attr.value());
|
||||
let new_value = DOMString::from(&**attr.value());
|
||||
|
|
|
@ -422,7 +422,8 @@ impl Node {
|
|||
|
||||
pub(crate) fn as_custom_element(&self) -> Option<DomRoot<Element>> {
|
||||
self.downcast::<Element>().and_then(|element| {
|
||||
if element.get_custom_element_definition().is_some() {
|
||||
if element.is_custom() {
|
||||
assert!(element.get_custom_element_definition().is_some());
|
||||
Some(DomRoot::from_ref(element))
|
||||
} else {
|
||||
None
|
||||
|
@ -2334,7 +2335,7 @@ impl Node {
|
|||
.filter_map(DomRoot::downcast::<Element>)
|
||||
{
|
||||
// Step 7.7.2, whatwg/dom#833
|
||||
if descendant.get_custom_element_definition().is_some() {
|
||||
if descendant.is_custom() {
|
||||
if descendant.is_connected() {
|
||||
ScriptThread::enqueue_callback_reaction(
|
||||
&descendant,
|
||||
|
|
2
tests/wpt/meta/MANIFEST.json
vendored
2
tests/wpt/meta/MANIFEST.json
vendored
|
@ -612804,7 +612804,7 @@
|
|||
]
|
||||
],
|
||||
"custom-element-reaction-queue.html": [
|
||||
"246b15a0af36cffa0b64f1d57e4208538b92bdd7",
|
||||
"eb8366f2b415894f396da613987982ae41ffe0b6",
|
||||
[
|
||||
null,
|
||||
{}
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
[custom-element-reaction-queue.html]
|
||||
[Upgrading a custom element must not invoke attributeChangedCallback for the attribute that is changed during upgrading]
|
||||
expected: FAIL
|
||||
|
|
@ -83,6 +83,60 @@ test_with_window(function (contentWindow) {
|
|||
assert_connected_log_entry(log[1], element);
|
||||
}, 'Upgrading a custom element must not invoke attributeChangedCallback for the attribute that is changed during upgrading');
|
||||
|
||||
test_with_window(function (contentWindow) {
|
||||
const contentDocument = contentWindow.document;
|
||||
contentDocument.write('<test-element>');
|
||||
|
||||
const element = contentDocument.querySelector('test-element');
|
||||
assert_equals(Object.getPrototypeOf(element), contentWindow.HTMLElement.prototype);
|
||||
|
||||
let log = [];
|
||||
class TestElement extends contentWindow.HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.remove();
|
||||
log.push(create_constructor_log(this));
|
||||
}
|
||||
connectedCallback(...args) {
|
||||
log.push(create_connected_callback_log(this, ...args));
|
||||
}
|
||||
disconnectedCallback(...args) {
|
||||
log.push(create_disconnected_callback_log(this, ...args));
|
||||
}
|
||||
}
|
||||
contentWindow.customElements.define('test-element', TestElement);
|
||||
assert_equals(Object.getPrototypeOf(element), TestElement.prototype);
|
||||
|
||||
assert_equals(log.length, 2);
|
||||
assert_constructor_log_entry(log[0], element);
|
||||
assert_connected_log_entry(log[1], element);
|
||||
}, 'Upgrading a custom element must not invoke disconnectedCallback if the element is disconnected during upgrading');
|
||||
|
||||
test_with_window(function (contentWindow) {
|
||||
const contentDocument = contentWindow.document;
|
||||
const element = contentDocument.createElement('test-element');
|
||||
assert_equals(Object.getPrototypeOf(element), contentWindow.HTMLElement.prototype);
|
||||
|
||||
let log = [];
|
||||
class TestElement extends contentWindow.HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
contentDocument.documentElement.appendChild(this);
|
||||
log.push(create_constructor_log(this));
|
||||
}
|
||||
connectedCallback(...args) {
|
||||
log.push(create_connected_callback_log(this, ...args));
|
||||
}
|
||||
}
|
||||
contentWindow.customElements.define('test-element', TestElement);
|
||||
contentWindow.customElements.upgrade(element);
|
||||
|
||||
assert_equals(Object.getPrototypeOf(element), TestElement.prototype);
|
||||
|
||||
assert_equals(log.length, 1);
|
||||
assert_constructor_log_entry(log[0], element);
|
||||
}, 'Upgrading a disconnected custom element must not invoke connectedCallback if the element is connected during upgrading');
|
||||
|
||||
test_with_window(function (contentWindow) {
|
||||
const contentDocument = contentWindow.document;
|
||||
contentDocument.write('<test-element id="first-element">');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue