The is="" attribute is confusing? Maybe we should encourage only ES6 class-based extension. #509
|
This was previously discussed at length in the other bug tracker, and it's explained in the spec in the sentence above that:
|
|
@domenic That quote that you referred to makes me think exactly the same thing as I just wrote:
You're pointing to something that exists in a spec, but I'm saying it doesn't have to be that way, specs can be modified. There is a solution (I don't know what that solution is specifically yet, but I know that the hardware on any computer that runs a browser nowadays isn't a limitation, and the only limitation is in the software we write, which can be modified). I simply can't understand why an HTML engine must need I wish I had the time and resources to read the Chromium source in order to point to an actual solution (someone else can write the spec, as I'm not even good at reading those), but in the meantime, I'm 100% sure a backwards-compatible programmatic solution exists. |
|
Yes, everything is Turing machines and everything can be implemented. However, there are real-world constraints---both in implementation complexity and in ecosystem impact---that make it not desirable. |
|
Some things are complex to implement, but this particular change doesn't seem to be. :] Would you mind kindly pointing to the complexity and impact that make it non-desirable? Is it because if the element isn't registered (i.e. with JS turned off) that the browser won't know to at least render a fallback What other reason might there be? |
|
When someone who comes from React tries to learn Custom Elements for the first time (which is more likely to happen than someone learning Custom Elements first due to the mere fact that specs are hard to read compared to things like React docs, unfortunately, because specs are meant for implementers, and the actual usage docs if any are sometimes limited or hard to find), they'll face these weird things like the redundant This is what classes are for, and in the case of the HTML engine where multiple types of elements may share the same interface (which is probably a partial cause to any current problems) the third argument to I'd take this further and propose that every single built in element should have a single unique associated class, and therefore ES2015 class extension would be the only required form of extension definition. Just in case, let me point out we must currently specify an extension three whole times. For example, to extend a button: class MyButton extends HTMLButtonElement {} // 1
customElements.define('my-button', MyButton, { extends: 'button' }) // 2<button is="my-button"></button> <!-- 3 -->That's three times we've needed to specify that we're extending something, just to extend one thing. Doesn't this strike you as a bad idea from an end-user perspective? It should ideally just be this, assuming that there is a one-to-one relationship between built-in elements and JS classes: class MyButton extends HTMLButtonElement {} // 1
customElements.define('my-button', MyButton)<my-button></my-button>I get what you're saying about complexities and real-world world constraints, but I think "breaking the web" might actually fix the web in the long run. There can be an API cleansing, and websites may have to specify that the new breaking-API is to be used by supplying an HTTP header. Previous behavior can be supported for a matter of years and finally dropped, the new API becoming default at that time. Sites that don't update within a matter of years probably aren't cared for anyways. I'm just arguing for a better web overall, and breaking changes are sometimes necessary. It seems I may be arguing for this forever though. Unless I am an employee at a browser vendor, I'm not sure my end-user viewpoints matter much. The least I can do is share them. |
|
The problem here is that UA internally checks local name e.g. Now I'm going to re-iterate that Apple objects to extending subclasses of |
I think that relying on element tag names might be a bad idea, especially if we give users ability to scope elements on a per-shadow-root basis (now that's a good idea!). If we can allow end users of a custom element to assign any name they wish to that custom element used within the user's component (within the user's component's inner shadow tree), then we can avoid the global mess that In React (by contrast) the creator of a component never decides what the name of that component will be in the end user's inner tree. The end user has full control over the name of an imported component thanks to ES6 Modules. We can encourage a similar concept by introducing a per-shadow-root custom element registration feature. If we can map names to classes without collision and without two names assigned to the same class (i.e. without elements like This API is still v0 in practice, so I think there's room for modification even if v1 is on the verge of coming out.
I think Webkit not implementing If we continue with globally registered elements, it will be inevitable that some two components in an app will have a name collision, and that the developer of that app will attempt to fix the problem by modifying the source of one custom element (possibly requiring forking of an NPM module, pushing to a new git repo, publishing a new module, etc, time consuming things) just to change the name of that element; it'd be a pain and can introduce unexpected errors if parts of the modified code are relying on the old tag names. TLDR, if we put more care into the JavaScript aspects of an element (f.e. choosing which class represents an element, which is already happening in v1) then we'll have a more solid Web Component design, and we can drop |
|
@domenic Can you describe the "ecosystem impact" that you might know of? |
|
I am referring to the various tools which key on local name, including JavaScript frameworks, HTML preprocessors and postprocessors, HTML conformance checkers, and so on. |
|
I think I know what you mean. For example, search engines read the tag names from the markup in order to detect what type of content and how to render it in the search results. This point may be moot because today it completely possible to use a root <html>
<head>
<title>foo</title>
</head>
<body>
<app></app>
</body>
</html>That's functionally equivalent to an app with no shadow roots and made entirely of randomly named elements: <html>
<head>
<title>foo</title>
</head>
<body>
<asf>
<oiur>
...
</oiur>
<urvcc>
...
</urvcc>
</asf>
</body>
</html>Based on that, I don't think it's necessary to keep element names. I imagine a couple remedies:
|
|
I'll note that we've vocally and repeatedly objected to having |
|
Itโs important to note that a lot of elements are implemented partially (or completely) with CSS. So, in order to support this and allow user agents to continue to implement elements like they do today, a new CSS pseudo-class would be needed: |
Not really. The point of the |
|
@chaals right. You would need the pseudo-class if using a custom element that extends a native button could be done like |
|
Also, like @trusktr said, if this and whatwg/html#896 become a thing, I think itโll be possible to remove altogether the Offering this as an alternative to the current way of defining extending native elements โ allowing user agent developers and authors to choose which they want to use โ is the best solution in my opinion. As @trusktr said, โI think โbreaking the webโ might actually fix the web in the long runโ. |
|
(@Zambonifofex it's generally not clear to me what you mean when you say "this", which makes it hard to engage)
I've tried breaking the Web, at the turn of the century when it was smaller, to do something that would have been really useful. It failed. For pretty much the reasons given by people who say "you can't break the web". Although user agent developers are less reluctant to break things than they were a decade ago, they're still very reluctant, and I believe with very good reason. I think a strategy reliant on breaking the Web to fix it is generally a non-starter, even if the alternatives are far more painful. |
|
For what it's worth, I agree with @rniwa's characterisation - we have an agreement that we won't write |
When I say โthisโ I mean โthis issueโ; the suggestion made by @trusktr in the first comment of this thread. But, honestly, โ not that Iโd be able to know, as Iโve never touched any browserโs code โ I think that this would be a much easier change to make for user agent developers than you guys are making it out to be. |
|
I mean, sure, it could be slightly annoying to go and change all of the checks for the tag name to something else, but would it be actually hard? |
|
The <my-el></my-el>class MyEl extends HTMLElement { /*... */ }
MyEl.extends = 'div'
document.registerElement('my-el', MyEl)
// ...
document.querySelector('my-el') instanceof MyEl // true or false? |
|
We should make the result of <my-el></my-el>class MyEl extends HTMLDivElement { /*... */ }
customElements.define('my-el', MyEl)
// ...
document.querySelector('my-el') instanceof MyEl // true! |
|
I forgot this line too, in the previous comment: document.querySelector('my-el') instanceof HTMLDivElement // also true! |
|
(@domenic I'm still using v0 in Chrome) |
I think you meant "instance" instead of "intense"? This seems to be the reason why I am against both of those methods of defining extension, as I believe encouraging ES6 Classes as the the tool for defining extension will reduce room for confusion. |
|
Perhaps existing native elements should be re-worked so that any differences they have should rather be described (explained) by using class extension, and not using those other two methods ( |
|
FWIW, we're against subclassing subclasses of |
|
@rniwa if you could enumerate a couple of these โvarious reasonsโ or link to some previous discussion on this subject that lead to this conclusion, itโd be appreciated. |
|
@rniwa I second @Zambonifofex, would love to know the rational behind this. In the case of needing features exclusive to native elements, how would someone use these features on a custom element without extending it? An example my company is dealing with is replicating the sizing of a native |
|
@bedeoverend I donโt think they are against extending native elements, they are simply against classes extending subclasses of |
|
We won't be supporting One fundamental problem is that subclassing a subclass of In addition, none of the builtin elements are designed to be subclassed, and in fact, we don't have builtin subclasses of Finally, the whole design of |
@rniwa True, which is why we should avoid subclassing when we can, but I think it's needed in order to fix the mistake that was made with Maybe we would need to reserve |
|
Yeah, there has been a discussion about that for |
|
I believe that would be totally fine along with agreement that subclassing in general is better avoided when possible. Nothing's perfect, but having those new subclasses for end-webdevs to extend from is already better than |
While I can agree is="" is not perfect---perhaps even "a hack", although IMO a pretty reasonable one---I think this opinion is just wrong. Web devs and users both benefit greatly from the ability to extend built-in elements, and is="" is the most practical solution so far. That is why the consensus was to keep is="" in the spec and let implementations decide its fate: because it allows developers to write less code and get more correct behavior, and because it helps users---especially disabled users---interact with web pages in a more predictable and easy manner. You can talk about how you dislike the technical aspects of is="" as a solution, but I think it's very unfair to say that omitting is="" is better for webdevs (or even "end-webdevs", although I'm not sure what those are). |
|
I've built web components for many years and talk with a lot of web developers regularly about them. I'd like to look at this question from their perspective. Devs don't care about implementation challenges or diving into the weeds. We need to keep customized built-in elements. CE v1 is not a spec without a way to extend existing HTML elements. My talk at the Progressive Web App Summit highlights some of the reasons why it's important to keep:
Whether Ultimately, developers have to write less code with |
Thatโd hopefully still be the case if |
|
I don't get why people keep making claims that In reality, a lot of custom form controls exist on the web for the sole purpose of customizing appearances against their builtin counterparts. Unfortunately, as soon as you've attached shadow root on a builtin element which is not even supported in shadow DOM v1, there is no accessibility benefit from using |
|
is@ is critical for supporting reasonable AX for links. We tried to replicate the subtle focus and keyboard behavior of I could be convinced that we don't need to allow subclassing input, but I think links are super important. Note also that developers have been using template with is@ very successfully over the past 3 years. Fwiw we also hope to introduce a unique class per tagName, so we would add all six classes for headers etc. It makes the platform make much more sense. :) |
|
My 2 cents, FWIW, Crawlers, old and new users, browsers themselves before they load non blocking async info about the custom elements, just to name few that benefits from It also shipped 3 years ago and it worked de-facto pretty well on real-world production sites. I'm not sure why this bug is still opened or still considered as something to be changed. |
|
Whatever happens here, platform consistency should be considered highly important. If all browsers but WebKit support |
|
WebKit works well through this polyfill of v0 that will eventually be upgraded to support v1 as soon as it's stable (I don't want to repeat the effort for something not final yet) Best of all, you can IE8 or even IE5 this page and always see where's your business. http://webreflection.github.io/document-register-element/test/examples/x-map.html You can disable everything you want, you gonna see what the map is supposed to show anyway |
|
@rniwa if it's been proved it works and scale well, I am not sure why WebKit would avoid it at all costs. The result might be some nasty user-land overwrite/interception in order to make it work in there too (like a polyfill would do). Moreover, the argument about violating the Liskov substitution principle doesn't feel appropriate for the Web environment. The entire global scope/context can be polluted (and it is) dozens of times by all libraries out there, with or without a namespace. That doesn't prevent standard bodies to implement As summary: in a parallel universe where developers couldn't change the environment your point would be more than valid, but I think that's not really how the real-Web-world moved forward for the last 20 years. If every other vendor agreed, please consider to follow this de-facto need and pragmatic solution for the sake of the Web, thank you. |
Well, since noโone else seems to agree with me and @trusktr, I think Iโm fine with this being closed. I still donโt like |
|
@Zambonifofex the DOM is old and not perfect, neither is the An example over every other, is the bloody TL;DR nobody likes The previous Why not closing this chapter and move forward then, since there are no equivalent solutions that either work or that have been even proposed? So please, let's implement |
|
That's very unfortunate. @paulkinlan wrote a great piece on platform inconsistencies recently, "The Lumpy Web".
I hope this inconsistency doesn't become detrimental to the adoption of Custom elements. |
|
The thing is, Apple has been objecting to this feature from the get go, and the only reason it remains in the spec is because Google kept objecting to it being removed from the spec. The fact of matter is, we only agreed to keep it in the spec to wait until the feature becomes at-risk at CR stage so that it can be removed. It's extremely frustrating for you to then make arguments to implement this feature after the fact. We've had this discussion before, and nothing has changed. So why do you think keep making the same arguments would change anything? |
|
'cause we're all thinking, reasonable, people and Custom elements with |
Sorry, I don't mean to minimize previous spec discussions. There are a ton of historical conversations that have taken place outside this bug...over many many years! It's hard to follow Webkit's full reasoning without that reasoning being documented here. Would be nice to have a summary on this bug. I think what you're seeing now is feedback from the actual dev community. Web developers don't participate in spec discussions. Github bugs makes things more approachable. |
|
Feedback from stakeholders - developers, toolmakers, end users, etc - is valuable. I'm grateful that people have provided it in a constructive and polite manner, because attacking individuals isn't helpful. There doesn't seem to be new information here. There are people who think @rniwa isn't unique in opposing Apple is not unique as an organisation in opposing the attribute. At the same time, there are many who think it is a good idea. Personally I agree with @WebReflection that it is of limited, but real value and we are better off having it than not. As chair, that doesn't mean I can impose it. The attribute is in there for now, with supporters and detractors. Given the obvious lack of consensus to either keep or remove it, the W3C Process includes testing whether there is a likelihood of interoperable implementation which will probably boil down to looking at actual implementation. Nobody is obliged to implement, we will look at what the market does. Apple (and others who share their dislike for The Web doesn't develop in lock step because it isn't imposed by a single actor, and overall that seems to be a strength. It is quite reasonable in a market for some players to decide not to implement something. It is unfortunate that this produces inconsistency at the bleeding edge, but it also gives us great power to let innovations come from anywhere instead of only market-dominating players being able to do it for us. Our process enables this deliberately, for reasons beyond the above. One of them is to make sure our work is not illegal anti-competitive industry collusion. That's important to a lot of companies who are important in this area. Anyone who wants to go further down that topic, which is beyond the scope of the Working Group, can buy me a beer and lecture me or let me lecture them. But please, not here. |
Custom Elements v1 #58
|
An alternative to class FooBarAttr {
attachedCallback() {
console.log('was created for first time');
}
changedCallback(newValue, oldValue) {
console.log('it changed');
}
}
customAttributes.define('foo-bar', FooBarAttr);This would be super simple to polyfill with MutationObservers as well. |
|
@rniwa A solution to this |
|
If you havenโt already, maybe you should create a new issue thread asking for this. It sounds like an excellent idea thatโd get more attention if it was in its own thread. |
|
I believe attributes should be on a per-custom-element basis, otherwise globally registered attributes will get messy quickly. Many custom elements may depend on values of attributes with the same name (I.e. name clashing can become a nasty problem). In native HTML, |
|
What about being able to define both global attributes and attributes on specific elements? customAttributes.define("foo-bar", HTMLElement, FooBarAttr); // Global attribute
customAttributes.define("foo-baz", MyElement, FooBazAttr); // Elementโspecific attributeStill, I like to encourage the practice of pseudoโnamespaces. That is, when writing a library, named, say, โmy libraryโ, instead of having a |
|
I would like to put my small feedback as a web-developer and would like to add another point to @ebidel 's list why It simplifies and optimizes not just styling, accessibility but also parsing. We've created a number of vanilla CEs that extends Removal of |
|
This is just a reminder that my V1 polyfill forces I think we, developers, will find a way to implement
|
|
@tomalec or just |
|
There's been a lot of argument here about why some people like Consider this custom element:
If
If that's the case, how does one implement it so all of the following are true?
|
|
@richardkazuomiller You have MutationObservers at your disposal, so you can mimic everything |
|
@matthewp That defeats the whole purpose of having custom elements and introduces a whole other set of issues. The whole point is that once a custom element is implemented it can be created anywhere and treated the same as any other element. If upgrading the We at least all agree that being able to create a subclass of a native element โ with or without |
|
@richardkazuomiller Webkit is opposed to subclassing native element subclasses outright, see comment from @rniwa above (#509 (comment)) |
|
Oh, I misunderstood subclasses of native element subclasses to mean subclasses of user-defined subclasses. My mistake. So I guess the answer to my (admittedly mostly rhetorical) questions really are "don't use custom elements". That's worse than I thought. In that case I'd like to rebut some of the points made by the anti-is side, from my point of view as a developer.
I've never heard of anyone who found it confusing. The intent of it is clear. Besides, if we bikeshedded every confusing part of the web until everything was perfect we wouldn't have browsers at all.
Things breaking because of an update to a superclass's implementation happens is a fact of life. It should be avoided wherever possible, but eliminating subclassing altogether is not the answer. The possibility of a hypothetical input type being added is not worth throwing away all the possible custom input types developers could be making. Don't throw the baby out with the bathwater
I can say from experience that whether they were designed for it or not, subclassing native elements works very well. While there may be limitations when extending inputs, for example, it's easy to work within those limitations.
I think you're assuming that preserving the builtin UI isn't exactly what a lot of devs are doing. Look at Polymer's iron-input. No crazy shadow DOM stuff, just key bindings and a validator but that alone is very powerful. I've extended One might suggest that instead of extending native elements, we should create some kind of wrapper or bind events when the document loads or something, but custom elements v1 works with elements created with I'm just a lowly webdev, so while I have opinions about the big-picture future-of-the-platform stuff, I'll leave that to you folks. I hope you'll consider my perspective when implementing (or not implementing) the spec. |
|
I would really like to have the ability to use the unreproducible features of native elements in custom ones. I don't really mind if that's through inheritance or some other "mixin" approach. Beyond even accessibility, which to me seems to be the biggest reason to want this, there are things like The problem with The same thing applies with the venerable As I said, I'd be fine with mixins instead of inheritance - has any effort been put into specifying that? Would it mean I could still get all the unreproducible behaviours, of let's say a |
|
FWIW, since "yurak is working on this", I guess all we have to do is wait that Firefox and Edge would follow and keep polyfilling WebKit (hopefully not forever). This is a page to check builtin extend status. This is the same page using my polyfill. |
|
Suppose I'm using for example I'm not trying to argue for or against it, just trying to understand the When it is of interest part better. |
|
@oleersoy I don't think so. |
|
So I just want to confirm that if I'm using In other words there is no point in doing |
|
@oleersoy the
A Last, but not least, if you have a custom element that doesn't need to extend any special functionality beside what Most of the time, that's all you need but as you can see, developers can, and will, use Custom Elements in various ways. I hope I've clarified most common use cases. |
|
@WebReflection Those are some great examples (^_^) @oleersoy To add to the previous comment, The reason an Chrome Developers Supercharged - Accordion |
|
So I'm trying to make my question really simple because I'd like a straightforward answer. If this cannot be answered in terms of yes or no please let me know why. Again I'm asking whether the minute I add the Polymer BTW - I'm saying Polymer specifically because I prefer not get into "Well if it was implemented this way theory". If we expend enough effort we can do anything. Just ask the Microsoft team that tried to integrate the browser into the desktop. |
|
@oleersoy The approach I suggested will work with Polymer's app-drawer. Just use CSS to make the app-drawer show its contents before it's upgraded and remove those styles if Polymer is available. You can probably get more specific and helpful answers about a particular Polymer element if you open an issue on that element's repository. |
|
@richardkazuomiller Thanks that seems reasonable. What if the |
|
If you're using an autonomous custom element (i.e. not using |
Not necessarily true for custom elements in general. Try using ShadowDOM with the A-Frame Custom Elements that are available at http://aframe.io, and you'll see that they won't work as expected (jsfiddles). A-Frame (and any other Custom Element libraries used for constructing custom render trees) need to be able to construct an internal representation of the final flat tree which is the result of composed shadow trees, and then the internal representation of the flat tree can be used (for example) to render a scene in WebGL or Canvas 2D. |
That's pretty orthogonal to what we're discussing here. That's just a limitation on the current shadow DOM API. |
|
@oleersoy Custom elements go through an upgrade process, which means PE is a built-in feature of the API. Consume components under the assumption that JS may never run. Then, sometime in the future JS does run, registers the elements. Boom. You're progressively enhancing that markup. This article and my presentation the PWA summit earlier this year discusses the notion of "progressively enhanced markup". Video. |
|
@ebidel just saw your comment now. Huge fan of your articles! I'll amend my comment a bit in light of yours. OK - Let me reboot my simple scenario and limit it to custom elements and javascript in general. SIDE NOTEMy background and primary reason for looking at all the specs is that I think custom elements and the shadow dom are fantastic tools for simplifying my apps, and my gut feeling is that anytime I create an element that does something beyond just special effects, the app will break given that the custom element API is not supported / The element upgrade has not yet kicked in. I'll illustrate what I mean. END SIDE NOTESo suppose I wrote an app consisting of two custom elements I could also have a So I load this app in a browser that does not support custom elements or will not upgrade them for some reason. The FancyButton falls back to a normal not so fancy button, and when clicked nothing works. So to me it seems as if I want an app that works well on all browsers, then I'm better off with a non custom element approach, but if I want to go bleeding edge and throw some users with dusty browsers under the bus then I would choose custom elements. In other words I simply don't see what advantage |
|
Right, that was one of the arguments we (WebKit team) made to argue against Similarly, anytime a shadow root is attached on a builtin element, we can't simply assume the ARIA role of the underlying element. For example, imagine input's |
|
If your app breaks because a certain API is not available, you're doing progressive enhancement wrong. The argument that a feature doesn't have any advantages because it might break in old browsers could be made about literally any new browser feature and if we accepted that we'd never make anything new. As for the shadow DOM stuff, I honestly don't think that has anything to do with |
|
@oleersoy in that scenario no, fancy-button wouldn't offer progressive enhancement because you're not progressively enhancing a button, you're giving it core functionality that your app is broken without. There are lots of good examples of progressive enhancement enabled by extended builtins (eg: iron-input mentioned above). An example from our own work - we're building a wc content management library, and by extending builtins we can render content to elements before upgrading with editing behaviours, and therefore support legacy browsers, pre-rendering, etc. Without extension this becomes infinitely harder. Also prog enhancement is only one (admittedly very important) upside of type extension. Another is inheriting unreplicable native behaviours (eg: template, anchor, button, img, html, etc). We've found that the 'just wrap the element' hack often falls short (eg: wrapped templates existing in doc flow, losing 1:1 interop with native elements). Given, this could be provided with mixins rather than |
So how would I progressively enhance my very simple app the right way?
That's not the argument I'm making. The first thing I try to do when convincing someone that a feature has clear advantages in terms of:
Is to come up with a really simple example that shows how it does this across the board. I think custom elements, shadow dom, etc. all do this and they are complete no brainers. However I personally don't see a application development scenario where the I provided a very simple application scenario that illustrates my thinking. If @richardkazuomiller and @seaneking could come up with an equally simple scenario that illustrates what you are saying and causes us all to realize that the benefit of implementing If I'm telling a team to consider progressive enhancement and specifically to use the
I think the point of progressive enhancement is that it's progressive. From what @ebidel is saying there are two ways of looking at it. One is that the API for using a component is simply not there so that the component falls back to a more lightweight way of operating. It still works, just not with all the bells and whistles we would like. In the other scenario, the API / native capability is there but the the browser or script has not had a chance to upgrade the element yet. So in this case it's not that the button is not offering PE. It offers it because of how it is declared
That's true because that's up to the runtime (Although I have tried progressively enhancing a few things, but my wife always objects, so I've mostly given up).
I think what you are saying is precisely what I'm trying to illustrate. I have a button that can be progressively enhanced and two custom elements that form the entire app. If those custom elements don't work, the app is broken. So why then use custom elements at all? We are assuming that the
This I totally agree with. I almost tattooed "Just wrap the element" on my forehead once, before getting more smarterer. I would love to see one example that uses custom elements in a minimal and realistic app that demonstrates how Again if there is one way to do it, and we say that we can also do it this way, then there should be some significant advantage over the next 4 years to doing it both ways. Otherwise we are just introducing more stuff to learn about and make decisions with and possibly further complicate a already fairly advanced set of tools with a fairly steep learning curve that we use to produce awesome things and this does does not just waste our time, but the time of millions of developers, maintainers, product managers, and investors. |
I think discussing that is out of the scope of this issue.
See the example in my previous comment |
Of coarse why would the practical application of the technology you are recommending be in the scope of the issue?
I have not seen a single example that makes sense in an application context. If you think that one component makes an application and progressively enhancing a single component in a vacuum is a great reason to ask millions of developers and product managers to understand this topic then good luck convincing Apple and MS. "Here guys this is going to useful to you 0.0000000001% if the time. Bon appetit!!". |
Your example, a specific use case that ignores all other already discussed in here, relies heavily on JS regardless the usage of the So, if your question is if you should use a polyfill or not, that covers also the
This is a good old example from V0 era that shows just one of the huge amount of benefits of the Somebody took that example saying "you could've just used a wrapper element" but that would be meaningless and redundant on the layout, and it might cause gotchas on IE8 side which is incompatible with randomly named elements (and CSS). The curent polyfill now fallbacks to V0 but it brings in V1 as much as it can (there are parts of V1 that cannot be polyfilled these days) and your specific use case would be covered too. Somebody went further away with the Last, but not least, I've used Custom Elements for years now and never together with ShadowDOM due greediness of the old polyfill with WeakMaps that were breaking all over. |
So what is the minimum amount of that JS that you would like the broadcasting example to contain in order to make it work well with the
Where in the simple broadcasting example I provided did I ask that?
What's the benefit? Specifically what is the It's already a custom element
I looked at your |
|
your demo example does not work without JS and unless you have a live editable version of it I'm not sure what you are asking for but I have a counter question: how would you create a fancy-button without The fact you don't consider all examples already described like That one, I am afraid, I cannot fix. |
Neither do custom elements.
Why would you want to PE the The
I know. And that is what the core argument should be about. I'm guessing And if it's really easy to handle those cases with what we already now, then why is the |
ahem #567 ahem |
|
@Zambonifofex I see you did a little thinking about this - Lightweight, simple, unobtrusive, puts the power in the hands of the developer. But seriously, this would be like using a scalpel to perform surgery. Who's going to go for that? |
|
BTW @WebReflection I probably offended you. I just call it the way I see it, but it is not my desire to offend you or make you go away. I think if we all take a solid look at this we will come up with something great that is a good fit for all of us. We can all win. |
So would I have a crazy but awesome idea: How about browsers take the "native" elements and re-write them entirely with JavaScript using Web Components APIs. This would make them moldable/hackable/monkey-patchable/extendable/breakable/mixinable/etc to the web developer's needs. If we did this first with problem elements (table, tr, form, input, etc), then web developers would inevitably solve the problems in various ways. Imagine the "native" (non-interpreted) side of a browser is merely a platform that allows for elements to be defined (Custom Elements), and that all pre-existing elements are merely custom elements. The used-to-be-"native" elements would still be native, just that they are defined in the browser's native JavaScript context, not the web app's context, and would still work even if javascript is "disabled". This will give us all a clear picture of how the web works and how to modify it. It would be a big undertaking, but would have awesome results. |
|
I think literally everyone here would want that. Itโs simply not realistic. How would one implement |
|
@trusktr, @domenic was exploring that idea over in https://github.com/domenic/html-as-custom-elements. |
|
It seems a lot of the people advocating for <table>
<rainbow-row>IIUC this blows up because Anyways since this scenario is so important to many of the I'd also like to appeal to everyone to focus in on the "Why?". You want the @prushforth I know you have been doing a lot of work on PE maps, so I hope the underlying considerations there become one of the primary drivers / test cases as well. |
|
Just want to point out one more thing that should probably be incorporated into the design framework. With native components we can use BEM modifiers like this (From Philip Walton's Extending Styles article): <!-- Using a BEM modifier -->
<button class="Button Button--small">Download</button>With custom elements that maps to: <!-- Using a Web Component with an attribute for variation -->
<my-button small>Download</my-button>My only point here is that it is less than straightforward to consolidate this type of architectural approach with the |
|
I think W3C should go with is="" . |
If you are designing for these cities then keep it light weight. The
Will be true.
These are all CSS core concerns. You can do these without the The A lot of companies are afraid to touch their CSS because the way they went about implementing it resulted essentially in a stack of wine glasses. None of the glasses can be touched without fear of the entire stack tumbling. You risk the same thing with the |
|
Create extra polyfill modul for Safari, then we can use this service https://polyfill.io/v2/docs/features/ or other serving solution. ;-) |
|
I have kept myself generally informed of Custom Element progress, but have been out of active development in this area for a couple years (I was a contributor to this spec in the v0 phase). Now that I am revisiting this area of dev to do meaningful work, I'm honestly astonished to see this is still unresolved. Being able to extend native elements in a way that leverages existing accessibility mechanisms/strategies, while providing a clear declaration syntax in markup, is something this group needs to account for - full stop The Do the right thing - get this resolved. |
|
First, please be aware of the Code of Ethics and Professional Conduct that governs your participation in this repository. Name calling people by saying "anti-is-ers are acting as the perfect-seeking enemies of good" would not result in any productive conversation. There are many technical reasons we strongly opposed to having the is attribute. Use cases presented for For accessibility, we've suggested adding the capability to define the default accessibility role in options to |
|
@rniwa first off, I'll immediately ask that you not manipulate my words: you just-so-happened to leave out the words "acting as" in your cherry picked snippet of my statement. My critique was of perceived behavior, and not intended or grammatically structured to be an ad hominem personal attack. I'll review the content you linked to, but please take care not to falsely accuse me again - I appreciate it even less than I have restrained myself to articulate here. |
|
Corrected. I still find your statement extremely offensive and vastly inappropriate way of participating in this discussion. |
|
I submitted an honest, assertive opinion based on over half a decade of work in this technical area, and carefully crafted the cited portion to avoid a fallacious personal attack. To label that "extremely offensive and vastly inappropriate" in the age of Trump, I feel, is a tad ridiculous. |
|
Today I learned that applying "Perfect is the enemy of good" aphorism is extremely offensive and vastly inappropriate. |
What is the meaningful work that you want to do? We can be a lot more productive if we stick to simple examples and specifics.
I like the spirit! Tom Brady just kept yelling THINK!!! at his players in the super bowl, and all of a sudden the Patriots celebrating the championship. A few more posts like that and the whole thing will be settled. |
|
@oleersoy good idea, let's talk simple examples - namely, brass tacks product requirements - and craft a solution that fits:
I'm still reading through material, but let me know if there is a proposed solution that checks these boxes. |
|
preemptive laugh emoji |
|
I don't think we can agree on that list of requirements because what constitutes a good design is often subjective and requirements can be arbitrarily restrictive as to favor one design over another. What we can agree on, however, are use cases. For example, being able to add a new JS API on each row a specific table is one. Creating a credit card input element which participates in the form submission and can be associated with a label element like other form control element is another. And the list can go on. Note that not all use cases need to be addressed by a single proposal or solution. Often times, we need to look at the wholistic picture of the entire Web platform, and decide whether a given use case should be addressed in one or another because what we're designing here will stay with us for another 20 years, if not 50 years. |
|
@rniwa no need for paternalistic recitation of the general purpose and responsibilities of web specs, I'm well aware of the process and implications of developing web standards. Now, on to actual discussion: The items I mentioned are not subjective, and ironically, are backed by the same need to account for the sort of long-term impacts you replied with. Namely, what kind of web do we want, and what should be present to ensure common ergonomics, utilities, and features continue to be supported. One of these is View Source. I realize in an age where some apps choose to render code primarily on the server and output amorphous blobs to the client, it's tempting to cut View Source from the requirements list. I believe that's a mistake, again, for the very reasons you outline. View Source, and the ergonomics of scanning code in markup and declarative contexts, is unbelievably important and a fundamental web convention that should be retained. The winds of client code and app frameworks are ever changing, and I'd almost never bet on their pendulum staying to one side for long. As such, it's incredibly important that we not entrench APIs in the imperative JS context. I believe it abandons developers and use cases that benefit from the inherent linkage of markup and declarative code to its semantic intent and functional purpose. After looking over the links presented here, why isn't this a case of "Yes, and"? There are clear benefits provided by the lengthy API/specs you cited, but what isn't clear is why their pursuit should be at the exclusion of something like |
This is not a simple self contained example. You are starting with the technology first and making the assumption that your solution is a great one. That may be, but start with the end goal (simple end result example first) and work backwards to the solution. I would start with simple examples illustrating the meaningful work that you want to do. |
|
I think there are very clear demonstrable capabilities that native controls
have that are either difficult or in some cases entirely impossible to shim
or otherwise create in our Javascript.
The most obvious example is the way in which a select dropdown, or indeed a
datalist on platforms that support it, can exist beyond the browser window.
(Short of some truly horrendous late 90s / early 00s hack of using a
chromeless pop-up, I dont think there's anyway to come close to mimicing
that behaviour.)
Now you might argue that the <select> is fine and doesn't need enhancing,
or that it could be enhanced in some other way than by extension of the
native class.
It's a bit trickier with <datalist> though. The implementations that exist
of a datalist bound to input vary, and the matching algorithm basically
sucks everywhere.
It would be awesome to be able to write a custom match algorithm for
datalist.
โฆ
|
True, this is a user-driven feature description. But because you are so passionate about abstracting needs from tech, we should leverage another tool that separates need from technology even more so than a utilization-centric use-case: User Stories. Here are 3 critical User Stories for this spec issue:
These are empirical statements of need that should drive the discussion. Solutions should be graded, in large part, on their ability to optimize for these needs. |
And one example of such a component is (Real world example - something from the meaningful work that you want to do)? |
|
@oleersoy an enhanced button that allows for icons, custom states, and other goodies, while retaining the event interplay, attribute features, and cross-context declaration ergonomics of |
|
Or indeed, a outside-browser-window control such as datalist / select.
On 19 Feb 2017 18:40, "Ole Ersoy" <[email protected]> wrote:
"As a dev-user, I want to create components that leverage native element
capabilities and UI in as few steps as possible."
And one example of such a component is?
โ
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#509 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAIGbxFqNxJuBvaeAX7bMKVCc6gSc_hMks5reIyVgaJpZM4Iq2sA>
.
|
And the markup for this button is? |
|
@oleersoy I'll answer by not specifying the exact markup, because remember, we're trying to get to the answer without prescription Ideally, the markup should:
After examining developer needs and optimal ergonomic configurations, it seems you'd want the combination of a native tag + some unique indication of its custom element nature. So you tell me, what does that logically reduce to? |
|
@csuwildcat Curious how you'd feel about a solving this problem through composition instead of direct inheritance. My thoughts stem from React and Higher Order Components that render out props.children. <my-field>
<input />
</my-field>In the above case Ideally this would be able to support arbitrary depths of nesting: <my-provider>
<my-behavior>
<select>
...
</select>
</my-behavior>
</my-provider>From the DOM perspective, selecting a decorator/proxy element would ultimately give you it's target. You could define a decorator/proxy element the same way you do a custom element now but provide a flag to denote that it is a decorator/proxy. @rniwa I'd be interested to hear what your thoughts on this are as well. |
You being an english major. |
|
@matthewrobb Indeed, nesting elements like that to fallback to native elements was what we suggested as one alternative to many use cases raised by people advocating for Let it be What it comes short of is when you want to leverage the capability of builtin elements. For example, it's not easy to replicate all the functionalities various input element types provide. For those use cases, we've argued that we need to:
Why? Because in vast majority of use cases we studied, what Web developers want is the ability to override or customize the appearance or the user-interaction model of builtin input element types. Since |
|
@oleersoy how kind of you; I suppose you assume that because I try to articulate ideas in a certain written form (ftr, I was a biz/econ major). Given the style of communication a person uses appears to be sufficient criteria for guessing their major, did you happen to convince an educational institution to issue you a degree in trolling? Thank you for that comical interlude, Ole. Given the contentiousness of the topic we're discussing, I appreciate that you took a moment to provide me with a laugh. |
|
I'm from Norway, so Trolling is in my nature. Did not have to go to school for that. Here's the thing. You said you have meaningful work that you want to do. So surely you have one example with real code and markup that you can show us? |
|
I was a contributor for the Web Components family of specs while I worked
at Mozilla for 5 years, and wrote X-Tag, one of the more significant Web
Components libraries. I just started working on X-Tag v2 using CE v1, with
an eye toward transitioning to a class-based API surface.
Thanks for asking though.
โฆ
|
|
It really feels like this should be the way to extend built-ins: class CustomTableRow extends HTMLTableRowElement {}
class CustomListItem extends HTMLLiElement {}
class CustomInput extends HTMLInputElement {}
// ...This follows the standard way to extend things and is how you extend custom elements. It'd make sense if this was consistent across the board, without any indirection ( Unfortunately: // true
document.createElement('q').constructor === document.createElement('blockquote').constructorI remember reading somewhere that changing this at the browser level is hard. But being that we're discussing ideals, extending builtins via the standard mechanism would be ideal, no? This would also assume the parser is updated so that you can place custom elements inside of elements that currently restrict their child list like lists and tables. |
Ok - Great - You did all that and you still can't provide some simple examples? |
|
@treshugart You cannot instantiate built in HTML elements for one thing. You also would still need to register the new element class. Just because ES has a class concept with extension doesn't really justify that model for this use case in my opinion. |
|
@oleersoy I've already provided an extremely simple example (at your request), which
still, even in what seems like such a trivial case, illustrates a ton of
native extension issues. You didn't like where that led, so now you're
moving the goal post. I'm turning my attention back to the folks on the
thread who are at least offering serious, thoughtful feedback.
|
Where's the markup? |
|
@matthewrobb I definitely feel composition patterns are useful and a very good option in various cases, but to force management and interaction across an element tree, vs simply leveraging native elements and their existing protos directly, results in suboptimal ergonomics and various other issues I listed. Within the X-Tag community, we have suggested composition from time to time for devs who faced issues in this vein. The reaction from developers using the library consistently sounded like this: "Ok, that's pretty gross and not what I would choose if I could, but I guess we'll have to deal with it." I believe the approach here should be "Yes, and". Something like |
|
@matthewrobb Registration was implied. I'm trying to not constrain myself by what browsers can currently do. We're discussing ideals, right? The reason I propose this is that - other than limitations due to the way browsers may implement them - it makes zero sense to me why there's a double standard between built-ins and custom elements. There's no tangible benefit to this. At the end of the day, they're all just elements that have different levels of prototype chains stemming from the common My ideal would be taking the example from https://www.w3.org/TR/custom-elements/#custom-elements-customized-builtin-example: <script>
class PlasticButton extends HTMLButtonElement {}
customElements.define('plastic-button', PlasticButton, { extends: 'button' });
</script>
<button is="plastic-button">Click Me!</button>And being able to do something like the following instead: <script>
class PlasticButton extends HTMLButtonElement {}
customElements.define('plastic-button', PlasticButton);
</script>
<plastic-button>Click Me!</plastic-button>Though, it's not much more concise, that is secondary to consistency, predictability and extensibility, IMO. Ideally a browser would know that your plastic button derives from the built-in button and you get form participation and accessibility for free. If browsers fixed the q / blockquote deriving from the quote constructor issue (and possibly others), then we can get all the information we need from the super class. I just thought I'd give my 2c in terms of ideals. Digressing, I get that ideals aren't reality and that we have to make compromises. I'd be more than happy using both At the end of the day, we need to be able to do:
Surely I've missed something, but these aren't just contrived use cases. Every single item in that list contributed to reasons we stopped using web components for our component library. At the end of the day, we just wanted a solution regardless of if it was ideal or not. It should add weight to this that I'm the author, and still a maintainer of, the second most popular web component library out there. We need to look at the big picture here. If people can't do what they need to do with web components they're going to turn to something else, even if it's a divergent solution. Web components were introduced in 2011. At the time of this writing, that's six years ago. How much of this time has been spent arguing about |
|
The trouble is that the builtin elements aren't written to be extensible in browser engines. Any algorithm that appears in the HTML specification directly looks up the internal state of each element the browser engine holds without going through the JavaScript gets and sets. e.g. the associated form control element of a As we've stated, if we're supporting a proper subclassing of HTML elements, at minimum, we would have to define what kind of things need to be overridable and provide hooks for authors to customize their behaviors for each builtin element we make subclassible as done for builtin JS types such as However, there is an alternative approach. Instead of looking builtin elements as some sort of a magic box which provides a bag of functionalities and capabilities, we can decompose them into a small set of primitive APIs that let each element provide such capabilities. For example, an input element uses the capability to make itself focusable, has a shadow tree with a contenteditable, and participates in a form submission process along with many other things. In our view, it is more fruitful to spec and introduce a small set of these primitives that authors can use to create components of their likings instead of forcing them to extend existing builtin elements, many of which have horrible API surface and surprising behaviors (e.g. value content attribute sets the default value and value IDL attribute sets/gets the current dirty value on an input element). |
@rniwa That is such a cool, outside-of-the-box suggestion. It would be iterative, too, which would hopefully mean that devs could be drip-fed the solutions they're yearning for. I'm interested in exploring the path this is going down because it feels like, if there is a direction for this, library authors can start providing abstractions similar to how these might be used natively, thus not only giving a stop-gap API that is similar to the WC future, but also being able to provide extensions in a similar manner. That said, would I be correct in saying this is still pretty far off? People seem to want a solution for their problems sooner rather than later and are willing to compromise for that. |
Haha, it's not so outside-of-the-box if you work on the browser engine. We have a whole bunch of C++ classes various elements use to behave the way they behave. It's not like we implement each element as one monolithic C++ class. If you think of it, the whole idea of shadow DOM came out of the internal implementation detail of input and textarea elements in WebKit, which Dave Hyatt modeled after XBL2.
Great. We're interested in exploring this space. I think a good start would be providing a mechanism to participate in a form submission. The accessibility object tree API would go a long way to address the accessibility concern, but providing the default accessibility role in Also, this is precisely why I was interested in the list of use cases. Because given use cases, we can come up with an iterative API which address each one of them. |
|
I can provide more details for each of those use cases if necessary,
though, I'm not sure this thread is the best place anymore.
โฆ
|
|
Since there are so many stakeholders monitoring this now, it might be fine to just start hashing some of the use cases out here, and then if anyone objects, move them to a separate issue. |
This is exactly why I mentioned the Uncanny Valley of pseudo-native Custom Elements. We must carefully consider the resulting reality that the above will create if it's offered as the go-to, singular mechanism for leveraging native element functionality. Here's what I firmly believe will occur if you don't go with a "Yes, and" multiple choice implementation that includes Dev A: "I need a button that does X% of what a native button does, and I only care enough to wire up Y% of the remaining using @rniwa's roll-it-all-yourself solution, because it takes more code and effort." Dev B "I want a button that does X% of what a native button does, and I only care enough to wire up Y% of the remaining using @rniwa's roll-it-all-yourself solution, because it takes more code and effort." Dev C "I want a button that does X% of what a native button does, and I only care enough to wire up Y% of the remaining using @rniwa's roll-it-all-yourself solution, because it takes more code and effort." Devs A, B, and C all add various bits of native button functionality to their 'buttons', some based on need, others based on time and effort, but all of them, even the ones who try to achieve nearly the same thing, will result in heterogeneous native-recreation attempts. What you end up with is hundreds of common button-esque implementations that are unintentionally jagged, just-off versions of native, expected button functionality. That solution strategy is a bit like saying: "We realize most people just want to add new wheels or a stereo to a car they buy, but wouldn't it be super cool if the only way to get a car with custom wheels was to have the car and wheels shipped to your house as a giant pile of parts that you need to assemble yourself?!" Please don't force drivers to roll their own cars from a pile of parts when all they want is to add custom wheels. |
This at least makes sense conceptually. Sort of like saying, please don't cut down the entire rain forest so orangotangos have a place to live! |
But how would that be different in the world of |
|
FWIW I'd be more than happy to see the following in the future: But all cases about graceful enhancement keep being ignored. Maybe by the time this thread will be resolved all browsers and textual Web surfers on the world will be natively capable of Custom Elements V1 so that graceful enhancement for this matter could be abandoned. customElements.define(
'my-button',
class extends HTMLElement implements HTMLButtonBehavior {} // ???
);Once we have these composable behavior I wonder if these can be multiple and/or created upfront. customElements.defineBehavior(
'button-like',
{implements: [
HTMLFocusBehavior,
HTMLDataListBehavior,
HTMLEditableBehavior
]}
);
customElements.define(
'my-button',
class extends HTMLElement {},
// ???
{behavior: 'button-like'}
);Just curious what other developers have in mind for this. Regards |
|
I love the idea of breaking all native "specialness" out into element-traits so to speak. Personally I'd like to see this go in this order:
It is worth noting however that this approach will have one major drawback in the end. Since we don't have proper interfaces in javascript it won't be easy to select elements in css or via dom api's that are effectively input boxes or any other built-in. Perhaps a pseudo for these traits would be in order? |
|
I really like @WebReflection's take on this, because it strikes a balance between "here's a mess of parts, good luck" and an all-in-one inheritance approach. Here's a slight tweak I was considering after reading Andrea's comment: customElements.defineExtension(
'button-like',
{
implements: [
HTMLImageBehavior,
HTMLButtonBehavior,
HTMLButtonAppearance
]
}
);Hopefully you could target these bundles in CSS too, consider: form *:extensions(button-like) {
}It would be nice to have behavior and appearance buckets that map 1:1 to their native element roots. I feel this would result in elements that are more cohesive across custom implementations. |
|
@csuwildcat I honestly think it might be a good idea to call these things "Element Interfaces". As for css you hit the nail on the head for what I was trying to get at but maybe here is where the form *:is(button-like) {
}Which leads to the next piece: Declaratively adding interfaces to elements <input is="button-like" />Thoughts? |
|
@matthewrobb love your changes ( |
|
As long as it works via progressive enhancement, like I still want my EDIT: I.E. It needs to fall-back in such a way that the page is still 'usable', if not pretty, without javascript what-so-ever. |
|
@matthewrobb not to be ironic but you basically wrote native built-in extends as these are defined already in the current V1 specification. The selector though, should rather be: form *[is=button-like] {
}to not reinvent the wheel on CSS land too. If |
|
@csuwildcat I like your refinement, I just think maybe form *:extension(button-like) {}
extension(button-like) and extension(select-like) {}This would play nice with the semantic used in customElements.defineExtension(
'button-like',
{
implements: [
HTMLImageBehavior,
HTMLButtonBehavior,
HTMLButtonAppearance
]
}
); |
|
@WebReflection The main difference with my suggestion is that rather than saying that some native element IS another element it would be a way of adding native interfaces to existing elements. My example was confusing: <my-button is="button-like"></my-button>And for the css case I intentionally used a pseudo because the goal is not to select elements that JUST contain an attribute (also while not stated I imagined that this attribute would take multiple values e.g. :implements(input-like) {}The above would select any existing form input elements plus anything that has the interface regardless of whether it was added in markup or at definition time. From a naming perspective I understand there would be conflict potential to use EDIT: Just to clarify as it may not be obvious I also definitely support the following form and am not entirely sold on a declarative way of doing this: customElements.defineExtension(
'button-like',
{
implements: [
HTMLImageBehavior,
HTMLButtonBehavior,
HTMLButtonAppearance
]
}
); |
|
@matthewrobb If we drop things that has to be defined in 3 different places (HTML, CSS, and JS counter part) whatever it is will ship sooner than later, which is IMO essential. Semantically speaking you also define an That being said, I'd like to understand what browser vendors have in mind (if anything) and ideally an ETA accordingly with the decision (I'm honestly tired to wait for this to ship and 3rd parts frameworks already won here because sadly nothing is apparently happening on the standard side). Regards |
|
@WebReflection I was only thinking about HTML, CSS, JS in terms of eventual completeness. I agree 100% that effort should ultimately be put behind making it happen in JS first. |
|
It'd be nice if decorators were further along in TC39 because they're a perfect fit for this in JS land. It doesn't solve the CSS issue as presented here, but it could quite easily if there was someway to hint to the CSS engine about the custom element directly on the constructor, similar to observed attributes. I'd much rather leverage existing JS language semantics if possible rather than add options and global names into the mix. On mobile, but I can flesh this out a bit more later. |
ehr ... like what? CSS and HTML are a separate world, which is why Let's not make this impossible for everyone to achieve in less than year, maybe? We already have a registry for elements, extending it for behaviours/composed interfaces seems easier for everyone.
decorators are Stage 2 and not even close to be shipped. I'd rather be pragmatic and move the Web forward, specially because any procedural way can be easily extended later on through decorators. That's the whole point, giving us the ability to simplify otherwise cumbersome low-level patterns, which is why we all wrapped CustomElements API somehow, right? |
...
...which I will expand on after addressing a few things.
Decorators imply that, however, decorators are just functions and always have been; this part of the API isn't contentious and is the part I wanted to focus on.
Which I explicitly noted by also saying:
I'll try and flesh this out a bit more. I think we're suggesting very similar things, but I'm trying to cut back the API a little bit. JSAs stated above, decorators are just functions. These are the same thing: function withFormParticipation (Base) {
// ...
}
@withFormParticipation
class MyElement extends HTMLElement {}
// is the same thing as...
const MyElement = withFormParticipation(class extends HTMLElement {});Decorators can be composed: function likeFormElement (Base) {
return withFormAccessibility(withFormParticipation(Base));
}
@likeFormElement
class MyFormElement extends HTMLElement {}
// or, of course...
const MyFormElement = likeFormElement(class extends HTMLElement {});You go on to say:
I was never against this, in fact, if you read in to my suggestion, I'm espousing the lowest-level way of doing this: functions. Decorators at this point are not worth their weight alone, but worth discussing as they emphasise functions as the composition mechanism because they are a future feature of ES that we'd be able to leverage if following this path. CSS, but also JS sugarThis is where the likening to If customElements.defineBehaviour('like-form-element', [
withFormAccessibility,
withFormParticipation
]);
class MyFormElement extends HTMLElement {
static get behaviours () {
return ['like-form-element'];
}
}
// This automatically behaves like-form-element because of the prop.
class MyFormElementSubclass extends MyFormElement {
// ...
}Really, the My concern here is that many prefer to ship custom elements without defining them to avoid naming conflicts and leave it up to the consumer to define them. If we introduce both I think it's worth touching on this point to ensure we don't pigeonhole ourselves, however, I'm not convinced we should spend too much time on it. Shipping the JS part is of utmost importance. I think it would be pragmatic to keep it as simple as possible for now and to see how libraries handle it. |
|
I created responsive html table with |
|
I don't think the custom elements API should introduce a new, single-scenario composition / inheritance mechanism ( Given that the features in question aren't currently exposed in any form (other than as part of the built-in elements), why concede that we need a special way to compose them? Wouldn't it be preferable to expose them in a way that makes them composable in plain JavaScript? Further, if this new, custom-elements-only composition API then isn't necessary for using these features in your custom element, why should it become part of (read: add complexity to) the custom elements API? This seems like a 'solution' looking for a problem. |
|
@bicknellr 100% agree. If this is in reference to the second part of my comment (maybe not?), then maybe I wasn't as clear as I should have been about leaving it out of this first iteration. I don't believe it's necessary, at all, but if done, I wanted to try and explore a simpler API for it, is all. To be clear, I have exactly zero use cases for styling against behaviours. Just because you can does not mean you should. |
|
@treshugart I know what are decorators and how to use them, but indeed these are something always deliverable in user-land, DOM APIs aren't. I'm also concerned about possible polyfills, if we have unpolyfillable features, we need transpilers, and transpilers can have bugs that make the feature unusable (e.g. extending native classes) |
|
@WebReflection I wasn't trying to be patronising, it was more for posterity than your benefit. For the record and to be as clear as possible: I'm advocating for functions. Just functions. They take a single argument that is the class. No additional API additions to
Polyfills aren't immune to bugs. Case in point: one of the reasons we stopped using web components is that the polyfills were horribly unstable. Maybe an alternative way to look at this would be to document the workarounds instead of forcing a solution down a particular path because it must be constrained to the ability to be polyfilled. Some workarounds that we've used fitting the items I outlined earlier:
I think this would have a far more positive outcome because workarounds can be documented now and users can start consuming then now. To add to this, documentation on ways to do things with web components seems to be the largest contributor to misinformation about them as well as confusion as to what's possible and how to do things. Even if "is" was settled on, it would take time to finalise and ship. I'm optimistic as to where this discussion is headed, which I definitely couldn't say a few days ago. Props to @rniwa for being objective here. |
You seemed to forget why namespaces are useful. Your functions cannot be just global scope pollution, those functions belongs to Custom Elements, so let's put them in the only global namespace introduced for the goal: the
This is upside down. I've been advocating against using transpilers because these are the one causing instability! Have you read this bug at all? You cannot trust transpilers, not polyfills!!! I'm growing white hair to advocate about transpilers problems, or suggest solutions,or create libraries immune to transpilers, and you tell me the problem is my super stable and tested polyfill used even by the production delivered Google AMP Project? Sorry but it's clear we're not on the same page here so I'll happily re-drop this thread. I also suggest you to watch my talk at wcremoteconf, you were giving yours too the day after. Best Regards. |
I'm speaking in terms of "pure" functions. As in, technically they may be called "methods" because they're on an object instance, but they don't store any state or have any side effects other than, quite possibly, mutating the class that's passed in as to avoid long prototype chains (if this is even an issue). I'm 100% behind them being in the
I don't think it's anyone's place but ours to determine the validity of our reasoning.
Yep.
Subjective. Objectively, polyfills were proven to be an issue for us.
I never mentioned your polyfill. Specifically, it was mostly the shadow DOM polyfill, though we had some issues with others, they were fairly minor. I apologise if you're taking this personally, but I think it's best if we try and get this discussion back on track. @rniwa what are your thoughts on using simple functions that are compatible with the decorator pattern, sitting within the It would be good for other WG members to weigh in, too. |
|
It would be great if someone could just put the pieces back on the board again...or leave most of the pieces off and just focus on one use case and the corresponding API? |
|
I think it's premature to try to come up with a set of compassable features like that. I think we need to first come up with a list of use cases that aren't adequately addressed by the current Web API (besides Once we have those primitive APIs to address use cases, I can see bundling some of them up to make it easily compassable seems as a sensible approach but perhaps this is an area we can leave to library/framework authors first. Once it became obvious that every library/framework is having some basic set of feature as a composable function/class, etc... then we can standardize them. In general, adding new features to browsers is a slow & painful process so we should be adding things that are already well vetted in JS library/framework. |
Sure. I'll mention the use cases we've had again:
|
|
@treshugart I don't think decorators are the right solution for platform mixins because they are applied to the wrong thing - the concrete subclass of HTMLElement that the developer is writing. Class mixins do the right thing, because they apply to the prototype chain above the target class. Methods can be override, super calls, etc: class MyGlobalLikeThing = WindowOrWorkerGlobalScope(Object) {
fetch(input, init) {
// do something
return super.fetch(input, init);
}
} |
|
@justinfagnani decorators were a mistake to mention, if only because they are distracting from my core proposal: functions. In your case FWIW decorators use the return value of functions, so you could rewrite this as: @WindowOrWorkerGlobalScope
class MyGlobalLikeThing {}See http://codepen.io/treshugart/pen/zZOrYX?editors=1010 for an example of this with a custom element. |
like I've said in my talk, Shadow DOM is one of that things that cannot be polyfilled, like WeakMaps or Proxy. It was their fault not to warn about inevitable issues a polyfill would've caused, and your responsibility to not use it, since not essential for Custom Elements (indeed it's a different specification)
Agreed. However, we already wrote ideas but @rniwa says he needs more use cases or libraries implementing something impossible to implement without I've no idea how to move forward. |
|
@WebReflection for posterity, you are incorrect on all accounts in terms of our use cases. Please, if you want to discuss this further, I am more than happy to take it offline. Here is not the place. |
|
@justinfagnani actually I stand corrected. While you can mixin with decorators, it applies the proto chain the other way around. Still: functions :) |
Why do you think it's impossible to implement? My proposal is to find use cases which can't be satisfied without My take on future directions of Web components is to chip away many small pieces. e.g. form submission participation, default ARIA roles for custom elements, etc... Some of those incremental improvements can be polyfiable but others may not be if we're exposing a fundamentally new capability to the Web. But that's okay. |
|
Also a fan of this. |
You have these use cases since the very beginning of this thread and @treshugart just added few.
we're just speculating on what could be the implementation of what you proposed but so far the entirety of the Web did just fine with
We cannot extend native builtins so how/what are we supposed to experiment, exactly? The data-boo is an experiment born as a joke that wraps native builtins inside their related CE, where it's possible, yet it would use promotion or upgrade builtin elements where encountered because, in case it's not clear yet, we cannot:
etcetera ... |
I'm not suggesting to start experimenting anything right now. The first step is to expose native builtin elements' capabilities as mandated by use cases.
This is not a use case. A use case would must be an user scenario which one may wish to extend native builtins to address.
Again, this is not a use case. A use case would be an user scenario in which one may wish to customize table rows, and for which one may wish to address it by defining it as a custom element.
Again, this is not a use case, and did you actually want to change some parser behavior with respect to
Setting the default ARIA role is something I've suggested time and time again. Here's an actual use case: I wish to create a toolbar component and set the toolbar ARIA role without having to add a content attribute visible to the component users. |
Promote gracefully higher resolution automatically only if devicePixelRatio is more than 1 and connection is WiFi/3G+ and there's no roaming involved. I guess this is not a use case neither, isn't it? I also would like to have the freedom to improve inputs as I need for my daily tasks, as well as textareas for editing related tasks and everything else you can do today with builtins. I'd like to have table rows I can drag and drop and resize accordingly with their content or container, I want a mechanism to be able to setup whatever is placed on the document that is a known type. I'd like to have Custom Elements primitives for any element I need so that other libraries using Are these use cases? |
Honestly the use cases are equal to or greater than those of the built-ins themselves. We aren't sitting around justifying why anyone would ever want to provide input to a web page so why should we re-justify the use cases that drove each and every currently existing built in element and ultimately brought along special features to support those use cases. My WORRY about this I really think for this case it is considerably more practical on all accounts to come up with solution that is broad-sweeping. The use case: Allow developers to build custom elements with all the same affordances, conveniences, and behaviors to built-ins. Requiring a user-story other than this is a political movement that we all know will block or stall progress on this issue for YEARS if not indefinitely. |
This is a great use case. However, we found that exposing information about whether an user is on WiFi, 3G, or otherwise using roaming is a great way to track users so we have to come up with some solution that doesn't involve directly exposing such information.
This is not a use case. We must state what those improvements are. Use cases state end results, not means to get there.
This is a great use case too. It seems like what you want is
But presumably, those primitives or library need to be compassable? e.g. if you want to make a helper to make an element focusable, and another to make it participate in the form submission, you may want to use both. In that case, what we need might be something like adding the support to MutationObserver to observe connected/disconnected. |
|
My use case is this: I want to be able to extend the declarative web with new features/behaviour for existing elements. Even if I have to completely re-write the features I need for an element in script i.e. it inherits nothing except the name (not perfect, but easy, I guess). I want to use this facility to propose new features for HTML, and I want to be able to provide a customised built-in as a polyfill for the day when the feature is implemented in some browser but not others/all. In this way, I see customised built-in elements alleviating some of the political pressure to implement features natively which could otherwise continue to happily exist as community-supported customised built-in elements. |
|
I really think for this case it is considerably more practical on all
accounts to come up with solution that is broad-sweeping. The use case:
Allow developers to build custom elements with all the same affordances,
conveniences, and behaviors to built-ins. Requiring a user-story other than
this is a political movement that we all know will block or stall progress
on this issue for YEARS if not indefinitely.
It couldn't be any closer to the truth than this. Vendors should rewrite
native elements using the custom element API and go from there.
โฆ
|
I don't think anyone disagrees with this.
We all want Aladdins Lamp. Everyone agrees that this is the ultimate end game. The point of having concrete real world user stories in addition to this end game is to ensure that we have real world test cases to verify progress against. It's possible to approach this from both ends. Personally I have a much easier time looking at something concrete, and then extrapolating what the API should be from there. For example take this boostrap markup from the dropdown example: <div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
Dropdown
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</div>This would be far more elegant as a few custom elements. So what is the API for creating those elements? What native capabilities should these elements inherit? Do they need everything that the native element has or is it better to use mixins to allow for precise features / behaviors? The point of a simple concrete use case is not to stand in the way of Aladdins Lamp. It's to evaluate ways to get the lamp. Once we look at this long enough the best way to get the lamp will be obvious, but we have to start looking at concrete real world cases, otherwise we will be stuck in this Mad Hatter world forever. GIVE ME THE LAMP!!! |
|
Let's not confuse user stories with use cases. I provided the overarching
"As a developer" user stories that clearly describe, without technical
definition, the desired flows and pain points a solution should optimize
for. A use case is a more technical, specific application scenario that
describes a desired output.
I also submitted a use case or two (one being a button with an icon and
custom events) for assessment against those user stories. I'd like to see
folks run the litany of use cases presented here through the empirical,
objective user stories that have already been submitted.
|
We want a factory to build anything. Lets at least try to build a car and a motorcycle with the prototype for that factory, and lets watch the parts flow through the routing (API) to make sure everyone likes what they see.
Where's the markup? This is important because it will end up driving the workflow for web / html developers. The two core things we are trying to do here is provide us (The component makers) with the flexibility to make the best components we can for the broadest audience (Folks that need screen readers, etc.) while at the same time providing the simplest most effective workflow for the html developers that are going to put these new components / elements to use, as well as the developers that will be maintaining this work. |
|
@csuwildcat you're a biz guy (Complement - I'm a biz guy too) so perhaps you read the case studies on Xerox quality issues during the height of their copier empire. The customers kept complaining that the machines were hard to use and very difficult to fix when they broke down. The engineers kept saying that that was just balony. It was not until the engineers had to use their own copiers and maintain them that the issues got fixed. Lets run some copies before we start throwing copiers on the market. |
(copied from comment below): The
is=""API can be confusing. For example (in current v0 API):The spec says:
But, in my mind, that's just what the spec says, but not that it has to be that way. Why has it been decided for it to be that way?
I believe that we can specify this type of information in the
customElement.define()call rather than in the markup. For example, that very same document shows this example:Obviously,
plastic-buttonextendsbuttonas defined right there in that call todefine(), so why do we need a redundantis=""attribute to be applied ontobutton? I think the following HTML and JavaScript is much nicer:The necessary info for the HTML engine to upgrade that element properly is right there, in
{ extends: "button" }. I do believe there's some way to make this work (as there always is with software, because we make it, it is ours, we make software do what we want, and this is absolutely true without me having to read a single line of browser source code to know it), and thatis=""is not required and can be completely removed from the spec because it seems like a hack to some limitation that can be solved somehow else (I don't know what that "somehow" is specifically, but I do know that the "somehow" exists because there's always some way to modify software to make it behave how we want within the limitations of current hardware where current hardware is not imposing any limitation on this feature).