nsp-server-pages 0.1.1 → 0.2.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.
Files changed (40) hide show
  1. package/cjs/index.js +6 -1
  2. package/cjs/package.json +1 -0
  3. package/cjs/src/app.js +20 -20
  4. package/cjs/src/catch.js +10 -9
  5. package/cjs/src/loaders.js +1 -1
  6. package/cjs/src/mount.js +6 -6
  7. package/cjs/src/parser/attr.js +92 -0
  8. package/{src/parse-el.js → cjs/src/parser/el.js} +15 -28
  9. package/cjs/src/parser/jsp.js +88 -0
  10. package/cjs/src/parser/scriptlet.js +47 -0
  11. package/cjs/src/parser/tag.js +130 -0
  12. package/{src/parse-text.js → cjs/src/parser/text.js} +13 -25
  13. package/cjs/src/stack-store.js +31 -0
  14. package/cjs/src/taglib.js +7 -7
  15. package/esm/index.js +2 -0
  16. package/esm/package.json +4 -0
  17. package/{src → esm/src}/app.js +19 -19
  18. package/{src → esm/src}/catch.js +10 -9
  19. package/{src → esm/src}/mount.js +6 -6
  20. package/esm/src/parser/attr.js +88 -0
  21. package/{cjs/src/parse-el.js → esm/src/parser/el.js} +11 -32
  22. package/esm/src/parser/jsp.js +83 -0
  23. package/esm/src/parser/scriptlet.js +43 -0
  24. package/esm/src/parser/tag.js +126 -0
  25. package/{cjs/src/parse-text.js → esm/src/parser/text.js} +9 -29
  26. package/esm/src/stack-store.js +27 -0
  27. package/{src → esm/src}/taglib.js +7 -7
  28. package/package.json +14 -13
  29. package/types/hooks.d.ts +103 -0
  30. package/{index.d.ts → types/index.d.ts} +62 -40
  31. package/cjs/src/parse-attr.js +0 -91
  32. package/cjs/src/parse-jsp.js +0 -206
  33. package/cjs/src/parse-scriptlet.js +0 -71
  34. package/index.js +0 -1
  35. package/src/parse-attr.js +0 -87
  36. package/src/parse-jsp.js +0 -201
  37. package/src/parse-scriptlet.js +0 -67
  38. /package/{src → esm/src}/bundle.js +0 -0
  39. /package/{src → esm/src}/concat.js +0 -0
  40. /package/{src → esm/src}/loaders.js +0 -0
