Skip to content

Commit 1d112e1

Browse files
tkent-googledomenic
authored andcommitted
Custom elements: add element internals
This provides the ElementInternals interface, which can be obtained for custom elements via the element.attachInternals() method. For now ElementInternals is empty, but it will gain members in #4383. This also adds the ability for custom elements to set the disabledFeatures static property, to disable element internals and shadow DOM. Some DOM-side infrastructure work there is necessary in whatwg/dom#760. Tests: - web-platform-tests/wpt#15123 - web-platform-tests/wpt#15516 - web-platform-tests/wpt#16853 Fixes WICG/webcomponents#758.
1 parent 6ba1b38 commit 1d112e1

File tree

1 file changed

+97
-5
lines changed

1 file changed

+97
-5
lines changed

source

Lines changed: 97 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3143,6 +3143,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
31433143
<li><dfn data-x-href="https://dom.spec.whatwg.org/#interface-documenttype"><code>DocumentType</code></dfn> interface</li>
31443144
<li><dfn data-x-href="https://dom.spec.whatwg.org/#interface-childnode"><code>ChildNode</code></dfn> interface</li>
31453145
<li><dfn data-x-href="https://dom.spec.whatwg.org/#interface-element"><code>Element</code></dfn> interface</li>
3146+
<li><dfn data-x="dom-element-attachshadow" data-x-href="https://dom.spec.whatwg.org/#dom-element-attachshadow"><code>attachShadow()</code></dfn> method.</li>
31463147
<li><dfn data-x-href="https://dom.spec.whatwg.org/#interface-node"><code>Node</code></dfn> interface</li>
31473148
<li><dfn data-x-href="https://dom.spec.whatwg.org/#interface-nodelist"><code>NodeList</code></dfn> interface</li>
31483149
<li><dfn data-x-href="https://dom.spec.whatwg.org/#interface-processinginstruction"><code>ProcessingInstruction</code></dfn> interface</li>
@@ -10180,6 +10181,8 @@ interface <dfn>HTMLElement</dfn> : <span>Element</span> {
1018010181
[<span>CEReactions</span>] attribute DOMString <span data-x="dom-autocapitalize">autocapitalize</span>;
1018110182

1018210183
[<span>CEReactions</span>] attribute [TreatNullAs=EmptyString] DOMString <span data-x="dom-innerText">innerText</span>;
10184+
10185+
<span>ElementInternals</span> <span data-x="dom-attachInternals">attachInternals</span>();
1018310186
};
1018410187

1018510188
<span>HTMLElement</span> includes <span>GlobalEventHandlers</span>;
@@ -66726,6 +66729,14 @@ document.body.append(parent);
6672666729
href="#html-element-constructors">HTML element constructors</a>. Each entry in the list will be
6672766730
either an element or an <dfn data-x="concept-already-constructed-marker"><i>already
6672866731
constructed</i> marker</dfn>.</dd>
66732+
66733+
<dt>A <dfn data-x="concept-custom-element-definition-disable-internals">disable
66734+
internals</dfn> boolean</dt>
66735+
<dd>Controls <code data-x="dom-attachInternals">attachInternals()</code>.
66736+
66737+
<dt>A <dfn data-x="concept-custom-element-definition-disable-shadow" data-export=""
66738+
data-dfn-for="custom element definition">disable shadow</dfn> boolean</dt>
66739+
<dd>Controls <code data-x="dom-element-attachshadow">attachShadow()</code>.
6672966740
</dl>
6673066741

