Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7f17718

Browse files
committed
feat: add DOM level 4 child element properties
This adds the properties childElementCount, firstElementChild, lastElementChild, nextElementSibling and previousElementSibling to Element. The first three are also added to Document and DocumentFragment.
1 parent 9ef2fd2 commit 7f17718

26 files changed

Lines changed: 3679 additions & 2174 deletions

lib/dom.js

Lines changed: 200 additions & 91 deletions
Large diffs are not rendered by default.

package-lock.json

Lines changed: 3374 additions & 2021 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
"eslint-plugin-n": "17.24.0",
5454
"eslint-plugin-prettier": "5.5.5",
5555
"get-stream": "6.0.1",
56-
"jest": "29.7.0",
56+
"jest": "30.3.0",
5757
"nodemon": "3.1.14",
5858
"np": "8.0.4",
5959
"prettier": "3.8.1",

readme.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ import { DOMParser } from '@xmldom/xmldom'
9292
```javascript
9393
serializeToString(node)
9494
```
95-
### DOM level2 method and attribute:
95+
### DOM level 2 method and attribute:
9696

9797
* [Node](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247)
9898

@@ -293,8 +293,17 @@ import { DOMParser } from '@xmldom/xmldom'
293293

294294
* [ParentNode](https://dom.spec.whatwg.org/#interface-parentnode) mixin (on `Document`, `DocumentFragment`, `Element`)
295295

296-
readonly attribute:
296+
readonly attributes:
297297
- `children`
298+
- `firstElementChild`
299+
- `lastElementChild`
300+
- `childElementCount`
301+
302+
* Element (from [NonDocumentTypeChildNode](https://dom.spec.whatwg.org/#nondocumenttypechildnode) mixin)
303+
304+
readonly attributes:
305+
- `previousElementSibling`
306+
- `nextElementSibling`
298307

299308
### DOM extension by xmldom
300309

test/__snapshots__/entities.test.js.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Jest Snapshot v1, https://goo.gl/fbAQLP
1+
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
22

33
exports[`entity replacement ignores js prototype chain should not pick up 'entities' from the prototype chain 1`] = `
44
{

test/conventions/__snapshots__/html.test.js.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Jest Snapshot v1, https://goo.gl/fbAQLP
1+
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
22

33
exports[`HTML_BOOLEAN_ATTRIBUTES should contain immutable allowfullscreen with value 'true' 1`] = `
44
[

test/conventions/__snapshots__/mime-type.test.js.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Jest Snapshot v1, https://goo.gl/fbAQLP
1+
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
22

33
exports[`MIME_TYPE should contain immutable HTML with correct value 1`] = `
44
[

test/conventions/__snapshots__/namespace.test.js.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Jest Snapshot v1, https://goo.gl/fbAQLP
1+
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
22

33
exports[`NAMESPACE should contain immutable HTML with correct value 1`] = `
44
[

test/dom-parser.test.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -187,15 +187,15 @@ describe('DOMParser', () => {
187187

188188
// warning
189189
expect(() => parser.parseFromString('<xml attr />', MIME_TYPE.XML_TEXT)).not.toThrow(ParseError);
190-
expect(onError).toBeCalledTimes(1);
190+
expect(onError).toHaveBeenCalledTimes(1);
191191
expect(onError).toHaveBeenCalledWith('warning', expect.anything(), expect.anything());
192192
// error
193193
expect(() => parser.parseFromString('<xml>&e;</xml>', MIME_TYPE.XML_TEXT)).toThrow(ParseError);
194-
expect(onError).toBeCalledTimes(2);
194+
expect(onError).toHaveBeenCalledTimes(2);
195195
expect(onError).toHaveBeenCalledWith('error', expect.anything(), expect.anything());
196196
// fatalError
197197
expect(() => parser.parseFromString('', MIME_TYPE.XML_TEXT)).toThrow(ParseError);
198-
expect(onError).toBeCalledTimes(3);
198+
expect(onError).toHaveBeenCalledTimes(3);
199199
expect(onError).toHaveBeenCalledWith('fatalError', expect.anything(), expect.anything());
200200
});
201201
test('should throw for level error when using onWarningStopParsing', () => {
@@ -204,15 +204,15 @@ describe('DOMParser', () => {
204204

205205
// warning
206206
expect(() => parser.parseFromString('<xml attr />', MIME_TYPE.XML_TEXT)).toThrow(ParseError);
207-
expect(onError).toBeCalledTimes(1);
207+
expect(onError).toHaveBeenCalledTimes(1);
208208
expect(onError).toHaveBeenCalledWith('warning', expect.anything(), expect.anything());
209209
// error
210210
expect(() => parser.parseFromString('<xml>&e;</xml>', MIME_TYPE.XML_TEXT)).toThrow(ParseError);
211-
expect(onError).toBeCalledTimes(2);
211+
expect(onError).toHaveBeenCalledTimes(2);
212212
expect(onError).toHaveBeenCalledWith('error', expect.anything(), expect.anything());
213213
// fatalError
214214
expect(() => parser.parseFromString('', MIME_TYPE.XML_TEXT)).toThrow(ParseError);
215-
expect(onError).toBeCalledTimes(3);
215+
expect(onError).toHaveBeenCalledTimes(3);
216216
expect(onError).toHaveBeenCalledWith('fatalError', expect.anything(), expect.anything());
217217
});
218218
test('should throw when errorHandler is not a function', () => {
@@ -222,7 +222,7 @@ describe('DOMParser', () => {
222222
var errorHandler = jest.fn();
223223
new DOMParser({ errorHandler });
224224

225-
expect(errorHandler).toBeCalledWith('warning', expect.stringContaining('onError'), expect.anything());
225+
expect(errorHandler).toHaveBeenCalledWith('warning', expect.stringContaining('onError'), expect.anything());
226226
});
227227
});
228228
});

test/dom/dom-implementation.test.js

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ describe('DOMImplementation', () => {
6262
expect(root.prefix).toBe(null);
6363
expect(root.localName).toBe(NAME);
6464
expect(doc.documentElement).toBe(root);
65+
expect(doc.childElementCount).toBe(1);
66+
expect(doc.firstElementChild).toBe(root);
67+
expect(doc.lastElementChild).toBe(root);
6568
expect(doc.contentType).toBe(MIME_TYPE.XML_APPLICATION);
6669
expect(doc.type).toBe('xml');
6770
});
@@ -80,6 +83,9 @@ describe('DOMImplementation', () => {
8083
expect(root.tagName).toBe(NAME);
8184

8285
expect(doc.documentElement).toBe(root);
86+
expect(doc.childElementCount).toBe(1);
87+
expect(doc.firstElementChild).toBe(root);
88+
expect(doc.lastElementChild).toBe(root);
8389
expect(doc.contentType).toBe(MIME_TYPE.XML_APPLICATION);
8490
expect(doc.type).toBe('xml');
8591
});
@@ -99,25 +105,9 @@ describe('DOMImplementation', () => {
99105
expect(root.tagName).toBe(qualifiedName);
100106

101107
expect(doc.documentElement).toBe(root);
102-
expect(doc.contentType).toBe(MIME_TYPE.XML_APPLICATION);
103-
expect(doc.type).toBe('xml');
104-
});
105-
106-
test('should create a Document with root element in a named namespace', () => {
107-
const impl = new DOMImplementation();
108-
const qualifiedName = `${PREFIX}:${NAME}`;
109-
const doc = impl.createDocument(NS, qualifiedName);
110-
111-
const root = doc.childNodes.item(0);
112-
expect(root).toBeInstanceOf(Element);
113-
expect(root.ownerDocument).toBe(doc);
114-
expect(root.namespaceURI).toBe(NS);
115-
expect(root.prefix).toBe(PREFIX);
116-
expect(root.localName).toBe(NAME);
117-
expect(root.nodeName).toBe(qualifiedName);
118-
expect(root.tagName).toBe(qualifiedName);
119-
120-
expect(doc.documentElement).toBe(root);
108+
expect(doc.childElementCount).toBe(1);
109+
expect(doc.firstElementChild).toBe(root);
110+
expect(doc.lastElementChild).toBe(root);
121111
expect(doc.contentType).toBe(MIME_TYPE.XML_APPLICATION);
122112
expect(doc.type).toBe('xml');
123113
});
@@ -142,6 +132,9 @@ describe('DOMImplementation', () => {
142132
expect(root.tagName).toBe(qualifiedName);
143133

144134
expect(doc.documentElement).toBe(root);
135+
expect(doc.childElementCount).toBe(1);
136+
expect(doc.firstElementChild).toBe(root);
137+
expect(doc.lastElementChild).toBe(root);
145138
expect(doc.contentType).toBe(MIME_TYPE.XML_APPLICATION);
146139
expect(doc.type).toBe('xml');
147140
});
@@ -210,6 +203,9 @@ describe('DOMImplementation', () => {
210203
expect(doc.doctype.ownerDocument).toBe(doc);
211204
expect(doc.childNodes.item(0)).toBe(doc.doctype);
212205
expect(doc.firstChild).toBe(doc.doctype);
206+
expect(doc.childElementCount).toBe(1);
207+
expect(doc.firstElementChild).toBe(doc.documentElement);
208+
expect(doc.lastElementChild).toBe(doc.documentElement);
213209

214210
expect(doc.documentElement).not.toBeNull();
215211
expect(doc.documentElement.localName).toBe('html');
@@ -219,10 +215,14 @@ describe('DOMImplementation', () => {
219215
expect(htmlNode.firstChild).not.toBeNull();
220216
expect(htmlNode.firstChild.nodeName).toBe('head');
221217
expect(htmlNode.firstChild.childNodes).toHaveLength(0);
218+
expect(htmlNode.firstElementChild).toBe(htmlNode.firstChild);
219+
expect(htmlNode.firstElementChild.nextElementSibling).toBe(htmlNode.lastChild);
222220

223221
expect(htmlNode.lastChild).not.toBeNull();
224222
expect(htmlNode.lastChild.nodeName).toBe('body');
225223
expect(htmlNode.lastChild.childNodes).toHaveLength(0);
224+
expect(htmlNode.lastElementChild).toBe(htmlNode.lastChild);
225+
expect(htmlNode.lastElementChild.previousElementSibling).toBe(htmlNode.firstChild);
226226
});
227227
test('should create an HTML document with specified elements including an empty title', () => {
228228
const impl = new DOMImplementation();

0 commit comments

Comments
 (0)