pseudo-dom 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/README.md +496 -72
  2. package/browser/pseudo-dom.js +619 -284
  3. package/browser/pseudo-dom.min.js +1 -1
  4. package/dist/classes/PseudoHTMLDocument.d.ts +2 -2
  5. package/dist/classes/PseudoHTMLDocument.js +10 -21
  6. package/dist/classes/PseudoHTMLDocument.min.js +1 -1
  7. package/dist/classes/PseudoNodeList.js +14 -8
  8. package/dist/classes/PseudoNodeList.min.js +1 -1
  9. package/dist/factories/generateNode.d.ts +2 -10
  10. package/dist/factories/generateNode.js +9 -42
  11. package/dist/factories/generateNode.min.js +1 -1
  12. package/dist/functions/getParentNodes.d.ts +8 -6
  13. package/dist/functions/getParentNodes.js +16 -9
  14. package/dist/functions/getParentNodes.min.js +1 -1
  15. package/dist/functions/getParentNodesFromAttribute.d.ts +7 -7
  16. package/dist/functions/getParentNodesFromAttribute.js +21 -1
  17. package/dist/functions/getParentNodesFromAttribute.min.js +1 -1
  18. package/dist/functions.d.ts +1 -1
  19. package/dist/services/DocumentFragmentService.d.ts +9 -0
  20. package/dist/services/DocumentFragmentService.js +16 -1
  21. package/dist/services/DocumentFragmentService.min.js +1 -1
  22. package/dist/services/DocumentService.d.ts +8 -0
  23. package/dist/services/DocumentService.js +15 -1
  24. package/dist/services/DocumentService.min.js +1 -1
  25. package/dist/services/ElementService.d.ts +5 -6
  26. package/dist/services/ElementService.js +17 -13
  27. package/dist/services/ElementService.min.js +1 -1
  28. package/dist/services/NodeService.d.ts +31 -16
  29. package/dist/services/NodeService.js +90 -33
  30. package/dist/services/NodeService.min.js +1 -1
  31. package/package.json +2 -2
package/README.md CHANGED
@@ -8,14 +8,17 @@ Pseudo DOM recreates the browser DOM API (following the MDN documentation) so DO
8
8
  example in tests, without a real or headless browser. It is written in TypeScript and ships type definitions.
9
9
 
10
10
  Working today: `EventService` (Event), `EventTargetService` (EventTarget listeners for the target itself), `NodeService`
11
- (Node: children, siblings, `appendChild`, `removeChild`), `ElementService` / `HTMLElementService` (Element and
12
- HTMLElement, including attributes, `NamedNodeMap`, `classList`), `AttrService`, `DOMTokenListService`,
13
- `NamedNodeMapService`, `PseudoNodeList`, and `generateDocument` for creating a document.
11
+ (Node: a real tree with `parentNode`, `previousSibling` / `nextSibling`, `firstChild` / `lastChild`, `appendChild`,
12
+ `insertBefore`, `removeChild`, `replaceChild`, `contains` and `getRootNode`; nodes move when they are added somewhere
13
+ else, document fragments insert their children, and a node cannot be put inside itself), `ElementService` /
14
+ `HTMLElementService` (Element and HTMLElement, including attributes, `NamedNodeMap`, `classList`), `AttrService`,
15
+ `DOMTokenListService`, `NamedNodeMapService`, `DocumentService` / `DocumentFragmentService`, `PseudoNodeList`, and
16
+ `generateDocument` for creating a document.
14
17
 
15
18
  Not implemented yet (these throw a "not implemented" error or are missing): event dispatch through the tree (capture,
16
- target and bubble phases), `cloneNode`, `compareDocumentPosition`, `contains`, `insertBefore`, `isEqualNode`,
17
- `replaceChild`, `querySelector` / `querySelectorAll`, `innerHTML` / `outerHTML` parsing, and most of the rest of the
18
- Element and Document APIs. The API will change before 1.0.
19
+ target and bubble phases), `cloneNode`, `compareDocumentPosition`, `isEqualNode`, `querySelector` /
20
+ `querySelectorAll`, `innerHTML` / `outerHTML` parsing, and most of the rest of the Element and Document APIs. The API
21
+ will change before 1.0.
19
22
  ## Modules
20
23
 
21
24
  <dl>
@@ -45,6 +48,13 @@ Element and Document APIs. The API will change before 1.0.
45
48
  <dt><a href="#ElementService">ElementService</a> ⇐ <code>PseudoNode</code></dt>
46
49
  <dd><p>Simulate the behaviour of the Element Class when there is no DOM available.</p>
47
50
  </dd>
51
+ <dt><a href="#DocumentService">DocumentService</a> ⇐ <code><a href="#NodeService">NodeService</a></code></dt>
52
+ <dd><p>Simulate the behaviour of the Document Class when there is no DOM available.</p>
53
+ </dd>
54
+ <dt><a href="#DocumentFragmentService">DocumentFragmentService</a> ⇐ <code><a href="#NodeService">NodeService</a></code></dt>
55
+ <dd><p>Simulate the behaviour of the DocumentFragment Class when there is no DOM available: a container for nodes which is
56
+ not part of a tree, when it is inserted its children are moved into the tree instead.</p>
57
+ </dd>
48
58
  <dt><a href="#DOMTokenListService">DOMTokenListService</a></dt>
49
59
  <dd><p>Simulate the behaviour of the DOMTokenList Class when there is no DOM available.</p>
50
60
  </dd>
@@ -52,7 +62,8 @@ Element and Document APIs. The API will change before 1.0.
52
62
  <dd><p>Simulate the behaviour of the Attr Class when there is no DOM available.</p>
53
63
  </dd>
54
64
  <dt><a href="#LinkedNode">LinkedNode</a> ⇐ <code><a href="#NodeService">NodeService</a></code></dt>
55
- <dd><p>A node which is stored in a TreeLinker and answers questions about its position in the tree by asking that linker.</p>
65
+ <dd><p>A node which is stored in a TreeLinker (for example by a list built from an array of values). It finds its siblings
66
+ from that linker, and its parent from the linker&#39;s parent when it has not been given one by appendChild.</p>
56
67
  </dd>
