Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-20 Thread Dimitri Glazkov
It seems that there's some additional reasoning that needs to go into
whether an element could be constructed as custom tag. Like in this
case, it should work both as a custom tag and as a type extension (the
is attr).

:DG

On Tue, Feb 19, 2013 at 10:13 PM, Daniel Buchner dan...@mozilla.com wrote:
 Nope, you're 100% right, I saw header and thought HTMLHeadingElement for
 some reason - so this seems like a valid concern. What are the
 mitigation/solution options we can present to developers for this case?


 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Tue, Feb 19, 2013 at 9:17 PM, Scott Miles sjmi...@google.com wrote:

 Perhaps I'm making a mistake, but there is no specific prototype for the
 native header element. 'header', 'footer', 'section', e.g., are all
 HTMLElement, so all I can do is

 FancyHeaderPrototype = Object.create(HTMLElement.prototype);

 Afaict, the 'headerness' cannot be expressed this way.


 On Tue, Feb 19, 2013 at 8:34 PM, Daniel Buchner dan...@mozilla.com
 wrote:

 Wait a sec, perhaps I've missed something, but in your example you never
 extend the actual native header element, was that on purpose? I was under
 the impression you still needed to inherit from it in the prototype
 creation/registration phase, is that not true?

 On Feb 19, 2013 8:26 PM, Scott Miles sjmi...@google.com wrote:

 Question: if I do

 FancyHeaderPrototype = Object.create(HTMLElement.prototype);
 document.register('fancy-header', {
   prototype: FancyHeaderPrototype
 ...

 In this case, I intend to extend header. I expect my custom elements
 to look like header is=fancy-header, but how does the system know what
 localName to use? I believe the notion was that the localName would be
 inferred from the prototype, but there are various semantic tags that share
 prototypes, so it seems ambiguous in these cases.

 S



Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-20 Thread Scott Miles
Since many of these cases are 'semantic' elements, whose only raison d'être
(afaik) is having a particular localName, I'm not sure how we get around
this without being able to specify an 'extends' option.

document.register('fancy-header', {
  prototype: FancyHeaderPrototype,
  extends: 'header'
...



On Wed, Feb 20, 2013 at 9:54 AM, Dimitri Glazkov dglaz...@google.comwrote:

 It seems that there's some additional reasoning that needs to go into
 whether an element could be constructed as custom tag. Like in this
 case, it should work both as a custom tag and as a type extension (the
 is attr).

 :DG

 On Tue, Feb 19, 2013 at 10:13 PM, Daniel Buchner dan...@mozilla.com
 wrote:
  Nope, you're 100% right, I saw header and thought HTMLHeadingElement for
  some reason - so this seems like a valid concern. What are the
  mitigation/solution options we can present to developers for this case?
 
 
  Daniel J. Buchner
  Product Manager, Developer Ecosystem
  Mozilla Corporation
 
 
  On Tue, Feb 19, 2013 at 9:17 PM, Scott Miles sjmi...@google.com wrote:
 
  Perhaps I'm making a mistake, but there is no specific prototype for the
  native header element. 'header', 'footer', 'section', e.g., are all
  HTMLElement, so all I can do is
 
  FancyHeaderPrototype = Object.create(HTMLElement.prototype);
 
  Afaict, the 'headerness' cannot be expressed this way.
 
 
  On Tue, Feb 19, 2013 at 8:34 PM, Daniel Buchner dan...@mozilla.com
  wrote:
 
  Wait a sec, perhaps I've missed something, but in your example you
 never
  extend the actual native header element, was that on purpose? I was
 under
  the impression you still needed to inherit from it in the prototype
  creation/registration phase, is that not true?
 
  On Feb 19, 2013 8:26 PM, Scott Miles sjmi...@google.com wrote:
 
  Question: if I do
 
  FancyHeaderPrototype = Object.create(HTMLElement.prototype);
  document.register('fancy-header', {
prototype: FancyHeaderPrototype
  ...
 
  In this case, I intend to extend header. I expect my custom elements
  to look like header is=fancy-header, but how does the system know
 what
  localName to use? I believe the notion was that the localName would be
  inferred from the prototype, but there are various semantic tags that
 share
  prototypes, so it seems ambiguous in these cases.
 
  S



Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-20 Thread Scott Miles
[I messed up and failed to reply-all a few messages back, see the quoted
text to pick up context]

 semantic is only important in markup

Hrm, ok. I'll have to think about that.

At any rate, I'm concerned that developers will not be able to predict what
kind of node they will get from a constructor. We had a rule that you get
one kind of node for 'custom' elements and another for extensions of known
elements. But now it's more complicated.

Scott

On Wed, Feb 20, 2013 at 10:39 AM, Dimitri Glazkov dglaz...@google.comwrote:

 On Wed, Feb 20, 2013 at 10:34 AM, Scott Miles sjmi...@google.com wrote:
  var FancyHeader = document.register('fancy-header', {prototype:
  FancyHeaderPrototype});
  document.appendChild(new FancyHeader());
 
  what I expect in my document:
 
  !-- better have localName 'header', because I specifically want to
  communicate that semantic --
  header is=fancy-header

 But semantic is only important in markup? If you're building this
 imperatively, there's really no semantics anymore. You're in a DOM
 tree.

 Now, a valid question would be: what if I wanted to serialize this DOM
 tree in a certain way? I don't have an answer to that.

 :DG



Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-19 Thread Scott Miles
 I'd be a much happier camper if I didn't have to think about handling
different return values.

I agree, and If it were up to me, there would be just one API for
document.register.

However, the argument given for dividing the API is that it is improper to
have a function return a value that is only important on some platforms. If
that's the winning argument, then isn't it pathological to make the 'non
constructor-returning API' return a constructor?


On Mon, Feb 18, 2013 at 12:59 PM, Daniel Buchner dan...@mozilla.com wrote:

 I agree with your approach on staging the two specs for this, but the last
 part about returning a constructor in one circumstance and undefined in the
 other is something developers would rather not deal with (in my
 observation). If I'm a downstream consumer or library author who's going to
 wrap this function (or any function for that matter), I'd be a much happier
 camper if I didn't have to think about handling different return values. Is
 there a clear harm in returning a constructor reliably that would make us
 want to diverge from an expected and reliable return value? It seems to me
 that the unexpected return value will be far more annoying than a little
 less mental separation between the two invocation setups.

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Mon, Feb 18, 2013 at 12:47 PM, Dimitri Glazkov dglaz...@google.comwrote:

 On Fri, Feb 15, 2013 at 8:42 AM, Daniel Buchner dan...@mozilla.com
 wrote:
  I'm not sure I buy the idea that two ways of doing the same thing does
 not
  seem like a good approach - the web platform's imperative and
 declarative
  duality is, by nature, two-way. Having two methods or an option that
 takes
  multiple input types is not an empirical negative, you may argue it is
 an
  ugly pattern, but that is largely subjective.

 For what it's worth, I totally agree with Anne that two-prong API is a
 huge wart and I feel shame for proposing it. But I would rather feel
 shame than waiting for Godot.

 
  Is this an accurate summary of what we're looking at for possible
 solutions?
  If so, can we at least get a decision on whether or not _this_ route is
  acceptable?
 
  FOO_CONSTRUCTOR = document.register(‘x-foo’, {
prototype: ELEMENT_PROTOTYPE,
lifecycle: {
   created: CALLBACK
}
  });

 I will spec this first.

 
  FOO_CONSTRUCTOR = document.register(‘x-foo’, {
constructor: FOO_CONSTRUCTOR
  });
 

 When we have implementers who can handle it, I'll spec that.

 Eventually, we'll work to deprecate the first approach.

 One thing that Scott suggested recently is that the second API variant
 always returns undefined, to better separate the two APIs and their
 usage patterns.

 :DG





Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-19 Thread Daniel Buchner
What is the harm in returning the same constructor that is being input for
this form of invocation? The output constructor is simply a pass-through of
the input constructor, right?

FOO_CONSTRUCTOR = document.register(‘x-foo’, {
  constructor: FOO_CONSTRUCTOR
});

I guess this isn't a big deal though, I'll certainly defer to you all on
the best course :)

Daniel J. Buchner
Product Manager, Developer Ecosystem
Mozilla Corporation


On Tue, Feb 19, 2013 at 12:51 PM, Scott Miles sjmi...@google.com wrote:

  I'd be a much happier camper if I didn't have to think about handling
 different return values.

 I agree, and If it were up to me, there would be just one API for
 document.register.

 However, the argument given for dividing the API is that it is improper to
 have a function return a value that is only important on some platforms. If
 that's the winning argument, then isn't it pathological to make the 'non
 constructor-returning API' return a constructor?


 On Mon, Feb 18, 2013 at 12:59 PM, Daniel Buchner dan...@mozilla.comwrote:

 I agree with your approach on staging the two specs for this, but the
 last part about returning a constructor in one circumstance and undefined
 in the other is something developers would rather not deal with (in my
 observation). If I'm a downstream consumer or library author who's going to
 wrap this function (or any function for that matter), I'd be a much happier
 camper if I didn't have to think about handling different return values. Is
 there a clear harm in returning a constructor reliably that would make us
 want to diverge from an expected and reliable return value? It seems to me
 that the unexpected return value will be far more annoying than a little
 less mental separation between the two invocation setups.

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Mon, Feb 18, 2013 at 12:47 PM, Dimitri Glazkov dglaz...@google.comwrote:

 On Fri, Feb 15, 2013 at 8:42 AM, Daniel Buchner dan...@mozilla.com
 wrote:
  I'm not sure I buy the idea that two ways of doing the same thing
 does not
  seem like a good approach - the web platform's imperative and
 declarative
  duality is, by nature, two-way. Having two methods or an option that
 takes
  multiple input types is not an empirical negative, you may argue it is
 an
  ugly pattern, but that is largely subjective.

 For what it's worth, I totally agree with Anne that two-prong API is a
 huge wart and I feel shame for proposing it. But I would rather feel
 shame than waiting for Godot.

 
  Is this an accurate summary of what we're looking at for possible
 solutions?
  If so, can we at least get a decision on whether or not _this_ route is
  acceptable?
 
  FOO_CONSTRUCTOR = document.register(‘x-foo’, {
prototype: ELEMENT_PROTOTYPE,
lifecycle: {
   created: CALLBACK
}
  });

 I will spec this first.

 
  FOO_CONSTRUCTOR = document.register(‘x-foo’, {
constructor: FOO_CONSTRUCTOR
  });
 

 When we have implementers who can handle it, I'll spec that.

 Eventually, we'll work to deprecate the first approach.

 One thing that Scott suggested recently is that the second API variant
 always returns undefined, to better separate the two APIs and their
 usage patterns.

 :DG






Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-19 Thread Scott Miles
Question: if I do

FancyHeaderPrototype = Object.create(HTMLElement.prototype);
document.register('fancy-header', {
  prototype: FancyHeaderPrototype
...

In this case, I intend to extend header. I expect my custom elements to
look like header is=fancy-header, but how does the system know what
localName to use? I believe the notion was that the localName would be
inferred from the prototype, but there are various semantic tags that share
prototypes, so it seems ambiguous in these cases.

S


On Tue, Feb 19, 2013 at 1:01 PM, Daniel Buchner dan...@mozilla.com wrote:

 What is the harm in returning the same constructor that is being input for
 this form of invocation? The output constructor is simply a pass-through of
 the input constructor, right?

 FOO_CONSTRUCTOR = document.register(‘x-foo’, {
   constructor: FOO_CONSTRUCTOR
 });

 I guess this isn't a big deal though, I'll certainly defer to you all on
 the best course :)

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Tue, Feb 19, 2013 at 12:51 PM, Scott Miles sjmi...@google.com wrote:

  I'd be a much happier camper if I didn't have to think about handling
 different return values.

 I agree, and If it were up to me, there would be just one API for
 document.register.

 However, the argument given for dividing the API is that it is improper
 to have a function return a value that is only important on some platforms. 
 If
 that's the winning argument, then isn't it pathological to make the 'non
 constructor-returning API' return a constructor?


 On Mon, Feb 18, 2013 at 12:59 PM, Daniel Buchner dan...@mozilla.comwrote:

 I agree with your approach on staging the two specs for this, but the
 last part about returning a constructor in one circumstance and undefined
 in the other is something developers would rather not deal with (in my
 observation). If I'm a downstream consumer or library author who's going to
 wrap this function (or any function for that matter), I'd be a much happier
 camper if I didn't have to think about handling different return values. Is
 there a clear harm in returning a constructor reliably that would make us
 want to diverge from an expected and reliable return value? It seems to me
 that the unexpected return value will be far more annoying than a little
 less mental separation between the two invocation setups.

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Mon, Feb 18, 2013 at 12:47 PM, Dimitri Glazkov 
 dglaz...@google.comwrote:

 On Fri, Feb 15, 2013 at 8:42 AM, Daniel Buchner dan...@mozilla.com
 wrote:
  I'm not sure I buy the idea that two ways of doing the same thing
 does not
  seem like a good approach - the web platform's imperative and
 declarative
  duality is, by nature, two-way. Having two methods or an option that
 takes
  multiple input types is not an empirical negative, you may argue it
 is an
  ugly pattern, but that is largely subjective.

 For what it's worth, I totally agree with Anne that two-prong API is a
 huge wart and I feel shame for proposing it. But I would rather feel
 shame than waiting for Godot.

 
  Is this an accurate summary of what we're looking at for possible
 solutions?
  If so, can we at least get a decision on whether or not _this_ route
 is
  acceptable?
 
  FOO_CONSTRUCTOR = document.register(‘x-foo’, {
prototype: ELEMENT_PROTOTYPE,
lifecycle: {
   created: CALLBACK
}
  });

 I will spec this first.

 
  FOO_CONSTRUCTOR = document.register(‘x-foo’, {
constructor: FOO_CONSTRUCTOR
  });
 

 When we have implementers who can handle it, I'll spec that.

 Eventually, we'll work to deprecate the first approach.

 One thing that Scott suggested recently is that the second API variant
 always returns undefined, to better separate the two APIs and their
 usage patterns.

 :DG







Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-19 Thread Daniel Buchner
Wait a sec, perhaps I've missed something, but in your example you never
extend the actual native header element, was that on purpose? I was under
the impression you still needed to inherit from it in the prototype
creation/registration phase, is that not true?
On Feb 19, 2013 8:26 PM, Scott Miles sjmi...@google.com wrote:

 Question: if I do

 FancyHeaderPrototype = Object.create(HTMLElement.prototype);
 document.register('fancy-header', {
   prototype: FancyHeaderPrototype
 ...

 In this case, I intend to extend header. I expect my custom elements to
 look like header is=fancy-header, but how does the system know what
 localName to use? I believe the notion was that the localName would be
 inferred from the prototype, but there are various semantic tags that share
 prototypes, so it seems ambiguous in these cases.

 S


 On Tue, Feb 19, 2013 at 1:01 PM, Daniel Buchner dan...@mozilla.comwrote:

 What is the harm in returning the same constructor that is being input
 for this form of invocation? The output constructor is simply a
 pass-through of the input constructor, right?

 FOO_CONSTRUCTOR = document.register(‘x-foo’, {
   constructor: FOO_CONSTRUCTOR
 });

 I guess this isn't a big deal though, I'll certainly defer to you all on
 the best course :)

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Tue, Feb 19, 2013 at 12:51 PM, Scott Miles sjmi...@google.com wrote:

  I'd be a much happier camper if I didn't have to think about handling
 different return values.

 I agree, and If it were up to me, there would be just one API for
 document.register.

 However, the argument given for dividing the API is that it is improper
 to have a function return a value that is only important on some platforms. 
 If
 that's the winning argument, then isn't it pathological to make the 'non
 constructor-returning API' return a constructor?


 On Mon, Feb 18, 2013 at 12:59 PM, Daniel Buchner dan...@mozilla.comwrote:

 I agree with your approach on staging the two specs for this, but the
 last part about returning a constructor in one circumstance and undefined
 in the other is something developers would rather not deal with (in my
 observation). If I'm a downstream consumer or library author who's going to
 wrap this function (or any function for that matter), I'd be a much happier
 camper if I didn't have to think about handling different return values. Is
 there a clear harm in returning a constructor reliably that would make us
 want to diverge from an expected and reliable return value? It seems to me
 that the unexpected return value will be far more annoying than a little
 less mental separation between the two invocation setups.

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Mon, Feb 18, 2013 at 12:47 PM, Dimitri Glazkov 
 dglaz...@google.comwrote:

 On Fri, Feb 15, 2013 at 8:42 AM, Daniel Buchner dan...@mozilla.com
 wrote:
  I'm not sure I buy the idea that two ways of doing the same thing
 does not
  seem like a good approach - the web platform's imperative and
 declarative
  duality is, by nature, two-way. Having two methods or an option that
 takes
  multiple input types is not an empirical negative, you may argue it
 is an
  ugly pattern, but that is largely subjective.

 For what it's worth, I totally agree with Anne that two-prong API is a
 huge wart and I feel shame for proposing it. But I would rather feel
 shame than waiting for Godot.

 
  Is this an accurate summary of what we're looking at for possible
 solutions?
  If so, can we at least get a decision on whether or not _this_ route
 is
  acceptable?
 
  FOO_CONSTRUCTOR = document.register(‘x-foo’, {
prototype: ELEMENT_PROTOTYPE,
lifecycle: {
   created: CALLBACK
}
  });

 I will spec this first.

 
  FOO_CONSTRUCTOR = document.register(‘x-foo’, {
constructor: FOO_CONSTRUCTOR
  });
 

 When we have implementers who can handle it, I'll spec that.

 Eventually, we'll work to deprecate the first approach.

 One thing that Scott suggested recently is that the second API variant
 always returns undefined, to better separate the two APIs and their
 usage patterns.

 :DG








Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-19 Thread Scott Miles
Perhaps I'm making a mistake, but there is no specific prototype for the
native header element. 'header', 'footer', 'section', e.g., are all
HTMLElement, so all I can do is

FancyHeaderPrototype = Object.create(HTMLElement.prototype);

Afaict, the 'headerness' cannot be expressed this way.


On Tue, Feb 19, 2013 at 8:34 PM, Daniel Buchner dan...@mozilla.com wrote:

 Wait a sec, perhaps I've missed something, but in your example you never
 extend the actual native header element, was that on purpose? I was under
 the impression you still needed to inherit from it in the prototype
 creation/registration phase, is that not true?
 On Feb 19, 2013 8:26 PM, Scott Miles sjmi...@google.com wrote:

 Question: if I do

 FancyHeaderPrototype = Object.create(HTMLElement.prototype);
 document.register('fancy-header', {
   prototype: FancyHeaderPrototype
 ...

 In this case, I intend to extend header. I expect my custom elements to
 look like header is=fancy-header, but how does the system know what
 localName to use? I believe the notion was that the localName would be
 inferred from the prototype, but there are various semantic tags that share
 prototypes, so it seems ambiguous in these cases.

 S


 On Tue, Feb 19, 2013 at 1:01 PM, Daniel Buchner dan...@mozilla.comwrote:

 What is the harm in returning the same constructor that is being input
 for this form of invocation? The output constructor is simply a
 pass-through of the input constructor, right?

 FOO_CONSTRUCTOR = document.register(‘x-foo’, {
   constructor: FOO_CONSTRUCTOR
 });

 I guess this isn't a big deal though, I'll certainly defer to you all on
 the best course :)

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Tue, Feb 19, 2013 at 12:51 PM, Scott Miles sjmi...@google.comwrote:

  I'd be a much happier camper if I didn't have to think about
 handling different return values.

 I agree, and If it were up to me, there would be just one API for
 document.register.

 However, the argument given for dividing the API is that it is improper
 to have a function return a value that is only important on some 
 platforms. If
 that's the winning argument, then isn't it pathological to make the 'non
 constructor-returning API' return a constructor?


 On Mon, Feb 18, 2013 at 12:59 PM, Daniel Buchner dan...@mozilla.comwrote:

 I agree with your approach on staging the two specs for this, but the
 last part about returning a constructor in one circumstance and undefined
 in the other is something developers would rather not deal with (in my
 observation). If I'm a downstream consumer or library author who's going 
 to
 wrap this function (or any function for that matter), I'd be a much 
 happier
 camper if I didn't have to think about handling different return values. 
 Is
 there a clear harm in returning a constructor reliably that would make us
 want to diverge from an expected and reliable return value? It seems to me
 that the unexpected return value will be far more annoying than a little
 less mental separation between the two invocation setups.

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Mon, Feb 18, 2013 at 12:47 PM, Dimitri Glazkov dglaz...@google.com
  wrote:

 On Fri, Feb 15, 2013 at 8:42 AM, Daniel Buchner dan...@mozilla.com
 wrote:
  I'm not sure I buy the idea that two ways of doing the same thing
 does not
  seem like a good approach - the web platform's imperative and
 declarative
  duality is, by nature, two-way. Having two methods or an option
 that takes
  multiple input types is not an empirical negative, you may argue it
 is an
  ugly pattern, but that is largely subjective.

 For what it's worth, I totally agree with Anne that two-prong API is a
 huge wart and I feel shame for proposing it. But I would rather feel
 shame than waiting for Godot.

 
  Is this an accurate summary of what we're looking at for possible
 solutions?
  If so, can we at least get a decision on whether or not _this_
 route is
  acceptable?
 
  FOO_CONSTRUCTOR = document.register(‘x-foo’, {
prototype: ELEMENT_PROTOTYPE,
lifecycle: {
   created: CALLBACK
}
  });

 I will spec this first.

 
  FOO_CONSTRUCTOR = document.register(‘x-foo’, {
constructor: FOO_CONSTRUCTOR
  });
 

 When we have implementers who can handle it, I'll spec that.

 Eventually, we'll work to deprecate the first approach.

 One thing that Scott suggested recently is that the second API variant
 always returns undefined, to better separate the two APIs and their
 usage patterns.

 :DG








Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-19 Thread Daniel Buchner
Nope, you're 100% right, I saw *header *and thought HTML*Heading*Element
for some reason - so this seems like a valid concern. What are the
mitigation/solution options we can present to developers for this case?


Daniel J. Buchner
Product Manager, Developer Ecosystem
Mozilla Corporation


On Tue, Feb 19, 2013 at 9:17 PM, Scott Miles sjmi...@google.com wrote:

 Perhaps I'm making a mistake, but there is no specific prototype for the
 native header element. 'header', 'footer', 'section', e.g., are all
 HTMLElement, so all I can do is

 FancyHeaderPrototype = Object.create(HTMLElement.prototype);

 Afaict, the 'headerness' cannot be expressed this way.


 On Tue, Feb 19, 2013 at 8:34 PM, Daniel Buchner dan...@mozilla.comwrote:

 Wait a sec, perhaps I've missed something, but in your example you never
 extend the actual native header element, was that on purpose? I was under
 the impression you still needed to inherit from it in the prototype
 creation/registration phase, is that not true?
  On Feb 19, 2013 8:26 PM, Scott Miles sjmi...@google.com wrote:

 Question: if I do

 FancyHeaderPrototype = Object.create(HTMLElement.prototype);
 document.register('fancy-header', {
   prototype: FancyHeaderPrototype
 ...

 In this case, I intend to extend header. I expect my custom elements
 to look like header is=fancy-header, but how does the system know what
 localName to use? I believe the notion was that the localName would be
 inferred from the prototype, but there are various semantic tags that share
 prototypes, so it seems ambiguous in these cases.

 S


 On Tue, Feb 19, 2013 at 1:01 PM, Daniel Buchner dan...@mozilla.comwrote:

 What is the harm in returning the same constructor that is being input
 for this form of invocation? The output constructor is simply a
 pass-through of the input constructor, right?

 FOO_CONSTRUCTOR = document.register(‘x-foo’, {
   constructor: FOO_CONSTRUCTOR
 });

 I guess this isn't a big deal though, I'll certainly defer to you all
 on the best course :)

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Tue, Feb 19, 2013 at 12:51 PM, Scott Miles sjmi...@google.comwrote:

  I'd be a much happier camper if I didn't have to think about
 handling different return values.

 I agree, and If it were up to me, there would be just one API for
 document.register.

 However, the argument given for dividing the API is that it is
 improper to have a function return a value that is only important on some
 platforms. If that's the winning argument, then isn't it pathological
 to make the 'non constructor-returning API' return a constructor?


 On Mon, Feb 18, 2013 at 12:59 PM, Daniel Buchner 
 dan...@mozilla.comwrote:

 I agree with your approach on staging the two specs for this, but the
 last part about returning a constructor in one circumstance and undefined
 in the other is something developers would rather not deal with (in my
 observation). If I'm a downstream consumer or library author who's going 
 to
 wrap this function (or any function for that matter), I'd be a much 
 happier
 camper if I didn't have to think about handling different return values. 
 Is
 there a clear harm in returning a constructor reliably that would make us
 want to diverge from an expected and reliable return value? It seems to 
 me
 that the unexpected return value will be far more annoying than a little
 less mental separation between the two invocation setups.

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Mon, Feb 18, 2013 at 12:47 PM, Dimitri Glazkov 
 dglaz...@google.com wrote:

 On Fri, Feb 15, 2013 at 8:42 AM, Daniel Buchner dan...@mozilla.com
 wrote:
  I'm not sure I buy the idea that two ways of doing the same thing
 does not
  seem like a good approach - the web platform's imperative and
 declarative
  duality is, by nature, two-way. Having two methods or an option
 that takes
  multiple input types is not an empirical negative, you may argue
 it is an
  ugly pattern, but that is largely subjective.

 For what it's worth, I totally agree with Anne that two-prong API is
 a
 huge wart and I feel shame for proposing it. But I would rather feel
 shame than waiting for Godot.

 
  Is this an accurate summary of what we're looking at for possible
 solutions?
  If so, can we at least get a decision on whether or not _this_
 route is
  acceptable?
 
  FOO_CONSTRUCTOR = document.register(‘x-foo’, {
prototype: ELEMENT_PROTOTYPE,
lifecycle: {
   created: CALLBACK
}
  });

 I will spec this first.

 
  FOO_CONSTRUCTOR = document.register(‘x-foo’, {
constructor: FOO_CONSTRUCTOR
  });
 

 When we have implementers who can handle it, I'll spec that.

 Eventually, we'll work to deprecate the first approach.

 One thing that Scott suggested recently is that the second API
 variant
 always returns undefined, to better separate the two APIs and their
 usage patterns.

 :DG









Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-18 Thread Dimitri Glazkov
On Fri, Feb 15, 2013 at 8:42 AM, Daniel Buchner dan...@mozilla.com wrote:
 I'm not sure I buy the idea that two ways of doing the same thing does not
 seem like a good approach - the web platform's imperative and declarative
 duality is, by nature, two-way. Having two methods or an option that takes
 multiple input types is not an empirical negative, you may argue it is an
 ugly pattern, but that is largely subjective.

For what it's worth, I totally agree with Anne that two-prong API is a
huge wart and I feel shame for proposing it. But I would rather feel
shame than waiting for Godot.


 Is this an accurate summary of what we're looking at for possible solutions?
 If so, can we at least get a decision on whether or not _this_ route is
 acceptable?

 FOO_CONSTRUCTOR = document.register(‘x-foo’, {
   prototype: ELEMENT_PROTOTYPE,
   lifecycle: {
  created: CALLBACK
   }
 });

I will spec this first.


 FOO_CONSTRUCTOR = document.register(‘x-foo’, {
   constructor: FOO_CONSTRUCTOR
 });


When we have implementers who can handle it, I'll spec that.

Eventually, we'll work to deprecate the first approach.

One thing that Scott suggested recently is that the second API variant
always returns undefined, to better separate the two APIs and their
usage patterns.

:DG



Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-18 Thread Daniel Buchner
I agree with your approach on staging the two specs for this, but the last
part about returning a constructor in one circumstance and undefined in the
other is something developers would rather not deal with (in my
observation). If I'm a downstream consumer or library author who's going to
wrap this function (or any function for that matter), I'd be a much happier
camper if I didn't have to think about handling different return values. Is
there a clear harm in returning a constructor reliably that would make us
want to diverge from an expected and reliable return value? It seems to me
that the unexpected return value will be far more annoying than a little
less mental separation between the two invocation setups.

Daniel J. Buchner
Product Manager, Developer Ecosystem
Mozilla Corporation


On Mon, Feb 18, 2013 at 12:47 PM, Dimitri Glazkov dglaz...@google.comwrote:

 On Fri, Feb 15, 2013 at 8:42 AM, Daniel Buchner dan...@mozilla.com
 wrote:
  I'm not sure I buy the idea that two ways of doing the same thing does
 not
  seem like a good approach - the web platform's imperative and
 declarative
  duality is, by nature, two-way. Having two methods or an option that
 takes
  multiple input types is not an empirical negative, you may argue it is an
  ugly pattern, but that is largely subjective.

 For what it's worth, I totally agree with Anne that two-prong API is a
 huge wart and I feel shame for proposing it. But I would rather feel
 shame than waiting for Godot.

 
  Is this an accurate summary of what we're looking at for possible
 solutions?
  If so, can we at least get a decision on whether or not _this_ route is
  acceptable?
 
  FOO_CONSTRUCTOR = document.register(‘x-foo’, {
prototype: ELEMENT_PROTOTYPE,
lifecycle: {
   created: CALLBACK
}
  });

 I will spec this first.

 
  FOO_CONSTRUCTOR = document.register(‘x-foo’, {
constructor: FOO_CONSTRUCTOR
  });
 

 When we have implementers who can handle it, I'll spec that.

 Eventually, we'll work to deprecate the first approach.

 One thing that Scott suggested recently is that the second API variant
 always returns undefined, to better separate the two APIs and their
 usage patterns.

 :DG



Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-15 Thread Anne van Kesteren
On Thu, Feb 14, 2013 at 9:48 PM, Dimitri Glazkov dglaz...@google.com wrote:
 What do you think?

It seems like this still requires magic for document.createElement()
and document.createElementNS().

Also, providing two ways of doing the same thing does not seem like a
good approach to standardization and will come to haunt us in the
future (in terms of maintenance, QA, new extensions to the platform,
etc.).


-- 
http://annevankesteren.nl/



Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-15 Thread Daniel Buchner
I'm not sure I buy the idea that two ways of doing the same thing does not
seem like a good approach - the web platform's imperative and declarative
duality is, by nature, two-way. Having two methods or an option that takes
multiple input types is not an empirical negative, you may argue it is an
ugly pattern, but that is largely subjective.

Is this an accurate summary of what we're looking at for possible
solutions? If so, can we at least get a decision on whether or not _this_
route is acceptable?

FOO_CONSTRUCTOR = document.register(‘x-foo’, {
  prototype: ELEMENT_PROTOTYPE,
  lifecycle: {
 created: CALLBACK
  }
});

FOO_CONSTRUCTOR = document.register(‘x-foo’, {
  constructor: FOO_CONSTRUCTOR
});





Daniel J. Buchner
Product Manager, Developer Ecosystem
Mozilla Corporation


On Fri, Feb 15, 2013 at 6:19 AM, Anne van Kesteren ann...@annevk.nl wrote:

 On Thu, Feb 14, 2013 at 9:48 PM, Dimitri Glazkov dglaz...@google.com
 wrote:
  What do you think?

 It seems like this still requires magic for document.createElement()
 and document.createElementNS().

 Also, providing two ways of doing the same thing does not seem like a
 good approach to standardization and will come to haunt us in the
 future (in terms of maintenance, QA, new extensions to the platform,
 etc.).


 --
 http://annevankesteren.nl/



Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-14 Thread Dimitri Glazkov
Folks,

I propose just a bit of sugaring as a compromise, but I want to make
sure this is really sugar and not acid, so please chime in.

1) We give up on unified syntax for ES5 and ES6, and instead focus on
unified plumbing
2) document.register returns a custom element constructor as a result,
just like currently specified:
https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn-document-register
3) There are two ways to register an element: with a constructor and
with a prototype object.
4) When registering with the constructor (aka the ES6 way), you must
supply the constructor/class as the constructor member in the
ElementRegistrationOptions dictionary
(https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#api-element-registration-options)
5) If the constructor is supplied, element registration overrides
[[Construct]] internal function as described in
http://lists.w3.org/Archives/Public/public-webapps/2013JanMar/0250.html
6) Registering with a prototype object (aka the current way) uses the
prototype member in ElementRegistrationOptions dictionary and works
roughly as currently specified
7) If the prototype object is supplied, the constructor is generated
as two steps:
  a) Instantiate the platform object
  b) Call created callback from lifecycle callback interface bound to this
8) We remove any sort of shadow tree creation and the corresponding
template argument from the spec. Shadow tree management is left
completely up to the author.

