New issue
Advanced search Search tips

Issue 821831 link

Starred by 4 users

Issue metadata

Status: WontFix
Owner:
Closed: Apr 2018
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Mac
Pri: 3
Type: Bug



Sign in to add a comment

Custom Elements unreliable initialization before DOMContentLoaded

Reported by andrea.g...@gmail.com, Mar 14 2018

Issue description

UserAgent: 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.
 
ce.html
1.1 KB View Download
Labels: Needs-Triage-M64
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.
Components: Blink
Components: -Blink Blink>HTML>CustomElements

Comment 5 by tkent@chromium.org, Mar 23 2018

Labels: -Pri-2 -Needs-Triage-M64 Hotlist-Interop Pri-3
Status: Available (was: Unconfirmed)
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.

> 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.

Comment 7 by tkent@chromium.org, 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". 
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.

Comment 9 by tkent@chromium.org, 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

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.


FYI the bug in Webkit has been filed:
https://bugs.webkit.org/show_bug.cgi?id=183931
Project Member

Comment 12 by bugdroid1@chromium.org, 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

Owner: tkent@chromium.org
Status: WontFix (was: Available)
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