57
68
  <dt><a href="#PseudoNodeList">PseudoNodeList</a> ⇐ <code>LinkedTreeList</code></dt>
58
69
  <dd><p>A NodeList, like the DOM one, iterates over the nodes themselves (the data stored in each TreeLinker), rather than
@@ -76,6 +87,15 @@ the linkers that hold them.</p>
76
87
  ## Functions
77
88
 
78
89
  <dl>
90
+ <dt><a href="#getParentNodesFromAttribute">getParentNodesFromAttribute(attr, value, node)</a> ⇒ <code>Array.&lt;PseudoNode&gt;</code></dt>
91
+ <dd><p>A selector function for retrieving existing parent PseudoNode from the given child item.
92
+ This function will check all the parents starting from node, and scan the attributes
93
+ property for matches. The return array contains all matching parent ancestors, starting with the root of the tree.</p>
94
+ </dd>
95
+ <dt><a href="#getParentNodes">getParentNodes(node)</a> ⇒ <code>Array.&lt;PseudoNode&gt;</code></dt>
96
+ <dd><p>Get all of the ancestors of a node, starting with the root of the tree and ending with the node&#39;s own parent (the
97
+ order in which an event travels down through them). A node which has no parent has no ancestors.</p>
98
+ </dd>
79
99
  <dt><a href="#generateNodeList">generateNodeList([innerList])</a> ⇒ <code><a href="#PseudoNodeList">PseudoNodeList</a></code></dt>
80
100
  <dd><p>Create a PseudoNodeList, optionally starting from an existing chain of linkers.</p>
81
101
  </dd>
@@ -114,22 +134,38 @@ Simulate the behaviour of the Node Class when there is no DOM available.
114
134
 
