Closed WebReflection closed 6 years ago
AMP short circuits the loop if document.readyState == 'complete'
and if the loop determines that there is no nextSibling
it does these 2 things
setInterval(…, 5)
for a nextSibling
to appearDOMContentLoaded
fires.This could probably also be implemented with MutationObserver
but the polling works pretty well.
Thanks @cramforce . My current resolution with full code coverage uses indeed a similar approach.
It's not optimal when a node isn't "ready" for long time but it grants the following:
document.readyState
is already complete and created()
kicks in before anything elseThere's also a guard against fake DOMContentLoaded events so every bloody case should be covered.
Thanks for hints and info.
The current
created() {...}
method should grant somehow that a Custom Element is live and/or well known.Unfortunately this is inconsistent due bugs present in 2 browsers out of 3 implementing Custom Elements.
Apparently the correct behavior is the one that would see
created()
invoke fail if the custom element is defined before DOMContentLoaded happens.https://bugs.chromium.org/p/chromium/issues/detail?id=821831
Workaround
The proposed work around comes from this @cramforce tweet and it seems to work in general but it has the following outstanding issue: in a case where the custom element is the last child of a tree of single/last child it fails to ever return true if the parent node has no white spaces or extra nodes.
This is particularly easy to reproduce via hyperHTML template literals so that such work around might result into a never ready component.
In above example
document.body
as well asdocument.documentElement
anddocument
itself will not have anextSibling
so the result of a main custom element as body app would be "never ready".Possible improvements
The not fully ready case never really happens with hyperHTML itself and it might occur for custom elements only when defined before DOMContentLoaded with Custom Elements within the body.
This is a specific issue with HyperHTMLElement class only, and very specific to the current document parsing state.
In order to be sure everything works:
defer
red scriptdocument.readyState
is notcomplete
keeping same logic in place, queuing all created callbacks invoked 'till that time instead of executing them onceIn latter case this
.ready
getter would be redundant / pointless, since any CE could definethis.ready = true
in their created constructor.