Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
trusktr opened this issue May 31, 2016 · 495 comments

Comments

@trusktr
Copy link

@trusktr trusktr commented May 31, 2016

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
Copy link
Contributor

@domenic domenic commented May 31, 2016

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
Copy link
Author

@trusktr trusktr commented May 31, 2016

@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
Copy link
Contributor

@domenic domenic commented May 31, 2016

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
Copy link
Author

@trusktr trusktr commented May 31, 2016

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
Copy link
Author

@trusktr trusktr commented May 31, 2016

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
Copy link
Contributor

@rniwa rniwa commented Jun 1, 2016

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
Copy link
Author

@trusktr trusktr commented Jun 7, 2016

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
Copy link
Author

@trusktr trusktr commented Jun 7, 2016

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

@domenic
Copy link
Contributor

@domenic domenic commented Jun 7, 2016

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
Copy link
Author

@trusktr trusktr commented Jun 7, 2016

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
Copy link
Contributor

@domenic domenic commented Jun 7, 2016

Remedy 1 is what we have consensus on.

@rniwa
Copy link
Contributor

@rniwa rniwa commented Jun 7, 2016

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.

@Zambonifofex
Copy link

@Zambonifofex Zambonifofex commented Jun 10, 2016

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
Copy link
Contributor

@chaals chaals commented Jun 11, 2016

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]

@Zambonifofex
Copy link

@Zambonifofex Zambonifofex commented Jun 11, 2016

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

@Zambonifofex
Copy link

@Zambonifofex Zambonifofex commented Jun 11, 2016

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
Copy link
Contributor

@chaals chaals commented Jun 11, 2016