Effectively, the created callback becomes the poor man's
constructor. It's very easy to convert from old syntax to new syntax:

The prototype way:

function MyButton() {
  // do constructor stuff ...
}
MyButton.prototype = Object.create(HTMLButtonElement.prototype, {
 ...
});
MyButton = document.register(‘x-button’, {
  prototype: MyButton.prototype,
  lifecycle: {
 created: MyButton
  }
});

The constructor way:

function MyButton() {
 // do constructor stuff ...
}
MyButton.prototype = Object.create(HTMLButtonElement.prototype, {
 ...
});
document.register(‘x-button’, {
 constructor: MyButton,
 ...
});

This is nearly the same approach as what  Scott sketched out here:
http://jsfiddle.net/aNHZH/7/, so we already know it's shimmable :)

What do you think?

:DG



Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-14 Thread Rick Waldron
On Thu, Feb 14, 2013 at 4:48 PM, Dimitri Glazkov dglaz...@google.comwrote:

 Folks,

 I propose just a bit of sugaring as a compromise, but I want to make
 sure this is really sugar and not acid, so please chime in.

 1) We give up on unified syntax for ES5 and ES6, and instead focus on
 unified plumbing
 2) document.register returns a custom element constructor as a result,
 just like currently specified:

 https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn-document-register
 3) There are two ways to register an element: with a constructor and
 with a prototype object.
 4) When registering with the constructor (aka the ES6 way), you must
 supply the constructor/class as the constructor member in the
 ElementRegistrationOptions dictionary
 (
 https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#api-element-registration-options
 )
 5) If the constructor is supplied, element registration overrides
 [[Construct]] internal function as described in
 http://lists.w3.org/Archives/Public/public-webapps/2013JanMar/0250.html
 6) Registering with a prototype object (aka the current way) uses the
 prototype member in ElementRegistrationOptions dictionary and works
 roughly as currently specified


See Q's below...


 7) If the prototype object is supplied, the constructor is generated
 as two steps:
   a) Instantiate the platform object
   b) Call created callback from lifecycle callback interface bound to
 this
 8) We remove any sort of shadow tree creation and the corresponding
 template argument from the spec. Shadow tree management is left
 completely up to the author.

 Effectively, the created callback becomes the poor man's
 constructor. It's very easy to convert from old syntax to new syntax:

 The prototype way:

 function MyButton() {
   // do constructor stuff ...
 }
 MyButton.prototype = Object.create(HTMLButtonElement.prototype, {
  ...
 });
 MyButton = document.register(‘x-button’, {
   prototype: MyButton.prototype,
   lifecycle: {
  created: MyButton
   }
 });



Does this actually mean that the second argument has a property called
prototype that itself has a special meaning?

Is the re-assignment MyButton intentional? I see the original MyButton
reference as the value of the created property, but then
document.register's return value is assigned to the same identifier? Maybe
this was a typo?




 The constructor way:

 function MyButton() {
  // do constructor stuff ...
 }
 MyButton.prototype = Object.create(HTMLButtonElement.prototype, {
  ...
 });
 document.register(‘x-button’, {
  constructor: MyButton,
  ...
 });


Same question as above, but re: constructor?


When I first read this, I was expecting to see something about syntax, this
is all API.


Rick




 This is nearly the same approach as what  Scott sketched out here:
 http://jsfiddle.net/aNHZH/7/, so we already know it's shimmable :)

 What do you think?

 :DG




Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-14 Thread Daniel Buchner
I love it, gives the developer control over the addition of sugar (just a
spoonful of...) and code preference, while at the same time addressing our
requirement set. Ship it!

Daniel J. Buchner
Product Manager, Developer Ecosystem
Mozilla Corporation


On Thu, Feb 14, 2013 at 1:48 PM, Dimitri Glazkov dglaz...@google.comwrote:

 Folks,

 I propose just a bit of sugaring as a compromise, but I want to make
 sure this is really sugar and not acid, so please chime in.

 1) We give up on unified syntax for ES5 and ES6, and instead focus on
 unified plumbing
 2) document.register returns a custom element constructor as a result,
 just like currently specified:

 https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn-document-register
 3) There are two ways to register an element: with a constructor and
 with a prototype object.
 4) When registering with the constructor (aka the ES6 way), you must
 supply the constructor/class as the constructor member in the
 ElementRegistrationOptions dictionary
 (
 https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#api-element-registration-options
 )
 5) If the constructor is supplied, element registration overrides
 [[Construct]] internal function as described in
 http://lists.w3.org/Archives/Public/public-webapps/2013JanMar/0250.html
 6) Registering with a prototype object (aka the current way) uses the
 prototype member in ElementRegistrationOptions dictionary and works
 roughly as currently specified
 7) If the prototype object is supplied, the constructor is generated
 as two steps:
   a) Instantiate the platform object
   b) Call created callback from lifecycle callback interface bound to
 this
 8) We remove any sort of shadow tree creation and the corresponding
 template argument from the spec. Shadow tree management is left
 completely up to the author.

 Effectively, the created callback becomes the poor man's
 constructor. It's very easy to convert from old syntax to new syntax:

 The prototype way:

 function MyButton() {
   // do constructor stuff ...
 }
 MyButton.prototype = Object.create(HTMLButtonElement.prototype, {
  ...
 });
 MyButton = document.register(‘x-button’, {
   prototype: MyButton.prototype,
   lifecycle: {
  created: MyButton
   }
 });

 The constructor way:

 function MyButton() {
  // do constructor stuff ...
 }
 MyButton.prototype = Object.create(HTMLButtonElement.prototype, {
  ...
 });
 document.register(‘x-button’, {
  constructor: MyButton,
  ...
 });

 This is nearly the same approach as what  Scott sketched out here:
 http://jsfiddle.net/aNHZH/7/, so we already know it's shimmable :)

 What do you think?

 :DG



Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-14 Thread Erik Arvidsson
Yeah, this post does not really talk about syntax. It comes after a
discussion how we could use ES6 class syntax.

The ES6 classes have the same semantics as provided in this thread using
ES5.

On Thu, Feb 14, 2013 at 5:10 PM, Rick Waldron waldron.r...@gmail.comwrote:


 On Thu, Feb 14, 2013 at 4:48 PM, Dimitri Glazkov dglaz...@google.comwrote:


 MyButton = document.register(‘x-button’, {
   prototype: MyButton.prototype,
   lifecycle: {
  created: MyButton
   }
 });



 Does this actually mean that the second argument has a property called
 prototype that itself has a special meaning?


This is just a dictionary.



 Is the re-assignment MyButton intentional? I see the original MyButton
 reference as the value of the created property, but then
 document.register's return value is assigned to the same identifier? Maybe
 this was a typo?


 document.register(‘x-button’, {
  constructor: MyButton,
  ...
 });


 Same question as above, but re: constructor?


Same answer here.

I'm not happy with these names but I can't think of anything better.

-- 
erik


Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-14 Thread Rick Waldron
On Thu, Feb 14, 2013 at 5:15 PM, Erik Arvidsson a...@chromium.org wrote:

 Yeah, this post does not really talk about syntax. It comes after a
 discussion how we could use ES6 class syntax.

 The ES6 classes have the same semantics as provided in this thread using
 ES5.

 On Thu, Feb 14, 2013 at 5:10 PM, Rick Waldron waldron.r...@gmail.comwrote:


 On Thu, Feb 14, 2013 at 4:48 PM, Dimitri Glazkov dglaz...@google.comwrote:


 MyButton = document.register(‘x-button’, {
   prototype: MyButton.prototype,
   lifecycle: {
  created: MyButton
   }
 });



 Does this actually mean that the second argument has a property called
 prototype that itself has a special meaning?


 This is just a dictionary.



 Is the re-assignment MyButton intentional? I see the original MyButton
 reference as the value of the created property, but then
 document.register's return value is assigned to the same identifier? Maybe
 this was a typo?


 document.register(‘x-button’, {
  constructor: MyButton,
  ...
 });


 Same question as above, but re: constructor?


 Same answer here.

 I'm not happy with these names but I can't think of anything better.


Fair enough, I trust your judgement here. Thanks for the follow up—always
appreciated.

Rick


 --
 erik




Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-14 Thread Scott Miles
MyButton = document.register(‘x-button’, {
  prototype: MyButton.prototype,
  lifecycle: {
 created: MyButton
  }
});

What's the benefit of allowing this syntax? I don't immediately see why you
couldn't just do it the other way.


On Thu, Feb 14, 2013 at 2:21 PM, Rick Waldron waldron.r...@gmail.comwrote:




 On Thu, Feb 14, 2013 at 5:15 PM, Erik Arvidsson a...@chromium.org wrote:

 Yeah, this post does not really talk about syntax. It comes after a
 discussion how we could use ES6 class syntax.

 The ES6 classes have the same semantics as provided in this thread using
 ES5.

 On Thu, Feb 14, 2013 at 5:10 PM, Rick Waldron waldron.r...@gmail.comwrote:


 On Thu, Feb 14, 2013 at 4:48 PM, Dimitri Glazkov dglaz...@google.comwrote:


 MyButton = document.register(‘x-button’, {
   prototype: MyButton.prototype,
   lifecycle: {
  created: MyButton
   }
 });



 Does this actually mean that the second argument has a property called
 prototype that itself has a special meaning?


 This is just a dictionary.



 Is the re-assignment MyButton intentional? I see the original MyButton
 reference as the value of the created property, but then
 document.register's return value is assigned to the same identifier? Maybe
 this was a typo?


 document.register(‘x-button’, {
  constructor: MyButton,
  ...
 });


 Same question as above, but re: constructor?


 Same answer here.

 I'm not happy with these names but I can't think of anything better.


 Fair enough, I trust your judgement here. Thanks for the follow up—always
 appreciated.

 Rick


 --
 erik





Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-14 Thread Daniel Buchner
It seems to me (please correct me if this is inaccurate) that you can't *
really* polyfill ES6 extension of existing element constructor inheritance,
because afaik, you cannot call the existing native constructors of elements
- it throws. So if you can only do a jankified 1/2 fill, why not just
provide an optional route that has no legacy issues for people who want to
use it?

I believe even Scott's polyfill doesn't do anything to enable
HTMLButtonElement.call(this);

Hopefully I'm in the ballpark here, but if what I said is wrong or not an
issue, what *is* the reasoning behind it?

Daniel J. Buchner
Product Manager, Developer Ecosystem
Mozilla Corporation


On Thu, Feb 14, 2013 at 2:23 PM, Scott Miles sjmi...@google.com wrote:

 MyButton = document.register(‘x-button’, {
   prototype: MyButton.prototype,
   lifecycle: {
  created: MyButton
   }
 });

 What's the benefit of allowing this syntax? I don't immediately see why
 you couldn't just do it the other way.


 On Thu, Feb 14, 2013 at 2:21 PM, Rick Waldron waldron.r...@gmail.comwrote:




 On Thu, Feb 14, 2013 at 5:15 PM, Erik Arvidsson a...@chromium.org wrote:

 Yeah, this post does not really talk about syntax. It comes after a
 discussion how we could use ES6 class syntax.

 The ES6 classes have the same semantics as provided in this thread using
 ES5.

 On Thu, Feb 14, 2013 at 5:10 PM, Rick Waldron waldron.r...@gmail.comwrote:


 On Thu, Feb 14, 2013 at 4:48 PM, Dimitri Glazkov 
 dglaz...@google.comwrote:


 MyButton = document.register(‘x-button’, {
   prototype: MyButton.prototype,
   lifecycle: {
  created: MyButton
   }
 });



 Does this actually mean that the second argument has a property called
 prototype that itself has a special meaning?


 This is just a dictionary.



 Is the re-assignment MyButton intentional? I see the original
 MyButton reference as the value of the created property, but then
 document.register's return value is assigned to the same identifier? Maybe
 this was a typo?


 document.register(‘x-button’, {
  constructor: MyButton,
  ...
 });


 Same question as above, but re: constructor?


 Same answer here.

 I'm not happy with these names but I can't think of anything better.


 Fair enough, I trust your judgement here. Thanks for the follow up—always
 appreciated.

 Rick


 --
 erik






Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-14 Thread Erik Arvidsson
On Thu, Feb 14, 2013 at 5:40 PM, Scott Miles sjmi...@google.com wrote:

 In all constructions the *actual* calling of HTMLButtonElement is done by
 the browser.

 All the user has to do is *not* call it, and only call super constructors
 if they are custom.

 For that reason, I don't see why this is an issue.


Or if you want you can polyfill HTMLButtonElement.call.

HTMLButtonElement.call = function() {};

On Thu, Feb 14, 2013 at 2:36 PM, Daniel Buchner dan...@mozilla.com wrote:

 It seems to me (please correct me if this is inaccurate) that you can't *
 really* polyfill ES6 extension of existing element constructor
 inheritance, because afaik, you cannot call the existing native
 constructors of elements - it throws. So if you can only do a jankified 1/2
 fill, why not just provide an optional route that has no legacy issues for
 people who want to use it?

 I believe even Scott's polyfill doesn't do anything to enable
 HTMLButtonElement.call(this);

 Hopefully I'm in the ballpark here, but if what I said is wrong or not an
 issue, what *is* the reasoning behind it?

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Thu, Feb 14, 2013 at 2:23 PM, Scott Miles sjmi...@google.com wrote:

 MyButton = document.register(‘x-button’, {
   prototype: MyButton.prototype,
   lifecycle: {
  created: MyButton
   }
 });

 What's the benefit of allowing this syntax? I don't immediately see why
 you couldn't just do it the other way.


 On Thu, Feb 14, 2013 at 2:21 PM, Rick Waldron waldron.r...@gmail.comwrote:




 On Thu, Feb 14, 2013 at 5:15 PM, Erik Arvidsson a...@chromium.orgwrote:

 Yeah, this post does not really talk about syntax. It comes after a
 discussion how we could use ES6 class syntax.

 The ES6 classes have the same semantics as provided in this thread
 using ES5.

 On Thu, Feb 14, 2013 at 5:10 PM, Rick Waldron 
 waldron.r...@gmail.comwrote:


 On Thu, Feb 14, 2013 at 4:48 PM, Dimitri Glazkov dglaz...@google.com
  wrote:


 MyButton = document.register(‘x-button’, {
   prototype: MyButton.prototype,
   lifecycle: {
  created: MyButton
   }
 });



 Does this actually mean that the second argument has a property
 called prototype that itself has a special meaning?


 This is just a dictionary.



 Is the re-assignment MyButton intentional? I see the original
 MyButton reference as the value of the created property, but then
 document.register's return value is assigned to the same identifier? 
 Maybe
 this was a typo?


 document.register(‘x-button’, {
  constructor: MyButton,
  ...
 });


 Same question as above, but re: constructor?


 Same answer here.

 I'm not happy with these names but I can't think of anything better.


 Fair enough, I trust your judgement here. Thanks for the follow
 up—always appreciated.

 Rick


 --
 erik








-- 
erik


Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-14 Thread Dimitri Glazkov
On Thu, Feb 14, 2013 at 2:40 PM, Scott Miles sjmi...@google.com wrote:
 In all constructions the *actual* calling of HTMLButtonElement is done by
 the browser.

No, this is not correct. It's the exact opposite :)

In this compromise proposal, the browser isn't calling any of the
constructors. Arv pointed out that since the invention of [[Create]]
override, we don't really need them anyway -- they never do anything
useful for existing HTML elements.

For your custom elements, I can totally see your library/framework
having a convention of calling the super constructor.

I did confuse matters but not putting in the invocation of the
HTMLButtonElement.call.

:DG



Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-14 Thread Scott Miles
Developer cannot call HTMLButtonElement. So whatever work it represents
that MUST be done by the browser.

Perhaps the browser doesn't call that exact function, but in any event,
neither does any user code.

Note that we are specifically taking about built ins, not custom
constructors.

S


