New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 619062 link

Starred by 7 users

Issue metadata

Status: WontFix
Owner:
Last visit > 30 days ago
Closed: Oct 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Bug

Blocking:
issue 594918



Sign in to add a comment

Can custom element classes extends subclasses of HTMLElement?

Project Member Reported by kojii@chromium.org, Jun 10 2016

Issue description

A question arose from the review comment https://codereview.chromium.org/2054433002#msg6

class C extends HTMLImageElement {
  constructor() { super(); }
}
customElements.define('a-a', C);

Is this allowed? A few question points:
* Current our impl throws "illegal constructor"
* Sync create element may work, but when async or upgrade, we create HTMLElement first, and can't upgrade it to HTMLImageElement.
 
This is somewhat related to https://github.com/whatwg/html/pull/1404.

Certainly this should be allowed if you did

customElements.define('a-a', C, { extends: 'img' })

Without the PR #1404 referenced above, the spec is broken and does not allow that. But it should.

The more interesting question is whether the version from your OP, without "extends", should be allowed. Per spec, after #1404 lands, it would be allowed, but have somewhat strange behavior, I think. For example, anything that did a local name test would fail (since the local name is 'a-a'), but it would probably pass the brand check for HTMLImageElement (so e.g. it could act as a canvas image source).

If we wanted to disallow it, we'd need to do some kind of lookup inside the HTMLImageElement constructor. Something like:

1. NewTarget is C
2. I have a definition for C with name = local name = 'a-a'
3. I am currently executing the HTMLImageElement constructor
4. HTMLImageElement's associated set of tag names is {'img'}
5. the definition for C does not have a local name in that set, so throw an error.

(Note that step 4 could give a set with multiple elements inside e.g. HTMLElement (lots of tags) or HTMLQuoteElement (q and blockquote).)

Comment 2 by kojii@chromium.org, Jun 11 2016

Thank you for the comment. Filed this bug because I originally thought this should work spec-wise and this is impl issue, but sounds like this is still a spec issue?

If there's no consensus to allow this yet, I personally vote not to allow in v1. Not only spec/js part but impl has an issue that once it creates a native HTMLElement instance, replacing it with a native HTMLImageElement during upgrade isn't easy.

rniwa seems to have some wish to change upgrade logic in future, so we could revisit that at that point.

I'll check with dominicc@ on Monday.
I have posted a spec fix to prevent this at https://github.com/whatwg/html/pull/1451.
Components: Blink>DOM

Comment 5 by p...@otaqui.com, Sep 28 2016

The call to customElements.define() in the OP's code should, I think, contain a third parameter which also specifies which element to extend:

class C extends HTMLImageElement {
  constructor() { super(); }
}
customElements.define('a-a', C, {extends: 'img');

Doing this, in Chrome 55.0.2873.4, throws "TypeError: Illegal constructor".

FWIW - I came across this problem when reading these documents about CE v1:

https://html.spec.whatwg.org/multipage/scripting.html#custom-elements-customized-builtin-example

https://developers.google.com/web/fundamentals/primers/customelements/

Comment 6 by p...@otaqui.com, Sep 28 2016

Actually I see that this is already being addressed:

https://bugs.chromium.org/p/chromium/issues/detail?id=618606
Status: WontFix (was: Assigned)
I'm going to mark this obsolete. The short answer is:

Yes, you can write customized built-in elements with "is" and "extends".

Yes, you could write extends HTMLImageElement and call "super". You won't be able to construct these, but the failure is well specified: The super call will check whether the tag name you're creating (eg "a-a") is a legal one for the active function object (HTMLImageElement) and throw a TypeError.

Those checks are not implemented yet, but will be real soon now.

In the meantime, per Comment 5, we throw a TypeError. So the behavior is almost identical. We'll just change the wording of the error message to make it more detailed.

Sign in to add a comment