1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
<!DOCTYPE html>
<html>
<head>
<title>Custom Elements: adoptedCallback</title>
<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
<meta name="assert" content="adoptedCallback must be enqueued whenever custom element is adopted into a new document">
<link rel="help" href="https://w3c.github.io/webcomponents/spec/custom/#dfn-connected-callback">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="./resources/custom-elements-helpers.js"></script>
</head>
<body>
<div id="log"></div>
<script>
var calls = [];
class MyCustomElement extends HTMLElement {
connectedCallback() { calls.push('connected'); }
adoptedCallback(oldDocument, newDocument) { calls.push('adopted'); calls.push(oldDocument); calls.push(newDocument); }
disconnectedCallback() { calls.push('disconnected'); }
}
customElements.define('my-custom-element', MyCustomElement);
test(function () {
var instance = document.createElement('my-custom-element');
calls = [];
document.body.appendChild(instance);
assert_array_equals(calls, ['connected']);
}, 'Inserting a custom element into the owner document must not enqueue and invoke adoptedCallback');
document_types().forEach(function (entry) {
if (entry.isOwner)
return;
var documentName = entry.name;
var getDocument = entry.create;
promise_test(function () {
return getDocument().then(function (doc) {
var instance = document.createElement('my-custom-element');
calls = [];
doc.documentElement.appendChild(instance);
assert_array_equals(calls, ['adopted', document, doc, 'connected']);
});
}, 'Inserting a custom element into ' + documentName + ' must enqueue and invoke adoptedCallback');
promise_test(function () {
return getDocument().then(function (doc) {
var instance = document.createElement('my-custom-element');
document.body.appendChild(instance);
calls = [];
doc.documentElement.appendChild(instance);
assert_array_equals(calls, ['disconnected', 'adopted', document, doc, 'connected']);
});
}, 'Moving a custom element from the owner document into ' + documentName + ' must enqueue and invoke adoptedCallback');
promise_test(function () {
return getDocument().then(function (doc) {
var instance = document.createElement('my-custom-element');
var parent = document.createElement('div');
parent.appendChild(instance);
calls = [];
doc.documentElement.appendChild(parent);
assert_array_equals(calls, ['adopted', document, doc, 'connected']);
});
}, 'Inserting an ancestor of custom element into ' + documentName + ' must enqueue and invoke adoptedCallback');
promise_test(function () {
return getDocument().then(function (doc) {
var instance = document.createElement('my-custom-element');
var parent = document.createElement('div');
parent.appendChild(instance);
document.body.appendChild(parent);
calls = [];
doc.documentElement.appendChild(parent);
assert_array_equals(calls, ['disconnected', 'adopted', document, doc, 'connected']);
});
}, 'Moving an ancestor of custom element from the owner document into ' + documentName + ' must enqueue and invoke adoptedCallback');
promise_test(function () {
return getDocument().then(function (doc) {
var instance = document.createElement('my-custom-element');
var host = doc.createElementNS('http://www.w3.org/1999/xhtml', 'div');
var shadowRoot = host.attachShadow({mode: 'closed'});
doc.documentElement.appendChild(host);
calls = [];
shadowRoot.appendChild(instance);
assert_array_equals(calls, ['adopted', document, doc, 'connected']);
});
}, 'Inserting a custom element into a shadow tree in ' + documentName + ' must enqueue and invoke adoptedCallback');
promise_test(function () {
return getDocument().then(function (doc) {
var instance = document.createElement('my-custom-element');
var host = document.createElement('div');
var shadowRoot = host.attachShadow({mode: 'closed'});
shadowRoot.appendChild(instance);
calls = [];
doc.documentElement.appendChild(host);
assert_array_equals(calls, ['adopted', document, doc, 'connected']);
});
}, 'Inserting the shadow host of a custom element into ' + documentName + ' must enqueue and invoke adoptedCallback');
promise_test(function () {
return getDocument().then(function (doc) {
var instance = document.createElement('my-custom-element');
var host = document.createElement('div');
var shadowRoot = host.attachShadow({mode: 'closed'});
shadowRoot.appendChild(instance);
document.body.appendChild(host);
calls = [];
doc.documentElement.appendChild(host);
assert_array_equals(calls, ['disconnected', 'adopted', document, doc, 'connected']);
});
}, 'Moving the shadow host of a custom element from the owner document into ' + documentName + ' must enqueue and invoke adoptedCallback');
promise_test(function () {
return getDocument().then(function (doc) {
const instance = document.createElement('my-custom-element');
const host = document.createElement('div');
const shadowRoot = host.attachShadow({mode: 'closed'});
shadowRoot.appendChild(instance);
document.body.appendChild(host);
calls = [];
doc.documentElement.appendChild(shadowRoot);
assert_array_equals(calls, ['disconnected', 'adopted', document, doc, 'connected']);
});
}, 'Moving the shadow host\'s shadow of a custom element from the owner document into ' + documentName + ' must enqueue and invoke adoptedCallback');
promise_test(function () {
return getDocument().then(function (doc) {
const instance = document.createElement('my-custom-element');
const template = document.createElement('template');
const templateContent = template.content;
templateContent.appendChild(instance);
document.body.appendChild(template);
calls = [];
doc.documentElement.appendChild(templateContent);
if (doc === templateContent.ownerDocument) {
assert_array_equals(calls, ['connected']);
} else {
assert_array_equals(calls, ['adopted', templateContent.ownerDocument, doc, 'connected']);
}
});
}, 'Moving the <template>\'s content of a custom element from the owner document into ' + documentName + ' must enqueue and invoke adoptedCallback');
promise_test(function () {
return getDocument().then(function (doc) {
var instance = document.createElement('my-custom-element');
var host = doc.createElementNS('http://www.w3.org/1999/xhtml', 'div');
var shadowRoot = host.attachShadow({mode: 'closed'});
calls = [];
shadowRoot.appendChild(instance);
assert_array_equals(calls, ['adopted', document, doc]);
});
}, 'Inserting a custom element into a detached shadow tree that belongs to ' + documentName + ' must enqueue and invoke adoptedCallback');
});
</script>
</body>
</html>
|