@quenk/wml 2.13.11 → 2.14.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/lib/cli.d.ts +8 -8
- package/lib/cli.js +1 -3
- package/lib/cli.js.map +1 -1
- package/lib/cli.ts +48 -60
- package/lib/compile/codegen.d.ts +4 -9
- package/lib/compile/codegen.js +161 -367
- package/lib/compile/codegen.js.map +1 -1
- package/lib/compile/codegen.ts +643 -952
- package/lib/compile/index.d.ts +2 -2
- package/lib/compile/index.js +4 -4
- package/lib/compile/index.js.map +1 -1
- package/lib/compile/index.ts +14 -17
- package/lib/compile/transform.d.ts +1 -1
- package/lib/compile/transform.js +9 -11
- package/lib/compile/transform.js.map +1 -1
- package/lib/compile/transform.ts +136 -143
- package/lib/{dom.d.ts → dom/index.d.ts} +8 -2
- package/lib/{dom.js → dom/index.js} +84 -70
- package/lib/dom/index.js.map +1 -0
- package/lib/dom/index.ts +425 -0
- package/lib/dom/monitor.d.ts +33 -0
- package/lib/dom/monitor.js +60 -0
- package/lib/dom/monitor.js.map +1 -0
- package/lib/dom/monitor.ts +75 -0
- package/lib/index.d.ts +10 -95
- package/lib/index.js +10 -10
- package/lib/index.js.map +1 -1
- package/lib/index.ts +57 -182
- package/lib/main.js +17 -17
- package/lib/main.js.map +1 -1
- package/lib/main.ts +38 -44
- package/lib/parse/ast.d.ts +2 -2
- package/lib/parse/ast.js +52 -53
- package/lib/parse/ast.js.map +1 -1
- package/lib/parse/ast.ts +396 -483
- package/lib/parse/generated.d.ts +3 -5
- package/lib/parse/generated.js +9504 -9264
- package/lib/parse/index.d.ts +2 -3
- package/lib/parse/index.js.map +1 -1
- package/lib/parse/index.ts +7 -9
- package/lib/parse/test.js +194 -192
- package/lib/parse/test.js.map +1 -1
- package/lib/parse/test.ts +294 -404
- package/lib/parse/wml.y +4 -0
- package/lib/tsconfig.json +19 -20
- package/lib/util.d.ts +10 -0
- package/lib/util.js +21 -0
- package/lib/util.js.map +1 -0
- package/lib/util.ts +39 -0
- package/lib/view/frame.d.ts +127 -0
- package/lib/view/frame.js +214 -0
- package/lib/view/frame.js.map +1 -0
- package/lib/view/frame.ts +295 -0
- package/lib/view/index.d.ts +58 -0
- package/lib/view/index.js +48 -0
- package/lib/view/index.js.map +1 -0
- package/lib/view/index.ts +98 -0
- package/package.json +3 -3
- package/lib/dom.js.map +0 -1
- package/lib/dom.ts +0 -479
package/lib/dom.ts
DELETED
|
@@ -1,479 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This module provides functions used in templates to generate supported DOM
|
|
3
|
-
* nodes.
|
|
4
|
-
*
|
|
5
|
-
* The idea here is to provide an abstraction over DOM construction so
|
|
6
|
-
* we can detect whether we are in a browser or elsewhere and adjust to
|
|
7
|
-
* suite.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { Record, mapTo, forEach } from '@quenk/noni/lib/data/record';
|
|
11
|
-
import { Type, isFunction, isObject } from '@quenk/noni/lib/data/type';
|
|
12
|
-
|
|
13
|
-
const DOCTYPE = '<!DOCTYPE html>';
|
|
14
|
-
|
|
15
|
-
const ATTR_ESC_MAP: { [key: string]: string } = {
|
|
16
|
-
|
|
17
|
-
'&': '\\u0026',
|
|
18
|
-
|
|
19
|
-
'>': '\\u003e',
|
|
20
|
-
|
|
21
|
-
'<': '\\u003c',
|
|
22
|
-
|
|
23
|
-
'"': '\\u0022',
|
|
24
|
-
|
|
25
|
-
'=': '\\u003d',
|
|
26
|
-
|
|
27
|
-
'\u005c': '\\u005c',
|
|
28
|
-
|
|
29
|
-
'\u2028': '\\u2028',
|
|
30
|
-
|
|
31
|
-
'\u2029': '\\u2029'
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const attrsEscRegex = new RegExp(`[${mapTo(ATTR_ESC_MAP, (_, k) => k)}]`, 'g');
|
|
36
|
-
|
|
37
|
-
const HTML_ENT_MAP: { [key: string]: string } = {
|
|
38
|
-
|
|
39
|
-
'"': '"',
|
|
40
|
-
|
|
41
|
-
'&': '&',
|
|
42
|
-
|
|
43
|
-
'\'': ''',
|
|
44
|
-
|
|
45
|
-
'<': '<',
|
|
46
|
-
|
|
47
|
-
'>': '>'
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const htmlEscRegex = new RegExp(`[${mapTo(HTML_ENT_MAP, (_, k) => k).join('')}]`, 'g');
|
|
52
|
-
|
|
53
|
-
const voidElements = [
|
|
54
|
-
'area',
|
|
55
|
-
'base',
|
|
56
|
-
'br',
|
|
57
|
-
'col',
|
|
58
|
-
'command',
|
|
59
|
-
'embed',
|
|
60
|
-
'hr',
|
|
61
|
-
'img',
|
|
62
|
-
'input',
|
|
63
|
-
'keygen',
|
|
64
|
-
'link',
|
|
65
|
-
'meta',
|
|
66
|
-
'param',
|
|
67
|
-
'source',
|
|
68
|
-
'track',
|
|
69
|
-
'wbr'
|
|
70
|
-
];
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* WMLDOMAttrs is a record of attributes bound for a WMLDOMElement.
|
|
74
|
-
*/
|
|
75
|
-
export interface WMLDOMAttrs extends Record<string | number | Function> { }
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* WMLNodeList implementation.
|
|
79
|
-
* @private
|
|
80
|
-
*/
|
|
81
|
-
export class WMLNodeList implements NodeListOf<WMLDOMNode> {
|
|
82
|
-
|
|
83
|
-
[index: number]: WMLDOMNode,
|
|
84
|
-
|
|
85
|
-
length = 0;
|
|
86
|
-
|
|
87
|
-
item() {
|
|
88
|
-
|
|
89
|
-
return <WMLDOMNode><Type>null;
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
forEach() { }
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* WMLDOMNode implements the properties and methods of the DOM Node interface to
|
|
99
|
-
* allow a fake DOM to be built in server side code.
|
|
100
|
-
*
|
|
101
|
-
* Most of the methods and properties cannot be relied on and should not be
|
|
102
|
-
* used.
|
|
103
|
-
*/
|
|
104
|
-
export class WMLDOMNode implements Node {
|
|
105
|
-
|
|
106
|
-
constructor(public nodeName: string, public nodeType: number) { }
|
|
107
|
-
|
|
108
|
-
readonly ATTRIBUTE_NODE = 2;
|
|
109
|
-
|
|
110
|
-
readonly CDATA_SECTION_NODE = 4;
|
|
111
|
-
|
|
112
|
-
readonly COMMENT_NODE = 8;
|
|
113
|
-
|
|
114
|
-
readonly DOCUMENT_FRAGMENT_NODE = 11;
|
|
115
|
-
|
|
116
|
-
readonly DOCUMENT_NODE = 9;
|
|
117
|
-
|
|
118
|
-
readonly DOCUMENT_POSITION_CONTAINED_BY = 16;
|
|
119
|
-
|
|
120
|
-
readonly DOCUMENT_POSITION_CONTAINS = 8;
|
|
121
|
-
|
|
122
|
-
readonly DOCUMENT_POSITION_DISCONNECTED = 1;
|
|
123
|
-
|
|
124
|
-
readonly DOCUMENT_POSITION_FOLLOWING = 4;
|
|
125
|
-
|
|
126
|
-
readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 32;
|
|
127
|
-
|
|
128
|
-
readonly DOCUMENT_POSITION_PRECEDING = 2;
|
|
129
|
-
|
|
130
|
-
readonly DOCUMENT_TYPE_NODE = 10;
|
|
131
|
-
|
|
132
|
-
readonly ELEMENT_NODE = 1;
|
|
133
|
-
|
|
134
|
-
readonly ENTITY_NODE = 6;
|
|
135
|
-
|
|
136
|
-
readonly ENTITY_REFERENCE_NODE = 5;
|
|
137
|
-
|
|
138
|
-
readonly NOTATION_NODE = 12;
|
|
139
|
-
|
|
140
|
-
readonly PROCESSING_INSTRUCTION_NODE = 7;
|
|
141
|
-
|
|
142
|
-
readonly TEXT_NODE = 3;
|
|
143
|
-
|
|
144
|
-
baseURI = '';
|
|
145
|
-
|
|
146
|
-
childNodes = new WMLNodeList();
|
|
147
|
-
|
|
148
|
-
firstChild = null;
|
|
149
|
-
|
|
150
|
-
isConnected = false;
|
|
151
|
-
|
|
152
|
-
lastChild = null;
|
|
153
|
-
|
|
154
|
-
namespaceURI = null;
|
|
155
|
-
|
|
156
|
-
nextSibling = null;
|
|
157
|
-
|
|
158
|
-
nodeValue = null;
|
|
159
|
-
|
|
160
|
-
ownerDocument = null;
|
|
161
|
-
|
|
162
|
-
parentElement = null;
|
|
163
|
-
|
|
164
|
-
parentNode = null;
|
|
165
|
-
|
|
166
|
-
previousSibling = null;
|
|
167
|
-
|
|
168
|
-
get textContent() {
|
|
169
|
-
|
|
170
|
-
return '';
|
|
171
|
-
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
addEventListener() { }
|
|
175
|
-
|
|
176
|
-
dispatchEvent() {
|
|
177
|
-
|
|
178
|
-
return false;
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
removeEventListener() { }
|
|
183
|
-
|
|
184
|
-
appendChild<T extends Node>(newChild: T): T {
|
|
185
|
-
|
|
186
|
-
return newChild;
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
cloneNode() {
|
|
191
|
-
|
|
192
|
-
return this;
|
|
193
|
-
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
compareDocumentPosition() {
|
|
197
|
-
|
|
198
|
-
return 0;
|
|
199
|
-
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
contains() {
|
|
203
|
-
|
|
204
|
-
return false;
|
|
205
|
-
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
getRootNode(): Node {
|
|
209
|
-
|
|
210
|
-
return this;
|
|
211
|
-
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
hasChildNodes() {
|
|
215
|
-
|
|
216
|
-
return false;
|
|
217
|
-
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
insertBefore<T extends Node>(newChild: T): T {
|
|
221
|
-
|
|
222
|
-
return newChild;
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
isDefaultNamespace() {
|
|
227
|
-
|
|
228
|
-
return false;
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
isEqualNode() {
|
|
233
|
-
|
|
234
|
-
return false;
|
|
235
|
-
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
isSameNode() {
|
|
239
|
-
|
|
240
|
-
return false;
|
|
241
|
-
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
lookupNamespaceURI() {
|
|
245
|
-
|
|
246
|
-
return null;
|
|
247
|
-
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
lookupPrefix() {
|
|
251
|
-
|
|
252
|
-
return null;
|
|
253
|
-
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
normalize() { }
|
|
257
|
-
|
|
258
|
-
remove() { }
|
|
259
|
-
|
|
260
|
-
before() { }
|
|
261
|
-
|
|
262
|
-
after() { }
|
|
263
|
-
|
|
264
|
-
replaceWith() { }
|
|
265
|
-
|
|
266
|
-
removeChild<T extends Node>(oldChild: T): T {
|
|
267
|
-
|
|
268
|
-
return oldChild;
|
|
269
|
-
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
replaceChild<T extends Node>(_: Node, oldChild: T): T {
|
|
273
|
-
|
|
274
|
-
return oldChild;
|
|
275
|
-
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* WMLDOMText is used to represent Text nodes on the server side.
|
|
282
|
-
* @private
|
|
283
|
-
*/
|
|
284
|
-
export class WMLDOMText extends WMLDOMNode {
|
|
285
|
-
|
|
286
|
-
constructor(public value: string, public escape = true) {
|
|
287
|
-
|
|
288
|
-
super('#text', -1);
|
|
289
|
-
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
get textContent() {
|
|
293
|
-
|
|
294
|
-
return this.escape ? escapeHTML(this.value) : this.value;
|
|
295
|
-
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* WMLDOMElement is used to represent Element nodes on the server side.
|
|
302
|
-
* @private
|
|
303
|
-
*/
|
|
304
|
-
export class WMLDOMElement extends WMLDOMNode {
|
|
305
|
-
|
|
306
|
-
constructor(
|
|
307
|
-
public tag: string,
|
|
308
|
-
public attrs: WMLDOMAttrs,
|
|
309
|
-
public children: Node[] = []) { super(tag, -1); }
|
|
310
|
-
|
|
311
|
-
get innerHTML(): string {
|
|
312
|
-
|
|
313
|
-
return this.children.map(c => (c.nodeName === '#text') ?
|
|
314
|
-
(<Text>c).textContent :
|
|
315
|
-
(<HTMLElement>c).outerHTML
|
|
316
|
-
).join('');
|
|
317
|
-
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
get outerHTML() {
|
|
321
|
-
|
|
322
|
-
let { tag } = this;
|
|
323
|
-
let content = this.innerHTML;
|
|
324
|
-
|
|
325
|
-
let attrs = mapTo(this.attrs, (value, name) => {
|
|
326
|
-
|
|
327
|
-
if (isObject(value) && (value instanceof WMLDOMText))
|
|
328
|
-
return `${name}="${value.textContent}"`;
|
|
329
|
-
else if (isFunction(value) || isObject(value) || (value == null))
|
|
330
|
-
return '';
|
|
331
|
-
else
|
|
332
|
-
return `${name}="${escapeAttrValue(String(value))}"`
|
|
333
|
-
|
|
334
|
-
}).join(' ');
|
|
335
|
-
|
|
336
|
-
attrs = (attrs.trim() != '') ? ` ${attrs}` : '';
|
|
337
|
-
|
|
338
|
-
let open = `<${tag}${attrs}>`;
|
|
339
|
-
|
|
340
|
-
if (tag === "html")
|
|
341
|
-
open = `${DOCTYPE}${open}`
|
|
342
|
-
|
|
343
|
-
return (voidElements.indexOf(tag) > -1) ?
|
|
344
|
-
open : `${open}${content}</${tag}>`;
|
|
345
|
-
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
setAttribute(key: string, value: Type) {
|
|
349
|
-
|
|
350
|
-
this.attrs[key] = value;
|
|
351
|
-
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
appendChild<T extends Node>(newChild: T): T {
|
|
355
|
-
|
|
356
|
-
this.children.push(newChild);
|
|
357
|
-
return newChild;
|
|
358
|
-
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* isBrowser is set to true if we detect a window and document global variable.
|
|
365
|
-
*/
|
|
366
|
-
export const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
367
|
-
|
|
368
|
-
/**
|
|
369
|
-
* escapeAttrValue for safe browser display.
|
|
370
|
-
*/
|
|
371
|
-
export const escapeAttrValue = (value: string) =>
|
|
372
|
-
value.replace(attrsEscRegex, hit => ATTR_ESC_MAP[hit]);
|
|
373
|
-
|
|
374
|
-
/**
|
|
375
|
-
* escapeHTML for safe browser display.
|
|
376
|
-
*/
|
|
377
|
-
export const escapeHTML = (value: string) =>
|
|
378
|
-
value.replace(htmlEscRegex, hit => HTML_ENT_MAP[hit]);
|
|
379
|
-
|
|
380
|
-
/**
|
|
381
|
-
* createTextNode wrapper.
|
|
382
|
-
*/
|
|
383
|
-
export const createTextNode = (txt: Type): Node => {
|
|
384
|
-
let str = String((txt == null) ? '' : txt);
|
|
385
|
-
return isBrowser ? document.createTextNode(str) : new WMLDOMText(str);
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
/**
|
|
389
|
-
* createUnsafeNode allows raw strings to be output without escaping.
|
|
390
|
-
*
|
|
391
|
-
* THIS MUST ONLY BE USED IF YOU ARE 100% SURE THE STRING IS SAFE TO OUTPUT!
|
|
392
|
-
*/
|
|
393
|
-
export const createUnsafeNode = (txt: Type): Node => {
|
|
394
|
-
let str = String((txt == null) ? '' : txt);
|
|
395
|
-
return isBrowser ? createBrowserUnsafeNode(str) : new WMLDOMText(str, false);
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
const createBrowserUnsafeNode = (html: string) => {
|
|
399
|
-
let tmpl = document.createElement('template');
|
|
400
|
-
tmpl.innerHTML = html;
|
|
401
|
-
return tmpl.content;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
export { createTextNode as text, createUnsafeNode as unsafe }
|
|
405
|
-
|
|
406
|
-
const namespaces = new Map([
|
|
407
|
-
['svg', 'http://www.w3.org/2000/svg']
|
|
408
|
-
]);
|
|
409
|
-
|
|
410
|
-
/**
|
|
411
|
-
* createElement wrapper.
|
|
412
|
-
*/
|
|
413
|
-
export const createElement = (
|
|
414
|
-
tag: string,
|
|
415
|
-
attrs: WMLDOMAttrs = {},
|
|
416
|
-
children: Node[] = [],
|
|
417
|
-
ns = ''): Element => {
|
|
418
|
-
|
|
419
|
-
if (!isBrowser) {
|
|
420
|
-
|
|
421
|
-
// XXX: The whole Element interface is not implemented but on server
|
|
422
|
-
// side we are only interested in setAttribute.
|
|
423
|
-
return <Element><Type>new WMLDOMElement(tag, attrs, children);
|
|
424
|
-
|
|
425
|
-
} else {
|
|
426
|
-
|
|
427
|
-
let e = ns ?
|
|
428
|
-
document.createElementNS(namespaces.get(ns) ?? '', tag) :
|
|
429
|
-
document.createElement(tag);
|
|
430
|
-
|
|
431
|
-
forEach(attrs, (value: Type, key) => {
|
|
432
|
-
|
|
433
|
-
if (typeof value === 'function') {
|
|
434
|
-
|
|
435
|
-
(<Type>e)[key] = value;
|
|
436
|
-
|
|
437
|
-
} else if (typeof value === 'string') {
|
|
438
|
-
|
|
439
|
-
// prevent setting things like disabled=""
|
|
440
|
-
if (value !== '')
|
|
441
|
-
e.setAttribute(key, value);
|
|
442
|
-
|
|
443
|
-
} else if (typeof value === 'boolean') {
|
|
444
|
-
|
|
445
|
-
e.setAttribute(key, '');
|
|
446
|
-
|
|
447
|
-
} else if (!isBrowser && value instanceof WMLDOMText) {
|
|
448
|
-
|
|
449
|
-
e.setAttribute(key, <Type>value);
|
|
450
|
-
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
});
|
|
454
|
-
|
|
455
|
-
children.forEach(c => {
|
|
456
|
-
|
|
457
|
-
switch (typeof c) {
|
|
458
|
-
|
|
459
|
-
case 'string':
|
|
460
|
-
case 'number':
|
|
461
|
-
case 'boolean':
|
|
462
|
-
e.appendChild(<Node>document.createTextNode('' + c));
|
|
463
|
-
case 'object':
|
|
464
|
-
e.appendChild(<Node>c);
|
|
465
|
-
break;
|
|
466
|
-
default:
|
|
467
|
-
throw new TypeError(
|
|
468
|
-
`Can not adopt child ${c} of type ${typeof c}`
|
|
469
|
-
);
|
|
470
|
-
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
});
|
|
474
|
-
|
|
475
|
-
return e;
|
|
476
|
-
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
}
|