Skip to content

Commit 197e5ea

Browse files
committed
DOM: createElement and createElementNS with scoped registries
For whatwg/dom#1341.
1 parent 570d512 commit 197e5ea

File tree

2 files changed

+116
-5
lines changed

2 files changed

+116
-5
lines changed

custom-elements/revamped-scoped-registry/Document-createElement.tentative.html

+29-5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
</head>
99
<body>
1010
<script>
11+
// Keep this ~synchronized with Document-createElementNS
12+
"use strict";
1113

1214
const scopedRegistry = new CustomElementRegistry();
1315
const otherScopedRegistry = new CustomElementRegistry();
@@ -30,12 +32,22 @@
3032
form: HTMLFormElement,
3133
span: HTMLSpanElement,
3234
table: HTMLTableElement,
35+
unknown: HTMLUnknownElement,
3336
};
34-
for (const localName in elements)
35-
assert_true(document.createElement(localName, {customElements: scopedRegistry}) instanceof elements[localName], localName);
36-
for (const localName in elements)
37-
assert_true(document.createElement(localName, {customElements: window.customElements}) instanceof elements[localName], localName);
38-
}, 'createElement should create a builtin element regardles of a custom element registry specified');
37+
for (const localName in elements) {
38+
const scopedElement = document.createElement(localName, {customElements: scopedRegistry});
39+
assert_true(scopedElement instanceof elements[localName], localName);
40+
assert_equals(scopedElement.customElements, scopedRegistry);
41+
42+
const globalExplicitElement = document.createElement(localName, {customElements: window.customElements});
43+
assert_true(globalExplicitElement instanceof elements[localName], localName);
44+
assert_equals(globalExplicitElement.customElements, window.customElements);
45+
46+
const globalImplicitElement = document.createElement(localName);
47+
assert_true(globalImplicitElement instanceof elements[localName], localName);
48+
assert_equals(globalImplicitElement.customElements, window.customElements);
49+
}
50+
}, 'createElement should create a builtin element regardless of a custom element registry specified');
3951

4052
test(() => {
4153
assert_true(document.createElement('a-b', {customElements: window.customElements}) instanceof GlobalABElement);
@@ -59,6 +71,18 @@
5971
assert_true(cdElement instanceof CDElement);
6072
}, 'createElement should create an upgrade candidate and the candidate should be upgraded when the element is defined');
6173

74+
test(() => {
75+
const doc = new Document();
76+
const scopedElement = doc.createElement("time", {customElements: scopedRegistry});
77+
assert_equals(scopedElement.namespaceURI, null);
78+
assert_equals(scopedElement.customElements, scopedRegistry);
79+
80+
const abElement = doc.createElement("a-b", {customElements: scopedRegistry});
81+
assert_equals(abElement.namespaceURI, null);
82+
assert_equals(abElement.customElements, scopedRegistry);
83+
assert_false(abElement instanceof ScopedABElement);
84+
}, 'createElement on a non-HTML document should still handle registries correctly');
85+
6286
</script>
6387
</body>
6488
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<link rel="help" href="https://github.com/whatwg/html/issues/10854">
5+
<script src="/resources/testharness.js"></script>
6+
<script src="/resources/testharnessreport.js"></script>
7+
</head>
8+
<body>
9+
<script>
10+
// Keep this ~synchronized with Document-createElement
11+
"use strict";
12+
13+
const scopedRegistry = new CustomElementRegistry();
14+
const otherScopedRegistry = new CustomElementRegistry();
15+
class GlobalABElement extends HTMLElement {};
16+
class ScopedABElement extends HTMLElement {};
17+
customElements.define('a-b', GlobalABElement);
18+
scopedRegistry.define('a-b', ScopedABElement);
19+
20+
test(() => {
21+
assert_true(document.createElementNS('http://www.w3.org/1999/xhtml', 'a-b') instanceof GlobalABElement);
22+
}, 'createElementNS should use the global registry by default');
23+
24+
test(() => {
25+
assert_true(document.createElementNS('http://www.w3.org/1999/xhtml', 'a-b', {customElements: scopedRegistry}) instanceof ScopedABElement);
26+
}, 'createElementNS should use the specified scoped registry');
27+
28+
test(() => {
29+
const elements = {
30+
div: HTMLDivElement,
31+
form: HTMLFormElement,
32+
span: HTMLSpanElement,
33+
table: HTMLTableElement,
34+
unknown: HTMLUnknownElement,
35+
};
36+
for (const localName in elements) {
37+
const scopedElement = document.createElementNS('http://www.w3.org/1999/xhtml', localName, {customElements: scopedRegistry});
38+
assert_true(scopedElement instanceof elements[localName], localName);
39+
assert_equals(scopedElement.customElements, scopedRegistry);
40+
41+
const globalExplicitElement = document.createElementNS('http://www.w3.org/1999/xhtml', localName, {customElements: window.customElements});
42+
assert_true(globalExplicitElement instanceof elements[localName], localName);
43+
assert_equals(globalExplicitElement.customElements, window.customElements);
44+
45+
const globalImplicitElement = document.createElementNS('http://www.w3.org/1999/xhtml', localName);
46+
assert_true(globalImplicitElement instanceof elements[localName], localName);
47+
assert_equals(globalImplicitElement.customElements, window.customElements);
48+
}
49+
}, 'createElementNS should create a builtin element regardless of a custom element registry specified');
50+
51+
test(() => {
52+
assert_true(document.createElementNS('http://www.w3.org/1999/xhtml', 'a-b', {customElements: window.customElements}) instanceof GlobalABElement);
53+
}, 'createElementNS should use the specified global registry');
54+
55+
test(() => {
56+
const element = document.createElementNS('http://www.w3.org/1999/xhtml', 'a-b', {customElements: otherScopedRegistry});
57+
assert_equals(element.__proto__.constructor.name, 'HTMLElement');
58+
}, 'createElementNS should create an upgrade candidate when there is no matching definition in the specified registry');
59+
60+
test(() => {
61+
class CDElement extends HTMLElement { }
62+
const registry = new CustomElementRegistry;
63+
const cdElement = document.createElementNS('http://www.w3.org/1999/xhtml', 'c-d', {customElements: registry});
64+
assert_false(cdElement instanceof CDElement);
65+
assert_equals(cdElement.__proto__.constructor.name, 'HTMLElement');
66+
registry.define('c-d', CDElement);
67+
assert_false(cdElement instanceof CDElement); // Not yet upgraded since it's disconnected.
68+
assert_equals(cdElement.__proto__.constructor.name, 'HTMLElement');
69+
document.body.appendChild(cdElement);
70+
assert_true(cdElement instanceof CDElement);
71+
}, 'createElementNS should create an upgrade candidate and the candidate should be upgraded when the element is defined');
72+
73+
test(() => {
74+
const doc = new Document();
75+
const scopedElement = doc.createElementNS(null, "time", {customElements: scopedRegistry});
76+
assert_equals(scopedElement.namespaceURI, null);
77+
assert_equals(scopedElement.customElements, scopedRegistry);
78+
79+
const abElement = doc.createElementNS(null, "a-b", {customElements: scopedRegistry});
80+
assert_equals(abElement.namespaceURI, null);
81+
assert_equals(abElement.customElements, scopedRegistry);
82+
assert_false(abElement instanceof ScopedABElement);
83+
}, 'createElementNS on a non-HTML document should still handle registries correctly');
84+
85+
</script>
86+
</body>
87+
</html>

0 commit comments

Comments
 (0)