-
Notifications
You must be signed in to change notification settings - Fork 396
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error when rendering the same stylesheet to two different documents (iframes, templates) #2609
Comments
Thanks for the very thorough bug report! I wrote a minimal repro (nolanlawson/lwc-barebone@431bec0) based on yours: document.body.appendChild(createElement("x-app", { is: App }));
const template = document.createElement('template');
template.content.appendChild(createElement("x-app", { is: App })); // throws The issue is that (apparently) adopted stylesheets cannot be reused across two documents – in this case, the main document and a document.body.appendChild(createElement("x-app", { is: App }));
const iframe = document.createElement('iframe');
iframe.contentDocument.appendChild(createElement("x-app", { is: App })); // throws One workaround you can use is to avoid We could try to track constructable stylesheets on a per-document basis, but I'm not sure if that's feasible. This is a tricky bug, and there's some more discussion of it here: WICG/construct-stylesheets#23 |
This issue has been linked to a new work item: W-10323566 |
@nolanlawson Nice minimal repro, and thanks for the workaround. As far as my team is concerned, that workaround is probably sufficient -- and extremely minimal in cost -- for us to move to the latest version of Thanks for the link to that discussion, too. Lots to think about there! |
So this is actually a really subtle issue. I have a minimal repro: const template = document.createElement('template')
const div = document.createElement('div')
div.attachShadow({ mode: 'open' })
template.content.appendChild(div)
const sheet = new CSSStyleSheet()
div.shadowRoot.adoptedStyleSheets = [sheet] In Chrome this throws:
In Firefox with the flag
Looking through various discussions on this (e.g. WICG/construct-stylesheets#133 and this Chromium issue), I'm not sure if there's a solution. There is no way AFAICT to associate the CSSStyleSheet's constructor document with the template's owner document. Apparently there are elaborate solutions involving adoptNode, but I haven't yet gotten them to work. In iframes, I assume this would not be a problem, because assuming the LWC engine is running inside the iframe, it would be getting |
Interestingly the same pattern works fine with Lit. The difference is this: const template = document.createElement('template');
const div = document.createElement('x-foo');
div.attachShadow({ mode: 'open' });
template.content.appendChild(div); // LWC assigns adoptedStyleSheets here
document.body.appendChild(template.content) // Lit assigns adoptedStyleSheets here The reason for the difference is that LWC doesn't use the "real" If we fix that bug, then assigning |
Turns out you don't even need a const div = document.createElement('div');
console.log('appending to div')
div.appendChild(elm);
console.log('appending div to document.body')
document.body.appendChild(div); |
Related to #1102 |
Duplicate of #3198 |
Description
This issue appears to affect Chrome only, and happens if (1) your
lwc
version is >= 2.3.7, (2) you render an LWC component usinglwc:dom="manual"
, (3) your manually-constructed DOM also includes an LWC component, and (4) the LWC component in the manually-constructed DOM has its own CSS stylesheet. If any of those conditions are not satisfied (e.g., you uselwc
version <= 2.3.4, or the LWC component in the manually-constructed DOM does not have its own stylesheet), the issue does not occur.The issue: under the aforementioned conditions, in Chrome, the
lwc
library throws an uncaught DOMException, and the app fails to render (crashes). The DOMException is as follows:The error is thrown at the moment that the
adoptedStylesheets
property of thetarget
is assigned ininsertConstructableStyleSheet
.Steps to Reproduce
I created a very small GitHub repo that reproduces the issue: https://github.com/jmrog/lwc-stylesheets-bug. I was unable to reproduce the issue in the webcomponents.dev environment, but am unsure what version of
lwc
is being used there anyway. The steps to reproduce the issue are available on the just-mentioned repo, but here they are again:yarn install
ornpm install
.yarn watch
ornpm run watch
.Again, the issue does not appear if you remove the child component's CSS file, or if you do not construct the DOM manually (e.g., change
this.isManual = true;
tothis.isManual = false;
in the constructor inapp.js
), or if you downgradelwc
enough (e.g., downgradinglwc-services
to3.1.0
in the aforementioned repo works), etc. It also does not appear in Firefox or Safari (only Chrome, as far as I know).Expected Results
The app renders as expected, and no error is thrown. Visual from the above repo:
Actual Results
The app fails to render (crashes) and shows an uncaught DOMException in the browser console, in Chrome only. Visual from the above repo:
Browsers Affected
Chrome, latest version (96.0.4664.110 as of this writing).
Version
Possible Solutions
Not really a solution, but just want to note that the changes introduced in #2460 seem to have triggered this issue.
The text was updated successfully, but these errors were encountered: