Re: alternate view on constructors for custom elements

2015-07-17 Thread Ryosuke Niwa

> On Jul 17, 2015, at 1:14 PM, Travis Leithead  
> wrote:
> 
> From: Domenic Denicola [mailto:d...@domenic.me] 
> 
>>> window.XFoo = document.registerElement(‘x-foo’, XFooStartup);
>> 
>> Why is XFoo different from XFooStartup? If I define a method in XFooStartup, 
>> does it exist in XFoo?
> 
> This won't work as I described it, given what you've told me, but my 
> assumption was essentially, that XFooStartup would act as if it didn't really 
> depend on HTMLElement for construction. So, it's constructor wouldn't be 
> linked to the actual custom element creation. Therefore XFoo (the 
> platform-provided constructor function is the thing that is actually used to 
> trigger construction, which would then result in the XFooStartup constructor 
> running. Basically, like this (reverting to non-class syntax):
> 
> function XFooStartup(val1, val2) {
>  this.prop = val1;
>  this.prop2 = val2;
> }
> window.XFoo = document.registerElement(‘x-foo’, XFooStartup);
> 
> all I was trying to express different from the current design is: 
> 1) replacing the createdCallback with the function constructor (and passing 
> the new element instance as 'this' when calling it)
> 2) passing through params from the XFoo platform-native constructor to the 
> XFooStartup function
> 3) calling XFooStartup synchronously

We can do this without wrapping author supplied constructor.  In ES6/ES2015 
classes, `this` variable is in the temporary dead zone (TDZ) until `super()` 
which allocates `this` and any attempt to access it will throw 
`ReferenceError`.  In other words, XFooStartup has no way of accessing the 
newly constructed object until `super()` has returned.  This in turns allows 
browser engines to create a native (C++) backing store for the HTML element 
inside HTMLElement’s constructor (or an equivalent code that runs as a part of 
call to `super()` from the direct subclass of HTMLElement) since the newly 
constructed (this) element is never accessed until the highest superclass' 
`super()` (which is HTMLElement in this case) had been called.

- R. Niwa




RE: alternate view on constructors for custom elements

2015-07-17 Thread Domenic Denicola
From: Travis Leithead [mailto:travis.leith...@microsoft.com]

> if super() is absolutely required for a constructor in a class
> that extends something, is there a requirement about when in the
> constructor method it be invoked? Must it always be the first call? Can it be
> later on, say at the end of the function?

It must be before `this` is referenced.

> Basically, like this (reverting to non-class syntax):

Yeah, and at that point you might as well make it a method on the actual class, 
and give it a nice name, like, say, createdCallback ;). Or, make it a function 
that takes the element as a parameter, and keep it separate from the class, 
perhaps in a "hooks" object ;).



RE: alternate view on constructors for custom elements

2015-07-17 Thread Travis Leithead
From: Domenic Denicola [mailto:d...@domenic.me] 
>
>From: Travis Leithead [mailto:travis.leith...@microsoft.com] 
>
>> Something magical happens here. The use of super() is supposed to call the 
>> constructor of the HTMLElement class—but that’s not a normal JS class. It 
>> doesn’t have a defined constructor() method [yet?].
>
>Yep. We'd need to define one; it's absolutely required. ES2015 classes that 
>don't call super() in their constructor simply aren't allowed, which means 
>inheriting from a constructor that throws (like HTMLElement currently does) is 
>impossible.
>
>https://github.com/domenic/element-constructors is a start at this.

Hmm. This does help. A lot. I wasn't aware that ES2015 classes added all these 
restrictions on top of the syntactic sugar over the classing function 
technique. Now I have some study to do to catch up. One question though before 
I do that: if super() is absolutely required for a constructor in a class that 
extends something, is there a requirement about when in the constructor method 
it be invoked? Must it always be the first call? Can it be later on, say at the 
end of the function? 

