Skip to content

Commit

Permalink
Move the check on registering an element interface as a custom element
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
domenic authored and annevk committed Aug 23, 2016
1 parent b2764ef commit 9c9b080
Showing 1 changed file with 24 additions and 31 deletions.
55 changes: 24 additions & 31 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -2915,7 +2915,6 @@ a.setAttribute('href', 'http://example.com/'); // change the content attribute d
<li><dfn data-x-href="https://heycam.github.io/webidl/#dfn-perform-a-security-check">perform a security check</dfn>
<li><dfn data-x-href="https://heycam.github.io/webidl/#dfn-platform-object">platform object</dfn></li>
<li><dfn data-x-href="https://heycam.github.io/webidl/#dfn-interface-object">interface object</dfn></li>
<li><dfn data-x-href="https://heycam.github.io/webidl/#dfn-inherited-interfaces">inherited interfaces</dfn></li>
<li><dfn data-x-href="https://heycam.github.io/webidl/#es-platform-objects">global environment associated with</dfn> a platform object</li>
<li><dfn data-noexport="" data-x-href="https://heycam.github.io/webidl/#dfn-callback-context">callback context</dfn>
<li><dfn data-x-href="https://heycam.github.io/webidl/#dfn-frozen-array-type">frozen array</dfn>
Expand Down Expand Up @@ -9757,6 +9756,26 @@ interface <dfn>HTMLUnknownElement</dfn> : <span>HTMLElement</span> { };</pre>
<li><p>Let <var>registry</var> be the <span>current global object</span>'s
<code>CustomElementsRegistry</code> object.</p></li>

<li>
<p>If NewTarget is equal to the <span>active function object</span>, then throw a
<code>TypeError</code> and abort these steps.</p>

<div class="example no-backref">
<p>This can occur when a custom element is defined using an <span>element interface</span> as
its constructor:</p>

<pre>customElements.define("bad-1", HTMLButtonElement);
new HTMLButtonElement(); // (1)
document.createElement("bad-1"); // (2)</pre>

<p>In this case, during the execution of <code>HTMLButtonElement</code> (either explicitly, as
in (1), or implicitly, as in (2)), both the <span>active function object</span> and NewTarget
are <code>HTMLButtonElement</code>. If this check was not present, it would be possible to
create an instance of <code>HTMLButtonElement</code> whose local name was <code
data-x="">bad-1</code>.</p>
</div>
</li>

<li>
<p>Let <var>definition</var> be the entry in <var>registry</var> with <span
data-x="concept-custom-element-definition-constructor">constructor</span> equal to NewTarget. If
Expand All @@ -9783,10 +9802,10 @@ interface <dfn>HTMLUnknownElement</dfn> : <span>HTMLElement</span> { };</pre>
<p>This can occur when a custom element is defined to not extend any local names, but
inherits from a non-<code>HTMLElement</code> class:</p>

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

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

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

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

<li>
<p>If <var>constructor</var> is either an <span>interface object</span> or <span>named
constructor</span>, whose corresponding interface either is <code>HTMLElement</code> or has
<code>HTMLElement</code> in its set of <span>inherited interfaces</span>, throw a
<code>TypeError</code> and abort these steps.</p>

<div class="note">
<p>This prevents passing, for example, <code class="no-backref">HTMLButtonElement</code> as
<var>constructor</var>, and thus enabling the creation of <code
class="no-backref">HTMLButtonElement</code> instances with a local name that is not <code
class="no-backref">button</code>.</p>

<p>Author-defined <span data-x="custom element constructor">custom element constructors</span>,
created for example via <code data-x="">class extends HTMLElement {}</code> or <code
data-x="">class extends HTMLButtonElement {}</code>, will pass this step without throwing a
<code>TypeError</code>, since they are not <span data-x="interface object">interface
objects</span>.</p>

<p><span data-x="interface object">Interface objects</span> that do not inherit from
<code>HTMLElement</code> (for example <code class="no-backref">TextTrack</code>), or classes
defined in the JavaScript specification (such as <code data-x="">Set</code>), will pass this
step without throwing a <code>TypeError</code>. However, they will later cause <span>create an
element</span> to fail.</p>
</div>
</li>

<li><p>If <var>name</var> is not a <span>valid custom element name</span>, then throw a
<span>"<code>SyntaxError</code>"</span> <code>DOMException</code> and abort these steps.</p></li>

Expand Down

0 comments on commit 9c9b080

Please sign in to comment.