6673166742
<p>To <dfn data-export="">look up a custom element definition</dfn>, given a <var>document</var>,
@@ -66899,6 +66910,13 @@ dictionary <dfn>ElementDefinitionOptions</dfn> {
6689966910
<li><p>Set this <code>CustomElementRegistry</code>'s <span>element definition is running</span>
6690066911
flag.</p></li>
6690166912

66913+
<li><p>Let <var>disableInternals</var> be false.
66914+
66915+
<li><p>Let <var>disableShadow</var> be false.
66916+
66917+
<li><p>Let <var>observedAttributes</var> be an empty <code
66918+
data-x="">sequence&lt;DOMString></code>.</p></li>
66919+
6690266920
<li>
6690366921
<p>Run the following substeps while catching any exceptions:</p>
6690466922

@@ -66930,9 +66948,6 @@ dictionary <dfn>ElementDefinitionOptions</dfn> {
6693066948
</ol>
6693166949
</li>
6693266950

66933-
<li><p>Let <var>observedAttributes</var> be an empty <code
66934-
data-x="">sequence&lt;DOMString></code>.</p></li>
66935-
6693666951
<li>
6693766952
<p>If the value of the entry in <var>lifecycleCallbacks</var> with key "<code
6693866953
data-x="">attributeChangedCallback</code>" is not null, then:</p>
@@ -66948,6 +66963,24 @@ dictionary <dfn>ElementDefinitionOptions</dfn> {
6694866963
<code data-x="">sequence&lt;DOMString></code>. Rethrow any exceptions from the
6694966964
conversion.</p></li>
6695066965
</ol>
66966+
66967+
<li><p>Let <var>disabledFeatures</var> be an empty <code
66968+
data-x="">sequence&lt;DOMString></code>.</p></li>
66969+
66970+
<li><p>Let <var>disabledFeaturesIterable</var> be <span
66971+
data-x="js-Get">Get</span>(<var>constructor</var>, "disabledFeatures"). Rethrow any
66972+
exceptions.</p></li>
66973+
66974+
<li><p>If <var>disabledFeaturesIterable</var> is not undefined, then set
66975+
<var>disabledFeatures</var> to the result of <span
66976+
data-x="concept-idl-convert">converting</span> <var>disabledFeaturesIterable</var> to a <code
66977+
data-x="">sequence&lt;DOMString></code>. Rethrow any exceptions from the conversion.</p></li>
66978+
66979+
<li><p>Set <var>disableInternals</var> to true if <var>disabledFeaturesSequence</var>
66980+
<span data-x="list contains">contains</span> "<code data-x="">internals</code>".</p></li>
66981+
66982+
<li><p>Set <var>disableShadow</var> to true if <var>disabledFeaturesSequence</var>
66983+
<span data-x="list contains">contains</span> "<code data-x="">shadow</code>".</p></li>
6695166984
</ol>
6695266985

6695366986
<p>Then, perform the following substep, regardless of whether the above steps threw an exception
@@ -66968,9 +67001,13 @@ dictionary <dfn>ElementDefinitionOptions</dfn> {
6696867001
<span data-x="concept-custom-element-definition-constructor">constructor</span>
6696967002
<var>constructor</var>, <span
6697067003
data-x="concept-custom-element-definition-observed-attributes">observed attributes</span>
66971-
<var>observedAttributes</var>, and <span
67004+
<var>observedAttributes</var>, <span
6697267005
data-x="concept-custom-element-definition-lifecycle-callbacks">lifecycle callbacks</span>
66973-
<var>lifecycleCallbacks</var>.</p></li>
67006+
<var>lifecycleCallbacks</var>, <span
67007+
data-x="concept-custom-element-definition-disable-internals">disable internals</span>
67008+
<var>disableInternals</var>, and <span
67009+
data-x="concept-custom-element-definition-disable-shadow">disable shadow</span>
67010+
<var>disableShadow</var>.</p></li>
6697467011

6697567012
<li><p>Add <var>definition</var> to this <code>CustomElementRegistry</code>.</p></li>
6697667013

@@ -67543,6 +67580,61 @@ customElements.define("x-foo", class extends HTMLElement {
6754367580

6754467581
</div>
6754567582

67583+
<h4>The <code>ElementInternals</code> interface</h4>
67584+
67585+
<dl class="domintro">
67586+
<dt><var>element</var> . <code subdfn data-x="dom-attachInternals">attachInternals()</code></dt>
67587+
67588+
<dd><p>Returns an <code>ElementInternals</code> object targeting the <span>custom element</span>
67589+
<var>element</var>. Throws an exception if <var>element</var> is not a <span>custom
67590+
element</span>, if the "<code data-x="">internals</code>" feature was disabled as part of the
67591+
element definition, or if it is called twice on the same element.</p></dd>
67592+
</dl>
67593+
67594+
<pre><code class="idl" data-x="">[Exposed=Window]
67595+
interface <dfn>ElementInternals</dfn> {
67596+
<!-- We'll add some stuff here -->
67597+
};</code></pre>
67598+
67599+
<!-- We should have a domintro block for ElementInternals -->
67600+
67601+
<p>Each <code>ElementInternals</code> has a <dfn data-x="internals-target">target element</dfn>,
67602+
which is a <span>custom element</span>. <code>ElementInternals</code> provides various operations
67603+
and attributes to allow control over internal features which the user agent provides to all
67604+
elements.</p>
67605+
67606+
<p>Each <code>HTMLElement</code> has an <dfn>attached internals</dfn> boolean, initially
67607+
false.</p>
67608+
67609+
<p>The <dfn><code data-x="dom-attachInternals">attachInternals()</code></dfn> method on
67610+
an <code>HTMLElement</code> <var>element</var>, when invoked, must run the following steps:</p>
67611+
67612+
<ol>
67613+
<!-- We could lift this restriction in the future. -->
67614+
<li><p>If <var>element</var>'s <span data-x="concept-element-is-value"><code
67615+
data-x="">is</code> value</span> is not null, then throw a
67616+
<span>"<code>NotSupportedError</code>"</span> <code>DOMException</code>.</p></li>
67617+
67618+
<li><p>Let <var>definition</var> be the result of <span
67619+
data-x="look up a custom element definition">looking up a custom element definition</span> given
67620+
<var>element</var>'s <span>node document</span>, its namespace, its local name, and null as
67621+
<span data-x="concept-element-is-value"><code data-x="">is</code> value</span>.</p></li>
67622+
67623+
<li><p>If <var>definition</var> is null, then throw an
67624+
<span>"<code>NotSupportedError</code>"</span> <code>DOMException</code>.</p></li>
67625+
67626+
<li><p>If <var>definition</var>'s <span
67627+
data-x="concept-custom-element-definition-disable-internals">disable internals</span> is true,
67628+
then throw a <span>"<code>NotSupportedError</code>"</span> <code>DOMException</code>.</p></li>
67629+
67630+
<li><p>If <var>element</var>'s <span>attached internals</span> is true, then throw an
67631+
<span>"<code>NotSupportedError</code>"</span> <code>DOMException</code>.</p></li>
67632+
67633+
<li><p>Set <var>element</var>'s <span>attached internals</span> to true.</p></li>
67634+
67635+
<li><p>Create a new <code>ElementInternals</code> instance
67636+
<span data-x="internals-target">targeting</span> <var>element</var>, and return it.</p></li>
67637+
</ol>
6754667638

6754767639
<h3 split-filename="semantics-other" id="common-idioms">Common idioms without dedicated elements</h3>
6754867640

0 commit comments

Comments
 (0)