>I take it when you said in [1]:
>
> I've discussed this issue with some of Edge's key parser developers. From a 
> technical ground, we do not have a problem with stopping the parser to 
> callout to author code in order to run a constructor, either during parsing 
> or cloning. For example, in parsing, I would expect that the callout happens 
> after initial instance creation, but before the target node is attached to 
> the DOM tree by the parser.
>
>you were not aware of this? Maybe now you better understand my follow-up 
>question in [2],

Yep. :-|

>> window.XFoo = document.registerElement(‘x-foo’, XFooStartup);
>
>Why is XFoo different from XFooStartup? If I define a method in XFooStartup, 
>does it exist in XFoo?

This won't work as I described it, given what you've told me, but my assumption 
was essentially, that XFooStartup would act as if it didn't really depend on 
HTMLElement for construction. So, it's constructor wouldn't be linked to the 
actual custom element creation. Therefore XFoo (the platform-provided 
constructor function is the thing that is actually used to trigger 
construction, which would then result in the XFooStartup constructor running. 
Basically, like this (reverting to non-class syntax):

function XFooStartup(val1, val2) {
  this.prop = val1;
  this.prop2 = val2;
}
window.XFoo = document.registerElement(‘x-foo’, XFooStartup);

all I was trying to express different from the current design is: 
1) replacing the createdCallback with the function constructor (and passing the 
new element instance as 'this' when calling it)
2) passing through params from the XFoo platform-native constructor to the 
XFooStartup function
3) calling XFooStartup synchronously


Re: alternate view on constructors for custom elements

2015-07-17 Thread Boris Zbarsky

On 7/17/15 2:03 PM, Travis Leithead wrote:

Something magical happens here. The use of super() is supposed to call
the constructor of the HTMLElement class—but that’s not a normal JS
class. It doesn’t have a defined constructor() method


Sure, but neither does Array.  What super() actually does is get the 
prototype of the current constructor and call it.  So in your case:


class CustomElement extends HTMLElement {
   constructor() {
  super();
   }
}

it would call the HTMLElement constructor.

Now there's a slight problem here, which is that HTMLElement is not 
defined to have a constructor in the spec right now.  We need to fix 
that, clearly, for this subclassing of elements with constructors stuff 
to make sense.



Also, as
has been pointed out, running the CustomElement constructor code
_/before/_ instantiating the actual element (at parse-time for example)


I'm not sure what "before" means here.  In the hypothetical world in 
which we call the CustomElement constructor from the parser, the parser 
would do that, and get back an object.  That would be the "actual element".



·Javascript classes are mutable—what if CustomElement’s proto chain is
mutated later?


Then you get something that may not be an HTMLElement when you construct 
via it.  Obviously consumers who care (like the parser, perhaps; though 
it may only care about getting Element) would need to check and handle 
that problem.



1.Native [internal] element is created with appropriate tag name,
attributes, etc.

2.JS constructor is called and provided the instance (as ‘this’)


The only problem with that is what Anne pointed out: there are some 
proposed ES spec additions that would require that the initial JS object 
allocation take the subclassing bits into account to determine which 
immutable state it's preallocated with.  Note that I'm not convinced 
that means we need to call JS from the parser; just that's the problem 
Anne is trying to solve.


Need to chew a bit on your XFooStartup proposal before I can comment on 
it intelligently.


-Boris



Two new custom elements ideas

2015-07-17 Thread Domenic Denicola
Hi all,

Over the last few days I’ve worked on two new potential ideas for custom 
elements, hoping to shake things up with new possibilities. These are both 
largely geared around how we react to the key custom elements question [1].

https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Optional-Upgrades-Optional-Constructors.md
 : this proposal assumes we come out in favor of running author code during 
parsing/cloning/editing/etc. It allows component authors to choose between 
using constructors, thus disallowing their components to be used with 
server-side rendering/progressive enhancement, and using a 
createdCallback-style two-stage initialization, which will then allow 
progressive enhancement. It is meant explicitly as a compromise proposal, 
similar in spirit to the { mode: "open"/"closed" } proposal, since we know 
different parties have different values and the way forward may be to simply 
accommodate both value systems and let developers light a path.

