W3C home > Mailing lists > Public > public-webapps@w3.org > January to March 2014

Re: Why can't we just use constructor instead of createdCallback?

From: Dimitri Glazkov <dglazkov@google.com>
Date: Tue, 18 Feb 2014 10:35:18 -0800
Message-ID: <CADh5Ky3ut=dV8sHjaha7jdGwwDajxiHTc=fDR8HrxEaS4A=faA@mail.gmail.com>
To: Jonas Sicking <jonas@sicking.cc>
Cc: Boris Zbarsky <bzbarsky@mit.edu>, Ryosuke Niwa <rniwa@apple.com>, Erik Arvidsson <arv@chromium.org>, WebApps WG <public-webapps@w3.org>, "Edward O'Connor" <eoconnor@apple.com>, William Chen <wchen@mozilla.com>
On Fri, Feb 14, 2014 at 3:58 PM, Jonas Sicking <jonas@sicking.cc> wrote:

>
> What I mean is that for nodes that doesn't have a constructor, and
> whose parent doesn't have a constructor, no need to add them to the
> above arrays. Just insert them into their parent. That means that when
> that the constructor of an element runs, the element doesn't have any
> parents or children.
>
> So no need to hide parents or children anywhere.
>

Okay, let me see if I got this right. The list is effectively a serialized
representation of a document subtree. The parent + order in the list
provides all the necessary information. We use this list to separate tree
construction into two stages: one before custom element constructors are
called, and one after.

In cases when the custom element is just a like button widget (a leaf in
the tree), the list is short and just contains the widgets.

In cases like "<body><my-app><div> ... the entire doc tree ...
</my-app></body>", the list contains the entire subtree of <my-app>, which
is effectively the document.

In cases like "<div><my-bar>..</my-bar><span>...</span> ... more siblings
... </div>", the list will contain at least all siblings of <my-bar>,
because they can't be inserted into tree until after <my-bar>'s constructor
runs.

When run, the constructors are free to explore the partially-completed
tree, which enables interesting hacks like this:

in document:
<div id="a"><my-bar></my-bar>.... lots more markup...

in my-bar constructor:
var myFutureParent = document.querySelector("#a");
// redirect tree construction to resume at a new point.
document.body.appendChild(myFutureParent);

Or, in my-bar constructor:
var myFutureParent = document.querySelector("#a");
var iframe = document.body.appendChild(document.createElement("iframe"));
// teleport the tree into another frame
iframe.contentDocument.body.appendChild(myFutureParent);

I can't immediately tell whether these hacks are cool or scary.

The thing that really bothers me is that this approach is contradicting
itself. We go to into pretty elaborate lengths to enable running
constructors during parsing, but the key performance lesson developers will
immediately learn is to avoid constructors on custom elements, because they
will trigger the two-phase code path during parsing. Here's a thing that
you can use, but you probably don't want to ever use it.

Here's an alternative proposal:

1) The Web developers are already aware of the fact that you can create new
instances of JS objects without running their constructors with
Object.create

2) Let's make sure that when they call constructors directly (as in var b =
new MyB(arg1,arg2);), the constructor is actually called.

3) When the parser instantiates the element, it does the equivalent of
Object.create, so no constructor is called.

It seems simple and easy to understand.

:DG<
Received on Tuesday, 18 February 2014 18:35:46 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 18:14:22 UTC