Re: [webcomponents]: Platonic form of custom elements declarative syntax
*Shouldn't we prevent such a thing? I can't redefine a button's template. There should be some guarantee I'm getting the same x-foo (API, look and feel) after it's been registered. What's the use case for swapping in a new template?* We've come across various occasions where we have a custom element, let's say it's an x-todo, that has multiple content/view states (not something achievable by a simple class/style change). There may be 200 of these elements in a summary view in the list panel of the page in question. When the user performs an action that requires an x-todo in summary view to display a more complex, detail view, we've found that the easiest way to reuse elements, make the change in the least amount of code, and avoid the cumbersome and repetitive paradigm of creating specific x-todo-summary and x-todo-detail elements for this purpose, is to simply have two different template elements for each view type. The views can be radically different in structure and visual style - yet thanks to our ability to simply swap out the template association on the specific x-todo in question, the whole thing is a snap: myTodoElement.template = 'detail-template'; Does this help clarify a bit? On Wed, Apr 10, 2013 at 10:05 PM, Eric Bidelman ericbidel...@google.comwrote: Have to lean towards Raf and Daniel on this one. Making a element registation a concern of template doesn't feel right. In this case, explicit structure and a few more characters is worth it. On Wed, Apr 10, 2013 at 9:00 PM, Daniel Buchner dan...@mozilla.comwrote: It's incredibly important that we agree that association of a template with element happens on the element side, something like: element template=foo-template (or by placing the template inside element, if that is the API we want). I don't think this part is opinion, but because doing the reverse - marking on the template which element it refers to - hinders a few valid use-cases: - one template from being used by many different elements - changing a template association on a single instance of an element type - say you have an x-foo on the page that you want to switch template associations on, but not for every other x-foo in the document. Wouldn't this case be far more clear cut if you could just query for the element and change some property? For instance: fooElement.template = 'foo-template-2'; Boom! This particular foo element just switched templates. Shouldn't we prevent such a thing? I can't redefine a button's template. There should be some guarantee I'm getting the same x-foo (API, look and feel) after it's been registered. What's the use case for swapping in a new template? - On Wed, Apr 10, 2013 at 8:19 PM, Daniel Buchner dan...@mozilla.comwrote: Here are a few (compelling?) answers/arguments: 1. Style elements had never done this before, yet it rocks socks: style scoped 2. It would be new for script elements, but hardly new for other elements. There are plenty of elements that have various behaviors or visual representations only when placed inside specific elements. Given this is already an advanced web API, I'm not sure a little upfront learning is a huge concern. We could even allow for this, given the paradigm is already established: script scoped *// could scope 'this' ref to the parentNode* 3. Are you referring to template attachment here? If so, I agree, thus the proposal I submitted allows for both ( https://gist.github.com/csuwldcat/5360471). If you want your template automatically associated with your element, put it inside, if not, you can specify which template a custom element should use by reference to its ID. On Wed, Apr 10, 2013 at 8:00 PM, John J Barton johnjbar...@johnjbarton.com wrote: On Wed, Apr 10, 2013 at 6:51 PM, Dimitri Glazkov dglaz...@google.comwrote: On Wed, Apr 10, 2013 at 6:38 PM, Rick Waldron waldron.r...@gmail.com wrote: Everyone's answer to this should be no; changing the expected value of the top level this, in some magical way, simply won't work. Can you explain why you feel this way? 1) Because script has never done this before, so it better be compelling. 2) Because causing |this| to change by moving the script tag in the HTML or adding a layer of elements etc seems likely to cause hard to understand bugs. 3) Forcing the binding based on position is inflexible. To be sure this is implicit-declarative vs explicit-imperative bias, not evidence. Oh, sorry you were asking Rick. jjb
Re: [webcomponents]: Platonic form of custom elements declarative syntax
Hi Allen, Fortunately the state of this is pretty close to what you are suggesting. We started of with the imperative solution and then went to look at a declarative version. At this point, the discussion got a bit side tracked. Lets back up and see what we have for the imperative version: class MyElement extends HTMLElement { constructor() { ... } insertedCallback() { // now I'm in document } attributeChangedCallback(name, value) { // ... } doFunkyThing() { // ... } } // And tell the browser about this new shiny element document.register('my-element, MyElement); Fast forward... For the declarative version we want to be able to associate a template element to be used as the shadow dom for the custom element. We went around in circles here and this thread was an attempt to start at a different starting point to see where we would end up. We initially had (plus/minus irrelevant details) element name=my-element template This is my shadow DOM content/content /template script class MyElement extends HTMLElement { ... } // We need a convenient way to register ('my-element, MyElement) here /script /element More inline... On Thu, Apr 11, 2013 at 2:14 AM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: On Apr 10, 2013, at 8:47 PM, Rick Waldron wrote: cc Allen Wirfs-Brock, Dave Herman Allen, Dave Would you mind reading back through the thread to provide some deeper insight? Thanks Rick ECMAScript really has a very simply concept of 'this' out-side of a function. It is a reference to the global object. In all other cases 'this' occurs within a function body and is bound as part of a function innovation. It would be a significant change to the ECMAScript semantics that are applied to 'this' the content of script tags. I'm sure, it would only cause confusion. Unfortunately NodeJS broke this invariant already. `this` inside a module that has been required is a not the [[Global]] object. This has caused me a lot of personal porting pain so I agree we must not break this invariant on the web. I'm not at all up on the details and subtitles of what you are trying to do with your tempaltes, but regardless, I want to suggest an alternative approach that I'm pretty sure in the long run would be more natural for JavaScript programmers. It seems to me, what you are doing with templates is allowing user to define new kinds of DOM nodes and that when you stamp out a template you are instantiating new instances of that kind of node. In programming language terms, you are enabling markup authors to declarative define new classes of DOM nodes and to create instance of those classes. The script behaviors you need to associate with a template are essentially the methods of the user defined classes. Rather than twisting around the interpretation of 'this' in template script blocks and inventing other one-off extensions, it would be much better to recognize this class-based approach and just let the user define the class. Using ES6 syntax this could be very easy: template bindtotagname=my_yay shadowroot divYay!/div /shadowroot script class My_yay extends TemplatedNode { constructor () { // runs when instances are created, can create per instance properties // can be left out if nothing special is required } whenBond(...args) { super(...args); invoke default behavior inherited from TemplatedNode // my_yay specific behavior // in methods 'this' binds to an instance } anotherMethods() { // other instance methods, properties of My_yay.prototype } static anotherStaticMethods() { } //properties of My_yay } /script /template Many details to work out, but I hope the intent is clear. You just define a JS class corresponding to the template instances. There may be a standard template interface with methods such as withBond that are support. Defaut implementations can be provided by a built-in super class. This can all be expresses, but less clearly and concisely using ES3/5 syntax. But since we are talking about a new HTML feature, I'd recommend being the first major HTMLfeature to embrace ES6 class syntax. The class extension in ES6 are quite stable and quite easy to implement. I'm pretty sure they will begin appearing in browsers sometime in the next 6 months. If webcomponents takes a dependency upon them, it would probably further speed up their implementation. The problem here is how do you register `My_yay` as the class that goes with the tag name `my_yay`. One option could be to use the completion value but it seems too magical/unreliable. It also does not scale well. I would like us to be able to put
Re: [webcomponents]: Platonic form of custom elements declarative syntax
On Thu, Apr 11, 2013 at 7:57 AM, Erik Arvidsson a...@chromium.org wrote: The problem here is how do you register `My_yay` as the class that goes with the tag name `my_yay`. One option could be to use the completion value but it seems too magical/unreliable. It also does not scale well. I would like us to be able to put all custom component classes in a single js file: element name=my-foo ... /element element name=my-bar ... /element element name=my-baz ... /element script src=my-elements.js/script // my-elements.js someDocument.querySelector('[name=my-foo]').registerConstructor(MyFoo); someDocument.querySelector('[name=my-bar]').registerConstructor(MyBar); someDocument.querySelector('[name=my-baz]').registerConstructor(MyBaz); This calls out for a less verbose and more DRY API. To me this seems to defeat modularity. Force me to organize all of MyFoo JS/HTML/CSS together and separate from MyBar and MyBaz. I already can create a big messy pile. Help me clean up my room. jjb
Re: [webcomponents]: Platonic form of custom elements declarative syntax
On 4/11/13 12:23 PM, Allen Wirfs-Brock wrote: So why don't you make register a static method on HTMLElement and then define the element semantics so it automatically does: MyElement.register() This would normally invoke the inherited static method I lost track of something here. Why would it do that? Does MyElement have Element on its proto chain? MyElement.prototype certainly has Element.prototype on _its_ proto chain, but that's a separate concern from what happens with the interface objects... Is this something that ES6 classes define differently from current WebIDL and implementations, and if so, do we need to align the two somehow? -Boris
Re: [webcomponents]: Platonic form of custom elements declarative syntax
On Apr 11, 2013, at 9:32 AM, Boris Zbarsky wrote: On 4/11/13 12:23 PM, Allen Wirfs-Brock wrote: So why don't you make register a static method on HTMLElement and then define the element semantics so it automatically does: MyElement.register() This would normally invoke the inherited static method I lost track of something here. Why would it do that? Does MyElement have Element on its proto chain? MyElement.prototype certainly has Element.prototype on _its_ proto chain, but that's a separate concern from what happens with the interface objects... Is this something that ES6 classes define differently from current WebIDL and implementations, and if so, do we need to align the two somehow? Yes ES6 has class-side inheritance. The ES5 equivalent for: class Sub extends Super { constructor() {/*constructor body */ } method1 () {} static method2 {} } is: function Sub() {/*constructor body */ } Sub.__proto__ = Super; Sub.prototype = Object.create(Super.prototype); Sub.prototype.method1 = function method1() {}; Sub.method2 = function method2 () {}; Sub.foo looks first looks for a own property on Sub, then on Super, etc. Allen
Re: [webcomponents]: Platonic form of custom elements declarative syntax
On 4/11/13 12:50 PM, Allen Wirfs-Brock wrote: Yes ES6 has class-side inheritance OK. Should we be doing that with WebIDL interface objects, perhaps? It would certainly make sense to me to do that, as long we we don't run into web compat issues. -Boris
Re: [webcomponents]: Platonic form of custom elements declarative syntax
On 4/11/13 12:55 PM, Boris Zbarsky wrote: On 4/11/13 12:50 PM, Allen Wirfs-Brock wrote: Yes ES6 has class-side inheritance OK. Should we be doing that with WebIDL interface objects, perhaps? It would certainly make sense to me to do that, as long we we don't run into web compat issues. I've filed https://bugzilla.mozilla.org/show_bug.cgi?id=860841 with a patch to do this. The specific behavior I'm implementing is that the prototype of the interface object for interface X is the interface object of the nearest ancestor of X that has one, and Function.prototype if there is no such ancestor. So for example, with that patch Object.getPrototypeOf(HTMLElement) == Element, and Object.getPrototypeOf(XMLHttpRequest) == EventTarget. Note that this doesn't quite match the proto chain, because Object.getPrototypeOf(XMLHttpRequest.prototype) is the prototype object for the XMLHttpRequestEventTarget interface, but that interface is [NoInterfaceObject]. -Boris
Re: [webcomponents]: Platonic form of custom elements declarative syntax
On Apr 11, 2013, at 12:04 PM, Boris Zbarsky wrote: On 4/11/13 12:55 PM, Boris Zbarsky wrote: On 4/11/13 12:50 PM, Allen Wirfs-Brock wrote: Yes ES6 has class-side inheritance OK. Should we be doing that with WebIDL interface objects, perhaps? It would certainly make sense to me to do that, as long we we don't run into web compat issues. I've filed https://bugzilla.mozilla.org/show_bug.cgi?id=860841 with a patch to do this. The specific behavior I'm implementing is that the prototype of the interface object for interface X is the interface object of the nearest ancestor of X that has one, and Function.prototype if there is no such ancestor. So for example, with that patch Object.getPrototypeOf(HTMLElement) == Element, and Object.getPrototypeOf(XMLHttpRequest) == EventTarget. Note that this doesn't quite match the proto chain, because Object.getPrototypeOf(XMLHttpRequest.prototype) is the prototype object for the XMLHttpRequestEventTarget interface, but that interface is [NoInterfaceObject]. -Boris That sounds about right. In ES6 you will still be able to wire-up arbitrary [[Prototype]] chains on both the instance and constructor-side using Object.create, __proto__ (now part of the standard), and ossibly crazy things via Proxy. But the most concise way to define class-like abstractions is going to be via class declaration. It seem quite desirable that the normal case for such abstractions specified via WebIDL is that they simply follow the ES6 class pattern. Exceptions are fine for legacy or special circumstances. Allen
[webcomponents]: Platonic form of custom elements declarative syntax
Dear Webappsonites, There's been a ton of thinking on what the custom elements declarative syntax must look like. Here, I present something has near-ideal developer ergonomics at the expense of terrible sins in other areas. Consider it to be beacon, rather than a concrete proposal. First, let's cleanse your palate. Forget about the element element and what goes inside of it. Eat some parsley. == Templates Bound to Tags == Instead, suppose you only have a template: template divYay!/div /template Templates are good for stamping things out, right? So let's invent a way to _bind_ a template to a _tag_. When the browser sees a tag to which the template is bound, it stamps the template out. Like so: 1) Define a template and bind it to a tag name: template bindtotagname=my-yay divYay!/div /template 2) Whenever my-yay is seen by the parser or createElement/NS(my-yay) is called, the template is stamped out to produce: my-yay divYay!/div /my-yay Cool! This is immediately useful for web developers. They can transform any markup into something they can use. Behind the scenes: the presence of boundtotagname triggers a call to document.register, and the argument is a browser-generated prototype object whose readyCallback takes the template and appends it to this. == Organic Shadow Trees == But what if they also wanted to employ encapsulation boundaries, leaving initial markup structure intact? No problem, much-maligned shadowroot to the rescue: 1) Define a template with a shadow tree and bind it to a tag name: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot /template 2) For each my-yay created, the template is stamped out to create a shadow root and populate it. Super-cool! Note, how the developer doesn't have to know anything about Shadow DOM to build custom elements (er, template-bound tags). Shadow trees are just an option. Behind the scenes: exactly the same as the first scenario. == Declarative Meets Imperative == Now, the developer wants to add some APIs to my-yay. Sure, no problem: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot script runwhenbound // runs right after document.register is triggered this.register(ExactSyntaxTBD); script /template So-cool-it-hurts! We built a fully functional custom element, taking small steps from an extremely simple concept to the full-blown thing. In the process, we also saw a completely decoupled shadow DOM from custom elements in both imperative and declarative forms, achieving singularity. Well, or at least a high degree of consistence. == Problems == There are severe issues. The shadowroot is turning out to be super-magical. The bindtotagname attribute will need to be also magical, to be consistent with how document.register could be used. The stamping out, after clearly specified, may raise eyebrows and turn out to be unintuitive. Templates are supposed to be inert, but the whole script runwhenbound thing is strongly negating this. There's probably more that I can't remember now. == Plea == However, I am hopeful that you smart folk will look at this, see the light, tweak the idea just a bit and hit the homerun. See the light, dammit! :DG
Re: [webcomponents]: Platonic form of custom elements declarative syntax
Thank you for distilling all that down into digestible content (yum, distillates). A couple of notes: The 'magic script' problem has been difficult to reconcile with template, so there is willingness to continue to use element, but ideally without nesting template. In other words, perhaps element can be a subtype of template. Where we really get into trouble is when we get into inheritance. I'm happy to discuss this further, but I figure I will wait until people have had time to think about your main content. Scott On Wed, Apr 10, 2013 at 11:47 AM, Dimitri Glazkov dglaz...@google.comwrote: Dear Webappsonites, There's been a ton of thinking on what the custom elements declarative syntax must look like. Here, I present something has near-ideal developer ergonomics at the expense of terrible sins in other areas. Consider it to be beacon, rather than a concrete proposal. First, let's cleanse your palate. Forget about the element element and what goes inside of it. Eat some parsley. == Templates Bound to Tags == Instead, suppose you only have a template: template divYay!/div /template Templates are good for stamping things out, right? So let's invent a way to _bind_ a template to a _tag_. When the browser sees a tag to which the template is bound, it stamps the template out. Like so: 1) Define a template and bind it to a tag name: template bindtotagname=my-yay divYay!/div /template 2) Whenever my-yay is seen by the parser or createElement/NS(my-yay) is called, the template is stamped out to produce: my-yay divYay!/div /my-yay Cool! This is immediately useful for web developers. They can transform any markup into something they can use. Behind the scenes: the presence of boundtotagname triggers a call to document.register, and the argument is a browser-generated prototype object whose readyCallback takes the template and appends it to this. == Organic Shadow Trees == But what if they also wanted to employ encapsulation boundaries, leaving initial markup structure intact? No problem, much-maligned shadowroot to the rescue: 1) Define a template with a shadow tree and bind it to a tag name: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot /template 2) For each my-yay created, the template is stamped out to create a shadow root and populate it. Super-cool! Note, how the developer doesn't have to know anything about Shadow DOM to build custom elements (er, template-bound tags). Shadow trees are just an option. Behind the scenes: exactly the same as the first scenario. == Declarative Meets Imperative == Now, the developer wants to add some APIs to my-yay. Sure, no problem: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot script runwhenbound // runs right after document.register is triggered this.register(ExactSyntaxTBD); script /template So-cool-it-hurts! We built a fully functional custom element, taking small steps from an extremely simple concept to the full-blown thing. In the process, we also saw a completely decoupled shadow DOM from custom elements in both imperative and declarative forms, achieving singularity. Well, or at least a high degree of consistence. == Problems == There are severe issues. The shadowroot is turning out to be super-magical. The bindtotagname attribute will need to be also magical, to be consistent with how document.register could be used. The stamping out, after clearly specified, may raise eyebrows and turn out to be unintuitive. Templates are supposed to be inert, but the whole script runwhenbound thing is strongly negating this. There's probably more that I can't remember now. == Plea == However, I am hopeful that you smart folk will look at this, see the light, tweak the idea just a bit and hit the homerun. See the light, dammit! :DG
Re: [webcomponents]: Platonic form of custom elements declarative syntax
No, strictly ergonomic. Less nesting and less characters (less nesting is more important IMO). I would also argue that there is less cognitive load on the author then the more explicit factoring, but I believe this is subjective. Scott On Wed, Apr 10, 2013 at 12:36 PM, Rafael Weinstein rafa...@google.comwrote: On Wed, Apr 10, 2013 at 11:47 AM, Dimitri Glazkov dglaz...@google.com wrote: Dear Webappsonites, There's been a ton of thinking on what the custom elements declarative syntax must look like. Here, I present something has near-ideal developer ergonomics at the expense of terrible sins in other areas. Consider it to be beacon, rather than a concrete proposal. First, let's cleanse your palate. Forget about the element element and what goes inside of it. Eat some parsley. == Templates Bound to Tags == Instead, suppose you only have a template: template divYay!/div /template Templates are good for stamping things out, right? So let's invent a way to _bind_ a template to a _tag_. When the browser sees a tag to which the template is bound, it stamps the template out. Like so: 1) Define a template and bind it to a tag name: template bindtotagname=my-yay divYay!/div /template 2) Whenever my-yay is seen by the parser or createElement/NS(my-yay) is called, the template is stamped out to produce: my-yay divYay!/div /my-yay Cool! This is immediately useful for web developers. They can transform any markup into something they can use. Behind the scenes: the presence of boundtotagname triggers a call to document.register, and the argument is a browser-generated prototype object whose readyCallback takes the template and appends it to this. == Organic Shadow Trees == But what if they also wanted to employ encapsulation boundaries, leaving initial markup structure intact? No problem, much-maligned shadowroot to the rescue: 1) Define a template with a shadow tree and bind it to a tag name: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot /template 2) For each my-yay created, the template is stamped out to create a shadow root and populate it. Super-cool! Note, how the developer doesn't have to know anything about Shadow DOM to build custom elements (er, template-bound tags). Shadow trees are just an option. Behind the scenes: exactly the same as the first scenario. == Declarative Meets Imperative == Now, the developer wants to add some APIs to my-yay. Sure, no problem: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot script runwhenbound // runs right after document.register is triggered this.register(ExactSyntaxTBD); script /template So-cool-it-hurts! We built a fully functional custom element, taking small steps from an extremely simple concept to the full-blown thing. In the process, we also saw a completely decoupled shadow DOM from custom elements in both imperative and declarative forms, achieving singularity. Well, or at least a high degree of consistence. == Problems == There are severe issues. The shadowroot is turning out to be super-magical. The bindtotagname attribute will need to be also magical, to be consistent with how document.register could be used. The stamping out, after clearly specified, may raise eyebrows and turn out to be unintuitive. Templates are supposed to be inert, but the whole script runwhenbound thing is strongly negating this. There's probably more that I can't remember now. The following expresses the same semantics: element tagname=my-yay template shadowroot divYay!/div /shadowroot /template script runwhenbound /script /element I get that your proposal is fewer characters to type. Are there other advantages? == Plea == However, I am hopeful that you smart folk will look at this, see the light, tweak the idea just a bit and hit the homerun. See the light, dammit! :DG
Re: [webcomponents]: Platonic form of custom elements declarative syntax
I have a counter proposal that takes into a count both the easy-to-declare, 1-to-1 case, as well as the 1-template-to-many-elements case: https://gist.github.com/csuwldcat/5358039 I can explain the advantages a bit more in an hour or so, I just got pulled into a meeting...le sigh. Daniel J. Buchner Product Manager, Developer Ecosystem Mozilla Corporation On Wed, Apr 10, 2013 at 12:40 PM, Scott Miles sjmi...@google.com wrote: No, strictly ergonomic. Less nesting and less characters (less nesting is more important IMO). I would also argue that there is less cognitive load on the author then the more explicit factoring, but I believe this is subjective. Scott On Wed, Apr 10, 2013 at 12:36 PM, Rafael Weinstein rafa...@google.comwrote: On Wed, Apr 10, 2013 at 11:47 AM, Dimitri Glazkov dglaz...@google.com wrote: Dear Webappsonites, There's been a ton of thinking on what the custom elements declarative syntax must look like. Here, I present something has near-ideal developer ergonomics at the expense of terrible sins in other areas. Consider it to be beacon, rather than a concrete proposal. First, let's cleanse your palate. Forget about the element element and what goes inside of it. Eat some parsley. == Templates Bound to Tags == Instead, suppose you only have a template: template divYay!/div /template Templates are good for stamping things out, right? So let's invent a way to _bind_ a template to a _tag_. When the browser sees a tag to which the template is bound, it stamps the template out. Like so: 1) Define a template and bind it to a tag name: template bindtotagname=my-yay divYay!/div /template 2) Whenever my-yay is seen by the parser or createElement/NS(my-yay) is called, the template is stamped out to produce: my-yay divYay!/div /my-yay Cool! This is immediately useful for web developers. They can transform any markup into something they can use. Behind the scenes: the presence of boundtotagname triggers a call to document.register, and the argument is a browser-generated prototype object whose readyCallback takes the template and appends it to this. == Organic Shadow Trees == But what if they also wanted to employ encapsulation boundaries, leaving initial markup structure intact? No problem, much-maligned shadowroot to the rescue: 1) Define a template with a shadow tree and bind it to a tag name: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot /template 2) For each my-yay created, the template is stamped out to create a shadow root and populate it. Super-cool! Note, how the developer doesn't have to know anything about Shadow DOM to build custom elements (er, template-bound tags). Shadow trees are just an option. Behind the scenes: exactly the same as the first scenario. == Declarative Meets Imperative == Now, the developer wants to add some APIs to my-yay. Sure, no problem: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot script runwhenbound // runs right after document.register is triggered this.register(ExactSyntaxTBD); script /template So-cool-it-hurts! We built a fully functional custom element, taking small steps from an extremely simple concept to the full-blown thing. In the process, we also saw a completely decoupled shadow DOM from custom elements in both imperative and declarative forms, achieving singularity. Well, or at least a high degree of consistence. == Problems == There are severe issues. The shadowroot is turning out to be super-magical. The bindtotagname attribute will need to be also magical, to be consistent with how document.register could be used. The stamping out, after clearly specified, may raise eyebrows and turn out to be unintuitive. Templates are supposed to be inert, but the whole script runwhenbound thing is strongly negating this. There's probably more that I can't remember now. The following expresses the same semantics: element tagname=my-yay template shadowroot divYay!/div /shadowroot /template script runwhenbound /script /element I get that your proposal is fewer characters to type. Are there other advantages? == Plea == However, I am hopeful that you smart folk will look at this, see the light, tweak the idea just a bit and hit the homerun. See the light, dammit! :DG
Re: [webcomponents]: Platonic form of custom elements declarative syntax
On Wed, Apr 10, 2013 at 4:15 PM, Daniel Buchner dan...@mozilla.com wrote: I have a counter proposal that takes into a count both the easy-to-declare, 1-to-1 case, as well as the 1-template-to-many-elements case: https://gist.github.com/csuwldcat/5358039 What about CSP that forbids inline scripts? https://wiki.mozilla.org/Apps/Security#Default_CSP_policy Rick I can explain the advantages a bit more in an hour or so, I just got pulled into a meeting...le sigh. Daniel J. Buchner Product Manager, Developer Ecosystem Mozilla Corporation On Wed, Apr 10, 2013 at 12:40 PM, Scott Miles sjmi...@google.com wrote: No, strictly ergonomic. Less nesting and less characters (less nesting is more important IMO). I would also argue that there is less cognitive load on the author then the more explicit factoring, but I believe this is subjective. Scott On Wed, Apr 10, 2013 at 12:36 PM, Rafael Weinstein rafa...@google.comwrote: On Wed, Apr 10, 2013 at 11:47 AM, Dimitri Glazkov dglaz...@google.com wrote: Dear Webappsonites, There's been a ton of thinking on what the custom elements declarative syntax must look like. Here, I present something has near-ideal developer ergonomics at the expense of terrible sins in other areas. Consider it to be beacon, rather than a concrete proposal. First, let's cleanse your palate. Forget about the element element and what goes inside of it. Eat some parsley. == Templates Bound to Tags == Instead, suppose you only have a template: template divYay!/div /template Templates are good for stamping things out, right? So let's invent a way to _bind_ a template to a _tag_. When the browser sees a tag to which the template is bound, it stamps the template out. Like so: 1) Define a template and bind it to a tag name: template bindtotagname=my-yay divYay!/div /template 2) Whenever my-yay is seen by the parser or createElement/NS(my-yay) is called, the template is stamped out to produce: my-yay divYay!/div /my-yay Cool! This is immediately useful for web developers. They can transform any markup into something they can use. Behind the scenes: the presence of boundtotagname triggers a call to document.register, and the argument is a browser-generated prototype object whose readyCallback takes the template and appends it to this. == Organic Shadow Trees == But what if they also wanted to employ encapsulation boundaries, leaving initial markup structure intact? No problem, much-maligned shadowroot to the rescue: 1) Define a template with a shadow tree and bind it to a tag name: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot /template 2) For each my-yay created, the template is stamped out to create a shadow root and populate it. Super-cool! Note, how the developer doesn't have to know anything about Shadow DOM to build custom elements (er, template-bound tags). Shadow trees are just an option. Behind the scenes: exactly the same as the first scenario. == Declarative Meets Imperative == Now, the developer wants to add some APIs to my-yay. Sure, no problem: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot script runwhenbound // runs right after document.register is triggered this.register(ExactSyntaxTBD); script /template So-cool-it-hurts! We built a fully functional custom element, taking small steps from an extremely simple concept to the full-blown thing. In the process, we also saw a completely decoupled shadow DOM from custom elements in both imperative and declarative forms, achieving singularity. Well, or at least a high degree of consistence. == Problems == There are severe issues. The shadowroot is turning out to be super-magical. The bindtotagname attribute will need to be also magical, to be consistent with how document.register could be used. The stamping out, after clearly specified, may raise eyebrows and turn out to be unintuitive. Templates are supposed to be inert, but the whole script runwhenbound thing is strongly negating this. There's probably more that I can't remember now. The following expresses the same semantics: element tagname=my-yay template shadowroot divYay!/div /shadowroot /template script runwhenbound /script /element I get that your proposal is fewer characters to type. Are there other advantages? == Plea == However, I am hopeful that you smart folk will look at this, see the light, tweak the idea just a bit and hit the homerun. See the light, dammit! :DG
Re: [webcomponents]: Platonic form of custom elements declarative syntax
*What about CSP that forbids inline scripts?https://wiki.mozilla.org/Apps/Security#Default_CSP_policy * Is there any reason developers wouldn't just modify the script tag under either method proposed to use src=link-to-non-inline-script to satisfy CSP requirements? The proposal I submitted certainly doesn't exclude that ability/use case (or so I thought - correct if wrong) Daniel J. Buchner Product Manager, Developer Ecosystem Mozilla Corporation On Wed, Apr 10, 2013 at 1:27 PM, Rick Waldron waldron.r...@gmail.comwrote: On Wed, Apr 10, 2013 at 4:15 PM, Daniel Buchner dan...@mozilla.comwrote: I have a counter proposal that takes into a count both the easy-to-declare, 1-to-1 case, as well as the 1-template-to-many-elements case: https://gist.github.com/csuwldcat/5358039 What about CSP that forbids inline scripts? https://wiki.mozilla.org/Apps/Security#Default_CSP_policy Rick I can explain the advantages a bit more in an hour or so, I just got pulled into a meeting...le sigh. Daniel J. Buchner Product Manager, Developer Ecosystem Mozilla Corporation On Wed, Apr 10, 2013 at 12:40 PM, Scott Miles sjmi...@google.com wrote: No, strictly ergonomic. Less nesting and less characters (less nesting is more important IMO). I would also argue that there is less cognitive load on the author then the more explicit factoring, but I believe this is subjective. Scott On Wed, Apr 10, 2013 at 12:36 PM, Rafael Weinstein rafa...@google.comwrote: On Wed, Apr 10, 2013 at 11:47 AM, Dimitri Glazkov dglaz...@google.com wrote: Dear Webappsonites, There's been a ton of thinking on what the custom elements declarative syntax must look like. Here, I present something has near-ideal developer ergonomics at the expense of terrible sins in other areas. Consider it to be beacon, rather than a concrete proposal. First, let's cleanse your palate. Forget about the element element and what goes inside of it. Eat some parsley. == Templates Bound to Tags == Instead, suppose you only have a template: template divYay!/div /template Templates are good for stamping things out, right? So let's invent a way to _bind_ a template to a _tag_. When the browser sees a tag to which the template is bound, it stamps the template out. Like so: 1) Define a template and bind it to a tag name: template bindtotagname=my-yay divYay!/div /template 2) Whenever my-yay is seen by the parser or createElement/NS(my-yay) is called, the template is stamped out to produce: my-yay divYay!/div /my-yay Cool! This is immediately useful for web developers. They can transform any markup into something they can use. Behind the scenes: the presence of boundtotagname triggers a call to document.register, and the argument is a browser-generated prototype object whose readyCallback takes the template and appends it to this. == Organic Shadow Trees == But what if they also wanted to employ encapsulation boundaries, leaving initial markup structure intact? No problem, much-maligned shadowroot to the rescue: 1) Define a template with a shadow tree and bind it to a tag name: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot /template 2) For each my-yay created, the template is stamped out to create a shadow root and populate it. Super-cool! Note, how the developer doesn't have to know anything about Shadow DOM to build custom elements (er, template-bound tags). Shadow trees are just an option. Behind the scenes: exactly the same as the first scenario. == Declarative Meets Imperative == Now, the developer wants to add some APIs to my-yay. Sure, no problem: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot script runwhenbound // runs right after document.register is triggered this.register(ExactSyntaxTBD); script /template So-cool-it-hurts! We built a fully functional custom element, taking small steps from an extremely simple concept to the full-blown thing. In the process, we also saw a completely decoupled shadow DOM from custom elements in both imperative and declarative forms, achieving singularity. Well, or at least a high degree of consistence. == Problems == There are severe issues. The shadowroot is turning out to be super-magical. The bindtotagname attribute will need to be also magical, to be consistent with how document.register could be used. The stamping out, after clearly specified, may raise eyebrows and turn out to be unintuitive. Templates are supposed to be inert, but the whole script runwhenbound thing is strongly negating this. There's probably more that I can't remember now. The following expresses the same semantics: element tagname=my-yay template shadowroot divYay!/div /shadowroot /template
Fwd: [webcomponents]: Platonic form of custom elements declarative syntax
Averting thread-hijacking... CSP is something we'll need to discuss with WebAppsSec peeps at the upcoming F2F. :DG -- Forwarded message -- From: Daniel Buchner dan...@mozilla.com Date: Wed, Apr 10, 2013 at 1:38 PM Subject: Re: [webcomponents]: Platonic form of custom elements declarative syntax To: Rick Waldron waldron.r...@gmail.com Cc: Scott Miles sjmi...@google.com, Rafael Weinstein rafa...@google.com, Dimitri Glazkov dglaz...@google.com, public-webapps public-webapps@w3.org, Blake Kaplan mrb...@mozilla.com, William Chen wc...@mozilla.com, Boris Zbarsky bzbar...@mozilla.com, Jonas Sicking jo...@sicking.cc, Steve Orvell sorv...@google.com What about CSP that forbids inline scripts? https://wiki.mozilla.org/Apps/Security#Default_CSP_policy Is there any reason developers wouldn't just modify the script tag under either method proposed to use src=link-to-non-inline-script to satisfy CSP requirements? The proposal I submitted certainly doesn't exclude that ability/use case (or so I thought - correct if wrong) Daniel J. Buchner Product Manager, Developer Ecosystem Mozilla Corporation On Wed, Apr 10, 2013 at 1:27 PM, Rick Waldron waldron.r...@gmail.com wrote: On Wed, Apr 10, 2013 at 4:15 PM, Daniel Buchner dan...@mozilla.com wrote: I have a counter proposal that takes into a count both the easy-to-declare, 1-to-1 case, as well as the 1-template-to-many-elements case: https://gist.github.com/csuwldcat/5358039 What about CSP that forbids inline scripts? https://wiki.mozilla.org/Apps/Security#Default_CSP_policy Rick I can explain the advantages a bit more in an hour or so, I just got pulled into a meeting...le sigh. Daniel J. Buchner Product Manager, Developer Ecosystem Mozilla Corporation On Wed, Apr 10, 2013 at 12:40 PM, Scott Miles sjmi...@google.com wrote: No, strictly ergonomic. Less nesting and less characters (less nesting is more important IMO). I would also argue that there is less cognitive load on the author then the more explicit factoring, but I believe this is subjective. Scott On Wed, Apr 10, 2013 at 12:36 PM, Rafael Weinstein rafa...@google.com wrote: On Wed, Apr 10, 2013 at 11:47 AM, Dimitri Glazkov dglaz...@google.com wrote: Dear Webappsonites, There's been a ton of thinking on what the custom elements declarative syntax must look like. Here, I present something has near-ideal developer ergonomics at the expense of terrible sins in other areas. Consider it to be beacon, rather than a concrete proposal. First, let's cleanse your palate. Forget about the element element and what goes inside of it. Eat some parsley. == Templates Bound to Tags == Instead, suppose you only have a template: template divYay!/div /template Templates are good for stamping things out, right? So let's invent a way to _bind_ a template to a _tag_. When the browser sees a tag to which the template is bound, it stamps the template out. Like so: 1) Define a template and bind it to a tag name: template bindtotagname=my-yay divYay!/div /template 2) Whenever my-yay is seen by the parser or createElement/NS(my-yay) is called, the template is stamped out to produce: my-yay divYay!/div /my-yay Cool! This is immediately useful for web developers. They can transform any markup into something they can use. Behind the scenes: the presence of boundtotagname triggers a call to document.register, and the argument is a browser-generated prototype object whose readyCallback takes the template and appends it to this. == Organic Shadow Trees == But what if they also wanted to employ encapsulation boundaries, leaving initial markup structure intact? No problem, much-maligned shadowroot to the rescue: 1) Define a template with a shadow tree and bind it to a tag name: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot /template 2) For each my-yay created, the template is stamped out to create a shadow root and populate it. Super-cool! Note, how the developer doesn't have to know anything about Shadow DOM to build custom elements (er, template-bound tags). Shadow trees are just an option. Behind the scenes: exactly the same as the first scenario. == Declarative Meets Imperative == Now, the developer wants to add some APIs to my-yay. Sure, no problem: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot script runwhenbound // runs right after document.register is triggered this.register(ExactSyntaxTBD); script /template So-cool-it-hurts! We built a fully functional custom element, taking small steps from an extremely simple concept to the full-blown thing. In the process, we also saw a completely decoupled shadow DOM from custom elements in both imperative and declarative forms, achieving singularity. Well
Re: [webcomponents]: Platonic form of custom elements declarative syntax
On Wed, Apr 10, 2013 at 4:38 PM, Daniel Buchner dan...@mozilla.com wrote: *What about CSP that forbids inline scripts?https://wiki.mozilla.org/Apps/Security#Default_CSP_policy * Is there any reason developers wouldn't just modify the script tag under either method proposed to use src=link-to-non-inline-script to satisfy CSP requirements? The proposal I submitted certainly doesn't exclude that ability/use case (or so I thought - correct if wrong) There is nothing stopping that at all. A bigger issue with proposal is that the global object appears to be the element's instance object itself, which isn't going to work Rick Daniel J. Buchner Product Manager, Developer Ecosystem Mozilla Corporation On Wed, Apr 10, 2013 at 1:27 PM, Rick Waldron waldron.r...@gmail.comwrote: On Wed, Apr 10, 2013 at 4:15 PM, Daniel Buchner dan...@mozilla.comwrote: I have a counter proposal that takes into a count both the easy-to-declare, 1-to-1 case, as well as the 1-template-to-many-elements case: https://gist.github.com/csuwldcat/5358039 What about CSP that forbids inline scripts? https://wiki.mozilla.org/Apps/Security#Default_CSP_policy Rick I can explain the advantages a bit more in an hour or so, I just got pulled into a meeting...le sigh. Daniel J. Buchner Product Manager, Developer Ecosystem Mozilla Corporation On Wed, Apr 10, 2013 at 12:40 PM, Scott Miles sjmi...@google.comwrote: No, strictly ergonomic. Less nesting and less characters (less nesting is more important IMO). I would also argue that there is less cognitive load on the author then the more explicit factoring, but I believe this is subjective. Scott On Wed, Apr 10, 2013 at 12:36 PM, Rafael Weinstein rafa...@google.comwrote: On Wed, Apr 10, 2013 at 11:47 AM, Dimitri Glazkov dglaz...@google.com wrote: Dear Webappsonites, There's been a ton of thinking on what the custom elements declarative syntax must look like. Here, I present something has near-ideal developer ergonomics at the expense of terrible sins in other areas. Consider it to be beacon, rather than a concrete proposal. First, let's cleanse your palate. Forget about the element element and what goes inside of it. Eat some parsley. == Templates Bound to Tags == Instead, suppose you only have a template: template divYay!/div /template Templates are good for stamping things out, right? So let's invent a way to _bind_ a template to a _tag_. When the browser sees a tag to which the template is bound, it stamps the template out. Like so: 1) Define a template and bind it to a tag name: template bindtotagname=my-yay divYay!/div /template 2) Whenever my-yay is seen by the parser or createElement/NS(my-yay) is called, the template is stamped out to produce: my-yay divYay!/div /my-yay Cool! This is immediately useful for web developers. They can transform any markup into something they can use. Behind the scenes: the presence of boundtotagname triggers a call to document.register, and the argument is a browser-generated prototype object whose readyCallback takes the template and appends it to this. == Organic Shadow Trees == But what if they also wanted to employ encapsulation boundaries, leaving initial markup structure intact? No problem, much-maligned shadowroot to the rescue: 1) Define a template with a shadow tree and bind it to a tag name: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot /template 2) For each my-yay created, the template is stamped out to create a shadow root and populate it. Super-cool! Note, how the developer doesn't have to know anything about Shadow DOM to build custom elements (er, template-bound tags). Shadow trees are just an option. Behind the scenes: exactly the same as the first scenario. == Declarative Meets Imperative == Now, the developer wants to add some APIs to my-yay. Sure, no problem: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot script runwhenbound // runs right after document.register is triggered this.register(ExactSyntaxTBD); script /template So-cool-it-hurts! We built a fully functional custom element, taking small steps from an extremely simple concept to the full-blown thing. In the process, we also saw a completely decoupled shadow DOM from custom elements in both imperative and declarative forms, achieving singularity. Well, or at least a high degree of consistence. == Problems == There are severe issues. The shadowroot is turning out to be super-magical. The bindtotagname attribute will need to be also magical, to be consistent with how document.register could be used. The stamping out, after clearly specified, may raise eyebrows and turn out to be unintuitive. Templates are supposed to be
Re: [webcomponents]: Platonic form of custom elements declarative syntax
On Wed, Apr 10, 2013 at 4:43 PM, Rick Waldron waldron.r...@gmail.comwrote: A bigger issue with proposal is that the global object appears to be the element's instance object itself, which isn't going to work +1 I'm not sure that `this` was supposed to be the [[Global]] object? But agree with you, this is something that has been itching me for a while too. I need to think a bit more about how to actually solve this issue though.
Re: [webcomponents]: Platonic form of custom elements declarative syntax
One thing I'm wondering re template elements and the association of a specific script with them, is what is it really doing for me? From what I see, not much. It seems the only thing it does, is allows you to have the generic, globally-scoped script run at a given time (via a new runwhen___ attribute) and the implicit relationship created by inclusion within the template element itself - which is essentially no different than just setting a global delegate in any 'ol script tag on the page. Are there show-stopper issues with empowering the script tags inside template elements to be a bit more powerful? (think local instance scoping, auto template event unbinding on removal, or any other helpful additions) If there are issues with making these script tags behave a bit different, then what is the compelling value proposition vs something like this: https://gist.github.com/csuwldcat/5358612 ? On Wed, Apr 10, 2013 at 1:43 PM, Rick Waldron waldron.r...@gmail.comwrote: On Wed, Apr 10, 2013 at 4:38 PM, Daniel Buchner dan...@mozilla.comwrote: *What about CSP that forbids inline scripts?https://wiki.mozilla.org/Apps/Security#Default_CSP_policy * Is there any reason developers wouldn't just modify the script tag under either method proposed to use src=link-to-non-inline-script to satisfy CSP requirements? The proposal I submitted certainly doesn't exclude that ability/use case (or so I thought - correct if wrong) There is nothing stopping that at all. A bigger issue with proposal is that the global object appears to be the element's instance object itself, which isn't going to work Rick Daniel J. Buchner Product Manager, Developer Ecosystem Mozilla Corporation On Wed, Apr 10, 2013 at 1:27 PM, Rick Waldron waldron.r...@gmail.comwrote: On Wed, Apr 10, 2013 at 4:15 PM, Daniel Buchner dan...@mozilla.comwrote: I have a counter proposal that takes into a count both the easy-to-declare, 1-to-1 case, as well as the 1-template-to-many-elements case: https://gist.github.com/csuwldcat/5358039 What about CSP that forbids inline scripts? https://wiki.mozilla.org/Apps/Security#Default_CSP_policy Rick I can explain the advantages a bit more in an hour or so, I just got pulled into a meeting...le sigh. Daniel J. Buchner Product Manager, Developer Ecosystem Mozilla Corporation On Wed, Apr 10, 2013 at 12:40 PM, Scott Miles sjmi...@google.comwrote: No, strictly ergonomic. Less nesting and less characters (less nesting is more important IMO). I would also argue that there is less cognitive load on the author then the more explicit factoring, but I believe this is subjective. Scott On Wed, Apr 10, 2013 at 12:36 PM, Rafael Weinstein rafa...@google.com wrote: On Wed, Apr 10, 2013 at 11:47 AM, Dimitri Glazkov dglaz...@google.com wrote: Dear Webappsonites, There's been a ton of thinking on what the custom elements declarative syntax must look like. Here, I present something has near-ideal developer ergonomics at the expense of terrible sins in other areas. Consider it to be beacon, rather than a concrete proposal. First, let's cleanse your palate. Forget about the element element and what goes inside of it. Eat some parsley. == Templates Bound to Tags == Instead, suppose you only have a template: template divYay!/div /template Templates are good for stamping things out, right? So let's invent a way to _bind_ a template to a _tag_. When the browser sees a tag to which the template is bound, it stamps the template out. Like so: 1) Define a template and bind it to a tag name: template bindtotagname=my-yay divYay!/div /template 2) Whenever my-yay is seen by the parser or createElement/NS(my-yay) is called, the template is stamped out to produce: my-yay divYay!/div /my-yay Cool! This is immediately useful for web developers. They can transform any markup into something they can use. Behind the scenes: the presence of boundtotagname triggers a call to document.register, and the argument is a browser-generated prototype object whose readyCallback takes the template and appends it to this. == Organic Shadow Trees == But what if they also wanted to employ encapsulation boundaries, leaving initial markup structure intact? No problem, much-maligned shadowroot to the rescue: 1) Define a template with a shadow tree and bind it to a tag name: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot /template 2) For each my-yay created, the template is stamped out to create a shadow root and populate it. Super-cool! Note, how the developer doesn't have to know anything about Shadow DOM to build custom elements (er, template-bound tags). Shadow trees are just an option. Behind the scenes: exactly the same as the first scenario. == Declarative Meets Imperative == Now, the developer wants to add
Re: [webcomponents]: Platonic form of custom elements declarative syntax
FWIW, I think it's a design mistake to make element registration a concern of template. I'd be more persuaded by the developer ergonomics argument if this was a cost that was incurred with the usage of custom elements, but it's not. It's only incurred with the element definition. Separately, I may have missed it, but it seems to me that allowing custom elements to stamp out light DOM is a new semantic, that isn't obviously solving a problem which is either identified, or related to web components. Did I miss earlier discussion about this? On Wed, Apr 10, 2013 at 12:40 PM, Scott Miles sjmi...@google.com wrote: No, strictly ergonomic. Less nesting and less characters (less nesting is more important IMO). I would also argue that there is less cognitive load on the author then the more explicit factoring, but I believe this is subjective. Scott On Wed, Apr 10, 2013 at 12:36 PM, Rafael Weinstein rafa...@google.com wrote: On Wed, Apr 10, 2013 at 11:47 AM, Dimitri Glazkov dglaz...@google.com wrote: Dear Webappsonites, There's been a ton of thinking on what the custom elements declarative syntax must look like. Here, I present something has near-ideal developer ergonomics at the expense of terrible sins in other areas. Consider it to be beacon, rather than a concrete proposal. First, let's cleanse your palate. Forget about the element element and what goes inside of it. Eat some parsley. == Templates Bound to Tags == Instead, suppose you only have a template: template divYay!/div /template Templates are good for stamping things out, right? So let's invent a way to _bind_ a template to a _tag_. When the browser sees a tag to which the template is bound, it stamps the template out. Like so: 1) Define a template and bind it to a tag name: template bindtotagname=my-yay divYay!/div /template 2) Whenever my-yay is seen by the parser or createElement/NS(my-yay) is called, the template is stamped out to produce: my-yay divYay!/div /my-yay Cool! This is immediately useful for web developers. They can transform any markup into something they can use. Behind the scenes: the presence of boundtotagname triggers a call to document.register, and the argument is a browser-generated prototype object whose readyCallback takes the template and appends it to this. == Organic Shadow Trees == But what if they also wanted to employ encapsulation boundaries, leaving initial markup structure intact? No problem, much-maligned shadowroot to the rescue: 1) Define a template with a shadow tree and bind it to a tag name: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot /template 2) For each my-yay created, the template is stamped out to create a shadow root and populate it. Super-cool! Note, how the developer doesn't have to know anything about Shadow DOM to build custom elements (er, template-bound tags). Shadow trees are just an option. Behind the scenes: exactly the same as the first scenario. == Declarative Meets Imperative == Now, the developer wants to add some APIs to my-yay. Sure, no problem: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot script runwhenbound // runs right after document.register is triggered this.register(ExactSyntaxTBD); script /template So-cool-it-hurts! We built a fully functional custom element, taking small steps from an extremely simple concept to the full-blown thing. In the process, we also saw a completely decoupled shadow DOM from custom elements in both imperative and declarative forms, achieving singularity. Well, or at least a high degree of consistence. == Problems == There are severe issues. The shadowroot is turning out to be super-magical. The bindtotagname attribute will need to be also magical, to be consistent with how document.register could be used. The stamping out, after clearly specified, may raise eyebrows and turn out to be unintuitive. Templates are supposed to be inert, but the whole script runwhenbound thing is strongly negating this. There's probably more that I can't remember now. The following expresses the same semantics: element tagname=my-yay template shadowroot divYay!/div /shadowroot /template script runwhenbound /script /element I get that your proposal is fewer characters to type. Are there other advantages? == Plea == However, I am hopeful that you smart folk will look at this, see the light, tweak the idea just a bit and hit the homerun. See the light, dammit! :DG
Re: [webcomponents]: Platonic form of custom elements declarative syntax
On Wed, Apr 10, 2013 at 2:45 PM, Rafael Weinstein rafa...@google.com wrote: FWIW, I think it's a design mistake to make element registration a concern of template. Sorry. I over-stated my conviction here. Let me walk that back: I'm not yet hearing sufficient justification for making element registration a concern of template I'd be more persuaded by the developer ergonomics argument if this was a cost that was incurred with the usage of custom elements, but it's not. It's only incurred with the element definition. Separately, I may have missed it, but it seems to me that allowing custom elements to stamp out light DOM is a new semantic, that isn't obviously solving a problem which is either identified, or related to web components. Did I miss earlier discussion about this? On Wed, Apr 10, 2013 at 12:40 PM, Scott Miles sjmi...@google.com wrote: No, strictly ergonomic. Less nesting and less characters (less nesting is more important IMO). I would also argue that there is less cognitive load on the author then the more explicit factoring, but I believe this is subjective. Scott On Wed, Apr 10, 2013 at 12:36 PM, Rafael Weinstein rafa...@google.com wrote: On Wed, Apr 10, 2013 at 11:47 AM, Dimitri Glazkov dglaz...@google.com wrote: Dear Webappsonites, There's been a ton of thinking on what the custom elements declarative syntax must look like. Here, I present something has near-ideal developer ergonomics at the expense of terrible sins in other areas. Consider it to be beacon, rather than a concrete proposal. First, let's cleanse your palate. Forget about the element element and what goes inside of it. Eat some parsley. == Templates Bound to Tags == Instead, suppose you only have a template: template divYay!/div /template Templates are good for stamping things out, right? So let's invent a way to _bind_ a template to a _tag_. When the browser sees a tag to which the template is bound, it stamps the template out. Like so: 1) Define a template and bind it to a tag name: template bindtotagname=my-yay divYay!/div /template 2) Whenever my-yay is seen by the parser or createElement/NS(my-yay) is called, the template is stamped out to produce: my-yay divYay!/div /my-yay Cool! This is immediately useful for web developers. They can transform any markup into something they can use. Behind the scenes: the presence of boundtotagname triggers a call to document.register, and the argument is a browser-generated prototype object whose readyCallback takes the template and appends it to this. == Organic Shadow Trees == But what if they also wanted to employ encapsulation boundaries, leaving initial markup structure intact? No problem, much-maligned shadowroot to the rescue: 1) Define a template with a shadow tree and bind it to a tag name: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot /template 2) For each my-yay created, the template is stamped out to create a shadow root and populate it. Super-cool! Note, how the developer doesn't have to know anything about Shadow DOM to build custom elements (er, template-bound tags). Shadow trees are just an option. Behind the scenes: exactly the same as the first scenario. == Declarative Meets Imperative == Now, the developer wants to add some APIs to my-yay. Sure, no problem: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot script runwhenbound // runs right after document.register is triggered this.register(ExactSyntaxTBD); script /template So-cool-it-hurts! We built a fully functional custom element, taking small steps from an extremely simple concept to the full-blown thing. In the process, we also saw a completely decoupled shadow DOM from custom elements in both imperative and declarative forms, achieving singularity. Well, or at least a high degree of consistence. == Problems == There are severe issues. The shadowroot is turning out to be super-magical. The bindtotagname attribute will need to be also magical, to be consistent with how document.register could be used. The stamping out, after clearly specified, may raise eyebrows and turn out to be unintuitive. Templates are supposed to be inert, but the whole script runwhenbound thing is strongly negating this. There's probably more that I can't remember now. The following expresses the same semantics: element tagname=my-yay template shadowroot divYay!/div /shadowroot /template script runwhenbound /script /element I get that your proposal is fewer characters to type. Are there other advantages? == Plea == However, I am hopeful that you smart folk will look at this, see the light, tweak the idea just a bit and hit the homerun. See the light, dammit!
Re: [webcomponents]: Platonic form of custom elements declarative syntax
On Wed, Apr 10, 2013 at 5:35 PM, Daniel Buchner dan...@mozilla.com wrote: One thing I'm wondering re template elements and the association of a specific script with them, is what is it really doing for me? From what I see, not much. It seems the only thing it does, is allows you to have the generic, globally-scoped script run at a given time (via a new runwhen___ attribute) and the implicit relationship created by inclusion within the template element itself - which is essentially no different than just setting a global delegate in any 'ol script tag on the page. I'd be interested in seeing a reasonable set of semantics defining how that specific script tag knows what its this value is; so far I understand that inside those script tags, |this| !== |window|. @Erik, what about |self|? That actually makes more sense and *almost* has a precedent in worker global scope Rick
Re: [webcomponents]: Platonic form of custom elements declarative syntax
mistake to make element registration a concern of template. Raf: does that include making a new type 'element' which is a subtype of 'template', which is specifically given this concern? stamp out light DOM is a new semantic This is true, it sort of appeared organically and we haven't wrestled with it enough. We have discussed it though. There are many libraries that use this kind of technique today, and it has a lot of appeal because it's an easier way to on-ramp people into web-components without hitting them over the head with shadow dom right away. There was originally some zeal that this would solve inheritance issues wrt declarative shadow dom, but all it really does is shift the problems around. On Wed, Apr 10, 2013 at 2:47 PM, Rafael Weinstein rafa...@google.comwrote: On Wed, Apr 10, 2013 at 2:45 PM, Rafael Weinstein rafa...@google.com wrote: FWIW, I think it's a design mistake to make element registration a concern of template. Sorry. I over-stated my conviction here. Let me walk that back: I'm not yet hearing sufficient justification for making element registration a concern of template I'd be more persuaded by the developer ergonomics argument if this was a cost that was incurred with the usage of custom elements, but it's not. It's only incurred with the element definition. Separately, I may have missed it, but it seems to me that allowing custom elements to stamp out light DOM is a new semantic, that isn't obviously solving a problem which is either identified, or related to web components. Did I miss earlier discussion about this? On Wed, Apr 10, 2013 at 12:40 PM, Scott Miles sjmi...@google.com wrote: No, strictly ergonomic. Less nesting and less characters (less nesting is more important IMO). I would also argue that there is less cognitive load on the author then the more explicit factoring, but I believe this is subjective. Scott On Wed, Apr 10, 2013 at 12:36 PM, Rafael Weinstein rafa...@google.com wrote: On Wed, Apr 10, 2013 at 11:47 AM, Dimitri Glazkov dglaz...@google.com wrote: Dear Webappsonites, There's been a ton of thinking on what the custom elements declarative syntax must look like. Here, I present something has near-ideal developer ergonomics at the expense of terrible sins in other areas. Consider it to be beacon, rather than a concrete proposal. First, let's cleanse your palate. Forget about the element element and what goes inside of it. Eat some parsley. == Templates Bound to Tags == Instead, suppose you only have a template: template divYay!/div /template Templates are good for stamping things out, right? So let's invent a way to _bind_ a template to a _tag_. When the browser sees a tag to which the template is bound, it stamps the template out. Like so: 1) Define a template and bind it to a tag name: template bindtotagname=my-yay divYay!/div /template 2) Whenever my-yay is seen by the parser or createElement/NS(my-yay) is called, the template is stamped out to produce: my-yay divYay!/div /my-yay Cool! This is immediately useful for web developers. They can transform any markup into something they can use. Behind the scenes: the presence of boundtotagname triggers a call to document.register, and the argument is a browser-generated prototype object whose readyCallback takes the template and appends it to this. == Organic Shadow Trees == But what if they also wanted to employ encapsulation boundaries, leaving initial markup structure intact? No problem, much-maligned shadowroot to the rescue: 1) Define a template with a shadow tree and bind it to a tag name: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot /template 2) For each my-yay created, the template is stamped out to create a shadow root and populate it. Super-cool! Note, how the developer doesn't have to know anything about Shadow DOM to build custom elements (er, template-bound tags). Shadow trees are just an option. Behind the scenes: exactly the same as the first scenario. == Declarative Meets Imperative == Now, the developer wants to add some APIs to my-yay. Sure, no problem: template bindtotagname=my-yay shadowroot divYay!/div /shadowroot script runwhenbound // runs right after document.register is triggered this.register(ExactSyntaxTBD); script /template So-cool-it-hurts! We built a fully functional custom element, taking small steps from an extremely simple concept to the full-blown thing. In the process, we also saw a completely decoupled shadow DOM from custom elements in both imperative and declarative forms, achieving singularity. Well, or at least a high degree of consistence. ==
Re: [webcomponents]: Platonic form of custom elements declarative syntax
how that specific script tag knows what its this value is I think I'm probably not answering your question, but I believe the notion was that that script tag is handled specially by element, so it's a script* which only ever executes in the 'scope' of element. On Wed, Apr 10, 2013 at 2:54 PM, Rick Waldron waldron.r...@gmail.comwrote: On Wed, Apr 10, 2013 at 5:35 PM, Daniel Buchner dan...@mozilla.comwrote: One thing I'm wondering re template elements and the association of a specific script with them, is what is it really doing for me? From what I see, not much. It seems the only thing it does, is allows you to have the generic, globally-scoped script run at a given time (via a new runwhen___ attribute) and the implicit relationship created by inclusion within the template element itself - which is essentially no different than just setting a global delegate in any 'ol script tag on the page. I'd be interested in seeing a reasonable set of semantics defining how that specific script tag knows what its this value is; so far I understand that inside those script tags, |this| !== |window|. @Erik, what about |self|? That actually makes more sense and *almost* has a precedent in worker global scope Rick
Re: [webcomponents]: Platonic form of custom elements declarative syntax
On Wed, Apr 10, 2013 at 3:30 PM, Daniel Buchner dan...@mozilla.com wrote: @John - in my opinion, template bindtotagname=my-yay is the wrong direction. You should be declaring which *template* an *element* uses, not which element a template captures. Having templates latch onto element types from afar breaks the one-to-many case, prevents sane swapping of templates on a specific element node, and many other oddities. Alternatively, element template=id-of-some-template is more flexible and the right 'direction' for such an association that suffers none of those issues, at least in my opinion. Feel free to disagree or set me straight if anything I said is not accurate :) I don't have any opinion on this aspect, sorry. I was only offering a modernization of an old and not-popular-among-purists way of connecting scripts and elements. jjb
Re: [webcomponents]: Platonic form of custom elements declarative syntax
On Wed, Apr 10, 2013 at 8:19 PM, Daniel Buchner dan...@mozilla.com wrote: Here are a few (compelling?) answers/arguments: 1. Style elements had never done this before, yet it rocks socks: style scoped Beat me to it. Another date point is @keyframes/@font-face, which are (today) ignored in style scoped. So there's already precedence for behavioral changes in the brave new world of web components. Since custom elements are fundamentally a new concept for web development, I don't think it's unreasonable to ask developers to expect slight differences. Familiar friends can act a little kooky now and then :) 1. It would be new for script elements, but hardly new for other elements. There are plenty of elements that have various behaviors or visual representations only when placed inside specific elements. Given this is already an advanced web API, I'm not sure a little upfront learning is a huge concern. We could even allow for this, given the paradigm is already established: script scoped *// could scope 'this' ref to the parentNode* 2. Are you referring to template attachment here? If so, I agree, thus the proposal I submitted allows for both ( https://gist.github.com/csuwldcat/5360471). If you want your template automatically associated with your element, put it inside, if not, you can specify which template a custom element should use by reference to its ID. On Wed, Apr 10, 2013 at 8:00 PM, John J Barton johnjbar...@johnjbarton.com wrote: On Wed, Apr 10, 2013 at 6:51 PM, Dimitri Glazkov dglaz...@google.comwrote: On Wed, Apr 10, 2013 at 6:38 PM, Rick Waldron waldron.r...@gmail.com wrote: Everyone's answer to this should be no; changing the expected value of the top level this, in some magical way, simply won't work. Can you explain why you feel this way? 1) Because script has never done this before, so it better be compelling. 2) Because causing |this| to change by moving the script tag in the HTML or adding a layer of elements etc seems likely to cause hard to understand bugs. 3) Forcing the binding based on position is inflexible. To be sure this is implicit-declarative vs explicit-imperative bias, not evidence. Oh, sorry you were asking Rick. jjb
Re: [webcomponents]: Platonic form of custom elements declarative syntax
It's incredibly important that we agree that association of a template with element happens on the element side, something like: element template=foo-template (or by placing the template inside element, if that is the API we want). I don't think this part is opinion, but because doing the reverse - marking on the template which element it refers to - hinders a few valid use-cases: - one template from being used by many different elements - changing a template association on a single instance of an element type - say you have an x-foo on the page that you want to switch template associations on, but not for every other x-foo in the document. Wouldn't this case be far more clear cut if you could just query for the element and change some property? For instance: fooElement.template = 'foo-template-2'; Boom! This particular foo element just switched templates. On Wed, Apr 10, 2013 at 8:19 PM, Daniel Buchner dan...@mozilla.com wrote: Here are a few (compelling?) answers/arguments: 1. Style elements had never done this before, yet it rocks socks: style scoped 2. It would be new for script elements, but hardly new for other elements. There are plenty of elements that have various behaviors or visual representations only when placed inside specific elements. Given this is already an advanced web API, I'm not sure a little upfront learning is a huge concern. We could even allow for this, given the paradigm is already established: script scoped *// could scope 'this' ref to the parentNode* 3. Are you referring to template attachment here? If so, I agree, thus the proposal I submitted allows for both ( https://gist.github.com/csuwldcat/5360471). If you want your template automatically associated with your element, put it inside, if not, you can specify which template a custom element should use by reference to its ID. On Wed, Apr 10, 2013 at 8:00 PM, John J Barton johnjbar...@johnjbarton.com wrote: On Wed, Apr 10, 2013 at 6:51 PM, Dimitri Glazkov dglaz...@google.comwrote: On Wed, Apr 10, 2013 at 6:38 PM, Rick Waldron waldron.r...@gmail.com wrote: Everyone's answer to this should be no; changing the expected value of the top level this, in some magical way, simply won't work. Can you explain why you feel this way? 1) Because script has never done this before, so it better be compelling. 2) Because causing |this| to change by moving the script tag in the HTML or adding a layer of elements etc seems likely to cause hard to understand bugs. 3) Forcing the binding based on position is inflexible. To be sure this is implicit-declarative vs explicit-imperative bias, not evidence. Oh, sorry you were asking Rick. jjb
Re: [webcomponents]: Platonic form of custom elements declarative syntax
Here are a few (compelling?) answers/arguments: 1. Style elements had never done this before, yet it rocks socks: style scoped 2. It would be new for script elements, but hardly new for other elements. There are plenty of elements that have various behaviors or visual representations only when placed inside specific elements. Given this is already an advanced web API, I'm not sure a little upfront learning is a huge concern. We could even allow for this, given the paradigm is already established: script scoped *// could scope 'this' ref to the parentNode* 3. Are you referring to template attachment here? If so, I agree, thus the proposal I submitted allows for both ( https://gist.github.com/csuwldcat/5360471). If you want your template automatically associated with your element, put it inside, if not, you can specify which template a custom element should use by reference to its ID. On Wed, Apr 10, 2013 at 8:00 PM, John J Barton johnjbar...@johnjbarton.comwrote: On Wed, Apr 10, 2013 at 6:51 PM, Dimitri Glazkov dglaz...@google.comwrote: On Wed, Apr 10, 2013 at 6:38 PM, Rick Waldron waldron.r...@gmail.com wrote: Everyone's answer to this should be no; changing the expected value of the top level this, in some magical way, simply won't work. Can you explain why you feel this way? 1) Because script has never done this before, so it better be compelling. 2) Because causing |this| to change by moving the script tag in the HTML or adding a layer of elements etc seems likely to cause hard to understand bugs. 3) Forcing the binding based on position is inflexible. To be sure this is implicit-declarative vs explicit-imperative bias, not evidence. Oh, sorry you were asking Rick. jjb
Re: [webcomponents]: Platonic form of custom elements declarative syntax
On Wed, Apr 10, 2013 at 6:38 PM, Rick Waldron waldron.r...@gmail.com wrote: Everyone's answer to this should be no; changing the expected value of the top level this, in some magical way, simply won't work. Can you explain why you feel this way? :DG
Re: [webcomponents]: Platonic form of custom elements declarative syntax
cc Allen Wirfs-Brock, Dave Herman Allen, Dave Would you mind reading back through the thread to provide some deeper insight? Thanks Rick On Wednesday, April 10, 2013, Daniel Buchner wrote: Here are a few (compelling?) answers/arguments: 1. Style elements had never done this before, yet it rocks socks: style scoped 2. It would be new for script elements, but hardly new for other elements. There are plenty of elements that have various behaviors or visual representations only when placed inside specific elements. Given this is already an advanced web API, I'm not sure a little upfront learning is a huge concern. We could even allow for this, given the paradigm is already established: script scoped *// could scope 'this' ref to the parentNode* 3. Are you referring to template attachment here? If so, I agree, thus the proposal I submitted allows for both ( https://gist.github.com/csuwldcat/5360471). If you want your template automatically associated with your element, put it inside, if not, you can specify which template a custom element should use by reference to its ID. On Wed, Apr 10, 2013 at 8:00 PM, John J Barton johnjbar...@johnjbarton.com javascript:_e({}, 'cvml', 'johnjbar...@johnjbarton.com'); wrote: On Wed, Apr 10, 2013 at 6:51 PM, Dimitri Glazkov dglaz...@google.comjavascript:_e({}, 'cvml', 'dglaz...@google.com'); wrote: On Wed, Apr 10, 2013 at 6:38 PM, Rick Waldron waldron.r...@gmail.comjavascript:_e({}, 'cvml', 'waldron.r...@gmail.com'); wrote: Everyone's answer to this should be no; changing the expected value of the top level this, in some magical way, simply won't work. Can you explain why you feel this way? 1) Because script has never done this before, so it better be compelling. 2) Because causing |this| to change by moving the script tag in the HTML or adding a layer of elements etc seems likely to cause hard to understand bugs. 3) Forcing the binding based on position is inflexible. To be sure this is implicit-declarative vs explicit-imperative bias, not evidence. Oh, sorry you were asking Rick. jjb
Re: [webcomponents]: Platonic form of custom elements declarative syntax
Have to lean towards Raf and Daniel on this one. Making a element registation a concern of template doesn't feel right. In this case, explicit structure and a few more characters is worth it. On Wed, Apr 10, 2013 at 9:00 PM, Daniel Buchner dan...@mozilla.com wrote: It's incredibly important that we agree that association of a template with element happens on the element side, something like: element template=foo-template (or by placing the template inside element, if that is the API we want). I don't think this part is opinion, but because doing the reverse - marking on the template which element it refers to - hinders a few valid use-cases: - one template from being used by many different elements - changing a template association on a single instance of an element type - say you have an x-foo on the page that you want to switch template associations on, but not for every other x-foo in the document. Wouldn't this case be far more clear cut if you could just query for the element and change some property? For instance: fooElement.template = 'foo-template-2'; Boom! This particular foo element just switched templates. Shouldn't we prevent such a thing? I can't redefine a button's template. There should be some guarantee I'm getting the same x-foo (API, look and feel) after it's been registered. What's the use case for swapping in a new template? - On Wed, Apr 10, 2013 at 8:19 PM, Daniel Buchner dan...@mozilla.comwrote: Here are a few (compelling?) answers/arguments: 1. Style elements had never done this before, yet it rocks socks: style scoped 2. It would be new for script elements, but hardly new for other elements. There are plenty of elements that have various behaviors or visual representations only when placed inside specific elements. Given this is already an advanced web API, I'm not sure a little upfront learning is a huge concern. We could even allow for this, given the paradigm is already established: script scoped *// could scope 'this' ref to the parentNode* 3. Are you referring to template attachment here? If so, I agree, thus the proposal I submitted allows for both ( https://gist.github.com/csuwldcat/5360471). If you want your template automatically associated with your element, put it inside, if not, you can specify which template a custom element should use by reference to its ID. On Wed, Apr 10, 2013 at 8:00 PM, John J Barton johnjbar...@johnjbarton.com wrote: On Wed, Apr 10, 2013 at 6:51 PM, Dimitri Glazkov dglaz...@google.comwrote: On Wed, Apr 10, 2013 at 6:38 PM, Rick Waldron waldron.r...@gmail.com wrote: Everyone's answer to this should be no; changing the expected value of the top level this, in some magical way, simply won't work. Can you explain why you feel this way? 1) Because script has never done this before, so it better be compelling. 2) Because causing |this| to change by moving the script tag in the HTML or adding a layer of elements etc seems likely to cause hard to understand bugs. 3) Forcing the binding based on position is inflexible. To be sure this is implicit-declarative vs explicit-imperative bias, not evidence. Oh, sorry you were asking Rick. jjb