https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Parser-Created-Constructors.md
 : this proposal assumes we do not achieve consensus to run author code during 
parsing/cloning/editing/etc. It recognizes that, if we disallow this, we cannot 
allow custom constructors, and then tries to make the best of that world. In 
particular, it is an alternative to the “Dmitry” proposal, designed to entirely 
avoid the dreaded proto-swizzling, while still having many of the same 
benefits. If you scroll to the bottom, you note how it also leaves the door 
open for future custom constructors, if we decide that it's something that we 
want in the future, but simply cannot afford to specify or implement right now 
due to how hard that is. In this sense it's meant somewhat as a bridging 
proposal, similar in spirit to the slots proposal, which falls short of the 
ideal imperative distribution API but will probably work for most developers 
anyway.

These are largely meant to get ideas moving, and to avoid polarizing the 
discussion into two camps. As I noted in [2], there are several degrees of 
freedom here; the key custom elements question is distinct from upgrades, which 
is distinct from ES2015 class syntax, which is distinct from constructor vs. 
created lifecycle hook, etc. The possibility space is pretty varied, and we 
have multiple tools in our toolbox to help arrive at a resolution that everyone 
finds agreeable.

Comments are of course welcome, and if you have time to read these before the 
F2F that would be really appreciated.

Thanks,
-Domenic

[1]: https://lists.w3.org/Archives/Public/public-webapps/2015JulSep/0159.html
[2]: https://lists.w3.org/Archives/Public/public-webapps/2015JulSep/0162.html



RE: alternate view on constructors for custom elements

2015-07-17 Thread Domenic Denicola
From: Travis Leithead [mailto:travis.leith...@microsoft.com] 

> Something magical happens here. The use of super() is supposed to call the 
> constructor of the HTMLElement class—but that’s not a normal JS class. It 
> doesn’t have a defined constructor() method [yet?].

Yep. We'd need to define one; it's absolutely required. ES2015 classes that 
don't call super() in their constructor simply aren't allowed, which means 
inheriting from a constructor that throws (like HTMLElement currently does) is 
impossible.

https://github.com/domenic/element-constructors is a start at this.

> I’m trying to rationalize the custom elements previous design with the use of 
> constructors. Basically, I think it should still be a two-stage creation 
> model:
> 1. Native [internal] element is created with appropriate tag name, 
> attributes, etc.
> 2. JS constructor is called and provided the instance (as ‘this’)
>
> #1 is triggered by the parser, or by a native constructor function. That 
> constructor function could either be provided separately like it is returned 
> from registerElement today, or in some other way (replacing the original 
> constructor?). Since replacing the original constructor sounds weird and 
> probably violates a bunch of JS invariants, I’ll assume sticking with the 
> original model. 
>
> This makes it much safer for implementations, since the native custom element 
> can always be safely created first, before running JS code. It also means 
> there’s no magic super() at work—which seems to leave too much control up to 
> author code to get right.

Ah! This is a big mistake!! You simply cannot do this split with ES2015 classes.

ES2015 classes are predicated on the idea that construction is an atomic 
operation, consisting of both allocation and initialization in one step. As 
such, class constructors cannot be called, only `new`ed. You cannot apply them 
with an already-created `this`, as if they were methods. This is fundamental to 
the class design; any other model needs to fall back to simply functions, not 
classes.

Indeed, the currently-specced design had a two-stage model---allocation/base 
initialization by the UA-generated constructor returned by 
document.registerElement, and author-controlled initialization by 
createdCallback(). This separation is, as you point out, makes things safer and 
easier to specify. And it is absolutely impossible to achieve if you insist on 
custom constructors, because in that case all allocation and initialization 
must happen together atomically. If we allow custom constructors, the 
allocation and initialization must both happen with a synchronous call to the 
custom constructor (which itself must call super()).

