Skip to content

Customized Autonomous Elements #750

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

Closed
bgrins opened this issue Apr 18, 2018 · 1 comment
Closed

Customized Autonomous Elements #750

bgrins opened this issue Apr 18, 2018 · 1 comment

Comments

@bgrins
Copy link

bgrins commented Apr 18, 2018

Right now, to extend an autonomous Custom Element you extend the JS class and then must register a new tag name. For instance:

<script>
class MyTextbox extends HTMLElement {
  connectedCallback() { this.textContent = "MyTextbox"; }
}
customElements.define("my-textbox", MyTextbox);

class MyAutocompleteTextbox extends MyTextbox {
  connectedCallback() { this.textContent = "MyAutocompleteTextbox"; }
}
customElements.define("my-autocomplete-textbox", MyAutocompleteTextbox);
</script>

<style>
  my-textbox, my-autocomplete-textbox { padding: 10px; }
</style>
<my-textbox></my-textbox>
<my-autocomplete-textbox></my-autocomplete-textbox>

However, there isn't a way to customize the base autonomous element in the same way you can customize a built-in element with the [is] attribute. Being able to do this would make it easier to share CSS and JS that are targeting the base autonmous element's tag name (my-textbox in this case). For example:

<script>
class MyTextbox extends HTMLElement {
  connectedCallback() { this.textContent = "MyTextbox"; }
}
customElements.define("my-textbox", MyTextbox);

class MyAutocompleteTextbox extends MyTextbox {
  connectedCallback() { this.textContent = "MyAutocompleteTextbox"; }
}
customElements.define("autocomplete-textbox", MyAutocompleteTextbox, { extends: "my-textbox" });
</script>

<style>
  my-textbox { padding: 10px; }
</style>
<my-textbox></my-textbox>
<my-textbox is="autocomplete-textbox"></my-textbox>

Implementations currently differ with how they treat this second case:

  • In Firefox, it throws a NotSupportedError: Operation is not supported
  • In Chrome and Safari it runs without exception, but it uses the MyTextbox class instead of the MyAutocompleteTextbox class on the <my-textbox is="autocomplete-textbox"> element.

I can't find prior discussion indicating why customizing elements is only supported for built-ins and not autonomous, so I'd like to see if this is something that could be supported.

@domenic
Copy link
Collaborator

domenic commented Apr 26, 2018

The is="" model is intended for allowing built-in browser features of the built-in element to still work. It's not intended as a way of allowing you to write one tag name in your CSS instead of two.

For autonomous custom elements, whether or not they inherit from anything between themselves and HTMLElement is an implementation detail. Inheriting from some other autonomous custom element is the same as inheriting from any other random class. (As long as you obey the requirement that HTMLElement end up in the prototype chain at some point.)

Finally, it's worth noting that is="" only works with a single level of inheritance; since autonomous custom elements can have arbitrary inheritance chains, it's not a good fit there.

Those are the reasons I remember for this. Basically, the model does not fit well, and the benefits are tiny (writing x does not save many characters over writing x, y).

Since we're unlikely to change this, let me close the issue. But, I'm happy to continue discussing in the closed thread.

@domenic domenic closed this as completed Apr 26, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants