RE: Custom element design with ES6 classes and Element constructors
Just to clarify, this argument for symbols is not dependent on modules. Restated, the comparison is between: ```js class MyButton extends HTMLElement { createdCallback() {} } ``` vs. ```js class MyButton extends HTMLElement { [Element.create]() {} } ``` We're already doing some crude namespacing with *Callback. I'd expect that as soon as the first iteration of Custom Elements is out, people will copy the *Callback style in user code. This is a powerful point that I definitely agree with. I would not be terribly surprised to find some library on the web already that asks you to create custom elements but encourages you supply a few more library-specific hooks with -Callback suffixes.
Re: Custom element design with ES6 classes and Element constructors
I'm sympathetic to this but I think it is fine that DOM continues to define new string based property names. Anytime we add a new property to an existing class we run into this issue and I don't think we want to give up on the superior usability of string based property names. I agree, FWIW. :DG
Re: Minimum viable custom elements
No argument that callbacks are also a useful new addition. :DG
Re: Custom element design with ES6 classes and Element constructors
On Thu, Jan 15, 2015 at 2:37 AM, Anne van Kesteren ann...@annevk.nl wrote: On Thu, Jan 15, 2015 at 5:11 AM, Yehuda Katz wyc...@gmail.com wrote: Can you say more about why same-identity upgrading is critical to the design (as opposed to dom-mutation upgrading)? I asked up-thread but didn't get any takers. I tried to summarize the various upgrade scenarios here (as well as the other issues): https://wiki.whatwg.org/wiki/CustomElements Thanks for starting this page! One thing that seems missing is Steve Faulkner's concern about removing is. :DG
Re: Custom element design with ES6 classes and Element constructors
It's not clear to me that: import HTMLElement from web/element; class MyButton extends HTMLElement { readyCallback() {} } is that much more usable than import HTMLElement, { ready } from web/element; class MyButton extends HTMLElement { [ready]() {} } In other words, in a modules world, you're already importing the class, and adding on a symbol isn't too bad. We're already doing some crude namespacing with *Callback. I'd expect that as soon as the first iteration of Custom Elements is out, people will copy the *Callback style in user code. We can always work around it with more obscure and more verbose names (since libraries will slurp up the good names) but that damages the ergonomic argument. On Thu, Jan 15, 2015, 9:32 AM Dimitri Glazkov dglaz...@google.com wrote: I'm sympathetic to this but I think it is fine that DOM continues to define new string based property names. Anytime we add a new property to an existing class we run into this issue and I don't think we want to give up on the superior usability of string based property names. I agree, FWIW. :DG
Re: Minimum viable custom elements
On Wed, Jan 14, 2015 at 9:25 PM, Ryosuke Niwa rn...@apple.com wrote: On Jan 14, 2015, at 6:45 AM, Anne van Kesteren ann...@annevk.nl wrote: * Existing lifecycle callbacks plus those agreed (copying, adopting). Could you give us pointers for a proposed definition of these two callbacks if there is any? I added a short description here: https://wiki.whatwg.org/wiki/CustomElements#Additional_lifecycle_callbacks These would basically cover these extension points that the DOM already offers and that HTML (and perhaps SVG) makes use of: https://dom.spec.whatwg.org/#concept-node-adopt-ext https://dom.spec.whatwg.org/#concept-node-clone-ext It also does not address subclassing normal elements. Again, while that seems desirable the current ideas are not attractive long term solutions. Punting on it in order to ship a v1 available everywhere seems preferable. I can't be enthusiastic enough to support this motion since that's more or less what I've been saying for the past six months or so. I hope that we are iterating to a subset that everyone is happy with. It would be great to get custom elements in all browsers. As far as I can tell the main sticking point is still how exactly we map markup to objects: https://wiki.whatwg.org/wiki/CustomElements#Upgrading -- https://annevankesteren.nl/
Re: Minimum viable custom elements
Anne, maybe you could write on the wiki what the current Web Components implementation in Chrome is using. That would make it a bit easier to follow for people who didn't follow all of the discussion so far. Kenneth On Thu Jan 15 2015 at 5:05:35 PM Anne van Kesteren ann...@annevk.nl wrote: On Wed, Jan 14, 2015 at 9:52 PM, Dimitri Glazkov dglaz...@google.com wrote: FWIW, I think that element upgrade is sort of fundamental to the usefulness of custom elements. In a world where most scripts are non-blocking (that's hopefully the modern world we should aim for), I'll effectively expect to walk the tree anyway. And if I walk the tree anyway, what's the point of custom elements in the first place? One of the key features (at least, to me) of custom elements was being able to harness the HTML Parser to instantiate your object tree. If that's not going happen consistently, then I am not sure custom elements are worth the trouble. IOW, if you're walking the tree, just do the work of callbacks as you encounter dash-separated elements. My rationale is this: * Unlike you I think lifecycle callbacks are the main selling point of a custom element. They give you access to hooks that normal elements have but are not otherwise exposed. * I think we could iterate towards a v2 that has an aspect of upgrading but perhaps works a bit differently from the current setup. E.g. a way to include an entire subtree of custom elements with a fallback mechanism of sorts. Or perhaps something inspired by JavaScript modules. * Upgrading can be added, but moving from Brain transplants to a more normal working constructor would be impossible after the fact. Now, given the discussion so far, it does seem that synchronous or almost-synchronous constructors have a number of hard issues and it's not entirely clear to me anymore those are worth pushing over Brain transplant or Dummy replacement, using the terminology from: https://wiki.whatwg.org/wiki/CustomElements#Upgrading -- https://annevankesteren.nl/
Re: Minimum viable custom elements
On Wed, Jan 14, 2015 at 9:52 PM, Dimitri Glazkov dglaz...@google.com wrote: FWIW, I think that element upgrade is sort of fundamental to the usefulness of custom elements. In a world where most scripts are non-blocking (that's hopefully the modern world we should aim for), I'll effectively expect to walk the tree anyway. And if I walk the tree anyway, what's the point of custom elements in the first place? One of the key features (at least, to me) of custom elements was being able to harness the HTML Parser to instantiate your object tree. If that's not going happen consistently, then I am not sure custom elements are worth the trouble. IOW, if you're walking the tree, just do the work of callbacks as you encounter dash-separated elements. My rationale is this: * Unlike you I think lifecycle callbacks are the main selling point of a custom element. They give you access to hooks that normal elements have but are not otherwise exposed. * I think we could iterate towards a v2 that has an aspect of upgrading but perhaps works a bit differently from the current setup. E.g. a way to include an entire subtree of custom elements with a fallback mechanism of sorts. Or perhaps something inspired by JavaScript modules. * Upgrading can be added, but moving from Brain transplants to a more normal working constructor would be impossible after the fact. Now, given the discussion so far, it does seem that synchronous or almost-synchronous constructors have a number of hard issues and it's not entirely clear to me anymore those are worth pushing over Brain transplant or Dummy replacement, using the terminology from: https://wiki.whatwg.org/wiki/CustomElements#Upgrading -- https://annevankesteren.nl/
Re: Custom element design with ES6 classes and Element constructors
On Thu, Jan 15, 2015 at 1:09 AM, Dmitry Lomov dslo...@chromium.org wrote: On Thu, Jan 15, 2015 at 5:11 AM, Yehuda Katz wyc...@gmail.com wrote: On Wed, Jan 14, 2015 at 3:47 PM, Domenic Denicola d...@domenic.me wrote: Isn't this at least a little future-hostile to things like `new MyElement(attrs)`? Is there a way we could get back to that in the future, in your mind? If this is what is desired, HTMLElement can pass all its arguments to createdCallback, i.e. call createdCallback(...args) in its constructor. Since default constructors pass all their arguments upstream, new MyElement(attrs) will pass attrs as arguments to HTMLElement constructor. HTMLElement constructor needs no arguments itself, so it will pass all of those to MyElement's createdCallback. Another option is to provide a species function, which would be what the UA calls. One of the problems with just forwarding the args is that the default arguments to HTMLElement constructor already has a bunch of parameters, as in the strawman at https://github.com/domenic/element-constructors/blob/master/element-constructors.js#L88 Can you say more about why same-identity upgrading is critical to the design (as opposed to dom-mutation upgrading)? I asked up-thread but didn't get any takers. I think these points have been pointed out before but I'll list them again: * Identity - Elements used as keys in maps etc * Hidden state - cloneNode copies some internal state but generally not enough (scroll position, selection, event listeners etc) * Mutation record spam * JS properties that are not reflected are lost On a final note, we could further bikeshed the name of createdCallback(), e.g. to either use a symbol or to be named something short and appealing like initialize() or create(), if that would make it even more appealing :) I think symbols are actually pretty important here. To elaborate, I envision a future where Ember tries to move its Component API to be just a DOM subclass. So when you inherit from Ember's `Component`, you're actually inheriting from a DOM `HTMLElement` too. document.register('my-element', class extends EmberComponent { }); But Ember already has a whole suite of methods and properties on `Ember.Component`, some of which may accidentally conflict with these callbacks (now and in the future). More generally, once people start writing libraries of HTMLElement subclasses, our ability to add new callback names for all elements is going to become pretty dicey, and we'll probably be forced into symbols anyway. We may as well avoid a future inconsistency and just namespace DOM-supplied callbacks separately from user-supplied properties and methods. I'm sympathetic to this but I think it is fine that DOM continues to define new string based property names. Anytime we add a new property to an existing class we run into this issue and I don't think we want to give up on the superior usability of string based property names. -- erik
Re: Minimum viable custom elements
On Thu, Jan 15, 2015 at 5:12 PM, Kenneth Rohde Christiansen kenneth.christian...@gmail.com wrote: Anne, maybe you could write on the wiki what the current Web Components implementation in Chrome is using. That would make it a bit easier to follow for people who didn't follow all of the discussion so far. I updated the page to point this out where it wasn't necessarily obvious (and ended up adding a row to the table): https://wiki.whatwg.org/wiki/CustomElements (I also gave Brain transplant an alternative name Dmitry as he made it look rather elegant :-)) -- https://annevankesteren.nl/
Re: Minimum viable custom elements
Thanks, this is very useful! On Thu Jan 15 2015 at 5:40:02 PM Anne van Kesteren ann...@annevk.nl wrote: On Thu, Jan 15, 2015 at 5:12 PM, Kenneth Rohde Christiansen kenneth.christian...@gmail.com wrote: Anne, maybe you could write on the wiki what the current Web Components implementation in Chrome is using. That would make it a bit easier to follow for people who didn't follow all of the discussion so far. I updated the page to point this out where it wasn't necessarily obvious (and ended up adding a row to the table): https://wiki.whatwg.org/wiki/CustomElements (I also gave Brain transplant an alternative name Dmitry as he made it look rather elegant :-)) -- https://annevankesteren.nl/
Re: Custom element design with ES6 classes and Element constructors
We're already doing some crude namespacing with *Callback. I'd expect that as soon as the first iteration of Custom Elements is out, people will copy the *Callback style in user code. This is a powerful point that I definitely agree with. I would not be terribly surprised to find some library on the web already that asks you to create custom elements but encourages you supply a few more library-specific hooks with -Callback suffixes. That makes sense. I am okay with that. :DG
RE: Minimum viable custom elements
From: Dimitri Glazkov [mailto:dglaz...@google.com] Why is Not having identity at creation-time is currently a mismatch with the rest of the platform a problem? Why does it all have to be consistent across the board? Are there any other platform objects that are created by HTML parser or a similar device? In IRC we've been discussing how I don't think there's actually any (observable) mismatch with the rest of the platform if we are careful. In particular, if we make it a rule that when parsing a given fragment, createdCallbacks run in registration order (not, say, in parse order), I think it works. Because then the built-in elements, which are (conceptually) registered first, go through the __proto__-munge + createdCallback() process first. Then, when the createdCallback() for any user-defined elements runs, all existing elements look to be already upgraded. If we want createdCallbacks to run in parse order (which does seem probably better, although I'd be curious for concrete arguments why), then the only deviation required between custom and built-in elements is privileging the native elements with some ability to jump to the front the queue. Which seems pretty reasonable given that we already have lots of cases where custom elements do things sorta-async and native elements need to do things more synchronously.
Re: Minimum viable custom elements
On Thu, Jan 15, 2015 at 12:27 PM, Ryosuke Niwa rn...@apple.com wrote: On Jan 15, 2015, at 11:47 AM, Brian Kardell bkard...@gmail.com wrote: Not to sidetrack the discussion but Steve Faulker made what I think was a valid observation and I haven't seen a response... Did I miss it? When and in which thread? Could you give us a pointer? Earlier in *this* thread. ~TJ
Re: Minimum viable custom elements
On Thu, Jan 15, 2015 at 8:03 AM, Anne van Kesteren ann...@annevk.nl wrote: * I think we could iterate towards a v2 that has an aspect of upgrading but perhaps works a bit differently from the current setup. E.g. a way to include an entire subtree of custom elements with a fallback mechanism of sorts. Or perhaps something inspired by JavaScript modules. Why is Not having identity at creation-time is currently a mismatch with the rest of the platform a problem? Why does it all have to be consistent across the board? Are there any other platform objects that are created by HTML parser or a similar device? * Upgrading can be added, but moving from Brain transplants to a more normal working constructor would be impossible after the fact. Why is this a problem? Is this for design purity? :DG
RE: Minimum viable custom elements
From: Ryosuke Niwa [mailto:rn...@apple.com] Unfortunately for developers, native syntax for inheritance in Stink 2.0 cannot be used to subclass views in Odour. The native syntax for inheritance can definitely be used! You just can't override the constructor, since constructing a view is a very delicate operation. Instead, you can provide some code that runs during the constructor, by overriding a specific method. I wouldn't call this incompatible, any more than saying that ASP.NET Page classes are incompatible with C# classes: http://www.4guysfromrolla.com/articles/041305-1.aspx (you define Page_Load instead of the constructor). I imagine I could find many other frameworks (perhaps ones written for Stink developers?) where when you use a framework and derive from a framework-provided base class, you can't override the framework's methods or constructors directly, but instead have to override provided hooks. If ES6 classes' constructor doesn't fundamentally work with custom elements, then why don't we change the design of ES6 classes. We would essentially be saying that the design of ES6 classes should be built to support one particular construction pattern (two-stage construction), over any others. Why not design it to support three-stage construction? There are surely libraries that have more than two phases of boot-up. One way to think about it is that there is a base constructor for all classes (corresponding, in spec language, to the definition of [[Construct]]), that in the newest TC39 design does the simplest thing possible. The DOM needs a more complicated setup. Shouldn't that be the DOM's responsibility to encode into *its* base constructor? Saying that TC39 doesn't have a time is like saying we can't make a spec change because WG has already decided to move the spec into REC by the end of the year in W3C. That, I certainly agree with. Any process reasons brought up are bogus. But the technical arguments for the simplest base constructor possible in the language are pretty sound. They're in fact reasons that motivated TC39 to go into a last-minute redesign marathon over the holiday weeks, to get *away* from the more complicated base constructor that contained a two-stage allocation/initialization split.
RE: Minimum viable custom elements
Steve's concerns are best illustrated with a more complicated element like button. He did a great pull request to the custom elements spec that contrasts all the work you have to do with taco-button vs. button is=tequila-button: https://w3c.github.io/webcomponents/spec/custom/#custom-tag-example vs. https://w3c.github.io/webcomponents/spec/custom/#type-extension-example The summary is that you *can* duplicate *some* of the semantics and accessibility properties of a built-in element when doing custom tags, but it's quite arduous. (And, it has minor undesirable side effects, such as new DOM attributes which can be overwritten, whereas native role semantics are baked in.) Additionally, in some cases you *can't* duplicate the semantics and accessibility: https://github.com/domenic/html-as-custom-elements/blob/master/docs/accessibility.md#incomplete-mitigation-strategies An easy example is that you can never get a screen reader to announce custom-p as a paragraph, while it will happily do so for p is=custom-p. This is because there is no ARIA role for paragraphs that you could set in the createdCallback of your CustomP. However, this second point is IMO just a gap in the capabilities of ARIA that should be addressed. If we could assume it will be addressed on the same timeline as custom elements being implemented (seems ... not impossible), that still leaves the concern about having to duplicate all the functionality of a button, e.g. keyboard support, focus support, reaction to the presence/absence of the disabled attribute, etc. -Original Message- From: Edward O'Connor [mailto:eocon...@apple.com] Sent: Thursday, January 15, 2015 18:33 To: WebApps WG Subject: Re: Minimum viable custom elements Hi all, Steve wrote: [I]t also does not address subclassing normal elements. Again, while that seems desirable Given that subclassing normal elements is the easiest and most robust method (for developers) of implementing semantics[1] and interaction support necessary for accessibility I would suggest it is undesirable to punt on it. Apologies in advance, Steve, if I'm missing something obvious. I probably am. I've been writing an article about turtles and I've gotten to the point that six levels of headings aren't enough. I want to use a seventh-level heading element in this article, but HTML only has h1–6. Currently, without custom elements, I can do this: div role=heading aria-level=7Cuora amboinensis, the southeast Asian box turtle/div Suppose instead that TedHaitchSeven is a subclass of HTMLElement and I've registered it as ted-h7. In its constructor or createdCallback or whatever, I add appropriate role and aria-level attributes. Now I can write this: ted-h7Cuora amboinensis, the southeast Asian box turtle/ted-h7 This is just as accessible as the div was, but is considerably more straightforward to use. So yay custom elements! If I wanted to use is= to do this, I guess I could write: h1 is=ted-h7Cuora amboinensis, the southeast Asian box turtle/h1 How is this easier? How is this more robust? I think maybe you could say this is more robust (if not easier) because, in a browser with JavaScript disabled, AT would see an h1. h1 is at least a heading, if not one of the right level. But in such a browser the div example above is even better, because AT would see both that the element is a heading and it would also see the correct level. OK, so let's work around the wrong-heading-level-when-JS-is-disabled problem by explicitly overriding h1's implicit heading level: h1 is=ted-h7 aria-level=7Cuora amboinensis, the southeast Asian box turtle/h1 I guess this is OK, but seeing aria-level=7 on and h1 rubs me the wrong way even if it's not technically wrong, and I don't see how this is easier or more robust than the other options. Thanks, Ted
Re: Minimum viable custom elements
Hi all, Steve wrote: [I]t also does not address subclassing normal elements. Again, while that seems desirable Given that subclassing normal elements is the easiest and most robust method (for developers) of implementing semantics[1] and interaction support necessary for accessibility I would suggest it is undesirable to punt on it. Apologies in advance, Steve, if I'm missing something obvious. I probably am. I've been writing an article about turtles and I've gotten to the point that six levels of headings aren't enough. I want to use a seventh-level heading element in this article, but HTML only has h1–6. Currently, without custom elements, I can do this: div role=heading aria-level=7Cuora amboinensis, the southeast Asian box turtle/div Suppose instead that TedHaitchSeven is a subclass of HTMLElement and I've registered it as ted-h7. In its constructor or createdCallback or whatever, I add appropriate role and aria-level attributes. Now I can write this: ted-h7Cuora amboinensis, the southeast Asian box turtle/ted-h7 This is just as accessible as the div was, but is considerably more straightforward to use. So yay custom elements! If I wanted to use is= to do this, I guess I could write: h1 is=ted-h7Cuora amboinensis, the southeast Asian box turtle/h1 How is this easier? How is this more robust? I think maybe you could say this is more robust (if not easier) because, in a browser with JavaScript disabled, AT would see an h1. h1 is at least a heading, if not one of the right level. But in such a browser the div example above is even better, because AT would see both that the element is a heading and it would also see the correct level. OK, so let's work around the wrong-heading-level-when-JS-is-disabled problem by explicitly overriding h1's implicit heading level: h1 is=ted-h7 aria-level=7Cuora amboinensis, the southeast Asian box turtle/h1 I guess this is OK, but seeing aria-level=7 on and h1 rubs me the wrong way even if it's not technically wrong, and I don't see how this is easier or more robust than the other options. Thanks, Ted
RE: Defining a constructor for Element and friends
I've updated my element constructors sketch at https://github.com/domenic/element-constructors/blob/master/element-constructors.js with a design that means no subclasses of HTMLElement (including the built-in elements) need to override their constructor or [Symbol.species](). It also uses an options argument for the constructors so it is more extensible in the future (e.g. Yehuda's attributes (or was it properties?) argument). It mostly doesn't delve into custom elements, but does contain a small sample to illustrate how their don't need to override the constructor or [Symbol.species] either, and how their constructor works exactly the same as that of e.g. HTMLParagraphElement. One interesting thing that falls out of the design is that it's trivial to allow a custom element class to be registered for multiple names; it requires no more work on the part of the class author than writing a class that corresponds to a single name, and is painless to use for consumers. -Original Message- From: Domenic Denicola [mailto:d...@domenic.me] Sent: Friday, January 9, 2015 20:01 To: Anne van Kesteren; WebApps WG; www-...@w3.org Subject: RE: Defining a constructor for Element and friends OK, so I've thought about this a lot, and there was some discussion on an unfortunately-TC39-private thread that I want to put out in the open. In [1] I outlined some initial thoughts, but that was actually a thread on a different topic, and my thinking has evolved. [1]: http://lists.w3.org/Archives/Public/public-webapps/2015JanMar/0035.html I was writing up my ideas in an email but it kind of snowballed into something bigger so now it's a repo: https://github.com/domenic/element-constructors One primary concern of mine is the one you mention: whether it is acceptable to have an element whose name is a, namespace is the HTML namespace, and interface is Element I do not really think this is acceptable, and furthermore I think it is avoidable. In the private thread Boris suggested a design where you can do `new Element(localName, namespace, prefix)`. This seems necessary to explain how `createElementNS` works, so we do want that. He also suggested the following invariants: 1. The localName and namespace of an element determine its set of internal slots. 2. The return value of `new Foo` has `Foo.prototype` as the prototype. I agree we should preserve these invariants, but added a few more to do with keeping the existing (localName, namespace) - constructor links solid. I've outlined the added invariants in the readme of the above repo. Other points of interest: - Explainer for a very-recently-agreed-upon ES6 feature that helps support the design: https://github.com/domenic/element-constructors/blob/master/new-target-explainer.md - Jump straight to the code: https://github.com/domenic/element-constructors/blob/master/element-constructors.js - Jump straight to the examples of what works and what doesn't: https://github.com/domenic/element-constructors/blob/master/element-constructors.js#L194 One ugly point of my design is that the constructor signature is `new Element(localName, document, namespace, prefix)`, i.e. I require the document to be passed in. I am not sure this is necessary but am playing it safe until someone with better understanding tells me one way or the other. See https://github.com/domenic/element-constructors/issues/1 for that discussion. --- As for how this applies to custom elements, in the private thread Boris asked: what is the use case for producing something that extends HTMLImageElement (and presumably has its internal slots?) but doesn't have img as the tag name and hence will not have anything ever look at those internal slots? Elsehwere on this thread or some related one IIRC he pointed out code that looks at the local name, finds img, and casts to the C++ backing representation of HTMLImageElement. So from what I am gathering in his view the parts of the platform that treat img elements specially currently work by checking explicitly that something has local name img (and HTML namespace). From a naïve authoring point of view that seems suboptimal. I'd rather be able to do `class MyImg extends HTMLImageElement { constructor(document) { super(document); } }` and have MyImg instances treated specially by the platform in all the ways img currently is. Or, for an easier example, I'd like to be able to do `class MyQ extends HTMLQuoteElement { constructor(document) { super(document); } }` and have `(new MyQ()).cite` actually work, instead of throw a cite getter incompatible with MyQ error because I didn't get the HTMLQuoteElement internal slots. The logical extension of this, then, is that if after that `document.registerElement` call I do `document.body.innerHTML = my-q cite=fooblah/my-q` I'd really like to see `document.querySelector(my-q).cite` return `foo`. However this idea that we'd like custom elements which inherit from
Re: Minimum viable custom elements
On Jan 15, 2015, at 11:28 AM, Domenic Denicola d...@domenic.me wrote: From: Dimitri Glazkov [mailto:dglaz...@google.com] Why is Not having identity at creation-time is currently a mismatch with the rest of the platform a problem? Why does it all have to be consistent across the board? Are there any other platform objects that are created by HTML parser or a similar device? In IRC we've been discussing how I don't think there's actually any (observable) mismatch with the rest of the platform if we are careful. In particular, if we make it a rule that when parsing a given fragment, createdCallbacks run in registration order (not, say, in parse order), I think it works. Because then the built-in elements, which are (conceptually) registered first, go through the __proto__-munge + createdCallback() process first. Then, when the createdCallback() for any user-defined elements runs, all existing elements look to be already upgraded. If we want createdCallbacks to run in parse order (which does seem probably better, although I'd be curious for concrete arguments why), then the only deviation required between custom and built-in elements is privileging the native elements with some ability to jump to the front the queue. Which seems pretty reasonable given that we already have lots of cases where custom elements do things sorta-async and native elements need to do things more synchronously. Let's think about this for a minute. Imagine that a hypothetical technology company Durian which has a popular platform called dOS with its own UI framework called Odour coupled with a programming language named Stink. In their exciting annual developer conference of the year, Durian introduces Stink 2.0 which supports proper OOP as well as a way to subclass a view in Odour. Developers rejoice for finally being able to use constructors, inheritance, etc… and subclass views in their applications. Unfortunately for developers, native syntax for inheritance in Stink 2.0 cannot be used to subclass views in Odour. In order to inherit from a view in Odour, Durian explains, developers must use a helper function. Developers outrage in despair and yells, why on the earth did you have to make them incompatible? I ask the same question. If ES6 classes' constructor doesn't fundamentally work with custom elements, then why don't we change the design of ES6 classes. Saying that TC39 doesn't have a time is like saying we can't make a spec change because WG has already decided to move the spec into REC by the end of the year in W3C. We shouldn't be making technical decisions like that especially for something as fundamental as supporting classes in the Web. - R. Niwa
oldNode.replaceWith(...collection) edge case
Currently, for `oldNode.replaceWith(…collection)`, if `collection` is array of multiple nodes, and `oldNode` is in `collection`, after the mutation method macro, `oldNode` lives in a doc frag. So in the replace algorithm, `parent` is the doc frag, `node` is also the doc frag, an `HierarchyRequestError` is thrown. I wonder if an error really should be thrown in this case? Intuitively, `collection` should be inserted before `oldNode`’s original next sibling. For example: ``` div id=d1/div div id=d2/div div id=d3/div div id=d4/div ``` Imagine `oldNode` is #d2, `collection` is [#d1,#d2,#d4], executing `oldNode.replaceWith(…collection)` should give ``` div id=d1/div div id=d2/div div id=d4/div div id=d3/div ``` Instead of throwing an error. To make it this work, before executing the mutation method macro, `oldNode`’s parent should be saved. It’s next sibling should also be saved, but the next sibling need to be found recursively if it happens to be in `collection` too. So, If I’m not wrong, this edge case could work in principle. I’m not sure if there is any interest to allow this?
Re: oldNode.replaceWith(...collection) edge case
Another way to do this is that in mutation method macro, prevent `oldNode` from being added to the doc frag, and after that, insert the doc frag before `oldNode`, finally remove `oldNode`. No recursive finding of next sibling is needed this way. On Jan 16, 2015, at 1:37 PM, Glen Huang curvedm...@gmail.com wrote: Currently, for `oldNode.replaceWith(…collection)`, if `collection` is array of multiple nodes, and `oldNode` is in `collection`, after the mutation method macro, `oldNode` lives in a doc frag. So in the replace algorithm, `parent` is the doc frag, `node` is also the doc frag, an `HierarchyRequestError` is thrown. I wonder if an error really should be thrown in this case? Intuitively, `collection` should be inserted before `oldNode`’s original next sibling. For example: ``` div id=d1/div div id=d2/div div id=d3/div div id=d4/div ``` Imagine `oldNode` is #d2, `collection` is [#d1,#d2,#d4], executing `oldNode.replaceWith(…collection)` should give ``` div id=d1/div div id=d2/div div id=d4/div div id=d3/div ``` Instead of throwing an error. To make it this work, before executing the mutation method macro, `oldNode`’s parent should be saved. It’s next sibling should also be saved, but the next sibling need to be found recursively if it happens to be in `collection` too. So, If I’m not wrong, this edge case could work in principle. I’m not sure if there is any interest to allow this?
Re: Minimum viable custom elements
Not to sidetrack the discussion but Steve Faulker made what I think was a valid observation and I haven't seen a response... Did I miss it?
Re: CfC: publish FPWD of Packaging on the Web; deadline November 3
On 10/27/14 12:34 AM, Arthur Barstow wrote: Jeni and the TAG would like to publish - on behalf of both the TAG and WebApps - a First Public Working Draft (FPWD) of the Packaging on the Web specification and this is a Call for Consensus (CfC) to do so using the following ED as the basis: http://w3ctag.github.io/packaging-on-the-web/ FYI, this FPWD was published today http://www.w3.org/TR/2015/WD-web-packaging-20150115/. Sorry for the delay. -AB
Re: Minimum viable custom elements
On Thu, Jan 15, 2015 at 6:43 PM, Domenic Denicola d...@domenic.me wrote: Steve's concerns are best illustrated with a more complicated element like button. He did a great pull request to the custom elements spec that contrasts all the work you have to do with taco-button vs. button is=tequila-button: https://w3c.github.io/webcomponents/spec/custom/#custom-tag-example vs. https://w3c.github.io/webcomponents/spec/custom/#type-extension-example The summary is that you *can* duplicate *some* of the semantics and accessibility properties of a built-in element when doing custom tags, but it's quite arduous. (And, it has minor undesirable side effects, such as new DOM attributes which can be overwritten, whereas native role semantics are baked in.) Additionally, in some cases you *can't* duplicate the semantics and accessibility: https://github.com/domenic/html-as-custom-elements/blob/master/docs/accessibility.md#incomplete-mitigation-strategies An easy example is that you can never get a screen reader to announce custom-p as a paragraph, while it will happily do so for p is=custom-p. This is because there is no ARIA role for paragraphs that you could set in the createdCallback of your CustomP. However, this second point is IMO just a gap in the capabilities of ARIA that should be addressed. If we could assume it will be addressed on the same timeline as custom elements being implemented (seems ... not impossible), that still leaves the concern about having to duplicate all the functionality of a button, e.g. keyboard support, focus support, reaction to the presence/absence of the disabled attribute, etc. -Original Message- From: Edward O'Connor [mailto:eocon...@apple.com] Sent: Thursday, January 15, 2015 18:33 To: WebApps WG Subject: Re: Minimum viable custom elements Hi all, Steve wrote: [I]t also does not address subclassing normal elements. Again, while that seems desirable Given that subclassing normal elements is the easiest and most robust method (for developers) of implementing semantics[1] and interaction support necessary for accessibility I would suggest it is undesirable to punt on it. Apologies in advance, Steve, if I'm missing something obvious. I probably am. I've been writing an article about turtles and I've gotten to the point that six levels of headings aren't enough. I want to use a seventh-level heading element in this article, but HTML only has h1–6. Currently, without custom elements, I can do this: div role=heading aria-level=7Cuora amboinensis, the southeast Asian box turtle/div Suppose instead that TedHaitchSeven is a subclass of HTMLElement and I've registered it as ted-h7. In its constructor or createdCallback or whatever, I add appropriate role and aria-level attributes. Now I can write this: ted-h7Cuora amboinensis, the southeast Asian box turtle/ted-h7 This is just as accessible as the div was, but is considerably more straightforward to use. So yay custom elements! If I wanted to use is= to do this, I guess I could write: h1 is=ted-h7Cuora amboinensis, the southeast Asian box turtle/h1 How is this easier? How is this more robust? I think maybe you could say this is more robust (if not easier) because, in a browser with JavaScript disabled, AT would see an h1. h1 is at least a heading, if not one of the right level. But in such a browser the div example above is even better, because AT would see both that the element is a heading and it would also see the correct level. OK, so let's work around the wrong-heading-level-when-JS-is-disabled problem by explicitly overriding h1's implicit heading level: h1 is=ted-h7 aria-level=7Cuora amboinensis, the southeast Asian box turtle/h1 I guess this is OK, but seeing aria-level=7 on and h1 rubs me the wrong way even if it's not technically wrong, and I don't see how this is easier or more robust than the other options. Thanks, Ted I think you really need look no further than HTML as Custom Elements work to see how difficult it would be to get accessibility right even if we had good APIs, which, as Domenic pointed out, we really don't. Anyway, it seems like one of the biggest criticisms we have seen of custom elements anyone has made has to do with accessibility... It definitely doesn't seem desirable to make it *harder* to get that right if we can avoid it, because this could definitely play into the success or failure story writ large. -- Brian Kardell :: @briankardell :: hitchjs.com
Re: Minimum viable custom elements
On Jan 15, 2015, at 3:17 PM, Domenic Denicola d...@domenic.me wrote: From: Ryosuke Niwa [mailto:rn...@apple.com] If ES6 classes' constructor doesn't fundamentally work with custom elements, then why don't we change the design of ES6 classes. We would essentially be saying that the design of ES6 classes should be built to support one particular construction pattern (two-stage construction), over any others. Why not design it to support three-stage construction? There are surely libraries that have more than two phases of boot-up. One way to think about it is that there is a base constructor for all classes (corresponding, in spec language, to the definition of [[Construct]]), that in the newest TC39 design does the simplest thing possible. The DOM needs a more complicated setup. Shouldn't that be the DOM's responsibility to encode into *its* base constructor? No, DOM doesn't require two-stage construction any more than a regular builtin objects in ES6. The only reason you need to have the two-stage setup is because you want to support asynchronous upgrading of elements. As we have repeatedly stated in the past, we don't support a design that involves upgrading elements after the element construction if it meant that we can't use ES6 constructor in the non-upgrade case. We'll submit a formal objection if necessary. Saying that TC39 doesn't have a time is like saying we can't make a spec change because WG has already decided to move the spec into REC by the end of the year in W3C. That, I certainly agree with. Any process reasons brought up are bogus. But the technical arguments for the simplest base constructor possible in the language are pretty sound. They're in fact reasons that motivated TC39 to go into a last-minute redesign marathon over the holiday weeks, to get *away* from the more complicated base constructor that contained a two-stage allocation/initialization split. That's fine. And I'm suggesting to do the same (picking the simplest design) in HTML custom elements by only supporting synchronous definition of elements, and letting authors and frameworks decide how to upgrade existing elements if they want to. - R. Niwa
Re: Minimum viable custom elements
On Jan 14, 2015, at 12:52 PM, Dimitri Glazkov dglaz...@google.com wrote: FWIW, I think that element upgrade is sort of fundamental to the usefulness of custom elements. In a world where most scripts are non-blocking (that's hopefully the modern world we should aim for), I'll effectively expect to walk the tree anyway. Allowing loading scripts asynchronously, including ones that define custom elements, is one thing; automatically resolving script dependencies for custom elements is another. When an author imports a ES6 module, we don't create a fake object which gets resolved later by rewriting its prototype. Even if we were to agree this is desirable, I don't think we're ready to bake the exact mechanism by which such asynchronous custom elements upgrades happens in the browser since the introduction of ES6 models is likely rewriting the landscape of how authors load external dependencies soon. Of course, I'm sympathetic to the view that we should make upgrading easier; e.g. by exposing the list of event listeners attached on an element so that replacing/cloning an element will be easier. - R. Niwa
Re: Custom element design with ES6 classes and Element constructors
On Thu, Jan 15, 2015 at 5:11 AM, Yehuda Katz wyc...@gmail.com wrote: Can you say more about why same-identity upgrading is critical to the design (as opposed to dom-mutation upgrading)? I asked up-thread but didn't get any takers. I tried to summarize the various upgrade scenarios here (as well as the other issues): https://wiki.whatwg.org/wiki/CustomElements None of them seem particularly attractive :-( More generally, once people start writing libraries of HTMLElement subclasses, our ability to add new callback names for all elements is going to become pretty dicey, and we'll probably be forced into symbols anyway. We may as well avoid a future inconsistency and just namespace DOM-supplied callbacks separately from user-supplied properties and methods. Agreed that now that we have symbols we should start using them to avoid collisions. -- https://annevankesteren.nl/
Re: Minimum viable custom elements
On Jan 15, 2015, at 11:47 AM, Brian Kardell bkard...@gmail.com wrote: Not to sidetrack the discussion but Steve Faulker made what I think was a valid observation and I haven't seen a response... Did I miss it? When and in which thread? Could you give us a pointer? - R. Niwa