(@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
Copy link
Contributor

@chaals chaals commented Jun 11, 2016

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

@Zambonifofex
Copy link

@Zambonifofex Zambonifofex commented Jun 12, 2016

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

@Zambonifofex
Copy link

@Zambonifofex Zambonifofex commented Jun 12, 2016

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
Copy link
Author

@trusktr trusktr commented Jul 2, 2016

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
Copy link
Contributor

@domenic domenic commented Jul 2, 2016

That API does not reflect the current custom elements API.

@trusktr
Copy link
Author

@trusktr trusktr commented Jul 2, 2016

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
Copy link
Author

@trusktr trusktr commented Jul 2, 2016

I forgot this line too, in the previous comment:

document.querySelector('my-el') instanceof HTMLDivElement // also true!
@trusktr
Copy link
Author

@trusktr trusktr commented Jul 2, 2016

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

@trusktr
Copy link
Author

@trusktr trusktr commented Jul 3, 2016

@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 trusktr changed the title Why must the is="" attribute exist? The is="" attribute is confusing? Maybe we should encourage only ES6 class-based extension. Jul 3, 2016
@trusktr
Copy link
Author

@trusktr trusktr commented Jul 3, 2016

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.

@WebReflection
Copy link

@WebReflection WebReflection commented Oct 19, 2018

@OvermindDL1 I don't know where you come from, but let me assure you document-register-element polyfill, used by AMP project too, brought V0 to all meaningful implementations already, including AFrame, so we're all good to go, the V0 API is the only one battle tested in the real world.

@OvermindDL1
Copy link

@OvermindDL1 OvermindDL1 commented Oct 19, 2018

@OvermindDL1 I don't know where you come from, but let me assure you document-register-element polyfill, used by AMP project too, brought V0 to all meaningful implementations already, including AFrame, so we're all good to go, the V0 API is the only one battle tested in the real world.

@WebReflection Sadly my job has me work on headless terminals an excessive amount, and I often have to do a surprising amount of web browsing via elinks or links2 or so due to no graphical interface. Thus no, no javascript whatsoever. A <button ...> I can 'click' on in elinks no problem, but no form of <my-button ...> or so. This is why is="..." is so useful, if only all evergreen browsers supported it...

@WebReflection
Copy link

@WebReflection WebReflection commented Oct 19, 2018

@OvermindDL1 that's why you should be pro V0 good old builtin extends, the page will work for elinks way better than any strongly coupled JS custom element that tries to re-create native bluitins such links, li, buttons, tables, etcetera. The V0 API got one thing right, backward compatibility, so please think carefully about what "dragon" you're fighting against 'cause I can assure you it's the wrong one if you care about backward compatibility in this very specific case.

@WebReflection
Copy link

@WebReflection WebReflection commented Oct 19, 2018

@OvermindDL1 I brought meaningful maps down to IE8 a while ago, please trust me when I tell you you should be pro builtins extends.

@WebReflection
Copy link

@WebReflection WebReflection commented Oct 20, 2018

FYI I've just published to npm built-in-element which is a polyfill for Custom Elements built-ins that works already in Safari https://github.com/WebReflection/built-in-element#built-in-element

Read the README carefully, regarding the only inevitable caveat, and let me know if I forgot anything.

For what I could test, Firefox and Chrome won't be affected at all by the feature detection and WebKit will be patched in a still quite performant way 👋

@OvermindDL1
Copy link

@OvermindDL1 OvermindDL1 commented Oct 22, 2018

@OvermindDL1 I brought meaningful maps down to IE8 a while ago, please trust me when I tell you you should be pro builtins extends.

Thankfully I don't have to deal with IE8 at work, I do, quite literally, have to deal with elinks and old screenreaders that we aren't allowed to update, so I don't have to deal with old javascript, I just have to deal with new javascript and No javascript. :-)

@WebReflection
Copy link

@WebReflection WebReflection commented Oct 22, 2018

too bad GitHub is half down today so you cannot see demo pages in elinks ... will ping you back once up and running again so you can understand the power, simplicity, and beauty of custom elements built-ins.

Also, after years working with Custom Elements in general:

  • the inheritance of builtins is superior, you get everything the standard/semantic element has to offer
  • multiple button with different classes are not an issue, no more than multiple custom elements that would like to be a built-in (and surely less)
  • there are (virtually) less DOM nodes to handle, and built-ins are easily well optimized in core
  • there is less to parse and UI works out of the BOX, you don't need to wait for definitions

I actually believe if the Custom Elements story was born extending builtins only, instead of a pseudo empty HTMLElement with a complex and unpolyfillable Shadow DOM, the Web would be in a way better shape / more advanced than now.

Instead, we keep discussing this thread ... but hopefully my latest poly that weights < 1K and works down to old IE (after optional polyfill for Custom Elements) would help moving forward.

If only we could also have native decorators to easily enrich classes instead of being stuck with single inheritance model it'd be so fun creating components and apps.

/rant

Best Regards

@OvermindDL1
Copy link

@OvermindDL1 OvermindDL1 commented Oct 22, 2018

I actually believe if the Custom Elements story was born extending builtins only

Hear hear! Although I wish shadow DOM's were standard a long time ago, would have helped so much...

@Nashorn
Copy link

@Nashorn Nashorn commented Dec 18, 2018

I don't think the majority of developers understand the issues they are ranting/asking about. The engineers behind the specs took years to think it up and finalize it, it may not be perfect but here's some insight:

The general pattern of comments state the issue of:

  1. redundancy
  2. confusion of why "is" attribute is needed on tag.

First the redundancy. I do think this is redundant:
customElements.define("plastic-button", PlasticButton, { extends: "button" });

PlasticButton already extends HTMLButton in class syntax, solution is to modify customElements.define() to lookup the parent constructor/ancestor class of PlasticButton, which would resolve to HTMLButton. define() can then make the redundant (3rd arg) call under the hood.

SOLUTION to "is" attribute:
You have to understand the use-case and context problem to see why "is" is very necessary. Imagine 1 such use-case:

HTML hand-off from a graphics/css developer. He hands you HTML5 markup. You open the html, eith manually in an editor or programmatically using query-selection on DOM, and add "is" to one of the buttons that should be/is Plastic. You address a few things:

  1. The semantics is preserved
  2. Accessibility is preserved
  3. Progressively decorated
  4. Smallest possible change

I have done this tons of times before to decorate existing html but have been using a "namespace" attribute, pointing the namespace to a class:
<div namespace="core.ui.PlasticButton"></div>

and during app boot lifecycle, tags with "namespaces" would get decorated in place as PlasticButtons.

Without the "is"/namespace idea, doing this programmatically or even manually would be like chopping and re-declaring fragments all across the src.

@oleersoy
Copy link

@oleersoy oleersoy commented Dec 20, 2018

@Nashorn now take your development approach one step further and start adding custom elements for <login-form> , <product-card>, etc. The minute you add these elements you might as well just do <plastic-button>.

If you use is you've already broken one of the tenants of good UX and that is that your UI should look and behave consistently across all platforms and that is completely orthogonal to what is is designed to do.

@Nashorn
Copy link

@Nashorn Nashorn commented Dec 21, 2018

Playing the role of an HTML guy, why would'nt i want custom semantic elements like a <post-card> or <shopping-cart> ? I dont see your point.

2nd, behavior-n-look across platforms using "is" will be broken? I don't see your point.

3rd, re-read what i posted on above (is attribute is needed!.
You have to consider the use-case for "is", which w3c have weighed and most developer-consumers have not yet.

Let me say it again in a different way, (Safari/iOS devs, if you're reading - i do hope you see it):

There are 4 mechanics of creating new instances of custom elements,
here they are:

  1. document.**createElement**("post-card");
  2. var card = **new** PostCard;
  3. <post-card>....content here....</post-card>
  4. <div is="post-card">....content here....</div>

1 and 2 from above is a programmatic design where 1, doc.createElement() is an Open-Closed dependency inverted design that allows for runtime injection in a dynamic environment from merely strings that look like tag-names (from db). Powerful. The latter is common to us and serves its onw role in the dynamic polymorphic landscape.

The 3rd and 4th are 2 declarative ways to achieve inline layout by letting the browser do the work of initialization. Semantics, code readability, and accessibility are achieved here on 1 aspect. The former (3rd bullet), is akin to 2nd bullet -- new PostCard;. The latter, 4th bullet, is similar to 1st bullet -- document.createElement**("post-card") offering the same SOLID principals as the programmatic createElement() method.

Recap:
1 and 4 complements (programmatic & declarative)
2 and 3 complements (programmatic & declarative)

The "is" attribute allows one to dynamically target a div, setting is to some Class and having it "react" accordingly without modifying one bit of existing html. IT IS SIMPLY AN ALTERNATIVE MECHANISM FOR INITIALIZATION, BUT FROM A DIFF PERSPECTIVE.

is is absolutely necessary as added way to declare usage and complements the 3 existing strategies we have currently. Think carefully, to get an existing DIV in DOM to react, change it's is, done!. Without is, one would create a new instance of a custom el, replace the existing DIV with new el, a more drastic dom modification (removal and adding to dom). 2nd, the possibility of causing existing semantics to change and possibly accessibility, whereas "is" preserves those as well.

It makes me really ponder life at times. Something as important as "is" is not recognized clearly because of lack of dev experience. Yet, crappy ass bullshit concepts like destructuring and exports/imports (a fucking hack job) made it into ES6? HAHAH. This is what happens when powerful organizations with $ infiltrate and lobby the board to adopt ideas or el$e.

@oleersoy
Copy link

@oleersoy oleersoy commented Dec 21, 2018

@Nashorn I think you are low on Vitamin D.

@chaals
Copy link
Contributor

@chaals chaals commented Dec 21, 2018

@oleersoy this sort of comment does not meet the standards of professional behaviour expected here.

@oleersoy
Copy link

@oleersoy oleersoy commented Dec 21, 2018

But:

Yet, crappy ass bullshit concepts like destructuring and exports/imports (a fucking hack job) made it into ES6? HAHAH.

Does?

@Nashorn
Copy link

@Nashorn Nashorn commented Dec 22, 2018

Low on vitamin D. You know bro, I did not come off that way. You're still a junior.

@oleersoy
Copy link

@oleersoy oleersoy commented Dec 22, 2018

It was just a hunch :). Anyways we're all learners. Happy Holidays!

@Nashorn
Copy link

@Nashorn Nashorn commented Dec 22, 2018

Happy holidays 😀

@trusktr
Copy link
Author

@trusktr trusktr commented Apr 9, 2019

Wow, there's been so many comments since I last visited.

I think it would be worth investigating alternative to the is="" attribute like "element-behaviors" or "element-features" or "custom-attributes":

(in fact, my element-behaviors is built on top of custom-attributes (that's how I made the has="" attribute concept there))

Please express your opinions on those ideas. They solve the issues that the is="" attribute has, plus they add more flexibility in API design that Custom Elements alone doesn't have. Think of those ideas similar to entity-component systems.

@trusktr
Copy link
Author

@trusktr trusktr commented Apr 9, 2019

instead of being stuck with single inheritance model it'd be so fun creating components and apps.

The above custom-attributes and element-behaviors are "mixin"-like ideas, whereby we can mix and match multiple functionalities onto any one element (is="" allows only one functionality).

@WebReflection By the way, you can have multiple inheritance with class-factory mixins. Check out my Mixin tool. Here's the tests, and here's an example where my Sizeable class extends from both Observable and TreeNode classes. For better context, here's what Observable looks like, it's a class, but also a mixin. (Note, Mixin works with any classes, not just my custom Class()es).

@WebReflection
Copy link

@WebReflection WebReflection commented Apr 9, 2019

I use mixins since about ever and I've never had an issue with the is attribute.

Like me, many other projects based on is attribute never had issues neither, and I'm personally tired of APIs that ship, and work, for years, and then break all of a sudden due people that never used those features but want so desperately remove'em.

The is attribute is ugly, but it works very well since its first appearance.

With Edge on Chromium, only Safari is missing the train but the polyfill for Safari only, works fast and well, plus Safari is used on powerful devices so performance is not an issue.

This thread should be closed, imo.

@Nashorn
Copy link

@Nashorn Nashorn commented Apr 9, 2019

Imo, shorter descriptive names are always better than long descriptive names. Saying my element is=Dropdown, and Dropdown is my view controller makes sense.

Dropdown can then programmatically mixin the traits for my class. You don't want to mud the water and turn HTML in XAML or worse, what ng did.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.