Skip to content

Commit 6c2b768

Browse files
committed
Remove quadratic behavior from clone a node
Strictly speaking this should be an editorial change, but as it's fairly significant not marking it as such. This improves integration with HTML as well. As part of this change we move the shadow tree behavior under creating the element clone as that is a more logical fit. Unfortunately subtree has to be passed everywhere as HTML needs it for its template element logic. That's also why clone a node's children is exported. Corresponding HTML PR: SOON. Fixes #1219. Closes #1220.
1 parent 719e45b commit 6c2b768

File tree

1 file changed

+79
-56
lines changed

1 file changed

+79
-56
lines changed

dom.bs

Lines changed: 79 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -4097,7 +4097,7 @@ interface Node : EventTarget {
40974097
[CEReactions] attribute DOMString? textContent;
40984098
[CEReactions] undefined normalize();
40994099

4100-
[CEReactions, NewObject] Node cloneNode(optional boolean deep = false);
4100+
[CEReactions, NewObject] Node cloneNode(optional boolean subtree = false);
41014101
boolean isEqualNode(Node? otherNode);
41024102
boolean isSameNode(Node? otherNode); // legacy alias of ===
41034103

@@ -4520,9 +4520,9 @@ each <a for=tree>descendant</a> <a>exclusive <code>Text</code> node</a> <var>nod
45204520
<hr>
45214521

45224522
<dl class=domintro>
4523-
<dt><code><var>node</var> . <a method for=Node lt=cloneNode()>cloneNode([<var>deep</var> = false])</a></code>
4523+
<dt><code><var>node</var> . <a method for=Node lt=cloneNode()>cloneNode([<var>subtree</var> = false])</a></code>
45244524
<dd>Returns a copy of <var>node</var>. If
4525-
<var>deep</var> is true, the copy also includes the
4525+
<var>subtree</var> is true, the copy also includes the
45264526
<var>node</var>'s <a for=tree>descendants</a>.
45274527

45284528
<dt><code><var>node</var> . {{Node/isEqualNode(otherNode)}}</code>
@@ -4534,31 +4534,59 @@ each <a for=tree>descendant</a> <a>exclusive <code>Text</code> node</a> <var>nod
45344534

45354535
<a lt="Other applicable specifications">Specifications</a> may define
45364536
<dfn export id=concept-node-clone-ext>cloning steps</dfn> for all or some <a for=/>nodes</a>. The
4537-
algorithm is passed <var>copy</var>, <var>node</var>, <var>document</var>, and an optional
4538-
<i>clone children flag</i>, as indicated in the <a lt="clone a node">clone</a> algorithm.
4537+
algorithm is passed <var>node</var>, <var>copy</var>, and <var>subtree</var> as indicated in the
4538+
<a>clone a single node</a> algorithm.
45394539

4540-
<p class=note>HTML defines <a>cloning steps</a> for <{script}> and <{input}>
4541-
elements. SVG ought to do the same for its <{script}> elements, but does not call this out
4542-
at the moment.
4540+
<p class=note>HTML defines <a>cloning steps</a> for several elements, such as <{input}>, <{script}>,
4541+
and <{template}>. SVG ought to do the same for its <{script}> elements, but does not.
45434542

4544-
<p>To <dfn export id=concept-node-clone lt="clone a node" local-lt="clone">clone</dfn> a
4545-
<var>node</var>, with an optional <var>document</var> and <i>clone children flag</i>, run these
4546-
steps:
4547-
<!-- This algorithm is used by dom-Node-cloneNode, dom-Document-importNode,
4548-
dom-Range-extractContents, dom-Range-cloneContents -->
4543+
<p>To <dfn export id=concept-node-clone local-lt="clone">clone a node</dfn> given a
4544+
<a for=/>node</a> <var>node</var> and an optional <a for=/>document</a> <var>document</var> (default
4545+
<var>node</var>'s <a for=Node>node document</a>) and boolean <var>subtree</var> (default false):
45494546

45504547
<ol>
4551-
<li><p>If <var>document</var> is not given, then set <var>document</var> to <var>node</var>'s
4552-
<a for=Node>node document</a>.
4553-
45544548
<li><a for=/>Assert</a>: <var>node</var> is not a <a for=/>document</a> or <var>node</var> is
45554549
<var>document</var>.
45564550

4551+
<li><p>Let <var>copy</var> be the result of <a>cloning a single node</a> given <var>node</var>,
4552+
<var>document</var>, and <var>subtree</var>.
4553+
4554+
<li><p>If <var>subtree</var> is true, then <a>clone a node's children</a> given <var>node</var>,
4555+
<var>copy</var>, <var>document</var>, and <var>subtree</var>.
4556+
4557+
<li><p>Return <var>copy</var>.
4558+
</ol>
4559+
4560+
<p>To <dfn export>clone a node's children</dfn> given a <a for=/>node</a> <var>node</var>, a
4561+
<a for=/>node</a> <var>copy</var>, a <a for=/>document</a> <var>document</var>, and a boolean
4562+
<var>subtree</var>:
4563+
4564+
<ol>
4565+
<li>
4566+
<p>For each <var>child</var> of <var>node</var>'s <a for=tree>children</a>, in <a>tree order</a>:
4567+
4568+
<ol>
4569+
<li><p>Let <var>childCopy</var> be the result of <a>cloning a single node</a> given
4570+
<var>node</var>, <var>document</var>, and <var>subtree</var>.
4571+
4572+
<li><p><a for=/>Append</a> <var>childCopy</var> to <var>copy</var>.
4573+
4574+
<li><p><a>Clone a node's children</a> given <var>child</var>, <var>childCopy</var>,
4575+
<var>document</var>, and <var>subtree</var>.
4576+
</ol>
4577+
</ol>
4578+
4579+
<p>To <dfn>clone a single node</dfn> given a <a for=/>node</a> <var>node</var>,
4580+
<a for=/>document</a> <var>document</var>, and boolean <var>subtree</var>:
4581+
4582+
<ol>
4583+
<li><p>Let <var>copy</var> be null.
4584+
45574585
<li>
45584586
<p>If <var>node</var> is an <a for=/>element</a>:
45594587

45604588
<ol>
4561-
<li><p>Let <var>copy</var> be the result of <a>creating an element</a>, given
4589+
<li><p>Set <var>copy</var> to the result of <a>creating an element</a>, given
45624590
<var>document</var>, <var>node</var>'s <a for=Element>local name</a>, <var>node</var>'s
45634591
<a for=Element>namespace</a>, <var>node</var>'s <a for=Element>namespace prefix</a>, and
45644592
<var>node</var>'s <a><code>is</code> value</a>.
@@ -4573,11 +4601,31 @@ dom-Range-extractContents, dom-Range-cloneContents -->
45734601
<li><p><a lt="append an attribute">Append</a> <var>copyAttribute</var> to <var>copy</var>.
45744602
</ol>
45754603
</li>
4604+
4605+
<li>
4606+
<p>If <var>node</var> is a <a for=Element>shadow host</a> and its
4607+
<a for=Element>shadow root</a>'s <a for=ShadowRoot>clonable</a> is true:
4608+
4609+
<ol>
4610+
<li><p>Assert: <var>copy</var> is not a <a for=Element>shadow host</a>.
4611+
4612+
<li><p>Run <a>attach a shadow root</a> with <var>copy</var>, <var>node</var>'s
4613+
<a for=Element>shadow root</a>'s <a for=ShadowRoot>mode</a>, true, <var>node</var>'s
4614+
<a for=Element>shadow root</a>'s <a for=ShadowRoot>serializable</a>, <var>node</var>'s
4615+
<a for=Element>shadow root</a>'s <a for=ShadowRoot>delegates focus</a>, and <var>node</var>'s
4616+
<a for=Element>shadow root</a>'s <a for=ShadowRoot>slot assignment</a>.
4617+
4618+
<li><p>Set <var>copy</var>'s <a for=Element>shadow root</a>'s <a for=ShadowRoot>declarative</a>
4619+
to <var>node</var>'s <a for=Element>shadow root</a>'s <a for=ShadowRoot>declarative</a>.
4620+
4621+
<li><p><a>Clone a node's children</a> given <var>node</var>'s <a for=Element>shadow root</a>,
4622+
<var>copy</var>'s <a for=Element>shadow root</a>, and <var>document</var>.
4623+
</ol>
45764624
</ol>
45774625
</li>
45784626

45794627
<li>
4580-
<p>Otherwise, let <var>copy</var> be a <a for=/>node</a> that <a>implements</a> the same
4628+
<p>Otherwise, set <var>copy</var> to a <a for=/>node</a> that <a>implements</a> the same
45814629
interfaces as <var>node</var>, and fulfills these additional requirements, switching on the
45824630
interface <var>node</var> <a>implements</a>:
45834631

@@ -4607,53 +4655,28 @@ dom-Range-extractContents, dom-Range-cloneContents -->
46074655
<dd><p>Do nothing.
46084656
</dl>
46094657

4658+
<li><p><a for=/>Assert</a>: <var>copy</var> is a <a for=/>node</a>.
4659+
46104660
<li><p>If <var>node</var> is a <a for=/>document</a>, then set <var>document</var> to
46114661
<var>copy</var>.
46124662

46134663
<li><p>Set <var>copy</var>'s <a for=Node>node document</a> to <var>document</var>.
46144664

46154665
<li><p>Run any <a>cloning steps</a> defined for <var>node</var> in
4616-
<a>other applicable specifications</a> and pass <var>copy</var>, <var>node</var>,
4617-
<var>document</var>, and the <i>clone children flag</i> if set, as parameters.
4618-
4619-
<li><p>If the <i>clone children flag</i> is set, then for each <a for=tree>child</a>
4620-
<var>child</var> of <var>node</var>, in <a>tree order</a>: <a>append</a> the result of
4621-
<a lt="clone a node">cloning</a> <var>child</var> with <var>document</var> and the
4622-
<i>clone children flag</i> set, to <var>copy</var>.
4623-
4624-
<li>
4625-
<p>If <var>node</var> is a <a for=Element>shadow host</a> whose <a for=/>shadow root</a>'s
4626-
<a for=ShadowRoot>clonable</a> is true:
4627-
4628-
<ol>
4629-
<li><p>Assert: <var>copy</var> is not a <a for=Element>shadow host</a>.
4630-
4631-
<li><p>Run <a>attach a shadow root</a> with <var>copy</var>, <var>node</var>'s
4632-
<a for=Element>shadow root</a>'s <a for=ShadowRoot>mode</a>, true, <var>node</var>'s
4633-
<a for=Element>shadow root</a>'s <a for=ShadowRoot>serializable</a>, <var>node</var>'s
4634-
<a for=Element>shadow root</a>'s <a for=ShadowRoot>delegates focus</a>, and <var>node</var>'s
4635-
<a for=Element>shadow root</a>'s <a for=ShadowRoot>slot assignment</a>.
4636-
4637-
<li><p>Set <var>copy</var>'s <a for=Element>shadow root</a>'s <a for=ShadowRoot>declarative</a>
4638-
to <var>node</var>'s <a for=Element>shadow root</a>'s <a for=ShadowRoot>declarative</a>.
4639-
4640-
<li><p>For each <a for=tree>child</a> <var>child</var> of <var>node</var>'s
4641-
<a for=Element>shadow root</a>, in <a>tree order</a>: <a>append</a> the result of
4642-
<a lt="clone a node">cloning</a> <var>child</var> with <var>document</var> and the
4643-
<i>clone children flag</i> set, to <var>copy</var>'s <a for=Element>shadow root</a>.
4644-
</ol>
4666+
<a>other applicable specifications</a> and pass <var>node</var>, <var>copy</var>, and
4667+
<var>subtree</var>.
46454668

46464669
<li><p>Return <var>copy</var>.
46474670
</ol>
46484671

4649-
<p>The <dfn method for=Node><code>cloneNode(<var>deep</var>)</code></dfn> method steps are:
4672+
<p>The <dfn method for=Node><code>cloneNode(<var>subtree</var>)</code></dfn> method steps are:
46504673

46514674
<ol>
46524675
<li><p>If <a>this</a> is a <a for=/>shadow root</a>, then <a>throw</a> a
46534676
"{{NotSupportedError!!exception}}" {{DOMException}}.
46544677

4655-
<li><p>Return a <a lt="clone a node">clone</a> of <a>this</a>, with the
4656-
<i>clone children flag</i> set if <var>deep</var> is true.
4678+
<li><p>Return the result of <a>cloning a node</a> given <a>this</a>, <a>this</a>'s
4679+
<a for=Node>node document</a>, and <var>subtree</var>.
46574680
</ol>
46584681

46594682
<p>A <a for=/>node</a> <var>A</var> <dfn export for=Node id=concept-node-equals>equals</dfn> a
@@ -5126,7 +5149,7 @@ interface Document : Node {
51265149
[NewObject] Comment createComment(DOMString data);
51275150
[NewObject] ProcessingInstruction createProcessingInstruction(DOMString target, DOMString data);
51285151

5129-
[CEReactions, NewObject] Node importNode(Node node, optional boolean deep = false);
5152+
[CEReactions, NewObject] Node importNode(Node node, optional boolean subtree = false);
51305153
[CEReactions] Node adoptNode(Node node);
51315154

51325155
[NewObject] Attr createAttribute(DOMString localName);
@@ -5552,9 +5575,9 @@ method steps are:
55525575
<hr>
55535576

55545577
<dl class=domintro>
5555-
<dt><var>clone</var> = <var>document</var> . <a method for=Document lt=importNode()>importNode(<var>node</var> [, <var>deep</var> = false])</a>
5578+
<dt><var>clone</var> = <var>document</var> . <a method for=Document lt=importNode()>importNode(<var>node</var> [, <var>subtree</var> = false])</a>
55565579
<dd>
5557-
<p>Returns a copy of <var>node</var>. If <var>deep</var> is true, the copy also includes the
5580+
<p>Returns a copy of <var>node</var>. If <var>subtree</var> is true, the copy also includes the
55585581
<var>node</var>'s <a for=tree>descendants</a>.
55595582

55605583
<p>If <var>node</var> is a <a>document</a> or a <a for=/>shadow root</a>, throws a
@@ -5571,15 +5594,15 @@ method steps are:
55715594
"{{HierarchyRequestError!!exception}}" {{DOMException}}.
55725595
</dl>
55735596

5574-
<p>The <dfn method for=Document><code>importNode(<var>node</var>, <var>deep</var>)</code></dfn>
5597+
<p>The <dfn method for=Document><code>importNode(<var>node</var>, <var>subtree</var>)</code></dfn>
55755598
method steps are:
55765599

55775600
<ol>
55785601
<li><p>If <var>node</var> is a <a>document</a> or <a for=/>shadow root</a>, then <a>throw</a> a
55795602
"{{NotSupportedError!!exception}}" {{DOMException}}.
55805603

5581-
<li><p>Return a <a lt="clone a node">clone</a> of <var>node</var>, with <a>this</a> and the
5582-
<i>clone children flag</i> set if <var>deep</var> is true.
5604+
<li><p>Return the result of <a>cloning a node</a> given <var>node</var>, <a>this</a>, and
5605+
<var>subtree</var>.
55835606
</ol>
55845607

55855608
<p><a lt="Other applicable specifications">Specifications</a> may define

0 commit comments

Comments
 (0)