On Thu, Feb 14, 2013 at 2:45 PM, Dimitri Glazkov dglaz...@google.comwrote:

 On Thu, Feb 14, 2013 at 2:40 PM, Scott Miles sjmi...@google.com wrote:
  In all constructions the *actual* calling of HTMLButtonElement is done by
  the browser.

 No, this is not correct. It's the exact opposite :)

 In this compromise proposal, the browser isn't calling any of the
 constructors. Arv pointed out that since the invention of [[Create]]
 override, we don't really need them anyway -- they never do anything
 useful for existing HTML elements.

 For your custom elements, I can totally see your library/framework
 having a convention of calling the super constructor.

 I did confuse matters but not putting in the invocation of the
 HTMLButtonElement.call.

 :DG



Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-14 Thread Dimitri Glazkov
On Thu, Feb 14, 2013 at 2:23 PM, Scott Miles sjmi...@google.com wrote:
 MyButton = document.register(‘x-button’, {
   prototype: MyButton.prototype,
   lifecycle: {
  created: MyButton
   }
 });

 What's the benefit of allowing this syntax? I don't immediately see why you
 couldn't just do it the other way.

Daniel answered the direct question, I think, but let me see if I
understand the question hiding behind your question :)

Why can't we just have one API, since these two are so close already?
In other words, can we not just use constructor API and return a
generated constructor?

Do I get a cookie? :)

:DG



Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-14 Thread Scott Miles
On Thu, Feb 14, 2013 at 2:48 PM, Dimitri Glazkov dglaz...@google.comwrote:

 On Thu, Feb 14, 2013 at 2:23 PM, Scott Miles sjmi...@google.com wrote:
  MyButton = document.register(‘x-button’, {
prototype: MyButton.prototype,
lifecycle: {
   created: MyButton
}
  });
 
  What's the benefit of allowing this syntax? I don't immediately see why
 you
  couldn't just do it the other way.

 Daniel answered the direct question, I think,


I must have missed that.


 but let me see if I
 understand the question hiding behind your question :)

 Why can't we just have one API, since these two are so close already?
 In other words, can we not just use constructor API and return a
 generated constructor?

 Do I get a cookie? :)

 :DG


Well, yes, here ya go: (o). But I must be missing something. You wouldn't
propose two APIs if they were equivalent, and I don't see how these are not
(in any meaningful way).


Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-14 Thread Daniel Buchner
Ok, I'll take your word that we get basically 1:1 and devs won't need to
recode or do any catch-casing inside constructors or protos for non-native
document.register polyfill use.

Regardless, if we are going to keep the property bag, which provides way
more than just the prototype property, it seems to me that...

document.register('x-super-button', {
constructor: SuperButton,
lifecycle: { ... }
});

...would still be the most concise, ergonomic syntax. Truth is, devs like
property bags. Major JS frameworks commonly use the property object pattern
for the description of new components and modules. Additionally, retaining
the property bag provides freedom to add other registration-centric
options/features at a later date - unlike 20/20 localName check hindsight,
we can *start* by retaining this flexibility now, so that hindsight does
not become not 20/13 ;)

Daniel J. Buchner
Product Manager, Developer Ecosystem
Mozilla Corporation


On Thu, Feb 14, 2013 at 2:41 PM, Erik Arvidsson a...@chromium.org wrote:


 On Thu, Feb 14, 2013 at 5:40 PM, Scott Miles sjmi...@google.com wrote:

 In all constructions the *actual* calling of HTMLButtonElement is done by
 the browser.

 All the user has to do is *not* call it, and only call super constructors
 if they are custom.

 For that reason, I don't see why this is an issue.


 Or if you want you can polyfill HTMLButtonElement.call.

 HTMLButtonElement.call = function() {};

 On Thu, Feb 14, 2013 at 2:36 PM, Daniel Buchner dan...@mozilla.comwrote:

 It seems to me (please correct me if this is inaccurate) that you can't
 *really* polyfill ES6 extension of existing element constructor
 inheritance, because afaik, you cannot call the existing native
 constructors of elements - it throws. So if you can only do a jankified 1/2
 fill, why not just provide an optional route that has no legacy issues for
 people who want to use it?

 I believe even Scott's polyfill doesn't do anything to enable
 HTMLButtonElement.call(this);

 Hopefully I'm in the ballpark here, but if what I said is wrong or not
 an issue, what *is* the reasoning behind it?

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Thu, Feb 14, 2013 at 2:23 PM, Scott Miles sjmi...@google.com wrote:

 MyButton = document.register(‘x-button’, {
   prototype: MyButton.prototype,
   lifecycle: {
  created: MyButton
   }
 });

 What's the benefit of allowing this syntax? I don't immediately see why
 you couldn't just do it the other way.


 On Thu, Feb 14, 2013 at 2:21 PM, Rick Waldron 
 waldron.r...@gmail.comwrote:




 On Thu, Feb 14, 2013 at 5:15 PM, Erik Arvidsson a...@chromium.orgwrote:

 Yeah, this post does not really talk about syntax. It comes after a
 discussion how we could use ES6 class syntax.

 The ES6 classes have the same semantics as provided in this thread
 using ES5.

 On Thu, Feb 14, 2013 at 5:10 PM, Rick Waldron waldron.r...@gmail.com
  wrote:


 On Thu, Feb 14, 2013 at 4:48 PM, Dimitri Glazkov 
 dglaz...@google.com wrote:


 MyButton = document.register(‘x-button’, {
   prototype: MyButton.prototype,
   lifecycle: {
  created: MyButton
   }
 });



 Does this actually mean that the second argument has a property
 called prototype that itself has a special meaning?


 This is just a dictionary.



 Is the re-assignment MyButton intentional? I see the original
 MyButton reference as the value of the created property, but then
 document.register's return value is assigned to the same identifier? 
 Maybe
 this was a typo?


 document.register(‘x-button’, {
  constructor: MyButton,
  ...
 });


 Same question as above, but re: constructor?


 Same answer here.

 I'm not happy with these names but I can't think of anything better.


 Fair enough, I trust your judgement here. Thanks for the follow
 up—always appreciated.

 Rick


 --
 erik








 --
 erik





Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-14 Thread Dimitri Glazkov
On Thu, Feb 14, 2013 at 2:47 PM, Scott Miles sjmi...@google.com wrote:
 Developer cannot call HTMLButtonElement. So whatever work it represents that
 MUST be done by the browser.

Right. I think we're agreeing, but using different words. An instance
of an HTMLButtonElement-derived element consists of two steps:

1) Instantiate a platform object (that's where the C++ object's
constructor is called)
2) Create a corresponding JS object (that's where the JS object's
constructor is called)

Most of the time, these happen one right after another, except when
the renderer is parsing HTML. The parser can't stop and let user code
run at any given time (again, a design limitation we have to live with
for a while). So we have to split these steps to happen at different
times:

a) The C++ step happens as the parser builds the tree
2) The JS step happens as a microtask after tree's been built.

Since these are two separate steps, I technically don't _need_ to put
HTMLButtonElement.call(this) into my element's constructor -- it's a
sure bet it will just be a useless dummy.

This is sad, because the next questions you'll ask will be:

Dimitri, but what if we built DOM in JS? How would this work then?
Wouldn't platform object be just a JS object? Why the heck would we
need this two-step split?

I don't have good answers. One of them is that we teach developers to
always put dummy HTMLButtonElement.call(this) lines into their element
constructors and future-proof the world like that.

:DG



Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-14 Thread Daniel Buchner
The polyfill rabbit hole of half-hearted, faux-ES6 polyfilling of
constructor inheritance seems to be far deeper than both conceptually in
code-level affect than our simple examples show. Further, what is so sexy
about forcing the pattern when we can't, hard stop, no-way, polyfill *class
*and *extends*?

In my mind, you gain widespread adoption of this if the legacy case is
super streamlined - if you tell developers:

Because we forced a constructor pattern, albeit without truly being able
to use class and extends, we hunted and pecked around the DOM and monkey
patched a bunch of things so you can construct one-off, weak sauce variants
of inherited constructors...just to use with this one method...oh, and
don't try to really use ES6 stuff, because we're just faking a small part
of it.

That sounds kinda gross IMO.

Daniel J. Buchner
Product Manager, Developer Ecosystem
Mozilla Corporation


On Thu, Feb 14, 2013 at 2:53 PM, Scott Miles sjmi...@google.com wrote:




 On Thu, Feb 14, 2013 at 2:48 PM, Dimitri Glazkov dglaz...@google.comwrote:

 On Thu, Feb 14, 2013 at 2:23 PM, Scott Miles sjmi...@google.com wrote:
  MyButton = document.register(‘x-button’, {
prototype: MyButton.prototype,
lifecycle: {
   created: MyButton
}
  });
 
  What's the benefit of allowing this syntax? I don't immediately see why
 you
  couldn't just do it the other way.

 Daniel answered the direct question, I think,


 I must have missed that.


 but let me see if I
 understand the question hiding behind your question :)

 Why can't we just have one API, since these two are so close already?
 In other words, can we not just use constructor API and return a
 generated constructor?

 Do I get a cookie? :)

 :DG


 Well, yes, here ya go: (o). But I must be missing something. You wouldn't
 propose two APIs if they were equivalent, and I don't see how these are not
 (in any meaningful way).



Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-14 Thread Dimitri Glazkov
On Thu, Feb 14, 2013 at 2:53 PM, Scott Miles sjmi...@google.com wrote:

 Well, yes, here ya go: (o). But I must be missing something. You wouldn't
 propose two APIs if they were equivalent, and I don't see how these are not
 (in any meaningful way).

The only difference is that one spits out a generated constructor, and
the other just returns a constructor unmodified (well, not in a
detectable way). My thinking was that if we have both be one and the
same API, we would have:

1) problems writing specification in an interoperable way (if you can
override [[Construct]] function, then do this...)

2) problems with authors seeing different effects of the API on each
browser (in Webcko, I get the same object as I passed in, maybe I
don't need the return value, oh wait, why does it fail in Gekit?)

Am I worrying about this too much?

:DG



Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-14 Thread Scott Miles
Ok. Since you showed both returning constructors, I just assumed in both
cases the returned constructor would be different, if required by platform.

I guess my attitude is to say always write it like this MyThing =
document.register(...), because depending on your runtime scenario it may
return a different method.

Yes, it's not ideal, but then there is only one way to write it.


On Thu, Feb 14, 2013 at 3:16 PM, Dimitri Glazkov dglaz...@google.comwrote:

 On Thu, Feb 14, 2013 at 2:53 PM, Scott Miles sjmi...@google.com wrote:

  Well, yes, here ya go: (o). But I must be missing something. You wouldn't
  propose two APIs if they were equivalent, and I don't see how these are
 not
  (in any meaningful way).

 The only difference is that one spits out a generated constructor, and
 the other just returns a constructor unmodified (well, not in a
 detectable way). My thinking was that if we have both be one and the
 same API, we would have:

 1) problems writing specification in an interoperable way (if you can
 override [[Construct]] function, then do this...)

 2) problems with authors seeing different effects of the API on each
 browser (in Webcko, I get the same object as I passed in, maybe I
 don't need the return value, oh wait, why does it fail in Gekit?)

 Am I worrying about this too much?

 :DG



Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-14 Thread Daniel Buchner
No, I believe this is *precisely *the thing to worry about - these nits and
catch-case gotchas are the sort of things developers see in an emerging
API/polyfill and say awe, that looks like an fractured, uncertain hassle,
I'll just wait until it is native in all browsers -- we must avoid this
at all cost, the web needs this *now*.

Daniel J. Buchner
Product Manager, Developer Ecosystem
Mozilla Corporation


On Thu, Feb 14, 2013 at 3:16 PM, Dimitri Glazkov dglaz...@google.comwrote:

 On Thu, Feb 14, 2013 at 2:53 PM, Scott Miles sjmi...@google.com wrote:

  Well, yes, here ya go: (o). But I must be missing something. You wouldn't
  propose two APIs if they were equivalent, and I don't see how these are
 not
  (in any meaningful way).

 The only difference is that one spits out a generated constructor, and
 the other just returns a constructor unmodified (well, not in a
 detectable way). My thinking was that if we have both be one and the
 same API, we would have:

 1) problems writing specification in an interoperable way (if you can
 override [[Construct]] function, then do this...)

 2) problems with authors seeing different effects of the API on each
 browser (in Webcko, I get the same object as I passed in, maybe I
 don't need the return value, oh wait, why does it fail in Gekit?)

 Am I worrying about this too much?

 :DG



Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-14 Thread Scott Miles
Is saying just do this and it will always work not good enough?

That part I'm not getting.


On Thu, Feb 14, 2013 at 3:30 PM, Daniel Buchner dan...@mozilla.com wrote:

 No, I believe this is *precisely *the thing to worry about - these nits
 and catch-case gotchas are the sort of things developers see in an emerging
 API/polyfill and say awe, that looks like an fractured, uncertain hassle,
 I'll just wait until it is native in all browsers -- we must avoid this
 at all cost, the web needs this *now*.

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Thu, Feb 14, 2013 at 3:16 PM, Dimitri Glazkov dglaz...@google.comwrote:

 On Thu, Feb 14, 2013 at 2:53 PM, Scott Miles sjmi...@google.com wrote:

  Well, yes, here ya go: (o). But I must be missing something. You
 wouldn't
  propose two APIs if they were equivalent, and I don't see how these are
 not
  (in any meaningful way).

 The only difference is that one spits out a generated constructor, and
 the other just returns a constructor unmodified (well, not in a
 detectable way). My thinking was that if we have both be one and the
 same API, we would have:

 1) problems writing specification in an interoperable way (if you can
 override [[Construct]] function, then do this...)

 2) problems with authors seeing different effects of the API on each
 browser (in Webcko, I get the same object as I passed in, maybe I
 don't need the return value, oh wait, why does it fail in Gekit?)

 Am I worrying about this too much?

 :DG





Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-14 Thread Boris Zbarsky

On 2/14/13 6:03 PM, Dimitri Glazkov wrote:

Since these are two separate steps, I technically don't _need_ to put
HTMLButtonElement.call(this) into my element's constructor -- it's a
sure bet it will just be a useless dummy.


For HTMLButtonElement, perhaps.  But for HTMLImageElement that's less clear.

-Boris



Re: Custom elements ES6/ES5 syntax compromise, was: document.register and ES6

2013-02-14 Thread Daniel Buchner
What does it actually profit us to singularly tie document.register to
require an ES6-esque syntax before it lands anyway? No one is saying not to
use it *when it arrives*, we're offering a way to make sure the polyfill
layer isn't needlessly bound to inconsequential externalities.

Hell, if you wanted a single API, call the property descriptor (or
something else that's general) and have it take both by checking what kind
of object the value is... ***ducks***
On Feb 14, 2013 5:14 PM, Boris Zbarsky bzbar...@mit.edu wrote:

 On 2/14/13 6:03 PM, Dimitri Glazkov wrote:

 Since these are two separate steps, I technically don't _need_ to put
 HTMLButtonElement.call(this) into my element's constructor -- it's a
 sure bet it will just be a useless dummy.


 For HTMLButtonElement, perhaps.  But for HTMLImageElement that's less
 clear.

 -Boris



Re: document.register and ES6

2013-02-12 Thread Dimitri Glazkov
On Mon, Feb 11, 2013 at 8:40 PM, Boris Zbarsky bzbar...@mit.edu wrote:

 On 2/7/13 6:15 PM, Dimitri Glazkov wrote:

 1) Expose the ability to override [[Construct]]. Arv tells me that he
 spoke with V8 peeps and they think they can do this fairly easily. How's
 the SpiderMonkey story looking here?


 Requires major surgery on how functions are implemented; not likely in the
 foreseeable future.


Yikes.


Re: document.register and ES6

2013-02-11 Thread Boris Zbarsky

On 2/7/13 6:15 PM, Dimitri Glazkov wrote:

1) Expose the ability to override [[Construct]]. Arv tells me that he
spoke with V8 peeps and they think they can do this fairly easily. How's
the SpiderMonkey story looking here?


Requires major surgery on how functions are implemented; not likely in 
the foreseeable future.


-Boris



Re: document.register and ES6

2013-02-08 Thread Erik Arvidsson
On Thu, Feb 7, 2013 at 11:51 PM, Scott Miles sjmi...@google.com wrote:

 P.P.S. Arv, do you have a preference from my three versions (or none of the
 above)?

I prefer number 2. This is what we want for ES6 anyway. Both 1 and 3
makes me have to repeat myself.

-- 
erik



Re: document.register and ES6

2013-02-08 Thread Scott Miles
The idea is supposed to be that 1 and 3 are only stopgaps until we get
'what we want'. In the future when you can derive a DOM element directly,
both bits of extra code can fall away. Was that clear? Does it change
anything in your mind?

If we go with 2, I believe it means nobody will ever use a custom element
without having to load a helper library first to make the nasty syntax go
away, which seems less than ideal. I donno, I'm not 100% either way.

Scott




On Fri, Feb 8, 2013 at 7:46 AM, Erik Arvidsson a...@chromium.org wrote:

 On Thu, Feb 7, 2013 at 11:51 PM, Scott Miles sjmi...@google.com wrote:

  P.P.S. Arv, do you have a preference from my three versions (or none of
 the
  above)?

 I prefer number 2. This is what we want for ES6 anyway. Both 1 and 3
 makes me have to repeat myself.

 --
 erik



Re: document.register and ES6

2013-02-08 Thread Erik Arvidsson
On Fri, Feb 8, 2013 at 11:54 AM, Scott Miles sjmi...@google.com wrote:
 The idea is supposed to be that 1 and 3 are only stopgaps until we get 'what
 we want'. In the future when you can derive a DOM element directly, both
 bits of extra code can fall away. Was that clear? Does it change anything in
 your mind?

 If we go with 2, I believe it means nobody will ever use a custom element
 without having to load a helper library first to make the nasty syntax go
 away, which seems less than ideal. I donno, I'm not 100% either way.

1 and 3 have nasty syntax too so until you can depend on ES6 you
probably want to use a helper function no matter what.

var MyElement = defineClass(HTMLElement, {
  constructor: function() {},
  method: function() {},
  get prop() {},
  set prop(v) {}
});
MyElement = document.register('my-element', {
  class: MyElement
});

I believe a polyfill would most likely actually just be a shim (in the
terms we have started to use) because:

1. We cannot really extends anything else but HTMLElement/HTMLUnknownElement.
2. We cannot return the correct function object from document.register.
3. We cannot setup the [[Prototype]] in IE.
4. The fixup is async at best

and since it just a shim you might as just impose extra restrictions
on the usage. These extra restrictions could be to use helper
functions.

-- 
erik



Re: document.register and ES6

2013-02-08 Thread Scott Miles
Sorry, I'm not quite following.

1. We cannot really extends anything else but
HTMLElement/HTMLUnknownElement.
2. We cannot return the correct function object from document.register.

I don't see why these are true?

(Btw note that my 'solution 3' removes the 'return a function from
register' and instead puts that into the intermediate function.)

Also, you and Dimtiri keep talking about polyfills, but I'm talking about
the *spec* first.

Are you saying that the spec for document.register will simply require ES6
and everything else we be some kind of hack? I guess I thought the idea was
to spec document.register such that it could be implemented by browser
vendors *before* class-syntax or JS inheritance for DOM was available. Am I
misunderstanding?


On Fri, Feb 8, 2013 at 9:11 AM, Erik Arvidsson a...@chromium.org wrote:

 On Fri, Feb 8, 2013 at 11:54 AM, Scott Miles sjmi...@google.com wrote:
  The idea is supposed to be that 1 and 3 are only stopgaps until we get
 'what
  we want'. In the future when you can derive a DOM element directly, both
  bits of extra code can fall away. Was that clear? Does it change
 anything in
  your mind?
 
  If we go with 2, I believe it means nobody will ever use a custom element
  without having to load a helper library first to make the nasty syntax go
  away, which seems less than ideal. I donno, I'm not 100% either way.

 1 and 3 have nasty syntax too so until you can depend on ES6 you
 probably want to use a helper function no matter what.

 var MyElement = defineClass(HTMLElement, {
   constructor: function() {},
   method: function() {},
   get prop() {},
   set prop(v) {}
 });
 MyElement = document.register('my-element', {
   class: MyElement
 });

 I believe a polyfill would most likely actually just be a shim (in the
 terms we have started to use) because:

 1. We cannot really extends anything else but
 HTMLElement/HTMLUnknownElement.
 2. We cannot return the correct function object from document.register.
 3. We cannot setup the [[Prototype]] in IE.
 4. The fixup is async at best

 and since it just a shim you might as just impose extra restrictions
 on the usage. These extra restrictions could be to use helper
 functions.

 --
 erik



Re: document.register and ES6

2013-02-08 Thread Boris Zbarsky

On 2/8/13 5:11 PM, Erik Arvidsson wrote:

1. We cannot really extends anything else but HTMLElement/HTMLUnknownElement.


Note that this restriction is not limited to polyfills.  Extending other 
HTMLElements with a custom tagname seems ... highly undesirable to me. 
In particular, if you have an element whose localName is not button 
but which is an HTMLButtonElement then some aspects of its buttonness 
will work in some UAs and other will not, and the set will depend on the 
UA and on the extensions installed and so forth.


If we need to subclass built-in non-generic HTML elements we need to do 
so with nodes which have the right localName.


-Boris



Re: document.register and ES6

2013-02-08 Thread Erik Arvidsson
On Fri, Feb 8, 2013 at 12:18 PM, Scott Miles sjmi...@google.com wrote:
 Sorry, I'm not quite following.

 1. We cannot really extends anything else but
 HTMLElement/HTMLUnknownElement.
 2. We cannot return the correct function object from document.register.

 I don't see why these are true?

1. Because an element with tagName === 'my-button' will not be an
HTMLButtonElement instance.
2. Because ES5 cannot set @@create so you need to create a new
function that wraps the original.

 (Btw note that my 'solution 3' removes the 'return a function from register'
 and instead puts that into the intermediate function.)

1 can be implemented using 3.

 Also, you and Dimtiri keep talking about polyfills, but I'm talking about
 the *spec* first.

 Are you saying that the spec for document.register will simply require ES6
 and everything else we be some kind of hack? I guess I thought the idea was
 to spec document.register such that it could be implemented by browser
 vendors *before* class-syntax or JS inheritance for DOM was available. Am I
 misunderstanding?

I think you are misunderstanding some things. There is no need to wait
for ES6 class syntax. ES6 class syntax is just syntactic sugar over
ES5 + __proto__. ES6 has formalized the semantics for new Expr to
use two phases. This cannot be done in useland code but we can achieve
the same using ES5 spec internals by mutating [[Construct]] (instead
of @@create in ES6).

A lot of these later discussions have been driven by a desire to be
able to shim this. If we didn't need to shim this we would not need to
have two different functions for one entity.

-- 
erik



Re: document.register and ES6

2013-02-08 Thread Scott Miles
 1. Because an element with tagName === 'my-button' will not be
an HTMLButtonElement instance.

Yes, but as I mentioned, the latest notion I undersstood was that we would
support button is='my-button' syntax in this case.

 2. We cannot return the correct function object from document.register.
 2. Because ES5 cannot set @@create so you need to create a new function
that wraps the original.

Yes, so all ES5 solutions must return some generated function. This is a
big reason we're going through this exercis and why I attempted to isolate
this requirement in a separate function that could then evacipate when ES6
solutions become possible.

 1 can be implemented using 3.

Yes, but given 3, document.register can be spec'd exactly as we want, and
the cost of requiring the function wrapper is isolated elsewhere. Given 1,
document.register has to be specified with the technical debt inside (take
an extra parameter, return a function).

Having said all that, you actually preferred (2). My only good argument
against (2) is that it requires document.register to return something,
which is not an ability it will need at some point in the future.


There is no need to wait for ES6 class syntax.
If we didn't need to shim this we would not need to have two different
functions for one entity.


The critical bit is not ES6 class syntax, it's that you cannot extend DOM
'classes' with JS. That's what's driving all of this, and afaik, affects
native implementations just as much as shims. Probably I should have
separated this from the 'class' question more clearly, but my goal was to
reach a destination that could smoothly evolve with both enhancements.


On Fri, Feb 8, 2013 at 9:34 AM, Erik Arvidsson a...@chromium.org wrote:

 On Fri, Feb 8, 2013 at 12:18 PM, Scott Miles sjmi...@google.com wrote:
  Sorry, I'm not quite following.
 
  1. We cannot really extends anything else but
  HTMLElement/HTMLUnknownElement.
  2. We cannot return the correct function object from document.register.
 
  I don't see why these are true?

 1. Because an element with tagName === 'my-button' will not be an
 HTMLButtonElement instance.
 2. Because ES5 cannot set @@create so you need to create a new
 function that wraps the original.

  (Btw note that my 'solution 3' removes the 'return a function from
 register'
  and instead puts that into the intermediate function.)

 1 can be implemented using 3.

  Also, you and Dimtiri keep talking about polyfills, but I'm talking about
  the *spec* first.
 
  Are you saying that the spec for document.register will simply require
 ES6
  and everything else we be some kind of hack? I guess I thought the idea
 was
  to spec document.register such that it could be implemented by browser
  vendors *before* class-syntax or JS inheritance for DOM was available.
 Am I
  misunderstanding?

 I think you are misunderstanding some things. There is no need to wait
 for ES6 class syntax. ES6 class syntax is just syntactic sugar over
 ES5 + __proto__. ES6 has formalized the semantics for new Expr to
 use two phases. This cannot be done in useland code but we can achieve
 the same using ES5 spec internals by mutating [[Construct]] (instead
 of @@create in ES6).

 A lot of these later discussions have been driven by a desire to be
 able to shim this. If we didn't need to shim this we would not need to
 have two different functions for one entity.

 --
 erik



Re: document.register and ES6

2013-02-08 Thread Dimitri Glazkov
On Fri, Feb 8, 2013 at 3:13 PM, Scott Miles sjmi...@google.com wrote:
 Aha, I see, that's a very good question.

Being discussed here.

https://www.w3.org/Bugs/Public/show_bug.cgi?id=20913

:DG



Re: document.register and ES6

2013-02-07 Thread Dimitri Glazkov
I think we have the solution for polyfills: return a slightly different
object from document.register. Should we do the same thing for ES5/3 or
should we spec this as  overwriting of the [[Construct]] method?

:DG


Re: document.register and ES6

2013-02-07 Thread Dimitri Glazkov
On Wed, Feb 6, 2013 at 10:01 AM, Boris Zbarsky bzbar...@mit.edu wrote:

 On 2/6/13 5:07 PM, Erik Arvidsson wrote:

 This refactoring is needed for ES6 anyway so it might be worth looking
 into no matter what.


 Well, yes, but it's a matter of timeframes.  It's incredibly unlikely that
 a complete refactoring of how functions are implemented (which is what I
 was given to understand would be required here) could be done in the next
 several months to a year  I doubt we want to wait that long to do
 document.register.


This is a valid and important concern. Boris, in your opinion, what is the
most compatible way to proceed here? I see a couple of options, but don't
know how difficult they will be implementation-wise:

1) Expose the ability to override [[Construct]]. Arv tells me that he spoke
with V8 peeps and they think they can do this fairly easily. How's the
SpiderMonkey story looking here?

