Skip to content

Commit 7cd51e7

Browse files
authored
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. All the arguments are exported as HTML needs them as well. And they are named parameters now for clarity. Corresponding HTML PR: whatwg/html#10859. Fixes #1219. Closes #1220.
1 parent 10dbae4 commit 7cd51e7

File tree

1 file changed

+95
-68
lines changed

1 file changed

+95
-68
lines changed

dom.bs

+95-68
Original file line numberDiff line numberDiff line change
@@ -972,8 +972,8 @@ object, an <a>event listener</a> is a broader concept as can be seen above.
972972
which takes an <a>event</a> <var>event</var>, and returns an {{EventTarget}} object. Unless
973973
specified otherwise it returns null.
974974

975-
<p class=note><a for=/>Nodes</a>, <a for=/>shadow roots</a>, and <a>documents</a>
976-
override the <a>get the parent</a> algorithm.
975+
<p class=note><a for=/>Nodes</a>, <a for=/>shadow roots</a>, and <a for=/>documents</a> override the
976+
<a>get the parent</a> algorithm.
977977

978978
<p>Each {{EventTarget}} object can have an associated
979979
<dfn export for=EventTarget>activation behavior</dfn> algorithm. The
@@ -2218,7 +2218,7 @@ It is represented as follows:
22182218

22192219
<ul class=domTree>
22202220
<li>
2221-
<a>Document</a>
2221+
<a for=/>Document</a>
22222222
<ul>
22232223
<li class=t10><a>Doctype</a>: <code>html</code>
22242224
<li class=t1>{{Element}}: <code>html</code> <span class=t2><code class="attribute name">class</code>="<code class="attribute value">e</code>"</span>
@@ -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

@@ -4294,7 +4294,7 @@ statement, switching on the interface <a>this</a> <a>implements</a>:
42944294
<dt><code><var>node</var> . {{Node/ownerDocument}}</code>
42954295
<dd>
42964296
Returns the <a for=Node>node document</a>.
4297-
Returns null for <a>documents</a>.
4297+
Returns null for <a for=/>documents</a>.
42984298

42994299
<dt><code><var>node</var> . {{Node/getRootNode()}}</code>
43004300
<dd>Returns <var>node</var>'s <a for=tree>root</a>.
@@ -4521,9 +4521,9 @@ each <a for=tree>descendant</a> <a>exclusive <code>Text</code> node</a> <var>nod
45214521
<hr>
45224522

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

45294529
<dt><code><var>node</var> . {{Node/isEqualNode(otherNode)}}</code>
@@ -4533,33 +4533,83 @@ each <a for=tree>descendant</a> <a>exclusive <code>Text</code> node</a> <var>nod
45334533

45344534
<div class=impl>
45354535

4536+
<div algorithm>
45364537
<a lt="Other applicable specifications">Specifications</a> may define
45374538
<dfn export id=concept-node-clone-ext>cloning steps</dfn> for all or some <a for=/>nodes</a>. The
4538-
algorithm is passed <var>copy</var>, <var>node</var>, <var>document</var>, and an optional
4539-
<i>clone children flag</i>, as indicated in the <a lt="clone a node">clone</a> algorithm.
4539+
algorithm is passed <var ignore>node</var>, <var ignore>copy</var>, and <var ignore>subtree</var> as
4540+
indicated in the <a>clone a node</a> algorithm.
45404541

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

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

45514553
<ol>
4552-
<li><p>If <var>document</var> is not given, then set <var>document</var> to <var>node</var>'s
4553-
<a for=Node>node document</a>.
4554+
<li><p><a for=/>Assert</a>: <var>node</var> is not a <a for=/>document</a> or <var>node</var> is
4555+
<var>document</var>.
45544556

4555-
<li><a for=/>Assert</a>: <var>node</var> is not a <a for=/>document</a> or <var>node</var> is
4557+
<li><p>Let <var>copy</var> be the result of <a>cloning a single node</a> given <var>node</var> and
45564558
<var>document</var>.
45574559

