WebReflection / document-register-element

A stand-alone working lightweight version of the W3C Custom Elements specification
ISC License
1.13k stars 116 forks source link

innerHTML helper function calls createdCallback before upgraded element has replaced the existing element #102

Closed johan-ludvigsson-stratsys closed 6 years ago

johan-ludvigsson-stratsys commented 7 years ago

See https://jsfiddle.net/8a50rx17/1/ for example.

Another issue I noticed is that innerHTML seems to cancel out the MutationObserver or something, when calling native innerHTML followed by the helper function. Remove the timeout and you will see that there is only one output.

WebReflection commented 7 years ago

I think this section describes already what's going on there? https://github.com/WebReflection/document-register-element#using-innerhtml

johan-ludvigsson-stratsys commented 7 years ago

Not quite. It is not a question about when the createdcallback is called, rather that it is called in manner where it can't access the child nodes. If you compare the jsfiddle in Chrome and Firefox, you will see that the child nodes are not available in the createdCallback when using the helper function.

If I remember correctly, the issue in the code is that createdCallback is invoked before the upgraded node has replaced the current node.

johan-ludvigsson-stratsys commented 7 years ago
    if (node.createdCallback) {
      node.created = true;
      node.createdCallback();
      node.created = false;
    }
    while ((fc = el.firstChild)) node.appendChild(fc);

Here are the childs appended after createdCallback.

johan-ludvigsson-stratsys commented 7 years ago

Also the same is also true for the parentNode, since the replace occurs just after the snippet I posted. Meaning that a createdCallback that has been used to access the parentNode (in cases of parsed HTML) will not work.

WebReflection commented 7 years ago

OK, I see what you mean.

I have just pushed (not published or tagged) a new innerHTML.js file that moves that part after the node has been appended/replaced, which I believe is the expected behavior.

Would this work for you?

johan-ludvigsson-stratsys commented 7 years ago

That would be as expected. This issue is not really something that impacts me, I just happened to come across it while looking into another issue.

Thanks anyway!

WebReflection commented 7 years ago

So, can we close this?

johan-ludvigsson-stratsys commented 7 years ago

Yep!

There was however one thing (which maybe I should make another report on) that I accidently discovered in the same test. Try this updated fiddle https://jsfiddle.net/8a50rx17/5/ in Chrome and Firefox. You will see that it only generates one output in Firefox.

maikelmclauflin commented 7 years ago

This issue is impacting me currently. Basically just trying to wipe out children in the created callback fails for shim.

is there any way to make sure the element resolves in or before the created callback?

https://jsfiddle.net/sdvjg5kn/2/

WebReflection commented 7 years ago

createdCallback is V0, which is a death API. In V1 you can modify the content only once connectedCallback or attributeChangedCallback is invoked the first time. That is also the right time to do that.

Via V0 you should have a smart class at your root of inheritance that invokes an init (or name as you want it) only once, and as soon as these events are triggered.

In V0 these events are named differently, such attachedCallback.

An example if this mechanism is here: https://github.com/WebReflection/document-register-element/issues/119#issuecomment-334144763

maikelmclauflin commented 7 years ago

Do you have an example of using v1 with es5? i am having a bit of trouble making non es6 happen that happen.

WebReflection commented 7 years ago

you need transpilers (with a patch) but that's the way I'd suggest moving forward otherwise you're stuck forever with a death API and an unmaintained polyfill (I really don't care about V0 API anymore, I don't want to promote its usage)

MikeVaz commented 7 years ago

Here is what you can use for ES5 to implement V1. Works only when polyfill is included. https://jsfiddle.net/webrealizer/c9z5k5nv/

WebReflection commented 7 years ago

don't forget the patch for native extends: https://github.com/WebReflection/babel-plugin-transform-builtin-classes

WebReflection commented 6 years ago

nothing to do here