WICG / webcomponents

Web Components specifications
Other
4.34k stars 371 forks source link

The is="" attribute is confusing? Maybe we should encourage only ES6 class-based extension. #509

Closed trusktr closed 7 years ago

trusktr commented 8 years ago

The is="" API can be confusing, and awkward. For example (in current v1 API):

inheritance currently has to be specified three times:

class MyButton extends HTMLButtonElement {} // 1st time
customElements.define('my-button', MyButton, { extends: 'button' }) // 2nd time
<button is="my-button"></button> <!-- 3rd time -->

But, I believe it could be better:

inheritance specified once, easier non-awkward API:

class MyButton extends HTMLButtonElement {} // 1st and only time
customElements.define('my-button', MyButton)
<my-button></my-button>

But, there's problems that the is="" attribute solves, like making it easy to specify that a <tr> element is actually a my-row element, without tripping up legacy parser behavior (among other problems). So, after discussing in this issue, I've implemented an idea in #727:

mixin-like "element behaviors", without extending builtins

The idea uses a has="" attribute to apply more than one behavior/functionality to an element (is="" can only apply a single behavior/functionality to an element), using lifecycle methods similar to Custom Elements.

For example:

// define behaviors
elementBehaviors.define('foo', class { // no inheritance necessary
  connectedCallback(el) { ... }
  disconnectedCallback(el) { ... }
  static get observedAttributes() { return ['some-attribute'] }
  attributeChangedCallback(el, attr, oldVal, newVal) { ... }
})
elementBehaviors.define('bar', class { ... })
elementBehaviors.define('baz', class { ... })
<!-- apply any number of behaviors to any number of elements: -->
<div has="bar baz"></div>
<table>
  <tr has="foo baz" some-attribute="lorem"></tr> <!-- yay! -->
</table>
<button has="bar foo" some-attribute="ipsum"></button>
<input has="foo bar baz" some-attribute="dolor"></input>

In a variety of cases, this has advantages over Custom Elements (with and without is="" and):

  1. No problems with parsing (f.e. the table/tr example)
  2. No inheritance, just simple classes
  3. Works alongside Custom Elements (even if they use is=""!)
  4. "element behaviors" is similar to "entity components" (but the word "component" is already used in Web Components and many other web frameworks, so "behaviors" was a better fit).
  5. Lastly, "element behaviors" makes it easier to augment existing HTML applications without having to change the tags in an HTML document.

See #727 for more details.


Original Post:

The spec says:

Trying to use a customized built-in element as an autonomous custom element will not work; that is, <plastic-button>Click me?</plastic-button> will simply create an HTMLElement with no special behaviour.

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:

customElements.define("plastic-button", PlasticButton, { extends: "button" });

Obviously, plastic-button extends button as defined right there in that call to define(), so why do we need a redundant is="" attribute to be applied onto button? I think the following HTML and JavaScript is much nicer:

<!-- before: <button is="plastic-button">Click me</button> -->
<plastic-button>Click me</plastic-button>
// before: const plasticButton = document.createElement("button", { is: "plastic-button" });
const plasticButton = document.createElement("plastic-button");

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 that is="" 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).

domenic commented 8 years ago

This was previously discussed at length in the other bug tracker, and it's explained in the spec in the sentence above that:

Customized built-in elements require a distinct syntax from autonomous custom elements because user agents and other software key off an element's local name in order to identify the element's semantics and behaviour. That is, the concept of customized built-in elements building on top of existing behaviour depends crucially on the extended elements retaining their original local name.

trusktr commented 8 years ago

@domenic That quote that you referred to makes me think exactly the same thing as I just wrote:

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 that is="" 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).

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 <button is="super-button"> (besides the fact that current algorithms require that) when clearly there's a JavaScript way to make the HTML engine understand that <super-button> means the same as <button is="super-button"> due to the fact we're defining that in the call to customElement.define.

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.

domenic commented 8 years ago

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.

trusktr commented 8 years ago

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 <button>? I think that's perfectly fine, because without JS the app probably won't work anyways, and I'm willing to bet that most people who will write JavaScript-based Custom Elements won't care if the app doesn't work with JS turned off. The Nike website doesn't work with JS turned off, and they care. Most people won't care. Developers who do care can just as easily use <noscript> and place a <button> in there, which makes much more semantic sense anyway.

What other reason might there be?