2) Until ES6 is here, return a generated constructor from
document.register, which is the approach that Scott/Arv/Daniel came up with
for polyfills. Effectively, this generated constructor will serve as the
surrogate [[Construct]] override.

3) ...

4) PROFIT

:DG


Re: document.register and ES6

2013-02-07 Thread Scott Miles
In my excitement for getting something that worked on the Big Three
(webkit, IE, FF), I inadvertently cheated by adding an extra parameter to
'document.register'.

TL;DR version:

Solutions to the extra parameter problem:

1. go ahead and have an (optional) extra parameter to document.register

   MyButton = function() { ... };
   MyButton.prototype = { ... };
   MyButton = document.register('x-button', MyButton, 'button');

2. require user to chain prototypes himself and infer the tagName from the
prototype

   MyButton = function() { ... };
   // making prototype requires icky DefineProperty syntax
   // on IE the only purpose of chaining the prototype is for tagName
inference
   MyButton.prototype = Object.create(HTMLButtonElement.prototype, { });
   MyButton = document.register('x-button', MyButton);

3. introduce an intermediate method to build the 'class':

  MyButton = function() { ... };
  MyButton.prototype = { ... };
  MyButton = document.extendElement('button', MyButton);
  document.register('x-button', MyButton);

Right now I'm preferring (3). WDTY?

===

Long version:

Recall that the goal is to support the simple notion of: make class,
register to tag. So,

  class MyButton extends HTMLButtonElement...
  document.register('x-button', MyButton);

My last proposed non-ES6 version had syntax like this:

   MyButton = function() { ... };
   MyButton.prototype = { ... };
   MyButton = document.register('x-button', MyButton, 'button');

The third parameter serves two purposes: (1) allows register to chain the
correct prototype (HTMLButtonElement.prototype) to MyButton.prototype and
(2) allows register to generate an appropriate constructor (i.e. one the
instantiates a 'button' element).

Trying to remove the third parameter created some new quandries.

One avenue is to suggest the developer set up the inheritance chain outside
of register. This is immediately appealing because it's very close to the
'goal syntax'. IOW,

   MyButton = function() { ... };
   MyButton.prototype = Object.create(HTMLButtonElement.prototype, { });
   MyButton = document.register('x-button', MyButton);

Btw: this form requires inferring the tag name 'button' from
HTMLButtonElement.prototype, which AFAIK, is not as easy as it sounds.

There are two potential downsides (1) adding properties to
MyButton.prototype requires property descriptors (or some helper function
the user must write), (2) on IE we aren't using the chained prototype
anyway.

An alternative would be to introduce another method, something like
'document.extendElement'. Usage would be like so:

  MyButton = function() { ... };
  MyButton.prototype = { ... };
  MyButton = document.extendElement('button', MyButton);
  document.register('x-button', MyButton);

Scott


On Thu, Feb 7, 2013 at 3:15 PM, Dimitri Glazkov dglaz...@google.com wrote:




 On Wed, Feb 6, 2013 at 10:01 AM, Boris Zbarsky bzbar...@mit.edu wrote:

 On 2/6/13 5:07 PM, Erik Arvidsson wrote:

 This refactoring is needed for ES6 anyway so it might be worth looking
 into no matter what.


 Well, yes, but it's a matter of timeframes.  It's incredibly unlikely
 that a complete refactoring of how functions are implemented (which is what
 I was given to understand would be required here) could be done in the next
 several months to a year  I doubt we want to wait that long to do
 document.register.


 This is a valid and important concern. Boris, in your opinion, what is the
 most compatible way to proceed here? I see a couple of options, but don't
 know how difficult they will be implementation-wise:

 1) Expose the ability to override [[Construct]]. Arv tells me that he
 spoke with V8 peeps and they think they can do this fairly easily. How's
 the SpiderMonkey story looking here?

 2) Until ES6 is here, return a generated constructor from
 document.register, which is the approach that Scott/Arv/Daniel came up with
 for polyfills. Effectively, this generated constructor will serve as the
 surrogate [[Construct]] override.

 3) ...

 4) PROFIT

 :DG



Re: document.register and ES6

2013-02-07 Thread Scott Miles
Good reminder. On webkit/ff at least, we have made polyfills which can
generate:

x-element // for elements derived from HTMLUnknownElement
button is=x-element // for all other elements

Since both syntaxes are now (to be) supported by spec, I think we are ok?

Scott

P.S. 100% of the custom elements in our current library are based on
HTMLUnknownElement.

P.P.S. Arv, do you have a preference from my three versions (or none of the
above)?

On Thu, Feb 7, 2013 at 7:16 PM, Erik Arvidsson a...@chromium.org wrote:

 Actually, that reminds me. How is a polyfill supposed to be able to create
 an element with the tag name my-button and still have the instance be an
 HTMLButtonElement? That does not seem possible. I guess a polyfill just
 need to limit the base to HTMLUnknownElement.
 On Feb 7, 2013 8:44 PM, Scott Miles sjmi...@google.com wrote:

 In my excitement for getting something that worked on the Big Three
 (webkit, IE, FF), I inadvertently cheated by adding an extra parameter to
 'document.register'.

 TL;DR version:

 Solutions to the extra parameter problem:

 1. go ahead and have an (optional) extra parameter to document.register

MyButton = function() { ... };
MyButton.prototype = { ... };
MyButton = document.register('x-button', MyButton, 'button');

 2. require user to chain prototypes himself and infer the tagName from
 the prototype

MyButton = function() { ... };
// making prototype requires icky DefineProperty syntax
// on IE the only purpose of chaining the prototype is for tagName
 inference
MyButton.prototype = Object.create(HTMLButtonElement.prototype, { });
MyButton = document.register('x-button', MyButton);

 3. introduce an intermediate method to build the 'class':

   MyButton = function() { ... };
   MyButton.prototype = { ... };
   MyButton = document.extendElement('button', MyButton);
   document.register('x-button', MyButton);

 Right now I'm preferring (3). WDTY?

 ===

 Long version:

 Recall that the goal is to support the simple notion of: make class,
 register to tag. So,

   class MyButton extends HTMLButtonElement...
   document.register('x-button', MyButton);

 My last proposed non-ES6 version had syntax like this:

MyButton = function() { ... };
MyButton.prototype = { ... };
MyButton = document.register('x-button', MyButton, 'button');

 The third parameter serves two purposes: (1) allows register to chain the
 correct prototype (HTMLButtonElement.prototype) to MyButton.prototype and
 (2) allows register to generate an appropriate constructor (i.e. one the
 instantiates a 'button' element).

 Trying to remove the third parameter created some new quandries.

 One avenue is to suggest the developer set up the inheritance chain
 outside of register. This is immediately appealing because it's very close
 to the 'goal syntax'. IOW,

MyButton = function() { ... };
MyButton.prototype = Object.create(HTMLButtonElement.prototype, { });
MyButton = document.register('x-button', MyButton);

 Btw: this form requires inferring the tag name 'button' from
 HTMLButtonElement.prototype, which AFAIK, is not as easy as it sounds.

 There are two potential downsides (1) adding properties to
 MyButton.prototype requires property descriptors (or some helper function
 the user must write), (2) on IE we aren't using the chained prototype
 anyway.

 An alternative would be to introduce another method, something like
 'document.extendElement'. Usage would be like so:

   MyButton = function() { ... };
   MyButton.prototype = { ... };
   MyButton = document.extendElement('button', MyButton);
   document.register('x-button', MyButton);

 Scott


 On Thu, Feb 7, 2013 at 3:15 PM, Dimitri Glazkov dglaz...@google.comwrote:




 On Wed, Feb 6, 2013 at 10:01 AM, Boris Zbarsky bzbar...@mit.edu wrote:

 On 2/6/13 5:07 PM, Erik Arvidsson wrote:

 This refactoring is needed for ES6 anyway so it might be worth looking
 into no matter what.


 Well, yes, but it's a matter of timeframes.  It's incredibly unlikely
 that a complete refactoring of how functions are implemented (which is what
 I was given to understand would be required here) could be done in the next
 several months to a year  I doubt we want to wait that long to do
 document.register.


 This is a valid and important concern. Boris, in your opinion, what is
 the most compatible way to proceed here? I see a couple of options, but
 don't know how difficult they will be implementation-wise:

 1) Expose the ability to override [[Construct]]. Arv tells me that he
 spoke with V8 peeps and they think they can do this fairly easily. How's
 the SpiderMonkey story looking here?

 2) Until ES6 is here, return a generated constructor from
 document.register, which is the approach that Scott/Arv/Daniel came up with
 for polyfills. Effectively, this generated constructor will serve as the
 surrogate [[Construct]] override.

 3) ...

 4) PROFIT

 :DG





Re: document.register and ES6

2013-02-07 Thread Daniel Buchner
Scott is right, there isn't a great polyfill answer for this part of the
spec, but fortunately it doesn't affect too potential many use-cases.
Developers will still go bananas for the functionality we can provide in
legacy UA versions.

- Daniel
 On Feb 7, 2013 8:51 PM, Scott Miles sjmi...@google.com wrote:

 Good reminder. On webkit/ff at least, we have made polyfills which can
 generate:

 x-element // for elements derived from HTMLUnknownElement
 button is=x-element // for all other elements

 Since both syntaxes are now (to be) supported by spec, I think we are ok?

 Scott

 P.S. 100% of the custom elements in our current library are based on
 HTMLUnknownElement.

 P.P.S. Arv, do you have a preference from my three versions (or none of
 the above)?

 On Thu, Feb 7, 2013 at 7:16 PM, Erik Arvidsson a...@chromium.org wrote:

 Actually, that reminds me. How is a polyfill supposed to be able to
 create an element with the tag name my-button and still have the instance
 be an HTMLButtonElement? That does not seem possible. I guess a polyfill
 just need to limit the base to HTMLUnknownElement.
 On Feb 7, 2013 8:44 PM, Scott Miles sjmi...@google.com wrote:

 In my excitement for getting something that worked on the Big Three
 (webkit, IE, FF), I inadvertently cheated by adding an extra parameter to
 'document.register'.

 TL;DR version:

 Solutions to the extra parameter problem:

 1. go ahead and have an (optional) extra parameter to document.register

MyButton = function() { ... };
MyButton.prototype = { ... };
MyButton = document.register('x-button', MyButton, 'button');

 2. require user to chain prototypes himself and infer the tagName from
 the prototype

MyButton = function() { ... };
// making prototype requires icky DefineProperty syntax
// on IE the only purpose of chaining the prototype is for tagName
 inference
MyButton.prototype = Object.create(HTMLButtonElement.prototype, { });
MyButton = document.register('x-button', MyButton);

 3. introduce an intermediate method to build the 'class':

   MyButton = function() { ... };
   MyButton.prototype = { ... };
   MyButton = document.extendElement('button', MyButton);
   document.register('x-button', MyButton);

 Right now I'm preferring (3). WDTY?

 ===

 Long version:

 Recall that the goal is to support the simple notion of: make class,
 register to tag. So,

   class MyButton extends HTMLButtonElement...
   document.register('x-button', MyButton);

 My last proposed non-ES6 version had syntax like this:

MyButton = function() { ... };
MyButton.prototype = { ... };
MyButton = document.register('x-button', MyButton, 'button');

 The third parameter serves two purposes: (1) allows register to chain
 the correct prototype (HTMLButtonElement.prototype) to MyButton.prototype
 and (2) allows register to generate an appropriate constructor (i.e. one
 the instantiates a 'button' element).

 Trying to remove the third parameter created some new quandries.

 One avenue is to suggest the developer set up the inheritance chain
 outside of register. This is immediately appealing because it's very close
 to the 'goal syntax'. IOW,

MyButton = function() { ... };
MyButton.prototype = Object.create(HTMLButtonElement.prototype, { });
MyButton = document.register('x-button', MyButton);

 Btw: this form requires inferring the tag name 'button' from
 HTMLButtonElement.prototype, which AFAIK, is not as easy as it sounds.

 There are two potential downsides (1) adding properties to
 MyButton.prototype requires property descriptors (or some helper function
 the user must write), (2) on IE we aren't using the chained prototype
 anyway.

 An alternative would be to introduce another method, something like
 'document.extendElement'. Usage would be like so:

   MyButton = function() { ... };
   MyButton.prototype = { ... };
   MyButton = document.extendElement('button', MyButton);
   document.register('x-button', MyButton);

 Scott


 On Thu, Feb 7, 2013 at 3:15 PM, Dimitri Glazkov dglaz...@google.comwrote:




 On Wed, Feb 6, 2013 at 10:01 AM, Boris Zbarsky bzbar...@mit.eduwrote:

 On 2/6/13 5:07 PM, Erik Arvidsson wrote:

 This refactoring is needed for ES6 anyway so it might be worth looking
 into no matter what.


 Well, yes, but it's a matter of timeframes.  It's incredibly unlikely
 that a complete refactoring of how functions are implemented (which is 
 what
 I was given to understand would be required here) could be done in the 
 next
 several months to a year  I doubt we want to wait that long to do
 document.register.


 This is a valid and important concern. Boris, in your opinion, what is
 the most compatible way to proceed here? I see a couple of options, but
 don't know how difficult they will be implementation-wise:

 1) Expose the ability to override [[Construct]]. Arv tells me that he
 spoke with V8 peeps and they think they can do this fairly easily. How's
 the SpiderMonkey story looking here?

 2) 

Re: document.register and ES6

2013-02-06 Thread Boris Zbarsky

On 2/5/13 10:28 PM, Boris Zbarsky wrote:

And the point is that document.register changes the [[Construct]] of
MyButton but does nothing else with it?


Note that I'm still checking how feasible this is in SpiderMonkey on any 
sort of finite timeframe, if we do decide to do this.  Functions right 
now don't have a [[Construct]] member in spidermonkey that's stored on a 
function directly; it's stored on a shared data structure.  So it's 
impossible to change the [[Construct]] of a single function as things 
stand...


-Boris



Re: document.register and ES6

2013-02-06 Thread David Bruant

Le 06/02/2013 11:27, Boris Zbarsky a écrit :

On 2/5/13 10:28 PM, Boris Zbarsky wrote:

And the point is that document.register changes the [[Construct]] of
MyButton but does nothing else with it?


Note that I'm still checking how feasible this is in SpiderMonkey on 
any sort of finite timeframe, if we do decide to do this. Functions 
right now don't have a [[Construct]] member in spidermonkey that's 
stored on a function directly; it's stored on a shared data 
structure.  So it's impossible to change the [[Construct]] of a single 
function as things stand...
As a band-aid short-term type of solution, the exposed function could be 
a proxy to the actual function with a specific construct trap. I've just 
tried the following on Firefox Aurora and it does what you'd expect:


function f(){
console.log('f call')
}

var pf = new Proxy(f, {
construct: function(target){
console.log('pf construct');
target();
}
})

pf();
new pf();

David



Re: document.register and ES6

2013-02-06 Thread Boris Zbarsky

On 2/6/13 10:36 AM, David Bruant wrote:

As a band-aid short-term type of solution, the exposed function could be
a proxy to the actual function with a specific construct trap


There is no exposed function.  In Erik's proposal the function is 
provided by the script and then the script keeps using it; the caller is 
expected to mutate the [[Construct]] of that existing function object.


If I get to create my own objects and get the script to use them, I can 
create things with a custom [[Construct]] that act like functions, no 
problem.  It's taking an existing function object created via execution 
of a function statement and changing its [[Construct]] that's problematic.


-Boris



Re: document.register and ES6

2013-02-06 Thread Boris Zbarsky

On 2/6/13 10:46 AM, Boris Zbarsky wrote:

There is no exposed function.  In Erik's proposal the function is
provided by the script and then the script keeps using it; the caller is
expected to mutate the [[Construct]]


I meant the _callee_ of course.  ;)

-Boris



Re: document.register and ES6

2013-02-06 Thread Erik Arvidsson
On Tue, Feb 5, 2013 at 8:26 PM, Daniel Buchner dan...@mozilla.com wrote:
 I have two questions:

 Does this affect our ability to polyfill doc.register in current browsers?

Good point. This is really important to us as well so we most likely
need to tweak this to make sure it will work.

Do we need to be able to do new MyButton or is
document.createElement/innerHTML/parser sufficient? If we need to be
able to do new in the polyfill I think we either need to tweak
document.register or get the developer to cooperate (by writing
different code). At this point I don't see how we can tweak the API
and still fulfill all of the requirements.

 Are you saying we're going to nix the ability to easily register insertion,
 removal, and attribute change callbacks from the API?

No. I don't think there is any change here. Instead of passing in
functions to document.register we can call methods on the custom
element. For example:

class MyButton extends HTMLButtonElement {
  constructor() {
super();
this.moreInit();
  }
  handleAttributeChange(name, value) { ... }
  moreInit() { ... }
  ...
}
document.register('my-button', MyButton);

instead of

var myButtonPrototype = Object.create(HTMLButtonElement.prototype, {
  handleAttributeChange: {
value: function(name, value) { ... },
enumerable: true,
configurable: true,
writable: true
  },
  moreInit: {
value: function() { ... },
enumerable: true,
configurable: true,
writable: true
  },
  ...
});

var MyButton = document.register('my-button', {
  prototype: myButtonPrototype,
  created: function(element) {
element.moreInit();
  },
  attributeChange: function(element, name, value) {
element.handleAttibuteChange(name, value);
  }
});

--
erik



Re: document.register and ES6

2013-02-06 Thread Erik Arvidsson
On Wed, Feb 6, 2013 at 5:27 AM, Boris Zbarsky bzbar...@mit.edu wrote:
 Note that I'm still checking how feasible this is in SpiderMonkey on any
 sort of finite timeframe, if we do decide to do this.  Functions right now
 don't have a [[Construct]] member in spidermonkey that's stored on a
 function directly; it's stored on a shared data structure.  So it's
 impossible to change the [[Construct]] of a single function as things
 stand...

This refactoring is needed for ES6 anyway so it might be worth looking
into no matter what.

For V8 we don't have a way to do this at the moment but I was told
that it should be easy to fix.

-- 
erik



Re: document.register and ES6

2013-02-06 Thread Erik Arvidsson
On Wed, Feb 6, 2013 at 12:47 PM, Scott Miles sjmi...@google.com wrote:
 Instead of passing in functions to document.register we can call methods
 on the custom element.

 My understanding is that the 'passing in functions' was a design decision,
 not a technical one. IOW, Dimitri spec'd it that way so these (private)
 lifecycle methods aren't just sitting there on the node's public API.

 This technique certainly on the table to change, but I think it's improper
 to deem it technical debt.

Good point about allowing these to be non public members of the element.

With that in mind maybe we should reconsider to go back to the
property bag even though it is a lot more verbose.

-- 
erik



Re: document.register and ES6

2013-02-06 Thread Boris Zbarsky

On 2/6/13 5:07 PM, Erik Arvidsson wrote:

This refactoring is needed for ES6 anyway so it might be worth looking
into no matter what.


Well, yes, but it's a matter of timeframes.  It's incredibly unlikely 
that a complete refactoring of how functions are implemented (which is 
what I was given to understand would be required here) could be done in 
the next several months to a year  I doubt we want to wait that long 
to do document.register.


-Boris



Re: document.register and ES6

2013-02-06 Thread Daniel Buchner
On Wed, Feb 6, 2013 at 9:03 AM, Erik Arvidsson a...@chromium.org wrote:

 On Tue, Feb 5, 2013 at 8:26 PM, Daniel Buchner dan...@mozilla.com wrote:
  I have two questions:
 
  Does this affect our ability to polyfill doc.register in current
 browsers?

 Good point. This is really important to us as well so we most likely
 need to tweak this to make sure it will work.

 Do we need to be able to do new MyButton or is
 document.createElement/innerHTML/parser sufficient? If we need to be
 able to do new in the polyfill I think we either need to tweak
 document.register or get the developer to cooperate (by writing
 different code). At this point I don't see how we can tweak the API
 and still fulfill all of the requirements.

  Are you saying we're going to nix the ability to easily register
 insertion,
  removal, and attribute change callbacks from the API?

 No. I don't think there is any change here. Instead of passing in
 functions to document.register we can call methods on the custom
 element. For example:

 class MyButton extends HTMLButtonElement {
   constructor() {
 super();
 this.moreInit();
   }
   handleAttributeChange(name, value) { ... }
   moreInit() { ... }
   ...
 }
 document.register('my-button', MyButton);


Above you say the developer would simply call methods on the custom
element - how do you figure? Are we going to imbue all elements with
magical handleRemoved, handleAttributeChange, etc function handlers that,
when simply defined in the closure, implicitly hook into mutation
observations? I hope this isn't the case, as it would be incredibly obtuse
and extremely magical. If that's not what you mean, please provide a full
example that leaves out none of the boilerplate - I would like to see what
developers are really in for.

You start the following code section below with instead of below, but
nothing below this point accurately represents how the spec currently
behaves


 instead of

 var myButtonPrototype = Object.create(HTMLButtonElement.prototype, {
   handleAttributeChange: {
 value: function(name, value) { ... },
 enumerable: true,
 configurable: true,
 writable: true
   },
   moreInit: {
 value: function() { ... },
 enumerable: true,
 configurable: true,
 writable: true
   },
   ...
 });

 var MyButton = document.register('my-button', {
   prototype: myButtonPrototype,
   created: function(element) {
 element.moreInit();
   },
   attributeChange: function(element, name, value) {
 element.handleAttibuteChange(name, value);
   }
 });


