Custom Elements unreliable initialization before DOMContentLoaded
Reported by
andrea.g...@gmail.com,
Mar 14 2018
|
|||||
Issue descriptionUserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/604.5.6 (KHTML, like Gecko) Version/11.0.3 Safari/604.5.6 Steps to reproduce the problem: 1. try the file or visit https://webreflection.github.io/eyeo/tests/ce.html 2. see that even after the CE is rendered, its content is empty 3. try to move the whole script after the body and see it always working What is the expected behavior? The upgrade mechanism behaves differently if a Custom Element is defined before the DOM is live or after. If defined before, it is impossible to bootstrap any container through its list of children (i.e. a tabs panel) What went wrong? WebKit/Safari defers both callbacks after DOMContentLoaded and only when a component has been fully upgraded. This is what every developer expects and there's no way to know, as library author, if others will include my components before or after the DOM is loaded. Did this work before? No Does this work in other browsers? N/A Chrome version: 64.0.3282.186 Channel: n/a OS Version: OS X 10.13.3 Flash Version: Having no way to properly initialize a Custom Element once fully upgraded is a real bummer. Thanks for fixing this.
,
Mar 14 2018
FYI there is also a Custom Elements V0 example to compare behaviors: https://webreflection.github.io/eyeo/tests/ce-v0.html Needless to say the createdCallback triggers when expected (once the custom elements has been fully updated and not before DOMContentLoaded). It looks like Safari followed this behavior when implementing attributeChangedCallback and connectedCallback.
,
Mar 21 2018
,
Mar 21 2018
,
Mar 23 2018
Chrome shows "conenctedCallback: 0" though Firefox Nightly and Safari TP shows "connectedCallback: 3". We should investigate the root cause of this difference.
However, connectedCallback is not a good timing to check child nodes. Even Safari and Firefox can call connectedCallback without 3 children if an HTTP response pauses between <but-why because=123> and </but-why>.
A custom element user might have code like:
let el = document.createElement('but-why');
document.body.appendChild(el);
el.innerHTML = '<p>a</p><p>b</p><p>c</p>';
connectedCallback can't catch the change by innerHTML. Using MutationObserver to know children changes is the best practice.
,
Mar 23 2018
> However, connectedCallback is not a good timing to check child nodes. It seems to be the case in every other browser though, because there it's triggered *after* DOMContentLoaded, not before as it is with Chrome only. > Even Safari and Firefox can call connectedCallback without 3 children if an HTTP response pauses between <but-why because=123> and </but-why>. Yes and no. Safari and FF explicitly triggers connected when the element is known and the DOMContentLoaded has been dispatched, not before. > A custom element user might have code like: It's quite obvious innerHTML can change the content, it has also nothing to do with connectedCallback so please let's stick with this specific case only, thanks. > Using MutationObserver to know children changes is the best practice. Again irrelevant. This bug is about being unable to rely in Chrome on Custom Elements definition. Please let's stick with the issue we have here without talking about other DOM APIs, thanks.
,
Mar 23 2018
> it's triggered *after* DOMContentLoaded, not before as it is with Chrome only. I didn't observe such behavior. "connectedCallback: 0" is always shown before "ready: 3".
,
Mar 23 2018
The sentence was about other browsers. Chrome invokes attachedCallback (aka connectedCalback) after DOMContentLoaded only with CustomElements V0, which is correct: https://webreflection.github.io/eyeo/tests/ce-v0.html Custom Elements V0 also had a created callback which is also always invoked after DOMContentLoaded. Safari does the same with connectedCallback: https://webreflection.github.io/eyeo/tests/ce.html The layout in Safari is: ``` constructor: 0 a b c ready: 3 attributeChangedCallback: 3 connectedCallback: 3 ``` Chrome fails to be consistent with both V0 and other browsers when it comes to V1. Chrome invokes connectedCallback, as well as attributeChangedCallback, *too early*. It should instead queue their invocation or delay Custom Elements initialization *after* DOMContentLoaded. Chrome makes distribution of Custom Elements problematic, because Custom Elements authors are incapable to know if their component definition will be included before or after the DOMContentLoaded event.
,
Mar 23 2018
It's a bug of Safari. custom element callbacks must be called before DOMContentLoaded in this case according to the HTML standard. Firefox Nightly shows: constructor: 0 attributeChangedCallback: 0 a b c connectedCallback: 3 ready: 3
,
Mar 23 2018
OK, let's go back for a second ... we have two browsers out of three showing `connectedCallback: 3`, which is the real issue, and what this ticket is about. I will file a bug in Safari/Webkit repository about DOMContentLoaded, then again I'd like to understand why I can trust connectedCallback in other browsers but not in Chrome.
,
Mar 23 2018
FYI the bug in Webkit has been filed: https://bugs.webkit.org/show_bug.cgi?id=183931
,
Apr 2 2018
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/d55ac7f492e90babfed8eac534eeadaa5be4f640 commit d55ac7f492e90babfed8eac534eeadaa5be4f640 Author: Kent Tamura <tkent@chromium.org> Date: Mon Apr 02 08:34:28 2018 custom-elements: Add tests for callback timing with HTML parser. Bug: 821831 Change-Id: I5b3e1978e37ce34e6fb885ca1077ea90ab2f494c Reviewed-on: https://chromium-review.googlesource.com/987972 Reviewed-by: Takayoshi Kochi <kochi@chromium.org> Commit-Queue: Kent Tamura <tkent@chromium.org> Cr-Commit-Position: refs/heads/master@{#547424} [modify] https://crrev.com/d55ac7f492e90babfed8eac534eeadaa5be4f640/third_party/WebKit/LayoutTests/external/wpt/custom-elements/parser/parser-sets-attributes-and-children.html
,
Apr 2 2018
I investigated the difference between Chrome and Firefox nightly, and found that it's a bug of Firefox nightly. It seems Firefox nightly doesn't implmenet step 3 of https://html.spec.whatwg.org/multipage/parsing.html#insert-a-foreign-element . I added a test for the Safari issue and the Firefox issue to WPT. We won't change any behavior of Chrome for this issue. |
|||||
►
Sign in to add a comment |
|||||
Comment 1 by viswa.karala@chromium.org
, Mar 14 2018