trusktr commented 8 years ago

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 is="" form of extension and globally-registered custom elements that are not registered on a per-component basis.

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 customElements.define is there to clarify things. The is="" attribute is simply redundant and out of place from an outter API perspective (which may matter more than whatever extra implementation complexity there may be) because we already specify the extension in the define() call.

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.

rniwa commented 8 years ago

The problem here is that UA internally checks local name e.g. element.localName == aTag to do various things, and all of that code needs to be updated to account for the fact there could be an intense of HTMLAnchorElement whose local name is not a.

Now I'm going to re-iterate that Apple objects to extending subclasses of HTMLElement using is= as currently spec'ed for various reasons we've stated in the past and this feature won't be supported in WebKit.

trusktr commented 8 years ago

The problem here is that UA internally checks local name e.g. element.localName == aTag to do various things, and all of that code needs to be updated to account for the fact there could be an intense of HTMLAnchorElement whose local name is not a.

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 window.customElements will be when an app gets large and when people widely adopt Web Components (wide adoption is one of the goals here).

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 <q> and <blockquote> sharing the same class), then we should be able to use instanceof instead of checking tag names, and element inheritance can be based solely on ES6 class extension, as it should be (rather than having the extra is="" feature). The change that would be needed here would be to ensure that the native elements map to separate leaf classes so it's possible to tell a <q> element apart from a <blockquote> element with instanceof and therefore encouraging that sort of checking over tag names.

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.

Apple objects to extending subclasses of HTMLElement using is=

I think Webkit not implementing is="" may be a great thing.

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 is="". It will also require fixing things like the <q>/<blockquote> problem.

trusktr commented 8 years ago

@domenic Can you describe the "ecosystem impact" that you might know of?

domenic commented 8 years ago

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.

trusktr commented 8 years ago

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 <app> component with a closed shadow root. In this case a search engine might only ever see

<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:

  1. Allowing both forms and let users decide which to use: <button is="awesome-button"> or <awesome-button> and let users decide which to use as they so wish.
  2. Allowing overriding of native elements (which pairs well with the idea of per-shadow-root element registrations as in "hey, let me define what a <p> element is within my component that has no paragraphs."). Then <button> could behave like <awesome-button>, and search engines or other tools would be able to receive the same semantic meaning. This idea only works if the elements are in Light DOM.
domenic commented 8 years ago

Remedy 1 is what we have consensus on.

rniwa commented 8 years ago

I'll note that we've vocally and repeatedly objected to having is=, and in fact, stated publicly that we won't implement this feature, but somehow the WG kept it in the spec. I wouldn't call that a consensus. We extremely reluctantly agreed to keep it in the spec until it gets removed at risk later.

zamfofex commented 8 years ago

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: :subtypeof(button)

chaals commented 8 years ago

a new CSS pseudo-class would be needed: :subtypeof(button)

Not really. The point of the is= approach is that since you have a button, that already matches CSS selectors for button. If you want to match a specific subtype you can do button[is=broken-button]

zamfofex commented 8 years ago

@chaals right. You would need the pseudo-class if using a custom element that extends a native button could be done like <awesome-button> instead of <button is="awesome-button">.

zamfofex commented 8 years ago

Also, like @trusktr said, if this and whatwg/html#896 become a thing, I think it’ll be possible to remove altogether the extends property from the options argument. We would then write customElements.define("awesome-button", class extends HTMLButtonElement{}, {}), which I really like.

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”.

chaals commented 8 years ago