Currently it is:

var MyButton = document.register('my-button', {
lifecycle: {
attributeChanged: function(){ ... }
}
});


Re: document.register and ES6

2013-02-06 Thread Dimitri Glazkov
On Wed, Feb 6, 2013 at 9:56 AM, Erik Arvidsson a...@chromium.org wrote:

 On Wed, Feb 6, 2013 at 12:47 PM, Scott Miles sjmi...@google.com wrote:
  Instead of passing in functions to document.register we can call
 methods
  on the custom element.
 
  My understanding is that the 'passing in functions' was a design
 decision,
  not a technical one. IOW, Dimitri spec'd it that way so these (private)
  lifecycle methods aren't just sitting there on the node's public API.
 
  This technique certainly on the table to change, but I think it's
 improper
  to deem it technical debt.

 Good point about allowing these to be non public members of the element.

 With that in mind maybe we should reconsider to go back to the
 property bag even though it is a lot more verbose.


+1. I think property bag is back. We can change as little as:

document.register(foo-bar, { propertyNameTBD: FooBar, ... });
// that is, the only change from current spec is replacing prototype
property
// with some other property that holds the class

or as much as:

document.register(foo-bar, FooBar, { /* property bag is a 3rd param */ });

:DG


Re: document.register and ES6

2013-02-06 Thread Dimitri Glazkov
On Tue, Feb 5, 2013 at 5:43 PM, Daniel Buchner dan...@mozilla.com wrote:

 So we're removing the async nature of the API? How is this a good trade? I
 thought this was one of the benefits? Is polyfilling still possible in a
 sane way that adheres to the specified behavior?


I don't think anyone answered the sync part yet. The sync part here is only
for the cases when the definition is already known. There is no difference
from what we have now.

:DG


Re: document.register and ES6

2013-02-06 Thread Dimitri Glazkov
On Wed, Feb 6, 2013 at 9:03 AM, Erik Arvidsson a...@chromium.org wrote:

Do we need to be able to do new MyButton or is

 document.createElement/innerHTML/parser sufficient? If we need to be
 able to do new in the polyfill I think we either need to tweak
 document.register or get the developer to cooperate (by writing
 different code). At this point I don't see how we can tweak the API
 and still fulfill all of the requirements.


Can the super call do this work somehow in the polyfill?

:DG


Re: document.register and ES6

2013-02-06 Thread Scott Miles
So, neglecting issues around the syntax of document.register and the
privatization of callbacks, is it fair to say the following is the intended
future:

class MyButton extends HTMLButtonElement {
  constructor() {
super();
// make root, etc.
  }
}
document.register('x-button', MyButton);

If so then can we do this in the present:

MyButtonImpl = function() {
  MyButton.super();
  // make root, etc.
};
MyButtonImpl.prototype = Object.create(HTMLButtonElement, { ... });

// the ‘real’ constructor comes from document.register
// register injects ‘super’ into MyButton
MyButton = document.register(‘x-button’, MyButtonImpl);


On Wed, Feb 6, 2013 at 10:35 AM, Dimitri Glazkov dglaz...@google.comwrote:




 On Wed, Feb 6, 2013 at 9:03 AM, Erik Arvidsson a...@chromium.org wrote:

 Do we need to be able to do new MyButton or is

 document.createElement/innerHTML/parser sufficient? If we need to be
 able to do new in the polyfill I think we either need to tweak
 document.register or get the developer to cooperate (by writing
 different code). At this point I don't see how we can tweak the API
 and still fulfill all of the requirements.


 Can the super call do this work somehow in the polyfill?

 :DG




Re: document.register and ES6

2013-02-06 Thread Scott Miles
 Instead of passing in functions to document.register we can call methods
on the custom element.

My understanding is that the 'passing in functions' was a design decision,
not a technical one. IOW, Dimitri spec'd it that way so these (private)
lifecycle methods aren't just sitting there on the node's public API.

This technique certainly on the table to change, but I think it's improper
to deem it technical debt.

Scott


On Wed, Feb 6, 2013 at 9:03 AM, Erik Arvidsson a...@chromium.org wrote:

 On Tue, Feb 5, 2013 at 8:26 PM, Daniel Buchner dan...@mozilla.com wrote:
  I have two questions:
 
  Does this affect our ability to polyfill doc.register in current
 browsers?

 Good point. This is really important to us as well so we most likely
 need to tweak this to make sure it will work.

 Do we need to be able to do new MyButton or is
 document.createElement/innerHTML/parser sufficient? If we need to be
 able to do new in the polyfill I think we either need to tweak
 document.register or get the developer to cooperate (by writing
 different code). At this point I don't see how we can tweak the API
 and still fulfill all of the requirements.

  Are you saying we're going to nix the ability to easily register
 insertion,
  removal, and attribute change callbacks from the API?

 No. I don't think there is any change here. Instead of passing in
 functions to document.register we can call methods on the custom
 element. For example:

 class MyButton extends HTMLButtonElement {
   constructor() {
 super();
 this.moreInit();
   }
   handleAttributeChange(name, value) { ... }
   moreInit() { ... }
   ...
 }
 document.register('my-button', MyButton);

 instead of

 var myButtonPrototype = Object.create(HTMLButtonElement.prototype, {
   handleAttributeChange: {
 value: function(name, value) { ... },
 enumerable: true,
 configurable: true,
 writable: true
   },
   moreInit: {
 value: function() { ... },
 enumerable: true,
 configurable: true,
 writable: true
   },
   ...
 });

 var MyButton = document.register('my-button', {
   prototype: myButtonPrototype,
   created: function(element) {
 element.moreInit();
   },
   attributeChange: function(element, name, value) {
 element.handleAttibuteChange(name, value);
   }
 });

 --
 erik




Re: document.register and ES6

2013-02-06 Thread Scott Miles
To be clear, the actual current spec is only:

var MyButton = document.register('my-button', {
  prototype: aPROTOTYPE
});

So, while Arv has included non-spec 'created' and 'attributeChanged', you
have completely omitted 'prototype'.

Also, wrt call methods on the custom element, I believe all Arv means is
that instead of registering an explicit callback function (e.g.
attributeChanged), we could implicitly register that function by including
it in the prototype.

He's not suggesting some big alteration of the basic behavior afaik.

Scott



On Wed, Feb 6, 2013 at 10:06 AM, Daniel Buchner dan...@mozilla.com wrote:



 On Wed, Feb 6, 2013 at 9:03 AM, Erik Arvidsson a...@chromium.org wrote:

 On Tue, Feb 5, 2013 at 8:26 PM, Daniel Buchner dan...@mozilla.com
 wrote:
  I have two questions:
 
  Does this affect our ability to polyfill doc.register in current
 browsers?

 Good point. This is really important to us as well so we most likely
 need to tweak this to make sure it will work.

 Do we need to be able to do new MyButton or is
 document.createElement/innerHTML/parser sufficient? If we need to be
 able to do new in the polyfill I think we either need to tweak
 document.register or get the developer to cooperate (by writing
 different code). At this point I don't see how we can tweak the API
 and still fulfill all of the requirements.

  Are you saying we're going to nix the ability to easily register
 insertion,
  removal, and attribute change callbacks from the API?

 No. I don't think there is any change here. Instead of passing in
 functions to document.register we can call methods on the custom
 element. For example:

 class MyButton extends HTMLButtonElement {
   constructor() {
 super();
 this.moreInit();
   }
   handleAttributeChange(name, value) { ... }
   moreInit() { ... }
   ...
 }
 document.register('my-button', MyButton);


 Above you say the developer would simply call methods on the custom
 element - how do you figure? Are we going to imbue all elements with
 magical handleRemoved, handleAttributeChange, etc function handlers that,
 when simply defined in the closure, implicitly hook into mutation
 observations? I hope this isn't the case, as it would be incredibly obtuse
 and extremely magical. If that's not what you mean, please provide a full
 example that leaves out none of the boilerplate - I would like to see what
 developers are really in for.

 You start the following code section below with instead of below, but
 nothing below this point accurately represents how the spec currently
 behaves


 instead of

 var myButtonPrototype = Object.create(HTMLButtonElement.prototype, {
   handleAttributeChange: {
 value: function(name, value) { ... },
 enumerable: true,
 configurable: true,
 writable: true
   },
   moreInit: {
 value: function() { ... },
 enumerable: true,
 configurable: true,
 writable: true
   },
   ...
 });

 var MyButton = document.register('my-button', {
   prototype: myButtonPrototype,
   created: function(element) {
 element.moreInit();
   },
   attributeChange: function(element, name, value) {
 element.handleAttibuteChange(name, value);
   }
 });


 Currently it is:

 var MyButton = document.register('my-button', {
 lifecycle: {
 attributeChanged: function(){ ... }
 }
 });



Re: document.register and ES6

2013-02-06 Thread Scott Miles
Sorry, replace MyButton.super() with MyButton.super.call(this);


On Wed, Feb 6, 2013 at 10:37 AM, Scott Miles sjmi...@google.com wrote:

 So, neglecting issues around the syntax of document.register and the
 privatization of callbacks, is it fair to say the following is the intended
 future:

 class MyButton extends HTMLButtonElement {
   constructor() {
 super();
 // make root, etc.
   }
 }
 document.register('x-button', MyButton);

 If so then can we do this in the present:

 MyButtonImpl = function() {
   MyButton.super();
   // make root, etc.
 };
 MyButtonImpl.prototype = Object.create(HTMLButtonElement, { ... });

 // the ‘real’ constructor comes from document.register
 // register injects ‘super’ into MyButton
 MyButton = document.register(‘x-button’, MyButtonImpl);


 On Wed, Feb 6, 2013 at 10:35 AM, Dimitri Glazkov dglaz...@google.comwrote:




 On Wed, Feb 6, 2013 at 9:03 AM, Erik Arvidsson a...@chromium.org wrote:

 Do we need to be able to do new MyButton or is

 document.createElement/innerHTML/parser sufficient? If we need to be
 able to do new in the polyfill I think we either need to tweak
 document.register or get the developer to cooperate (by writing
 different code). At this point I don't see how we can tweak the API
 and still fulfill all of the requirements.


 Can the super call do this work somehow in the polyfill?

 :DG






Re: document.register and ES6

2013-02-06 Thread Erik Arvidsson
On Wed, Feb 6, 2013 at 1:38 PM, Scott Miles sjmi...@google.com wrote:
 Sorry, replace MyButton.super() with MyButton.super.call(this);


 On Wed, Feb 6, 2013 at 10:37 AM, Scott Miles sjmi...@google.com wrote:

 So, neglecting issues around the syntax of document.register and the
 privatization of callbacks, is it fair to say the following is the intended
 future:

 class MyButton extends HTMLButtonElement {
   constructor() {
 super();
 // make root, etc.
   }
 }
 document.register('x-button', MyButton);

 If so then can we do this in the present:

 MyButtonImpl = function() {

What do you mean here?

   MyButton.super();

Did you get that backwards? I don't see how MyButtonImpl can be
derived from MyButton.

   // make root, etc.
 };
 MyButtonImpl.prototype = Object.create(HTMLButtonElement, { ... });

 // the ‘real’ constructor comes from document.register
 // register injects ‘super’ into MyButton
 MyButton = document.register(‘x-button’, MyButtonImpl);

What is the relationship between MyButton and MyButtonImpl?

If MyButton.__proto__ === MyButtonImpl and
MyButton.prototype.__proto__ === MyButtonImpl.prototype then this
might work (but this cannot be polyfilled either).

--
erik



Re: document.register and ES6

2013-02-06 Thread Scott Miles
On Wed, Feb 6, 2013 at 11:18 AM, Erik Arvidsson a...@chromium.org wrote:

 On Wed, Feb 6, 2013 at 1:38 PM, Scott Miles sjmi...@google.com wrote:
  Sorry, replace MyButton.super() with MyButton.super.call(this);
 
 
  On Wed, Feb 6, 2013 at 10:37 AM, Scott Miles sjmi...@google.com wrote:
 
  So, neglecting issues around the syntax of document.register and the
  privatization of callbacks, is it fair to say the following is the
 intended
  future:
 
  class MyButton extends HTMLButtonElement {
constructor() {
  super();
  // make root, etc.
}
  }
  document.register('x-button', MyButton);
 
  If so then can we do this in the present:
 
  MyButtonImpl = function() {

 What do you mean here?

MyButton.super();

 Did you get that backwards? I don't see how MyButtonImpl can be
 derived from MyButton.


Its not. The 'super' means 'the super-class constructor for MyButton that
does not include magic DOM object generation' (in this case,
HTMLButtonElement). For MyDerivedButton, MyDerivedButton.super would point
to MyButtonImpl.

The existence of MyButtonImpl is an unfortunate side-effect of needing a
generated constructor.

The idea is to correspond as closely as possible with the ES6
version. MyButtonImpl goes away in ES6, it's purpose in the meantime is
just to provide something that looks like a proper class.

I could write it this way:

*MyButton = function() {
  MyButton.super();
  // make root, etc.
};
MyButton.prototype = Object.create(HTMLButtonElement, { ... });*
*
MyButton = document.register(‘x-button’, MyButton);
*

Written this way, MyButton no longer refers to the constructor you
specified, but instead refers to the generated constructor. This is
conceptually cleaner, but it's a bit tricky. For maximum clarity, I named
the internal version MyButtonImpl in my example code, but there is no
reason to have that symbol.



// make root, etc.
  };
  MyButtonImpl.prototype = Object.create(HTMLButtonElement, { ... });
 
  // the ‘real’ constructor comes from document.register
  // register injects ‘super’ into MyButton
  MyButton = document.register(‘x-button’, MyButtonImpl);

 What is the relationship between MyButton and MyButtonImpl?

 If MyButton.__proto__ === MyButtonImpl and
 MyButton.prototype.__proto__ === MyButtonImpl.prototype then this
 might work (but this cannot be polyfilled either).


MyButton.prototype == MyButtonImpl.prototype or
MyButton.prototype.__proto__ == MyButtonImpl.prototype, depending on needs.

MyButton itself does magic DOM construction work that we cannot do with
normal inheritance, then invokes MyButtonImpl. MyButtonImpl is never used
as a constructor itself (not as an argument to 'new' anyway).

From the user's perspective, he has made a single class which implements
his element (the goal!). The unfortunate name shenanigan (I called my class
MyButtonImpl, but after 'register' I refer to it as MyButton) is the
simplest way I could conceive to overcome the 'generated constructor'
problem.

To be clear, everything I come up with is intended to polyfill (modulo my
error), because I generally am writing those myself (at first anyway). One
version might look like this:

document.register = function(inExtends, inClass) {
  var ctor = makePrototypeTwiddlingConstructorForDomNodes(inClass);
  ctor.prototype = inClass.prototype;
  addToTagRegistry(inExtends, ctor, inClass);
  ctor.super = getClassForExtendee(inExtends);
  return ctor;
};


--
 erik



Re: document.register and ES6

2013-02-06 Thread Scott Miles
Errata:
 makePrototypeTwiddlingConstructorForDomNodes needs to know the extendee

var ctor = makePrototypeTwiddlingConstructorForDomNodes(inExtends, inClass);


On Wed, Feb 6, 2013 at 11:59 AM, Scott Miles sjmi...@google.com wrote:

 On Wed, Feb 6, 2013 at 11:18 AM, Erik Arvidsson a...@chromium.org wrote:

 On Wed, Feb 6, 2013 at 1:38 PM, Scott Miles sjmi...@google.com wrote:
  Sorry, replace MyButton.super() with MyButton.super.call(this);
 
 
  On Wed, Feb 6, 2013 at 10:37 AM, Scott Miles sjmi...@google.com
 wrote:
 
  So, neglecting issues around the syntax of document.register and the
  privatization of callbacks, is it fair to say the following is the
 intended
  future:
 
  class MyButton extends HTMLButtonElement {
constructor() {
  super();
  // make root, etc.
}
  }
  document.register('x-button', MyButton);
 
  If so then can we do this in the present:
 
  MyButtonImpl = function() {

 What do you mean here?

MyButton.super();

 Did you get that backwards? I don't see how MyButtonImpl can be
 derived from MyButton.


 Its not. The 'super' means 'the super-class constructor for MyButton that
 does not include magic DOM object generation' (in this case,
 HTMLButtonElement). For MyDerivedButton, MyDerivedButton.super would point
 to MyButtonImpl.

 The existence of MyButtonImpl is an unfortunate side-effect of needing a
 generated constructor.

 The idea is to correspond as closely as possible with the ES6
 version. MyButtonImpl goes away in ES6, it's purpose in the meantime is
 just to provide something that looks like a proper class.

 I could write it this way:

 *MyButton = function() {

   MyButton.super();
   // make root, etc.
 };
 MyButton.prototype = Object.create(HTMLButtonElement, { ... });*
 *
 MyButton = document.register(‘x-button’, MyButton);
 *

 Written this way, MyButton no longer refers to the constructor you
 specified, but instead refers to the generated constructor. This is
 conceptually cleaner, but it's a bit tricky. For maximum clarity, I named
 the internal version MyButtonImpl in my example code, but there is no
 reason to have that symbol.



// make root, etc.
  };
  MyButtonImpl.prototype = Object.create(HTMLButtonElement, { ... });
 
  // the ‘real’ constructor comes from document.register
  // register injects ‘super’ into MyButton
  MyButton = document.register(‘x-button’, MyButtonImpl);

 What is the relationship between MyButton and MyButtonImpl?

 If MyButton.__proto__ === MyButtonImpl and
 MyButton.prototype.__proto__ === MyButtonImpl.prototype then this
 might work (but this cannot be polyfilled either).


 MyButton.prototype == MyButtonImpl.prototype or
 MyButton.prototype.__proto__ == MyButtonImpl.prototype, depending on needs.

 MyButton itself does magic DOM construction work that we cannot do with
 normal inheritance, then invokes MyButtonImpl. MyButtonImpl is never used
 as a constructor itself (not as an argument to 'new' anyway).

 From the user's perspective, he has made a single class which implements
 his element (the goal!). The unfortunate name shenanigan (I called my class
 MyButtonImpl, but after 'register' I refer to it as MyButton) is the
 simplest way I could conceive to overcome the 'generated constructor'
 problem.

 To be clear, everything I come up with is intended to polyfill (modulo my
 error), because I generally am writing those myself (at first anyway). One
 version might look like this:

 document.register = function(inExtends, inClass) {
   var ctor = makePrototypeTwiddlingConstructorForDomNodes(inClass);
   ctor.prototype = inClass.prototype;
   addToTagRegistry(inExtends, ctor, inClass);
   ctor.super = getClassForExtendee(inExtends);
   return ctor;
 };


 --
 erik





Re: document.register and ES6

2013-02-06 Thread Scott Miles
There were several errors in my pseudo-code, here is a working version:

http://jsfiddle.net/yNbnL/1/

S


On Wed, Feb 6, 2013 at 12:01 PM, Scott Miles sjmi...@google.com wrote:

 Errata:
  makePrototypeTwiddlingConstructorForDomNodes needs to know the extendee

  var ctor = makePrototypeTwiddlingConstructorForDomNodes(inExtends,
 inClass);


 On Wed, Feb 6, 2013 at 11:59 AM, Scott Miles sjmi...@google.com wrote:

 On Wed, Feb 6, 2013 at 11:18 AM, Erik Arvidsson a...@chromium.org wrote:

 On Wed, Feb 6, 2013 at 1:38 PM, Scott Miles sjmi...@google.com wrote:
  Sorry, replace MyButton.super() with MyButton.super.call(this);
 
 
  On Wed, Feb 6, 2013 at 10:37 AM, Scott Miles sjmi...@google.com
 wrote:
 
  So, neglecting issues around the syntax of document.register and the
  privatization of callbacks, is it fair to say the following is the
 intended
  future:
 
  class MyButton extends HTMLButtonElement {
constructor() {
  super();
  // make root, etc.
}
  }
  document.register('x-button', MyButton);
 
  If so then can we do this in the present:
 
  MyButtonImpl = function() {

 What do you mean here?

MyButton.super();

 Did you get that backwards? I don't see how MyButtonImpl can be
 derived from MyButton.


 Its not. The 'super' means 'the super-class constructor for MyButton that
 does not include magic DOM object generation' (in this case,
 HTMLButtonElement). For MyDerivedButton, MyDerivedButton.super would point
 to MyButtonImpl.

 The existence of MyButtonImpl is an unfortunate side-effect of needing a
 generated constructor.

 The idea is to correspond as closely as possible with the ES6
 version. MyButtonImpl goes away in ES6, it's purpose in the meantime is
 just to provide something that looks like a proper class.

 I could write it this way:

 *MyButton = function() {

   MyButton.super();
   // make root, etc.
 };
 MyButton.prototype = Object.create(HTMLButtonElement, { ... });*
 *
 MyButton = document.register(‘x-button’, MyButton);
 *

 Written this way, MyButton no longer refers to the constructor you
 specified, but instead refers to the generated constructor. This is
 conceptually cleaner, but it's a bit tricky. For maximum clarity, I named
 the internal version MyButtonImpl in my example code, but there is no
 reason to have that symbol.



// make root, etc.
  };
  MyButtonImpl.prototype = Object.create(HTMLButtonElement, { ... });
 
  // the ‘real’ constructor comes from document.register
  // register injects ‘super’ into MyButton
  MyButton = document.register(‘x-button’, MyButtonImpl);

 What is the relationship between MyButton and MyButtonImpl?

 If MyButton.__proto__ === MyButtonImpl and
 MyButton.prototype.__proto__ === MyButtonImpl.prototype then this
 might work (but this cannot be polyfilled either).


 MyButton.prototype == MyButtonImpl.prototype or
 MyButton.prototype.__proto__ == MyButtonImpl.prototype, depending on needs.

 MyButton itself does magic DOM construction work that we cannot do with
 normal inheritance, then invokes MyButtonImpl. MyButtonImpl is never used
 as a constructor itself (not as an argument to 'new' anyway).

 From the user's perspective, he has made a single class which implements
 his element (the goal!). The unfortunate name shenanigan (I called my class
 MyButtonImpl, but after 'register' I refer to it as MyButton) is the
 simplest way I could conceive to overcome the 'generated constructor'
 problem.

 To be clear, everything I come up with is intended to polyfill (modulo my
 error), because I generally am writing those myself (at first anyway). One
 version might look like this:

 document.register = function(inExtends, inClass) {
   var ctor = makePrototypeTwiddlingConstructorForDomNodes(inClass);
   ctor.prototype = inClass.prototype;
   addToTagRegistry(inExtends, ctor, inClass);
   ctor.super = getClassForExtendee(inExtends);
   return ctor;
 };


 --
 erik






Re: document.register and ES6

2013-02-06 Thread Daniel Buchner
Scott: is this example not intended to work in IE9? It throws, the output
object is missing the 'oranginate' method.

Daniel J. Buchner
Product Manager, Developer Ecosystem
Mozilla Corporation


On Wed, Feb 6, 2013 at 12:32 PM, Scott Miles sjmi...@google.com wrote:

 There were several errors in my pseudo-code, here is a working version:

 http://jsfiddle.net/yNbnL/1/

 S


 On Wed, Feb 6, 2013 at 12:01 PM, Scott Miles sjmi...@google.com wrote:

 Errata:
  makePrototypeTwiddlingConstructorForDomNodes needs to know the extendee

  var ctor = makePrototypeTwiddlingConstructorForDomNodes(inExtends,
 inClass);


 On Wed, Feb 6, 2013 at 11:59 AM, Scott Miles sjmi...@google.com wrote:

 On Wed, Feb 6, 2013 at 11:18 AM, Erik Arvidsson a...@chromium.orgwrote:

 On Wed, Feb 6, 2013 at 1:38 PM, Scott Miles sjmi...@google.com wrote:
  Sorry, replace MyButton.super() with MyButton.super.call(this);
 
 
  On Wed, Feb 6, 2013 at 10:37 AM, Scott Miles sjmi...@google.com
 wrote:
 
  So, neglecting issues around the syntax of document.register and the
  privatization of callbacks, is it fair to say the following is the
 intended
  future:
 
  class MyButton extends HTMLButtonElement {
constructor() {
  super();
  // make root, etc.
}
  }
  document.register('x-button', MyButton);
 
  If so then can we do this in the present:
 
  MyButtonImpl = function() {

 What do you mean here?

MyButton.super();

 Did you get that backwards? I don't see how MyButtonImpl can be
 derived from MyButton.


 Its not. The 'super' means 'the super-class constructor for MyButton
 that does not include magic DOM object generation' (in this case,
 HTMLButtonElement). For MyDerivedButton, MyDerivedButton.super would point
 to MyButtonImpl.

 The existence of MyButtonImpl is an unfortunate side-effect of needing a
 generated constructor.

 The idea is to correspond as closely as possible with the ES6
 version. MyButtonImpl goes away in ES6, it's purpose in the meantime is
 just to provide something that looks like a proper class.

 I could write it this way:

 *MyButton = function() {

   MyButton.super();
   // make root, etc.
 };
 MyButton.prototype = Object.create(HTMLButtonElement, { ... });*
 *
 MyButton = document.register(‘x-button’, MyButton);
 *

 Written this way, MyButton no longer refers to the constructor you
 specified, but instead refers to the generated constructor. This is
 conceptually cleaner, but it's a bit tricky. For maximum clarity, I named
 the internal version MyButtonImpl in my example code, but there is no
 reason to have that symbol.



