Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<div id="host-window"><template shadowrootmode="open"><a-b></a-b></template></div>
<div id="host-null"><template shadowrootmode="open" shadowrootcustomelementregistry=""><a-b></a-b></template></div>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was never used in the test.

<script>

setup({allow_uncaught_exception : true});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
const clone = document.getElementById('host-null').cloneNode(true);
const ab = clone.shadowRoot.querySelector('a-b');
document.body.appendChild(ab);
assert_equals(ab.customElementRegistry, window.customElements);
assert_equals(ab.customElementRegistry, null);

const frame = document.createElement('iframe');
t.add_cleanup(() => frame.remove());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@
test(() => {
const host = document.body.appendChild(document.createElement('div'));
const shadowRoot = host.attachShadow({mode: 'closed', customElementRegistry: null});
assert_equals(shadowRoot.customElementRegistry, window.customElements);
}, 'attachShadow() should use the global registry when customElementRegistry is null (host uses global registry)');
assert_equals(shadowRoot.customElementRegistry, null);
}, 'attachShadow() should use null registry when customElementRegistry is null (host uses global registry)');

test(() => {
const registry = new CustomElementRegistry;
const host = document.body.appendChild(document.createElement('div', {customElementRegistry: registry}));
const shadowRoot = host.attachShadow({mode: 'closed', customElementRegistry: null});
assert_equals(shadowRoot.customElementRegistry, window.customElements);
}, 'attachShadow() should use the global registry when customElementRegistry is null (host uses custom registry)');
assert_equals(shadowRoot.customElementRegistry, null);
}, 'attachShadow() should use null registry when customElementRegistry is null (host uses custom registry)');

