Per the custom element specification,
The element must not gain any attributes or children, as this violates the expectations of consumers who use the
createElementorcreateElementNSmethods.
Both Firefox and Chrome correctly throw an error in this situation. However, when attaching a shadow DOM, no error is present (in either browser).
Firefox:
NotSupportedError: Operation is not supported
Chrome:
Uncaught DOMException: Failed to construct 'CustomElement': The result must not have children
Without shadow DOM
function createElement(tag, ...children) {
let root;
if (typeof tag === 'symbol') {
root = document.createDocumentFragment();
} else {
root = document.createElement(tag);
}
children.forEach(node => root.appendChild(node));
return root;
}
customElements.define(
'x-foo',
class extends HTMLElement {
constructor() {
super();
this.appendChild(
createElement(
Symbol(),
createElement('div'),
),
);
}
},
);
createElement('x-foo');
With shadow DOM
function createElement(tag, ...children) {
let root;
if (typeof tag === 'symbol') {
root = document.createDocumentFragment();
} else {
root = document.createElement(tag);
}
children.forEach(node => root.appendChild(node));
return root;
}
customElements.define(
'x-foo',
class extends HTMLElement {
constructor() {
super();
// it doesn't matter if this is open or closed
this.attachShadow({ mode: 'closed' }).appendChild(
createElement(
Symbol(),
createElement('div'),
),
);
}
},
);
createElement('x-foo');
Please note: in order to view the examples, you need to be using (at least) one of the following: Firefox 63, Chrome 67, Safari 10.1. Edge is not supported.
My question is as follows:
Is the behavior demonstrated correct, per the specification?
Adding a child node to the root would cause a DOM reflow; how can this be avoided without a shadow DOM present?