summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/custom-elements/enqueue-custom-element-callback-reactions-inside-another-callback.html
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/custom-elements/enqueue-custom-element-callback-reactions-inside-another-callback.html')
-rw-r--r--testing/web-platform/tests/custom-elements/enqueue-custom-element-callback-reactions-inside-another-callback.html223
1 files changed, 223 insertions, 0 deletions
diff --git a/testing/web-platform/tests/custom-elements/enqueue-custom-element-callback-reactions-inside-another-callback.html b/testing/web-platform/tests/custom-elements/enqueue-custom-element-callback-reactions-inside-another-callback.html
new file mode 100644
index 0000000000..2fd932f29a
--- /dev/null
+++ b/testing/web-platform/tests/custom-elements/enqueue-custom-element-callback-reactions-inside-another-callback.html
@@ -0,0 +1,223 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Custom Elements: must enqueue an element on the appropriate element queue after checking callback is null and the attribute name</title>
+<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
+<meta name="assert" content="To enqueue a custom element callback reaction, the callback must be checked of being null and whether the attribute name is observed or not">
+<link rel="help" content="https://html.spec.whatwg.org/multipage/custom-elements.html#enqueue-a-custom-element-callback-reaction">
+<link rel="help" content="https://github.com/w3c/webcomponents/issues/760">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/custom-elements-helpers.js"></script>
+</head>
+<body>
+<script>
+
+test_with_window((contentWindow, contentDocument) => {
+ class ParentElement extends contentWindow.HTMLElement {
+ connectedCallback()
+ {
+ logs.push('begin');
+ const child = this.firstChild;
+ child.remove();
+ logs.push('end');
+ }
+ }
+ contentWindow.customElements.define('parent-element', ParentElement);
+
+ const logs = [];
+ class ChildElement extends contentWindow.HTMLElement {
+ connectedCallback() { logs.push('connected'); }
+ disconnectedCallback() { logs.push('disconnected'); }
+ }
+ contentWindow.customElements.define('child-element', ChildElement);
+
+ const parent = new ParentElement;
+ const child = new ChildElement;
+ parent.appendChild(child);
+
+ contentDocument.body.appendChild(parent);
+ assert_array_equals(logs, ['begin', 'connected', 'disconnected', 'end']);
+}, 'Disconnecting an element with disconnectedCallback while it has a connectedCallback in its custom element reaction queue must result in connectedCallback getting invoked before the removal completes');
+
+test_with_window((contentWindow, contentDocument) => {
+ class ParentElement extends contentWindow.HTMLElement {
+ connectedCallback()
+ {
+ logs.push('begin');
+ const child = this.firstChild;
+ child.remove();
+ logs.push('end');
+ }
+ }
+ contentWindow.customElements.define('parent-element', ParentElement);
+
+ const logs = [];
+ class ChildElement extends contentWindow.HTMLElement {
+ connectedCallback() { logs.push('connected'); }
+ }
+ contentWindow.customElements.define('child-element', ChildElement);
+
+ const parent = new ParentElement;
+ const child = new ChildElement;
+ parent.appendChild(child);
+
+ contentDocument.body.appendChild(parent);
+ assert_array_equals(logs, ['begin', 'end', 'connected']);
+}, 'Disconnecting an element without disconnectedCallback while it has a connectedCallback in its custom element reaction queue must not result in connectedCallback getting invoked before the removal completes');
+
+test_with_window((contentWindow, contentDocument) => {
+ class ParentElement extends contentWindow.HTMLElement {
+ disconnectedCallback()
+ {
+ logs.push('begin');
+ contentDocument.body.appendChild(this.firstChild);
+ logs.push('end');
+ }
+ }
+ contentWindow.customElements.define('parent-element', ParentElement);
+
+ const logs = [];
+ class ChildElement extends contentWindow.HTMLElement {
+ connectedCallback() { logs.push('connected'); }
+ disconnectedCallback() { logs.push('disconnected'); }
+ }
+ contentWindow.customElements.define('child-element', ChildElement);
+
+ const parent = new ParentElement;
+ const child = new ChildElement;
+ parent.appendChild(child);
+ contentDocument.body.appendChild(parent);
+ parent.remove();
+ assert_array_equals(logs, ['connected', 'begin', 'disconnected', 'connected', 'end']);
+}, 'Connecting a element with connectedCallback while it has a disconnectedCallback in its custom element reaction queue must result in disconnectedCallback getting invoked before the insertion completes');
+
+test_with_window((contentWindow, contentDocument) => {
+ class ParentElement extends contentWindow.HTMLElement {
+ disconnectedCallback()
+ {
+ logs.push('begin');
+ contentDocument.body.appendChild(this.firstChild);
+ logs.push('end');
+ }
+ }
+ contentWindow.customElements.define('parent-element', ParentElement);
+
+ const logs = [];
+ class ChildElement extends contentWindow.HTMLElement {
+ disconnectedCallback() { logs.push('disconnected'); }
+ }
+ contentWindow.customElements.define('child-element', ChildElement);
+
+ const parent = new ParentElement;
+ const child = new ChildElement;
+ parent.appendChild(child);
+ contentDocument.body.appendChild(parent);
+ parent.remove();
+ assert_array_equals(logs, ['begin', 'end', 'disconnected']);
+}, 'Connecting an element without connectedCallback while it has a disconnectedCallback in its custom element reaction queue must not result in disconnectedCallback getting invoked before the insertion completes');
+
+test_with_window((contentWindow, contentDocument) => {
+ class ParentElement extends contentWindow.HTMLElement {
+ connectedCallback()
+ {
+ logs.push('begin');
+ document.adoptNode(this.firstChild);
+ logs.push('end');
+ }
+ }
+ contentWindow.customElements.define('parent-element', ParentElement);
+
+ const logs = [];
+ class ChildElement extends contentWindow.HTMLElement {
+ adoptedCallback() { logs.push('adopted'); }
+ connectedCallback() { logs.push('connected'); }
+ }
+ contentWindow.customElements.define('child-element', ChildElement);
+
+ const parent = new ParentElement;
+ const child = new ChildElement;
+ parent.appendChild(child);
+ contentDocument.body.appendChild(parent);
+ assert_array_equals(logs, ['begin', 'connected', 'adopted', 'end']);
+}, 'Adopting an element with adoptingCallback while it has a connectedCallback in its custom element reaction queue must result in connectedCallback getting invoked before the adoption completes');
+
+test_with_window((contentWindow, contentDocument) => {
+ class ParentElement extends contentWindow.HTMLElement {
+ connectedCallback()
+ {
+ logs.push('begin');
+ document.adoptNode(this.firstChild);
+ logs.push('end');
+ }
+ }
+ contentWindow.customElements.define('parent-element', ParentElement);
+
+ const logs = [];
+ class ChildElement extends contentWindow.HTMLElement {
+ connectedCallback() { logs.push('connected'); }
+ }
+ contentWindow.customElements.define('child-element', ChildElement);
+
+ const parent = new ParentElement;
+ const child = new ChildElement;
+ parent.appendChild(child);
+ contentDocument.body.appendChild(parent);
+ assert_array_equals(logs, ['begin', 'end', 'connected']);
+}, 'Adopting an element without adoptingCallback while it has a connectedCallback in its custom element reaction queue must not result in connectedCallback getting invoked before the adoption completes');
+
+test_with_window((contentWindow, contentDocument) => {
+ class ParentElement extends contentWindow.HTMLElement {
+ connectedCallback()
+ {
+ logs.push('begin');
+ this.firstChild.setAttribute('title', 'foo');
+ logs.push('end');
+ }
+ }
+ contentWindow.customElements.define('parent-element', ParentElement);
+
+ const logs = [];
+ class ChildElement extends contentWindow.HTMLElement {
+ attributeChangedCallback() { logs.push('attributeChanged'); }
+ connectedCallback() { logs.push('connected'); }
+ static get observedAttributes() { return ['title']; }
+ }
+ contentWindow.customElements.define('child-element', ChildElement);
+
+ const parent = new ParentElement;
+ const child = new ChildElement;
+ parent.appendChild(child);
+ contentDocument.body.appendChild(parent);
+ assert_array_equals(logs, ['begin', 'connected', 'attributeChanged', 'end']);
+}, 'Setting an observed attribute on an element with attributeChangedCallback while it has a connectedCallback in its custom element reaction queue must result in connectedCallback getting invoked before the attribute change completes');
+
+test_with_window((contentWindow, contentDocument) => {
+ class ParentElement extends contentWindow.HTMLElement {
+ connectedCallback()
+ {
+ logs.push('begin');
+ this.firstChild.setAttribute('lang', 'en');
+ logs.push('end');
+ }
+ }
+ contentWindow.customElements.define('parent-element', ParentElement);
+
+ const logs = [];
+ class ChildElement extends contentWindow.HTMLElement {
+ attributeChangedCallback() { logs.push('attributeChanged'); }
+ connectedCallback() { logs.push('connected'); }
+ static get observedAttributes() { return ['title']; }
+ }
+ contentWindow.customElements.define('child-element', ChildElement);
+
+ const parent = new ParentElement;
+ const child = new ChildElement;
+ parent.appendChild(child);
+ contentDocument.body.appendChild(parent);
+ assert_array_equals(logs, ['begin', 'end', 'connected']);
+}, 'Setting an observed attribute on an element with attributeChangedCallback while it has a connectedCallback in its custom element reaction queue must not result in connectedCallback getting invoked before the attribute change completes');
+
+</script>
+</body>
+</html>