@@ -1,206 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.jspToJS = exports.parseJSP = void 0;
4
- const parse_text_js_1 = require("./parse-text.js");
5
- const parse_attr_js_1 = require("./parse-attr.js");
6
- const parse_scriptlet_js_1 = require("./parse-scriptlet.js");
7
- const emptyText = {
8
- '""': true,
9
- "''": true,
10
- "``": true,
11
- "null": true,
12
- "undefined": true,
13
- "": true,
14
- };
15
- const isElement = (node) => ("function" === typeof node?.toJS);
16
- /**
17
- * Parser for JSP document
18
- */
19
- const parseJSP = (app, src) => new JspParser(app, src);
20
- exports.parseJSP = parseJSP;
21
- /**
22
- * Root element or an taglib element
23
- */
24
- class Element {
25
- constructor(app, tagName, tagLine) {
26
- this.app = app;
27
- this.tagName = tagName;
28
- this.tagLine = tagLine;
29
- this.children = [];
30
- //
31
- }
32
- append(node) {
33
- this.children.push(node);
34
- }
35
- /**
36
- * Transpile JSP document to JavaScript source code
37
- */
38
- toJS(option) {
39
- const { app, tagLine } = this;
40
- const { comment, nspName, trimSpaces, vName } = app.options;
41
- const indent = +app.options.indent || 0;
42
- const currentIndent = +option?.indent || 0;
43
- const nextIndent = currentIndent + indent;
44
- const currentLF = currentIndent ? "\n" + " ".repeat(currentIndent) : "\n";
45
- const nextLF = nextIndent ? "\n" + " ".repeat(nextIndent) : "\n";
46
- const { children } = this;
47
- const args = children.map(item => {
48
- if (isElement(item)) {
49
- return item.toJS({ indent: nextIndent });
50
- }
51
- else if (!/\S/.test(item)) {
52
- // item with only whitespace
53
- return (trimSpaces !== false) ? '""' : JSON.stringify(item);
54
- }
55
- else {
56
- if (trimSpaces !== false) {
57
- item = item.replace(/^\s*[\r\n]/s, "\n");
58
- item = item.replace(/\s*[\r\n]\s*$/s, "\n");
59
- item = item.replace(/^[ \t]+/s, " ");
60
- item = item.replace(/[ \t]+$/s, " ");
61
- }
62
- let js = (0, parse_text_js_1.parseText)(app, item).toJS({ indent: nextIndent });
63
- if (/\(.+?\)|\$\{.+?}/s.test(js)) {
64
- js = `${vName} => ${js}`; // array function
65
- }
66
- return js;
67
- }
68
- }).filter(v => !emptyText[v]);
69
- const hasBody = !!children.length;
70
- // keep at least single empty string if all arguments are empty strings
71
- if (hasBody && !args.length) {
72
- args.push('""');
73
- }
74
- const { tagName } = this;
75
- const isRoot = !tagName;
76
- const last = args.length - 1;
77
- args.forEach((v, idx) => {
78
- const isComment = /^\/\/[^\n]*$/s.test(v);
79
- if (idx !== last && !isComment) {
80
- args[idx] += ",";
81
- }
82
- else if (idx === last && isComment) {
83
- args[idx] += currentLF;
84
- }
85
- });
86
- let body = args.join(nextLF);
87
- const bodyL = /^`\n/s.test(body) ? (isRoot ? "" : " ") : nextLF;
88
- const bodyR = /(\n`|[)\s])$/s.test(body) ? "" : currentLF;
89
- if (isRoot) {
90
- return `${nspName}.bundle(${bodyL}${body}${bodyR})`; // root element
91
- }
92
- // attributes as the second argument
93
- let attr = (0, parse_attr_js_1.parseAttr)(app, tagLine).toJS({ indent: args.length ? nextIndent : currentIndent });
94
- if (/\(.+?\)|\$\{.+?}/s.test(attr)) {
95
- attr = `${vName} => (${attr})`; // array function
96
- }
97
- const commentV = comment ? `// ${tagLine?.replace(/\s*[\r\n]\s*/g, " ") ?? ""}${currentLF}` : "";
98
- const nameV = JSON.stringify(tagName);
99
- const hasAttr = /:/.test(attr);
100
- const attrV = (hasBody || hasAttr) ? `, ${attr}` : "";
101
- const bodyV = hasBody ? `,${bodyL}${body}${bodyR}` : "";
102
- return `${commentV}${nspName}.tag(${nameV}${attrV}${bodyV})`;
103
- }
104
- }
105
- /**
106
- * Tree of elements
107
- */
108
- class Tree {
109
- constructor(root) {
110
- this.root = root;
111
- this.tree = [];
112
- this.tree.push(root);
113
- }
114
- append(node) {
115
- this.tree.at(0).append(node);
116
- }
117
- open(node) {
118
- this.append(node);
119
- this.tree.unshift(node);
120
- }
121
- close(tagName) {
122
- const openTag = this.getTagName();
123
- if (openTag !== tagName) {
124
- throw new Error(`mismatch closing tag: ${openTag} !== ${tagName}`);
125
- }
126
- this.tree.shift();
127
- }
128
- getTagName() {
129
- return this.tree.at(0).tagName;
130
- }
131
- isRoot() {
132
- return this.tree.length === 1;
133
- }
134
- }
135
- class JspParser {
136
- constructor(app, src) {
137
- this.app = app;
138
- this.src = src;
139
- //
140
- }
141
- /**
142
- * Transpile JSP document to JavaScript source code
143
- */
144
- toJS(option) {
145
- const { app, src } = this;
146
- return (0, exports.jspToJS)(app, src, option);
147
- }
148
- /**
149
- * Compile JSP document to JavaScript function
150
- */
151
- toFn() {
152
- const { app } = this;
153
- const { nspName } = app.options;
154
- const js = this.toJS();
155
- try {
156
- const fn = Function(nspName, `return ${js}`);
157
- return fn(app);
158
- }
159
- catch (e) {
160
- app.log("JspParser: " + js?.substring(0, 1000));
161
- throw e;
162
- }
163
- }
164
- }
165
- const nameRE = `[A-Za-z][A-Za-z0-9]*`;
166
- const stringRE = `"(?:\\\\[.]|[^\\\\"])*"|'(?:\\\\[.]|[^\\\\'])*'`;
167
- const insideRE = `[^"']|${stringRE}`;
168
- const tagRegExp = new RegExp(`(</?${nameRE}:(?:${insideRE})*?>)|(<%(?:${insideRE})*?%>)`, "s");
169
- const jspToJS = (app, src, option) => {
170
- const root = new Element(app);
171
- const tree = new Tree(root);
172
- const array = src.split(tagRegExp);
173
- for (let i = 0; i < array.length; i++) {
174
- const i3 = i % 3;
175
- let str = array[i];
176
- if (i3 === 1 && str) {
177
- // taglib
178
- const tagName = str.match(/^<\/?([^\s=/>]+)/)?.[1];
179
- if (/^<\//.test(str)) {
180
- tree.close(tagName);
181
- continue;
182
- }
183
- const element = new Element(app, tagName, str);
184
- if (/\/\s*>$/.test(str)) {
185
- tree.append(element);
186
- }
187
- else {
188
- tree.open(element);
189
- }
190
- }
191
- else if (i3 === 2 && str) {
192
- // <% scriptlet %>
193
- const item = (0, parse_scriptlet_js_1.parseScriptlet)(app, str);
194
- tree.append(item);
195
- }
196
- else if (i3 === 0) {
197
- // text node
198
- tree.append(str);
199
- }
200
- }
201
- if (!tree.isRoot()) {
202
- throw new Error("missing closing tag: " + tree.getTagName());
203
- }
204
- return root.toJS(option);
205
- };
206
- exports.jspToJS = jspToJS;
@@ -1,71 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseScriptlet = void 0;
4
- const parse_el_js_1 = require("./parse-el.js");
5
- /**
6
- * Parser for Directive, Declaration, Scriptlet
7
- * <%-- comment --%>
8
- * <%@ directive %>
9
- * <%! declaration(s) %>
10
- * <% scriptlet %>
11
- * <%= expression %>
12
- */
13
- const parseScriptlet = (app, src) => new ScriptletParser(app, src);
14
- exports.parseScriptlet = parseScriptlet;
15
- const typeMap = {
16
- "<%-": "comment",
17
- "<%@": "directive",
18
- "<%!": "declaration",
19
- "<%=": "expression",
20
- };
21
- class ScriptletParser {
22
- constructor(app, src) {
23
- this.app = app;
24
- this.src = src;
25
- //
26
- }
27
- /**
28
- * Compile <% scriptlet %> to JavaScript function instance
29
- */
30
- toFn() {
31
- const { app } = this;
32
- const { nspName } = app.options;
33
- const js = this.toJS();
34
- const isComment = /^\/\/[^\n]*$/s.test(js);
35
- if (isComment)
36
- return () => null;
37
- try {
38
- const fn = Function(nspName, `return ${js}`);
39
- return fn(app);
40
- }
41
- catch (e) {
42
- app.log("ScriptletParser: " + js?.substring(0, 1000));
43
- throw e;
44
- }
45
- }
46
- /**
47
- * Transpile <% scriptlet %> to JavaScript source code
48
- */
49
- toJS(option) {
50
- const { app } = this;
51
- const { nspName, vName } = app.options;
52
- const currentIndent = +option?.indent || 0;
53
- const currentLF = currentIndent ? "\n" + " ".repeat(currentIndent) : "\n";
54
- let { src } = this;
55
- const type = typeMap[src.substring(0, 3)] || "scriptlet";
56
- if (type === "comment") {
57
- src = src.replace(/[ \t]*[\r\n]+/sg, `${currentLF}// `);
58
- return `// ${src}`;
59
- }
60
- if (type === "expression") {
61
- src = src.replace(/^<%=\s*/s, "");
62
- src = src.replace(/\s*%>$/s, "");
63
- src = (0, parse_el_js_1.parseEL)(app, src).toJS(option);
64
- return `${vName} => (${src})`;
65
- }
66
- app.log(`${type} found: ${src?.substring(0, 1000)}`);
67
- src = /`|\$\{/.test(src) ? JSON.stringify(src) : "`" + src + "`";
68
- src = `${vName} => ${nspName}.process("${type}", ${src}, ${vName})`;
69
- return src;
70
- }
71
- }
package/index.js DELETED
@@ -1 +0,0 @@
1
- export {createNSP} from "./src/app.js";
package/src/parse-attr.js DELETED
@@ -1,87 +0,0 @@
1
- import { parseText } from "./parse-text.js";
2
- /**
3
- * Parser for HTML tag attributes <tagName attr="value"/>
4
- */
5
- export const parseAttr = (app, src) => new AttrParser(app, src);
6
- class AttrParser {
7
- constructor(app, src) {
8
- this.app = app;
9
- this.src = src;
10
- //
11
- }
12
- /**
13
- * Transpile HTML tag attributes to JavaScript source code
14
- */
15
- toJS(option) {
16
- return attrToJS(this.app, this.src, option);
17
- }
18
- /**
19
- * Compile HTML tag attributes to JavaScript function instance
20
- */
21
- toFn() {
22
- const { app } = this;
23
- const { nspName, vName } = app.options;
24
- const js = this.toJS();
25
- try {
26
- const fn = Function(nspName, vName, `return ${js}`);
27
- return (context) => fn(app, context);
28
- }
29
- catch (e) {
30
- app.log("AttrParser: " + js.substring(0, 1000));
31
- throw e;
32
- }
33
- }
34
- }
35
- /**
36
- * Transpile HTML tag attributes to JavaScript source code
37
- */
38
- const attrToJS = (app, tag, option) => {
39
- tag = tag?.replace(/^\s*<\S+\s*/s, "");
40
- tag = tag?.replace(/\s*\/?>\s*$/s, "");
41
- const indent = +app.options.indent || 0;
42
- const currentIndent = +option?.indent || 0;
43
- const nextIndent = currentIndent + indent;
44
- const currentLF = currentIndent ? "\n" + " ".repeat(currentIndent) : "\n";
45
- const nextLF = nextIndent ? "\n" + " ".repeat(nextIndent) : "\n";
46
- const keys = [];
47
- const index = {};
48
- tag?.replace(/([^\s='"]+)(\s*=(?:\s*"([^"]*)"|\s*'([^']*)'|([^\s='"]*)))?/g, (_, key, eq, v1, v2, v3) => {
49
- if (!index[key])
50
- keys.push(key);
51
- index[key] = (eq ? unescapeXML(v1 || v2 || v3 || "") : true);
52
- return "";
53
- });
54
- const items = keys.map(key => {
55
- let value = index[key];
56
- if (!/^[A-Za-z_]\w+$/.test(key)) {
57
- key = JSON.stringify(key);
58
- }
59
- if ("string" === typeof value) {
60
- value = parseText(app, value).toJS({ indent: nextIndent });
61
- }
62
- return `${key}: ${value}`;
63
- });
64
- // no arguments
65
- if (!keys.length)
66
- return 'null';
67
- const js = items.join(`,${nextLF}`);
68
- const trailingComma = (keys.length > 1) ? "," : "";
69
- return `{${nextLF}${js}${trailingComma}${currentLF}}`;
70
- };
71
- const UNESCAPE = {
72
- "&amp;": "&",
73
- "&lt;": "<",
74
- "&gt;": ">",
75
- "&apos;": "'",
76
- "&quot;": '"'
77
- };
78
- const unescapeXML = (str) => {
79
- return str?.replace(/(&(?:lt|gt|amp|apos|quot|#(?:\d{1,6}|x[0-9a-fA-F]{1,5}));)/g, (str) => {
80
- if (str[1] === "#") {
81
- const code = (str[2] === "x") ? parseInt(str.substring(3), 16) : parseInt(str.substr(2), 10);
82
- if (code > -1)
83
- return String.fromCharCode(code);
84
- }
85
- return UNESCAPE[str] || str;
86
- });
87
- };
package/src/parse-jsp.js DELETED
@@ -1,201 +0,0 @@
1
- import { parseText } from "./parse-text.js";
2
- import { parseAttr } from "./parse-attr.js";
3
- import { parseScriptlet } from "./parse-scriptlet.js";
4
- const emptyText = {
5
- '""': true,
6
- "''": true,
7
- "``": true,
8
- "null": true,
9
- "undefined": true,
10
- "": true,
11
- };
12
- const isElement = (node) => ("function" === typeof node?.toJS);
13
- /**
14
- * Parser for JSP document
15
- */
16
- export const parseJSP = (app, src) => new JspParser(app, src);
17
- /**
18
- * Root element or an taglib element
19
- */
20
- class Element {
21
- constructor(app, tagName, tagLine) {
22
- this.app = app;
23
- this.tagName = tagName;
24
- this.tagLine = tagLine;
25
- this.children = [];
26
- //
27
- }
28
- append(node) {
29
- this.children.push(node);
30
- }
31
- /**
32
- * Transpile JSP document to JavaScript source code
33
- */
34
- toJS(option) {
35
- const { app, tagLine } = this;
36
- const { comment, nspName, trimSpaces, vName } = app.options;
37
- const indent = +app.options.indent || 0;
38
- const currentIndent = +option?.indent || 0;
39
- const nextIndent = currentIndent + indent;
40
- const currentLF = currentIndent ? "\n" + " ".repeat(currentIndent) : "\n";
41
- const nextLF = nextIndent ? "\n" + " ".repeat(nextIndent) : "\n";
42
- const { children } = this;
43
- const args = children.map(item => {
44
- if (isElement(item)) {
45
- return item.toJS({ indent: nextIndent });
46
- }
47
- else if (!/\S/.test(item)) {
48
- // item with only whitespace
49
- return (trimSpaces !== false) ? '""' : JSON.stringify(item);
50
- }
51
- else {
52
- if (trimSpaces !== false) {
53
- item = item.replace(/^\s*[\r\n]/s, "\n");
54
- item = item.replace(/\s*[\r\n]\s*$/s, "\n");
55
- item = item.replace(/^[ \t]+/s, " ");
56
- item = item.replace(/[ \t]+$/s, " ");
57
- }
58
- let js = parseText(app, item).toJS({ indent: nextIndent });
59
- if (/\(.+?\)|\$\{.+?}/s.test(js)) {
60
- js = `${vName} => ${js}`; // array function
61
- }
62
- return js;
63
- }
64
- }).filter(v => !emptyText[v]);
65
- const hasBody = !!children.length;
66
- // keep at least single empty string if all arguments are empty strings
67
- if (hasBody && !args.length) {
68
- args.push('""');
69
- }
70
- const { tagName } = this;
71
- const isRoot = !tagName;
72
- const last = args.length - 1;
73
- args.forEach((v, idx) => {
74
- const isComment = /^\/\/[^\n]*$/s.test(v);
75
- if (idx !== last && !isComment) {
76
- args[idx] += ",";
77
- }
78
- else if (idx === last && isComment) {
79
- args[idx] += currentLF;
80
- }
81
- });
82
- let body = args.join(nextLF);
83
- const bodyL = /^`\n/s.test(body) ? (isRoot ? "" : " ") : nextLF;
84
- const bodyR = /(\n`|[)\s])$/s.test(body) ? "" : currentLF;
85
- if (isRoot) {
86
- return `${nspName}.bundle(${bodyL}${body}${bodyR})`; // root element
87
- }
88
- // attributes as the second argument
89
- let attr = parseAttr(app, tagLine).toJS({ indent: args.length ? nextIndent : currentIndent });
90
- if (/\(.+?\)|\$\{.+?}/s.test(attr)) {
91
- attr = `${vName} => (${attr})`; // array function
92
- }
93
- const commentV = comment ? `// ${tagLine?.replace(/\s*[\r\n]\s*/g, " ") ?? ""}${currentLF}` : "";
94
- const nameV = JSON.stringify(tagName);
95
- const hasAttr = /:/.test(attr);
96
- const attrV = (hasBody || hasAttr) ? `, ${attr}` : "";
97
- const bodyV = hasBody ? `,${bodyL}${body}${bodyR}` : "";
98
- return `${commentV}${nspName}.tag(${nameV}${attrV}${bodyV})`;
99
- }
100
- }
101
- /**
102
- * Tree of elements
103
- */
104
- class Tree {
105
- constructor(root) {
106
- this.root = root;
107
- this.tree = [];
108
- this.tree.push(root);
109
- }
110
- append(node) {
111
- this.tree.at(0).append(node);
112
- }
113
- open(node) {
114
- this.append(node);
115
- this.tree.unshift(node);
116
- }
117
- close(tagName) {
118
- const openTag = this.getTagName();
119
- if (openTag !== tagName) {
120
- throw new Error(`mismatch closing tag: ${openTag} !== ${tagName}`);
121
- }
122
- this.tree.shift();
123
- }
124
- getTagName() {
125
- return this.tree.at(0).tagName;
126
- }
127
- isRoot() {
128
- return this.tree.length === 1;
129
- }
130
- }
131
- class JspParser {
132
- constructor(app, src) {
133
- this.app = app;
134
- this.src = src;
135
- //
136
- }
137
- /**
138
- * Transpile JSP document to JavaScript source code
139
- */
140
- toJS(option) {
141
- const { app, src } = this;
142
- return jspToJS(app, src, option);
143
- }
144
- /**
145
- * Compile JSP document to JavaScript function
146
- */
147
- toFn() {
148
- const { app } = this;
149
- const { nspName } = app.options;
150
- const js = this.toJS();
151
- try {
152
- const fn = Function(nspName, `return ${js}`);
153
- return fn(app);
154
- }
155
- catch (e) {
156
- app.log("JspParser: " + js?.substring(0, 1000));
157
- throw e;
158
- }
159
- }
160
- }
161
- const nameRE = `[A-Za-z][A-Za-z0-9]*`;
162
- const stringRE = `"(?:\\\\[.]|[^\\\\"])*"|'(?:\\\\[.]|[^\\\\'])*'`;
163
- const insideRE = `[^"']|${stringRE}`;
164
- const tagRegExp = new RegExp(`(</?${nameRE}:(?:${insideRE})*?>)|(<%(?:${insideRE})*?%>)`, "s");
165
- export const jspToJS = (app, src, option) => {
166
- const root = new Element(app);
167
- const tree = new Tree(root);
168
- const array = src.split(tagRegExp);
169
- for (let i = 0; i < array.length; i++) {
170
- const i3 = i % 3;
171
- let str = array[i];
172
- if (i3 === 1 && str) {
173
- // taglib
174
- const tagName = str.match(/^<\/?([^\s=/>]+)/)?.[1];
175
- if (/^<\//.test(str)) {
176
- tree.close(tagName);
177
- continue;
178
- }
179
- const element = new Element(app, tagName, str);
180
- if (/\/\s*>$/.test(str)) {
181
- tree.append(element);
182
- }
183
- else {
184
- tree.open(element);
185
- }
186
- }
187
- else if (i3 === 2 && str) {
188
- // <% scriptlet %>
189
- const item = parseScriptlet(app, str);
190
- tree.append(item);
191
- }
192
- else if (i3 === 0) {
193
- // text node
194
- tree.append(str);
195
- }
196
- }
197
- if (!tree.isRoot()) {
198
- throw new Error("missing closing tag: " + tree.getTagName());
199
- }
200
- return root.toJS(option);
201
- };
@@ -1,67 +0,0 @@
1
- import { parseEL } from "./parse-el.js";
2
- /**
3
- * Parser for Directive, Declaration, Scriptlet
4
- * <%-- comment --%>
5
- * <%@ directive %>
6
- * <%! declaration(s) %>
7
- * <% scriptlet %>
8
- * <%= expression %>
9
- */
10
- export const parseScriptlet = (app, src) => new ScriptletParser(app, src);
11
- const typeMap = {
12
- "<%-": "comment",
13
- "<%@": "directive",
14
- "<%!": "declaration",
15
- "<%=": "expression",
16
- };
17
- class ScriptletParser {
18
- constructor(app, src) {
19
- this.app = app;
20
- this.src = src;
21
- //
22
- }
23
- /**
24
- * Compile <% scriptlet %> to JavaScript function instance
25
- */
26
- toFn() {
27
- const { app } = this;
28
- const { nspName } = app.options;
29
- const js = this.toJS();
30
- const isComment = /^\/\/[^\n]*$/s.test(js);
31
- if (isComment)
32
- return () => null;
33
- try {
34
- const fn = Function(nspName, `return ${js}`);
35
- return fn(app);
36
- }
37
- catch (e) {
38
- app.log("ScriptletParser: " + js?.substring(0, 1000));
39
- throw e;
40
- }
41
- }
42
- /**
43
- * Transpile <% scriptlet %> to JavaScript source code
44
- */
45
- toJS(option) {
46
- const { app } = this;
47
- const { nspName, vName } = app.options;
48
- const currentIndent = +option?.indent || 0;
49
- const currentLF = currentIndent ? "\n" + " ".repeat(currentIndent) : "\n";
50
- let { src } = this;
51
- const type = typeMap[src.substring(0, 3)] || "scriptlet";
52
- if (type === "comment") {
53
- src = src.replace(/[ \t]*[\r\n]+/sg, `${currentLF}// `);
54
- return `// ${src}`;
55
- }
56
- if (type === "expression") {
57
- src = src.replace(/^<%=\s*/s, "");
58
- src = src.replace(/\s*%>$/s, "");
59
- src = parseEL(app, src).toJS(option);
60
- return `${vName} => (${src})`;
61
- }
62
- app.log(`${type} found: ${src?.substring(0, 1000)}`);
63
- src = /`|\$\{/.test(src) ? JSON.stringify(src) : "`" + src + "`";
64
- src = `${vName} => ${nspName}.process("${type}", ${src}, ${vName})`;
65
- return src;
66
- }
67
- }
File without changes
File without changes
File without changes