This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 20189 - [Custom]: Provide an event that signals when all custom elements in static source are ready/upgraded
Summary: [Custom]: Provide an event that signals when all custom elements in static so...
Status: RESOLVED LATER
Alias: None
Product: WebAppsWG
Classification: Unclassified
Component: HISTORICAL - Component Model (show other bugs)
Version: unspecified
Hardware: All All
: P2 normal
Target Milestone: ---
Assignee: Dimitri Glazkov
QA Contact: public-webapps-bugzilla
URL:
Whiteboard:
Keywords:
: 18721 (view as bug list)
Depends on:
Blocks: 18511
  Show dependency treegraph
 
Reported: 2012-11-30 20:03 UTC by Daniel Buchner
Modified: 2013-10-07 16:29 UTC (History)
5 users (show)

See Also:


Attachments

Description Daniel Buchner 2012-11-30 20:03:44 UTC
When using many different custom elements on a page, it quickly becomes tiresome to have to listen for granular-upgrade bubbling for each custom element on the page and filter for the nodes you may want to interact with.

While granular upgrade events are useful, a great many use-cases would benefit from something like a "DOMComponentsUpgraded" event. Such an event would notify the developer when all custom elements in the static source of the page have finished their upgrade cycle and are ready for manipulation. Think of it as the DOMContentLoaded for custom elements.

Thoughts?
Comment 1 Dimitri Glazkov 2012-12-03 17:36:25 UTC
Adding Steve and Scott, because they have ideas.
Comment 2 Scott Miles 2012-12-03 17:55:26 UTC
+1.

I think we absolutely need this event. Otherwise, 'components being ready' at start up becomes a game of bookkeeping (and possibly race conditions).

Scott
Comment 3 Daniel Buchner 2013-04-11 22:48:59 UTC
This is a hugely important event, I say we go with either "DOMComponentsUpgraded" or "DOMElementsUpgraded" - either one seems to convey the point.
Comment 4 Dimitri Glazkov 2013-05-21 20:22:51 UTC
So... here's what I am planning. 

1) The HTML Imports and Custom Elements specs will be written in a way that ensures that by the time the rendering engine starts running script in the document, all of the custom elements would have already been upgraded.

2) Technically, this means that we don't need the DOMElementsUpgraded events, because there's no way for a script to see them in the pre-upgraded state.

3) However, I can totally see how it would be impossible to polyfill this. So, perhaps we should still have this event, and it would be spec'd to fire just before the first <script> element block is to be executed by the parser.

WDYT?
Comment 5 Dominic Cooney 2013-05-22 03:49:28 UTC
(In reply to comment #4)
> So... here's what I am planning. 
> 
> 1) The HTML Imports and Custom Elements specs will be written in a way that
> ensures that by the time the rendering engine starts running script in the
> document, all of the custom elements would have already been upgraded.

To split hairs--all custom elements that could be upgraded have been upgraded.

> 2) Technically, this means that we don't need the DOMElementsUpgraded
> events, because there's no way for a script to see them in the pre-upgraded
> state.
> 
> 3) However, I can totally see how it would be impossible to polyfill this.
> So, perhaps we should still have this event, and it would be spec'd to fire
> just before the first <script> element block is to be executed by the parser.
> 
> WDYT?

I don't think that this is a good idea; won't this mean major surgery to implementations requiring much more speculative parsing? For example, what does this do?

<!DOCTYPE html>
<script>
document.write('You\'re telling me I don\'t run yet?');
</script>
<link rel="import" ...>
<x-a>...

Does it process the import, maybe call x-a's readyCallback, and then rewind things to run the first script block and do the document.write? Seems like crazymaking.

So if you *do* run that script block first (you should!) then polyfilling this is possible; it just means you need to pull in your polyfill before your first <link rel="import" ...>.
Comment 6 Daniel Buchner 2013-05-22 20:32:05 UTC
I don't see how we get out of offering an event, consider the following:

What happens when someone implements and registers their tag definition with purely imperative code via a <script> included in original source or any script piped in that is late-firing?  If I register an element with document.register within a script, am I to presume there is no event to let me know when that code has upgraded all the nodes in the document that match the definition? If so, this could be a significant landmine for developers.