// make root, etc.
  };
  MyButtonImpl.prototype = Object.create(HTMLButtonElement, { ... });
 
  // the ‘real’ constructor comes from document.register
  // register injects ‘super’ into MyButton
  MyButton = document.register(‘x-button’, MyButtonImpl);

 What is the relationship between MyButton and MyButtonImpl?

 If MyButton.__proto__ === MyButtonImpl and
 MyButton.prototype.__proto__ === MyButtonImpl.prototype then this
 might work (but this cannot be polyfilled either).


 MyButton.prototype == MyButtonImpl.prototype or
 MyButton.prototype.__proto__ == MyButtonImpl.prototype, depending on needs.

 MyButton itself does magic DOM construction work that we cannot do with
 normal inheritance, then invokes MyButtonImpl. MyButtonImpl is never used
 as a constructor itself (not as an argument to 'new' anyway).

 From the user's perspective, he has made a single class which implements
 his element (the goal!). The unfortunate name shenanigan (I called my class
 MyButtonImpl, but after 'register' I refer to it as MyButton) is the
 simplest way I could conceive to overcome the 'generated constructor'
 problem.

 To be clear, everything I come up with is intended to polyfill (modulo
 my error), because I generally am writing those myself (at first anyway).
 One version might look like this:

 document.register = function(inExtends, inClass) {
   var ctor = makePrototypeTwiddlingConstructorForDomNodes(inClass);
   ctor.prototype = inClass.prototype;
   addToTagRegistry(inExtends, ctor, inClass);
   ctor.super = getClassForExtendee(inExtends);
   return ctor;
 };


 --
 erik







Re: document.register and ES6

2013-02-06 Thread Scott Miles
Yes, it's not intended to work in IE ... I used __proto__.


On Wed, Feb 6, 2013 at 12:41 PM, Daniel Buchner dan...@mozilla.com wrote:

 Scott: is this example not intended to work in IE9? It throws, the output
 object is missing the 'oranginate' method.

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Wed, Feb 6, 2013 at 12:32 PM, Scott Miles sjmi...@google.com wrote:

 There were several errors in my pseudo-code, here is a working version:

 http://jsfiddle.net/yNbnL/1/

 S


 On Wed, Feb 6, 2013 at 12:01 PM, Scott Miles sjmi...@google.com wrote:

 Errata:
  makePrototypeTwiddlingConstructorForDomNodes needs to know the extendee

  var ctor = makePrototypeTwiddlingConstructorForDomNodes(inExtends,
 inClass);


 On Wed, Feb 6, 2013 at 11:59 AM, Scott Miles sjmi...@google.com wrote:

 On Wed, Feb 6, 2013 at 11:18 AM, Erik Arvidsson a...@chromium.orgwrote:

 On Wed, Feb 6, 2013 at 1:38 PM, Scott Miles sjmi...@google.com
 wrote:
  Sorry, replace MyButton.super() with MyButton.super.call(this);
 
 
  On Wed, Feb 6, 2013 at 10:37 AM, Scott Miles sjmi...@google.com
 wrote:
 
  So, neglecting issues around the syntax of document.register and the
  privatization of callbacks, is it fair to say the following is the
 intended
  future:
 
  class MyButton extends HTMLButtonElement {
constructor() {
  super();
  // make root, etc.
}
  }
  document.register('x-button', MyButton);
 
  If so then can we do this in the present:
 
  MyButtonImpl = function() {

 What do you mean here?

MyButton.super();

 Did you get that backwards? I don't see how MyButtonImpl can be
 derived from MyButton.


 Its not. The 'super' means 'the super-class constructor for MyButton
 that does not include magic DOM object generation' (in this case,
 HTMLButtonElement). For MyDerivedButton, MyDerivedButton.super would point
 to MyButtonImpl.

 The existence of MyButtonImpl is an unfortunate side-effect of needing
 a generated constructor.

 The idea is to correspond as closely as possible with the ES6
 version. MyButtonImpl goes away in ES6, it's purpose in the meantime is
 just to provide something that looks like a proper class.

 I could write it this way:

 *MyButton = function() {

   MyButton.super();
   // make root, etc.
 };
 MyButton.prototype = Object.create(HTMLButtonElement, { ... });*
 *
 MyButton = document.register(‘x-button’, MyButton);
 *

 Written this way, MyButton no longer refers to the constructor you
 specified, but instead refers to the generated constructor. This is
 conceptually cleaner, but it's a bit tricky. For maximum clarity, I named
 the internal version MyButtonImpl in my example code, but there is no
 reason to have that symbol.



// make root, etc.
  };
  MyButtonImpl.prototype = Object.create(HTMLButtonElement, { ... });
 
  // the ‘real’ constructor comes from document.register
  // register injects ‘super’ into MyButton
  MyButton = document.register(‘x-button’, MyButtonImpl);

 What is the relationship between MyButton and MyButtonImpl?

 If MyButton.__proto__ === MyButtonImpl and
 MyButton.prototype.__proto__ === MyButtonImpl.prototype then this
 might work (but this cannot be polyfilled either).


 MyButton.prototype == MyButtonImpl.prototype or
 MyButton.prototype.__proto__ == MyButtonImpl.prototype, depending on needs.

 MyButton itself does magic DOM construction work that we cannot do with
 normal inheritance, then invokes MyButtonImpl. MyButtonImpl is never used
 as a constructor itself (not as an argument to 'new' anyway).

 From the user's perspective, he has made a single class which
 implements his element (the goal!). The unfortunate name shenanigan (I
 called my class MyButtonImpl, but after 'register' I refer to it as
 MyButton) is the simplest way I could conceive to overcome the 'generated
 constructor' problem.

 To be clear, everything I come up with is intended to polyfill (modulo
 my error), because I generally am writing those myself (at first anyway).
 One version might look like this:

 document.register = function(inExtends, inClass) {
   var ctor = makePrototypeTwiddlingConstructorForDomNodes(inClass);
   ctor.prototype = inClass.prototype;
   addToTagRegistry(inExtends, ctor, inClass);
   ctor.super = getClassForExtendee(inExtends);
   return ctor;
 };


 --
 erik








Re: document.register and ES6

2013-02-06 Thread Scott Miles
Sorry for the flood, but here is another version that shows inheriting from
custom elements (Webkit/FF only).

http://jsfiddle.net/cEmZq/


On Wed, Feb 6, 2013 at 12:43 PM, Scott Miles sjmi...@google.com wrote:

 Yes, it's not intended to work in IE ... I used __proto__.


 On Wed, Feb 6, 2013 at 12:41 PM, Daniel Buchner dan...@mozilla.comwrote:

 Scott: is this example not intended to work in IE9? It throws, the output
 object is missing the 'oranginate' method.

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Wed, Feb 6, 2013 at 12:32 PM, Scott Miles sjmi...@google.com wrote:

 There were several errors in my pseudo-code, here is a working version:

 http://jsfiddle.net/yNbnL/1/

 S


 On Wed, Feb 6, 2013 at 12:01 PM, Scott Miles sjmi...@google.com wrote:

 Errata:
  makePrototypeTwiddlingConstructorForDomNodes needs to know the extendee

  var ctor = makePrototypeTwiddlingConstructorForDomNodes(inExtends,
 inClass);


 On Wed, Feb 6, 2013 at 11:59 AM, Scott Miles sjmi...@google.comwrote:

 On Wed, Feb 6, 2013 at 11:18 AM, Erik Arvidsson a...@chromium.orgwrote:

 On Wed, Feb 6, 2013 at 1:38 PM, Scott Miles sjmi...@google.com
 wrote:
  Sorry, replace MyButton.super() with MyButton.super.call(this);
 
 
  On Wed, Feb 6, 2013 at 10:37 AM, Scott Miles sjmi...@google.com
 wrote:
 
  So, neglecting issues around the syntax of document.register and
 the
  privatization of callbacks, is it fair to say the following is the
 intended
  future:
 
  class MyButton extends HTMLButtonElement {
constructor() {
  super();
  // make root, etc.
}
  }
  document.register('x-button', MyButton);
 
  If so then can we do this in the present:
 
  MyButtonImpl = function() {

 What do you mean here?

MyButton.super();

 Did you get that backwards? I don't see how MyButtonImpl can be
 derived from MyButton.


 Its not. The 'super' means 'the super-class constructor for MyButton
 that does not include magic DOM object generation' (in this case,
 HTMLButtonElement). For MyDerivedButton, MyDerivedButton.super would point
 to MyButtonImpl.

 The existence of MyButtonImpl is an unfortunate side-effect of needing
 a generated constructor.

 The idea is to correspond as closely as possible with the ES6
 version. MyButtonImpl goes away in ES6, it's purpose in the meantime is
 just to provide something that looks like a proper class.

 I could write it this way:

 *MyButton = function() {

   MyButton.super();
   // make root, etc.
 };
 MyButton.prototype = Object.create(HTMLButtonElement, { ... });*
 *
 MyButton = document.register(‘x-button’, MyButton);
 *

 Written this way, MyButton no longer refers to the constructor you
 specified, but instead refers to the generated constructor. This is
 conceptually cleaner, but it's a bit tricky. For maximum clarity, I named
 the internal version MyButtonImpl in my example code, but there is no
 reason to have that symbol.



// make root, etc.
  };
  MyButtonImpl.prototype = Object.create(HTMLButtonElement, { ... });
 
  // the ‘real’ constructor comes from document.register
  // register injects ‘super’ into MyButton
  MyButton = document.register(‘x-button’, MyButtonImpl);

 What is the relationship between MyButton and MyButtonImpl?

 If MyButton.__proto__ === MyButtonImpl and
 MyButton.prototype.__proto__ === MyButtonImpl.prototype then this
 might work (but this cannot be polyfilled either).


 MyButton.prototype == MyButtonImpl.prototype or
 MyButton.prototype.__proto__ == MyButtonImpl.prototype, depending on 
 needs.

 MyButton itself does magic DOM construction work that we cannot do
 with normal inheritance, then invokes MyButtonImpl. MyButtonImpl is never
 used as a constructor itself (not as an argument to 'new' anyway).

 From the user's perspective, he has made a single class which
 implements his element (the goal!). The unfortunate name shenanigan (I
 called my class MyButtonImpl, but after 'register' I refer to it as
 MyButton) is the simplest way I could conceive to overcome the 'generated
 constructor' problem.

 To be clear, everything I come up with is intended to polyfill (modulo
 my error), because I generally am writing those myself (at first anyway).
 One version might look like this:

 document.register = function(inExtends, inClass) {
   var ctor = makePrototypeTwiddlingConstructorForDomNodes(inClass);
   ctor.prototype = inClass.prototype;
   addToTagRegistry(inExtends, ctor, inClass);
   ctor.super = getClassForExtendee(inExtends);
   return ctor;
 };


 --
 erik









Re: document.register and ES6

2013-02-06 Thread Scott Miles
Arg, I messed up the link there. Corrected: http://jsfiddle.net/cEmZq/1/


On Wed, Feb 6, 2013 at 12:47 PM, Scott Miles sjmi...@google.com wrote:

 Sorry for the flood, but here is another version that shows inheriting
 from custom elements (Webkit/FF only).

 http://jsfiddle.net/cEmZq/


 On Wed, Feb 6, 2013 at 12:43 PM, Scott Miles sjmi...@google.com wrote:

 Yes, it's not intended to work in IE ... I used __proto__.


 On Wed, Feb 6, 2013 at 12:41 PM, Daniel Buchner dan...@mozilla.comwrote:

 Scott: is this example not intended to work in IE9? It throws, the
 output object is missing the 'oranginate' method.

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Wed, Feb 6, 2013 at 12:32 PM, Scott Miles sjmi...@google.com wrote:

 There were several errors in my pseudo-code, here is a working version:

 http://jsfiddle.net/yNbnL/1/

 S


 On Wed, Feb 6, 2013 at 12:01 PM, Scott Miles sjmi...@google.comwrote:

 Errata:
  makePrototypeTwiddlingConstructorForDomNodes needs to know the
 extendee

  var ctor = makePrototypeTwiddlingConstructorForDomNodes(inExtends,
 inClass);


 On Wed, Feb 6, 2013 at 11:59 AM, Scott Miles sjmi...@google.comwrote:

 On Wed, Feb 6, 2013 at 11:18 AM, Erik Arvidsson a...@chromium.orgwrote:

 On Wed, Feb 6, 2013 at 1:38 PM, Scott Miles sjmi...@google.com
 wrote:
  Sorry, replace MyButton.super() with MyButton.super.call(this);
 
 
  On Wed, Feb 6, 2013 at 10:37 AM, Scott Miles sjmi...@google.com
 wrote:
 
  So, neglecting issues around the syntax of document.register and
 the
  privatization of callbacks, is it fair to say the following is
 the intended
  future:
 
  class MyButton extends HTMLButtonElement {
constructor() {
  super();
  // make root, etc.
}
  }
  document.register('x-button', MyButton);
 
  If so then can we do this in the present:
 
  MyButtonImpl = function() {

 What do you mean here?

MyButton.super();

 Did you get that backwards? I don't see how MyButtonImpl can be
 derived from MyButton.


 Its not. The 'super' means 'the super-class constructor for MyButton
 that does not include magic DOM object generation' (in this case,
 HTMLButtonElement). For MyDerivedButton, MyDerivedButton.super would 
 point
 to MyButtonImpl.

 The existence of MyButtonImpl is an unfortunate side-effect of
 needing a generated constructor.

 The idea is to correspond as closely as possible with the ES6
 version. MyButtonImpl goes away in ES6, it's purpose in the meantime is
 just to provide something that looks like a proper class.

 I could write it this way:

 *MyButton = function() {

   MyButton.super();
   // make root, etc.
 };
 MyButton.prototype = Object.create(HTMLButtonElement, { ... });*
 *
 MyButton = document.register(‘x-button’, MyButton);
 *

 Written this way, MyButton no longer refers to the constructor you
 specified, but instead refers to the generated constructor. This is
 conceptually cleaner, but it's a bit tricky. For maximum clarity, I named
 the internal version MyButtonImpl in my example code, but there is no
 reason to have that symbol.



// make root, etc.
  };
  MyButtonImpl.prototype = Object.create(HTMLButtonElement, { ...
 });
 
  // the ‘real’ constructor comes from document.register
  // register injects ‘super’ into MyButton
  MyButton = document.register(‘x-button’, MyButtonImpl);

 What is the relationship between MyButton and MyButtonImpl?

 If MyButton.__proto__ === MyButtonImpl and
 MyButton.prototype.__proto__ === MyButtonImpl.prototype then this
 might work (but this cannot be polyfilled either).


 MyButton.prototype == MyButtonImpl.prototype or
 MyButton.prototype.__proto__ == MyButtonImpl.prototype, depending on 
 needs.

 MyButton itself does magic DOM construction work that we cannot do
 with normal inheritance, then invokes MyButtonImpl. MyButtonImpl is never
 used as a constructor itself (not as an argument to 'new' anyway).

 From the user's perspective, he has made a single class which
 implements his element (the goal!). The unfortunate name shenanigan (I
 called my class MyButtonImpl, but after 'register' I refer to it as
 MyButton) is the simplest way I could conceive to overcome the 'generated
 constructor' problem.

 To be clear, everything I come up with is intended to polyfill
 (modulo my error), because I generally am writing those myself (at first
 anyway). One version might look like this:

 document.register = function(inExtends, inClass) {
   var ctor = makePrototypeTwiddlingConstructorForDomNodes(inClass);
   ctor.prototype = inClass.prototype;
   addToTagRegistry(inExtends, ctor, inClass);
   ctor.super = getClassForExtendee(inExtends);
   return ctor;
 };


 --
 erik










Re: document.register and ES6

2013-02-06 Thread Erik Arvidsson
If we are willing to return a new constructor function I think we have
no problems. I was concerned that it would lead to people using the
wrong function but it does solve the issues.

class MyButtonImpl extends HTMLButtonElement {
}
let MyButton = document.register('my-button', {
  class: MyButtonImpl // maybe call the property implementation if
we don't want to use class.
});

I feel like this is getting close to my pain tolerance for boilerplate
code but I'm willing to realize that currently this is the only
working proposal (for polyfilling in __proto__ browser).

I'm still curious how people are planning to do this in non __proto__ browsers?

On Wed, Feb 6, 2013 at 3:43 PM, Scott Miles sjmi...@google.com wrote:
 Yes, it's not intended to work in IE ... I used __proto__.


 On Wed, Feb 6, 2013 at 12:41 PM, Daniel Buchner dan...@mozilla.com wrote:

 Scott: is this example not intended to work in IE9? It throws, the output
 object is missing the 'oranginate' method.

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Wed, Feb 6, 2013 at 12:32 PM, Scott Miles sjmi...@google.com wrote:

 There were several errors in my pseudo-code, here is a working version:

 http://jsfiddle.net/yNbnL/1/

 S


 On Wed, Feb 6, 2013 at 12:01 PM, Scott Miles sjmi...@google.com wrote:

 Errata:
  makePrototypeTwiddlingConstructorForDomNodes needs to know the extendee

 var ctor = makePrototypeTwiddlingConstructorForDomNodes(inExtends,
 inClass);


 On Wed, Feb 6, 2013 at 11:59 AM, Scott Miles sjmi...@google.com wrote:

 On Wed, Feb 6, 2013 at 11:18 AM, Erik Arvidsson a...@chromium.org
 wrote:

 On Wed, Feb 6, 2013 at 1:38 PM, Scott Miles sjmi...@google.com
 wrote:
  Sorry, replace MyButton.super() with MyButton.super.call(this);
 
 
  On Wed, Feb 6, 2013 at 10:37 AM, Scott Miles sjmi...@google.com
  wrote:
 
  So, neglecting issues around the syntax of document.register and
  the
  privatization of callbacks, is it fair to say the following is the
  intended
  future:
 
  class MyButton extends HTMLButtonElement {
constructor() {
  super();
  // make root, etc.
}
  }
  document.register('x-button', MyButton);
 
  If so then can we do this in the present:
 
  MyButtonImpl = function() {

 What do you mean here?

MyButton.super();

 Did you get that backwards? I don't see how MyButtonImpl can be
 derived from MyButton.


 Its not. The 'super' means 'the super-class constructor for MyButton
 that does not include magic DOM object generation' (in this case,
 HTMLButtonElement). For MyDerivedButton, MyDerivedButton.super would point
 to MyButtonImpl.

 The existence of MyButtonImpl is an unfortunate side-effect of needing
 a generated constructor.

 The idea is to correspond as closely as possible with the ES6 version.
 MyButtonImpl goes away in ES6, it's purpose in the meantime is just to
 provide something that looks like a proper class.

 I could write it this way:

 MyButton = function() {

  MyButton.super();
  // make root, etc.
 };
 MyButton.prototype = Object.create(HTMLButtonElement, { ... });
 MyButton = document.register(‘x-button’, MyButton);

 Written this way, MyButton no longer refers to the constructor you
 specified, but instead refers to the generated constructor. This is
 conceptually cleaner, but it's a bit tricky. For maximum clarity, I named
 the internal version MyButtonImpl in my example code, but there is no 
 reason
 to have that symbol.



// make root, etc.
  };
  MyButtonImpl.prototype = Object.create(HTMLButtonElement, { ... });
 
  // the ‘real’ constructor comes from document.register
  // register injects ‘super’ into MyButton
  MyButton = document.register(‘x-button’, MyButtonImpl);

 What is the relationship between MyButton and MyButtonImpl?

 If MyButton.__proto__ === MyButtonImpl and
 MyButton.prototype.__proto__ === MyButtonImpl.prototype then this
 might work (but this cannot be polyfilled either).


 MyButton.prototype == MyButtonImpl.prototype or
 MyButton.prototype.__proto__ == MyButtonImpl.prototype, depending on 
 needs.

 MyButton itself does magic DOM construction work that we cannot do with
 normal inheritance, then invokes MyButtonImpl. MyButtonImpl is never used 
 as
 a constructor itself (not as an argument to 'new' anyway).

 From the user's perspective, he has made a single class which
 implements his element (the goal!). The unfortunate name shenanigan (I
 called my class MyButtonImpl, but after 'register' I refer to it as
 MyButton) is the simplest way I could conceive to overcome the 'generated
 constructor' problem.

 To be clear, everything I come up with is intended to polyfill (modulo
 my error), because I generally am writing those myself (at first anyway).
 One version might look like this:

 document.register = function(inExtends, inClass) {
   var ctor = makePrototypeTwiddlingConstructorForDomNodes(inClass);
   ctor.prototype = inClass.prototype;
   addToTagRegistry(inExtends, ctor, inClass);
   ctor.super = 

Re: document.register and ES6

2013-02-06 Thread Scott Miles
Afaik, the 'generated constructor' is technical debt we are stuck with
until we can actually invoke DOM constructors from JS. If there is a better
way around it, I'm all ears!

polyfilling without __proto__: I don't know if it's possible, which is a
good point. I was basically ignoring that problem, but I guess I should not
do that: we may have to utterly change our target.

Iow, perhaps we can decorate node instances with API scraped off of a
separate prototype chain. Ironically, this is close to what my component
sugaring layer does anyway, in order to support protected API.

S


On Wed, Feb 6, 2013 at 12:50 PM, Erik Arvidsson a...@chromium.org wrote:

 If we are willing to return a new constructor function I think we have
 no problems. I was concerned that it would lead to people using the
 wrong function but it does solve the issues.

 class MyButtonImpl extends HTMLButtonElement {
 }
 let MyButton = document.register('my-button', {
   class: MyButtonImpl // maybe call the property implementation if
 we don't want to use class.
 });

 I feel like this is getting close to my pain tolerance for boilerplate
 code but I'm willing to realize that currently this is the only
 working proposal (for polyfilling in __proto__ browser).

 I'm still curious how people are planning to do this in non __proto__
 browsers?

 On Wed, Feb 6, 2013 at 3:43 PM, Scott Miles sjmi...@google.com wrote:
  Yes, it's not intended to work in IE ... I used __proto__.
 
 
  On Wed, Feb 6, 2013 at 12:41 PM, Daniel Buchner dan...@mozilla.com
 wrote:
 
  Scott: is this example not intended to work in IE9? It throws, the
 output
  object is missing the 'oranginate' method.
 
  Daniel J. Buchner
  Product Manager, Developer Ecosystem
  Mozilla Corporation
 
 
  On Wed, Feb 6, 2013 at 12:32 PM, Scott Miles sjmi...@google.com
 wrote:
 
  There were several errors in my pseudo-code, here is a working version:
 
  http://jsfiddle.net/yNbnL/1/
 
  S
 
 
  On Wed, Feb 6, 2013 at 12:01 PM, Scott Miles sjmi...@google.com
 wrote:
 
  Errata:
   makePrototypeTwiddlingConstructorForDomNodes needs to know the
 extendee
 
  var ctor = makePrototypeTwiddlingConstructorForDomNodes(inExtends,
  inClass);
 
 
  On Wed, Feb 6, 2013 at 11:59 AM, Scott Miles sjmi...@google.com
 wrote:
 
  On Wed, Feb 6, 2013 at 11:18 AM, Erik Arvidsson a...@chromium.org
  wrote:
 
  On Wed, Feb 6, 2013 at 1:38 PM, Scott Miles sjmi...@google.com
  wrote:
   Sorry, replace MyButton.super() with MyButton.super.call(this);
  
  
   On Wed, Feb 6, 2013 at 10:37 AM, Scott Miles sjmi...@google.com
   wrote:
  
   So, neglecting issues around the syntax of document.register and
   the
   privatization of callbacks, is it fair to say the following is
 the
   intended
   future:
  
   class MyButton extends HTMLButtonElement {
 constructor() {
   super();
   // make root, etc.
 }
   }
   document.register('x-button', MyButton);
  
   If so then can we do this in the present:
  
   MyButtonImpl = function() {
 
  What do you mean here?
 
 MyButton.super();
 
  Did you get that backwards? I don't see how MyButtonImpl can be
  derived from MyButton.
 
 
  Its not. The 'super' means 'the super-class constructor for MyButton
  that does not include magic DOM object generation' (in this case,
  HTMLButtonElement). For MyDerivedButton, MyDerivedButton.super would
 point
  to MyButtonImpl.
 
  The existence of MyButtonImpl is an unfortunate side-effect of
 needing
  a generated constructor.
 
  The idea is to correspond as closely as possible with the ES6
 version.
  MyButtonImpl goes away in ES6, it's purpose in the meantime is just
 to
  provide something that looks like a proper class.
 
  I could write it this way:
 
  MyButton = function() {
 
   MyButton.super();
   // make root, etc.
  };
  MyButton.prototype = Object.create(HTMLButtonElement, { ... });
  MyButton = document.register(‘x-button’, MyButton);
 
  Written this way, MyButton no longer refers to the constructor you
  specified, but instead refers to the generated constructor. This is
  conceptually cleaner, but it's a bit tricky. For maximum clarity, I
 named
  the internal version MyButtonImpl in my example code, but there is
 no reason
  to have that symbol.
 
 
 
 // make root, etc.
   };
   MyButtonImpl.prototype = Object.create(HTMLButtonElement, { ...
 });
  
   // the ‘real’ constructor comes from document.register
   // register injects ‘super’ into MyButton
   MyButton = document.register(‘x-button’, MyButtonImpl);
 
  What is the relationship between MyButton and MyButtonImpl?
 
  If MyButton.__proto__ === MyButtonImpl and
  MyButton.prototype.__proto__ === MyButtonImpl.prototype then this
  might work (but this cannot be polyfilled either).
 
 
  MyButton.prototype == MyButtonImpl.prototype or
  MyButton.prototype.__proto__ == MyButtonImpl.prototype, depending on
 needs.
 
  MyButton itself does magic DOM construction work that we cannot do
 with
  normal inheritance, then invokes 

