polyfills
polyfills copied to clipboard
document.domain and <node>.innerHTML on IE11
Description
When using the polyfills in IE11, if document.domain is set, SCRIPT5022: WrongDocumentError at line 84 of template/template.js.
I'm not finding any information in my various searches that shed any light on why this is happening or how to eliminate it.
Setting document.domain AFTER loading the polyfill does not change the results.
Using
This appears to be a bug in the polyfill more than an issue with the component.
Steps to Reproduce
Using this HTML:
<!DOCTYPE html>
<head>
<title>Web component test</title>
<script>
document.domain = '<somedomain>.com';
</script>
<script src="https://unpkg.com/@webcomponents/webcomponentsjs/webcomponents-bundle.js"></script>
</head>
<body>
Web components test.
<div id="wc1">Initial content.</div>
<button onclick="document.getElementById('wc1').innerHTML = 'Updated content ' + Date.now();">Update</button>
<button onclick="addNode('div');">Add node</button>
<script>
function addNode(nodeName) {
var node = document.createElement(nodeName);
node.innerHTML = 'New node';
document.body.appendChild(node);
}
</script>
</body>
- Create an HTML file on your local web server using the above HTML.
- Set
document.domainto your domain. - Load the file from your web server into IE11.
- Open the developer tools (press F12).
- Click the 'Add node' button.
Expected Results
A new node at the end of the document with the text 'New node'
Actual Results
In the Javascript console: SCRIPT5022: WrongDocumentError template.js (84,11)
Browsers Affected
- [ ] Chrome
- [ ] Firefox
- [ ] Edge
- [ ] Safari
- [x] IE 11
What versions of Windows and IE 11 are you running? I tried publishing the above test case to a publicly accessible server, and with IE 11 (11.239.18362.0) and Windows 10 Pro (1093), it worked as expected (i.e., no error was thrown).
Interesting. It doesn't work on any version of IE11 for us. My particular setup is Windows 10 Enterprise (1803), OS build 17134.885, using IE11 11.0.135 (11.885.17134.0).
I have the page up here if anyone wants to try it: https://static.adp.com/mas/mdf-sample/21.0.4/webComponentTest.html
I just tried the URL in my last message on Windows 10 Pro (1903), OS build 18362.267 with IE11 11.0.135 (11.239.13262.0) and it fails as I expect.
It only fails if document.domain is set.
Ah, the issue at https://static.adp.com/mas/mdf-sample/21.0.4/webComponentTest.html is likely that the document.domain value is set to the parent domain rather than the domain of the page itself. Try setting it to static.adp.com.
(Or don't set it, in which case the default will be static.adp.com)
I disagree - it's quite normal in integration environments, where we may use iframe from different hosts, to set document.domain to the same value (a more general domain) so that the apps can interact.
Sorry, I didn't mean to say it was incorrect, just that the problem is that document.domain is being set to something that isn't exactly the document domain, and that's what's causing the breakage.
And my assertion is that its use should not cause breakage. Which is borne out by the behavior of every other browser, including Edge.
If, in the end, we can't use web components in IE11 because we also use document.domain, then let's get that documented at webcomponents.org on the polyfills page so that others don't struggle with the same issue.
First, many thanks to anyone who may be looking at this. Here is more data from moving up the stack:
The exception is thrown in the replacement for Node.prototype.appendChild found at line 84 of packages/template/template.js:
origAppendChild.call(this, child);
The code is now calling the original Node.appendChild to append to the actual DOM.
This was called from the insertBefore function line 350 of packages/shadydom/src/patches/Node.js:
container[utils.NATIVE_PREFIX + 'appendChild'](node);
Next up is the innerHTML setter at line 54 of packages/shadydom/src/patches/ElementOrShadowRoot.js:
this[utils.SHADY_PREFIX + 'insertBefore'](firstChild);
This is called from another innerHTML setter at line 63 of packages/custom-elements/src/Patch/Element.js:
baseDescriptor.set.call(this, htmlString);
And that code is triggered by setting innerHTML in my web page at line 20:
node.innerHTML = 'New node';
and the node is just a div created with document.createElement().
It feels like (and I can't say for sure) that the code is mixing 'shady' DOM and 'real' DOM in a way that confuses IE at this point, but I don't have an environment (yet) where I can tweak the polyfills and see what happens.
I'm hoping those with more experience with the polyfills can point the way.
The next level down in my investigation points to the inertDoc created in packages/shadydom/src/patches/ElementOrShadowRoot.js.
I'm guessing that document.implementation.createHTMLDocument('inert') creates a document object that does not have the same domain as the original document object, so that when the code creates a new htmlContainer at line 45:
htmlContainer = inertDoc.createElementNS(this.namespaceURI, containerName);
that new div has the full host name (static.adp.com) as the document.domain instead of the the assigned document.domain (adp.com) set in the original document.
Does this seem like I'm on the right track?
My suspicion was correct. If I add this to ElementOrShadowRoot.js right after inertDoc is created:
if (inertDoc.domain !== document.domain) {
inertDoc.domain = document.domain;
}
and then setting innerHTML in IE11 works for us.
I will look at how to create a pull request for this change.
We also facing same issue while integrating custom elements on one of our page.
Usage of document.domain='someValue'; just bombs in template.js.
Any plan to get the raised MR merged? or fix this issue?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.