From cc53f27e4b04663bc31fb9844f0d82666b2e48fe Mon Sep 17 00:00:00 2001 From: Ruslan <40831934+flytestb@users.noreply.github.com> Date: Wed, 15 Feb 2023 20:57:05 +0100 Subject: [PATCH 1/2] Added colon to parsing attribute name Added colon to parsing attribute name for vue compatibility --- src/nodes/html.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nodes/html.ts b/src/nodes/html.ts index 4e45d7b..cc4064c 100644 --- a/src/nodes/html.ts +++ b/src/nodes/html.ts @@ -690,7 +690,7 @@ export default class HTMLElement extends Node { } const attrs = {} as RawAttributes; if (this.rawAttrs) { - const re = /([a-zA-Z()[\]#@$.?][a-zA-Z0-9-_:()[\]#]*)(?:\s*=\s*((?:'[^']*')|(?:"[^"]*")|\S+))?/g; + const re = /([a-zA-Z()[\]#@$.?:][a-zA-Z0-9-_:()[\]#]*)(?:\s*=\s*((?:'[^']*')|(?:"[^"]*")|\S+))?/g; let match: RegExpExecArray; while ((match = re.exec(this.rawAttrs))) { const key = match[1]; From 8c11f858586decca43ea690ec9c36244ab9c9eb2 Mon Sep 17 00:00:00 2001 From: Benn Bollay Date: Sat, 18 Feb 2023 14:59:53 -0800 Subject: [PATCH 2/2] First attribute in a tag wins The HTML specification nominally does not allow duplicate attributes in a tag (see 13.1.2.3, last paragraph). However, browsers fail graciously when encountering such a tag, respecting only the first tag present and discarding subsequent duplicates (Safari 17614.1.25.9.10, Chrome 109.0.5414.119). Bring node-html-parser in alignment with that convention, respecting the first attribute and ignoring subsequent matches. --- src/nodes/html.ts | 2 +- test/tests/html.js | 5 +++++ test/tests/issues/224.js | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/nodes/html.ts b/src/nodes/html.ts index 4e45d7b..3280293 100644 --- a/src/nodes/html.ts +++ b/src/nodes/html.ts @@ -696,7 +696,7 @@ export default class HTMLElement extends Node { const key = match[1]; let val = match[2] || null; if (val && (val[0] === `'` || val[0] === `"`)) val = val.slice(1, val.length - 1); - attrs[key] = val; + attrs[key] = attrs[key] || val; } } this._rawAttrs = attrs; diff --git a/test/tests/html.js b/test/tests/html.js index de006b2..2ccbc04 100644 --- a/test/tests/html.js +++ b/test/tests/html.js @@ -333,6 +333,11 @@ describe('HTML Parser', function () { root.firstChild.getAttribute('a').should.eql('a1b'); }); + it('should return value of the first attribute', function () { + const root = parseHTML('

'); + root.firstChild.getAttribute('a').should.eql('a1b'); + }); + it('should return null when there is no such attribute', function () { const root = parseHTML('

'); should.equal(root.firstChild.getAttribute('b'), null); diff --git a/test/tests/issues/224.js b/test/tests/issues/224.js index 523a590..532f71b 100644 --- a/test/tests/issues/224.js +++ b/test/tests/issues/224.js @@ -1,7 +1,7 @@ const fs = require('fs'); const { parse } = require('@test/test-target'); -describe.only('issue 224', function () { +describe('issue 224', function () { it('query', function () { const html = fs.readFileSync(__dirname + '/../../assets/html/melon.html', 'utf-8'); const root = parse(html);