Re: document.register and ES6

2013-02-06 Thread Scott Miles
Well, this (non-robust quicky test) works in IE:

http://jsfiddle.net/zUzCx/1/


On Wed, Feb 6, 2013 at 12:59 PM, Scott Miles sjmi...@google.com wrote:

 Afaik, the 'generated constructor' is technical debt we are stuck with
 until we can actually invoke DOM constructors from JS. If there is a better
 way around it, I'm all ears!

 polyfilling without __proto__: I don't know if it's possible, which is a
 good point. I was basically ignoring that problem, but I guess I should not
 do that: we may have to utterly change our target.

 Iow, perhaps we can decorate node instances with API scraped off of a
 separate prototype chain. Ironically, this is close to what my component
 sugaring layer does anyway, in order to support protected API.

 S


 On Wed, Feb 6, 2013 at 12:50 PM, Erik Arvidsson a...@chromium.org wrote:

 If we are willing to return a new constructor function I think we have
 no problems. I was concerned that it would lead to people using the
 wrong function but it does solve the issues.

 class MyButtonImpl extends HTMLButtonElement {
 }
 let MyButton = document.register('my-button', {
   class: MyButtonImpl // maybe call the property implementation if
 we don't want to use class.
 });

 I feel like this is getting close to my pain tolerance for boilerplate
 code but I'm willing to realize that currently this is the only
 working proposal (for polyfilling in __proto__ browser).

 I'm still curious how people are planning to do this in non __proto__
 browsers?

 On Wed, Feb 6, 2013 at 3:43 PM, Scott Miles sjmi...@google.com wrote:
  Yes, it's not intended to work in IE ... I used __proto__.
 
 
  On Wed, Feb 6, 2013 at 12:41 PM, Daniel Buchner dan...@mozilla.com
 wrote:
 
  Scott: is this example not intended to work in IE9? It throws, the
 output
  object is missing the 'oranginate' method.
 
  Daniel J. Buchner
  Product Manager, Developer Ecosystem
  Mozilla Corporation
 
 
  On Wed, Feb 6, 2013 at 12:32 PM, Scott Miles sjmi...@google.com
 wrote:
 
  There were several errors in my pseudo-code, here is a working
 version:
 
  http://jsfiddle.net/yNbnL/1/
 
  S
 
 
  On Wed, Feb 6, 2013 at 12:01 PM, Scott Miles sjmi...@google.com
 wrote:
 
  Errata:
   makePrototypeTwiddlingConstructorForDomNodes needs to know the
 extendee
 
  var ctor = makePrototypeTwiddlingConstructorForDomNodes(inExtends,
  inClass);
 
 
  On Wed, Feb 6, 2013 at 11:59 AM, Scott Miles sjmi...@google.com
 wrote:
 
  On Wed, Feb 6, 2013 at 11:18 AM, Erik Arvidsson a...@chromium.org
  wrote:
 
  On Wed, Feb 6, 2013 at 1:38 PM, Scott Miles sjmi...@google.com
  wrote:
   Sorry, replace MyButton.super() with MyButton.super.call(this);
  
  
   On Wed, Feb 6, 2013 at 10:37 AM, Scott Miles sjmi...@google.com
 
   wrote:
  
   So, neglecting issues around the syntax of document.register and
   the
   privatization of callbacks, is it fair to say the following is
 the
   intended
   future:
  
   class MyButton extends HTMLButtonElement {
 constructor() {
   super();
   // make root, etc.
 }
   }
   document.register('x-button', MyButton);
  
   If so then can we do this in the present:
  
   MyButtonImpl = function() {
 
  What do you mean here?
 
 MyButton.super();
 
  Did you get that backwards? I don't see how MyButtonImpl can be
  derived from MyButton.
 
 
  Its not. The 'super' means 'the super-class constructor for MyButton
  that does not include magic DOM object generation' (in this case,
  HTMLButtonElement). For MyDerivedButton, MyDerivedButton.super
 would point
  to MyButtonImpl.
 
  The existence of MyButtonImpl is an unfortunate side-effect of
 needing
  a generated constructor.
 
  The idea is to correspond as closely as possible with the ES6
 version.
  MyButtonImpl goes away in ES6, it's purpose in the meantime is just
 to
  provide something that looks like a proper class.
 
  I could write it this way:
 
  MyButton = function() {
 
   MyButton.super();
   // make root, etc.
  };
  MyButton.prototype = Object.create(HTMLButtonElement, { ... });
  MyButton = document.register(‘x-button’, MyButton);
 
  Written this way, MyButton no longer refers to the constructor you
  specified, but instead refers to the generated constructor. This is
  conceptually cleaner, but it's a bit tricky. For maximum clarity, I
 named
  the internal version MyButtonImpl in my example code, but there is
 no reason
  to have that symbol.
 
 
 
 // make root, etc.
   };
   MyButtonImpl.prototype = Object.create(HTMLButtonElement, { ...
 });
  
   // the ‘real’ constructor comes from document.register
   // register injects ‘super’ into MyButton
   MyButton = document.register(‘x-button’, MyButtonImpl);
 
  What is the relationship between MyButton and MyButtonImpl?
 
  If MyButton.__proto__ === MyButtonImpl and
  MyButton.prototype.__proto__ === MyButtonImpl.prototype then this
  might work (but this cannot be polyfilled either).
 
 
  MyButton.prototype == MyButtonImpl.prototype or
  MyButton.prototype.__proto__ 

Re: document.register and ES6

2013-02-06 Thread Daniel Buchner
So you're directly setting the user-added methods on matched elements in
browsers that don't support proto, but what about accessors?

If we modified the spec (as previously suggested) to take an *unbaked*
prototype object, we could polyfill all property types:

var myButton = document.register('x-mybutton', {
prototype: {
foo: {
set: function(){ ... },
get: function(){ ... }
}
}
});

Equipped with the unbaked prototype descriptor, in your upgrade phase, you
should be able to simply bake the node with:
Object.defineProperties(element, unbakedPrototypeDescriptor) - right?

Daniel J. Buchner
Product Manager, Developer Ecosystem
Mozilla Corporation


On Wed, Feb 6, 2013 at 1:07 PM, Scott Miles sjmi...@google.com wrote:

 Well, this (non-robust quicky test) works in IE:

 http://jsfiddle.net/zUzCx/1/


 On Wed, Feb 6, 2013 at 12:59 PM, Scott Miles sjmi...@google.com wrote:

 Afaik, the 'generated constructor' is technical debt we are stuck with
 until we can actually invoke DOM constructors from JS. If there is a better
 way around it, I'm all ears!

 polyfilling without __proto__: I don't know if it's possible, which is a
 good point. I was basically ignoring that problem, but I guess I should not
 do that: we may have to utterly change our target.

 Iow, perhaps we can decorate node instances with API scraped off of a
 separate prototype chain. Ironically, this is close to what my component
 sugaring layer does anyway, in order to support protected API.

 S


 On Wed, Feb 6, 2013 at 12:50 PM, Erik Arvidsson a...@chromium.org wrote:

 If we are willing to return a new constructor function I think we have
 no problems. I was concerned that it would lead to people using the
 wrong function but it does solve the issues.

 class MyButtonImpl extends HTMLButtonElement {
 }
 let MyButton = document.register('my-button', {
   class: MyButtonImpl // maybe call the property implementation if
 we don't want to use class.
 });

 I feel like this is getting close to my pain tolerance for boilerplate
 code but I'm willing to realize that currently this is the only
 working proposal (for polyfilling in __proto__ browser).

 I'm still curious how people are planning to do this in non __proto__
 browsers?

 On Wed, Feb 6, 2013 at 3:43 PM, Scott Miles sjmi...@google.com wrote:
  Yes, it's not intended to work in IE ... I used __proto__.
 
 
  On Wed, Feb 6, 2013 at 12:41 PM, Daniel Buchner dan...@mozilla.com
 wrote:
 
  Scott: is this example not intended to work in IE9? It throws, the
 output
  object is missing the 'oranginate' method.
 
  Daniel J. Buchner
  Product Manager, Developer Ecosystem
  Mozilla Corporation
 
 
  On Wed, Feb 6, 2013 at 12:32 PM, Scott Miles sjmi...@google.com
 wrote:
 
  There were several errors in my pseudo-code, here is a working
 version:
 
  http://jsfiddle.net/yNbnL/1/
 
  S
 
 
  On Wed, Feb 6, 2013 at 12:01 PM, Scott Miles sjmi...@google.com
 wrote:
 
  Errata:
   makePrototypeTwiddlingConstructorForDomNodes needs to know the
 extendee
 
  var ctor = makePrototypeTwiddlingConstructorForDomNodes(inExtends,
  inClass);
 
 
  On Wed, Feb 6, 2013 at 11:59 AM, Scott Miles sjmi...@google.com
 wrote:
 
  On Wed, Feb 6, 2013 at 11:18 AM, Erik Arvidsson a...@chromium.org
  wrote:
 
  On Wed, Feb 6, 2013 at 1:38 PM, Scott Miles sjmi...@google.com
  wrote:
   Sorry, replace MyButton.super() with MyButton.super.call(this);
  
  
   On Wed, Feb 6, 2013 at 10:37 AM, Scott Miles 
 sjmi...@google.com
   wrote:
  
   So, neglecting issues around the syntax of document.register
 and
   the
   privatization of callbacks, is it fair to say the following is
 the
   intended
   future:
  
   class MyButton extends HTMLButtonElement {
 constructor() {
   super();
   // make root, etc.
 }
   }
   document.register('x-button', MyButton);
  
   If so then can we do this in the present:
  
   MyButtonImpl = function() {
 
  What do you mean here?
 
 MyButton.super();
 
  Did you get that backwards? I don't see how MyButtonImpl can be
  derived from MyButton.
 
 
  Its not. The 'super' means 'the super-class constructor for
 MyButton
  that does not include magic DOM object generation' (in this case,
  HTMLButtonElement). For MyDerivedButton, MyDerivedButton.super
 would point
  to MyButtonImpl.
 
  The existence of MyButtonImpl is an unfortunate side-effect of
 needing
  a generated constructor.
 
  The idea is to correspond as closely as possible with the ES6
 version.
  MyButtonImpl goes away in ES6, it's purpose in the meantime is
 just to
  provide something that looks like a proper class.
 
  I could write it this way:
 
  MyButton = function() {
 
   MyButton.super();
   // make root, etc.
  };
  MyButton.prototype = Object.create(HTMLButtonElement, { ... });
  MyButton = document.register(‘x-button’, MyButton);
 
  Written this way, MyButton no longer refers to the constructor you
  specified, but instead refers to the generated constructor. 

Re: document.register and ES6

2013-02-06 Thread Scott Miles
On Wed, Feb 6, 2013 at 1:27 PM, Daniel Buchner dan...@mozilla.com wrote:

 So you're directly setting the user-added methods on matched elements in
 browsers that don't support proto, but what about accessors?


I believe those can be forwarded too, I just didn't bother in my fiddle.


 Equipped with the unbaked prototype descriptor, in your upgrade phase, you
 should be able to simply bake the node with:
 Object.defineProperties(element, unbakedPrototypeDescriptor) - right?


Yes, but I believe developers would freak out if we required them to
provide that type of descriptor (I would).

 snip


Re: document.register and ES6

2013-02-06 Thread Erik Arvidsson
On Wed, Feb 6, 2013 at 4:27 PM, Daniel Buchner dan...@mozilla.com wrote:
 So you're directly setting the user-added methods on matched elements in
 browsers that don't support proto, but what about accessors?

 If we modified the spec (as previously suggested) to take an *unbaked*
 prototype object, we could polyfill all property types:

Just use the dedicated syntax. Using property descriptor is an anti
pattern. We must not expose new APIs that PDs.


 var myButton = document.register('x-mybutton', {
 prototype: {
 foo: {
 set: function(){ ... },
 get: function(){ ... }
 }
 }
 });

var myButton = document.register('x-mybutton', {
  prototype: {
get foo() { ... },
set foo(v) { ... }
  }
});


--
erik



Re: document.register and ES6

2013-02-06 Thread Daniel Buchner
I just made sure it worked, and it does. As for developers freaking out, I
really don't believe they would. If that was the case,
Object.defineProperties should be causing a global pandemic of
whopperdeveloper freakouts (
http://www.youtube.com/watch?v=IhF6Kr4ITNQ).

This would give us easy IE compat for the whole range of property types,
and I'm willing to all but guarantee developers will have a bigger freakout
about not having IE9 support than the prototype property of
document.register taking both a baked and unbaked object.

Daniel J. Buchner
Product Manager, Developer Ecosystem
Mozilla Corporation


On Wed, Feb 6, 2013 at 1:34 PM, Scott Miles sjmi...@google.com wrote:

 On Wed, Feb 6, 2013 at 1:27 PM, Daniel Buchner dan...@mozilla.com wrote:

 So you're directly setting the user-added methods on matched elements in
 browsers that don't support proto, but what about accessors?


 I believe those can be forwarded too, I just didn't bother in my fiddle.


 Equipped with the unbaked prototype descriptor, in your upgrade phase,
 you should be able to simply bake the node with:
 Object.defineProperties(element, unbakedPrototypeDescriptor) - right?


 Yes, but I believe developers would freak out if we required them to
 provide that type of descriptor (I would).

  snip



Re: document.register and ES6

2013-02-06 Thread Scott Miles
Remember where we started: absurdly clean ES6 class syntax.

Requiring class definition class using property descriptors is a radical
march in the other direction.

I'm hardcore about syntactical tidiness. The reason I'm not freaking out
about defineProperties is IMO because I can avoid it when I don't need it
(which is about 99% of the time).

Scott

On Wed, Feb 6, 2013 at 1:50 PM, Daniel Buchner dan...@mozilla.com wrote:

 I just made sure it worked, and it does. As for developers freaking out, I
 really don't believe they would. If that was the case,
 Object.defineProperties should be causing a global pandemic of 
 whopperdeveloper freakouts (
 http://www.youtube.com/watch?v=IhF6Kr4ITNQ).

 This would give us easy IE compat for the whole range of property types,
 and I'm willing to all but guarantee developers will have a bigger freakout
 about not having IE9 support than the prototype property of
 document.register taking both a baked and unbaked object.

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Wed, Feb 6, 2013 at 1:34 PM, Scott Miles sjmi...@google.com wrote:

 On Wed, Feb 6, 2013 at 1:27 PM, Daniel Buchner dan...@mozilla.comwrote:

 So you're directly setting the user-added methods on matched elements in
 browsers that don't support proto, but what about accessors?


 I believe those can be forwarded too, I just didn't bother in my fiddle.


 Equipped with the unbaked prototype descriptor, in your upgrade phase,
 you should be able to simply bake the node with:
 Object.defineProperties(element, unbakedPrototypeDescriptor) - right?


 Yes, but I believe developers would freak out if we required them to
 provide that type of descriptor (I would).

  snip





Re: document.register and ES6

2013-02-06 Thread Daniel Buchner
I guess it isn't a show stopper for poly-*ish*-fills, I would just wrap the
native document.register method where it is present  sniff the incoming
prototype property value to detect whether it was baked  cache the unbaked
prototype  then pass a baked one to the native method.

Of course this means we'll (I'll) be evangelizing a polyfill with a
slightly augmented wrapper for taking unbaked objects, but for IE
compatibility devs will probably offer their first born, so I doubt they'll
bat an eye at such a benign incongruity.

Daniel J. Buchner
Product Manager, Developer Ecosystem
Mozilla Corporation


On Wed, Feb 6, 2013 at 2:01 PM, Scott Miles sjmi...@google.com wrote:

 Remember where we started: absurdly clean ES6 class syntax.

 Requiring class definition class using property descriptors is a radical
 march in the other direction.

 I'm hardcore about syntactical tidiness. The reason I'm not freaking out
 about defineProperties is IMO because I can avoid it when I don't need it
 (which is about 99% of the time).

 Scott


 On Wed, Feb 6, 2013 at 1:50 PM, Daniel Buchner dan...@mozilla.com wrote:

 I just made sure it worked, and it does. As for developers freaking out,
 I really don't believe they would. If that was the case,
 Object.defineProperties should be causing a global pandemic of 
 whopperdeveloper freakouts (
 http://www.youtube.com/watch?v=IhF6Kr4ITNQ).

 This would give us easy IE compat for the whole range of property types,
 and I'm willing to all but guarantee developers will have a bigger freakout
 about not having IE9 support than the prototype property of
 document.register taking both a baked and unbaked object.

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Wed, Feb 6, 2013 at 1:34 PM, Scott Miles sjmi...@google.com wrote:

 On Wed, Feb 6, 2013 at 1:27 PM, Daniel Buchner dan...@mozilla.comwrote:

 So you're directly setting the user-added methods on matched elements
 in browsers that don't support proto, but what about accessors?


 I believe those can be forwarded too, I just didn't bother in my fiddle.


 Equipped with the unbaked prototype descriptor, in your upgrade phase,
 you should be able to simply bake the node with:
 Object.defineProperties(element, unbakedPrototypeDescriptor) - right?


 Yes, but I believe developers would freak out if we required them to
 provide that type of descriptor (I would).

  snip






Re: document.register and ES6

2013-02-06 Thread Scott Miles
Seems like you decided that descriptor syntax is *necessary* for IE
compatibility. I'm 80% sure it is not.

S


On Wed, Feb 6, 2013 at 2:10 PM, Daniel Buchner dan...@mozilla.com wrote:

 I guess it isn't a show stopper for poly-*ish*-fills, I would just wrap
 the native document.register method where it is present  sniff the
 incoming prototype property value to detect whether it was baked  cache
 the unbaked prototype  then pass a baked one to the native method.

 Of course this means we'll (I'll) be evangelizing a polyfill with a
 slightly augmented wrapper for taking unbaked objects, but for IE
 compatibility devs will probably offer their first born, so I doubt they'll
 bat an eye at such a benign incongruity.

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Wed, Feb 6, 2013 at 2:01 PM, Scott Miles sjmi...@google.com wrote:

 Remember where we started: absurdly clean ES6 class syntax.

 Requiring class definition class using property descriptors is a radical
 march in the other direction.

 I'm hardcore about syntactical tidiness. The reason I'm not freaking out
 about defineProperties is IMO because I can avoid it when I don't need it
 (which is about 99% of the time).

 Scott


 On Wed, Feb 6, 2013 at 1:50 PM, Daniel Buchner dan...@mozilla.comwrote:

 I just made sure it worked, and it does. As for developers freaking out,
 I really don't believe they would. If that was the case,
 Object.defineProperties should be causing a global pandemic of 
 whopperdeveloper freakouts (
 http://www.youtube.com/watch?v=IhF6Kr4ITNQ).

 This would give us easy IE compat for the whole range of property types,
 and I'm willing to all but guarantee developers will have a bigger freakout
 about not having IE9 support than the prototype property of
 document.register taking both a baked and unbaked object.

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Wed, Feb 6, 2013 at 1:34 PM, Scott Miles sjmi...@google.com wrote:

 On Wed, Feb 6, 2013 at 1:27 PM, Daniel Buchner dan...@mozilla.comwrote:

 So you're directly setting the user-added methods on matched elements
 in browsers that don't support proto, but what about accessors?


 I believe those can be forwarded too, I just didn't bother in my fiddle.


 Equipped with the unbaked prototype descriptor, in your upgrade phase,
 you should be able to simply bake the node with:
 Object.defineProperties(element, unbakedPrototypeDescriptor) - right?


 Yes, but I believe developers would freak out if we required them to
 provide that type of descriptor (I would).

  snip







Re: document.register and ES6

2013-02-06 Thread Daniel Buchner
Short of running Object.getOwnPropertyNames on the existing node  then
iterating over each to grab the property descriptor with
Object.getOwnPropertyDescriptor to rebuild an unbaked object  and finally
setting the properties with Object.setProperties, I am unaware of how to do
so - is there an easier way? If so I would love to not do the above or go
the unbaked object allowance wrapper route :)

Daniel J. Buchner
Product Manager, Developer Ecosystem
Mozilla Corporation


On Wed, Feb 6, 2013 at 2:28 PM, Scott Miles sjmi...@google.com wrote:

 Seems like you decided that descriptor syntax is *necessary* for IE
 compatibility. I'm 80% sure it is not.

 S


 On Wed, Feb 6, 2013 at 2:10 PM, Daniel Buchner dan...@mozilla.com wrote:

 I guess it isn't a show stopper for poly-*ish*-fills, I would just wrap
 the native document.register method where it is present  sniff the
 incoming prototype property value to detect whether it was baked  cache
 the unbaked prototype  then pass a baked one to the native method.

 Of course this means we'll (I'll) be evangelizing a polyfill with a
 slightly augmented wrapper for taking unbaked objects, but for IE
 compatibility devs will probably offer their first born, so I doubt they'll
 bat an eye at such a benign incongruity.

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Wed, Feb 6, 2013 at 2:01 PM, Scott Miles sjmi...@google.com wrote:

 Remember where we started: absurdly clean ES6 class syntax.

 Requiring class definition class using property descriptors is a radical
 march in the other direction.

 I'm hardcore about syntactical tidiness. The reason I'm not freaking out
 about defineProperties is IMO because I can avoid it when I don't need it
 (which is about 99% of the time).

 Scott


 On Wed, Feb 6, 2013 at 1:50 PM, Daniel Buchner dan...@mozilla.comwrote:

 I just made sure it worked, and it does. As for developers freaking
 out, I really don't believe they would. If that was the case,
 Object.defineProperties should be causing a global pandemic of 
 whopperdeveloper freakouts (
 http://www.youtube.com/watch?v=IhF6Kr4ITNQ).

 This would give us easy IE compat for the whole range of property
 types, and I'm willing to all but guarantee developers will have a bigger
 freakout about not having IE9 support than the prototype property of
 document.register taking both a baked and unbaked object.

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Wed, Feb 6, 2013 at 1:34 PM, Scott Miles sjmi...@google.com wrote:

 On Wed, Feb 6, 2013 at 1:27 PM, Daniel Buchner dan...@mozilla.comwrote:

 So you're directly setting the user-added methods on matched elements
 in browsers that don't support proto, but what about accessors?


 I believe those can be forwarded too, I just didn't bother in my
 fiddle.


 Equipped with the unbaked prototype descriptor, in your upgrade
 phase, you should be able to simply bake the node with:
 Object.defineProperties(element, unbakedPrototypeDescriptor) - right?


 Yes, but I believe developers would freak out if we required them to
 provide that type of descriptor (I would).

  snip








Re: document.register and ES6

2013-02-06 Thread Scott Miles
If that works, then what's the problem? It only need be done once per
component.

I'm still confused, because it seems to me that 'unbaked object allowance
route' == components only work in IE if specified using tortured syntax.

That's no bueno IMO.


On Wed, Feb 6, 2013 at 2:41 PM, Daniel Buchner dan...@mozilla.com wrote:

 Short of running Object.getOwnPropertyNames on the existing node  then
 iterating over each to grab the property descriptor with
 Object.getOwnPropertyDescriptor to rebuild an unbaked object  and finally
 setting the properties with Object.setProperties, I am unaware of how to do
 so - is there an easier way? If so I would love to not do the above or go
 the unbaked object allowance wrapper route :)

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Wed, Feb 6, 2013 at 2:28 PM, Scott Miles sjmi...@google.com wrote:

 Seems like you decided that descriptor syntax is *necessary* for IE
 compatibility. I'm 80% sure it is not.

 S


 On Wed, Feb 6, 2013 at 2:10 PM, Daniel Buchner dan...@mozilla.comwrote:

 I guess it isn't a show stopper for poly-*ish*-fills, I would just wrap
 the native document.register method where it is present  sniff the
 incoming prototype property value to detect whether it was baked  cache
 the unbaked prototype  then pass a baked one to the native method.

 Of course this means we'll (I'll) be evangelizing a polyfill with a
 slightly augmented wrapper for taking unbaked objects, but for IE
 compatibility devs will probably offer their first born, so I doubt they'll
 bat an eye at such a benign incongruity.

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Wed, Feb 6, 2013 at 2:01 PM, Scott Miles sjmi...@google.com wrote:

 Remember where we started: absurdly clean ES6 class syntax.

 Requiring class definition class using property descriptors is a
 radical march in the other direction.

 I'm hardcore about syntactical tidiness. The reason I'm not freaking
 out about defineProperties is IMO because I can avoid it when I don't need
 it (which is about 99% of the time).

 Scott


 On Wed, Feb 6, 2013 at 1:50 PM, Daniel Buchner dan...@mozilla.comwrote:

 I just made sure it worked, and it does. As for developers freaking
 out, I really don't believe they would. If that was the case,
 Object.defineProperties should be causing a global pandemic of 
 whopperdeveloper freakouts (
 http://www.youtube.com/watch?v=IhF6Kr4ITNQ).

 This would give us easy IE compat for the whole range of property
 types, and I'm willing to all but guarantee developers will have a bigger
 freakout about not having IE9 support than the prototype property of
 document.register taking both a baked and unbaked object.

 Daniel J. Buchner
 Product Manager, Developer Ecosystem
 Mozilla Corporation


 On Wed, Feb 6, 2013 at 1:34 PM, Scott Miles sjmi...@google.comwrote:

 On Wed, Feb 6, 2013 at 1:27 PM, Daniel Buchner dan...@mozilla.comwrote:

 So you're directly setting the user-added methods on matched
 elements in browsers that don't support proto, but what about accessors?


 I believe those can be forwarded too, I just didn't bother in my
 fiddle.


 Equipped with the unbaked prototype descriptor, in your upgrade
 phase, you should be able to simply bake the node with:
 Object.defineProperties(element, unbakedPrototypeDescriptor) - right?


 Yes, but I believe developers would freak out if we required them to
 provide that type of descriptor (I would).

  snip









document.register and ES6

2013-02-05 Thread Erik Arvidsson
The way document.register is currently proposed makes it
future-hostile to ES6. I've heard several people from different
organizations say that this is a blocking issue.

Over the last couple of days we (me, Dimitri and others) have worked
on some alterations to the current spec proposal. The discussion got
pretty extensive so I'll try to summarize the main points.

https://www.w3.org/Bugs/Public/show_bug.cgi?id=20831

With ES6 we really want to be able to write code like this:

class MyButton extends HTMLButtonElement {
  ...
}
document.register('x-button', MyButton);

In ES6 speak, we have split the new Foo(...args) expression into
Foo.call(Foo[@@create](), ...args) which means that creating the
instance has been separated from the call to the function. This allows
us to subclass Array etc. It also opens up possibilities to subclass
Element. All Element need is a @@create method that creates the
instance (and sets the internal pointer to the underlying C++ object
like we do today). For custom elements we can therefore generate the
@@create method for the function passed to document.register. This
function would create an instance in the same way as previously speced
at 
https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn-custom-element-instantiation

== What about ES5/3? ==

In ES5/3 speak we don't have the @@create refactoring but we do have
an internal [[Construct]] method. In the reformed version of
document.create we can override [[Construct]] of the passed in
function to create the instance and then do the [[Call]].

This also means API change from what is currently specified. Instead of

document.register(‘x-button’, { prototype:
Object.create(HTMLButtonElement.prototype, {
  ...
});

We will have:

function MyButton() {
  HTMLButtonElement.call(this);
  // yay, I can have a real constructor!
  // do constructor stuff ...
}
MyButton.prototype = Object.create(HTMLButtonElement.prototype, {
  ...
});
document.register(‘x-button’, MyButton);

We think it’s much better, because:
a) we no longer have to spit out some magic generated constructor
b) we can let developers have a constructor in their custom element
c) there will be no API changes when ES6 classes arrive
d) there is no longer a need for crazy callbacks “created” and
“shadowRootCreated”, because they can just be code in the constructor