My suggestion would be to fire one 'CustomElementsUpgraded' event for each *type* of element declared (which would contain an 'elementName' property) when all elements of that type present in the DOM have been upgraded. This would allow developers to know when elements are OK to touch regardless of which declaration route they opt for, or how 'late' they register an element.

Make sense? Let me know if I'm explaining the problem/solution clearly.
Comment 7 Dimitri Glazkov 2013-05-22 21:01:10 UTC
(In reply to comment #6)
> I don't see how we get out of offering an event, consider the following:
> 
> What happens when someone implements and registers their tag definition with
> purely imperative code via a <script> included in original source or any
> script piped in that is late-firing?  If I register an element with
> document.register within a script, am I to presume there is no event to let
> me know when that code has upgraded all the nodes in the document that match
> the definition? If so, this could be a significant landmine for developers.

The document.register is synchronous. In other words, anytime you register an element imperatively, the nodes will be upgraded as soon as document.register returns.

There is no timing difference between element registration and element upgrade. They are an atomic operation from the spec perspective -- see steps of https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn-element-registration-algorithm.

> My suggestion would be to fire one 'CustomElementsUpgraded' event for each
> *type* of element declared (which would contain an 'elementName' property)
> when all elements of that type present in the DOM have been upgraded. This
> would allow developers to know when elements are OK to touch regardless of
> which declaration route they opt for, or how 'late' they register an element.

Is the purpose of such event to let consumers of a specific custom element to observe when such custom element is registered?

For example, Bob wants to use <foo-bar>, and he wants to listen to an event that tells him that <foo-bar> has loaded from some set of HTML imports. The only place where I see this useful is if Bob has a script that runs _before_ imports (or calls to document.register):

<script>

document.addEventListener('register', functon(evt) {
    if (evt.localName == 'foo-bar') {
        // do stuff ...
    }
});

</script>
<link rel="import" href="some-component-library.html">
...

Did I get this right? :)
Comment 8 Daniel Buchner 2013-05-22 21:41:02 UTC
(In reply to comment #7)
> (In reply to comment #6)
> > I don't see how we get out of offering an event, consider the following:
> > 
> > What happens when someone implements and registers their tag definition with
> > purely imperative code via a <script> included in original source or any
> > script piped in that is late-firing?  If I register an element with
> > document.register within a script, am I to presume there is no event to let
> > me know when that code has upgraded all the nodes in the document that match
> > the definition? If so, this could be a significant landmine for developers.
> 
> The document.register is synchronous. In other words, anytime you register
> an element imperatively, the nodes will be upgraded as soon as
> document.register returns.

I thought this was the case - it seems Google's Custom Elements polyfill (both stable and master) never upgrades in-source elements when document.register() is used anywhere other than an imported HTML file. I'll file a bug for Scott and team on GitHub.

> > My suggestion would be to fire one 'CustomElementsUpgraded' event for each
> > *type* of element declared (which would contain an 'elementName' property)
> > when all elements of that type present in the DOM have been upgraded. This
> > would allow developers to know when elements are OK to touch regardless of
> > which declaration route they opt for, or how 'late' they register an element.
> 
> Is the purpose of such event to let consumers of a specific custom element
> to observe when such custom element is registered?
> 
> For example, Bob wants to use <foo-bar>, and he wants to listen to an event
> that tells him that <foo-bar> has loaded from some set of HTML imports. The
> only place where I see this useful is if Bob has a script that runs _before_
> imports (or calls to document.register):
> 
> <script>
> 
> document.addEventListener('register', functon(evt) {
>     if (evt.localName == 'foo-bar') {
>         // do stuff ...
>     }
> });
> 
> </script>
> <link rel="import" href="some-component-library.html">
> ...
> 
> Did I get this right? :)

Yeah, this is a good summary of the use-case. It would be a factor if a developer wanted to act on a type of element when it becomes ready and they either don't control the definition/execution of it, or don't know when it will be imported/registered.

Technically, the difficulty I was facing was due to the Google polyfill bug, but I believe the scenario posed above remains a valid use-case - do you agree?
Comment 9 Dimitri Glazkov 2013-05-29 19:21:41 UTC
*** Bug 18721 has been marked as a duplicate of this bug. ***