(@Zambonifofex it's generally not clear to me what you mean when you say "this", which makes it hard to engage)

As @trusktr said, “I think ‘breaking the web’ might actually fix the web in the long run”.

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.

chaals commented 8 years ago

For what it's worth, I agree with @rniwa's characterisation - we have an agreement that we won't write is= out right now, but I don't see a strong consensus behind it. (Although as an individual I'm one of those who think it's pretty much indispensable to making this stuff work).

zamfofex commented 8 years ago

@chaals

(@Zambonifofex it's generally not clear to me what you mean when you say "this", which makes it hard to engage)

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.

zamfofex commented 8 years ago

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?

trusktr commented 7 years ago

The is="" API can be confusing. For example (in current v0 API):

<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?
domenic commented 7 years ago

That API does not reflect the current custom elements API.

trusktr commented 7 years ago

We should make the result of instanceof be obvious. I think this could be better in v1 (without is="" and without options.extends):

<my-el></my-el>
class MyEl extends HTMLDivElement { /*... */ }
customElements.define('my-el', MyEl)

// ...

document.querySelector('my-el') instanceof MyEl // true!
trusktr commented 7 years ago

I forgot this line too, in the previous comment:

document.querySelector('my-el') instanceof HTMLDivElement // also true!
trusktr commented 7 years ago

(@domenic I'm still using v0 in Chrome)

trusktr commented 7 years ago

@rniwa

there could be an intense of HTMLAnchorElement whose local name is not a.

I think you meant "instance" instead of "intense"? This seems to be the reason why is="" exists, making it possible to create new elements that extend from elements that inherit from the same class, but that possibly have new behavior added to them in their definitions along with differing nodeNames. This is also the reason for the {extends: "element-name"} (I am calling it options.extends), which effectively accomplishes the same thing. I feel like this may be an anti-pattern considering that we now have ES6 classes for describing extension.

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.

trusktr commented 7 years ago

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 (is="" and options.extends). An example of native elements that are defined with the same interface/class but with different nodeNames are q and blockquote which share the HTMLQuoteElement interface. We should attempt to describe the difference (if any) between these elements with class extension rather than is="" combined with options.extends. If there is no difference except for nodeName, then if they are both instanceof the same class that is fine too as long as the behavior for both elements is entirely defined in the shared class, and not by other means.

rniwa commented 7 years ago

FWIW, we're against subclassing subclasses of HTMLElement (e.g. HTMLInputElement, etc...) for various reasons, so WebKit isn't going to support this feature anyway. Extension of builtin elements are much better served with mixins.

zamfofex commented 7 years ago

@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.

bedeoverend commented 7 years ago

@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 img element, so far we haven't found any cross browser way to replicate the way it sizes, therefore having an element extension, so right now using is, is the only way to achieve this.

zamfofex commented 7 years ago

@bedeoverend I don’t think they are against extending native elements, they are simply against classes extending subclasses of HTMLElement. So you would still be able to extend native elements using the extends property of the customElements.define method. What would be illegal is the class passed to the method to extend a subclass of HTMLElement.

rniwa commented 7 years ago

We won't be supporting extends either.

One fundamental problem is that subclassing a subclass of HTMLInputElement or HTMLImageElement often leads to a violation of the Liskov substitution principle over time. Because they're builtin elements, they're very likely to be extended in the future. Imagine that we had this feature supported before type=date was added. Then your subclass of HTMLInputElement must also support type=date in order to satisfy the substitution principle. Similarly, imagine we had added this feature before srcset was added to HTMLImageElement and you wrote a subclass of HTMLImageElement. Then not supporting srcset results in the violation of the principle again.

In addition, none of the builtin elements are designed to be subclassed, and in fact, we don't have builtin subclasses of HTMLElement that are also builtins. This limits the usefulness of any sort of subclassing. Furthermore, we don't have any hooks for the processing models and internal states of builtin elements such as the dirtiness of HTMLImageElement's value and when and how HTMLInputElement picks the appropriate image.

Finally, the whole design of is= is a hack, and it would harm the long term health of the Web platform.

trusktr commented 7 years ago

FWIW, we're against subclassing subclasses of HTMLElement (e.g. HTMLInputElement, etc...) for various reasons, so WebKit isn't going to support this feature anyway. Extension of builtin elements are much better served with mixins.

One fundamental problem is that subclassing a subclass of HTMLInputElement or HTMLImageElement often leads to a violation of the Liskov substitution principle over time.

@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 q and blockquote. Otherwise, how does the web manifesto explain the difference between <q> and <blockquote>? I.e. How would the customElements.define() calls for q and blockquote differ in order to theoretically satisfy the web manifesto?

Maybe we would need to reserve HTMLQuoteElement for the q tag, and make a new HTMLBlockQuoteElement for the blockquote element, both of which extend from HTMLElement. I can see how that would be one way to satisfy the web manifesto and remain closer to Liskov's substitution principle.

rniwa commented 7 years ago

Yeah, there has been a discussion about that for q and blockquote. A more likely consensus is to introduce two subclasses of HTMLQuoteElement, e.g. HTMLInlineQuoteElement and HTMLBlockQuoteElement and have q and blockquote each use it. It's a bit more hairly story for h1 through h6, which seems to require an introduction of six subclasses of HTMLHeadingElement from HTMLH1Element through HTMLH6Element.

trusktr commented 7 years ago

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 is=""+options.extends.

domenic commented 7 years ago

having those new subclasses for end-webdevs to extend from is already better than is=""+options.extends.

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).

ebidel commented 7 years ago

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 is="" is the way to extend elements or not doesn't matter to much. But we definitely need a solution rather than no solution and currently, that's is="". Personally, I see nothing wrong with is="". It's worked great for the last couple of years in Chrome's v0 implementation. It's been implemented in a browser and proven. There may be edge cases with subclassing certain elements, but TBH, I haven't seen many (any?) developers run into them.

Ultimately, developers have to write less code with is="". That's huge. Extensions bring more reuse and keep best practices to our platform. Not less. Let's not remove such a useful feature.

zamfofex commented 7 years ago

@domenic

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.

That’d hopefully still be the case if is="custom-button" gets removed in favor of <custom-button>.

rniwa commented 7 years ago

I don't get why people keep making claims that is= improves accessibility. It simply doesn't except the very simple scenario in which the entire UI of the builtin form control is preserved (e.g. just adding JS methods).

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= because UA can't determine how elements in a shadow tree corresponds to what UI actions without explicit annotations by the author.

esprehn commented 7 years ago

is@ is critical for supporting reasonable AX for links. We tried to replicate the subtle focus and keyboard behavior of <a> with a custom element for quite a while before giving up and doing <a is="...">. Nesting a link inside an element breaks styling since my-link:visited etc. stop working.

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. :)

WebReflection commented 7 years ago

My 2 cents, FWIW, <a is=""></a> or <img is=""> confuses nobody about the intent, <shena-nigans></shena-nigans> is a complete wonder of what the heck is that tag about.

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 is

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. AFAIK not a single developer I've talked to said it was confusing (I also gave a talk about this)

treshugart commented 7 years ago

Whatever happens here, platform consistency should be considered highly important. If all browsers but WebKit support is, anyone with a valid use-case for using it will have to not use it, or remove Safari from their browser support matrix. There are good reasons for both sides of the argument, but I think there should be some compromise.

WebReflection commented 7 years ago

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. That's just a tiny demo of how powerful is the is attribute.

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 ( ok, not if you're using a text only browser ¯(ツ)/¯ )

WebReflection commented 7 years ago

@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 MyLibrary or fetch if that's an appropriate name for a new feature, isn't it? Of course, modules partially solve this but polyfills will still do feature detections and pollute globally.

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.

zamfofex commented 7 years ago

@WebReflection

I'm not sure why this bug is still opened or still considered as something to be changed.

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 is, but I can live with it.

WebReflection commented 7 years ago

@Zambonifofex the DOM is old and not perfect, neither is the is attribute as solution. However, it solves everything every native HTMLElement has solved during the last 25 years without any need to reinvent the wheel. Moreover, it doesn't require O(n^2) amount of nodes (named custom elements plus eventually native links/input/whatever inside) and also it makes it possible to better integrate with the Web platform.

An example over every other, is the bloody tr that cannot be wrapped around a custom-tr element because it will break and table are still the best, semantic, accessible way to display tabular data.

TL;DR nobody likes is but whoever worked with it will admit is the most pragmatic, easy-peasy, cross platform friendly and working solution we have so that every developer moved forward building great stuff based on such attribute.

The previous x-img tag goes even further, using CSS like img[is=x-map], x-map {} to have common styles for before and after the upgrade which replaces the image with something else that has nothing to do with an image (it's a Leaflet canvas/iframe/different-world)

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 is and move forward the Web. Thank you!

rniwa commented 7 years ago

FWIW, we're going to iterate our opinion that we're not going to implement is attribute in WebKit.

ebidel commented 7 years ago

That's very unfortunate.

@paulkinlan wrote a great piece on platform inconsistencies recently, "The Lumpy Web".

  • Platform inconsistencies hurt us more than big feature differences, we should start to try and prioritize aligning the platform
  • We need better tools to help us understand what the inconsistencies are and guidance on how to manage them
  • Developers should raise more issues to keep browser vendors accountable when there are differences

I hope this inconsistency doesn't become detrimental to the adoption of Custom elements.

rniwa commented 7 years ago

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?

WebReflection commented 7 years ago

'cause we're all thinking, reasonable, people and Custom elements with is attribute have been already adopted and not only by Google and Chrome.