Skip to content

Commit 9f379ac

Browse files
committed
add use: syntax for directive
1 parent dcfdc96 commit 9f379ac

File tree

6 files changed

+84
-7
lines changed

6 files changed

+84
-7
lines changed

jest.config.js

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/** @type {import('jest').Config} */
2+
export default {
3+
testEnvironment: "jsdom"
4+
}

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
"main": "lib/index.js",
66
"module": "dist/index.js",
77
"types": "types/index.d.ts",
8+
"type": "module",
89
"scripts": {
910
"build": "rollup -c",
1011
"prepublishOnly": "npm run build",
11-
"test": "echo \"Error: no test specified\" && exit 1",
12+
"test": "NODE_OPTIONS='--experimental-vm-modules $NODE_OPTIONS' jest",
1213
"prepare": "npm run build"
1314
},
1415
"repository": {

src/parse.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ function parseTag(/**@type {string}*/tag) {
3939
type: 'tag',
4040
name: '',
4141
voidElement: false,
42-
attrs: {},
42+
attrs: [],
4343
children: []
4444
};
4545
const tagMatch = tag.match(/<\/?([^\s]+?)[/\s>]/)
@@ -68,8 +68,11 @@ function parseTag(/**@type {string}*/tag) {
6868
// TODO named groups method not working yet, groups is undefined in tests (maybe not out in Node.js yet)
6969
// const groups = match.groups
7070
// res.attrs[groups.boolean || groups.name] = groups.value1 || groups.value2 || ""
71-
72-
res.attrs[match[1] || match[2]] = match[4] || match[5] || ''
71+
if ((match[1] || match[2]).startsWith('use:')) {
72+
res.attrs.push({ type: 'directive', name: match[1] || match[2], value: match[4] || match[5] || '' });
73+
} else {
74+
res.attrs.push({ type: 'attr', name: match[1] || match[2], value: match[4] || match[5] || '' });
75+
}
7376
}
7477

7578
return res

src/stringify.js

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
// Based on package html-parse-stringify2
22
// Expanded to handle webcomponents
33

4+
/**
5+
* @param {import('../types/index').IDom['attrs']} attrs
6+
* @returns {string}
7+
*/
48
function attrString(attrs) {
59
const buff = [];
6-
for (const key in attrs) {
7-
buff.push(key + '="' + attrs[key].replace(/"/g, '&quot;') + '"');
10+
for (const attr of attrs) {
11+
buff.push(attr.name + '="' + attr.value.replace(/"/g, '&quot;') + '"');
812
}
913
if (!buff.length) {
1014
return '';
1115
}
1216
return ' ' + buff.join(' ');
1317
};
1418

19+
/**
20+
* @param {string} buff
21+
* @param {import('../types/index').IDom} doc
22+
* @returns {string}
23+
*/
1524
function stringifier(buff, doc) {
1625
switch (doc.type) {
1726
case 'text':
@@ -27,6 +36,10 @@ function stringifier(buff, doc) {
2736
}
2837
};
2938

39+
/**
40+
* @param {import('../types/index').IDom[]} doc
41+
* @returns {string}
42+
*/
3043
export function stringify(doc) {
3144
return doc.reduce(function (token, rootEl) {
3245
return token + stringifier('', rootEl);

test/parse.spec.js

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { parse } from "../src";
2+
3+
describe("parse", () => {
4+
test("Simple div", () => {
5+
const html = "<div asd=23 qwe=\"1243423\"></div>";
6+
const result = parse(html);
7+
expect(result).toEqual([
8+
{
9+
type: "tag",
10+
name: "div",
11+
attrs: [
12+
{ name: "asd", value: "23", type: 'attr' },
13+
{ name: "qwe", value: "1243423", type: 'attr' }
14+
],
15+
children: [],
16+
voidElement: false
17+
}
18+
]);
19+
});
20+
21+
test("With dynamic content", () => {
22+
const html = "<div qwe=#23#>###</div>";
23+
const result = parse(html);
24+
expect(result).toEqual([
25+
{
26+
type: "tag",
27+
name: "div",
28+
attrs: [
29+
{ name: "qwe", value: "#23#", type: 'attr' }
30+
],
31+
children: [
32+
{ type: "text", content: "###" }
33+
],
34+
voidElement: false
35+
}
36+
]);
37+
});
38+
39+
test("With use effect", () => {
40+
const html = "<div use:#1#=#2#>#3#</div>";
41+
const result = parse(html);
42+
expect(result).toEqual([
43+
{
44+
type: "tag",
45+
name: "div",
46+
attrs: [
47+
{ name: "use:#1#", value: "#2#", type: 'directive' }
48+
],
49+
children: [
50+
{ type: "text", content: "#3#" }
51+
],
52+
voidElement: false
53+
}
54+
]);
55+
});
56+
});

types/index.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ export interface IDom {
33
content ? : string;
44
voidElement: boolean;
55
name: string;
6-
attrs: { [key: string]: any };
6+
attrs: { type: 'attr' | 'directive', name: string, value: string}[];
77
children: IDom[];
88
}
99

0 commit comments

Comments
 (0)