Skip to content

Commit b286af8

Browse files
committedDec 26, 2024
Merge branch 'fix/support-attributes-with-dots' of github.com:callmephilip/node-html-parser
2 parents 8772285 + 32a4daf commit b286af8

File tree

2 files changed

+60
-14
lines changed

2 files changed

+60
-14
lines changed
 

‎src/nodes/html.ts

+16-14
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,11 @@ export default class HTMLElement extends Node {
159159
return 'null';
160160
}
161161

162-
return JSON.stringify(attr.replace(/"/g, '"')).replace(/\\t/g, '\t').replace(/\\n/g, '\n').replace(/\\r/g, '\r').replace(/\\/g, '');
162+
return JSON.stringify(attr.replace(/"/g, '"'))
163+
.replace(/\\t/g, '\t')
164+
.replace(/\\n/g, '\n')
165+
.replace(/\\r/g, '\r')
166+
.replace(/\\/g, '');
163167
}
164168

165169
/**
@@ -373,11 +377,7 @@ export default class HTMLElement extends Node {
373377
return child === this;
374378
});
375379
resetParent([this], null);
376-
parent.childNodes = [
377-
...parent.childNodes.slice(0, idx),
378-
...resetParent(content, parent),
379-
...parent.childNodes.slice(idx + 1),
380-
];
380+
parent.childNodes = [...parent.childNodes.slice(0, idx), ...resetParent(content, parent), ...parent.childNodes.slice(idx + 1)];
381381
return this;
382382
}
383383

@@ -456,10 +456,12 @@ export default class HTMLElement extends Node {
456456
this.childNodes.length = o;
457457

458458
// remove whitespace between attributes
459-
const attrs = Object.keys(this.rawAttributes).map((key) => {
460-
const val = this.rawAttributes[key];
461-
return `${key}=${JSON.stringify(val)}`;
462-
}).join(' ');
459+
const attrs = Object.keys(this.rawAttributes)
460+
.map((key) => {
461+
const val = this.rawAttributes[key];
462+
return `${key}=${JSON.stringify(val)}`;
463+
})
464+
.join(' ');
463465
this.rawAttrs = attrs;
464466
delete this._rawAttrs;
465467
return this;
@@ -565,7 +567,7 @@ export default class HTMLElement extends Node {
565567
if (child.nodeType === NodeType.ELEMENT_NODE) {
566568
if (child.id === id) {
567569
return child;
568-
};
570+
}
569571

570572
// if children are existing push the current status to the stack and keep searching for elements in the level below
571573
if (child.childNodes.length > 0) {
@@ -686,7 +688,7 @@ export default class HTMLElement extends Node {
686688
}
687689
const attrs = {} as RawAttributes;
688690
if (this.rawAttrs) {
689-
const re = /([a-zA-Z()[\]#@$.?:][a-zA-Z0-9-_:()[\]#]*)(?:\s*=\s*((?:'[^']*')|(?:"[^"]*")|\S+))?/g;
691+
const re = /([a-zA-Z()[\]#@$.?:][a-zA-Z0-9-._:()[\]#]*)(?:\s*=\s*((?:'[^']*')|(?:"[^"]*")|\S+))?/g;
690692
let match: RegExpExecArray;
691693
while ((match = re.exec(this.rawAttrs))) {
692694
const key = match[1];
@@ -1025,7 +1027,7 @@ export interface Options {
10251027
* void tag serialisation, add a final slash <br/>
10261028
*/
10271029
closingSlash?: boolean;
1028-
}
1030+
};
10291031
}
10301032

10311033
const frameflag = 'documentfragmentcontainer';
@@ -1249,7 +1251,7 @@ export function parse(data: string, options = {} as Partial<Options>) {
12491251
* and removes nodes from any potential parent.
12501252
*/
12511253
function resolveInsertable(insertable: NodeInsertable[]): Node[] {
1252-
return insertable.map(val => {
1254+
return insertable.map((val) => {
12531255
if (typeof val === 'string') {
12541256
return new TextNode(val);
12551257
}

‎test/tests/attributes-with-dots.js

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
const { parse } = require('@test/test-target');
2+
3+
describe('funky attributes', function () {
4+
it('x-transition.duration.500ms', function () {
5+
const root = parse('<div x-transition.duration.500ms></div>');
6+
const div = root.firstChild;
7+
div.getAttribute('x-transition.duration.500ms').should.eql('');
8+
div.toString().should.eql('<div x-transition.duration.500ms></div>');
9+
});
10+
11+
it('x-transition:enter.duration.500ms and x-transition:leave.duration.400ms', function () {
12+
const root = parse('<div x-transition:enter.duration.500ms x-transition:leave.duration.400ms></div>');
13+
const div = root.firstChild;
14+
div.getAttribute('x-transition:enter.duration.500ms').should.eql('');
15+
div.getAttribute('x-transition:leave.duration.400ms').should.eql('');
16+
div.toString().should.eql('<div x-transition:enter.duration.500ms x-transition:leave.duration.400ms></div>');
17+
});
18+
19+
it('@click="open = ! open"', function () {
20+
const root = parse('<button @click="open = ! open">Toggle</button>');
21+
const div = root.firstChild;
22+
div.getAttribute('@click').should.eql('open = ! open');
23+
div.toString().should.eql('<button @click="open = ! open">Toggle</button>');
24+
});
25+
26+
it('a bunch of stuff at the same time', function () {
27+
const root = parse(
28+
'<div x-show="open" x-transition:enter="transition ease-out duration-300" x-transition:enter-start="opacity-0 scale-90" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-in duration-300" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-90">Hello 👋</div>'
29+
);
30+
const div = root.firstChild;
31+
32+
div.getAttribute('x-show').should.eql('open');
33+
div.getAttribute('x-transition:enter').should.eql('transition ease-out duration-300');
34+
div.getAttribute('x-transition:enter-start').should.eql('opacity-0 scale-90');
35+
div.getAttribute('x-transition:enter-end').should.eql('opacity-100 scale-100');
36+
div.getAttribute('x-transition:leave').should.eql('transition ease-in duration-300');
37+
div.getAttribute('x-transition:leave-start').should.eql('opacity-100 scale-100');
38+
div.getAttribute('x-transition:leave-end').should.eql('opacity-0 scale-90');
39+
40+
div.toString().should.eql(
41+
'<div x-show="open" x-transition:enter="transition ease-out duration-300" x-transition:enter-start="opacity-0 scale-90" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-in duration-300" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-90">Hello 👋</div>'
42+
);
43+
});
44+
});

0 commit comments

Comments
 (0)
Please sign in to comment.