ghtml 3.0.8 → 3.0.10
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/bench/index.js +2 -4
- package/bin/README.md +1 -1
- package/bin/example/assets/script.js +1 -1
- package/bin/example/routes/index.js +1 -3
- package/bin/example/server.js +3 -8
- package/bin/src/index.js +7 -7
- package/bin/src/utils.js +6 -2
- package/eslint.config.js +12 -1
- package/package.json +3 -3
- package/src/index.d.ts +3 -1
- package/src/index.js +258 -1
- package/src/html.d.ts +0 -3
- package/src/html.js +0 -248
package/bench/index.js
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
/* eslint-disable no-unused-vars */
|
|
2
|
-
|
|
3
|
-
import { html } from "../src/index.js";
|
|
2
|
+
import { html } from "ghtml";
|
|
4
3
|
import { Bench } from "tinybench";
|
|
5
4
|
import { writeFileSync } from "node:fs";
|
|
6
5
|
import { Buffer } from "node:buffer";
|
|
7
6
|
|
|
8
|
-
let result = "";
|
|
9
|
-
|
|
10
7
|
const bench = new Bench({ time: 500 });
|
|
8
|
+
let result = "";
|
|
11
9
|
|
|
12
10
|
bench.add("simple HTML formatting", () => {
|
|
13
11
|
result = html`<div>Hello, world!</div>`;
|
package/bin/README.md
CHANGED
|
@@ -5,7 +5,7 @@ Append unique hashes to assets referenced in your views to aggressively cache th
|
|
|
5
5
|
Running the following command will scan asset files found in the `roots` path(s) and replace their references in the `refs` path(s) with hashed versions:
|
|
6
6
|
|
|
7
7
|
```sh
|
|
8
|
-
npx ghtml --roots="base/path/to/scan/assets/1/,base/path/to/scan/assets/2/" --refs="views/path/to/append/hashes/1/,views/path/to/append/hashes/2/"
|
|
8
|
+
npx ghtml --roots="base/path/to/scan/assets/1/,base/path/to/scan/assets/2/" --refs="views/path/to/append/hashes/1/,views/path/to/append/hashes/2/" --prefix="/optional/prefix/"
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
## Example (Fastify)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
globalThis.console.
|
|
1
|
+
globalThis.console.log("Hello World!");
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/* eslint-disable n/no-missing-import, require-await */
|
|
2
|
-
|
|
3
1
|
import { html } from "ghtml";
|
|
4
2
|
|
|
5
3
|
export default async (fastify) => {
|
|
@@ -21,7 +19,7 @@ export default async (fastify) => {
|
|
|
21
19
|
<body>
|
|
22
20
|
!${inner}
|
|
23
21
|
</body>
|
|
24
|
-
</html
|
|
22
|
+
</html>`;
|
|
25
23
|
});
|
|
26
24
|
|
|
27
25
|
fastify.get("/", async (request, reply) => {
|
package/bin/example/server.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/* eslint-disable n/no-missing-import */
|
|
2
|
-
|
|
3
1
|
import Fastify from "fastify";
|
|
4
2
|
|
|
5
3
|
const fastify = Fastify();
|
|
@@ -17,10 +15,7 @@ await fastify.register(import("@fastify/static"), {
|
|
|
17
15
|
// Routes
|
|
18
16
|
fastify.register(import("./routes/index.js"));
|
|
19
17
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
throw err;
|
|
23
|
-
}
|
|
18
|
+
// Listen
|
|
19
|
+
const address = await fastify.listen({ port: 5050 });
|
|
24
20
|
|
|
25
|
-
|
|
26
|
-
});
|
|
21
|
+
globalThis.console.log(`Server listening at ${address}`);
|
package/bin/src/index.js
CHANGED
|
@@ -18,7 +18,7 @@ const parseArguments = (args) => {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
if (!roots || !refs) {
|
|
21
|
-
globalThis.console.
|
|
21
|
+
globalThis.console.log(
|
|
22
22
|
'Usage: npx ghtml --roots="base/path/to/scan/assets/1/,base/path/to/scan/assets/2/" --refs="views/path/to/append/hashes/1/,views/path/to/append/hashes/2/" [--prefix="/optional/prefix/"]',
|
|
23
23
|
);
|
|
24
24
|
process.exit(1);
|
|
@@ -31,10 +31,10 @@ const main = async () => {
|
|
|
31
31
|
const { roots, refs, prefix } = parseArguments(process.argv.slice(2));
|
|
32
32
|
|
|
33
33
|
try {
|
|
34
|
-
globalThis.console.
|
|
35
|
-
globalThis.console.
|
|
36
|
-
globalThis.console.
|
|
37
|
-
globalThis.console.
|
|
34
|
+
globalThis.console.log(`Generating hashes and updating file paths...`);
|
|
35
|
+
globalThis.console.log(`Scanning files in: ${roots}`);
|
|
36
|
+
globalThis.console.log(`Updating files in: ${refs}`);
|
|
37
|
+
globalThis.console.log(`Using prefix: ${prefix}`);
|
|
38
38
|
|
|
39
39
|
await generateHashesAndReplace({
|
|
40
40
|
roots,
|
|
@@ -42,11 +42,11 @@ const main = async () => {
|
|
|
42
42
|
prefix,
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
-
globalThis.console.
|
|
45
|
+
globalThis.console.log(
|
|
46
46
|
"Hash generation and file updates completed successfully.",
|
|
47
47
|
);
|
|
48
48
|
} catch (error) {
|
|
49
|
-
globalThis.console.
|
|
49
|
+
globalThis.console.log(`Error occurred: ${error.message}`);
|
|
50
50
|
process.exit(1);
|
|
51
51
|
}
|
|
52
52
|
};
|
package/bin/src/utils.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/* eslint-disable no-await-in-loop */
|
|
2
|
-
|
|
3
1
|
import { Glob } from "glob";
|
|
4
2
|
import { createHash } from "node:crypto";
|
|
5
3
|
import { readFile, writeFile } from "node:fs/promises";
|
|
@@ -8,11 +6,13 @@ import { win32, posix } from "node:path";
|
|
|
8
6
|
const generateFileHash = async (filePath) => {
|
|
9
7
|
try {
|
|
10
8
|
const fileBuffer = await readFile(filePath);
|
|
9
|
+
|
|
11
10
|
return createHash("md5").update(fileBuffer).digest("hex").slice(0, 16);
|
|
12
11
|
} catch (err) {
|
|
13
12
|
if (err.code !== "ENOENT") {
|
|
14
13
|
throw err;
|
|
15
14
|
}
|
|
15
|
+
|
|
16
16
|
return "";
|
|
17
17
|
}
|
|
18
18
|
};
|
|
@@ -26,6 +26,7 @@ const updateFilePathsWithHashes = async (
|
|
|
26
26
|
) => {
|
|
27
27
|
for (let ref of refs) {
|
|
28
28
|
ref = ref.replaceAll(win32.sep, posix.sep);
|
|
29
|
+
|
|
29
30
|
if (!ref.endsWith("/")) {
|
|
30
31
|
ref += "/";
|
|
31
32
|
}
|
|
@@ -84,11 +85,13 @@ export const generateHashesAndReplace = async ({
|
|
|
84
85
|
skipPatterns = ["**/node_modules/**"],
|
|
85
86
|
}) => {
|
|
86
87
|
const fileHashes = new Map();
|
|
88
|
+
|
|
87
89
|
roots = Array.isArray(roots) ? roots : [roots];
|
|
88
90
|
refs = Array.isArray(refs) ? refs : [refs];
|
|
89
91
|
|
|
90
92
|
for (let root of roots) {
|
|
91
93
|
root = root.replaceAll(win32.sep, posix.sep);
|
|
94
|
+
|
|
92
95
|
if (!root.endsWith("/")) {
|
|
93
96
|
root += "/";
|
|
94
97
|
}
|
|
@@ -114,6 +117,7 @@ export const generateHashesAndReplace = async ({
|
|
|
114
117
|
|
|
115
118
|
for (let i = 0; i < files.length; ++i) {
|
|
116
119
|
const fileRelativePath = posix.relative(root, files[i]);
|
|
120
|
+
|
|
117
121
|
fileHashes.set(fileRelativePath, hashes[i]);
|
|
118
122
|
}
|
|
119
123
|
}
|
package/eslint.config.js
CHANGED
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Replace your template engine with fast JavaScript by leveraging the power of tagged templates.",
|
|
4
4
|
"author": "Gürgün Dayıoğlu",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"version": "3.0.
|
|
6
|
+
"version": "3.0.10",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"bin": "./bin/src/index.js",
|
|
9
9
|
"main": "./src/index.js",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"test": "npm run lint && c8 --100 node --test test/*.js",
|
|
20
20
|
"lint": "eslint . && prettier --check .",
|
|
21
21
|
"lint:fix": "eslint --fix . && prettier --write .",
|
|
22
|
-
"typescript": "tsc src/*.js --allowJs --declaration --emitDeclarationOnly"
|
|
22
|
+
"typescript": "tsc src/*.js --allowJs --declaration --emitDeclarationOnly --skipLibCheck"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"glob": "^10.4.5"
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@fastify/pre-commit": "^2.1.0",
|
|
29
29
|
"c8": "^10.1.2",
|
|
30
|
-
"grules": "^0.25.
|
|
30
|
+
"grules": "^0.25.5",
|
|
31
31
|
"tinybench": "^2.9.0",
|
|
32
32
|
"typescript": ">=5.6.2"
|
|
33
33
|
},
|
package/src/index.d.ts
CHANGED
|
@@ -1 +1,3 @@
|
|
|
1
|
-
export
|
|
1
|
+
export function html(literals: TemplateStringsArray, ...expressions: any[]): string;
|
|
2
|
+
export function htmlGenerator(literals: TemplateStringsArray, ...expressions: any[]): Generator<string, void, void>;
|
|
3
|
+
export function htmlAsyncGenerator(literals: TemplateStringsArray, ...expressions: any[]): AsyncGenerator<string, void, void>;
|
package/src/index.js
CHANGED
|
@@ -1 +1,258 @@
|
|
|
1
|
-
|
|
1
|
+
const escapeRegExp = /["&'<=>]/g;
|
|
2
|
+
|
|
3
|
+
const escapeFunction = (string) => {
|
|
4
|
+
let escaped = "";
|
|
5
|
+
let start = 0;
|
|
6
|
+
|
|
7
|
+
while (escapeRegExp.test(string)) {
|
|
8
|
+
const i = escapeRegExp.lastIndex - 1;
|
|
9
|
+
|
|
10
|
+
switch (string.charCodeAt(i)) {
|
|
11
|
+
// "
|
|
12
|
+
case 34: {
|
|
13
|
+
escaped += string.slice(start, i) + """;
|
|
14
|
+
break;
|
|
15
|
+
}
|
|
16
|
+
// &
|
|
17
|
+
case 38: {
|
|
18
|
+
escaped += string.slice(start, i) + "&";
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
// '
|
|
22
|
+
case 39: {
|
|
23
|
+
escaped += string.slice(start, i) + "'";
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
// <
|
|
27
|
+
case 60: {
|
|
28
|
+
escaped += string.slice(start, i) + "<";
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
// =
|
|
32
|
+
case 61: {
|
|
33
|
+
escaped += string.slice(start, i) + "=";
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
// >
|
|
37
|
+
case 62: {
|
|
38
|
+
escaped += string.slice(start, i) + ">";
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
start = escapeRegExp.lastIndex;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return escaped + string.slice(start);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @param {TemplateStringsArray} literals literals
|
|
51
|
+
* @param {...any} expressions expressions
|
|
52
|
+
* @returns {string} string
|
|
53
|
+
*/
|
|
54
|
+
export const html = (literals, ...expressions) => {
|
|
55
|
+
let accumulator = "";
|
|
56
|
+
|
|
57
|
+
for (let i = 0; i !== expressions.length; ++i) {
|
|
58
|
+
let literal = literals.raw[i];
|
|
59
|
+
let string = Array.isArray(expressions[i])
|
|
60
|
+
? expressions[i].join("")
|
|
61
|
+
: String(expressions[i] ?? "");
|
|
62
|
+
|
|
63
|
+
if (literal && literal.charCodeAt(literal.length - 1) === 33) {
|
|
64
|
+
literal = literal.slice(0, -1);
|
|
65
|
+
} else {
|
|
66
|
+
string &&= escapeFunction(string);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
accumulator += literal + string;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return accumulator + literals.raw[expressions.length];
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @param {TemplateStringsArray} literals literals
|
|
77
|
+
* @param {...any} expressions expressions
|
|
78
|
+
* @yields {string} string
|
|
79
|
+
* @returns {Generator<string, void, void>} Generator<string, void, void>
|
|
80
|
+
*/
|
|
81
|
+
export const htmlGenerator = function* (literals, ...expressions) {
|
|
82
|
+
for (let i = 0; i !== expressions.length; ++i) {
|
|
83
|
+
let expression = expressions[i];
|
|
84
|
+
let literal = literals.raw[i];
|
|
85
|
+
let string;
|
|
86
|
+
|
|
87
|
+
if (typeof expression === "string") {
|
|
88
|
+
string = expression;
|
|
89
|
+
} else if (expression === undefined || expression === null) {
|
|
90
|
+
string = "";
|
|
91
|
+
} else {
|
|
92
|
+
if (expression[Symbol.iterator]) {
|
|
93
|
+
const isRaw =
|
|
94
|
+
Boolean(literal) && literal.charCodeAt(literal.length - 1) === 33;
|
|
95
|
+
|
|
96
|
+
if (isRaw) {
|
|
97
|
+
literal = literal.slice(0, -1);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (literal) {
|
|
101
|
+
yield literal;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
for (expression of expression) {
|
|
105
|
+
if (typeof expression === "string") {
|
|
106
|
+
string = expression;
|
|
107
|
+
} else {
|
|
108
|
+
if (expression === undefined || expression === null) {
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (expression[Symbol.iterator]) {
|
|
113
|
+
for (expression of expression) {
|
|
114
|
+
if (expression === undefined || expression === null) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
string = String(expression);
|
|
119
|
+
|
|
120
|
+
if (string) {
|
|
121
|
+
if (!isRaw) {
|
|
122
|
+
string = escapeFunction(string);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
yield string;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
string = String(expression);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (string) {
|
|
136
|
+
if (!isRaw) {
|
|
137
|
+
string = escapeFunction(string);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
yield string;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
string = String(expression);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (literal && literal.charCodeAt(literal.length - 1) === 33) {
|
|
151
|
+
literal = literal.slice(0, -1);
|
|
152
|
+
} else {
|
|
153
|
+
string &&= escapeFunction(string);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (literal || string) {
|
|
157
|
+
yield literal + string;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (literals.raw[expressions.length]) {
|
|
162
|
+
yield literals.raw[expressions.length];
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* @param {TemplateStringsArray} literals literals
|
|
168
|
+
* @param {...any} expressions expressions
|
|
169
|
+
* @yields {string} string
|
|
170
|
+
* @returns {AsyncGenerator<string, void, void>} AsyncGenerator<string, void, void>
|
|
171
|
+
*/
|
|
172
|
+
export const htmlAsyncGenerator = async function* (literals, ...expressions) {
|
|
173
|
+
for (let i = 0; i !== expressions.length; ++i) {
|
|
174
|
+
let expression = await expressions[i];
|
|
175
|
+
let literal = literals.raw[i];
|
|
176
|
+
let string;
|
|
177
|
+
|
|
178
|
+
if (typeof expression === "string") {
|
|
179
|
+
string = expression;
|
|
180
|
+
} else if (expression === undefined || expression === null) {
|
|
181
|
+
string = "";
|
|
182
|
+
} else {
|
|
183
|
+
if (expression[Symbol.iterator] || expression[Symbol.asyncIterator]) {
|
|
184
|
+
const isRaw =
|
|
185
|
+
Boolean(literal) && literal.charCodeAt(literal.length - 1) === 33;
|
|
186
|
+
|
|
187
|
+
if (isRaw) {
|
|
188
|
+
literal = literal.slice(0, -1);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (literal) {
|
|
192
|
+
yield literal;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
for await (expression of expression) {
|
|
196
|
+
if (typeof expression === "string") {
|
|
197
|
+
string = expression;
|
|
198
|
+
} else {
|
|
199
|
+
if (expression === undefined || expression === null) {
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (
|
|
204
|
+
expression[Symbol.iterator] ||
|
|
205
|
+
expression[Symbol.asyncIterator]
|
|
206
|
+
) {
|
|
207
|
+
for await (expression of expression) {
|
|
208
|
+
if (expression === undefined || expression === null) {
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
string = String(expression);
|
|
213
|
+
|
|
214
|
+
if (string) {
|
|
215
|
+
if (!isRaw) {
|
|
216
|
+
string = escapeFunction(string);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
yield string;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
string = String(expression);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (string) {
|
|
230
|
+
if (!isRaw) {
|
|
231
|
+
string = escapeFunction(string);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
yield string;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
string = String(expression);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (literal && literal.charCodeAt(literal.length - 1) === 33) {
|
|
245
|
+
literal = literal.slice(0, -1);
|
|
246
|
+
} else {
|
|
247
|
+
string &&= escapeFunction(string);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (literal || string) {
|
|
251
|
+
yield literal + string;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (literals.raw[expressions.length]) {
|
|
256
|
+
yield literals.raw[expressions.length];
|
|
257
|
+
}
|
|
258
|
+
};
|
package/src/html.d.ts
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
export function html(literals: TemplateStringsArray, ...expressions: any[]): string;
|
|
2
|
-
export function htmlGenerator(literals: TemplateStringsArray, ...expressions: any[]): Generator<string, void, void>;
|
|
3
|
-
export function htmlAsyncGenerator(literals: TemplateStringsArray, ...expressions: any[]): AsyncGenerator<string, void, void>;
|
package/src/html.js
DELETED
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-await-in-loop, require-unicode-regexp */
|
|
2
|
-
|
|
3
|
-
const escapeRegExp = /["&'<=>]/g;
|
|
4
|
-
|
|
5
|
-
const escapeFunction = (string) => {
|
|
6
|
-
let escaped = "";
|
|
7
|
-
let start = 0;
|
|
8
|
-
|
|
9
|
-
while (escapeRegExp.test(string)) {
|
|
10
|
-
const i = escapeRegExp.lastIndex - 1;
|
|
11
|
-
|
|
12
|
-
switch (string.charCodeAt(i)) {
|
|
13
|
-
case 34: // "
|
|
14
|
-
escaped += string.slice(start, i) + """;
|
|
15
|
-
break;
|
|
16
|
-
case 38: // &
|
|
17
|
-
escaped += string.slice(start, i) + "&";
|
|
18
|
-
break;
|
|
19
|
-
case 39: // '
|
|
20
|
-
escaped += string.slice(start, i) + "'";
|
|
21
|
-
break;
|
|
22
|
-
case 60: // <
|
|
23
|
-
escaped += string.slice(start, i) + "<";
|
|
24
|
-
break;
|
|
25
|
-
case 61: // =
|
|
26
|
-
escaped += string.slice(start, i) + "=";
|
|
27
|
-
break;
|
|
28
|
-
case 62: // >
|
|
29
|
-
escaped += string.slice(start, i) + ">";
|
|
30
|
-
break;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
start = escapeRegExp.lastIndex;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return escaped + string.slice(start);
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* @param {TemplateStringsArray} literals literals
|
|
41
|
-
* @param {...any} expressions expressions
|
|
42
|
-
* @returns {string} string
|
|
43
|
-
*/
|
|
44
|
-
export const html = (literals, ...expressions) => {
|
|
45
|
-
let accumulator = "";
|
|
46
|
-
|
|
47
|
-
for (let i = 0; i !== expressions.length; ++i) {
|
|
48
|
-
let literal = literals.raw[i];
|
|
49
|
-
let string = Array.isArray(expressions[i])
|
|
50
|
-
? expressions[i].join("")
|
|
51
|
-
: String(expressions[i] ?? "");
|
|
52
|
-
|
|
53
|
-
if (literal && literal.charCodeAt(literal.length - 1) === 33) {
|
|
54
|
-
literal = literal.slice(0, -1);
|
|
55
|
-
} else {
|
|
56
|
-
string &&= escapeFunction(string);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
accumulator += literal + string;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return accumulator + literals.raw[expressions.length];
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* @param {TemplateStringsArray} literals literals
|
|
67
|
-
* @param {...any} expressions expressions
|
|
68
|
-
* @yields {string} string
|
|
69
|
-
* @returns {Generator<string, void, void>} Generator<string, void, void>
|
|
70
|
-
*/
|
|
71
|
-
export const htmlGenerator = function* (literals, ...expressions) {
|
|
72
|
-
for (let i = 0; i !== expressions.length; ++i) {
|
|
73
|
-
let expression = expressions[i];
|
|
74
|
-
let literal = literals.raw[i];
|
|
75
|
-
let string;
|
|
76
|
-
|
|
77
|
-
if (typeof expression === "string") {
|
|
78
|
-
string = expression;
|
|
79
|
-
} else if (expression === undefined || expression === null) {
|
|
80
|
-
string = "";
|
|
81
|
-
} else {
|
|
82
|
-
if (expression[Symbol.iterator]) {
|
|
83
|
-
const isRaw =
|
|
84
|
-
Boolean(literal) && literal.charCodeAt(literal.length - 1) === 33;
|
|
85
|
-
|
|
86
|
-
if (isRaw) {
|
|
87
|
-
literal = literal.slice(0, -1);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (literal) {
|
|
91
|
-
yield literal;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
for (expression of expression) {
|
|
95
|
-
if (typeof expression === "string") {
|
|
96
|
-
string = expression;
|
|
97
|
-
} else {
|
|
98
|
-
if (expression === undefined || expression === null) {
|
|
99
|
-
continue;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (expression[Symbol.iterator]) {
|
|
103
|
-
for (expression of expression) {
|
|
104
|
-
if (expression === undefined || expression === null) {
|
|
105
|
-
continue;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
string = String(expression);
|
|
109
|
-
|
|
110
|
-
if (string) {
|
|
111
|
-
if (!isRaw) {
|
|
112
|
-
string = escapeFunction(string);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
yield string;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
continue;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
string = String(expression);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
if (string) {
|
|
126
|
-
if (!isRaw) {
|
|
127
|
-
string = escapeFunction(string);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
yield string;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
continue;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
string = String(expression);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (literal && literal.charCodeAt(literal.length - 1) === 33) {
|
|
141
|
-
literal = literal.slice(0, -1);
|
|
142
|
-
} else {
|
|
143
|
-
string &&= escapeFunction(string);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (literal || string) {
|
|
147
|
-
yield literal + string;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
if (literals.raw[expressions.length]) {
|
|
152
|
-
yield literals.raw[expressions.length];
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* @param {TemplateStringsArray} literals literals
|
|
158
|
-
* @param {...any} expressions expressions
|
|
159
|
-
* @yields {string} string
|
|
160
|
-
* @returns {AsyncGenerator<string, void, void>} AsyncGenerator<string, void, void>
|
|
161
|
-
*/
|
|
162
|
-
export const htmlAsyncGenerator = async function* (literals, ...expressions) {
|
|
163
|
-
for (let i = 0; i !== expressions.length; ++i) {
|
|
164
|
-
let expression = await expressions[i];
|
|
165
|
-
let literal = literals.raw[i];
|
|
166
|
-
let string;
|
|
167
|
-
|
|
168
|
-
if (typeof expression === "string") {
|
|
169
|
-
string = expression;
|
|
170
|
-
} else if (expression === undefined || expression === null) {
|
|
171
|
-
string = "";
|
|
172
|
-
} else {
|
|
173
|
-
if (expression[Symbol.iterator] || expression[Symbol.asyncIterator]) {
|
|
174
|
-
const isRaw =
|
|
175
|
-
Boolean(literal) && literal.charCodeAt(literal.length - 1) === 33;
|
|
176
|
-
|
|
177
|
-
if (isRaw) {
|
|
178
|
-
literal = literal.slice(0, -1);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
if (literal) {
|
|
182
|
-
yield literal;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
for await (expression of expression) {
|
|
186
|
-
if (typeof expression === "string") {
|
|
187
|
-
string = expression;
|
|
188
|
-
} else {
|
|
189
|
-
if (expression === undefined || expression === null) {
|
|
190
|
-
continue;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
if (
|
|
194
|
-
expression[Symbol.iterator] ||
|
|
195
|
-
expression[Symbol.asyncIterator]
|
|
196
|
-
) {
|
|
197
|
-
for await (expression of expression) {
|
|
198
|
-
if (expression === undefined || expression === null) {
|
|
199
|
-
continue;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
string = String(expression);
|
|
203
|
-
|
|
204
|
-
if (string) {
|
|
205
|
-
if (!isRaw) {
|
|
206
|
-
string = escapeFunction(string);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
yield string;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
continue;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
string = String(expression);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
if (string) {
|
|
220
|
-
if (!isRaw) {
|
|
221
|
-
string = escapeFunction(string);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
yield string;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
continue;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
string = String(expression);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
if (literal && literal.charCodeAt(literal.length - 1) === 33) {
|
|
235
|
-
literal = literal.slice(0, -1);
|
|
236
|
-
} else {
|
|
237
|
-
string &&= escapeFunction(string);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
if (literal || string) {
|
|
241
|
-
yield literal + string;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
if (literals.raw[expressions.length]) {
|
|
246
|
-
yield literals.raw[expressions.length];
|
|
247
|
-
}
|
|
248
|
-
};
|