== Does this mean that the user code now runs while parsing? ==

We’ve heard in the past that allowing user code execution while the
parser is building a tree is undesirable due to performance and
specific design issues. However, now that the custom element
constructor is no longer generated, it may appear as if the
user-specified constructor would run when each element is
instantiated.

We intend to address this as follows:
* When the parser builds a tree, it only creates underlying C++ objects
* Just before entering script,
* we first instantiate all custom elements (think Object.create, but
with all the baggage of being a wrapper around a C++ object), so that
they all have the right prototype chains, in tree order
* then, we invoke the respective internal [[Call]] methods of all
custom elements, in tree order

How does template fit into this?

The dependencies on template and shadow DOM are now removed from
document.register API. If people want to use a template and shadow DOM
they can easily do this in code:

class MyButton extends HTMLButtonElement {
  constructor() {
super();
var template = ...
var shadowRoot = this.createShadowRoot();
shadowRoot.appendChild(template.content.cloneNode(true));
  }
}
document.register('x-button', MyButton);


--
erik



Re: document.register and ES6

2013-02-05 Thread Boris Zbarsky

On 2/5/13 10:12 PM, Erik Arvidsson wrote:

In ES6 speak, we have split the new Foo(...args) expression into
Foo.call(Foo[@@create](), ...args) which means that creating the
instance has been separated from the call to the function.


So in particular this allows creation of uninitialized instances in 
some sense, yes?



function MyButton() {
   HTMLButtonElement.call(this);


This won't work right given how HTMLButtonElement is currently defined 
in WebIDL.  Need to fix that at the very least.



MyButton.prototype = Object.create(HTMLButtonElement.prototype, {
   ...
});
document.register(‘x-button’, MyButton);


And the point is that document.register changes the [[Construct]] of 
MyButton but does nothing else with it?


What happens if the same function is registered for several different 
tag names, in terms of what happens with the [[Construct]]?



* Just before entering script,


Define, please.  How does one determine this, in a rendering engine 
implementation?  I certainly have no way to tell, in Gecko, when I'm 
entering script, offhand


-Boris



Re: document.register and ES6

2013-02-05 Thread Erik Arvidsson
On Tue, Feb 5, 2013 at 5:28 PM, Boris Zbarsky bzbar...@mit.edu wrote:
 So in particular this allows creation of uninitialized instances in some
 sense, yes?

Depends how much logic is put in the constructor vs @@create. For DOM
Elements I think we want to put *all* the logic in create. @@create
does not allow any parameters so for Image for example, we want to put
the src, width and height handling in the constructor. I don't think
there is any problem here.

 This won't work right given how HTMLButtonElement is currently defined in
 WebIDL.  Need to fix that at the very least.

Yes, but for document.register I think we can get away without
changing this. We might need to add no op call methods to these
functions but that seems like the right thing to do anyway. The WebIDL
interface constructors are already strange as they are and I doubt
anyone would object to making them less strange.



 MyButton.prototype = Object.create(HTMLButtonElement.prototype, {
...
 });
 document.register(‘x-button’, MyButton);


 And the point is that document.register changes the [[Construct]] of
 MyButton but does nothing else with it?

Yes.

 What happens if the same function is registered for several different tag
 names, in terms of what happens with the [[Construct]]?

I vote for throwing. We could allow the tag name to be used as an
alias but I don't really understand the use case you have in mind
here.

 * Just before entering script,

 Define, please.  How does one determine this, in a rendering engine
 implementation?  I certainly have no way to tell, in Gecko, when I'm
 entering script, offhand

I was told this is needed for mutation observers that are queued up
during parse. I'll let Dimitri or Rafael chime in with details.

--
erik



Re: document.register and ES6

2013-02-05 Thread Boris Zbarsky

On 2/5/13 11:01 PM, Erik Arvidsson wrote:

On Tue, Feb 5, 2013 at 5:28 PM, Boris Zbarsky bzbar...@mit.edu wrote:

So in particular this allows creation of uninitialized instances in some
sense, yes?


Depends how much logic is put in the constructor vs @@create. For DOM
Elements I think we want to put *all* the logic in create.


OK, I can live with that as long as the only arguments are things like 
for Image.  We'll have to be pretty careful about how we define our 
Element subclass constructors in the future, though...


And there are knock-on effects on all other objects in WebIDL.  See below.


This won't work right given how HTMLButtonElement is currently defined in
WebIDL.  Need to fix that at the very least.


Yes, but for document.register I think we can get away without
changing this.


No, you can't.  You really need to get WebIDL fixed here.


We might need to add no op call methods to these
functions


They already have [[Call]].  What they don't have is a custom 
[[Construct]].  Which means that they end up invoking the [[Construct]] 
defined in ES5 section 13.2.2, which in step 8 calls the [[Call]] and if 
that returns an object (which the WebIDL [[Call]] does) throws away the 
object that [[construct]] just created and returns the object [[Call]] 
returned.


And you can't no-op the [[Call]] because web pages, afaik, use things like:

  var myImage = Image();

and

  var xhr = XMLHttpRequest();

just like they use Date() and Object() and Array().  The above is 
supported for DOM constructors in at least Gecko and Presto, though 
apparently not Chrome or Safari; I don't have IE to test right now.  But 
the point is that right now those constructors are not particularly 
weird in Gecko and Presto, and I'm not entirely happy making them _more_ 
weird.


Maybe the fact that Chrome and Safari don't support this means that we 
can in fact redefine the [[Construct]] to create the right sort of 
object and then invoke [[Call]] which will actually initialize the 
object.  But that brings us back to being able to create 
partially-initialized objects for all IDL interfaces, not just elements


Perhaps we need to define an IDL annotation for interfaces that opt in 
to this split between [[Call]] and [[Construct]] and then have elements 
opt in to it?



but that seems like the right thing to do anyway. The WebIDL
interface constructors are already strange as they are


Not in Gecko and Presto as far as I can tell...  Certainly not any 
stranger than Date or Array.



and I doubt anyone would object to making them less strange.


I have no problem with less strange, but you're proposing more strange. 
 Again, as far as I can tell.



What happens if the same function is registered for several different tag
names, in terms of what happens with the [[Construct]]?


I vote for throwing. We could allow the tag name to be used as an
alias but I don't really understand the use case you have in mind
here.


I don't have a use case.  What I have is an edge case that I can see 
implementations doing random non-interoperable crap for if we don't 
define it.


Throwing sounds fine to me.


Define, please.  How does one determine this, in a rendering engine
implementation?  I certainly have no way to tell, in Gecko, when I'm
entering script, offhand


I was told this is needed for mutation observers that are queued up
during parse. I'll let Dimitri or Rafael chime in with details.


Ah, OK.  Defining this stuff to happen at end of microtask or whatever 
it is that normally triggers mutation observers makes a lot more sense 
than before entering script.  ;)


Thanks,
Boris




Re: document.register and ES6

2013-02-05 Thread Rafael Weinstein
On Tue, Feb 5, 2013 at 3:25 PM, Boris Zbarsky bzbar...@mit.edu wrote:

 On 2/5/13 11:01 PM, Erik Arvidsson wrote:

 On Tue, Feb 5, 2013 at 5:28 PM, Boris Zbarsky bzbar...@mit.edu wrote:

 So in particular this allows creation of uninitialized instances in
 some
 sense, yes?


 Depends how much logic is put in the constructor vs @@create. For DOM
 Elements I think we want to put *all* the logic in create.


 OK, I can live with that as long as the only arguments are things like for
 Image.  We'll have to be pretty careful about how we define our Element
 subclass constructors in the future, though...

 And there are knock-on effects on all other objects in WebIDL.  See below.


  This won't work right given how HTMLButtonElement is currently defined in
 WebIDL.  Need to fix that at the very least.


 Yes, but for document.register I think we can get away without
 changing this.


 No, you can't.  You really need to get WebIDL fixed here.


  We might need to add no op call methods to these
 functions


 They already have [[Call]].  What they don't have is a custom
 [[Construct]].  Which means that they end up invoking the [[Construct]]
 defined in ES5 section 13.2.2, which in step 8 calls the [[Call]] and if
 that returns an object (which the WebIDL [[Call]] does) throws away the
 object that [[construct]] just created and returns the object [[Call]]
 returned.

 And you can't no-op the [[Call]] because web pages, afaik, use things like:

   var myImage = Image();

 and

   var xhr = XMLHttpRequest();

 just like they use Date() and Object() and Array().  The above is
 supported for DOM constructors in at least Gecko and Presto, though
 apparently not Chrome or Safari; I don't have IE to test right now.  But
 the point is that right now those constructors are not particularly weird
 in Gecko and Presto, and I'm not entirely happy making them _more_ weird.

 Maybe the fact that Chrome and Safari don't support this means that we can
 in fact redefine the [[Construct]] to create the right sort of object and
 then invoke [[Call]] which will actually initialize the object.  But that
 brings us back to being able to create partially-initialized objects for
 all IDL interfaces, not just elements

 Perhaps we need to define an IDL annotation for interfaces that opt in to
 this split between [[Call]] and [[Construct]] and then have elements opt in
 to it?


  but that seems like the right thing to do anyway. The WebIDL
 interface constructors are already strange as they are


 Not in Gecko and Presto as far as I can tell...  Certainly not any
 stranger than Date or Array.


  and I doubt anyone would object to making them less strange.


 I have no problem with less strange, but you're proposing more strange.
  Again, as far as I can tell.


  What happens if the same function is registered for several different tag
 names, in terms of what happens with the [[Construct]]?


 I vote for throwing. We could allow the tag name to be used as an
 alias but I don't really understand the use case you have in mind
 here.


 I don't have a use case.  What I have is an edge case that I can see
 implementations doing random non-interoperable crap for if we don't define
 it.

 Throwing sounds fine to me.


  Define, please.  How does one determine this, in a rendering engine
 implementation?  I certainly have no way to tell, in Gecko, when I'm
 entering script, offhand


 I was told this is needed for mutation observers that are queued up
 during parse. I'll let Dimitri or Rafael chime in with details.


 Ah, OK.  Defining this stuff to happen at end of microtask or whatever it
 is that normally triggers mutation observers makes a lot more sense than
 before entering script.  ;)


http://www.whatwg.org/specs/web-apps/current-work/#parsing-main-incdata

The first thing that happens upon encoutering /script is performing a
microtask check point.

I think Arv is suggesting that running custom element constructors would be
included in this work.


 Thanks,
 Boris




Re: document.register and ES6

2013-02-05 Thread Daniel Buchner
I have two questions:

   1. Does this affect our ability to polyfill doc.register in current
   browsers?
   2. Are you saying we're going to nix the ability to easily register
   insertion, removal, and attribute change callbacks from the API?

I believe #2 is very important and should not be discarded, while #1 is
simply a deal breaker. Can you explain how your proposal accounts for these
concerns?

- Daniel

Daniel J. Buchner
Product Manager, Developer Ecosystem
Mozilla Corporation


On Tue, Feb 5, 2013 at 2:12 PM, Erik Arvidsson a...@chromium.org wrote:

 The way document.register is currently proposed makes it
 future-hostile to ES6. I've heard several people from different
 organizations say that this is a blocking issue.

 Over the last couple of days we (me, Dimitri and others) have worked
 on some alterations to the current spec proposal. The discussion got
 pretty extensive so I'll try to summarize the main points.

 https://www.w3.org/Bugs/Public/show_bug.cgi?id=20831

 With ES6 we really want to be able to write code like this:

 class MyButton extends HTMLButtonElement {
   ...
 }
 document.register('x-button', MyButton);

 In ES6 speak, we have split the new Foo(...args) expression into
 Foo.call(Foo[@@create](), ...args) which means that creating the
 instance has been separated from the call to the function. This allows
 us to subclass Array etc. It also opens up possibilities to subclass
 Element. All Element need is a @@create method that creates the
 instance (and sets the internal pointer to the underlying C++ object
 like we do today). For custom elements we can therefore generate the
 @@create method for the function passed to document.register. This
 function would create an instance in the same way as previously speced
 at
 https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn-custom-element-instantiation

 == What about ES5/3? ==

 In ES5/3 speak we don't have the @@create refactoring but we do have
 an internal [[Construct]] method. In the reformed version of
 document.create we can override [[Construct]] of the passed in
 function to create the instance and then do the [[Call]].

 This also means API change from what is currently specified. Instead of

 document.register(‘x-button’, { prototype:
 Object.create(HTMLButtonElement.prototype, {
   ...
 });

 We will have:

 function MyButton() {
   HTMLButtonElement.call(this);
   // yay, I can have a real constructor!
   // do constructor stuff ...
 }
 MyButton.prototype = Object.create(HTMLButtonElement.prototype, {
   ...
 });
 document.register(‘x-button’, MyButton);

 We think it’s much better, because:
 a) we no longer have to spit out some magic generated constructor
 b) we can let developers have a constructor in their custom element
 c) there will be no API changes when ES6 classes arrive
 d) there is no longer a need for crazy callbacks “created” and
 “shadowRootCreated”, because they can just be code in the constructor

 == Does this mean that the user code now runs while parsing? ==

 We’ve heard in the past that allowing user code execution while the
 parser is building a tree is undesirable due to performance and
 specific design issues. However, now that the custom element
 constructor is no longer generated, it may appear as if the
 user-specified constructor would run when each element is
 instantiated.

 We intend to address this as follows:
 * When the parser builds a tree, it only creates underlying C++ objects
 * Just before entering script,
 * we first instantiate all custom elements (think Object.create, but
 with all the baggage of being a wrapper around a C++ object), so that
 they all have the right prototype chains, in tree order
 * then, we invoke the respective internal [[Call]] methods of all
 custom elements, in tree order

 How does template fit into this?

 The dependencies on template and shadow DOM are now removed from
 document.register API. If people want to use a template and shadow DOM
 they can easily do this in code:

 class MyButton extends HTMLButtonElement {
   constructor() {
 super();
 var template = ...
 var shadowRoot = this.createShadowRoot();
 shadowRoot.appendChild(template.content.cloneNode(true));
   }
 }
 document.register('x-button', MyButton);


 --
 erik



Re: document.register and ES6

2013-02-05 Thread Daniel Buchner
*
So this won't work?*

var MyButton = document.register(‘x-mybutton’, {
prototype: Object.create(HTMLButtonElement.prototype, { ... })
});
class MySuperButton extends MyButton { ... };
document.register('x-superbutton', MySuperButton);

*But this will?*

function MyButton() {
  HTMLButtonElement.call(this);
  // yay, I can have a real constructor!
  // do constructor stuff ...
}
MyButton.prototype = Object.create(HTMLButtonElement.prototype, {
  ...
});
document.register(‘x-button’, MyButton);

Can someone reply with a terse pro/con/gain/loss list that identifies what
parts of the current API (and its behavior) this proposal affects?

Daniel J. Buchner
Product Manager, Developer Ecosystem
Mozilla Corporation


On Tue, Feb 5, 2013 at 2:12 PM, Erik Arvidsson a...@chromium.org wrote:

 The way document.register is currently proposed makes it
 future-hostile to ES6. I've heard several people from different
 organizations say that this is a blocking issue.

 Over the last couple of days we (me, Dimitri and others) have worked
 on some alterations to the current spec proposal. The discussion got
 pretty extensive so I'll try to summarize the main points.

 https://www.w3.org/Bugs/Public/show_bug.cgi?id=20831

 With ES6 we really want to be able to write code like this:

 class MyButton extends HTMLButtonElement {
   ...
 }
 document.register('x-button', MyButton);

 In ES6 speak, we have split the new Foo(...args) expression into
 Foo.call(Foo[@@create](), ...args) which means that creating the
 instance has been separated from the call to the function. This allows
 us to subclass Array etc. It also opens up possibilities to subclass
 Element. All Element need is a @@create method that creates the
 instance (and sets the internal pointer to the underlying C++ object
 like we do today). For custom elements we can therefore generate the
 @@create method for the function passed to document.register. This
 function would create an instance in the same way as previously speced
 at
 https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn-custom-element-instantiation

 == What about ES5/3? ==

 In ES5/3 speak we don't have the @@create refactoring but we do have
 an internal [[Construct]] method. In the reformed version of
 document.create we can override [[Construct]] of the passed in
 function to create the instance and then do the [[Call]].

 This also means API change from what is currently specified. Instead of

 document.register(‘x-button’, { prototype:
 Object.create(HTMLButtonElement.prototype, {
   ...
 });

 We will have:

 function MyButton() {
   HTMLButtonElement.call(this);
   // yay, I can have a real constructor!
   // do constructor stuff ...
 }
 MyButton.prototype = Object.create(HTMLButtonElement.prototype, {
   ...
 });
 document.register(‘x-button’, MyButton);

 We think it’s much better, because:
 a) we no longer have to spit out some magic generated constructor
 b) we can let developers have a constructor in their custom element
 c) there will be no API changes when ES6 classes arrive
 d) there is no longer a need for crazy callbacks “created” and
 “shadowRootCreated”, because they can just be code in the constructor

 == Does this mean that the user code now runs while parsing? ==

 We’ve heard in the past that allowing user code execution while the
 parser is building a tree is undesirable due to performance and
 specific design issues. However, now that the custom element
 constructor is no longer generated, it may appear as if the
 user-specified constructor would run when each element is
 instantiated.

 We intend to address this as follows:
 * When the parser builds a tree, it only creates underlying C++ objects
 * Just before entering script,
 * we first instantiate all custom elements (think Object.create, but
 with all the baggage of being a wrapper around a C++ object), so that
 they all have the right prototype chains, in tree order
 * then, we invoke the respective internal [[Call]] methods of all
 custom elements, in tree order

 How does template fit into this?

 The dependencies on template and shadow DOM are now removed from
 document.register API. If people want to use a template and shadow DOM
 they can easily do this in code:

 class MyButton extends HTMLButtonElement {
   constructor() {
 super();
 var template = ...
 var shadowRoot = this.createShadowRoot();
 shadowRoot.appendChild(template.content.cloneNode(true));
   }
 }
 document.register('x-button', MyButton);


 --
 erik