Skip to content

Commit 9c9b080

Browse files
domenicannevk
authored andcommitted
Move the check on registering an element interface as a custom element
Previously, this would be prevented at definition time. However, that required extra work to know all of the possible element interfaces, and was inconsistent with other failure cases. This moves the necessary check to construction time, which allows it to be simplified. Fixes WICG/webcomponents#541.
1 parent b2764ef commit 9c9b080

File tree

1 file changed

+24
-31
lines changed

1 file changed

+24
-31
lines changed

source

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2915,7 +2915,6 @@ a.setAttribute('href', 'http://example.com/'); // change the content attribute d
29152915
<li><dfn data-x-href="https://heycam.github.io/webidl/#dfn-perform-a-security-check">perform a security check</dfn>
29162916
<li><dfn data-x-href="https://heycam.github.io/webidl/#dfn-platform-object">platform object</dfn></li>
29172917
<li><dfn data-x-href="https://heycam.github.io/webidl/#dfn-interface-object">interface object</dfn></li>
2918-
<li><dfn data-x-href="https://heycam.github.io/webidl/#dfn-inherited-interfaces">inherited interfaces</dfn></li>
29192918
<li><dfn data-x-href="https://heycam.github.io/webidl/#es-platform-objects">global environment associated with</dfn> a platform object</li>
29202919
<li><dfn data-noexport="" data-x-href="https://heycam.github.io/webidl/#dfn-callback-context">callback context</dfn>
29212920
<li><dfn data-x-href="https://heycam.github.io/webidl/#dfn-frozen-array-type">frozen array</dfn>
@@ -9757,6 +9756,26 @@ interface <dfn>HTMLUnknownElement</dfn> : <span>HTMLElement</span> { };</pre>
97579756
<li><p>Let <var>registry</var> be the <span>current global object</span>'s
97589757
<code>CustomElementsRegistry</code> object.</p></li>
97599758

9759+
<li>
9760+
<p>If NewTarget is equal to the <span>active function object</span>, then throw a
9761+
<code>TypeError</code> and abort these steps.</p>
9762+
9763+
<div class="example no-backref">
9764+
<p>This can occur when a custom element is defined using an <span>element interface</span> as
9765+
its constructor:</p>
9766+
9767+
<pre>customElements.define("bad-1", HTMLButtonElement);
9768+
new HTMLButtonElement(); // (1)
9769+
document.createElement("bad-1"); // (2)</pre>
9770+
9771+
<p>In this case, during the execution of <code>HTMLButtonElement</code> (either explicitly, as
9772+
in (1), or implicitly, as in (2)), both the <span>active function object</span> and NewTarget
9773+
are <code>HTMLButtonElement</code>. If this check was not present, it would be possible to
9774+
create an instance of <code>HTMLButtonElement</code> whose local name was <code
9775+
data-x="">bad-1</code>.</p>
9776+
</div>
9777+
</li>
9778+
97609779
<li>
97619780
<p>Let <var>definition</var> be the entry in <var>registry</var> with <span
97629781
data-x="concept-custom-element-definition-constructor">constructor</span> equal to NewTarget. If
@@ -9783,10 +9802,10 @@ interface <dfn>HTMLUnknownElement</dfn> : <span>HTMLElement</span> { };</pre>
97839802
<p>This can occur when a custom element is defined to not extend any local names, but
97849803
inherits from a non-<code>HTMLElement</code> class:</p>
97859804

9786-
<pre>customElements.define("bad-1", class Bad1 extends HTMLParagraphElement {});</pre>
9805+
<pre>customElements.define("bad-2", class Bad2 extends HTMLParagraphElement {});</pre>
97879806

97889807
<p>In this case, during the (implicit) <code data-x="">super()</code> call that occurs when
9789-
constructing an instance of <code data-x="">Bad1</code>, the <span>active function
9808+
constructing an instance of <code data-x="">Bad2</code>, the <span>active function
97909809
object</span> is <code>HTMLParagraphElement</code>, not <code>HTMLElement</code>.</p>
97919810
</div>
97929811
</li>
@@ -9811,10 +9830,10 @@ interface <dfn>HTMLUnknownElement</dfn> : <span>HTMLElement</span> { };</pre>
98119830
<p>This can occur when a custom element is defined to extend a given local name but inherits
98129831
from the wrong class:</p>
98139832

9814-
<pre>customElements.define("bad-2", class Bad2 extends HTMLQuoteElement {}, { extends: "p" });</pre>
9833+
<pre>customElements.define("bad-3", class Bad3 extends HTMLQuoteElement {}, { extends: "p" });</pre>
98159834

98169835
<p>In this case, during the (implicit) <code data-x="">super()</code> call that occurs when
9817-
constructing an instance of <code data-x="">Bad2</code>, <var>valid local names</var> is the
9836+
constructing an instance of <code data-x="">Bad3</code>, <var>valid local names</var> is the
98189837
list containing <code>q</code> and <code>blockquote</code>, but <var>definition</var>'s <span
98199838
data-x="concept-custom-element-definition-local-name">local name</span> is <code>p</code>,
98209839
which is not in that list.</p>
@@ -66411,32 +66430,6 @@ dictionary <dfn>ElementDefinitionOptions</dfn> {
6641166430
<li><p>If <span>IsConstructor</span>(<var>constructor</var>) is false, then throw a
6641266431
<code>TypeError</code> and abort these steps.</p></li>
6641366432

66414-
<li>
66415-
<p>If <var>constructor</var> is either an <span>interface object</span> or <span>named
66416-
constructor</span>, whose corresponding interface either is <code>HTMLElement</code> or has
66417-
<code>HTMLElement</code> in its set of <span>inherited interfaces</span>, throw a
66418-
<code>TypeError</code> and abort these steps.</p>
66419-
66420-
<div class="note">
66421-
<p>This prevents passing, for example, <code class="no-backref">HTMLButtonElement</code> as
66422-
<var>constructor</var>, and thus enabling the creation of <code
66423-
class="no-backref">HTMLButtonElement</code> instances with a local name that is not <code
66424-
class="no-backref">button</code>.</p>
66425-
66426-
<p>Author-defined <span data-x="custom element constructor">custom element constructors</span>,
66427-
created for example via <code data-x="">class extends HTMLElement {}</code> or <code
66428-
data-x="">class extends HTMLButtonElement {}</code>, will pass this step without throwing a
66429-
<code>TypeError</code>, since they are not <span data-x="interface object">interface
66430-
objects</span>.</p>
66431-
66432-
<p><span data-x="interface object">Interface objects</span> that do not inherit from
66433-
<code>HTMLElement</code> (for example <code class="no-backref">TextTrack</code>), or classes
66434-
defined in the JavaScript specification (such as <code data-x="">Set</code>), will pass this
66435-
step without throwing a <code>TypeError</code>. However, they will later cause <span>create an
66436-
element</span> to fail.</p>
66437-
</div>
66438-
</li>
66439-
6644066433
<li><p>If <var>name</var> is not a <span>valid custom element name</span>, then throw a
6644166434
<span>"<code>SyntaxError</code>"</span> <code>DOMException</code> and abort these steps.</p></li>
6644266435

0 commit comments

Comments
 (0)