test(() => {
const registry = new CustomElementRegistry;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"/>
<link rel="help" href="https://html.spec.whatwg.org/multipage/custom-elements.html#dom-customelementregistry-initialize"/>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<script>
<![CDATA[

customElements.define('c-d', class ABElement extends HTMLElement { });

]]>
</script>
<div id="container"><a-b customelementregistry=""></a-b><c-d customelementregistry=""></c-d></div>
<script>
<![CDATA[

const container = document.getElementById('container');
test((test) => {
assert_equals(container.querySelector('a-b').customElementRegistry, null);
}, `XHTML parser should create a custom element candidate with null registry if customelementregistry is set`);

test((test) => {
assert_equals(container.querySelector('c-d').customElementRegistry, null);
}, `XHTML parser should create a defined custom element with null registry if customelementregistry is set`);

test((test) => {
container.setHTMLUnsafe(`<a-b customelementregistry></a-b>`);
assert_equals(container.querySelector('a-b').customElementRegistry, null);
}, `XHTML fragment parser should create a custom element candidate with null registry if customelementregistry is set`);

test((test) => {
container.setHTMLUnsafe(`<c-d></c-d>`);
assert_equals(container.querySelector('c-d').customElementRegistry, window.customElements);
container.setHTMLUnsafe(`<c-d customelementregistry></c-d>`);
assert_equals(container.querySelector('c-d').customElementRegistry, null);
}, `XHTML fragment parser should create a defined custom element with null registry if customelementregistry is set`);

]]>
</script>
</body>
</html>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to add tests to ensure the subtree of the element with customelementregistry attribute also has null registry in both HTML and XHTML?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A good idea. Will do.

Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<!DOCTYPE html>
<html>
<head>
<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
<link rel="help" href="https://html.spec.whatwg.org/multipage/custom-elements.html#dom-customelementregistry-initialize">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<script>

function makeIframe(test) {
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
test.add_cleanup(() => iframe.remove());
return [iframe.contentDocument, iframe.contentWindow];
}

function makeIframeWithABElement(test) {
const [doc, win] = makeIframe(test);
win.customElements.define('a-b', class ABElement extends win.HTMLElement { });
return [doc, win];
}

function runBasicTests(makeIframe, elementName, elementDescription) {
test((test) => {
const [doc, win] = makeIframe(test);
doc.documentElement.setHTMLUnsafe(`<${elementName} customelementregistry></${elementName}>`);
assert_equals(doc.querySelector(elementName).customElementRegistry, null);
}, `HTML parser should create a ${elementDescription} with null registry if customelementregistry is set`);

test((test) => {
const [doc, win] = makeIframe(test);
assert_equals(doc.createElement(elementName, {customElementRegistry: null}).customElementRegistry, null);
assert_equals(doc.createElementNS('http://www.w3.org/1999/xhtml', 'div', {customElementRegistry: null}).customElementRegistry, null);
}, `document.createElement should create a ${elementDescription} with null registry if customElement is set to null`);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd imagine the test for null registry option on createElement to be placed in Document-createElement.html

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me address these comments in a follow up since the corresponding WebKit change has already landed.

test((test) => {
const [doc, win] = makeIframe(test);
const host = doc.createElement(elementName);
const shadowRoot = host.attachShadow({mode: 'closed', customElementRegistry: null})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto, would imagine this to be placed in ShadowRoot-init-customElementRegistry.html

assert_equals(shadowRoot.customElementRegistry, null);
}, `attchShadow on a ${elementDescription} with null customElementRegistry should create a ShadowRoot with null registry`);

test((test) => {
const [doc, win] = makeIframe(test);
const element = doc.createElement(elementName);
assert_equals(element.customElementRegistry, win.customElements);
element.setAttribute('customelementregistry', '');
assert_equals(element.customElementRegistry, win.customElements);
}, `Setting customelementregistry content attribute after a ${elementDescription} had finishsed parsing should not set null registry`);

test((test) => {
const [doc, win] = makeIframe(test);
const element = doc.createElement(elementName, {customElementRegistry: null});
assert_equals(element.customElementRegistry, null);
assert_equals(element.cloneNode(false).customElementRegistry, null);

doc.documentElement.setHTMLUnsafe(`<${elementName} customelementregistry></${elementName}>`);
assert_equals(doc.querySelector(elementName).customElementRegistry, null);
assert_equals(doc.querySelector(elementName).cloneNode(true).customElementRegistry, null);
}, `Cloning a ${elementDescription} with null regsitry should create an element with null registry`);
}

runBasicTests(makeIframe, 'div', 'builtin element');
runBasicTests(makeIframe, 'a-b', 'custom element candidate');
runBasicTests(makeIframeWithABElement, 'a-b', 'custom element');

test((test) => {
const [doc, win] = makeIframe(test);

const upgradeCandidate = doc.createElement('a-b');
assert_equals(upgradeCandidate.customElementRegistry, win.customElements);

doc.body.setHTMLUnsafe('<a-b></a-b>');
assert_equals(doc.querySelector('a-b').customElementRegistry, win.customElements);

assert_equals(upgradeCandidate.customElementRegistry, win.customElements);
let customElementRegistryDuringConstruction = null;
win.customElements.define('a-b', class ABElement extends win.HTMLElement {
constructor() {
super();
this.setAttribute('customelementregistry', '');
customElementRegistryDuringConstruction = this.customElementRegistry;
this.removeAttribute('customelementregistry', '');
}
});
assert_equals(customElementRegistryDuringConstruction, win.customElements);
assert_equals(doc.querySelector('a-b').customElementRegistry, win.customElements);

const element = doc.createElement('a-b');
assert_equals(customElementRegistryDuringConstruction, win.customElements);
assert_equals(element.customElementRegistry, win.customElements);

doc.body.setHTMLUnsafe('<a-b></a-b>');
assert_equals(customElementRegistryDuringConstruction, win.customElements);
assert_equals(element.customElementRegistry, win.customElements);

win.customElements.upgrade(upgradeCandidate);
assert_equals(customElementRegistryDuringConstruction, win.customElements);
assert_equals(element.customElementRegistry, win.customElements);
}, `Setting customelementregistry content attribute during constructor should not make it use null registry`);

</script>
</body>
</html>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to create test cases for cross document append where append does upgrade due to element getting registry on adopt?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A good idea. Will do.

Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<!DOCTYPE html>
<html>
<head>
<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<script>

test(() => {
assert_equals((new Document).createElement('a-b').customElementRegistry, null);
assert_equals(document.implementation.createHTMLDocument().createElement('a-b').customElementRegistry, null);
assert_equals(document.implementation.createDocument('http://www.w3.org/1999/xhtml', 'html', null).createElement('a-b').customElementRegistry, null);
}, 'customElementRegistry of an upgrade candidate created in a document without a browsing context uses null regsitry by default');

function makeIframe(test) {
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
test.add_cleanup(() => iframe.remove());
return [iframe.contentDocument, iframe.contentWindow];
}

test((test) => {
const [doc, win] = makeIframe(test);
doc.documentElement.setHTMLUnsafe('<div id="host"><template shadowrootmode="open" shadowrootclonable="true" shadowrootcustomelementregistry><a-b></a-b></template></div>');
const hostClone = doc.getElementById('host').cloneNode(true);
assert_equals(hostClone.shadowRoot.customElementRegistry, null);
assert_equals(hostClone.shadowRoot.querySelector('a-b').customElementRegistry, null);
}, 'Connecting a custom element candiate in a shadow root with a scoped custom element registry has null registry by default');

test((test) => {
const [doc, win] = makeIframe(test);
doc.documentElement.setHTMLUnsafe('<div id="host"><template shadowrootmode="open" shadowrootclonable="true" shadowrootcustomelementregistry><a-b></a-b></template></div>');
win.customElements.define('a-b', class ABElement extends win.HTMLElement { });
const hostClone = doc.getElementById('host').cloneNode(true);
assert_equals(hostClone.shadowRoot.customElementRegistry, null);
const candidate = hostClone.shadowRoot.querySelector('a-b');
assert_equals(candidate.customElementRegistry, null);
doc.body.appendChild(candidate);
assert_equals(candidate.customElementRegistry, null);
}, 'Connecting a custom element candiate with null registry does not set the registry');

test((test) => {
const [doc, win] = makeIframe(test);
doc.documentElement.setHTMLUnsafe('<div id="host"><template shadowrootmode="open" shadowrootclonable="true" shadowrootcustomelementregistry><a-b></a-b></template></div>');
win.customElements.define('a-b', class ABElement extends win.HTMLElement { });
const hostClone = doc.getElementById('host').cloneNode(true);
const candidate = hostClone.shadowRoot.querySelector('a-b');
const registry = new CustomElementRegistry;
assert_equals(candidate.customElementRegistry, null);
registry.initialize(hostClone.shadowRoot);
assert_equals(candidate.customElementRegistry, registry);
doc.body.appendChild(candidate);
assert_equals(candidate.customElementRegistry, registry);

const element = doc.createElement('host', {customElementRegistry: registry});
assert_equals(element.customElementRegistry, registry);
doc.body.appendChild(element);
assert_equals(element.customElementRegistry, registry);
}, 'Connecting a custom element candiate with a scoped custom element registry does not change the registry');

test((test) => {
const [doc, win] = makeIframe(test);
doc.documentElement.setHTMLUnsafe('<div id="host1"><template shadowrootmode="open" shadowrootclonable="true" shadowrootcustomelementregistry><a-b></a-b></template></div>'
+ '<div id="host2"><template shadowrootmode="open" shadowrootclonable="true" shadowrootcustomelementregistry><c-d></c-d></template></div>');
win.customElements.define('a-b', class ABElement extends win.HTMLElement { });
const clone1 = doc.getElementById('host1').cloneNode(true);
const clone2 = doc.getElementById('host2').cloneNode(true);
const candidate = clone1.shadowRoot.querySelector('a-b');
assert_equals(candidate.customElementRegistry, null);
assert_equals(clone2.shadowRoot.querySelector('c-d').customElementRegistry, null);
const registry = new CustomElementRegistry;
registry.initialize(clone2.shadowRoot);
assert_equals(clone2.shadowRoot.querySelector('c-d').customElementRegistry, registry);
clone2.shadowRoot.appendChild(candidate);
assert_equals(candidate.customElementRegistry, null);
}, 'Inserting a custom element candiate with null registry does not change the registry');

test((test) => {
const [doc, win] = makeIframe(test);
const registry = new CustomElementRegistry;
const host = doc.createElement('div');
const shadowRoot = host.attachShadow({mode: 'closed', customElementRegistry: registry});
assert_equals(shadowRoot.customElementRegistry, registry);
doc.body.appendChild(host);
assert_equals(shadowRoot.customElementRegistry, registry);
}, 'Inserting the shadow host of a shadow root with a scoped custom element registry does not change the registry');

</script>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,8 @@

test(t => {
const name = nextCustomElementName();
const node = document.body.appendChild(document.createElement(name));

const registry = new CustomElementRegistry;
const node = document.body.appendChild(document.createElement(name, {customElementRegistry: registry}));
const shadow = attachShadowForTest(t, registry);
shadow.appendChild(node);

Expand Down