115
135
  * [NodeService](#NodeService) ⇐ <code>PseudoEventTarget</code>
116
136
  * [.appendChild(childNode)](#NodeService+appendChild) ⇒ <code>PseudoNode</code>
137
+ * [.childInserted(child)](#NodeService+childInserted)
117
138
  * [.cloneNode()](#NodeService+cloneNode)
118
139
  * [.compareDocumentPosition()](#NodeService+compareDocumentPosition)
119
- * [.contains()](#NodeService+contains)
120
- * [.insertBefore()](#NodeService+insertBefore)
140
+ * [.contains(otherNode)](#NodeService+contains) ⇒ <code>boolean</code>
141
+ * [.insertBefore(newNode, [referenceNode])](#NodeService+insertBefore) ⇒ <code>PseudoNode</code>
121
142
  * [.isEqualNode()](#NodeService+isEqualNode)
122
143
  * [.removeChild(childElement)](#NodeService+removeChild) ⇒ <code>PseudoNode</code>
123
- * [.replaceChild()](#NodeService+replaceChild)
144
+ * [.replaceChild(newChild, oldChild)](#NodeService+replaceChild) ⇒ <code>PseudoNode</code>
124
145
 
125
146
  <a name="NodeService+appendChild"></a>
126
147
 
127
148
  ### nodeService.appendChild(childNode) ⇒ <code>PseudoNode</code>
149
+ Add a node as the last child of this node (a node which is already in a tree is moved).
150
+
128
151
  **Kind**: instance method of [<code>NodeService</code>](#NodeService)
152
+ **Returns**: <code>PseudoNode</code> - The added node
129
153
 
130
- | Param | Type |
131
- | --- | --- |
132
- | childNode | <code>PseudoNode</code> |
154
+ | Param | Type | Description |
155
+ | --- | --- | --- |
156
+ | childNode | <code>PseudoNode</code> | The node to add |
157
+
158
+ <a name="NodeService+childInserted"></a>
159
+
160
+ ### nodeService.childInserted(child)
161
+ Called each time a node has been inserted as a child of this node, so that nodes which need to react to children
162
+ (for example elements applying default events) can do so.
163
+
164
+ **Kind**: instance method of [<code>NodeService</code>](#NodeService)
165
+
166
+ | Param | Type | Description |
167
+ | --- | --- | --- |
168
+ | child | [<code>NodeService</code>](#NodeService) | The node which was inserted |
133
169
 
134
170
  <a name="NodeService+cloneNode"></a>
135
171
 
@@ -153,23 +189,32 @@ Not implemented yet.
153
189
 
154
190
  <a name="NodeService+contains"></a>
155
191
 
156
- ### nodeService.contains()
157
- Not implemented yet.
192
+ ### nodeService.contains(otherNode) ⇒ <code>boolean</code>
193
+ Check whether a node is this node or one of its descendants.
158
194
 
159
195
  **Kind**: instance method of [<code>NodeService</code>](#NodeService)
160
- **Throws**:
161
196
 
162
- - <code>Error</code>
197
+ | Param | Type | Description |
198
+ | --- | --- | --- |
199
+ | otherNode | <code>PseudoNode</code> \| <code>null</code> | The node to look for |
163
200
 
164
201
  <a name="NodeService+insertBefore"></a>
165
202
 
166
- ### nodeService.insertBefore()
167
- Not implemented yet.
203
+ ### nodeService.insertBefore(newNode, [referenceNode]) ⇒ <code>PseudoNode</code>
204
+ Insert a node as a child of this node, before the given child (or at the end when there is none). A node which is
205
+ already in a tree is moved, and the children of a document fragment are moved in order.
168
206
 
169
207
  **Kind**: instance method of [<code>NodeService</code>](#NodeService)
208
+ **Returns**: <code>PseudoNode</code> - The inserted node
170
209
  **Throws**:
171
210
 
172
- - <code>Error</code>
211
+ - <code>Error</code> When the reference node is not a child of this node, or the new node is this node or contains it
212
+
213
+
214
+ | Param | Type | Default | Description |
215
+ | --- | --- | --- | --- |
216
+ | newNode | <code>PseudoNode</code> | | The node to insert |
217
+ | [referenceNode] | <code>PseudoNode</code> \| <code>null</code> | <code></code> | The child of this node to insert before, or null to insert at the end |
173
218
 
174
219
  <a name="NodeService+isEqualNode"></a>
175
220
 
@@ -184,9 +229,10 @@ Not implemented yet.
184
229
  <a name="NodeService+removeChild"></a>
185
230
 
186
231
  ### nodeService.removeChild(childElement) ⇒ <code>PseudoNode</code>
187
- Remove the given child from this node.
232
+ Remove a child from this node, it no longer has a parent or siblings afterwards.
188
233
 
189
234
  **Kind**: instance method of [<code>NodeService</code>](#NodeService)
235
+ **Returns**: <code>PseudoNode</code> - The removed node
190
236
  **Throws**:
191
237
 
192
238
  - <code>Error</code> When the node is not a child of this node
@@ -194,17 +240,24 @@ Remove the given child from this node.
194
240
 
195
241
  | Param | Type | Description |
196
242
  | --- | --- | --- |
197
- | childElement | <code>PseudoNode</code> | The child node, or its TreeLinker from the children list |
243
+ | childElement | <code>PseudoNode</code> | The child node to remove |
198
244
 
199
245
  <a name="NodeService+replaceChild"></a>
200
246
 
201
- ### nodeService.replaceChild()
202
- Not implemented yet.
247
+ ### nodeService.replaceChild(newChild, oldChild) ⇒ <code>PseudoNode</code>
248
+ Replace a child of this node with another node (which is moved if it is already in a tree).
203
249
 
204
250
  **Kind**: instance method of [<code>NodeService</code>](#NodeService)
251
+ **Returns**: <code>PseudoNode</code> - The replaced node
205
252
  **Throws**:
206
253
 
207
- - <code>Error</code>
254
+ - <code>Error</code> When the old node is not a child of this node
255
+
256
+
257
+ | Param | Type | Description |
258
+ | --- | --- | --- |
259
+ | newChild | <code>PseudoNode</code> | The node which takes the place |
260
+ | oldChild | <code>PseudoNode</code> | The child of this node to replace |
208
261
 
209
262
  <a name="NamedNodeMapService"></a>
210
263
 
@@ -421,7 +474,7 @@ Simulate the behaviour of the Element Class when there is no DOM available.
421
474
  * [ElementService](#ElementService) ⇐ <code>PseudoNode</code>
422
475
  * [new ElementService([settings])](#new_ElementService_new)
423
476
  * [.applyDefaultEvent()](#ElementService+applyDefaultEvent) ⇒ <code>function</code>
424
- * [.appendChild(childElement)](#ElementService+appendChild) ⇒ <code>PseudoNode</code>
477
+ * [.childInserted(child)](#ElementService+childInserted)
425
478
  * [.hasAttribute(attributeName)](#ElementService+hasAttribute) ⇒ <code>boolean</code>
426
479
  * [.setAttribute(attributeName, attributeValue)](#ElementService+setAttribute) ⇒ <code>undefined</code>
427
480
  * [.getAttribute(attributeName)](#ElementService+getAttribute) ⇒ <code>string</code> \| <code>null</code>
@@ -436,8 +489,8 @@ Simulate the behaviour of the Element Class when there is no DOM available.
436
489
  | [settings] | <code>Object</code> | <code>{}</code> | |
437
490
  | [settings.tagName] | <code>string</code> | <code>&quot;&#x27;&#x27;&quot;</code> | The name of the tag this element represents |
438
491
  | [settings.attributes] | <code>Array.&lt;{name: string, value: \*}&gt;</code> | <code>[]</code> | The attributes (also assigned as properties) to start with |
439
- | [settings.parent] | <code>PseudoNode</code> \| <code>null</code> | <code></code> | The parent node |
440
- | [settings.children] | <code>Array</code> | <code>[]</code> | The values or nodes to start as children |
492
+ | [settings.parent] | <code>PseudoNode</code> \| <code>null</code> | <code></code> | The node to add this element to as its last child |
493
+ | [settings.children] | <code>Array.&lt;PseudoNode&gt;</code> | <code>[]</code> | The nodes to start as children |
441
494
 
442
495
  <a name="ElementService+applyDefaultEvent"></a>
443
496
 
@@ -445,14 +498,16 @@ Simulate the behaviour of the Element Class when there is no DOM available.
445
498
  Some elements have default behaviour, this registers it when the element is added.
446
499
 
447
500
  **Kind**: instance method of [<code>ElementService</code>](#ElementService)
448
- <a name="ElementService+appendChild"></a>
501
+ <a name="ElementService+childInserted"></a>
502
+
503
+ ### elementService.childInserted(child)
504
+ An element which is added as a child gets its default events (for example a submit button submits its form).
449
505
 
450
- ### elementService.appendChild(childElement) ⇒ <code>PseudoNode</code>
451
506
  **Kind**: instance method of [<code>ElementService</code>](#ElementService)
452
507
 
453
- | Param | Type |
454
- | --- | --- |
455
- | childElement | <code>PseudoNode</code> \| [<code>ElementService</code>](#ElementService) |
508
+ | Param | Type | Description |
509
+ | --- | --- | --- |
510
+ | child | [<code>NodeService</code>](#NodeService) | The node which was inserted |
456
511
 
457
512
  <a name="ElementService+hasAttribute"></a>
458
513
 
@@ -500,6 +555,279 @@ Remove an attribute from the element.
500
555
  | --- | --- |
501
556
  | attributeName | <code>string</code> |
502
557
 
558
+ <a name="DocumentService"></a>
559
+
560
+ ## DocumentService ⇐ [<code>NodeService</code>](#NodeService)
561
+ Simulate the behaviour of the Document Class when there is no DOM available.
562
+
563
+ **Kind**: global class
564
+ **Extends**: [<code>NodeService</code>](#NodeService)
565
+ **Author**: Joshua Heagle <joshuaheagle@gmail.com>
566
+
567
+ * [DocumentService](#DocumentService) ⇐ [<code>NodeService</code>](#NodeService)
568
+ * [.appendChild(childNode)](#NodeService+appendChild) ⇒ <code>PseudoNode</code>
569
+ * [.childInserted(child)](#NodeService+childInserted)
570
+ * [.cloneNode()](#NodeService+cloneNode)
571
+ * [.compareDocumentPosition()](#NodeService+compareDocumentPosition)
572
+ * [.contains(otherNode)](#NodeService+contains) ⇒ <code>boolean</code>
573
+ * [.insertBefore(newNode, [referenceNode])](#NodeService+insertBefore) ⇒ <code>PseudoNode</code>
574
+ * [.isEqualNode()](#NodeService+isEqualNode)
575
+ * [.removeChild(childElement)](#NodeService+removeChild) ⇒ <code>PseudoNode</code>
576
+ * [.replaceChild(newChild, oldChild)](#NodeService+replaceChild) ⇒ <code>PseudoNode</code>
577
+
578
+ <a name="NodeService+appendChild"></a>
579
+
580
+ ### documentService.appendChild(childNode) ⇒ <code>PseudoNode</code>
581
+ Add a node as the last child of this node (a node which is already in a tree is moved).
582
+
583
+ **Kind**: instance method of [<code>DocumentService</code>](#DocumentService)
584
+ **Returns**: <code>PseudoNode</code> - The added node
585
+
586
+ | Param | Type | Description |
587
+ | --- | --- | --- |
588
+ | childNode | <code>PseudoNode</code> | The node to add |
589
+
590
+ <a name="NodeService+childInserted"></a>
591
+
592
+ ### documentService.childInserted(child)
593
+ Called each time a node has been inserted as a child of this node, so that nodes which need to react to children
594
+ (for example elements applying default events) can do so.
595
+
596
+ **Kind**: instance method of [<code>DocumentService</code>](#DocumentService)
597
+
598
+ | Param | Type | Description |
599
+ | --- | --- | --- |
600
+ | child | [<code>NodeService</code>](#NodeService) | The node which was inserted |
601
+
602
+ <a name="NodeService+cloneNode"></a>
603
+
604
+ ### documentService.cloneNode()
605
+ Not implemented yet.
606
+
607
+ **Kind**: instance method of [<code>DocumentService</code>](#DocumentService)
608
+ **Throws**:
609
+
610
+ - <code>Error</code>
611
+
612
+ <a name="NodeService+compareDocumentPosition"></a>
613
+
614
+ ### documentService.compareDocumentPosition()
615
+ Not implemented yet.
616
+
617
+ **Kind**: instance method of [<code>DocumentService</code>](#DocumentService)
618
+ **Throws**:
619
+
620
+ - <code>Error</code>
621
+
622
+ <a name="NodeService+contains"></a>
623
+
624
+ ### documentService.contains(otherNode) ⇒ <code>boolean</code>
625
+ Check whether a node is this node or one of its descendants.
626
+
627
+ **Kind**: instance method of [<code>DocumentService</code>](#DocumentService)
628
+
629
+ | Param | Type | Description |
630
+ | --- | --- | --- |
631
+ | otherNode | <code>PseudoNode</code> \| <code>null</code> | The node to look for |
632
+
633
+ <a name="NodeService+insertBefore"></a>
634
+
635
+ ### documentService.insertBefore(newNode, [referenceNode]) ⇒ <code>PseudoNode</code>
636
+ Insert a node as a child of this node, before the given child (or at the end when there is none). A node which is
637
+ already in a tree is moved, and the children of a document fragment are moved in order.
638
+
639
+ **Kind**: instance method of [<code>DocumentService</code>](#DocumentService)
640
+ **Returns**: <code>PseudoNode</code> - The inserted node
641
+ **Throws**:
642
+
643
+ - <code>Error</code> When the reference node is not a child of this node, or the new node is this node or contains it
644
+
645
+
646
+ | Param | Type | Default | Description |
647
+ | --- | --- | --- | --- |
648
+ | newNode | <code>PseudoNode</code> | | The node to insert |
649
+ | [referenceNode] | <code>PseudoNode</code> \| <code>null</code> | <code></code> | The child of this node to insert before, or null to insert at the end |
650
+
651
+ <a name="NodeService+isEqualNode"></a>
652
+
653
+ ### documentService.isEqualNode()
654
+ Not implemented yet.
655
+
656
+ **Kind**: instance method of [<code>DocumentService</code>](#DocumentService)
657
+ **Throws**:
658
+
659
+ - <code>Error</code>
660
+
661
+ <a name="NodeService+removeChild"></a>
662
+
663
+ ### documentService.removeChild(childElement) ⇒ <code>PseudoNode</code>
664
+ Remove a child from this node, it no longer has a parent or siblings afterwards.
665
+
666
+ **Kind**: instance method of [<code>DocumentService</code>](#DocumentService)
667
+ **Returns**: <code>PseudoNode</code> - The removed node
668
+ **Throws**:
669
+
670
+ - <code>Error</code> When the node is not a child of this node
671
+
672
+
673
+ | Param | Type | Description |
674
+ | --- | --- | --- |
675
+ | childElement | <code>PseudoNode</code> | The child node to remove |
676
+
677
+ <a name="NodeService+replaceChild"></a>
678
+
679
+ ### documentService.replaceChild(newChild, oldChild) ⇒ <code>PseudoNode</code>
680
+ Replace a child of this node with another node (which is moved if it is already in a tree).
681
+
682
+ **Kind**: instance method of [<code>DocumentService</code>](#DocumentService)
683
+ **Returns**: <code>PseudoNode</code> - The replaced node
684
+ **Throws**:
685
+
686
+ - <code>Error</code> When the old node is not a child of this node
687
+
688
+
689
+ | Param | Type | Description |
690
+ | --- | --- | --- |
691
+ | newChild | <code>PseudoNode</code> | The node which takes the place |
692
+ | oldChild | <code>PseudoNode</code> | The child of this node to replace |
693
+
694
+ <a name="DocumentFragmentService"></a>
695
+
696
+ ## DocumentFragmentService ⇐ [<code>NodeService</code>](#NodeService)
697
+ Simulate the behaviour of the DocumentFragment Class when there is no DOM available: a container for nodes which is
698
+ not part of a tree, when it is inserted its children are moved into the tree instead.
699
+
700
+ **Kind**: global class
701
+ **Extends**: [<code>NodeService</code>](#NodeService)
702
+ **Author**: Joshua Heagle <joshuaheagle@gmail.com>
703
+
704
+ * [DocumentFragmentService](#DocumentFragmentService) ⇐ [<code>NodeService</code>](#NodeService)
705
+ * [.appendChild(childNode)](#NodeService+appendChild) ⇒ <code>PseudoNode</code>
706
+ * [.childInserted(child)](#NodeService+childInserted)
707
+ * [.cloneNode()](#NodeService+cloneNode)
708
+ * [.compareDocumentPosition()](#NodeService+compareDocumentPosition)
709
+ * [.contains(otherNode)](#NodeService+contains) ⇒ <code>boolean</code>
710
+ * [.insertBefore(newNode, [referenceNode])](#NodeService+insertBefore) ⇒ <code>PseudoNode</code>
711
+ * [.isEqualNode()](#NodeService+isEqualNode)
712
+ * [.removeChild(childElement)](#NodeService+removeChild) ⇒ <code>PseudoNode</code>
713
+ * [.replaceChild(newChild, oldChild)](#NodeService+replaceChild) ⇒ <code>PseudoNode</code>
714
+
715
+ <a name="NodeService+appendChild"></a>
716
+
717
+ ### documentFragmentService.appendChild(childNode) ⇒ <code>PseudoNode</code>
718
+ Add a node as the last child of this node (a node which is already in a tree is moved).
719
+
720
+ **Kind**: instance method of [<code>DocumentFragmentService</code>](#DocumentFragmentService)
721
+ **Returns**: <code>PseudoNode</code> - The added node
722
+
723
+ | Param | Type | Description |
724
+ | --- | --- | --- |
725
+ | childNode | <code>PseudoNode</code> | The node to add |
726
+
727
+ <a name="NodeService+childInserted"></a>
728
+
729
+ ### documentFragmentService.childInserted(child)
730
+ Called each time a node has been inserted as a child of this node, so that nodes which need to react to children
731
+ (for example elements applying default events) can do so.
732
+
733
+ **Kind**: instance method of [<code>DocumentFragmentService</code>](#DocumentFragmentService)
734
+
735
+ | Param | Type | Description |
736
+ | --- | --- | --- |
737
+ | child | [<code>NodeService</code>](#NodeService) | The node which was inserted |
738
+
739
+ <a name="NodeService+cloneNode"></a>
740
+
741
+ ### documentFragmentService.cloneNode()
742
+ Not implemented yet.
743
+
744
+ **Kind**: instance method of [<code>DocumentFragmentService</code>](#DocumentFragmentService)
745
+ **Throws**:
746
+
747
+ - <code>Error</code>
748
+
749
+ <a name="NodeService+compareDocumentPosition"></a>
750
+
751
+ ### documentFragmentService.compareDocumentPosition()
752
+ Not implemented yet.
753
+
754
+ **Kind**: instance method of [<code>DocumentFragmentService</code>](#DocumentFragmentService)
755
+ **Throws**:
756
+
757
+ - <code>Error</code>
758
+
759
+ <a name="NodeService+contains"></a>
760
+
761
+ ### documentFragmentService.contains(otherNode) ⇒ <code>boolean</code>
762
+ Check whether a node is this node or one of its descendants.
763
+
764
+ **Kind**: instance method of [<code>DocumentFragmentService</code>](#DocumentFragmentService)
765
+
766
+ | Param | Type | Description |
767
+ | --- | --- | --- |
768
+ | otherNode | <code>PseudoNode</code> \| <code>null</code> | The node to look for |
769
+
770
+ <a name="NodeService+insertBefore"></a>
771
+
772
+ ### documentFragmentService.insertBefore(newNode, [referenceNode]) ⇒ <code>PseudoNode</code>
773
+ Insert a node as a child of this node, before the given child (or at the end when there is none). A node which is
774
+ already in a tree is moved, and the children of a document fragment are moved in order.
775
+
776
+ **Kind**: instance method of [<code>DocumentFragmentService</code>](#DocumentFragmentService)
777
+ **Returns**: <code>PseudoNode</code> - The inserted node
778
+ **Throws**:
779
+
780
+ - <code>Error</code> When the reference node is not a child of this node, or the new node is this node or contains it
781
+
782
+
783
+ | Param | Type | Default | Description |
784
+ | --- | --- | --- | --- |
785
+ | newNode | <code>PseudoNode</code> | | The node to insert |
786
+ | [referenceNode] | <code>PseudoNode</code> \| <code>null</code> | <code></code> | The child of this node to insert before, or null to insert at the end |
787
+
788
+ <a name="NodeService+isEqualNode"></a>
789
+
790
+ ### documentFragmentService.isEqualNode()
791
+ Not implemented yet.
792
+
793
+ **Kind**: instance method of [<code>DocumentFragmentService</code>](#DocumentFragmentService)
794
+ **Throws**:
795
+
796
+ - <code>Error</code>
797
+
798
+ <a name="NodeService+removeChild"></a>
799
+
800
+ ### documentFragmentService.removeChild(childElement) ⇒ <code>PseudoNode</code>
801
+ Remove a child from this node, it no longer has a parent or siblings afterwards.
802
+
803
+ **Kind**: instance method of [<code>DocumentFragmentService</code>](#DocumentFragmentService)
804
+ **Returns**: <code>PseudoNode</code> - The removed node
805
+ **Throws**:
806
+
807
+ - <code>Error</code> When the node is not a child of this node
808
+
809
+
810
+ | Param | Type | Description |
811
+ | --- | --- | --- |
812
+ | childElement | <code>PseudoNode</code> | The child node to remove |
813
+
814
+ <a name="NodeService+replaceChild"></a>
815
+
816
+ ### documentFragmentService.replaceChild(newChild, oldChild) ⇒ <code>PseudoNode</code>
817
+ Replace a child of this node with another node (which is moved if it is already in a tree).
818
+
819
+ **Kind**: instance method of [<code>DocumentFragmentService</code>](#DocumentFragmentService)
820
+ **Returns**: <code>PseudoNode</code> - The replaced node
821
+ **Throws**:
822
+
823
+ - <code>Error</code> When the old node is not a child of this node
824
+
825
+
826
+ | Param | Type | Description |
827
+ | --- | --- | --- |
828
+ | newChild | <code>PseudoNode</code> | The node which takes the place |
829
+ | oldChild | <code>PseudoNode</code> | The child of this node to replace |
830
+
503
831
  <a name="DOMTokenListService"></a>
504
832
 
505
833
  ## DOMTokenListService
@@ -528,13 +856,14 @@ Simulate the behaviour of the Attr Class when there is no DOM available.
528
856
  * [AttrService](#AttrService) ⇐ [<code>NodeService</code>](#NodeService)
529
857
  * [new AttrService(name, [value], [ownerElement], [namespaceURI], [prefix])](#new_AttrService_new)
530
858
  * [.appendChild(childNode)](#NodeService+appendChild) ⇒ <code>PseudoNode</code>
859
+ * [.childInserted(child)](#NodeService+childInserted)
531
860
  * [.cloneNode()](#NodeService+cloneNode)
532
861
  * [.compareDocumentPosition()](#NodeService+compareDocumentPosition)
533
- * [.contains()](#NodeService+contains)
534
- * [.insertBefore()](#NodeService+insertBefore)
862
+ * [.contains(otherNode)](#NodeService+contains) ⇒ <code>boolean</code>
863
+ * [.insertBefore(newNode, [referenceNode])](#NodeService+insertBefore) ⇒ <code>PseudoNode</code>
535
864
  * [.isEqualNode()](#NodeService+isEqualNode)
536
865
  * [.removeChild(childElement)](#NodeService+removeChild) ⇒ <code>PseudoNode</code>
537
- * [.replaceChild()](#NodeService+replaceChild)
866
+ * [.replaceChild(newChild, oldChild)](#NodeService+replaceChild) ⇒ <code>PseudoNode</code>
538
867
 
539
868
  <a name="new_AttrService_new"></a>
540
869
 
@@ -551,12 +880,28 @@ Simulate the behaviour of the Attr Class when there is no DOM available.
551
880
  <a name="NodeService+appendChild"></a>
552
881
 
553
882
  ### attrService.appendChild(childNode) ⇒ <code>PseudoNode</code>
883
+ Add a node as the last child of this node (a node which is already in a tree is moved).
884
+
554
885
  **Kind**: instance method of [<code>AttrService</code>](#AttrService)
555
886
  **Overrides**: [<code>appendChild</code>](#NodeService+appendChild)
887
+ **Returns**: <code>PseudoNode</code> - The added node
556
888
 
557
- | Param | Type |
558
- | --- | --- |
559
- | childNode | <code>PseudoNode</code> |
889
+ | Param | Type | Description |
890
+ | --- | --- | --- |
891
+ | childNode | <code>PseudoNode</code> | The node to add |
892
+
893
+ <a name="NodeService+childInserted"></a>
894
+
895
+ ### attrService.childInserted(child)
896
+ Called each time a node has been inserted as a child of this node, so that nodes which need to react to children
897
+ (for example elements applying default events) can do so.
898
+
899
+ **Kind**: instance method of [<code>AttrService</code>](#AttrService)
900
+ **Overrides**: [<code>childInserted</code>](#NodeService+childInserted)
901
+
902
+ | Param | Type | Description |
903
+ | --- | --- | --- |
904
+ | child | [<code>NodeService</code>](#NodeService) | The node which was inserted |
560
905
 
561
906
  <a name="NodeService+cloneNode"></a>
562
907
 
@@ -582,25 +927,34 @@ Not implemented yet.
582
927
 
583
928
  <a name="NodeService+contains"></a>
584
929
 
585
- ### attrService.contains()
586
- Not implemented yet.
930
+ ### attrService.contains(otherNode) ⇒ <code>boolean</code>
931
+ Check whether a node is this node or one of its descendants.
587
932
 
588
933
  **Kind**: instance method of [<code>AttrService</code>](#AttrService)
589
934
  **Overrides**: [<code>contains</code>](#NodeService+contains)
590
- **Throws**:
591
935
 
592
- - <code>Error</code>
936
+ | Param | Type | Description |
937
+ | --- | --- | --- |
938
+ | otherNode | <code>PseudoNode</code> \| <code>null</code> | The node to look for |
593
939
 
594
940
  <a name="NodeService+insertBefore"></a>
595
941
 
596
- ### attrService.insertBefore()
597
- Not implemented yet.
942
+ ### attrService.insertBefore(newNode, [referenceNode]) ⇒ <code>PseudoNode</code>
943
+ Insert a node as a child of this node, before the given child (or at the end when there is none). A node which is
944
+ already in a tree is moved, and the children of a document fragment are moved in order.
598
945
 
599
946
  **Kind**: instance method of [<code>AttrService</code>](#AttrService)
600
947
  **Overrides**: [<code>insertBefore</code>](#NodeService+insertBefore)
948
+ **Returns**: <code>PseudoNode</code> - The inserted node
601
949
  **Throws**:
602
950
 
603
- - <code>Error</code>
951
+ - <code>Error</code> When the reference node is not a child of this node, or the new node is this node or contains it
952
+
953
+
954
+ | Param | Type | Default | Description |
955
+ | --- | --- | --- | --- |
956
+ | newNode | <code>PseudoNode</code> | | The node to insert |
957
+ | [referenceNode] | <code>PseudoNode</code> \| <code>null</code> | <code></code> | The child of this node to insert before, or null to insert at the end |
604
958
 
605
959
  <a name="NodeService+isEqualNode"></a>
606
960
 
@@ -616,10 +970,11 @@ Not implemented yet.
616
970
  <a name="NodeService+removeChild"></a>
617
971
 
618
972
  ### attrService.removeChild(childElement) ⇒ <code>PseudoNode</code>
619
- Remove the given child from this node.
973
+ Remove a child from this node, it no longer has a parent or siblings afterwards.
620
974
 
621
975
  **Kind**: instance method of [<code>AttrService</code>](#AttrService)
622
976
  **Overrides**: [<code>removeChild</code>](#NodeService+removeChild)
977
+ **Returns**: <code>PseudoNode</code> - The removed node
623
978
  **Throws**:
624
979
 
625
980
  - <code>Error</code> When the node is not a child of this node
@@ -627,23 +982,31 @@ Remove the given child from this node.
627
982
 
628
983
  | Param | Type | Description |
629
984
  | --- | --- | --- |
630
- | childElement | <code>PseudoNode</code> | The child node, or its TreeLinker from the children list |
985
+ | childElement | <code>PseudoNode</code> | The child node to remove |
631
986
 
632
987
  <a name="NodeService+replaceChild"></a>
633
988
 
634
- ### attrService.replaceChild()
635
- Not implemented yet.
989
+ ### attrService.replaceChild(newChild, oldChild) ⇒ <code>PseudoNode</code>
990
+ Replace a child of this node with another node (which is moved if it is already in a tree).
636
991
 
637
992
  **Kind**: instance method of [<code>AttrService</code>](#AttrService)
638
993
  **Overrides**: [<code>replaceChild</code>](#NodeService+replaceChild)
994
+ **Returns**: <code>PseudoNode</code> - The replaced node
639
995
  **Throws**:
640
996
 
641
- - <code>Error</code>
997
+ - <code>Error</code> When the old node is not a child of this node
998
+
999
+
1000
+ | Param | Type | Description |
1001
+ | --- | --- | --- |
1002
+ | newChild | <code>PseudoNode</code> | The node which takes the place |
1003
+ | oldChild | <code>PseudoNode</code> | The child of this node to replace |
642
1004
 
643
1005
  <a name="LinkedNode"></a>
644
1006
 
645
1007
  ## LinkedNode ⇐ [<code>NodeService</code>](#NodeService)
646
- A node which is stored in a TreeLinker and answers questions about its position in the tree by asking that linker.
1008
+ A node which is stored in a TreeLinker (for example by a list built from an array of values). It finds its siblings
1009
+ from that linker, and its parent from the linker's parent when it has not been given one by appendChild.
647
1010
 
648
1011
  **Kind**: global class
649
1012
  **Extends**: [<code>NodeService</code>](#NodeService)
@@ -652,13 +1015,14 @@ A node which is stored in a TreeLinker and answers questions about its position
652
1015
  * [LinkedNode](#LinkedNode) ⇐ [<code>NodeService</code>](#NodeService)
653
1016
  * [new LinkedNode(linker, value)](#new_LinkedNode_new)
654
1017
  * [.appendChild(childNode)](#NodeService+appendChild) ⇒ <code>PseudoNode</code>
1018
+ * [.childInserted(child)](#NodeService+childInserted)
655
1019
  * [.cloneNode()](#NodeService+cloneNode)
656
1020
  * [.compareDocumentPosition()](#NodeService+compareDocumentPosition)
657
- * [.contains()](#NodeService+contains)
658
- * [.insertBefore()](#NodeService+insertBefore)
1021
+ * [.contains(otherNode)](#NodeService+contains) ⇒ <code>boolean</code>
1022
+ * [.insertBefore(newNode, [referenceNode])](#NodeService+insertBefore) ⇒ <code>PseudoNode</code>
659
1023
  * [.isEqualNode()](#NodeService+isEqualNode)
660
1024
  * [.removeChild(childElement)](#NodeService+removeChild) ⇒ <code>PseudoNode</code>
661
- * [.replaceChild()](#NodeService+replaceChild)
1025
+ * [.replaceChild(newChild, oldChild)](#NodeService+replaceChild) ⇒ <code>PseudoNode</code>
662
1026
 
663
1027
  <a name="new_LinkedNode_new"></a>
664
1028
 
@@ -672,12 +1036,28 @@ A node which is stored in a TreeLinker and answers questions about its position
672
1036
  <a name="NodeService+appendChild"></a>
673
1037
 
674
1038
  ### linkedNode.appendChild(childNode) ⇒ <code>PseudoNode</code>
1039
+ Add a node as the last child of this node (a node which is already in a tree is moved).
1040
+
675
1041
  **Kind**: instance method of [<code>LinkedNode</code>](#LinkedNode)
676
1042
  **Overrides**: [<code>appendChild</code>](#NodeService+appendChild)
1043
+ **Returns**: <code>PseudoNode</code> - The added node
677
1044
 
678
- | Param | Type |
679
- | --- | --- |
680
- | childNode | <code>PseudoNode</code> |
1045
+ | Param | Type | Description |
1046
+ | --- | --- | --- |
1047
+ | childNode | <code>PseudoNode</code> | The node to add |
1048
+
1049
+ <a name="NodeService+childInserted"></a>
1050
+
1051
+ ### linkedNode.childInserted(child)
1052
+ Called each time a node has been inserted as a child of this node, so that nodes which need to react to children
1053
+ (for example elements applying default events) can do so.
1054
+
1055
+ **Kind**: instance method of [<code>LinkedNode</code>](#LinkedNode)
1056
+ **Overrides**: [<code>childInserted</code>](#NodeService+childInserted)
1057
+
1058
+ | Param | Type | Description |
1059
+ | --- | --- | --- |
1060
+ | child | [<code>NodeService</code>](#NodeService) | The node which was inserted |
681
1061
 
682
1062
  <a name="NodeService+cloneNode"></a>
683
1063
 
@@ -703,25 +1083,34 @@ Not implemented yet.
703
1083
 
704
1084
  <a name="NodeService+contains"></a>
705
1085
 
706
- ### linkedNode.contains()
707
- Not implemented yet.
1086
+ ### linkedNode.contains(otherNode) ⇒ <code>boolean</code>
1087
+ Check whether a node is this node or one of its descendants.
708
1088
 
709
1089
  **Kind**: instance method of [<code>LinkedNode</code>](#LinkedNode)
710
1090
  **Overrides**: [<code>contains</code>](#NodeService+contains)
711
- **Throws**:
712
1091
 
713
- - <code>Error</code>
1092
+ | Param | Type | Description |
1093
+ | --- | --- | --- |
1094
+ | otherNode | <code>PseudoNode</code> \| <code>null</code> | The node to look for |
714
1095
 
715
1096
  <a name="NodeService+insertBefore"></a>
716
1097
 
717
- ### linkedNode.insertBefore()
718
- Not implemented yet.
1098
+ ### linkedNode.insertBefore(newNode, [referenceNode]) ⇒ <code>PseudoNode</code>
1099
+ Insert a node as a child of this node, before the given child (or at the end when there is none). A node which is
1100
+ already in a tree is moved, and the children of a document fragment are moved in order.
719
1101
 
720
1102
  **Kind**: instance method of [<code>LinkedNode</code>](#LinkedNode)
721
1103
  **Overrides**: [<code>insertBefore</code>](#NodeService+insertBefore)
1104
+ **Returns**: <code>PseudoNode</code> - The inserted node
722
1105
  **Throws**:
723
1106
 
724
- - <code>Error</code>
1107
+ - <code>Error</code> When the reference node is not a child of this node, or the new node is this node or contains it
1108
+
1109
+
1110
+ | Param | Type | Default | Description |
1111
+ | --- | --- | --- | --- |
1112
+ | newNode | <code>PseudoNode</code> | | The node to insert |
1113
+ | [referenceNode] | <code>PseudoNode</code> \| <code>null</code> | <code></code> | The child of this node to insert before, or null to insert at the end |
725
1114
 
726
1115
  <a name="NodeService+isEqualNode"></a>
727
1116
 
@@ -737,10 +1126,11 @@ Not implemented yet.
737
1126
  <a name="NodeService+removeChild"></a>
738
1127
 
739
1128
  ### linkedNode.removeChild(childElement) ⇒ <code>PseudoNode</code>
740
- Remove the given child from this node.
1129
+ Remove a child from this node, it no longer has a parent or siblings afterwards.
741
1130
 
742
1131
  **Kind**: instance method of [<code>LinkedNode</code>](#LinkedNode)
743
1132
  **Overrides**: [<code>removeChild</code>](#NodeService+removeChild)
1133
+ **Returns**: <code>PseudoNode</code> - The removed node
744
1134
  **Throws**:
745
1135
 
746
1136
  - <code>Error</code> When the node is not a child of this node
@@ -748,18 +1138,25 @@ Remove the given child from this node.
748
1138
 
749
1139
  | Param | Type | Description |
750
1140
  | --- | --- | --- |
751
- | childElement | <code>PseudoNode</code> | The child node, or its TreeLinker from the children list |
1141
+ | childElement | <code>PseudoNode</code> | The child node to remove |
752
1142
 
753
1143
  <a name="NodeService+replaceChild"></a>
754
1144
 
755
- ### linkedNode.replaceChild()
756
- Not implemented yet.
1145
+ ### linkedNode.replaceChild(newChild, oldChild) ⇒ <code>PseudoNode</code>
1146
+ Replace a child of this node with another node (which is moved if it is already in a tree).
757
1147
 
758
1148
  **Kind**: instance method of [<code>LinkedNode</code>](#LinkedNode)
759
1149
  **Overrides**: [<code>replaceChild</code>](#NodeService+replaceChild)
1150
+ **Returns**: <code>PseudoNode</code> - The replaced node
760
1151
  **Throws**:
761
1152
 
762
- - <code>Error</code>
1153
+ - <code>Error</code> When the old node is not a child of this node
1154
+
1155
+
1156
+ | Param | Type | Description |
1157
+ | --- | --- | --- |
1158
+ | newChild | <code>PseudoNode</code> | The node which takes the place |
1159
+ | oldChild | <code>PseudoNode</code> | The child of this node to replace |
763
1160
 
764
1161
  <a name="PseudoNodeList"></a>
765
1162
 
@@ -807,7 +1204,7 @@ Simulate the behaviour of the HTMLDocument Class when there is no DOM available.
807
1204
  | --- | --- | --- |
808
1205
  | head | <code>PseudoHTMLElement</code> | A reference to the Head child element |
809
1206
  | body | <code>PseudoHTMLElement</code> | A reference to the Body child element |
810
- | createElement | <code>function</code> | Generate a new PseudoHTMLElement with parent of document |
1207
+ | createElement | <code>function</code> | Generate a new PseudoHTMLElement (which is not in the document until it is appended) |
811
1208
 
812
1209
 
813
1210
  * [PseudoHTMLDocument](#PseudoHTMLDocument) ⇐ <code>PseudoHTMLElement</code>
@@ -836,7 +1233,7 @@ Create document body element
836
1233
  <a name="PseudoHTMLDocument+createElement"></a>
837
1234
 
838
1235
  ### pseudoHTMLDocument.createElement(tagName) ⇒ <code>PseudoHTMLElement</code>
839
- Create and return a PseudoHTMLElement
1236
+ Create and return a PseudoHTMLElement, which is not added to the document until it is appended somewhere
840
1237
 
841
1238
  **Kind**: instance method of [<code>PseudoHTMLDocument</code>](#PseudoHTMLDocument)
842
1239
 
@@ -963,6 +1360,33 @@ The function (or object with handleEvent) which was originally given when regist
963
1360
 
964
1361
  ## HTMLElementService\_1 : <code>PseudoHTMLElement</code>
965
1362
  **Kind**: global constant
1363
+ <a name="getParentNodesFromAttribute"></a>
1364
+
1365
+ ## getParentNodesFromAttribute(attr, value, node) ⇒ <code>Array.&lt;PseudoNode&gt;</code>
1366
+ A selector function for retrieving existing parent PseudoNode from the given child item.
1367
+ This function will check all the parents starting from node, and scan the attributes
1368
+ property for matches. The return array contains all matching parent ancestors, starting with the root of the tree.
1369
+
1370
+ **Kind**: global function
1371
+
1372
+ | Param | Type | Description |
1373
+ | --- | --- | --- |
1374
+ | attr | <code>string</code> | The property to compare on each ancestor (a missing property counts as false) |
1375
+ | value | <code>boolean</code> \| <code>number</code> \| <code>string</code> | The value the property must have |
1376
+ | node | <code>PseudoEventTarget</code> \| <code>PseudoNode</code> \| <code>\*</code> | The node to find the matching ancestors of |
1377
+
1378
+ <a name="getParentNodes"></a>
1379
+
1380
+ ## getParentNodes(node) ⇒ <code>Array.&lt;PseudoNode&gt;</code>
1381
+ Get all of the ancestors of a node, starting with the root of the tree and ending with the node's own parent (the
1382
+ order in which an event travels down through them). A node which has no parent has no ancestors.
1383
+
1384
+ **Kind**: global function
1385
+
1386
+ | Param | Type | Description |
1387
+ | --- | --- | --- |
1388
+ | node | <code>PseudoEventTarget</code> \| <code>PseudoNode</code> \| <code>\*</code> | The node to find the ancestors of |
1389
+
966
1390
  <a name="generateNodeList"></a>
967
1391
 
968
1392
  ## generateNodeList([innerList]) ⇒ [<code>PseudoNodeList</code>](#PseudoNodeList)