@solidjs/html 2.0.0-experimental.1 → 2.0.0-experimental.2
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/LICENSE +1 -1
- package/dist/html.cjs +3 -3
- package/dist/html.js +198 -91
- package/package.json +2 -2
- package/types/index.d.ts +0 -3
- package/types/lit.d.ts +0 -57
package/LICENSE
CHANGED
package/dist/html.cjs
CHANGED
|
@@ -64,7 +64,7 @@ function parseTag(tag) {
|
|
|
64
64
|
}
|
|
65
65
|
function pushTextNode(list, html, start) {
|
|
66
66
|
const end = html.indexOf('<', start);
|
|
67
|
-
const content = html.slice(start, end === -1 ?
|
|
67
|
+
const content = html.slice(start, end === -1 ? undefined : end);
|
|
68
68
|
if (!/^\s*$/.test(content)) {
|
|
69
69
|
list.push({
|
|
70
70
|
type: 'text',
|
|
@@ -83,7 +83,7 @@ function pushCommentNode(list, tag) {
|
|
|
83
83
|
}
|
|
84
84
|
function parse(html) {
|
|
85
85
|
const result = [];
|
|
86
|
-
let current =
|
|
86
|
+
let current = undefined;
|
|
87
87
|
let level = -1;
|
|
88
88
|
const arr = [];
|
|
89
89
|
const byTag = {};
|
|
@@ -92,7 +92,7 @@ function parse(html) {
|
|
|
92
92
|
const isComment = tag.slice(0, 4) === '<!--';
|
|
93
93
|
const start = index + tag.length;
|
|
94
94
|
const nextChar = html.charAt(start);
|
|
95
|
-
let parent =
|
|
95
|
+
let parent = undefined;
|
|
96
96
|
if (isOpen && !isComment) {
|
|
97
97
|
level++;
|
|
98
98
|
current = parseTag(tag);
|
package/dist/html.js
CHANGED
|
@@ -1,7 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
effect,
|
|
3
|
+
style,
|
|
4
|
+
insert,
|
|
5
|
+
untrack,
|
|
6
|
+
spread,
|
|
7
|
+
createComponent,
|
|
8
|
+
delegateEvents,
|
|
9
|
+
className,
|
|
10
|
+
mergeProps,
|
|
11
|
+
dynamicProperty,
|
|
12
|
+
setAttribute,
|
|
13
|
+
setAttributeNS,
|
|
14
|
+
addEventListener,
|
|
15
|
+
getPropAlias,
|
|
16
|
+
Properties,
|
|
17
|
+
ChildProperties,
|
|
18
|
+
DelegatedEvents,
|
|
19
|
+
SVGElements,
|
|
20
|
+
SVGNamespace
|
|
21
|
+
} from "@solidjs/web";
|
|
2
22
|
|
|
3
23
|
const tagRE = /(?:<!--[\S\s]*?-->|<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>)/g;
|
|
4
|
-
const attrRE =
|
|
24
|
+
const attrRE =
|
|
25
|
+
/(?:\s(?<boolean>[^/\s><=]+?)(?=[\s/>]))|(?:(?<name>\S+?)(?:\s*=\s*(?:(['"])(?<quotedValue>[\s\S]*?)\3|(?<unquotedValue>[^\s>]+))))/g;
|
|
5
26
|
const lookup = {
|
|
6
27
|
area: true,
|
|
7
28
|
base: true,
|
|
@@ -22,8 +43,8 @@ const lookup = {
|
|
|
22
43
|
};
|
|
23
44
|
function parseTag(tag) {
|
|
24
45
|
const res = {
|
|
25
|
-
type:
|
|
26
|
-
name:
|
|
46
|
+
type: "tag",
|
|
47
|
+
name: "",
|
|
27
48
|
voidElement: false,
|
|
28
49
|
attrs: [],
|
|
29
50
|
children: []
|
|
@@ -31,70 +52,70 @@ function parseTag(tag) {
|
|
|
31
52
|
const tagMatch = tag.match(/<\/?([^\s]+?)[/\s>]/);
|
|
32
53
|
if (tagMatch) {
|
|
33
54
|
res.name = tagMatch[1];
|
|
34
|
-
if (lookup[tagMatch[1].toLowerCase()] || tag.charAt(tag.length - 2) ===
|
|
55
|
+
if (lookup[tagMatch[1].toLowerCase()] || tag.charAt(tag.length - 2) === "/") {
|
|
35
56
|
res.voidElement = true;
|
|
36
57
|
}
|
|
37
|
-
if (res.name.startsWith(
|
|
38
|
-
const endIndex = tag.indexOf(
|
|
58
|
+
if (res.name.startsWith("!--")) {
|
|
59
|
+
const endIndex = tag.indexOf("-->");
|
|
39
60
|
return {
|
|
40
|
-
type:
|
|
41
|
-
comment: endIndex !== -1 ? tag.slice(4, endIndex) :
|
|
61
|
+
type: "comment",
|
|
62
|
+
comment: endIndex !== -1 ? tag.slice(4, endIndex) : ""
|
|
42
63
|
};
|
|
43
64
|
}
|
|
44
65
|
}
|
|
45
66
|
const reg = new RegExp(attrRE);
|
|
46
67
|
for (const match of tag.matchAll(reg)) {
|
|
47
|
-
if ((match[1] || match[2]).startsWith(
|
|
68
|
+
if ((match[1] || match[2]).startsWith("use:")) {
|
|
48
69
|
res.attrs.push({
|
|
49
|
-
type:
|
|
70
|
+
type: "directive",
|
|
50
71
|
name: match[1] || match[2],
|
|
51
|
-
value: match[4] || match[5] ||
|
|
72
|
+
value: match[4] || match[5] || ""
|
|
52
73
|
});
|
|
53
74
|
} else {
|
|
54
75
|
res.attrs.push({
|
|
55
|
-
type:
|
|
76
|
+
type: "attr",
|
|
56
77
|
name: match[1] || match[2],
|
|
57
|
-
value: match[4] || match[5] ||
|
|
78
|
+
value: match[4] || match[5] || ""
|
|
58
79
|
});
|
|
59
80
|
}
|
|
60
81
|
}
|
|
61
82
|
return res;
|
|
62
83
|
}
|
|
63
84
|
function pushTextNode(list, html, start) {
|
|
64
|
-
const end = html.indexOf(
|
|
65
|
-
const content = html.slice(start, end === -1 ?
|
|
85
|
+
const end = html.indexOf("<", start);
|
|
86
|
+
const content = html.slice(start, end === -1 ? undefined : end);
|
|
66
87
|
if (!/^\s*$/.test(content)) {
|
|
67
88
|
list.push({
|
|
68
|
-
type:
|
|
89
|
+
type: "text",
|
|
69
90
|
content: content
|
|
70
91
|
});
|
|
71
92
|
}
|
|
72
93
|
}
|
|
73
94
|
function pushCommentNode(list, tag) {
|
|
74
|
-
const content = tag.replace(
|
|
95
|
+
const content = tag.replace("<!--", "").replace("-->", "");
|
|
75
96
|
if (!/^\s*$/.test(content)) {
|
|
76
97
|
list.push({
|
|
77
|
-
type:
|
|
98
|
+
type: "comment",
|
|
78
99
|
content: content
|
|
79
100
|
});
|
|
80
101
|
}
|
|
81
102
|
}
|
|
82
103
|
function parse(html) {
|
|
83
104
|
const result = [];
|
|
84
|
-
let current =
|
|
105
|
+
let current = undefined;
|
|
85
106
|
let level = -1;
|
|
86
107
|
const arr = [];
|
|
87
108
|
const byTag = {};
|
|
88
109
|
html.replace(tagRE, (tag, index) => {
|
|
89
|
-
const isOpen = tag.charAt(1) !==
|
|
90
|
-
const isComment = tag.slice(0, 4) ===
|
|
110
|
+
const isOpen = tag.charAt(1) !== "/";
|
|
111
|
+
const isComment = tag.slice(0, 4) === "<!--";
|
|
91
112
|
const start = index + tag.length;
|
|
92
113
|
const nextChar = html.charAt(start);
|
|
93
|
-
let parent =
|
|
114
|
+
let parent = undefined;
|
|
94
115
|
if (isOpen && !isComment) {
|
|
95
116
|
level++;
|
|
96
117
|
current = parseTag(tag);
|
|
97
|
-
if (!current.voidElement && nextChar && nextChar !==
|
|
118
|
+
if (!current.voidElement && nextChar && nextChar !== "<") {
|
|
98
119
|
pushTextNode(current.children, html, start);
|
|
99
120
|
}
|
|
100
121
|
byTag[current.tagName] = current;
|
|
@@ -118,7 +139,7 @@ function parse(html) {
|
|
|
118
139
|
if (!isComment) {
|
|
119
140
|
level--;
|
|
120
141
|
}
|
|
121
|
-
if (nextChar !==
|
|
142
|
+
if (nextChar !== "<" && nextChar) {
|
|
122
143
|
parent = level === -1 ? result : arr[level].children;
|
|
123
144
|
pushTextNode(parent, html, start);
|
|
124
145
|
}
|
|
@@ -129,41 +150,47 @@ function parse(html) {
|
|
|
129
150
|
function attrString(attrs) {
|
|
130
151
|
const buff = [];
|
|
131
152
|
for (const attr of attrs) {
|
|
132
|
-
buff.push(attr.name + '="' + attr.value.replace(/"/g,
|
|
153
|
+
buff.push(attr.name + '="' + attr.value.replace(/"/g, """) + '"');
|
|
133
154
|
}
|
|
134
155
|
if (!buff.length) {
|
|
135
|
-
return
|
|
156
|
+
return "";
|
|
136
157
|
}
|
|
137
|
-
return
|
|
158
|
+
return " " + buff.join(" ");
|
|
138
159
|
}
|
|
139
160
|
function stringifier(buff, doc) {
|
|
140
161
|
switch (doc.type) {
|
|
141
|
-
case
|
|
162
|
+
case "text":
|
|
142
163
|
return buff + doc.content;
|
|
143
|
-
case
|
|
144
|
-
buff +=
|
|
164
|
+
case "tag":
|
|
165
|
+
buff +=
|
|
166
|
+
"<" + doc.name + (doc.attrs ? attrString(doc.attrs) : "") + (doc.voidElement ? "/>" : ">");
|
|
145
167
|
if (doc.voidElement) {
|
|
146
168
|
return buff;
|
|
147
169
|
}
|
|
148
|
-
return buff + doc.children.reduce(stringifier,
|
|
149
|
-
case
|
|
150
|
-
return buff +=
|
|
170
|
+
return buff + doc.children.reduce(stringifier, "") + "</" + doc.name + ">";
|
|
171
|
+
case "comment":
|
|
172
|
+
return (buff += "<!--" + doc.content + "-->");
|
|
151
173
|
}
|
|
152
174
|
}
|
|
153
175
|
function stringify(doc) {
|
|
154
176
|
return doc.reduce(function (token, rootEl) {
|
|
155
|
-
return token + stringifier(
|
|
156
|
-
},
|
|
177
|
+
return token + stringifier("", rootEl);
|
|
178
|
+
}, "");
|
|
157
179
|
}
|
|
158
180
|
const cache = new Map();
|
|
159
|
-
const VOID_ELEMENTS =
|
|
181
|
+
const VOID_ELEMENTS =
|
|
182
|
+
/^(?:area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)$/i;
|
|
160
183
|
const spaces = " \\f\\n\\r\\t";
|
|
161
184
|
const almostEverything = "[^" + spaces + "\\/>\"'=]+";
|
|
162
185
|
const attrName = "[ " + spaces + "]+(?:use:<!--#-->|" + almostEverything + ")";
|
|
163
186
|
const tagName = "<([A-Za-z$#]+[A-Za-z0-9:_-]*)((?:";
|
|
164
|
-
const attrPartials =
|
|
187
|
+
const attrPartials =
|
|
188
|
+
"(?:\\s*=\\s*(?:'[^']*?'|\"[^\"]*?\"|\\([^)]*?\\)|<[^>]*?>|" + almostEverything + "))?)";
|
|
165
189
|
const attrSeeker = new RegExp(tagName + attrName + attrPartials + "+)([ " + spaces + "]*/?>)", "g");
|
|
166
|
-
const findAttributes = new RegExp(
|
|
190
|
+
const findAttributes = new RegExp(
|
|
191
|
+
"(" + attrName + "\\s*=\\s*)(<!--#-->|['\"(]([\\w\\s]*<!--#-->[\\w\\s]*)*['\")])",
|
|
192
|
+
"gi"
|
|
193
|
+
);
|
|
167
194
|
const selfClosing = new RegExp(tagName + attrName + attrPartials + "*)([ " + spaces + "]*/>)", "g");
|
|
168
195
|
const marker = "<!--#-->";
|
|
169
196
|
const reservedNameSpaces = new Set(["class", "on", "style", "use", "prop", "attr"]);
|
|
@@ -171,7 +198,10 @@ function attrReplacer($0, $1, $2, $3) {
|
|
|
171
198
|
return "<" + $1 + $2.replace(findAttributes, replaceAttributes) + $3;
|
|
172
199
|
}
|
|
173
200
|
function replaceAttributes($0, $1, $2) {
|
|
174
|
-
return
|
|
201
|
+
return (
|
|
202
|
+
$1.replace(/<!--#-->/g, "###") +
|
|
203
|
+
($2[0] === '"' || $2[0] === "'" ? $2.replace(/<!--#-->/g, "###") : '"###"')
|
|
204
|
+
);
|
|
175
205
|
}
|
|
176
206
|
function fullClosing($0, $1, $2) {
|
|
177
207
|
return VOID_ELEMENTS.test($1) ? $0 : "<" + $1 + $2 + "></" + $1 + ">";
|
|
@@ -179,15 +209,17 @@ function fullClosing($0, $1, $2) {
|
|
|
179
209
|
function parseDirective(name, value, tag, options) {
|
|
180
210
|
if (name === "use:###" && value === "###") {
|
|
181
211
|
const count = options.counter++;
|
|
182
|
-
options.exprs.push(
|
|
212
|
+
options.exprs.push(
|
|
213
|
+
`typeof exprs[${count}] === "function" ? r.use(exprs[${count}], ${tag}, exprs[${options.counter++}]) : (()=>{throw new Error("use:### must be a function")})()`
|
|
214
|
+
);
|
|
183
215
|
} else {
|
|
184
216
|
throw new Error(`Not support syntax ${name} must be use:{function}`);
|
|
185
217
|
}
|
|
186
218
|
}
|
|
187
|
-
function createHTML(
|
|
188
|
-
|
|
189
|
-
functionBuilder = (...args) => new Function(...args)
|
|
190
|
-
|
|
219
|
+
function createHTML(
|
|
220
|
+
r,
|
|
221
|
+
{ delegateEvents = true, functionBuilder = (...args) => new Function(...args) } = {}
|
|
222
|
+
) {
|
|
191
223
|
let uuid = 1;
|
|
192
224
|
r.wrapProps = props => {
|
|
193
225
|
const d = Object.getOwnPropertyDescriptors(props);
|
|
@@ -196,7 +228,7 @@ function createHTML(r, {
|
|
|
196
228
|
}
|
|
197
229
|
return props;
|
|
198
230
|
};
|
|
199
|
-
r.resolveFn = fn => typeof fn === "function" ? fn() : fn;
|
|
231
|
+
r.resolveFn = fn => (typeof fn === "function" ? fn() : fn);
|
|
200
232
|
function createTemplate(statics, opt) {
|
|
201
233
|
let i = 0,
|
|
202
234
|
markup = "";
|
|
@@ -204,7 +236,16 @@ function createHTML(r, {
|
|
|
204
236
|
markup = markup + statics[i] + "<!--#-->";
|
|
205
237
|
}
|
|
206
238
|
markup = markup + statics[i];
|
|
207
|
-
const replaceList = [
|
|
239
|
+
const replaceList = [
|
|
240
|
+
[selfClosing, fullClosing],
|
|
241
|
+
[/<(<!--#-->)/g, "<###"],
|
|
242
|
+
[/\.\.\.(<!--#-->)/g, "###"],
|
|
243
|
+
[attrSeeker, attrReplacer],
|
|
244
|
+
[/>\n+\s*/g, ">"],
|
|
245
|
+
[/\n+\s*</g, "<"],
|
|
246
|
+
[/\s+</g, " <"],
|
|
247
|
+
[/>\s+/g, "> "]
|
|
248
|
+
];
|
|
208
249
|
markup = replaceList.reduce((acc, x) => {
|
|
209
250
|
return acc.replace(x[0], x[1]);
|
|
210
251
|
}, markup);
|
|
@@ -239,7 +280,7 @@ function createHTML(r, {
|
|
|
239
280
|
} else {
|
|
240
281
|
const chunks = value.split("###");
|
|
241
282
|
options.counter = chunks.length - 1 + options.counter;
|
|
242
|
-
expr = chunks.map((v, i) => i ? ` + _$v[${i - 1}] + "${v}"` : `"${v}"`).join("");
|
|
283
|
+
expr = chunks.map((v, i) => (i ? ` + _$v[${i - 1}] + "${v}"` : `"${v}"`)).join("");
|
|
243
284
|
}
|
|
244
285
|
if ((parts = name.split(":")) && parts[1] && reservedNameSpaces.has(parts[0])) {
|
|
245
286
|
name = parts[1];
|
|
@@ -251,11 +292,19 @@ function createHTML(r, {
|
|
|
251
292
|
options.exprs.push(`r.style(${tag},${expr},_$p)`);
|
|
252
293
|
} else if (name === "class") {
|
|
253
294
|
options.exprs.push(`r.className(${tag},${expr},${isSVG},_$p)`);
|
|
254
|
-
} else if (
|
|
255
|
-
|
|
295
|
+
} else if (
|
|
296
|
+
namespace !== "attr" &&
|
|
297
|
+
(isChildProp ||
|
|
298
|
+
(!isSVG && (r.getPropAlias(name, node.name.toUpperCase()) || isProp)) ||
|
|
299
|
+
namespace === "prop")
|
|
300
|
+
) {
|
|
301
|
+
options.exprs.push(
|
|
302
|
+
`${tag}.${r.getPropAlias(name, node.name.toUpperCase()) || name} = ${expr}`
|
|
303
|
+
);
|
|
256
304
|
} else {
|
|
257
305
|
const ns = isSVG && name.indexOf(":") > -1 && r.SVGNamespace[name.split(":")[0]];
|
|
258
|
-
if (ns) options.exprs.push(`r.setAttributeNS(${tag},"${ns}","${name}",${expr})`);
|
|
306
|
+
if (ns) options.exprs.push(`r.setAttributeNS(${tag},"${ns}","${name}",${expr})`);
|
|
307
|
+
else options.exprs.push(`r.setAttribute(${tag},"${name}",${expr})`);
|
|
259
308
|
}
|
|
260
309
|
}
|
|
261
310
|
function parseAttribute(node, tag, name, value, isSVG, options) {
|
|
@@ -263,10 +312,14 @@ function createHTML(r, {
|
|
|
263
312
|
if (!name.includes(":")) {
|
|
264
313
|
const lc = name.slice(2).toLowerCase();
|
|
265
314
|
const delegate = delegateEvents && r.DelegatedEvents.has(lc);
|
|
266
|
-
options.exprs.push(
|
|
315
|
+
options.exprs.push(
|
|
316
|
+
`r.addEventListener(${tag},"${lc}",exprs[${options.counter++}],${delegate})`
|
|
317
|
+
);
|
|
267
318
|
delegate && options.delegatedEvents.add(lc);
|
|
268
319
|
} else {
|
|
269
|
-
options.exprs.push(
|
|
320
|
+
options.exprs.push(
|
|
321
|
+
`${tag}.addEventListener("${name.slice(3)}",exprs[${options.counter++}])`
|
|
322
|
+
);
|
|
270
323
|
}
|
|
271
324
|
} else if (name === "ref") {
|
|
272
325
|
options.exprs.push(`exprs[${options.counter++}](${tag})`);
|
|
@@ -278,7 +331,9 @@ function createHTML(r, {
|
|
|
278
331
|
parseKeyValue(node, tag, name, value, isSVG, childOptions);
|
|
279
332
|
options.decl.push(`_fn${count} = (_$v, _$p) => {\n${childOptions.exprs.join(";\n")};\n}`);
|
|
280
333
|
if (value === "###") {
|
|
281
|
-
options.exprs.push(
|
|
334
|
+
options.exprs.push(
|
|
335
|
+
`typeof exprs[${count}] === "function" ? r.effect(() => exprs[${count}](), _fn${count}) : _fn${count}(exprs[${count}])`
|
|
336
|
+
);
|
|
282
337
|
} else {
|
|
283
338
|
let check = "";
|
|
284
339
|
let list = "";
|
|
@@ -293,7 +348,9 @@ function createHTML(r, {
|
|
|
293
348
|
list += `exprs[${i}]`;
|
|
294
349
|
reactiveList += `r.resolveFn(exprs[${i}])`;
|
|
295
350
|
}
|
|
296
|
-
options.exprs.push(
|
|
351
|
+
options.exprs.push(
|
|
352
|
+
check + ` ? r.effect(() => [${reactiveList}], _fn${count}) : _fn${count}([${list}])`
|
|
353
|
+
);
|
|
297
354
|
}
|
|
298
355
|
options.counter = childOptions.counter;
|
|
299
356
|
options.wrap = false;
|
|
@@ -308,7 +365,10 @@ function createHTML(r, {
|
|
|
308
365
|
if (node.children.length > 1) {
|
|
309
366
|
for (let i = 0; i < node.children.length; i++) {
|
|
310
367
|
const child = node.children[i];
|
|
311
|
-
if (
|
|
368
|
+
if (
|
|
369
|
+
(child.type === "comment" && child.content === "#") ||
|
|
370
|
+
(child.type === "tag" && child.name === "###")
|
|
371
|
+
) {
|
|
312
372
|
childOptions.multi = true;
|
|
313
373
|
break;
|
|
314
374
|
}
|
|
@@ -329,7 +389,9 @@ function createHTML(r, {
|
|
|
329
389
|
continue;
|
|
330
390
|
}
|
|
331
391
|
parseNode(child, childOptions);
|
|
332
|
-
if (!childOptions.multi && child.type === "comment" && child.content === "#")
|
|
392
|
+
if (!childOptions.multi && child.type === "comment" && child.content === "#")
|
|
393
|
+
node.children.splice(i, 1);
|
|
394
|
+
else i++;
|
|
333
395
|
}
|
|
334
396
|
options.counter = childOptions.counter;
|
|
335
397
|
options.templateId = childOptions.templateId;
|
|
@@ -352,26 +414,28 @@ function createHTML(r, {
|
|
|
352
414
|
propGroups = [props],
|
|
353
415
|
componentIdentifier = options.counter++;
|
|
354
416
|
for (let i = 0; i < keys.length; i++) {
|
|
355
|
-
const {
|
|
356
|
-
type,
|
|
357
|
-
name,
|
|
358
|
-
value
|
|
359
|
-
} = node.attrs[i];
|
|
417
|
+
const { type, name, value } = node.attrs[i];
|
|
360
418
|
if (type === "attr") {
|
|
361
419
|
if (name === "###") {
|
|
362
420
|
propGroups.push(`exprs[${options.counter++}]`);
|
|
363
|
-
propGroups.push(props = []);
|
|
421
|
+
propGroups.push((props = []));
|
|
364
422
|
} else if (value === "###") {
|
|
365
423
|
props.push(`${name}: exprs[${options.counter++}]`);
|
|
366
424
|
} else props.push(`${name}: "${value}"`);
|
|
367
425
|
} else if (type === "directive") {
|
|
368
426
|
const tag = `_$el${uuid++}`;
|
|
369
427
|
const topDecl = !options.decl.length;
|
|
370
|
-
options.decl.push(
|
|
428
|
+
options.decl.push(
|
|
429
|
+
topDecl ? "" : `${tag} = ${options.path}.${options.first ? "firstChild" : "nextSibling"}`
|
|
430
|
+
);
|
|
371
431
|
parseDirective(name, value, tag, options);
|
|
372
432
|
}
|
|
373
433
|
}
|
|
374
|
-
if (
|
|
434
|
+
if (
|
|
435
|
+
node.children.length === 1 &&
|
|
436
|
+
node.children[0].type === "comment" &&
|
|
437
|
+
node.children[0].content === "#"
|
|
438
|
+
) {
|
|
375
439
|
props.push(`children: () => exprs[${options.counter++}]`);
|
|
376
440
|
} else if (node.children.length) {
|
|
377
441
|
const children = {
|
|
@@ -394,7 +458,20 @@ function createHTML(r, {
|
|
|
394
458
|
tag = `_$el${uuid++}`;
|
|
395
459
|
options.decl.push(`${tag} = ${options.path}.${options.first ? "firstChild" : "nextSibling"}`);
|
|
396
460
|
}
|
|
397
|
-
if (options.parent)
|
|
461
|
+
if (options.parent)
|
|
462
|
+
options.exprs.push(
|
|
463
|
+
`r.insert(${
|
|
464
|
+
options.parent
|
|
465
|
+
}, r.createComponent(exprs[${componentIdentifier}],${processComponentProps(propGroups)})${
|
|
466
|
+
tag ? `, ${tag}` : ""
|
|
467
|
+
})`
|
|
468
|
+
);
|
|
469
|
+
else
|
|
470
|
+
options.exprs.push(
|
|
471
|
+
`${
|
|
472
|
+
options.fragment ? "" : "return "
|
|
473
|
+
}r.createComponent(exprs[${componentIdentifier}],${processComponentProps(propGroups)})`
|
|
474
|
+
);
|
|
398
475
|
options.path = tag;
|
|
399
476
|
options.first = false;
|
|
400
477
|
}
|
|
@@ -425,13 +502,21 @@ function createHTML(r, {
|
|
|
425
502
|
});
|
|
426
503
|
options.templateNodes.push([child]);
|
|
427
504
|
parseNode(child, childOptions);
|
|
428
|
-
parts.push(
|
|
505
|
+
parts.push(
|
|
506
|
+
`function() { ${
|
|
507
|
+
childOptions.decl.join(",\n") +
|
|
508
|
+
";\n" +
|
|
509
|
+
childOptions.exprs.join(";\n") +
|
|
510
|
+
`;\nreturn _$el${id};\n`
|
|
511
|
+
}}()`
|
|
512
|
+
);
|
|
429
513
|
options.counter = childOptions.counter;
|
|
430
514
|
options.templateId = childOptions.templateId;
|
|
431
515
|
} else if (child.type === "text") {
|
|
432
516
|
parts.push(`"${child.content}"`);
|
|
433
517
|
} else if (child.type === "comment") {
|
|
434
|
-
if (child.content === "#") parts.push(`exprs[${options.counter++}]`);
|
|
518
|
+
if (child.content === "#") parts.push(`exprs[${options.counter++}]`);
|
|
519
|
+
else if (child.content) {
|
|
435
520
|
for (let i = 0; i < child.content.split("###").length - 1; i++) {
|
|
436
521
|
parts.push(`exprs[${options.counter++}]`);
|
|
437
522
|
}
|
|
@@ -443,24 +528,26 @@ function createHTML(r, {
|
|
|
443
528
|
const tag = `_$el${uuid++}`;
|
|
444
529
|
const topDecl = !options.decl.length;
|
|
445
530
|
const templateId = options.templateId;
|
|
446
|
-
options.decl.push(
|
|
531
|
+
options.decl.push(
|
|
532
|
+
topDecl ? "" : `${tag} = ${options.path}.${options.first ? "firstChild" : "nextSibling"}`
|
|
533
|
+
);
|
|
447
534
|
const isSVG = r.SVGElements.has(node.name);
|
|
448
535
|
options.hasCustomElement = node.name.includes("-") || node.attrs.some(e => e.name === "is");
|
|
449
|
-
options.isImportNode =
|
|
536
|
+
options.isImportNode =
|
|
537
|
+
(node.name === "img" || node.name === "iframe") &&
|
|
538
|
+
node.attrs.some(e => e.name === "loading" && e.value === "lazy");
|
|
450
539
|
if (node.attrs.some(e => e.name === "###")) {
|
|
451
540
|
const spreadArgs = [];
|
|
452
541
|
let current = "";
|
|
453
542
|
const newAttrs = [];
|
|
454
543
|
for (let i = 0; i < node.attrs.length; i++) {
|
|
455
|
-
const {
|
|
456
|
-
type,
|
|
457
|
-
name,
|
|
458
|
-
value
|
|
459
|
-
} = node.attrs[i];
|
|
544
|
+
const { type, name, value } = node.attrs[i];
|
|
460
545
|
if (type === "attr") {
|
|
461
546
|
if (value.includes("###")) {
|
|
462
547
|
let count = options.counter++;
|
|
463
|
-
current += `${name}: ${
|
|
548
|
+
current += `${name}: ${
|
|
549
|
+
name !== "ref" ? `typeof exprs[${count}] === "function" ? exprs[${count}]() : ` : ""
|
|
550
|
+
}exprs[${count}],`;
|
|
464
551
|
} else if (name === "###") {
|
|
465
552
|
if (current.length) {
|
|
466
553
|
spreadArgs.push(`()=>({${current}})`);
|
|
@@ -478,14 +565,16 @@ function createHTML(r, {
|
|
|
478
565
|
if (current.length) {
|
|
479
566
|
spreadArgs.push(`()=>({${current}})`);
|
|
480
567
|
}
|
|
481
|
-
options.exprs.push(
|
|
568
|
+
options.exprs.push(
|
|
569
|
+
`r.spread(${tag},${
|
|
570
|
+
spreadArgs.length === 1
|
|
571
|
+
? `typeof ${spreadArgs[0]} === "function" ? r.mergeProps(${spreadArgs[0]}) : ${spreadArgs[0]}`
|
|
572
|
+
: `r.mergeProps(${spreadArgs.join(",")})`
|
|
573
|
+
},${isSVG},${!!node.children.length})`
|
|
574
|
+
);
|
|
482
575
|
} else {
|
|
483
576
|
for (let i = 0; i < node.attrs.length; i++) {
|
|
484
|
-
const {
|
|
485
|
-
type,
|
|
486
|
-
name,
|
|
487
|
-
value
|
|
488
|
-
} = node.attrs[i];
|
|
577
|
+
const { type, name, value } = node.attrs[i];
|
|
489
578
|
if (type === "directive") {
|
|
490
579
|
parseDirective(name, value, tag, options);
|
|
491
580
|
node.attrs.splice(i, 1);
|
|
@@ -503,7 +592,10 @@ function createHTML(r, {
|
|
|
503
592
|
options.first = false;
|
|
504
593
|
processChildren(node, options);
|
|
505
594
|
if (topDecl) {
|
|
506
|
-
options.decl[0] =
|
|
595
|
+
options.decl[0] =
|
|
596
|
+
options.hasCustomElement || options.isImportNode
|
|
597
|
+
? `const ${tag} = r.untrack(() => document.importNode(tmpls[${templateId}].content.firstChild, true))`
|
|
598
|
+
: `const ${tag} = tmpls[${templateId}].content.firstChild.cloneNode(true)`;
|
|
507
599
|
}
|
|
508
600
|
} else if (node.type === "text") {
|
|
509
601
|
const tag = `_$el${uuid++}`;
|
|
@@ -538,10 +630,12 @@ function createHTML(r, {
|
|
|
538
630
|
origNodes = nodes;
|
|
539
631
|
let toplevel;
|
|
540
632
|
if (nodes.length > 1) {
|
|
541
|
-
nodes = [
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
633
|
+
nodes = [
|
|
634
|
+
{
|
|
635
|
+
type: "fragment",
|
|
636
|
+
children: nodes
|
|
637
|
+
}
|
|
638
|
+
];
|
|
545
639
|
}
|
|
546
640
|
if (nodes[0].name === "###") {
|
|
547
641
|
toplevel = true;
|
|
@@ -549,12 +643,25 @@ function createHTML(r, {
|
|
|
549
643
|
} else parseNode(nodes[0], options);
|
|
550
644
|
r.delegateEvents(Array.from(options.delegatedEvents));
|
|
551
645
|
const templateNodes = [origNodes].concat(options.templateNodes);
|
|
552
|
-
return [
|
|
646
|
+
return [
|
|
647
|
+
templateNodes.map(t => stringify(t)),
|
|
648
|
+
funcBuilder(
|
|
649
|
+
"tmpls",
|
|
650
|
+
"exprs",
|
|
651
|
+
"r",
|
|
652
|
+
options.decl.join(",\n") +
|
|
653
|
+
";\n" +
|
|
654
|
+
options.exprs.join(";\n") +
|
|
655
|
+
(toplevel ? "" : `;\nreturn _$el${id};\n`)
|
|
656
|
+
)
|
|
657
|
+
];
|
|
553
658
|
}
|
|
554
659
|
function html(statics, ...args) {
|
|
555
|
-
const templates =
|
|
556
|
-
|
|
557
|
-
|
|
660
|
+
const templates =
|
|
661
|
+
cache.get(statics) ||
|
|
662
|
+
createTemplate(statics, {
|
|
663
|
+
funcBuilder: functionBuilder
|
|
664
|
+
});
|
|
558
665
|
return templates[0].create(templates, args, r);
|
|
559
666
|
}
|
|
560
667
|
return html;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidjs/html",
|
|
3
3
|
"description": "Build-less Tagged-Template-Literal Templating for Solid",
|
|
4
|
-
"version": "2.0.0-experimental.
|
|
4
|
+
"version": "2.0.0-experimental.2",
|
|
5
5
|
"author": "Ryan Carniato",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://solidjs.com",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"./dist/*": "./dist/*"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@solidjs/web": "^2.0.0-experimental.
|
|
34
|
+
"@solidjs/web": "^2.0.0-experimental.2"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@solidjs/web": "2.0.0-experimental.1"
|
package/types/index.d.ts
DELETED
package/types/lit.d.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
type MountableElement = Element | Document | ShadowRoot | DocumentFragment | Node;
|
|
2
|
-
type ClassList =
|
|
3
|
-
| Record<string, boolean>
|
|
4
|
-
| Array<string | number | boolean | null | undefined | Record<string, boolean>>;
|
|
5
|
-
interface Runtime {
|
|
6
|
-
effect<T>(fn: (prev?: T) => T, effect: (value: T, prev?: T) => void, init?: T): void;
|
|
7
|
-
untrack<T>(fn: () => T): T;
|
|
8
|
-
insert(parent: MountableElement, accessor: any, marker?: Node | null, init?: any): any;
|
|
9
|
-
spread<T>(node: Element, accessor: (() => T) | T, isSVG?: Boolean, skipChildren?: Boolean): void;
|
|
10
|
-
createComponent(Comp: (props: any) => any, props: any): any;
|
|
11
|
-
addEventListener(
|
|
12
|
-
node: Element,
|
|
13
|
-
name: string,
|
|
14
|
-
handler: EventListener | EventListenerObject | (EventListenerObject & AddEventListenerOptions),
|
|
15
|
-
delegate: boolean
|
|
16
|
-
): void;
|
|
17
|
-
delegateEvents(eventNames: string[]): void;
|
|
18
|
-
className(
|
|
19
|
-
node: Element,
|
|
20
|
-
value: string | ClassList,
|
|
21
|
-
isSVG?: boolean,
|
|
22
|
-
prev?: string | ClassList
|
|
23
|
-
): void;
|
|
24
|
-
style(
|
|
25
|
-
node: Element,
|
|
26
|
-
value: {
|
|
27
|
-
[k: string]: string;
|
|
28
|
-
},
|
|
29
|
-
prev?: {
|
|
30
|
-
[k: string]: string;
|
|
31
|
-
}
|
|
32
|
-
): void;
|
|
33
|
-
mergeProps(...sources: unknown[]): unknown;
|
|
34
|
-
dynamicProperty(props: any, key: string): any;
|
|
35
|
-
setAttribute(node: Element, name: string, value: any): void;
|
|
36
|
-
setAttributeNS(node: Element, namespace: string, name: string, value: any): void;
|
|
37
|
-
getPropAlias(prop: string, tagName: string): string | undefined;
|
|
38
|
-
Properties: Set<string>;
|
|
39
|
-
ChildProperties: Set<string>;
|
|
40
|
-
DelegatedEvents: Set<string>;
|
|
41
|
-
SVGElements: Set<string>;
|
|
42
|
-
SVGNamespace: Record<string, string>;
|
|
43
|
-
}
|
|
44
|
-
export type HTMLTag = {
|
|
45
|
-
(statics: TemplateStringsArray, ...args: unknown[]): Node | Node[];
|
|
46
|
-
};
|
|
47
|
-
export declare function createHTML(
|
|
48
|
-
r: Runtime,
|
|
49
|
-
{
|
|
50
|
-
delegateEvents,
|
|
51
|
-
functionBuilder
|
|
52
|
-
}?: {
|
|
53
|
-
delegateEvents?: boolean;
|
|
54
|
-
functionBuilder?: (...args: string[]) => Function;
|
|
55
|
-
}
|
|
56
|
-
): HTMLTag;
|
|
57
|
-
export {};
|