pseudo-dom 0.5.0 → 0.6.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.
- package/README.md +961 -4
- package/browser/pseudo-dom.js +3196 -21570
- package/browser/pseudo-dom.min.js +1 -1
- package/dist/interfaces/PseudoElement.d.ts +28 -17
- package/dist/interfaces/PseudoHTMLCollection.d.ts +22 -1
- package/dist/services/ElementService.d.ts +64 -1
- package/dist/services/ElementService.js +123 -0
- package/dist/services/ElementService.min.js +1 -1
- package/dist/services/HTMLCollectionService.d.ts +46 -0
- package/dist/services/HTMLCollectionService.js +68 -1
- package/dist/services/HTMLCollectionService.min.js +1 -1
- package/dist/services/NodeService.d.ts +49 -1
- package/dist/services/NodeService.js +103 -7
- package/dist/services/NodeService.min.js +1 -1
- package/package.json +3 -3
|
@@ -470,9 +470,10 @@ export interface PseudoElement extends PseudoNode {
|
|
|
470
470
|
*/
|
|
471
471
|
set ariaValueText(value: string);
|
|
472
472
|
/**
|
|
473
|
-
* Inserts a set of Node objects or strings in the children list of the Element's parent, just after the Element.
|
|
473
|
+
* Inserts a set of Node objects or strings in the children list of the Element's parent, just after the Element. Does
|
|
474
|
+
* nothing when the element has no parent.
|
|
474
475
|
*/
|
|
475
|
-
after(...nodes: PseudoNode
|
|
476
|
+
after(...nodes: Array<PseudoNode | string>): void;
|
|
476
477
|
/**
|
|
477
478
|
* A shortcut method to create and run an animation on an element. Returns the created Animation object instance.
|
|
478
479
|
*/
|
|
@@ -485,7 +486,7 @@ export interface PseudoElement extends PseudoNode {
|
|
|
485
486
|
/**
|
|
486
487
|
* Inserts a set of Node objects or strings after the last child of the element.
|
|
487
488
|
*/
|
|
488
|
-
append(...
|
|
489
|
+
append(...nodes: Array<PseudoNode | string>): void;
|
|
489
490
|
/**
|
|
490
491
|
* Attaches a shadow DOM tree to the specified element and returns a reference to its ShadowRoot.
|
|
491
492
|
*/
|
|
@@ -496,9 +497,10 @@ export interface PseudoElement extends PseudoNode {
|
|
|
496
497
|
slotAssignment: string;
|
|
497
498
|
}): PseudoShadowRoot;
|
|
498
499
|
/**
|
|
499
|
-
* Inserts a set of Node objects or strings in the children list of the Element's parent, just before the Element.
|
|
500
|
+
* Inserts a set of Node objects or strings in the children list of the Element's parent, just before the Element. Does
|
|
501
|
+
* nothing when the element has no parent.
|
|
500
502
|
*/
|
|
501
|
-
before(...
|
|
503
|
+
before(...nodes: Array<PseudoNode | string>): void;
|
|
502
504
|
/**
|
|
503
505
|
* Returns whether an element is expected to be visible or not based on configurable checks.
|
|
504
506
|
*/
|
|
@@ -572,17 +574,25 @@ export interface PseudoElement extends PseudoNode {
|
|
|
572
574
|
*/
|
|
573
575
|
hasPointerCapture(): string;
|
|
574
576
|
/**
|
|
575
|
-
* Inserts a given element
|
|
577
|
+
* Inserts a given element at a given position relative to the element it is invoked upon.
|
|
578
|
+
* @param {string} position beforebegin, afterbegin, beforeend or afterend
|
|
579
|
+
* @param {PseudoElement} element The element to insert
|
|
580
|
+
* @returns {PseudoElement|null} The inserted element, or null when the position needs a parent this element does not have
|
|
576
581
|
*/
|
|
577
|
-
insertAdjacentElement():
|
|
582
|
+
insertAdjacentElement(position: string, element: PseudoElement): PseudoElement | null;
|
|
578
583
|
/**
|
|
579
|
-
* Parses the text as HTML or XML and inserts the resulting nodes into the tree in the position given.
|
|
584
|
+
* Parses the text as HTML or XML and inserts the resulting nodes into the tree in the position given. Not implemented
|
|
585
|
+
* yet (HTML parsing is out of scope for now).
|
|
586
|
+
* @param {string} position beforebegin, afterbegin, beforeend or afterend
|
|
587
|
+
* @param {string} text The markup to parse
|
|
580
588
|
*/
|
|
581
|
-
insertAdjacentHTML():
|
|
589
|
+
insertAdjacentHTML(position: string, text: string): void;
|
|
582
590
|
/**
|
|
583
|
-
* Inserts a given text
|
|
591
|
+
* Inserts a given text at a given position relative to the element it is invoked upon.
|
|
592
|
+
* @param {string} position beforebegin, afterbegin, beforeend or afterend
|
|
593
|
+
* @param {string} text The text to insert
|
|
584
594
|
*/
|
|
585
|
-
insertAdjacentText():
|
|
595
|
+
insertAdjacentText(position: string, text: string): void;
|
|
586
596
|
/**
|
|
587
597
|
* Returns a boolean value indicating whether or not the element would be selected by the specified selector string.
|
|
588
598
|
*/
|
|
@@ -590,7 +600,7 @@ export interface PseudoElement extends PseudoNode {
|
|
|
590
600
|
/**
|
|
591
601
|
* Inserts a set of Node objects or strings before the first child of the element.
|
|
592
602
|
*/
|
|
593
|
-
prepend():
|
|
603
|
+
prepend(...nodes: Array<PseudoNode | string>): void;
|
|
594
604
|
/**
|
|
595
605
|
* Returns the first Node which matches the specified selector string relative to the element.
|
|
596
606
|
*/
|
|
@@ -604,9 +614,9 @@ export interface PseudoElement extends PseudoNode {
|
|
|
604
614
|
*/
|
|
605
615
|
releasePointerCapture(): string;
|
|
606
616
|
/**
|
|
607
|
-
* Removes the element from the children list of its parent.
|
|
617
|
+
* Removes the element from the children list of its parent. Does nothing when it has no parent.
|
|
608
618
|
*/
|
|
609
|
-
remove():
|
|
619
|
+
remove(): void;
|
|
610
620
|
/**
|
|
611
621
|
* Removes the named attribute from the current node.
|
|
612
622
|
*/
|
|
@@ -622,11 +632,12 @@ export interface PseudoElement extends PseudoNode {
|
|
|
622
632
|
/**
|
|
623
633
|
* Replaces the existing children of a Node with a specified new set of children.
|
|
624
634
|
*/
|
|
625
|
-
replaceChildren():
|
|
635
|
+
replaceChildren(...nodes: Array<PseudoNode | string>): void;
|
|
626
636
|
/**
|
|
627
|
-
* Replaces the element in the children list of its parent with a set of Node objects or strings.
|
|
637
|
+
* Replaces the element in the children list of its parent with a set of Node objects or strings. Does nothing when it
|
|
638
|
+
* has no parent.
|
|
628
639
|
*/
|
|
629
|
-
replaceWith():
|
|
640
|
+
replaceWith(...nodes: Array<PseudoNode | string>): void;
|
|
630
641
|
/**
|
|
631
642
|
* Asynchronously asks the browser to make the element fullscreen.
|
|
632
643
|
*/
|
|
@@ -1,2 +1,23 @@
|
|
|
1
|
-
|
|
1
|
+
import { PseudoElement } from './PseudoElement';
|
|
2
|
+
/**
|
|
3
|
+
* A live collection of an element's (or a document's / document fragment's) element children: it is not a snapshot,
|
|
4
|
+
* reading it after the tree changes reflects the change.
|
|
5
|
+
*/
|
|
6
|
+
export interface PseudoHTMLCollection extends Iterable<PseudoElement> {
|
|
7
|
+
/**
|
|
8
|
+
* How many elements are in the collection.
|
|
9
|
+
*/
|
|
10
|
+
get length(): number;
|
|
11
|
+
/**
|
|
12
|
+
* The element at the given index, or null when there is none.
|
|
13
|
+
* @param {number} index
|
|
14
|
+
* @returns {PseudoElement|null}
|
|
15
|
+
*/
|
|
16
|
+
item(index: number): PseudoElement | null;
|
|
17
|
+
/**
|
|
18
|
+
* The element whose id, or whose name attribute, is the given value, or null when there is none.
|
|
19
|
+
* @param {string} name
|
|
20
|
+
* @returns {PseudoElement|null}
|
|
21
|
+
*/
|
|
22
|
+
namedItem(name: string): PseudoElement | null;
|
|
2
23
|
}
|
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
* @version 1.0.0
|
|
5
5
|
*/
|
|
6
6
|
import { PseudoNode } from '../interfaces/PseudoNode';
|
|
7
|
-
import { NodeService } from './NodeService';
|
|
8
7
|
import { PseudoElement } from '../interfaces/PseudoElement';
|
|
8
|
+
import { NodeService } from './NodeService';
|
|
9
9
|
import { PseudoNamedNodeMap } from '../interfaces/PseudoNamedNodeMap';
|
|
10
10
|
import { PseudoDOMTokenList } from '../interfaces/PseudoDOMTokenList';
|
|
11
|
+
import { PseudoHTMLCollection } from '../interfaces/PseudoHTMLCollection';
|
|
11
12
|
type attribute = {
|
|
12
13
|
name: string;
|
|
13
14
|
value: any;
|
|
@@ -80,6 +81,68 @@ export declare class ElementService extends NodeService implements Partial<Pseud
|
|
|
80
81
|
* Some elements have default behaviour, this registers it when the element is added.
|
|
81
82
|
* @returns {Function}
|
|
82
83
|
*/
|
|
84
|
+
/**
|
|
85
|
+
* A live view of this element's element children (text, comments and the like are not included).
|
|
86
|
+
* @returns {PseudoHTMLCollection}
|
|
87
|
+
*/
|
|
88
|
+
get children(): PseudoHTMLCollection;
|
|
89
|
+
/**
|
|
90
|
+
* How many element children this element has.
|
|
91
|
+
* @returns {number}
|
|
92
|
+
*/
|
|
93
|
+
get childElementCount(): number;
|
|
94
|
+
/**
|
|
95
|
+
* The first child of this element which is an element, or null when there is none.
|
|
96
|
+
* @returns {PseudoElement|null}
|
|
97
|
+
*/
|
|
98
|
+
get firstElementChild(): PseudoElement | null;
|
|
99
|
+
/**
|
|
100
|
+
* The last child of this element which is an element, or null when there is none.
|
|
101
|
+
* @returns {PseudoElement|null}
|
|
102
|
+
*/
|
|
103
|
+
get lastElementChild(): PseudoElement | null;
|
|
104
|
+
/**
|
|
105
|
+
* The sibling after this one which is an element, or null when there is none.
|
|
106
|
+
* @returns {PseudoElement|null}
|
|
107
|
+
*/
|
|
108
|
+
get nextElementSibling(): PseudoElement | null;
|
|
109
|
+
/**
|
|
110
|
+
* The sibling before this one which is an element, or null when there is none.
|
|
111
|
+
* @returns {PseudoElement|null}
|
|
112
|
+
*/
|
|
113
|
+
get previousElementSibling(): PseudoElement | null;
|
|
114
|
+
/**
|
|
115
|
+
* Put an element at a position relative to this one: beforebegin (before this element, as its previous sibling),
|
|
116
|
+
* afterbegin (as this element's first child), beforeend (as this element's last child) or afterend (after this
|
|
117
|
+
* element, as its next sibling).
|
|
118
|
+
* @param {string} position beforebegin, afterbegin, beforeend or afterend
|
|
119
|
+
* @param {ElementService} element The element to insert
|
|
120
|
+
* @returns {ElementService|null} The inserted element, or null when the position needed a parent this element does not have
|
|
121
|
+
* @throws {Error} When the position is not one of the four above
|
|
122
|
+
*/
|
|
123
|
+
insertAdjacentElement(position: string, element: PseudoElement): PseudoElement | null;
|
|
124
|
+
/**
|
|
125
|
+
* Put text at a position relative to this element, the same as insertAdjacentElement but the text becomes a text node.
|
|
126
|
+
* @param {string} position beforebegin, afterbegin, beforeend or afterend
|
|
127
|
+
* @param {string} text The text to insert
|
|
128
|
+
* @throws {Error} When the position is not one of the four above
|
|
129
|
+
*/
|
|
130
|
+
insertAdjacentText(position: string, text: string): void;
|
|
131
|
+
/**
|
|
132
|
+
* Shared implementation for insertAdjacentElement / insertAdjacentText.
|
|
133
|
+
* @param {string} position beforebegin, afterbegin, beforeend or afterend
|
|
134
|
+
* @param {PseudoNode|string} node The node (or text) to insert
|
|
135
|
+
* @returns {PseudoNode|null} The inserted node, or null when the position needed a parent this element does not have
|
|
136
|
+
* @throws {Error} When the position is not one of the four above
|
|
137
|
+
*/
|
|
138
|
+
private insertAdjacent;
|
|
139
|
+
/**
|
|
140
|
+
* Not implemented yet (HTML parsing is out of scope for now).
|
|
141
|
+
* @param {string} position beforebegin, afterbegin, beforeend or afterend
|
|
142
|
+
* @param {string} text The markup which would be parsed
|
|
143
|
+
* @throws {Error}
|
|
144
|
+
*/
|
|
145
|
+
insertAdjacentHTML(position: string, text: string): void;
|
|
83
146
|
applyDefaultEvent(): Function;
|
|
84
147
|
/**
|
|
85
148
|
* An element which is added as a child gets its default events (for example a submit button submits its form).
|
|
@@ -23,6 +23,7 @@ const AttrService_1 = require('./AttrService')
|
|
|
23
23
|
const DOMTokenListService_1 = require('./DOMTokenListService')
|
|
24
24
|
const NamedNodeMapService_1 = require('./NamedNodeMapService')
|
|
25
25
|
const getParentNodesFromAttribute_1 = __importDefault(require('../functions/getParentNodesFromAttribute'))
|
|
26
|
+
const HTMLCollectionService_1 = require('./HTMLCollectionService')
|
|
26
27
|
const cloneObject_1 = __importDefault(require('si-funciona/dist/helpers/objects/cloneObject'))
|
|
27
28
|
const isEqual_1 = __importDefault(require('si-funciona/dist/helpers/objects/isEqual'))
|
|
28
29
|
/**
|
|
@@ -184,6 +185,128 @@ class ElementService extends NodeService_1.NodeService {
|
|
|
184
185
|
* Some elements have default behaviour, this registers it when the element is added.
|
|
185
186
|
* @returns {Function}
|
|
186
187
|
*/
|
|
188
|
+
/**
|
|
189
|
+
* A live view of this element's element children (text, comments and the like are not included).
|
|
190
|
+
* @returns {PseudoHTMLCollection}
|
|
191
|
+
*/
|
|
192
|
+
get children () {
|
|
193
|
+
return new HTMLCollectionService_1.HTMLCollectionService(this)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* How many element children this element has.
|
|
198
|
+
* @returns {number}
|
|
199
|
+
*/
|
|
200
|
+
get childElementCount () {
|
|
201
|
+
return this.children.length
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* The first child of this element which is an element, or null when there is none.
|
|
206
|
+
* @returns {PseudoElement|null}
|
|
207
|
+
*/
|
|
208
|
+
get firstElementChild () {
|
|
209
|
+
return this.children.item(0)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* The last child of this element which is an element, or null when there is none.
|
|
214
|
+
* @returns {PseudoElement|null}
|
|
215
|
+
*/
|
|
216
|
+
get lastElementChild () {
|
|
217
|
+
const elementChildren = this.children
|
|
218
|
+
return elementChildren.item(elementChildren.length - 1)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* The sibling after this one which is an element, or null when there is none.
|
|
223
|
+
* @returns {PseudoElement|null}
|
|
224
|
+
*/
|
|
225
|
+
get nextElementSibling () {
|
|
226
|
+
let sibling = this.nextSibling
|
|
227
|
+
while (sibling && sibling.nodeType !== NodeService_1.NodeService.ELEMENT_NODE) {
|
|
228
|
+
sibling = sibling.nextSibling
|
|
229
|
+
}
|
|
230
|
+
return sibling
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* The sibling before this one which is an element, or null when there is none.
|
|
235
|
+
* @returns {PseudoElement|null}
|
|
236
|
+
*/
|
|
237
|
+
get previousElementSibling () {
|
|
238
|
+
let sibling = this.previousSibling
|
|
239
|
+
while (sibling && sibling.nodeType !== NodeService_1.NodeService.ELEMENT_NODE) {
|
|
240
|
+
sibling = sibling.previousSibling
|
|
241
|
+
}
|
|
242
|
+
return sibling
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Put an element at a position relative to this one: beforebegin (before this element, as its previous sibling),
|
|
247
|
+
* afterbegin (as this element's first child), beforeend (as this element's last child) or afterend (after this
|
|
248
|
+
* element, as its next sibling).
|
|
249
|
+
* @param {string} position beforebegin, afterbegin, beforeend or afterend
|
|
250
|
+
* @param {ElementService} element The element to insert
|
|
251
|
+
* @returns {ElementService|null} The inserted element, or null when the position needed a parent this element does not have
|
|
252
|
+
* @throws {Error} When the position is not one of the four above
|
|
253
|
+
*/
|
|
254
|
+
insertAdjacentElement (position, element) {
|
|
255
|
+
return this.insertAdjacent(position, element)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Put text at a position relative to this element, the same as insertAdjacentElement but the text becomes a text node.
|
|
260
|
+
* @param {string} position beforebegin, afterbegin, beforeend or afterend
|
|
261
|
+
* @param {string} text The text to insert
|
|
262
|
+
* @throws {Error} When the position is not one of the four above
|
|
263
|
+
*/
|
|
264
|
+
insertAdjacentText (position, text) {
|
|
265
|
+
this.insertAdjacent(position, text)
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Shared implementation for insertAdjacentElement / insertAdjacentText.
|
|
270
|
+
* @param {string} position beforebegin, afterbegin, beforeend or afterend
|
|
271
|
+
* @param {PseudoNode|string} node The node (or text) to insert
|
|
272
|
+
* @returns {PseudoNode|null} The inserted node, or null when the position needed a parent this element does not have
|
|
273
|
+
* @throws {Error} When the position is not one of the four above
|
|
274
|
+
*/
|
|
275
|
+
insertAdjacent (position, node) {
|
|
276
|
+
switch (position) {
|
|
277
|
+
case 'beforebegin':
|
|
278
|
+
if (!this.parentNode) {
|
|
279
|
+
return null
|
|
280
|
+
}
|
|
281
|
+
this.before(node)
|
|
282
|
+
return node
|
|
283
|
+
case 'afterbegin':
|
|
284
|
+
this.prepend(node)
|
|
285
|
+
return node
|
|
286
|
+
case 'beforeend':
|
|
287
|
+
this.append(node)
|
|
288
|
+
return node
|
|
289
|
+
case 'afterend':
|
|
290
|
+
if (!this.parentNode) {
|
|
291
|
+
return null
|
|
292
|
+
}
|
|
293
|
+
this.after(node)
|
|
294
|
+
return node
|
|
295
|
+
default:
|
|
296
|
+
throw new Error(`"${position}" is not one of beforebegin, afterbegin, beforeend or afterend.`)
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Not implemented yet (HTML parsing is out of scope for now).
|
|
302
|
+
* @param {string} position beforebegin, afterbegin, beforeend or afterend
|
|
303
|
+
* @param {string} text The markup which would be parsed
|
|
304
|
+
* @throws {Error}
|
|
305
|
+
*/
|
|
306
|
+
insertAdjacentHTML (position, text) {
|
|
307
|
+
throw new Error('ElementService.insertAdjacentHTML() is not implemented yet.')
|
|
308
|
+
}
|
|
309
|
+
|
|
187
310
|
applyDefaultEvent () {
|
|
188
311
|
let callback = event => undefined
|
|
189
312
|
if (this.defaultEventApplied) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.every.js"),require("core-js/modules/esnext.iterator.find.js"),require("core-js/modules/esnext.iterator.for-each.js"),require("core-js/modules/esnext.iterator.map.js"),require("core-js/modules/esnext.iterator.some.js");var __importDefault=function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.ElementService=void 0;const createEvent_1=__importDefault(require("../factories/createEvent")),NodeService_1=require("./NodeService"),AttrService_1=require("./AttrService"),DOMTokenListService_1=require("./DOMTokenListService"),NamedNodeMapService_1=require("./NamedNodeMapService"),getParentNodesFromAttribute_1=__importDefault(require("../functions/getParentNodesFromAttribute")),cloneObject_1=__importDefault(require("si-funciona/dist/helpers/objects/cloneObject")),isEqual_1=__importDefault(require("si-funciona/dist/helpers/objects/isEqual"));class ElementService extends NodeService_1.NodeService{constructor({tagName:e="",attributes:t=[],parent:r=null,children:i=[]}={}){super(),this.defaultEventApplied=!1,this.tokenList=new DOMTokenListService_1.DOMTokenListService,this.tag=e,this.attributeList=t.concat([{name:"className",value:""},{name:"id",value:""},{name:"innerHTML",value:""}]),this.propertyAttributes=this.attributeList.map(({name:e})=>e),this.attributeList.forEach(({name:e,value:t})=>{this[e]=t}),i.forEach(e=>{if(!e||"number"!=typeof e.nodeType)throw new TypeError("The children of an element must be nodes.");this.appendChild(e)}),r&&r.appendChild(this)}currentAttributes(){return this.attributeList.map(({name:e,value:t})=>({name:e,value:this.propertyAttributes.indexOf(e)>=0?this[e]:t}))}get nodeName(){return this.tag}cloneShallow(){const e=new this.constructor({tagName:this.tag});return e.attributeList.length=0,this.currentAttributes().forEach(({name:t,value:r})=>{const i="object"==typeof r&&null!==r?(0,cloneObject_1.default)(r):r;e.attributeList.push({name:t,value:i}),e.propertyAttributes.indexOf(t)>=0&&(e[t]=i)}),e.ownerDocumentStore=this.ownerDocumentStore,e}equalsShallow(e){const t=this.currentAttributes(),r=e.currentAttributes();return this.nodeName===e.nodeName&&t.length===r.length&&t.every(({name:e,value:t})=>{const i=r.find(t=>t.name===e);return void 0!==i&&(0,isEqual_1.default)(t,i.value)})}get tagName(){return this.tag}get nodeType(){return NodeService_1.NodeService.ELEMENT_NODE}get attributes(){return new NamedNodeMapService_1.NamedNodeMapService(this.currentAttributes().map(({name:e,value:t})=>new AttrService_1.AttrService(e,String(t),this)))}get classList(){return this.tokenList}get className(){return this.tokenList.value}set className(e){this.tokenList.value=e}applyDefaultEvent(){let e=e=>{};if(this.defaultEventApplied)return e;switch(this.tagName){case"button":case"input":e=e=>{const t=String(this.getAttribute("type")||this.type||"").toLowerCase(),r="button"===this.tagName?"button"!==t&&"reset"!==t:/^(submit|image)$/.test(t),i=(0,getParentNodesFromAttribute_1.default)("tagName","form",this);r&&i.length&&!this.hasAttribute("disabled")&&i[i.length-1].dispatchEvent((0,createEvent_1.default)("submit",{},{browser:!0,trusted:e.isTrusted}))},super.setDefaultEvent("click",e),this.defaultEventApplied=!0}return e}childInserted(e){"function"==typeof e.applyDefaultEvent&&e.applyDefaultEvent()}hasAttribute(e){return this.attributeList.some(({name:t})=>t===e)}setAttribute(e,t){const r=this.attributeList.find(({name:t})=>t===e);r?r.value=t:this.attributeList.push({name:e,value:t}),this.propertyAttributes.indexOf(e)>=0&&(this[e]=t)}getAttribute(e){const t=this.currentAttributes().find(({name:t})=>t===e);return t?t.value:null}removeAttribute(e){const t=this.attributeList.findIndex(({name:t})=>t===e);t>=0&&this.attributeList.splice(t,1)}}exports.ElementService=ElementService;
|
|
1
|
+
"use strict";require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.every.js"),require("core-js/modules/esnext.iterator.find.js"),require("core-js/modules/esnext.iterator.for-each.js"),require("core-js/modules/esnext.iterator.map.js"),require("core-js/modules/esnext.iterator.some.js");var __importDefault=function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.ElementService=void 0;const createEvent_1=__importDefault(require("../factories/createEvent")),NodeService_1=require("./NodeService"),AttrService_1=require("./AttrService"),DOMTokenListService_1=require("./DOMTokenListService"),NamedNodeMapService_1=require("./NamedNodeMapService"),getParentNodesFromAttribute_1=__importDefault(require("../functions/getParentNodesFromAttribute")),HTMLCollectionService_1=require("./HTMLCollectionService"),cloneObject_1=__importDefault(require("si-funciona/dist/helpers/objects/cloneObject")),isEqual_1=__importDefault(require("si-funciona/dist/helpers/objects/isEqual"));class ElementService extends NodeService_1.NodeService{constructor({tagName:e="",attributes:t=[],parent:r=null,children:i=[]}={}){super(),this.defaultEventApplied=!1,this.tokenList=new DOMTokenListService_1.DOMTokenListService,this.tag=e,this.attributeList=t.concat([{name:"className",value:""},{name:"id",value:""},{name:"innerHTML",value:""}]),this.propertyAttributes=this.attributeList.map(({name:e})=>e),this.attributeList.forEach(({name:e,value:t})=>{this[e]=t}),i.forEach(e=>{if(!e||"number"!=typeof e.nodeType)throw new TypeError("The children of an element must be nodes.");this.appendChild(e)}),r&&r.appendChild(this)}currentAttributes(){return this.attributeList.map(({name:e,value:t})=>({name:e,value:this.propertyAttributes.indexOf(e)>=0?this[e]:t}))}get nodeName(){return this.tag}cloneShallow(){const e=new this.constructor({tagName:this.tag});return e.attributeList.length=0,this.currentAttributes().forEach(({name:t,value:r})=>{const i="object"==typeof r&&null!==r?(0,cloneObject_1.default)(r):r;e.attributeList.push({name:t,value:i}),e.propertyAttributes.indexOf(t)>=0&&(e[t]=i)}),e.ownerDocumentStore=this.ownerDocumentStore,e}equalsShallow(e){const t=this.currentAttributes(),r=e.currentAttributes();return this.nodeName===e.nodeName&&t.length===r.length&&t.every(({name:e,value:t})=>{const i=r.find(t=>t.name===e);return void 0!==i&&(0,isEqual_1.default)(t,i.value)})}get tagName(){return this.tag}get nodeType(){return NodeService_1.NodeService.ELEMENT_NODE}get attributes(){return new NamedNodeMapService_1.NamedNodeMapService(this.currentAttributes().map(({name:e,value:t})=>new AttrService_1.AttrService(e,String(t),this)))}get classList(){return this.tokenList}get className(){return this.tokenList.value}set className(e){this.tokenList.value=e}get children(){return new HTMLCollectionService_1.HTMLCollectionService(this)}get childElementCount(){return this.children.length}get firstElementChild(){return this.children.item(0)}get lastElementChild(){const e=this.children;return e.item(e.length-1)}get nextElementSibling(){let e=this.nextSibling;for(;e&&e.nodeType!==NodeService_1.NodeService.ELEMENT_NODE;)e=e.nextSibling;return e}get previousElementSibling(){let e=this.previousSibling;for(;e&&e.nodeType!==NodeService_1.NodeService.ELEMENT_NODE;)e=e.previousSibling;return e}insertAdjacentElement(e,t){return this.insertAdjacent(e,t)}insertAdjacentText(e,t){this.insertAdjacent(e,t)}insertAdjacent(e,t){switch(e){case"beforebegin":return this.parentNode?(this.before(t),t):null;case"afterbegin":return this.prepend(t),t;case"beforeend":return this.append(t),t;case"afterend":return this.parentNode?(this.after(t),t):null;default:throw new Error(`"${e}" is not one of beforebegin, afterbegin, beforeend or afterend.`)}}insertAdjacentHTML(e,t){throw new Error("ElementService.insertAdjacentHTML() is not implemented yet.")}applyDefaultEvent(){let e=e=>{};if(this.defaultEventApplied)return e;switch(this.tagName){case"button":case"input":e=e=>{const t=String(this.getAttribute("type")||this.type||"").toLowerCase(),r="button"===this.tagName?"button"!==t&&"reset"!==t:/^(submit|image)$/.test(t),i=(0,getParentNodesFromAttribute_1.default)("tagName","form",this);r&&i.length&&!this.hasAttribute("disabled")&&i[i.length-1].dispatchEvent((0,createEvent_1.default)("submit",{},{browser:!0,trusted:e.isTrusted}))},super.setDefaultEvent("click",e),this.defaultEventApplied=!0}return e}childInserted(e){"function"==typeof e.applyDefaultEvent&&e.applyDefaultEvent()}hasAttribute(e){return this.attributeList.some(({name:t})=>t===e)}setAttribute(e,t){const r=this.attributeList.find(({name:t})=>t===e);r?r.value=t:this.attributeList.push({name:e,value:t}),this.propertyAttributes.indexOf(e)>=0&&(this[e]=t)}getAttribute(e){const t=this.currentAttributes().find(({name:t})=>t===e);return t?t.value:null}removeAttribute(e){const t=this.attributeList.findIndex(({name:t})=>t===e);t>=0&&this.attributeList.splice(t,1)}}exports.ElementService=ElementService;
|
|
@@ -1,3 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Substitute for the DOM HTMLCollection Class.
|
|
3
|
+
* @author Joshua Heagle <joshuaheagle@gmail.com>
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
import { NodeService } from './NodeService';
|
|
1
7
|
import { PseudoHTMLCollection } from '../interfaces/PseudoHTMLCollection';
|
|
8
|
+
/**
|
|
9
|
+
* Simulate the behaviour of the HTMLCollection Class when there is no DOM available: a live view of the element
|
|
10
|
+
* children of a node, recomputed from its childNodes each time it is used rather than kept in sync as they change.
|
|
11
|
+
* @author Joshua Heagle <joshuaheagle@gmail.com>
|
|
12
|
+
* @class
|
|
13
|
+
*/
|
|
2
14
|
export declare class HTMLCollectionService implements PseudoHTMLCollection {
|
|
15
|
+
private readonly owner;
|
|
16
|
+
/**
|
|
17
|
+
* @param {NodeService} owner The node whose element children this is a live view of
|
|
18
|
+
* @constructor
|
|
19
|
+
*/
|
|
20
|
+
constructor(owner: NodeService);
|
|
21
|
+
/**
|
|
22
|
+
* The current element children of the owner, in order.
|
|
23
|
+
* @returns {Array<PseudoNode>}
|
|
24
|
+
*/
|
|
25
|
+
private elements;
|
|
26
|
+
/**
|
|
27
|
+
* How many elements are in the collection right now.
|
|
28
|
+
* @returns {number}
|
|
29
|
+
*/
|
|
30
|
+
get length(): number;
|
|
31
|
+
/**
|
|
32
|
+
* The element at the given index, or null when there is none.
|
|
33
|
+
* @param {number} index
|
|
34
|
+
* @returns {*}
|
|
35
|
+
*/
|
|
36
|
+
item(index: number): any | null;
|
|
37
|
+
/**
|
|
38
|
+
* The element whose id, or (failing that) whose name attribute, is the given value, or null when there is none.
|
|
39
|
+
* @param {string} name
|
|
40
|
+
* @returns {*}
|
|
41
|
+
*/
|
|
42
|
+
namedItem(name: string): any | null;
|
|
43
|
+
/**
|
|
44
|
+
* Iterate over the current element children.
|
|
45
|
+
* @returns {Iterator}
|
|
46
|
+
*/
|
|
47
|
+
[Symbol.iterator](): Iterator<any>;
|
|
3
48
|
}
|
|
49
|
+
export default HTMLCollectionService;
|
|
@@ -1,8 +1,75 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
require('core-js/modules/esnext.iterator.constructor.js')
|
|
4
|
+
require('core-js/modules/esnext.iterator.filter.js')
|
|
5
|
+
require('core-js/modules/esnext.iterator.find.js')
|
|
3
6
|
Object.defineProperty(exports, '__esModule', {
|
|
4
7
|
value: true
|
|
5
8
|
})
|
|
6
9
|
exports.HTMLCollectionService = void 0
|
|
7
|
-
|
|
10
|
+
/**
|
|
11
|
+
* @file Substitute for the DOM HTMLCollection Class.
|
|
12
|
+
* @author Joshua Heagle <joshuaheagle@gmail.com>
|
|
13
|
+
* @version 1.0.0
|
|
14
|
+
*/
|
|
15
|
+
const NodeService_1 = require('./NodeService')
|
|
16
|
+
/**
|
|
17
|
+
* Simulate the behaviour of the HTMLCollection Class when there is no DOM available: a live view of the element
|
|
18
|
+
* children of a node, recomputed from its childNodes each time it is used rather than kept in sync as they change.
|
|
19
|
+
* @author Joshua Heagle <joshuaheagle@gmail.com>
|
|
20
|
+
* @class
|
|
21
|
+
*/
|
|
22
|
+
class HTMLCollectionService {
|
|
23
|
+
/**
|
|
24
|
+
* @param {NodeService} owner The node whose element children this is a live view of
|
|
25
|
+
* @constructor
|
|
26
|
+
*/
|
|
27
|
+
constructor (owner) {
|
|
28
|
+
this.owner = owner
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The current element children of the owner, in order.
|
|
33
|
+
* @returns {Array<PseudoNode>}
|
|
34
|
+
*/
|
|
35
|
+
elements () {
|
|
36
|
+
return Array.from(this.owner.childNodes).filter(node => node.nodeType === NodeService_1.NodeService.ELEMENT_NODE)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* How many elements are in the collection right now.
|
|
41
|
+
* @returns {number}
|
|
42
|
+
*/
|
|
43
|
+
get length () {
|
|
44
|
+
return this.elements().length
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The element at the given index, or null when there is none.
|
|
49
|
+
* @param {number} index
|
|
50
|
+
* @returns {*}
|
|
51
|
+
*/
|
|
52
|
+
item (index) {
|
|
53
|
+
return this.elements()[index] || null
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The element whose id, or (failing that) whose name attribute, is the given value, or null when there is none.
|
|
58
|
+
* @param {string} name
|
|
59
|
+
* @returns {*}
|
|
60
|
+
*/
|
|
61
|
+
namedItem (name) {
|
|
62
|
+
const elements = this.elements()
|
|
63
|
+
return elements.find(element => element.id === name) || elements.find(element => element.getAttribute('name') === name) || null
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Iterate over the current element children.
|
|
68
|
+
* @returns {Iterator}
|
|
69
|
+
*/
|
|
70
|
+
[Symbol.iterator] () {
|
|
71
|
+
return this.elements()[Symbol.iterator]()
|
|
72
|
+
}
|
|
73
|
+
}
|
|
8
74
|
exports.HTMLCollectionService = HTMLCollectionService
|
|
75
|
+
exports.default = HTMLCollectionService
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.HTMLCollectionService=void 0;class HTMLCollectionService{}exports.HTMLCollectionService=HTMLCollectionService;
|
|
1
|
+
"use strict";require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.filter.js"),require("core-js/modules/esnext.iterator.find.js"),Object.defineProperty(exports,"__esModule",{value:!0}),exports.HTMLCollectionService=void 0;const NodeService_1=require("./NodeService");class HTMLCollectionService{constructor(e){this.owner=e}elements(){return Array.from(this.owner.childNodes).filter(e=>e.nodeType===NodeService_1.NodeService.ELEMENT_NODE)}get length(){return this.elements().length}item(e){return this.elements()[e]||null}namedItem(e){const t=this.elements();return t.find(t=>t.id===e)||t.find(t=>t.getAttribute("name")===e)||null}[Symbol.iterator](){return this.elements()[Symbol.iterator]()}}exports.HTMLCollectionService=HTMLCollectionService,exports.default=HTMLCollectionService;
|
|
@@ -36,7 +36,8 @@ export declare class NodeService extends EventTargetService implements PseudoNod
|
|
|
36
36
|
static readonly DOCUMENT_POSITION_CONTAINED_BY = 16;
|
|
37
37
|
static readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 32;
|
|
38
38
|
private static nextNodeId;
|
|
39
|
-
children
|
|
39
|
+
/** The raw list of every child node (all types), used to implement childNodes/firstChild/lastChild/insertBefore/removeChild. Not the same thing as Element.children (an HTMLCollection of just the element children). */
|
|
40
|
+
protected childList: PseudoNodeList | LinkedTreeList;
|
|
40
41
|
parent: PseudoNode | null;
|
|
41
42
|
protected nodeNameValue: string;
|
|
42
43
|
private nodeValueStore;
|
|
@@ -91,6 +92,53 @@ export declare class NodeService extends EventTargetService implements PseudoNod
|
|
|
91
92
|
* @returns {boolean}
|
|
92
93
|
*/
|
|
93
94
|
protected equalsShallow(other: NodeService): boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Add nodes (strings become text nodes) as the last children of this node, in the order given.
|
|
97
|
+
* @param {...(PseudoNode|string)} nodes The nodes (or text) to add
|
|
98
|
+
* @throws {Error} When this kind of node cannot have children
|
|
99
|
+
*/
|
|
100
|
+
append(...nodes: Array<PseudoNode | string>): void;
|
|
101
|
+
/**
|
|
102
|
+
* Add nodes (strings become text nodes) as the first children of this node, in the order given.
|
|
103
|
+
* @param {...(PseudoNode|string)} nodes The nodes (or text) to add
|
|
104
|
+
* @throws {Error} When this kind of node cannot have children
|
|
105
|
+
*/
|
|
106
|
+
prepend(...nodes: Array<PseudoNode | string>): void;
|
|
107
|
+
/**
|
|
108
|
+
* Remove every child of this node and put the given nodes (strings become text nodes) in their place, in order.
|
|
109
|
+
* @param {...(PseudoNode|string)} nodes The nodes (or text) to add
|
|
110
|
+
* @throws {Error} When this kind of node cannot have children
|
|
111
|
+
*/
|
|
112
|
+
replaceChildren(...nodes: Array<PseudoNode | string>): void;
|
|
113
|
+
/**
|
|
114
|
+
* Add nodes (strings become text nodes) as this node's previous siblings, in order. Does nothing when this node has
|
|
115
|
+
* no parent.
|
|
116
|
+
* @param {...(PseudoNode|string)} nodes The nodes (or text) to add
|
|
117
|
+
*/
|
|
118
|
+
before(...nodes: Array<PseudoNode | string>): void;
|
|
119
|
+
/**
|
|
120
|
+
* Add nodes (strings become text nodes) as this node's next siblings, in order. Does nothing when this node has no
|
|
121
|
+
* parent.
|
|
122
|
+
* @param {...(PseudoNode|string)} nodes The nodes (or text) to add
|
|
123
|
+
*/
|
|
124
|
+
after(...nodes: Array<PseudoNode | string>): void;
|
|
125
|
+
/**
|
|
126
|
+
* Put the given nodes (strings become text nodes) where this node is, in order, then remove this node. Does nothing
|
|
127
|
+
* when this node has no parent.
|
|
128
|
+
* @param {...(PseudoNode|string)} nodes The nodes (or text) to put in this node's place
|
|
129
|
+
*/
|
|
130
|
+
replaceWith(...nodes: Array<PseudoNode | string>): void;
|
|
131
|
+
/**
|
|
132
|
+
* Remove this node from its parent. Does nothing when it has no parent.
|
|
133
|
+
*/
|
|
134
|
+
remove(): void;
|
|
135
|
+
/**
|
|
136
|
+
* Turn a value given to append / prepend / before / after / replaceWith / replaceChildren into a node: a string
|
|
137
|
+
* becomes a text node belonging to this node's document, anything else is returned as it is.
|
|
138
|
+
* @param {PseudoNode|string} value The value to add
|
|
139
|
+
* @returns {PseudoNode}
|
|
140
|
+
*/
|
|
141
|
+
private toChildNode;
|
|
94
142
|
/**
|
|
95
143
|
* Called each time a node has been inserted as a child of this node, so that nodes which need to react to children
|
|
96
144
|
* (for example elements applying default events) can do so.
|