I take it when you said in [1]:

> I've discussed this issue with some of Edge's key parser developers. From a 
> technical ground, we do not have a problem with stopping the parser to 
> callout to author code in order to run a constructor, either during parsing 
> or cloning. For example, in parsing, I would expect that the callout happens 
> after initial instance creation, but before the target node is attached to 
> the DOM tree by the parser.

you were not aware of this? Maybe now you better understand my follow-up 
question in [2],

> Can you expand on this more? In particular I am confused on how "initial 
> instance creation" can happen without calling the constructor.

[1]: https://lists.w3.org/Archives/Public/public-webapps/2015JulSep/0161.html
[2]: https://lists.w3.org/Archives/Public/public-webapps/2015JulSep/0162.html

> Basic example of what I’m thinking:
>
> class XFooStartup extends HTMLElement {
>   constructor(val1, val2) {
>  this.prop = val1;
>  this.prop2 = val2;

This is invalid at runtime, since it fails to call super().

>   }
> }
> window.XFoo = document.registerElement(‘x-foo’, XFooStartup);

Why is XFoo different from XFooStartup? If I define a method in XFooStartup, 
does it exist in XFoo?

> // (1)
> var x1 = new XFooStartup(“first”, “second”);
> // (2)
> var x2 = new XFoo(“first”, “second”);
>
> Calling (1) does not create a custom element. Extending from HTMLElement is 
> not magical, it’s just a prototype inheritance, as can be done today. super() 
> would do whatever super() does when the super class has no defined method to 
> invoke.

(It would throw, in other words.)

> x1 is a regular JS object with a .prop and .prop2.

This can't be true. Either x1 doesn't exist, because you didn't call super() 
and so `new XFooStartup` threw. Or x1 called super(), and it is no longer an 
ordinary JS object, because by calling super() (which is basically shorthand 
for `this = new super()`) you have made sure that it is a true 
allocated-and-initialized-by-the-UA HTMLElement.

> Calling (2) runs the platform-provided constructor function which internally 
> inits a new HTMLElement in the C++ (or could be Element if in XML document?). 
> Then the platform immediately (synchronously) invokes the provided 
> construc

alternate view on constructors for custom elements

2015-07-17 Thread Travis Leithead
OK, after reading Dominic's proposal [1], I'm a little confused. I thought that 
I understood how constructors should work, but there's some magic going on that 
I can't follow... I'm sure you folks can help.

