@quenk/wml 2.13.10 → 2.14.0
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 +164 -369
- package/lib/compile/codegen.js.map +1 -1
- package/lib/compile/codegen.ts +644 -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 +8 -6
- package/lib/compile/transform.js +46 -18
- package/lib/compile/transform.js.map +1 -1
- package/lib/compile/transform.ts +139 -116
- package/lib/{dom.d.ts → dom/index.d.ts} +8 -2
- package/lib/{dom.js → dom/index.js} +84 -66
- 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 +12 -6
- package/lib/parse/ast.js +68 -58
- package/lib/parse/ast.js.map +1 -1
- package/lib/parse/ast.ts +400 -482
- 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 +103 -0
- package/lib/view/frame.js +206 -0
- package/lib/view/frame.js.map +1 -0
- package/lib/view/frame.ts +249 -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 +97 -0
- package/package.json +4 -3
- package/lib/dom.js.map +0 -1
- package/lib/dom.ts +0 -475
package/lib/compile/index.d.ts
CHANGED
package/lib/compile/index.js
CHANGED
|
@@ -6,13 +6,13 @@ const record_1 = require("@quenk/noni/lib/data/record");
|
|
|
6
6
|
const parse_1 = require("../parse");
|
|
7
7
|
const codegen_1 = require("./codegen");
|
|
8
8
|
const defaultOptions = {
|
|
9
|
-
module:
|
|
10
|
-
dom:
|
|
11
|
-
EOL: os.EOL
|
|
9
|
+
module: "@quenk/wml",
|
|
10
|
+
dom: "@quenk/wml/lib/dom",
|
|
11
|
+
EOL: os.EOL,
|
|
12
12
|
};
|
|
13
13
|
/**
|
|
14
14
|
* compile a string of WML text directly into typescript.
|
|
15
15
|
*/
|
|
16
|
-
const compile = (src, opts = {}) => (0, parse_1.parse)(src).map(m => codegen_1.CodeGenerator.create((0, record_1.merge)(defaultOptions, opts)).generate(m));
|
|
16
|
+
const compile = (src, opts = {}) => (0, parse_1.parse)(src).map((m) => codegen_1.CodeGenerator.create((0, record_1.merge)(defaultOptions, opts)).generate(m));
|
|
17
17
|
exports.compile = compile;
|
|
18
18
|
//# sourceMappingURL=index.js.map
|
package/lib/compile/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;AAAA,yBAAyB;AAEzB,wDAAoD;AAGpD,oCAAiC;AACjC,uCAAgE;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;AAAA,yBAAyB;AAEzB,wDAAoD;AAGpD,oCAAiC;AACjC,uCAAgE;AAgBhE,MAAM,cAAc,GAAG;IACrB,MAAM,EAAE,YAAY;IAEpB,GAAG,EAAE,oBAAoB;IAEzB,GAAG,EAAE,EAAE,CAAC,GAAG;CACZ,CAAC;AAEF;;GAEG;AACI,MAAM,OAAO,GAAG,CAAC,GAAW,EAAE,OAAgB,EAAE,EAAkB,EAAE,CACzE,IAAA,aAAK,EAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACnB,uBAAa,CAAC,MAAM,CAAC,IAAA,cAAK,EAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAC9D,CAAC;AAHS,QAAA,OAAO,WAGhB"}
|
package/lib/compile/index.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import * as os from
|
|
1
|
+
import * as os from "os";
|
|
2
2
|
|
|
3
|
-
import { merge } from
|
|
4
|
-
import { Except } from
|
|
3
|
+
import { merge } from "@quenk/noni/lib/data/record";
|
|
4
|
+
import { Except } from "@quenk/noni/lib/control/error";
|
|
5
5
|
|
|
6
|
-
import { parse } from
|
|
7
|
-
import { CodeGenerator, CodeGeneratorOptions } from
|
|
6
|
+
import { parse } from "../parse";
|
|
7
|
+
import { CodeGenerator, CodeGeneratorOptions } from "./codegen";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* TypeScript output.
|
|
@@ -15,26 +15,23 @@ export type TypeScript = string;
|
|
|
15
15
|
* Options for changing the behaviour of compilation.
|
|
16
16
|
*/
|
|
17
17
|
export interface Options extends Partial<CodeGeneratorOptions> {
|
|
18
|
+
debug?: boolean;
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
main?: string,
|
|
22
|
-
|
|
20
|
+
main?: string;
|
|
23
21
|
}
|
|
24
22
|
|
|
25
23
|
const defaultOptions = {
|
|
24
|
+
module: "@quenk/wml",
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
dom: '@quenk/wml/lib/dom',
|
|
26
|
+
dom: "@quenk/wml/lib/dom",
|
|
30
27
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
28
|
+
EOL: os.EOL,
|
|
29
|
+
};
|
|
34
30
|
|
|
35
31
|
/**
|
|
36
32
|
* compile a string of WML text directly into typescript.
|
|
37
33
|
*/
|
|
38
34
|
export const compile = (src: string, opts: Options = {}): Except<string> =>
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
parse(src).map((m) =>
|
|
36
|
+
CodeGenerator.create(merge(defaultOptions, opts)).generate(m),
|
|
37
|
+
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as ast from
|
|
1
|
+
import * as ast from "../parse/ast";
|
|
2
2
|
/**
|
|
3
3
|
* rewriteViewContext normalizes the various forms of the context declaration
|
|
4
4
|
* in a view statement.
|
|
@@ -7,14 +7,16 @@ import * as ast from '../parse/ast';
|
|
|
7
7
|
* <view-type>Context, imports are included in the module's import list.
|
|
8
8
|
*/
|
|
9
9
|
export declare const rewriteViewStatementContext: (tree: ast.Module, node: ast.ViewStatement) => ast.Export[];
|
|
10
|
+
export declare const TAG_NAME_SVG = "svg";
|
|
10
11
|
/**
|
|
11
|
-
*
|
|
12
|
-
* to the `wml:ns` attribute recursively.
|
|
12
|
+
* tagSVGNodes traverses the tree to detect any embedded svg.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
14
|
+
* If an svg parent tag is found, it and all its children will receive a
|
|
15
|
+
* wml:ns=svg attribute. This will cause the runtime to use createElementNS()
|
|
16
|
+
* instead of createElement, allowing the svg document to be treated as SVG
|
|
17
|
+
* and not HTML DOM.
|
|
16
18
|
*/
|
|
17
|
-
export declare const
|
|
19
|
+
export declare const tagSVGNodes: (tag: ast.Tag) => ast.Tag;
|
|
18
20
|
/**
|
|
19
21
|
* transformTree applies all the needed transforms to the AST before
|
|
20
22
|
* compilation.
|
package/lib/compile/transform.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.transformTree = exports.
|
|
3
|
+
exports.transformTree = exports.tagSVGNodes = exports.TAG_NAME_SVG = exports.rewriteViewStatementContext = void 0;
|
|
4
4
|
const ast = require("../parse/ast");
|
|
5
|
+
const codegen_1 = require("./codegen");
|
|
5
6
|
/**
|
|
6
7
|
* rewriteViewContext normalizes the various forms of the context declaration
|
|
7
8
|
* in a view statement.
|
|
@@ -21,11 +22,9 @@ const rewriteViewStatementContext = (tree, node) => {
|
|
|
21
22
|
else if (node.context instanceof ast.ContextFromStatement) {
|
|
22
23
|
let { context } = node;
|
|
23
24
|
let { location } = context;
|
|
24
|
-
tree.imports.push(new ast.ImportStatement(new ast.CompositeMember([
|
|
25
|
-
context.cons.id
|
|
26
|
-
], location), context.module, location));
|
|
25
|
+
tree.imports.push(new ast.ImportStatement(new ast.CompositeMember([context.cons.id], location), context.module, location));
|
|
27
26
|
return [
|
|
28
|
-
new ast.ViewStatement(node.id, node.typeParameters, context.cons, node.directives, node.root, node.location)
|
|
27
|
+
new ast.ViewStatement(node.id, node.typeParameters, context.cons, node.directives, node.root, node.location),
|
|
29
28
|
];
|
|
30
29
|
}
|
|
31
30
|
else {
|
|
@@ -33,24 +32,53 @@ const rewriteViewStatementContext = (tree, node) => {
|
|
|
33
32
|
}
|
|
34
33
|
};
|
|
35
34
|
exports.rewriteViewStatementContext = rewriteViewStatementContext;
|
|
35
|
+
exports.TAG_NAME_SVG = "svg";
|
|
36
36
|
/**
|
|
37
|
-
*
|
|
38
|
-
* to the `wml:ns` attribute recursively.
|
|
37
|
+
* tagSVGNodes traverses the tree to detect any embedded svg.
|
|
39
38
|
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
39
|
+
* If an svg parent tag is found, it and all its children will receive a
|
|
40
|
+
* wml:ns=svg attribute. This will cause the runtime to use createElementNS()
|
|
41
|
+
* instead of createElement, allowing the svg document to be treated as SVG
|
|
42
|
+
* and not HTML DOM.
|
|
42
43
|
*/
|
|
43
|
-
const
|
|
44
|
-
let
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
const tagSVGNodes = (tag) => {
|
|
45
|
+
let pending = [[false, [tag]]];
|
|
46
|
+
while (pending.length) {
|
|
47
|
+
let [isSvg, stack] = pending.pop();
|
|
48
|
+
while (stack.length) {
|
|
49
|
+
let next = stack.pop();
|
|
50
|
+
if (next instanceof ast.Node &&
|
|
51
|
+
(0, codegen_1.identifierOrConstructor2TS)(next.open) === exports.TAG_NAME_SVG &&
|
|
52
|
+
!isSvg) {
|
|
53
|
+
pending.push([true, [next]]);
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
let childrens = [];
|
|
57
|
+
if (next instanceof ast.Node) {
|
|
58
|
+
if (isSvg)
|
|
59
|
+
next.attributes.push(new ast.Attribute(new ast.UnqualifiedIdentifier("wml", {}), new ast.UnqualifiedIdentifier("ns", {}), new ast.StringLiteral("svg", {}), {}));
|
|
60
|
+
childrens.push(next.children);
|
|
61
|
+
}
|
|
62
|
+
else if (next instanceof ast.Widget || next instanceof ast.ElseClause) {
|
|
63
|
+
childrens.push(next.children);
|
|
64
|
+
}
|
|
65
|
+
else if (next instanceof ast.ForOfStatement) {
|
|
66
|
+
childrens.push(next.body, next.otherwise);
|
|
67
|
+
}
|
|
68
|
+
else if (next instanceof ast.IfStatement ||
|
|
69
|
+
next instanceof ast.ElseIfClause) {
|
|
70
|
+
childrens.push(next.then);
|
|
71
|
+
if (next.elseClause)
|
|
72
|
+
childrens.push([next.elseClause]);
|
|
73
|
+
}
|
|
74
|
+
for (let children of childrens)
|
|
75
|
+
for (let child of children)
|
|
76
|
+
stack.push(child);
|
|
77
|
+
}
|
|
48
78
|
}
|
|
49
|
-
tag.children = tag.children.map(child => ((child instanceof ast.Node) || (child instanceof ast.Widget)) ?
|
|
50
|
-
(0, exports.tagXMLNamespaces)(child, attr) : child);
|
|
51
79
|
return tag;
|
|
52
80
|
};
|
|
53
|
-
exports.
|
|
81
|
+
exports.tagSVGNodes = tagSVGNodes;
|
|
54
82
|
/**
|
|
55
83
|
* transformTree applies all the needed transforms to the AST before
|
|
56
84
|
* compilation.
|
|
@@ -59,7 +87,7 @@ const transformTree = (tree) => {
|
|
|
59
87
|
let newTree = tree.clone(); // Try not to modify what we don't own.
|
|
60
88
|
newTree.exports = tree.exports.reduce((prev, next) => {
|
|
61
89
|
if (next instanceof ast.ViewStatement) {
|
|
62
|
-
next.root = (0, exports.
|
|
90
|
+
next.root = (0, exports.tagSVGNodes)(next.root);
|
|
63
91
|
return [...prev, ...(0, exports.rewriteViewStatementContext)(newTree, next)];
|
|
64
92
|
}
|
|
65
93
|
else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.js","sourceRoot":"","sources":["transform.ts"],"names":[],"mappings":";;;AAAA,oCAAoC;
|
|
1
|
+
{"version":3,"file":"transform.js","sourceRoot":"","sources":["transform.ts"],"names":[],"mappings":"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"}
|
package/lib/compile/transform.ts
CHANGED
|
@@ -1,133 +1,156 @@
|
|
|
1
|
-
import * as ast from
|
|
1
|
+
import * as ast from "../parse/ast";
|
|
2
|
+
import { identifierOrConstructor2TS } from "./codegen";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* rewriteViewContext normalizes the various forms of the context declaration
|
|
5
6
|
* in a view statement.
|
|
6
7
|
*
|
|
7
|
-
* "where" clauses are turned into context declarations with id
|
|
8
|
+
* "where" clauses are turned into context declarations with id
|
|
8
9
|
* <view-type>Context, imports are included in the module's import list.
|
|
9
10
|
*/
|
|
10
|
-
export const rewriteViewStatementContext =
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
11
|
+
export const rewriteViewStatementContext = (
|
|
12
|
+
tree: ast.Module,
|
|
13
|
+
node: ast.ViewStatement,
|
|
14
|
+
): ast.Export[] => {
|
|
15
|
+
if (Array.isArray(node.context)) {
|
|
16
|
+
// TODO: Is this branch still needed?
|
|
17
|
+
|
|
18
|
+
let contextName = `${node.id.value}Context`;
|
|
19
|
+
|
|
20
|
+
let context = new ast.ContextStatement(
|
|
21
|
+
new ast.UnqualifiedIdentifier(contextName, node.id.location),
|
|
22
|
+
node.typeParameters,
|
|
23
|
+
node.context,
|
|
24
|
+
node.location,
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
let consType = new ast.ConstructorType(
|
|
28
|
+
context.id,
|
|
29
|
+
context.typeParameters,
|
|
30
|
+
context.location,
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
let view = new ast.ViewStatement(
|
|
34
|
+
node.id,
|
|
35
|
+
node.typeParameters,
|
|
36
|
+
consType,
|
|
37
|
+
node.directives,
|
|
38
|
+
node.root,
|
|
39
|
+
node.location,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
return [context, view];
|
|
43
|
+
} else if (node.context instanceof ast.ContextFromStatement) {
|
|
44
|
+
let { context } = node;
|
|
45
|
+
|
|
46
|
+
let { location } = context;
|
|
47
|
+
|
|
48
|
+
tree.imports.push(
|
|
49
|
+
new ast.ImportStatement(
|
|
50
|
+
new ast.CompositeMember(
|
|
51
|
+
[<ast.UnqualifiedConstructor>context.cons.id],
|
|
52
|
+
location,
|
|
53
|
+
),
|
|
54
|
+
context.module,
|
|
55
|
+
location,
|
|
56
|
+
),
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
return [
|
|
60
|
+
new ast.ViewStatement(
|
|
61
|
+
node.id,
|
|
62
|
+
node.typeParameters,
|
|
63
|
+
context.cons,
|
|
64
|
+
node.directives,
|
|
65
|
+
node.root,
|
|
66
|
+
node.location,
|
|
67
|
+
),
|
|
68
|
+
];
|
|
69
|
+
} else {
|
|
70
|
+
return [node];
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const TAG_NAME_SVG = "svg";
|
|
74
75
|
|
|
75
76
|
/**
|
|
76
|
-
*
|
|
77
|
-
* to the `wml:ns` attribute recursively.
|
|
77
|
+
* tagSVGNodes traverses the tree to detect any embedded svg.
|
|
78
78
|
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
79
|
+
* If an svg parent tag is found, it and all its children will receive a
|
|
80
|
+
* wml:ns=svg attribute. This will cause the runtime to use createElementNS()
|
|
81
|
+
* instead of createElement, allowing the svg document to be treated as SVG
|
|
82
|
+
* and not HTML DOM.
|
|
81
83
|
*/
|
|
82
|
-
export const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
84
|
+
export const tagSVGNodes = (tag: ast.Tag) => {
|
|
85
|
+
let pending: [boolean, object[]][] = [[false, [tag]]];
|
|
86
|
+
|
|
87
|
+
while (pending.length) {
|
|
88
|
+
let [isSvg, stack] = <[boolean, object[]]>pending.pop();
|
|
89
|
+
|
|
90
|
+
while (stack.length) {
|
|
91
|
+
let next = stack.pop();
|
|
92
|
+
|
|
93
|
+
if (
|
|
94
|
+
next instanceof ast.Node &&
|
|
95
|
+
identifierOrConstructor2TS(next.open) === TAG_NAME_SVG &&
|
|
96
|
+
!isSvg
|
|
97
|
+
) {
|
|
98
|
+
pending.push([true, [next]]);
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
let childrens = [];
|
|
103
|
+
if (next instanceof ast.Node) {
|
|
104
|
+
if (isSvg)
|
|
105
|
+
next.attributes.push(
|
|
106
|
+
new ast.Attribute(
|
|
107
|
+
new ast.UnqualifiedIdentifier("wml", {}),
|
|
108
|
+
new ast.UnqualifiedIdentifier("ns", {}),
|
|
109
|
+
new ast.StringLiteral("svg", {}),
|
|
110
|
+
{},
|
|
111
|
+
),
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
childrens.push(next.children);
|
|
115
|
+
} else if (next instanceof ast.Widget || next instanceof ast.ElseClause) {
|
|
116
|
+
childrens.push(next.children);
|
|
117
|
+
} else if (next instanceof ast.ForOfStatement) {
|
|
118
|
+
childrens.push(next.body, next.otherwise);
|
|
119
|
+
} else if (
|
|
120
|
+
next instanceof ast.IfStatement ||
|
|
121
|
+
next instanceof ast.ElseIfClause
|
|
122
|
+
) {
|
|
123
|
+
childrens.push(next.then);
|
|
124
|
+
if (next.elseClause) childrens.push([next.elseClause]);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
for (let children of childrens)
|
|
128
|
+
for (let child of children) stack.push(child);
|
|
106
129
|
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return tag;
|
|
133
|
+
};
|
|
107
134
|
|
|
108
135
|
/**
|
|
109
|
-
* transformTree applies all the needed transforms to the AST before
|
|
136
|
+
* transformTree applies all the needed transforms to the AST before
|
|
110
137
|
* compilation.
|
|
111
138
|
*/
|
|
112
139
|
export const transformTree = (tree: ast.Module) => {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
return newTree;
|
|
132
|
-
|
|
133
|
-
}
|
|
140
|
+
let newTree = tree.clone(); // Try not to modify what we don't own.
|
|
141
|
+
|
|
142
|
+
newTree.exports = tree.exports.reduce(
|
|
143
|
+
(prev, next) => {
|
|
144
|
+
if (next instanceof ast.ViewStatement) {
|
|
145
|
+
next.root = tagSVGNodes(next.root);
|
|
146
|
+
|
|
147
|
+
return [...prev, ...rewriteViewStatementContext(newTree, next)];
|
|
148
|
+
} else {
|
|
149
|
+
return [...prev, next];
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
<ast.Export[]>[],
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
return newTree;
|
|
156
|
+
};
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* we can detect whether we are in a browser or elsewhere and adjust to
|
|
7
7
|
* suite.
|
|
8
8
|
*/
|
|
9
|
-
import { Record } from
|
|
10
|
-
import { Type } from
|
|
9
|
+
import { Record } from "@quenk/noni/lib/data/record";
|
|
10
|
+
import { Type } from "@quenk/noni/lib/data/type";
|
|
11
11
|
/**
|
|
12
12
|
* WMLDOMAttrs is a record of attributes bound for a WMLDOMElement.
|
|
13
13
|
*/
|
|
@@ -18,6 +18,11 @@ export interface WMLDOMAttrs extends Record<string | number | Function> {
|
|
|
18
18
|
* @private
|
|
19
19
|
*/
|
|
20
20
|
export declare class WMLNodeList implements NodeListOf<WMLDOMNode> {
|
|
21
|
+
entries(): ArrayIterator<[number, WMLDOMNode]>;
|
|
22
|
+
keys(): ArrayIterator<number>;
|
|
23
|
+
values(): ArrayIterator<WMLDOMNode>;
|
|
24
|
+
[Symbol.iterator](): ArrayIterator<WMLDOMNode>;
|
|
25
|
+
[Symbol.dispose](): void;
|
|
21
26
|
[index: number]: WMLDOMNode;
|
|
22
27
|
length: number;
|
|
23
28
|
item(): WMLDOMNode;
|
|
@@ -65,6 +70,7 @@ export declare class WMLDOMNode implements Node {
|
|
|
65
70
|
parentNode: null;
|
|
66
71
|
previousSibling: null;
|
|
67
72
|
get textContent(): string;
|
|
73
|
+
[Symbol.dispose](): void;
|
|
68
74
|
addEventListener(): void;
|
|
69
75
|
dispatchEvent(): boolean;
|
|
70
76
|
removeEventListener(): void;
|