4560+
<li><p>Run any <a>cloning steps</a> defined for <var>node</var> in
4561+
<a>other applicable specifications</a> and pass <var>node</var>, <var>copy</var>, and
4562+
<var>subtree</var> as parameters.
4563+
4564+
<li><p>If <var>parent</var> is non-null, then <a for=/>append</a> <var>copy</var> to
4565+
<var>parent</var>.
4566+
4567+
<li><p>If <var>subtree</var> is true, then for each <var>child</var> of <var>node</var>'s
4568+
<a for=tree>children</a>, in <a>tree order</a>: <a>clone a node</a> given <var>child</var> with
4569+
<a for="clone a node"><i>document</i></a> set to <var>document</var>,
4570+
<a for="clone a node"><i>subtree</i></a> set to <var>subtree</var>, and
4571+
<a for="clone a node"><i>parent</i></a> set to <var>copy</var>.
4572+
4573+
<li>
4574+
<p>If <var>node</var> is an <a for=/>element</a>, <var>node</var> is a
4575+
<a for=Element>shadow host</a>, and <var>node</var>'s <a for=Element>shadow root</a>'s
4576+
<a for=ShadowRoot>clonable</a> is true:
4577+
4578+
<ol>
4579+
<li><p><a for=/>Assert</a>: <var>copy</var> is not a <a for=Element>shadow host</a>.
4580+
4581+
<li><p><a>Attach a shadow root</a> with <var>copy</var>, <var>node</var>'s
4582+
<a for=Element>shadow root</a>'s <a for=ShadowRoot>mode</a>, true, <var>node</var>'s
4583+
<a for=Element>shadow root</a>'s <a for=ShadowRoot>serializable</a>, <var>node</var>'s
4584+
<a for=Element>shadow root</a>'s <a for=ShadowRoot>delegates focus</a>, and <var>node</var>'s
4585+
<a for=Element>shadow root</a>'s <a for=ShadowRoot>slot assignment</a>.
4586+
4587+
<li><p>Set <var>copy</var>'s <a for=Element>shadow root</a>'s <a for=ShadowRoot>declarative</a>
4588+
to <var>node</var>'s <a for=Element>shadow root</a>'s <a for=ShadowRoot>declarative</a>.
4589+
4590+
<li><p>For each <var>child</var> of <var>node</var>'s <a for=Element>shadow root</a>'s
4591+
<a for=tree>children</a>, in <a>tree order</a>: <a>clone a node</a> given <var>child</var> with
4592+
<a for="clone a node"><i>document</i></a> set to <var>document</var>,
4593+
<a for="clone a node"><i>subtree</i></a> set to <var>subtree</var>, and
4594+
<a for="clone a node"><i>parent</i></a> set to <var>copy</var>'s <a for=Element>shadow root</a>.
4595+
</ol>
4596+
4597+
<li><p>Return <var>copy</var>.
4598+
</ol>
4599+
</div>
4600+
4601+
<div algorithm>
4602+
<p>To <dfn>clone a single node</dfn> given a <a for=/>node</a> <var>node</var> and
4603+
<a for=/>document</a> <var>document</var>:
4604+
4605+
<ol>
4606+
<li><p>Let <var>copy</var> be null.
4607+
45584608
<li>
45594609
<p>If <var>node</var> is an <a for=/>element</a>:
45604610

45614611
<ol>
4562-
<li><p>Let <var>copy</var> be the result of <a>creating an element</a>, given
4612+
<li><p>Set <var>copy</var> to the result of <a>creating an element</a>, given
45634613
<var>document</var>, <var>node</var>'s <a for=Element>local name</a>, <var>node</var>'s
45644614
<a for=Element>namespace</a>, <var>node</var>'s <a for=Element>namespace prefix</a>, and
45654615
<var>node</var>'s <a><code>is</code> value</a>.
@@ -4569,16 +4619,15 @@ dom-Range-extractContents, dom-Range-cloneContents -->
45694619
<a for=Element>attribute list</a>:
45704620

45714621
<ol>
4572-
<li><p>Let <var>copyAttribute</var> be a <a>clone</a> of <var>attribute</var>.
4622+
<li><p>Let <var>copyAttribute</var> be the result of <a>cloning a single node</a> given
4623+
<var>attribute</var> and <var>document</var>.
45734624

45744625
<li><p><a lt="append an attribute">Append</a> <var>copyAttribute</var> to <var>copy</var>.
45754626
</ol>
4576-
</li>
45774627
</ol>
4578-
</li>
45794628

45804629
<li>
4581-
<p>Otherwise, let <var>copy</var> be a <a for=/>node</a> that <a>implements</a> the same
4630+
<p>Otherwise, set <var>copy</var> to a <a for=/>node</a> that <a>implements</a> the same
45824631
interfaces as <var>node</var>, and fulfills these additional requirements, switching on the
45834632
interface <var>node</var> <a>implements</a>:
45844633

@@ -4608,54 +4657,28 @@ dom-Range-extractContents, dom-Range-cloneContents -->
46084657
<dd><p>Do nothing.
46094658
</dl>
46104659

4660+
<li><p><a for=/>Assert</a>: <var>copy</var> is a <a for=/>node</a>.
4661+
46114662
<li><p>If <var>node</var> is a <a for=/>document</a>, then set <var>document</var> to
46124663
<var>copy</var>.
46134664

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

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