```
class CustomElement extends HTMLElement {
   constructor() {
  super();
   }
}

Something magical happens here. The use of super() is supposed to call the 
constructor of the HTMLElement class-but that's not a normal JS class. It 
doesn't have a defined constructor() method [yet?]. Also, as has been pointed 
out, running the CustomElement constructor code _before_ instantiating the 
actual element (at parse-time for example) opens up a world of potential 
problems as have been explored:

*Javascript classes are mutable-what if CustomElement's proto chain is 
mutated later?

*What if the constructor throws?
...just to name a few.

I'm trying to rationalize the custom elements previous design with the use of 
constructors. Basically, I think it should still be a two-stage creation model:

1.  Native [internal] element is created with appropriate tag name, 
attributes, etc.

2.  JS constructor is called and provided the instance (as 'this')

#1 is triggered by the parser, or by a native constructor function. That 
constructor function could either be provided separately like it is returned 
from registerElement today, or in some other way (replacing the original 
constructor?). Since replacing the original constructor sounds weird and 
probably violates a bunch of JS invariants, I'll assume sticking with the 
original model.

This makes it much safer for implementations, since the native custom element 
can always be safely created first, before running JS code. It also means 
there's no magic super() at work-which seems to leave too much control up to 
author code to get right.

Basic example of what I'm thinking:

class XFooStartup extends HTMLElement {
   constructor(val1, val2) {
  this.prop = val1;
  this.prop2 = val2;
   }
}
window.XFoo = document.registerElement('x-foo', XFooStartup);

// (1)
var x1 = new XFooStartup("first", "second");
// (2)
var x2 = new XFoo("first", "second");

Calling (1) does not create a custom element. Extending from HTMLElement is not 
magical, it's just a prototype inheritance, as can be done today. super() would 
do whatever super() does when the super class has no defined method to invoke. 
x1 is a regular JS object with a .prop and .prop2.

Calling (2) runs the platform-provided constructor function which internally 
inits a new HTMLElement in the C++ (or could be Element if in XML document?). 
Then the platform immediately (synchronously) invokes the provided constructor 
function as if:
XFooStartup.apply(newHTMLElementInstance, argsPassedThroughFromCall);
so that XFooStartup's constructor operates on the 'this' being the instance 
created by the platform.


[1] 
https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Optional-Upgrades-Optional-Constructors.md


Re: The key custom elements question: custom constructors?

2015-07-17 Thread Boris Zbarsky

On 7/17/15 12:05 PM, Anne van Kesteren wrote:

True, but either way this doesn't seem like a problem. You can create
a DocumentFragment, insert a new , and then let it be GC'd,
today.


Sure.  In practice it won't get GC'd until the load completes, which is 
sucky, but that's life.


-Boris




Re: The key custom elements question: custom constructors?

2015-07-17 Thread Anne van Kesteren
On Fri, Jul 17, 2015 at 5:47 PM, Boris Zbarsky  wrote:
> On 7/17/15 10:38 AM, Anne van Kesteren wrote:
>> If I look at "update the image data" step 6 it seems it might be
>> fetched at a later point?
>
> Yes, but in practice the fetch will go ahead, no?  There's nothing to
> prevent it from happening, so it's going to happen once you reach a stable
> state...

True, but either way this doesn't seem like a problem. You can create
a DocumentFragment, insert a new , and then let it be GC'd,
today.


-- 
https://annevankesteren.nl/



Re: The key custom elements question: custom constructors?

2015-07-17 Thread Boris Zbarsky

On 7/17/15 10:38 AM, Anne van Kesteren wrote:

If I look at "update the image data" step 6 it seems it might be
fetched at a later point?


Yes, but in practice the fetch will go ahead, no?  There's nothing to 
prevent it from happening, so it's going to happen once you reach a 
stable state...


-Boris



Re: The key custom elements question: custom constructors?

2015-07-17 Thread Anne van Kesteren
On Fri, Jul 17, 2015 at 4:15 PM, Domenic Denicola  wrote:
> From: Anne van Kesteren [mailto:ann...@annevk.nl]
>> It fails atomically, based on the definition of innerHTML.
>
> What if that 512 KiB of HTML contains ? Following 
> definitions, I assume we fire off the network request?

If I look at "update the image data" step 6 it seems it might be
fetched at a later point?


> What if it contains a  where XBaz's constructor does 
> `document.body.innerHTML = "Hello"`? Can the parsing algorithm deal 
> with the (following the definitions, required) re-entrancy?

I think the specification can, since it just invokes the fragment
parser with some parameters and then replaces the contents of XBaz
with the obtained DocumentFragment. Implementations probably can too.
E.g., document.body.innerHTML = "..."  is quite
similar.


-- 
https://annevankesteren.nl/



RE: The key custom elements question: custom constructors?

2015-07-17 Thread Domenic Denicola
From: Anne van Kesteren [mailto:ann...@annevk.nl] 

>> // What about
>> document.body.innerHTML = "[512 KiB of normal HTML] "; 
>> // ? does the HTML make it in, or does the operation fail atomically, or 
>> something else?
>
> It fails atomically, based on the definition of innerHTML.

What if that 512 KiB of HTML contains ? Following 
definitions, I assume we fire off the network request?

What if it contains a  where XBaz's constructor does 
`document.body.innerHTML = "Hello"`? Can the parsing algorithm deal with 
the (following the definitions, required) re-entrancy?



[Bug 28614] Weaken the requirement of the time of running async steps

2015-07-17 Thread bugzilla
https://www.w3.org/Bugs/Public/show_bug.cgi?id=28614

Anne  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |WORKSFORME

--- Comment #7 from Anne  ---
Yeah, Philip is correct. Resize can already take any amount of time.

-- 
You are receiving this mail because:
You are on the CC list for the bug.



[Bug 27162] Browser differences in graphical layout of fullscreen mode.

2015-07-17 Thread bugzilla
https://www.w3.org/Bugs/Public/show_bug.cgi?id=27162

Anne  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |WORKSFORME

-- 
You are receiving this mail because:
You are on the CC list for the bug.



Re: Informal Service Worker working session

2015-07-17 Thread Alex Russell
Thanks everyone! Started a draft agenda page here; please pile in!

https://github.com/slightlyoff/ServiceWorker/wiki/july_20_2015_meeting_agenda

On Wed, Jul 15, 2015 at 10:38 PM, Benjamin Kelly  wrote:

> On Sat, Jul 4, 2015 at 7:26 AM, Alex Russell 
> wrote:
>
>> As many SW participants are going to be in town for the WebApps F2F on
>> the 21st, Google San Francisco is hosting a working day, 9am-5pm PST on
>> July 20th to work through open issues and discuss future work.
>>
>> If you're attending, or would like to, simply RSVP here:
>> http://doodle.com/hqm3ga8pfepidy7r
>>
>
> Alex,
>
> Thanks for hosting!
>
> In preparation for the meeting we've come up with a rough list of things
> we'd like to discuss next week:
>
>  - Clarify behavior in places where the fetch spec has not been integrated
> into other specs yet.  For example, intercepting something that is
> currently same-origin with a synthetic or CORS response, how interception
> works with CSP, etc.  Clearly Chrome has done something for these cases and
> we'd like to be compatible where possible.
>  - Consider adding a "foreign fetch" feature to communicate with a SW on a
> different origin.  Straw man of the concept can be found at
> https://wiki.whatwg.org/wiki/Foreign_Fetch .
>  - Discuss navigator.connect().  In particular, can the use cases
> motivating navigator.connect() be satisfied with a simpler solution like
> the "foreign fetch" concept.
>  - Discuss how to make it easier to use multiple service workers for the
> same site.  For example, currently its difficult to update two service
> workers coherently.  One will always be a newer version than the other.
>  - Discuss how to handle heavy-weight processing for things like
> background sync without introducing fetch event latency.  This could be
> using multiple service workers (with issues above addressed) or possible
> supporting SharedWorker, etc.
>  - Consider using the service worker script URL to identify the service
> worker instead of its scope.  This would move us closer to not requiring a
> scope for service workers that aren't handling fetch events.
>  - Consider allowing specific features, like fetch and push, to be
> specified at registration time.  Again, the goal is to get away from the
> current situation where registering a service worker immediately implies
> fetch event handling.
>  - Consider providing an API for creating a service worker without going
> through the installation life cycle.
>  - Share information about how we plan to avoid abuse of push and
> background sync events.
>
> Anyway, we just wanted to give people a chance to think about some of this
> before we meet.  Obviously we may not have time to cover all of this in a
> day, but it would be nice to cover any contentious bits.
>
> Thanks again and see you all next week.
>
> Ben
>


Re: The key custom elements question: custom constructors?

2015-07-17 Thread Anne van Kesteren
On Thu, Jul 16, 2015 at 10:36 PM, Domenic Denicola  wrote:
> I have a related question: what happens if the constructor throws?

Right, this is the kind of thing we need to figure out.


> 
> 
> "use strict";
>
> window.throwingMode = true;
>
> class XFoo extends HTMLElement {
> constructor() {
> if (window.throwingMode) {
> throw new Error("uh-oh!");
> }
> }
> }
>
> document.registerElement("x-foo", XFoo);
> 
>
> 
>
>