lui-templates 0.2.0 → 0.2.1
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/package.json +1 -1
- package/src/parser.js +133 -0
- package/src/parsers/html.js +12 -11
package/package.json
CHANGED
package/src/parser.js
CHANGED
|
@@ -55,3 +55,136 @@ export const html_is_self_closing = tag => html_self_closing.includes(tag);
|
|
|
55
55
|
|
|
56
56
|
const html_boolean_attrs = new Set('disabled,checked,selected,readonly,required,autofocus,autoplay,controls,loop,muted,open,hidden,multiple,defer,async,novalidate,formnovalidate'.split(','));
|
|
57
57
|
export const html_is_boolean_attr = attr => html_boolean_attrs.has(attr.toLowerCase());
|
|
58
|
+
|
|
59
|
+
const html_entity_map = new Map([
|
|
60
|
+
// Common punctuation and symbols
|
|
61
|
+
['lt', '<'],
|
|
62
|
+
['gt', '>'],
|
|
63
|
+
['amp', '&'],
|
|
64
|
+
['quot', '"'],
|
|
65
|
+
['apos', "'"],
|
|
66
|
+
// Common Latin characters with diacritics
|
|
67
|
+
['auml', 'ä'],
|
|
68
|
+
['Auml', 'Ä'],
|
|
69
|
+
['ouml', 'ö'],
|
|
70
|
+
['Ouml', 'Ö'],
|
|
71
|
+
['uuml', 'ü'],
|
|
72
|
+
['Uuml', 'Ü'],
|
|
73
|
+
['szlig', 'ß'],
|
|
74
|
+
['euml', 'ë'],
|
|
75
|
+
['Euml', 'Ë'],
|
|
76
|
+
['iuml', 'ï'],
|
|
77
|
+
['Iuml', 'Ï'],
|
|
78
|
+
['yuml', 'ÿ'],
|
|
79
|
+
['Yuml', 'Ÿ'],
|
|
80
|
+
['aacute', 'á'],
|
|
81
|
+
['Aacute', 'Á'],
|
|
82
|
+
['eacute', 'é'],
|
|
83
|
+
['Eacute', 'É'],
|
|
84
|
+
['iacute', 'í'],
|
|
85
|
+
['Iacute', 'Í'],
|
|
86
|
+
['oacute', 'ó'],
|
|
87
|
+
['Oacute', 'Ó'],
|
|
88
|
+
['uacute', 'ú'],
|
|
89
|
+
['Uacute', 'Ú'],
|
|
90
|
+
['yacute', 'ý'],
|
|
91
|
+
['Yacute', 'Ý'],
|
|
92
|
+
['agrave', 'à'],
|
|
93
|
+
['Agrave', 'À'],
|
|
94
|
+
['egrave', 'è'],
|
|
95
|
+
['Egrave', 'È'],
|
|
96
|
+
['igrave', 'ì'],
|
|
97
|
+
['Igrave', 'Ì'],
|
|
98
|
+
['ograve', 'ò'],
|
|
99
|
+
['Ograve', 'Ò'],
|
|
100
|
+
['ugrave', 'ù'],
|
|
101
|
+
['Ugrave', 'Ù'],
|
|
102
|
+
['acirc', 'â'],
|
|
103
|
+
['Acirc', 'Â'],
|
|
104
|
+
['ecirc', 'ê'],
|
|
105
|
+
['Ecirc', 'Ê'],
|
|
106
|
+
['icirc', 'î'],
|
|
107
|
+
['Icirc', 'Î'],
|
|
108
|
+
['ocirc', 'ô'],
|
|
109
|
+
['Ocirc', 'Ô'],
|
|
110
|
+
['ucirc', 'û'],
|
|
111
|
+
['Ucirc', 'Û'],
|
|
112
|
+
['atilde', 'ã'],
|
|
113
|
+
['Atilde', 'Ã'],
|
|
114
|
+
['ntilde', 'ñ'],
|
|
115
|
+
['Ntilde', 'Ñ'],
|
|
116
|
+
['otilde', 'õ'],
|
|
117
|
+
['Otilde', 'Õ'],
|
|
118
|
+
['aring', 'å'],
|
|
119
|
+
['Aring', 'Å'],
|
|
120
|
+
['ccedil', 'ç'],
|
|
121
|
+
['Ccedil', 'Ç'],
|
|
122
|
+
['aelig', 'æ'],
|
|
123
|
+
['AElig', 'Æ'],
|
|
124
|
+
['oslash', 'ø'],
|
|
125
|
+
['Oslash', 'Ø'],
|
|
126
|
+
['eth', 'ð'],
|
|
127
|
+
['ETH', 'Ð'],
|
|
128
|
+
['thorn', 'þ'],
|
|
129
|
+
['THORN', 'Þ'],
|
|
130
|
+
// Common symbols and special characters
|
|
131
|
+
['nbsp', '\u00A0'],
|
|
132
|
+
['copy', '©'],
|
|
133
|
+
['reg', '®'],
|
|
134
|
+
['trade', '™'],
|
|
135
|
+
['euro', '€'],
|
|
136
|
+
['cent', '¢'],
|
|
137
|
+
['pound', '£'],
|
|
138
|
+
['yen', '¥'],
|
|
139
|
+
['sect', '§'],
|
|
140
|
+
['para', '¶'],
|
|
141
|
+
['deg', '°'],
|
|
142
|
+
['plusmn', '±'],
|
|
143
|
+
['micro', 'µ'],
|
|
144
|
+
['middot', '·'],
|
|
145
|
+
['bull', '•'],
|
|
146
|
+
['hellip', '…'],
|
|
147
|
+
['prime', '′'],
|
|
148
|
+
['Prime', '″'],
|
|
149
|
+
['lsquo', '\u2018'],
|
|
150
|
+
['rsquo', '\u2019'],
|
|
151
|
+
['ldquo', '\u201C'],
|
|
152
|
+
['rdquo', '\u201D'],
|
|
153
|
+
['sbquo', '\u201A'],
|
|
154
|
+
['bdquo', '\u201E'],
|
|
155
|
+
['dagger', '†'],
|
|
156
|
+
['Dagger', '‡'],
|
|
157
|
+
['permil', '‰'],
|
|
158
|
+
['lsaquo', '‹'],
|
|
159
|
+
['rsaquo', '›'],
|
|
160
|
+
['ndash', '\u2013'],
|
|
161
|
+
['mdash', '\u2014'],
|
|
162
|
+
['minus', '−'],
|
|
163
|
+
['times', '×'],
|
|
164
|
+
['divide', '÷'],
|
|
165
|
+
['frac14', '¼'],
|
|
166
|
+
['frac12', '½'],
|
|
167
|
+
['frac34', '¾'],
|
|
168
|
+
]);
|
|
169
|
+
|
|
170
|
+
function html_entity_translate(match, entity) {
|
|
171
|
+
if (entity[0] === '#') {
|
|
172
|
+
const codePoint = (
|
|
173
|
+
entity[1].toLowerCase() === 'x'
|
|
174
|
+
? parseInt(entity.slice(2), 16)
|
|
175
|
+
: parseInt(entity.slice(1), 10)
|
|
176
|
+
);
|
|
177
|
+
if (
|
|
178
|
+
codePoint >= 0 && codePoint < 0x110000 &&
|
|
179
|
+
(codePoint < 0xD800 || codePoint >= 0xE000)
|
|
180
|
+
) {
|
|
181
|
+
return String.fromCodePoint(codePoint);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return html_entity_map.get(entity) || match;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export const html_unescape = text => text.replace(
|
|
188
|
+
/&([a-zA-Z][a-zA-Z0-9]*|#[0-9]+|#[xX][0-9a-fA-F]+);/g,
|
|
189
|
+
html_entity_translate
|
|
190
|
+
);
|
package/src/parsers/html.js
CHANGED
|
@@ -3,14 +3,15 @@ import {
|
|
|
3
3
|
VALUE_TYPE_STATIC,
|
|
4
4
|
} from '../constants.js';
|
|
5
5
|
import {
|
|
6
|
+
html_attr_to_dom,
|
|
6
7
|
html_is_self_closing,
|
|
7
8
|
html_is_whitespace,
|
|
8
|
-
|
|
9
|
+
html_unescape,
|
|
9
10
|
html_whitespaces,
|
|
10
11
|
} from '../parser.js';
|
|
11
12
|
|
|
12
|
-
const
|
|
13
|
-
const
|
|
13
|
+
const TOKEN_TAG_START = 0;
|
|
14
|
+
const TOKEN_TAG_END = 1;
|
|
14
15
|
const TOKEN_TEXT = 2;
|
|
15
16
|
|
|
16
17
|
export default async function parse_html(src, path) {
|
|
@@ -140,7 +141,7 @@ class Tokenizer {
|
|
|
140
141
|
this.chars_consume('>');
|
|
141
142
|
|
|
142
143
|
tokens.push({
|
|
143
|
-
type:
|
|
144
|
+
type: TOKEN_TAG_END,
|
|
144
145
|
...position,
|
|
145
146
|
tag_name,
|
|
146
147
|
});
|
|
@@ -175,7 +176,7 @@ class Tokenizer {
|
|
|
175
176
|
this.chars_consume('>');
|
|
176
177
|
|
|
177
178
|
const start_token = {
|
|
178
|
-
type:
|
|
179
|
+
type: TOKEN_TAG_START,
|
|
179
180
|
...position,
|
|
180
181
|
tag_name,
|
|
181
182
|
props,
|
|
@@ -188,7 +189,7 @@ class Tokenizer {
|
|
|
188
189
|
return [
|
|
189
190
|
start_token,
|
|
190
191
|
{
|
|
191
|
-
type:
|
|
192
|
+
type: TOKEN_TAG_END,
|
|
192
193
|
...position,
|
|
193
194
|
tag_name,
|
|
194
195
|
}
|
|
@@ -250,7 +251,7 @@ function build_nodes(tokens, index, index_end) {
|
|
|
250
251
|
for (; index < index_end; index++) {
|
|
251
252
|
const token = tokens[index];
|
|
252
253
|
switch (token.type) {
|
|
253
|
-
case
|
|
254
|
+
case TOKEN_TAG_START: {
|
|
254
255
|
const {tag_name, props} = token;
|
|
255
256
|
const index_start = ++index;
|
|
256
257
|
|
|
@@ -259,10 +260,10 @@ function build_nodes(tokens, index, index_end) {
|
|
|
259
260
|
loop: for (; index < index_end; index++) {
|
|
260
261
|
const token = tokens[index];
|
|
261
262
|
switch (token.type) {
|
|
262
|
-
case
|
|
263
|
+
case TOKEN_TAG_START:
|
|
263
264
|
if (token.tag_name === tag_name) depth++;
|
|
264
265
|
break;
|
|
265
|
-
case
|
|
266
|
+
case TOKEN_TAG_END:
|
|
266
267
|
if (
|
|
267
268
|
token.tag_name === tag_name &&
|
|
268
269
|
--depth === 0
|
|
@@ -291,7 +292,7 @@ function build_nodes(tokens, index, index_end) {
|
|
|
291
292
|
});
|
|
292
293
|
break;
|
|
293
294
|
}
|
|
294
|
-
case
|
|
295
|
+
case TOKEN_TAG_END:
|
|
295
296
|
error(`Unexpected closing tag </${token.tag_name}>`, token);
|
|
296
297
|
case TOKEN_TEXT: {
|
|
297
298
|
let {value} = token;
|
|
@@ -333,7 +334,7 @@ function build_nodes(tokens, index, index_end) {
|
|
|
333
334
|
props: {
|
|
334
335
|
innerText: {
|
|
335
336
|
type: VALUE_TYPE_STATIC,
|
|
336
|
-
data: value,
|
|
337
|
+
data: html_unescape(value),
|
|
337
338
|
},
|
|
338
339
|
},
|
|
339
340
|
children: [],
|