4650-
<p>The <dfn method for=Node><code>cloneNode(<var>deep</var>)</code></dfn> method steps are:
4671+
<div algorithm>
4672+
<p>The <dfn method for=Node><code>cloneNode(<var>subtree</var>)</code></dfn> method steps are:
46514673

46524674
<ol>
46534675
<li><p>If <a>this</a> is a <a for=/>shadow root</a>, then <a>throw</a> a
46544676
"{{NotSupportedError!!exception}}" {{DOMException}}.
46554677

4656-
<li><p>Return a <a lt="clone a node">clone</a> of <a>this</a>, with the
4657-
<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> with
4679+
<a for="clone a node"><i>subtree</i></a> set to <var>subtree</var>.
46584680
</ol>
4681+
</div>
46594682

46604683
<p>A <a for=/>node</a> <var>A</var> <dfn export for=Node id=concept-node-equals>equals</dfn> a
46614684
<a for=/>node</a> <var>B</var> if all of the following conditions are true:
@@ -5127,7 +5150,7 @@ interface Document : Node {
51275150
[NewObject] Comment createComment(DOMString data);
51285151
[NewObject] ProcessingInstruction createProcessingInstruction(DOMString target, DOMString data);
51295152

5130-
[CEReactions, NewObject] Node importNode(Node node, optional boolean deep = false);
5153+
[CEReactions, NewObject] Node importNode(Node node, optional boolean subtree = false);
51315154
[CEReactions] Node adoptNode(Node node);
51325155

51335156
[NewObject] Attr createAttribute(DOMString localName);
@@ -5188,9 +5211,9 @@ is "<code>quirks</code>", and
51885211
<a for=Document>mode</a> is "<code>limited-quirks</code>".
51895212

51905213
<div class=note>
5191-
<p>The <a for=Document>mode</a> is only ever changed from the default for <a>documents</a> created
5192-
by the <a>HTML parser</a> based on the presence, absence, or value of the DOCTYPE string, and by a
5193-
new <a for=/>browsing context</a> (initial "<code>about:blank</code>"). [[!HTML]]
5214+
<p>The <a for=Document>mode</a> is only ever changed from the default for <a for=/>documents</a>
5215+
created by the <a>HTML parser</a> based on the presence, absence, or value of the DOCTYPE string,
5216+
and by a new <a for=/>browsing context</a> (initial "<code>about:blank</code>"). [[!HTML]]
51945217

51955218
<p><a>No-quirks mode</a> was originally known as "standards mode" and <a>limited-quirks mode</a>
51965219
was once known as "almost standards mode". They have been renamed because their details are now
@@ -5554,9 +5577,9 @@ method steps are:
55545577
<hr>
55555578

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

55625585
<p>If <var>node</var> is a <a for=/>document</a> or a <a for=/>shadow root</a>, throws a
@@ -5573,16 +5596,19 @@ method steps are:
55735596
"{{HierarchyRequestError!!exception}}" {{DOMException}}.
55745597
</dl>
55755598

5576-
<p>The <dfn method for=Document><code>importNode(<var>node</var>, <var>deep</var>)</code></dfn>
5599+
<div algorithm>
5600+
<p>The <dfn method for=Document><code>importNode(<var>node</var>, <var>subtree</var>)</code></dfn>
55775601
method steps are:
55785602

55795603
<ol>
55805604
<li><p>If <var>node</var> is a <a for=/>document</a> or <a for=/>shadow root</a>, then <a>throw</a>
55815605
a "{{NotSupportedError!!exception}}" {{DOMException}}.
55825606

5583-
<li><p>Return a <a lt="clone a node">clone</a> of <var>node</var>, with <a>this</a> and the
5584-
<i>clone children flag</i> set if <var>deep</var> is true.
5607+
<li><p>Return the result of <a>cloning a node</a> given <var>node</var> with
5608+
<a for="clone a node"><i>document</i></a> set to <a>this</a> and
5609+
<a for="clone a node"><i>subtree</i></a> set to <var>subtree</var>.
55855610
</ol>
5611+
</div>
55865612

55875613
<p><a lt="Other applicable specifications">Specifications</a> may define
55885614
<dfn export id=concept-node-adopt-ext>adopting steps</dfn> for all or some <a for=/>nodes</a>. The
@@ -10402,6 +10428,7 @@ Daniel Clark,
1040210428
Daniel Glazman,
1040310429
Darien Maillet Valentine<!-- bhathos; GitHub -->,
1040410430
Darin Fisher,
10431+
David Baron,
1040510432
David Bruant,
1040610433
David Flanagan,
1040710434
David Håsäther,

0 commit comments

Comments
 (0)