@kosatyi/ejs 0.0.106 → 0.0.108
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/README.md +4 -7
- package/bin/bundler.js +21 -9
- package/dist/cjs/browser.js +532 -650
- package/dist/cjs/bundler.js +110 -78
- package/dist/cjs/element.js +28 -63
- package/dist/cjs/index.js +540 -667
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/worker.js +553 -976
- package/dist/esm/browser.js +565 -588
- package/dist/esm/bundler.js +109 -78
- package/dist/esm/element.js +16 -50
- package/dist/esm/index.js +569 -604
- package/dist/esm/worker.js +563 -611
- package/dist/kosatyi-ejs-0.0.107.tgz +0 -0
- package/dist/umd/browser.js +533 -651
- package/dist/umd/browser.js.map +7 -0
- package/dist/umd/browser.min.js +1 -1
- package/dist/umd/browser.min.js.map +7 -0
- package/dist/umd/element.js +28 -63
- package/dist/umd/element.min.js +1 -1
- package/dist/umd/index.js +541 -668
- package/dist/umd/index.min.js +1 -1
- package/dist/umd/worker.js +819 -1242
- package/dist/umd/worker.min.js +1 -3
- package/package.json +80 -71
- package/types/browser.d.ts +10 -0
- package/types/bundler.d.ts +11 -12
- package/types/context.d.ts +96 -0
- package/types/ejs.d.ts +111 -73
- package/types/element.d.ts +9 -0
- package/types/error.d.ts +14 -0
- package/types/global.d.ts +6 -6
- package/types/index.d.ts +16 -0
- package/types/worker.d.ts +31 -0
package/dist/esm/browser.js
CHANGED
|
@@ -1,20 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @type {EjsConfig}
|
|
3
|
+
*/
|
|
4
|
+
const ejsDefaults = {
|
|
5
|
+
precompiled: 'ejsPrecompiled',
|
|
6
|
+
cache: true,
|
|
7
|
+
path: 'views',
|
|
8
|
+
extension: 'ejs',
|
|
9
|
+
rmWhitespace: true,
|
|
10
|
+
strict: true,
|
|
11
|
+
resolver: (path, template) => {
|
|
12
|
+
return Promise.resolve(
|
|
13
|
+
['resolver is not defined', path, template].join(' '),
|
|
14
|
+
)
|
|
15
|
+
},
|
|
16
|
+
globals: [],
|
|
17
|
+
vars: {
|
|
18
|
+
SCOPE: 'ejs',
|
|
19
|
+
COMPONENT: 'ui',
|
|
20
|
+
ELEMENT: 'el',
|
|
21
|
+
EXTEND: '$$e',
|
|
22
|
+
BUFFER: '$$a',
|
|
23
|
+
LAYOUT: '$$l',
|
|
24
|
+
BLOCKS: '$$b',
|
|
25
|
+
MACRO: '$$m',
|
|
26
|
+
SAFE: '$$v',
|
|
27
|
+
},
|
|
28
|
+
token: {
|
|
29
|
+
start: '<%',
|
|
30
|
+
end: '%>',
|
|
31
|
+
regex: '([\\s\\S]+?)',
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const jsVariableName = /^[a-zA-Z_$][0-9a-zA-Z_$]*$/;
|
|
36
|
+
|
|
1
37
|
const typeProp = function () {
|
|
2
38
|
const args = [].slice.call(arguments);
|
|
3
39
|
const callback = args.shift();
|
|
4
40
|
return args.filter(callback).pop()
|
|
5
41
|
};
|
|
6
|
-
const isArray = (
|
|
7
|
-
const isFunction = (
|
|
8
|
-
const isString = (
|
|
9
|
-
const isBoolean = (
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
42
|
+
const isArray = (value) => Array.isArray(value);
|
|
43
|
+
const isFunction = (value) => typeof value === 'function';
|
|
44
|
+
const isString = (value) => typeof value === 'string';
|
|
45
|
+
const isBoolean = (value) => typeof value === 'boolean';
|
|
46
|
+
const isArrayOfVariables = (value) => {
|
|
47
|
+
if (!isArray(value)) return false
|
|
48
|
+
return value.filter((name) => {
|
|
49
|
+
const valid = jsVariableName.test(name);
|
|
50
|
+
if (valid === false)
|
|
51
|
+
console.log(
|
|
52
|
+
`ejsConfig.globals: expected '${name}' to be valid variable name --> skipped`,
|
|
53
|
+
);
|
|
54
|
+
return valid
|
|
55
|
+
})
|
|
56
|
+
};
|
|
16
57
|
|
|
17
|
-
const
|
|
58
|
+
const configSchema = (config, options) => {
|
|
59
|
+
return Object.assign(config, {
|
|
60
|
+
path: typeProp(isString, ejsDefaults.path, config.path, options.path),
|
|
61
|
+
precompiled: typeProp(
|
|
62
|
+
isString,
|
|
63
|
+
ejsDefaults.precompiled,
|
|
64
|
+
config.export,
|
|
65
|
+
options.export,
|
|
66
|
+
),
|
|
67
|
+
resolver: typeProp(
|
|
68
|
+
isFunction,
|
|
69
|
+
ejsDefaults.resolver,
|
|
70
|
+
config.resolver,
|
|
71
|
+
options.resolver,
|
|
72
|
+
),
|
|
73
|
+
extension: typeProp(
|
|
74
|
+
isString,
|
|
75
|
+
ejsDefaults.extension,
|
|
76
|
+
config.extension,
|
|
77
|
+
options.extension,
|
|
78
|
+
),
|
|
79
|
+
strict: typeProp(
|
|
80
|
+
isBoolean,
|
|
81
|
+
ejsDefaults.strict,
|
|
82
|
+
config.strict,
|
|
83
|
+
options.strict,
|
|
84
|
+
),
|
|
85
|
+
rmWhitespace: typeProp(
|
|
86
|
+
isBoolean,
|
|
87
|
+
ejsDefaults.rmWhitespace,
|
|
88
|
+
config.rmWhitespace,
|
|
89
|
+
options.rmWhitespace,
|
|
90
|
+
),
|
|
91
|
+
cache: typeProp(
|
|
92
|
+
isBoolean,
|
|
93
|
+
ejsDefaults.cache,
|
|
94
|
+
config.cache,
|
|
95
|
+
options.cache,
|
|
96
|
+
),
|
|
97
|
+
globals: typeProp(
|
|
98
|
+
isArray,
|
|
99
|
+
ejsDefaults.globals,
|
|
100
|
+
config.globals,
|
|
101
|
+
isArrayOfVariables(options.globals),
|
|
102
|
+
),
|
|
103
|
+
token: Object.assign(
|
|
104
|
+
{},
|
|
105
|
+
ejsDefaults.token,
|
|
106
|
+
config.token,
|
|
107
|
+
options.token,
|
|
108
|
+
),
|
|
109
|
+
vars: Object.assign({}, ejsDefaults.vars, config.vars, options.vars),
|
|
110
|
+
})
|
|
111
|
+
};
|
|
18
112
|
|
|
19
113
|
const symbolEntities = {
|
|
20
114
|
"'": "'",
|
|
@@ -44,14 +138,14 @@ const symbolEntitiesMatch = regexKeys(symbolEntities);
|
|
|
44
138
|
const entities = (string = '') => {
|
|
45
139
|
return ('' + string).replace(
|
|
46
140
|
htmlEntitiesMatch,
|
|
47
|
-
(match) => htmlEntities[match]
|
|
141
|
+
(match) => htmlEntities[match],
|
|
48
142
|
)
|
|
49
143
|
};
|
|
50
144
|
|
|
51
145
|
const symbols = (string) => {
|
|
52
146
|
return ('' + string).replace(
|
|
53
147
|
symbolEntitiesMatch,
|
|
54
|
-
(match) => '\\' + symbolEntities[match]
|
|
148
|
+
(match) => '\\' + symbolEntities[match],
|
|
55
149
|
)
|
|
56
150
|
};
|
|
57
151
|
|
|
@@ -60,8 +154,8 @@ const safeValue = (value, escape) => {
|
|
|
60
154
|
return check == null
|
|
61
155
|
? ''
|
|
62
156
|
: Boolean(escape) === true
|
|
63
|
-
|
|
64
|
-
|
|
157
|
+
? entities(check)
|
|
158
|
+
: check
|
|
65
159
|
};
|
|
66
160
|
|
|
67
161
|
const getPath = (context, name, strict) => {
|
|
@@ -85,25 +179,6 @@ const getPath = (context, name, strict) => {
|
|
|
85
179
|
return [data, prop]
|
|
86
180
|
};
|
|
87
181
|
|
|
88
|
-
const ext = (path, defaults) => {
|
|
89
|
-
const ext = path.split('.').pop();
|
|
90
|
-
if (ext !== defaults) {
|
|
91
|
-
path = [path, defaults].join('.');
|
|
92
|
-
}
|
|
93
|
-
return path
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* @type {<T extends {}, U, V, W,Y>(T,U,V,W,Y)=> T & U & V & W & Y}
|
|
98
|
-
*/
|
|
99
|
-
const extend = (target, ...args) => {
|
|
100
|
-
return args
|
|
101
|
-
.filter((source) => source)
|
|
102
|
-
.reduce((target, source) => Object.assign(target, source), target)
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
const noop = () => {};
|
|
106
|
-
|
|
107
182
|
const each = (object, callback) => {
|
|
108
183
|
let prop;
|
|
109
184
|
for (prop in object) {
|
|
@@ -113,53 +188,16 @@ const each = (object, callback) => {
|
|
|
113
188
|
}
|
|
114
189
|
};
|
|
115
190
|
|
|
116
|
-
const map = (object, callback, context) => {
|
|
117
|
-
const result = [];
|
|
118
|
-
each(
|
|
119
|
-
object,
|
|
120
|
-
(value, key, object) => {
|
|
121
|
-
let item = callback(value, key, object);
|
|
122
|
-
if (isUndefined(item) === false) {
|
|
123
|
-
result.push(item);
|
|
124
|
-
}
|
|
125
|
-
});
|
|
126
|
-
return result
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
const filter = (object, callback, context) => {
|
|
130
|
-
const isArray = object instanceof Array;
|
|
131
|
-
const result = isArray ? [] : {};
|
|
132
|
-
each(
|
|
133
|
-
object,
|
|
134
|
-
(value, key, object) => {
|
|
135
|
-
let item = callback(value, key, object);
|
|
136
|
-
if (isUndefined(item) === false) {
|
|
137
|
-
if (isArray) {
|
|
138
|
-
result.push(item);
|
|
139
|
-
} else {
|
|
140
|
-
result[key] = item;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
return result
|
|
145
|
-
};
|
|
146
|
-
|
|
147
191
|
const omit = (object, list) => {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
192
|
+
const result = { ...object };
|
|
193
|
+
for (const key of list) {
|
|
194
|
+
delete result[key];
|
|
195
|
+
}
|
|
196
|
+
return result
|
|
153
197
|
};
|
|
154
198
|
|
|
155
|
-
/**
|
|
156
|
-
*
|
|
157
|
-
* @param object
|
|
158
|
-
* @param prop
|
|
159
|
-
* @return {boolean}
|
|
160
|
-
*/
|
|
161
199
|
const hasProp = (object, prop) => {
|
|
162
|
-
return object &&
|
|
200
|
+
return object && Object.hasOwn(object, prop)
|
|
163
201
|
};
|
|
164
202
|
|
|
165
203
|
const joinPath = (path, template) => {
|
|
@@ -168,9 +206,68 @@ const joinPath = (path, template) => {
|
|
|
168
206
|
return template
|
|
169
207
|
};
|
|
170
208
|
|
|
171
|
-
const
|
|
209
|
+
const bindContext = (object, methods = []) => {
|
|
210
|
+
for (let i = 0, len = methods.length; i < len; i++) {
|
|
211
|
+
const name = methods[i];
|
|
212
|
+
if (name in object) {
|
|
213
|
+
object[name] = object[name].bind(object);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
class Template {
|
|
219
|
+
#path
|
|
220
|
+
#resolver
|
|
221
|
+
#cache
|
|
222
|
+
#compiler
|
|
223
|
+
static exports = ['configure', 'get', 'compile']
|
|
224
|
+
constructor(options, cache, compiler) {
|
|
225
|
+
bindContext(this, this.constructor.exports);
|
|
226
|
+
this.#cache = cache;
|
|
227
|
+
this.#compiler = compiler;
|
|
228
|
+
this.configure(options ?? {});
|
|
229
|
+
}
|
|
230
|
+
configure(options) {
|
|
231
|
+
this.#path = options.path;
|
|
232
|
+
if (isFunction(options.resolver)) {
|
|
233
|
+
this.#resolver = options.resolver;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
#resolve(template) {
|
|
237
|
+
const cached = this.#cache.get(template);
|
|
238
|
+
if (cached instanceof Promise) return cached
|
|
239
|
+
const result = Promise.resolve(this.#resolver(this.#path, template));
|
|
240
|
+
this.#cache.set(template, result);
|
|
241
|
+
return result
|
|
242
|
+
}
|
|
243
|
+
compile(content, template) {
|
|
244
|
+
const cached = this.#cache.get(template);
|
|
245
|
+
if (typeof cached === 'function') return cached
|
|
246
|
+
if (typeof content === 'string') {
|
|
247
|
+
content = this.#compiler.compile(content, template);
|
|
248
|
+
}
|
|
249
|
+
if (typeof content === 'function') {
|
|
250
|
+
this.#cache.set(template, content);
|
|
251
|
+
return content
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
get(template) {
|
|
255
|
+
return this.#resolve(template).then((content) =>
|
|
256
|
+
this.compile(content, template),
|
|
257
|
+
)
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const tokenList = [
|
|
262
|
+
['-', (v, b, s) => `')\n${b}(${s}(${v},1))\n${b}('`],
|
|
263
|
+
['=', (v, b, s) => `')\n${b}(${s}(${v}))\n${b}('`],
|
|
264
|
+
['#', (v, b) => `')\n/**${v}**/\n${b}('`],
|
|
265
|
+
['', (v, b) => `')\n${v}\n${b}('`],
|
|
266
|
+
];
|
|
267
|
+
|
|
268
|
+
const tokensMatch = (regex, content, callback) => {
|
|
172
269
|
let index = 0;
|
|
173
|
-
|
|
270
|
+
content.replace(regex, function () {
|
|
174
271
|
const params = [].slice.call(arguments, 0, -1);
|
|
175
272
|
const offset = params.pop();
|
|
176
273
|
const match = params.shift();
|
|
@@ -180,291 +277,167 @@ const matchTokens = (regex, text, callback) => {
|
|
|
180
277
|
});
|
|
181
278
|
};
|
|
182
279
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
defaults.cache = true;
|
|
187
|
-
defaults.chokidar = null;
|
|
188
|
-
defaults.path = 'views';
|
|
189
|
-
defaults.resolver = function(path, template) {
|
|
190
|
-
return Promise.resolve(
|
|
191
|
-
['resolver is not defined', path, template].join(' ')
|
|
192
|
-
)
|
|
193
|
-
};
|
|
194
|
-
defaults.extension = 'ejs';
|
|
195
|
-
defaults.rmWhitespace = true;
|
|
196
|
-
defaults.withObject = true;
|
|
197
|
-
defaults.globalHelpers = [];
|
|
198
|
-
defaults.vars = {
|
|
199
|
-
SCOPE: 'ejs',
|
|
200
|
-
COMPONENT: 'ui',
|
|
201
|
-
ELEMENT: 'el',
|
|
202
|
-
EXTEND: '$$e',
|
|
203
|
-
BUFFER: '$$a',
|
|
204
|
-
LAYOUT: '$$l',
|
|
205
|
-
BLOCKS: '$$b',
|
|
206
|
-
MACRO: '$$m',
|
|
207
|
-
SAFE: '$$v'
|
|
208
|
-
};
|
|
209
|
-
defaults.token = {
|
|
210
|
-
start: '<%',
|
|
211
|
-
end: '%>',
|
|
212
|
-
regex: '([\\s\\S]+?)'
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
const configSchema = (config, options) => {
|
|
216
|
-
return extend(config, {
|
|
217
|
-
path: typeProp(isString, defaults.path, config.path, options.path),
|
|
218
|
-
export: typeProp(
|
|
219
|
-
isString,
|
|
220
|
-
defaults.export,
|
|
221
|
-
config.export,
|
|
222
|
-
options.export
|
|
223
|
-
),
|
|
224
|
-
resolver: typeProp(
|
|
225
|
-
isFunction,
|
|
226
|
-
defaults.resolver,
|
|
227
|
-
config.resolver,
|
|
228
|
-
options.resolver
|
|
229
|
-
),
|
|
230
|
-
extension: typeProp(
|
|
231
|
-
isString,
|
|
232
|
-
defaults.extension,
|
|
233
|
-
config.extension,
|
|
234
|
-
options.extension
|
|
235
|
-
),
|
|
236
|
-
withObject: typeProp(
|
|
237
|
-
isBoolean,
|
|
238
|
-
defaults.withObject,
|
|
239
|
-
config.withObject,
|
|
240
|
-
options.withObject
|
|
241
|
-
),
|
|
242
|
-
rmWhitespace: typeProp(
|
|
243
|
-
isBoolean,
|
|
244
|
-
defaults.rmWhitespace,
|
|
245
|
-
config.rmWhitespace,
|
|
246
|
-
options.rmWhitespace
|
|
247
|
-
),
|
|
248
|
-
cache: typeProp(isBoolean, defaults.cache, config.cache, options.cache),
|
|
249
|
-
token: extend({}, defaults.token, config.token, options.token),
|
|
250
|
-
vars: extend({}, defaults.vars, config.vars, options.vars),
|
|
251
|
-
globalHelpers: typeProp(
|
|
252
|
-
isArray,
|
|
253
|
-
defaults.globalHelpers,
|
|
254
|
-
config.globalHelpers,
|
|
255
|
-
options.globalHelpers
|
|
256
|
-
),
|
|
257
|
-
})
|
|
258
|
-
};
|
|
280
|
+
class Compiler {
|
|
281
|
+
#config = {}
|
|
282
|
+
static exports = ['compile']
|
|
259
283
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
resolver: null
|
|
264
|
-
};
|
|
265
|
-
const resolve = (path) => {
|
|
266
|
-
return config.resolver(config.path, path)
|
|
267
|
-
};
|
|
268
|
-
const result = (template, content) => {
|
|
269
|
-
cache.set(template, content);
|
|
270
|
-
return content
|
|
271
|
-
};
|
|
272
|
-
const compile = (content, template) => {
|
|
273
|
-
if (isFunction(content)) {
|
|
274
|
-
return content
|
|
275
|
-
} else {
|
|
276
|
-
return compiler.compile(content, template)
|
|
277
|
-
}
|
|
278
|
-
};
|
|
279
|
-
const get = (template) => {
|
|
280
|
-
if (cache.exist(template)) {
|
|
281
|
-
return cache.resolve(template)
|
|
282
|
-
}
|
|
283
|
-
return resolve(template).then((content) =>
|
|
284
|
-
result(template, compile(content, template))
|
|
285
|
-
)
|
|
286
|
-
};
|
|
287
|
-
const configure = (options) => {
|
|
288
|
-
config.path = options.path;
|
|
289
|
-
if (isFunction(options.resolver)) {
|
|
290
|
-
config.resolver = options.resolver;
|
|
291
|
-
}
|
|
292
|
-
};
|
|
293
|
-
configure(options);
|
|
294
|
-
return {
|
|
295
|
-
get,
|
|
296
|
-
configure,
|
|
297
|
-
compile
|
|
284
|
+
constructor(options) {
|
|
285
|
+
bindContext(this, this.constructor.exports);
|
|
286
|
+
this.configure(options);
|
|
298
287
|
}
|
|
299
|
-
};
|
|
300
|
-
|
|
301
|
-
const configSymbols = [
|
|
302
|
-
{
|
|
303
|
-
symbol: '-',
|
|
304
|
-
format(value) {
|
|
305
|
-
return `')\n${this.BUFFER}(${this.SAFE}(${value},1))\n${this.BUFFER}('`
|
|
306
|
-
},
|
|
307
|
-
},
|
|
308
|
-
{
|
|
309
|
-
symbol: '=',
|
|
310
|
-
format(value) {
|
|
311
|
-
return `')\n${this.BUFFER}(${this.SAFE}(${value}))\n${this.BUFFER}('`
|
|
312
|
-
},
|
|
313
|
-
},
|
|
314
|
-
{
|
|
315
|
-
symbol: '#',
|
|
316
|
-
format(value) {
|
|
317
|
-
return `')\n/**${value}**/\n${this.BUFFER}('`
|
|
318
|
-
},
|
|
319
|
-
},
|
|
320
|
-
{
|
|
321
|
-
symbol: '',
|
|
322
|
-
format(value) {
|
|
323
|
-
return `')\n${value.trim()}\n${this.BUFFER}('`
|
|
324
|
-
},
|
|
325
|
-
},
|
|
326
|
-
];
|
|
327
288
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
config.
|
|
332
|
-
config.
|
|
333
|
-
config.
|
|
334
|
-
config.
|
|
335
|
-
config.
|
|
336
|
-
config.matches = [];
|
|
337
|
-
config.formats = [];
|
|
338
|
-
config.slurp = {
|
|
289
|
+
configure(options) {
|
|
290
|
+
this.#config.strict = options.strict;
|
|
291
|
+
this.#config.rmWhitespace = options.rmWhitespace;
|
|
292
|
+
this.#config.token = options.token;
|
|
293
|
+
this.#config.vars = options.vars;
|
|
294
|
+
this.#config.globals = options.globals;
|
|
295
|
+
this.#config.legacy = options.legacy ?? true;
|
|
296
|
+
this.#config.slurp = {
|
|
339
297
|
match: '[s\t\n]*',
|
|
340
|
-
start: [config.token.start, '_'],
|
|
341
|
-
end: ['_', config.token.end],
|
|
298
|
+
start: [this.#config.token.start, '_'],
|
|
299
|
+
end: ['_', this.#config.token.end],
|
|
342
300
|
};
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
.concat(
|
|
301
|
+
this.#config.matches = [];
|
|
302
|
+
this.#config.formats = [];
|
|
303
|
+
for (const [symbol, format] of tokenList) {
|
|
304
|
+
this.#config.matches.push(
|
|
305
|
+
this.#config.token.start
|
|
306
|
+
.concat(symbol)
|
|
307
|
+
.concat(this.#config.token.regex)
|
|
308
|
+
.concat(this.#config.token.end),
|
|
349
309
|
);
|
|
350
|
-
config.formats.push(
|
|
351
|
-
}
|
|
352
|
-
config.regex = new RegExp(
|
|
353
|
-
config.matches.join('|').concat('|$'),
|
|
354
|
-
'g'
|
|
310
|
+
this.#config.formats.push(format);
|
|
311
|
+
}
|
|
312
|
+
this.#config.regex = new RegExp(
|
|
313
|
+
this.#config.matches.join('|').concat('|$'),
|
|
314
|
+
'g',
|
|
355
315
|
);
|
|
356
|
-
config.slurpStart = new RegExp(
|
|
357
|
-
[config.slurp.match, config.slurp.start.join('')].join(
|
|
358
|
-
''
|
|
316
|
+
this.#config.slurpStart = new RegExp(
|
|
317
|
+
[this.#config.slurp.match, this.#config.slurp.start.join('')].join(
|
|
318
|
+
'',
|
|
359
319
|
),
|
|
360
|
-
'gm'
|
|
320
|
+
'gm',
|
|
361
321
|
);
|
|
362
|
-
config.slurpEnd = new RegExp(
|
|
363
|
-
[config.slurp.end.join(''), config.slurp.match].join(
|
|
364
|
-
''
|
|
322
|
+
this.#config.slurpEnd = new RegExp(
|
|
323
|
+
[this.#config.slurp.end.join(''), this.#config.slurp.match].join(
|
|
324
|
+
'',
|
|
365
325
|
),
|
|
366
|
-
'gm'
|
|
326
|
+
'gm',
|
|
367
327
|
);
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
328
|
+
if (this.#config.globals.length) {
|
|
329
|
+
if (this.#config.legacy) {
|
|
330
|
+
this.#config.globalVariables = `const ${this.#config.globals
|
|
331
|
+
.map((name) => `${name}=${this.#config.vars.SCOPE}.${name}`)
|
|
332
|
+
.join(',')};`;
|
|
333
|
+
} else {
|
|
334
|
+
this.#config.globalVariables = `const {${this.#config.globals.join(',')}} = ${this.#config.vars.SCOPE};`;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
compile(content, path) {
|
|
339
|
+
const GLOBALS = this.#config.globalVariables;
|
|
340
|
+
const { SCOPE, SAFE, BUFFER, COMPONENT, ELEMENT } = this.#config.vars;
|
|
341
|
+
if (this.#config.rmWhitespace) {
|
|
373
342
|
content = String(content)
|
|
374
343
|
.replace(/[\r\n]+/g, '\n')
|
|
375
344
|
.replace(/^\s+|\s+$/gm, '');
|
|
376
345
|
}
|
|
377
346
|
content = String(content)
|
|
378
|
-
.replace(config.slurpStart, config.token.start)
|
|
379
|
-
.replace(config.slurpEnd, config.token.end);
|
|
380
|
-
let
|
|
381
|
-
|
|
382
|
-
|
|
347
|
+
.replace(this.#config.slurpStart, this.#config.token.start)
|
|
348
|
+
.replace(this.#config.slurpEnd, this.#config.token.end);
|
|
349
|
+
let OUTPUT = `${BUFFER}('`;
|
|
350
|
+
tokensMatch(this.#config.regex, content, (params, index, offset) => {
|
|
351
|
+
OUTPUT += symbols(content.slice(index, offset));
|
|
383
352
|
params.forEach((value, index) => {
|
|
384
353
|
if (value) {
|
|
385
|
-
|
|
354
|
+
OUTPUT += this.#config.formats[index](
|
|
355
|
+
value.trim(),
|
|
356
|
+
BUFFER,
|
|
357
|
+
SAFE,
|
|
358
|
+
);
|
|
386
359
|
}
|
|
387
360
|
});
|
|
388
361
|
});
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
if (config.
|
|
392
|
-
|
|
362
|
+
OUTPUT += `');`;
|
|
363
|
+
OUTPUT = `try{${OUTPUT}}catch(e){return ${BUFFER}.error(e,'${path}')}`;
|
|
364
|
+
if (this.#config.strict === false) {
|
|
365
|
+
OUTPUT = `with(${SCOPE}){${OUTPUT}}`;
|
|
366
|
+
}
|
|
367
|
+
OUTPUT = `${BUFFER}.start();${OUTPUT}return ${BUFFER}.end();`;
|
|
368
|
+
OUTPUT += `\n//# sourceURL=${path}`;
|
|
369
|
+
if (GLOBALS) {
|
|
370
|
+
OUTPUT = `${GLOBALS}\n${OUTPUT}`;
|
|
393
371
|
}
|
|
394
|
-
source = `${BUFFER}.start();${source}return ${BUFFER}.end();`;
|
|
395
|
-
source += `\n//# sourceURL=${path}`;
|
|
396
|
-
let result = null;
|
|
397
|
-
let params = [SCOPE, COMPONENT, ELEMENT, BUFFER, SAFE].concat(GLOBALS);
|
|
398
372
|
try {
|
|
399
|
-
|
|
400
|
-
result
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
373
|
+
const params = [SCOPE, COMPONENT, ELEMENT, BUFFER, SAFE];
|
|
374
|
+
const result = Function.apply(null, params.concat(OUTPUT));
|
|
375
|
+
result.source = `(function(${params.join(',')}){\n${OUTPUT}\n});`;
|
|
376
|
+
return result
|
|
377
|
+
} catch (error) {
|
|
378
|
+
error.filename = path;
|
|
379
|
+
error.source = OUTPUT;
|
|
380
|
+
throw error
|
|
405
381
|
}
|
|
406
|
-
return result
|
|
407
|
-
};
|
|
408
|
-
configure(options);
|
|
409
|
-
return {
|
|
410
|
-
configure,
|
|
411
|
-
compile,
|
|
412
382
|
}
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
const global = typeof globalThis !== 'undefined' ? globalThis : window || self;
|
|
383
|
+
}
|
|
416
384
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
385
|
+
class Cache {
|
|
386
|
+
static exports = [
|
|
387
|
+
'load',
|
|
388
|
+
'set',
|
|
389
|
+
'get',
|
|
390
|
+
'exist',
|
|
391
|
+
'clear',
|
|
392
|
+
'remove',
|
|
393
|
+
'resolve',
|
|
394
|
+
]
|
|
395
|
+
#cache = true
|
|
396
|
+
#precompiled
|
|
397
|
+
#list = {}
|
|
398
|
+
constructor(options) {
|
|
399
|
+
bindContext(this, this.constructor.exports);
|
|
400
|
+
this.configure(options);
|
|
401
|
+
}
|
|
402
|
+
get(key) {
|
|
403
|
+
if (this.#cache) {
|
|
404
|
+
return this.#list[key]
|
|
423
405
|
}
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
if (
|
|
427
|
-
|
|
406
|
+
}
|
|
407
|
+
set(key, value) {
|
|
408
|
+
if (this.#cache) {
|
|
409
|
+
this.#list[key] = value;
|
|
428
410
|
}
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
if (
|
|
432
|
-
list
|
|
411
|
+
}
|
|
412
|
+
exist(key) {
|
|
413
|
+
if (this.#cache) {
|
|
414
|
+
return this.#list.hasOwnProperty(key)
|
|
433
415
|
}
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
416
|
+
}
|
|
417
|
+
clear() {
|
|
418
|
+
Object.keys(this.#list).forEach(this.remove);
|
|
419
|
+
}
|
|
420
|
+
remove(key) {
|
|
421
|
+
delete this.#list[key];
|
|
422
|
+
}
|
|
423
|
+
resolve(key) {
|
|
424
|
+
return Promise.resolve(this.get(key))
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
load(data) {
|
|
428
|
+
if (this.#cache) {
|
|
429
|
+
Object.assign(this.#list, data || {});
|
|
438
430
|
}
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
const resolve = (key) => {
|
|
447
|
-
return Promise.resolve(get(key))
|
|
448
|
-
};
|
|
449
|
-
const configure = (options = {}) => {
|
|
450
|
-
config.enabled = options.cache;
|
|
451
|
-
config.export = options.export;
|
|
452
|
-
if (isNode() === false) {
|
|
453
|
-
load(global[config.export]);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
configure(options) {
|
|
434
|
+
this.#cache = options.cache;
|
|
435
|
+
this.#precompiled = options.precompiled;
|
|
436
|
+
if (typeof window === 'object') {
|
|
437
|
+
this.load(window[this.#precompiled]);
|
|
454
438
|
}
|
|
455
|
-
};
|
|
456
|
-
configure(options);
|
|
457
|
-
return {
|
|
458
|
-
configure,
|
|
459
|
-
load,
|
|
460
|
-
set,
|
|
461
|
-
get,
|
|
462
|
-
exist,
|
|
463
|
-
clear,
|
|
464
|
-
remove,
|
|
465
|
-
resolve,
|
|
466
439
|
}
|
|
467
|
-
}
|
|
440
|
+
}
|
|
468
441
|
|
|
469
442
|
const selfClosed = [
|
|
470
443
|
'area',
|
|
@@ -490,20 +463,24 @@ const slash = '/';
|
|
|
490
463
|
const lt = '<';
|
|
491
464
|
const gt = '>';
|
|
492
465
|
|
|
466
|
+
const eachAttribute = ([key, value]) => {
|
|
467
|
+
if (value !== null && value !== undefined) {
|
|
468
|
+
return [entities(key), [quote, entities(value), quote].join('')].join(
|
|
469
|
+
equal,
|
|
470
|
+
)
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
|
|
493
474
|
const element = (tag, attrs, content) => {
|
|
494
475
|
const result = [];
|
|
495
476
|
const hasClosedTag = selfClosed.indexOf(tag) === -1;
|
|
496
|
-
const attributes =
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
[quote, entities(value), quote].join(''),
|
|
501
|
-
].join(equal)
|
|
502
|
-
}
|
|
503
|
-
}).join(space);
|
|
477
|
+
const attributes = Object.entries(attrs ?? {})
|
|
478
|
+
.map(eachAttribute)
|
|
479
|
+
.filter((e) => e)
|
|
480
|
+
.join(space);
|
|
504
481
|
result.push([lt, tag, space, attributes, gt].join(''));
|
|
505
482
|
if (content && hasClosedTag) {
|
|
506
|
-
result.push(content
|
|
483
|
+
result.push(Array.isArray(content) ? content.join('') : content);
|
|
507
484
|
}
|
|
508
485
|
if (hasClosedTag) {
|
|
509
486
|
result.push([lt, slash, tag, gt].join(''));
|
|
@@ -511,93 +488,73 @@ const element = (tag, attrs, content) => {
|
|
|
511
488
|
return result.join('')
|
|
512
489
|
};
|
|
513
490
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
code: 0,
|
|
524
|
-
getCode() {
|
|
525
|
-
return this.code
|
|
526
|
-
},
|
|
527
|
-
getMessage() {
|
|
528
|
-
return this.message
|
|
529
|
-
},
|
|
530
|
-
toString() {
|
|
531
|
-
return this.getMessage()
|
|
491
|
+
class TemplateError extends Error {
|
|
492
|
+
name = 'TemplateError'
|
|
493
|
+
constructor(error) {
|
|
494
|
+
super(error);
|
|
495
|
+
if (error instanceof Error) {
|
|
496
|
+
this.stack = error.stack;
|
|
497
|
+
this.filename = error.filename;
|
|
498
|
+
this.lineno = error.lineno;
|
|
499
|
+
}
|
|
532
500
|
}
|
|
533
|
-
}
|
|
501
|
+
}
|
|
534
502
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
*/
|
|
539
|
-
function TemplateNotFound(){
|
|
540
|
-
TemplateError.call(this);
|
|
503
|
+
class TemplateNotFound extends TemplateError {
|
|
504
|
+
name = 'TemplateNotFound'
|
|
505
|
+
code = 404
|
|
541
506
|
}
|
|
542
|
-
Object.setPrototypeOf(TemplateNotFound.prototype, TemplateError.prototype);
|
|
543
|
-
Object.assign(TemplateNotFound.prototype, { code: 404 });
|
|
544
507
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
*/
|
|
549
|
-
function TemplateSyntaxError(){
|
|
550
|
-
TemplateError.call(this);
|
|
508
|
+
class TemplateSyntaxError extends TemplateError {
|
|
509
|
+
name = 'TemplateSyntaxError'
|
|
510
|
+
code = 500
|
|
551
511
|
}
|
|
552
|
-
Object.setPrototypeOf(TemplateSyntaxError.prototype, TemplateError.prototype);
|
|
553
|
-
Object.assign(TemplateSyntaxError.prototype, { code: 500 });
|
|
554
512
|
|
|
555
|
-
|
|
513
|
+
const resolve = (list) => {
|
|
556
514
|
return Promise.all(list || [])
|
|
557
515
|
.then((list) => list.join(''))
|
|
558
516
|
.catch((e) => e)
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
function reject(error) {
|
|
562
|
-
return Promise.reject(new TemplateSyntaxError(error.message))
|
|
563
|
-
}
|
|
517
|
+
};
|
|
564
518
|
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
*/
|
|
569
|
-
function createBuffer() {
|
|
570
|
-
let store = [],
|
|
571
|
-
array = [];
|
|
519
|
+
const reject = (error) => {
|
|
520
|
+
return Promise.reject(new TemplateSyntaxError(error))
|
|
521
|
+
};
|
|
572
522
|
|
|
573
|
-
|
|
523
|
+
const EjsBuffer = () => {
|
|
524
|
+
let store = [];
|
|
525
|
+
let array = [];
|
|
526
|
+
/**
|
|
527
|
+
*
|
|
528
|
+
* @param value
|
|
529
|
+
* @constructor
|
|
530
|
+
*/
|
|
531
|
+
const EjsBuffer = (value) => {
|
|
574
532
|
array.push(value);
|
|
575
533
|
};
|
|
576
|
-
|
|
577
|
-
buffer.start = () => {
|
|
534
|
+
EjsBuffer.start = () => {
|
|
578
535
|
array = [];
|
|
579
536
|
};
|
|
580
|
-
|
|
537
|
+
EjsBuffer.backup = () => {
|
|
581
538
|
store.push(array.concat());
|
|
582
539
|
array = [];
|
|
583
540
|
};
|
|
584
|
-
|
|
541
|
+
EjsBuffer.restore = () => {
|
|
585
542
|
const result = array.concat();
|
|
586
543
|
array = store.pop();
|
|
587
544
|
return resolve(result)
|
|
588
545
|
};
|
|
589
|
-
|
|
546
|
+
EjsBuffer.error = (e, filename) => {
|
|
590
547
|
return reject(e)
|
|
591
548
|
};
|
|
592
|
-
|
|
549
|
+
EjsBuffer.end = () => {
|
|
593
550
|
return resolve(array)
|
|
594
551
|
};
|
|
595
|
-
return
|
|
596
|
-
}
|
|
552
|
+
return EjsBuffer
|
|
553
|
+
};
|
|
597
554
|
|
|
598
|
-
const PARENT = Symbol('
|
|
555
|
+
const PARENT = Symbol('EjsContext.parentTemplate');
|
|
599
556
|
|
|
600
|
-
const
|
|
557
|
+
const createContext$1 = (config, methods) => {
|
|
601
558
|
const {
|
|
602
559
|
BLOCKS,
|
|
603
560
|
MACRO,
|
|
@@ -607,70 +564,64 @@ const createContextScope = (config, methods) => {
|
|
|
607
564
|
SAFE,
|
|
608
565
|
SCOPE,
|
|
609
566
|
COMPONENT,
|
|
610
|
-
ELEMENT
|
|
567
|
+
ELEMENT,
|
|
611
568
|
} = config.vars;
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
*
|
|
615
|
-
* @type {symbol}
|
|
616
|
-
*/
|
|
617
|
-
|
|
618
|
-
/**
|
|
619
|
-
* @name ContextScope
|
|
620
|
-
* @param data
|
|
621
|
-
* @constructor
|
|
622
|
-
*/
|
|
623
|
-
function ContextScope(data) {
|
|
569
|
+
const globals = config.globals || [];
|
|
570
|
+
function EjsContext(data) {
|
|
624
571
|
this[PARENT] = null;
|
|
625
572
|
this[BLOCKS] = {};
|
|
626
573
|
this[MACRO] = {};
|
|
627
574
|
Object.assign(
|
|
628
575
|
this,
|
|
629
|
-
omit(data, [SCOPE, BUFFER, SAFE, COMPONENT, ELEMENT])
|
|
576
|
+
omit(data, [SCOPE, BUFFER, SAFE, COMPONENT, ELEMENT]),
|
|
630
577
|
);
|
|
631
578
|
}
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
579
|
+
Object.entries(methods).forEach(([name, value]) => {
|
|
580
|
+
if (isFunction(value) && globals.includes(name)) {
|
|
581
|
+
value = value.bind(EjsContext.prototype);
|
|
582
|
+
}
|
|
583
|
+
EjsContext.prototype[name] = value;
|
|
636
584
|
});
|
|
637
|
-
Object.defineProperty(
|
|
585
|
+
Object.defineProperty(EjsContext.prototype, BUFFER, {
|
|
586
|
+
value: EjsBuffer(),
|
|
587
|
+
});
|
|
588
|
+
Object.defineProperty(EjsContext.prototype, BLOCKS, {
|
|
638
589
|
value: {},
|
|
639
|
-
writable: true
|
|
590
|
+
writable: true,
|
|
640
591
|
});
|
|
641
|
-
Object.defineProperty(
|
|
592
|
+
Object.defineProperty(EjsContext.prototype, MACRO, {
|
|
642
593
|
value: {},
|
|
643
|
-
writable: true
|
|
594
|
+
writable: true,
|
|
644
595
|
});
|
|
645
|
-
Object.defineProperty(
|
|
596
|
+
Object.defineProperty(EjsContext.prototype, LAYOUT, {
|
|
646
597
|
value: false,
|
|
647
|
-
writable: true
|
|
598
|
+
writable: true,
|
|
648
599
|
});
|
|
649
|
-
Object.defineProperty(
|
|
600
|
+
Object.defineProperty(EjsContext.prototype, EXTEND, {
|
|
650
601
|
value: false,
|
|
651
|
-
writable: true
|
|
602
|
+
writable: true,
|
|
652
603
|
});
|
|
653
|
-
Object.defineProperty(
|
|
604
|
+
Object.defineProperty(EjsContext.prototype, PARENT, {
|
|
654
605
|
value: null,
|
|
655
|
-
writable: true
|
|
606
|
+
writable: true,
|
|
656
607
|
});
|
|
657
|
-
Object.defineProperties(
|
|
608
|
+
Object.defineProperties(EjsContext.prototype, {
|
|
658
609
|
/** @type {function} */
|
|
659
610
|
setParentTemplate: {
|
|
660
611
|
value(value) {
|
|
661
612
|
this[PARENT] = value;
|
|
662
613
|
return this
|
|
663
|
-
}
|
|
614
|
+
},
|
|
664
615
|
},
|
|
665
616
|
/** @type {function} */
|
|
666
617
|
getParentTemplate: {
|
|
667
618
|
value() {
|
|
668
619
|
return this[PARENT]
|
|
669
|
-
}
|
|
620
|
+
},
|
|
670
621
|
},
|
|
671
622
|
/** @type {function} */
|
|
672
623
|
useSafeValue: {
|
|
673
|
-
get: () => safeValue
|
|
624
|
+
get: () => safeValue,
|
|
674
625
|
},
|
|
675
626
|
/** @type {function} */
|
|
676
627
|
useComponent: {
|
|
@@ -682,7 +633,7 @@ const createContextScope = (config, methods) => {
|
|
|
682
633
|
throw new Error(`${COMPONENT} must be a function`)
|
|
683
634
|
}
|
|
684
635
|
}
|
|
685
|
-
}
|
|
636
|
+
},
|
|
686
637
|
},
|
|
687
638
|
/** @type {function} */
|
|
688
639
|
useElement: {
|
|
@@ -694,51 +645,51 @@ const createContextScope = (config, methods) => {
|
|
|
694
645
|
throw new Error(`${ELEMENT} must be a function`)
|
|
695
646
|
}
|
|
696
647
|
}
|
|
697
|
-
}
|
|
648
|
+
},
|
|
698
649
|
},
|
|
699
|
-
/** @type {
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
return this[
|
|
703
|
-
}
|
|
650
|
+
/** @type {function} */
|
|
651
|
+
useBuffer: {
|
|
652
|
+
get() {
|
|
653
|
+
return this[BUFFER]
|
|
654
|
+
},
|
|
704
655
|
},
|
|
705
656
|
/** @type {function} */
|
|
706
|
-
|
|
657
|
+
getMacro: {
|
|
707
658
|
value() {
|
|
708
|
-
return this[
|
|
709
|
-
}
|
|
659
|
+
return this[MACRO]
|
|
660
|
+
},
|
|
710
661
|
},
|
|
711
662
|
/** @type {function} */
|
|
712
663
|
getBlocks: {
|
|
713
664
|
value() {
|
|
714
665
|
return this[BLOCKS]
|
|
715
|
-
}
|
|
666
|
+
},
|
|
716
667
|
},
|
|
717
668
|
/** @type {function} */
|
|
718
669
|
setExtend: {
|
|
719
670
|
value(value) {
|
|
720
671
|
this[EXTEND] = value;
|
|
721
672
|
return this
|
|
722
|
-
}
|
|
673
|
+
},
|
|
723
674
|
},
|
|
724
675
|
/** @type {function} */
|
|
725
676
|
getExtend: {
|
|
726
677
|
value() {
|
|
727
678
|
return this[EXTEND]
|
|
728
|
-
}
|
|
679
|
+
},
|
|
729
680
|
},
|
|
730
681
|
/** @type {function} */
|
|
731
682
|
setLayout: {
|
|
732
683
|
value(layout) {
|
|
733
684
|
this[LAYOUT] = layout;
|
|
734
685
|
return this
|
|
735
|
-
}
|
|
686
|
+
},
|
|
736
687
|
},
|
|
737
688
|
/** @type {function} */
|
|
738
689
|
getLayout: {
|
|
739
690
|
value() {
|
|
740
691
|
return this[LAYOUT]
|
|
741
|
-
}
|
|
692
|
+
},
|
|
742
693
|
},
|
|
743
694
|
/** @type {function} */
|
|
744
695
|
clone: {
|
|
@@ -748,36 +699,32 @@ const createContextScope = (config, methods) => {
|
|
|
748
699
|
filter.push(BLOCKS);
|
|
749
700
|
}
|
|
750
701
|
return omit(this, filter)
|
|
751
|
-
}
|
|
702
|
+
},
|
|
752
703
|
},
|
|
753
704
|
/** @type {function} */
|
|
754
705
|
extend: {
|
|
755
706
|
value(layout) {
|
|
756
707
|
this.setExtend(true);
|
|
757
708
|
this.setLayout(layout);
|
|
758
|
-
}
|
|
709
|
+
},
|
|
759
710
|
},
|
|
760
711
|
/** @type {function} */
|
|
761
712
|
echo: {
|
|
762
|
-
value(
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
params.forEach(buffer);
|
|
766
|
-
}
|
|
713
|
+
value() {
|
|
714
|
+
return [].slice.call(arguments).forEach(this.useBuffer)
|
|
715
|
+
},
|
|
767
716
|
},
|
|
768
717
|
/** @type {function} */
|
|
769
718
|
fn: {
|
|
770
719
|
value(callback) {
|
|
771
|
-
|
|
772
|
-
const context = this;
|
|
773
|
-
return function() {
|
|
720
|
+
return () => {
|
|
774
721
|
if (isFunction(callback)) {
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
return
|
|
722
|
+
this.useBuffer.backup();
|
|
723
|
+
this.useBuffer(callback.apply(this, arguments));
|
|
724
|
+
return this.useBuffer.restore()
|
|
778
725
|
}
|
|
779
726
|
}
|
|
780
|
-
}
|
|
727
|
+
},
|
|
781
728
|
},
|
|
782
729
|
/** @type {function} */
|
|
783
730
|
macro: {
|
|
@@ -785,10 +732,10 @@ const createContextScope = (config, methods) => {
|
|
|
785
732
|
const list = this.getMacro();
|
|
786
733
|
const macro = this.fn(callback);
|
|
787
734
|
const context = this;
|
|
788
|
-
list[name] = function() {
|
|
735
|
+
list[name] = function () {
|
|
789
736
|
return context.echo(macro.apply(undefined, arguments))
|
|
790
737
|
};
|
|
791
|
-
}
|
|
738
|
+
},
|
|
792
739
|
},
|
|
793
740
|
/** @type {function} */
|
|
794
741
|
call: {
|
|
@@ -799,7 +746,7 @@ const createContextScope = (config, methods) => {
|
|
|
799
746
|
if (isFunction(macro)) {
|
|
800
747
|
return macro.apply(macro, params)
|
|
801
748
|
}
|
|
802
|
-
}
|
|
749
|
+
},
|
|
803
750
|
},
|
|
804
751
|
/** @type {function} */
|
|
805
752
|
block: {
|
|
@@ -809,55 +756,53 @@ const createContextScope = (config, methods) => {
|
|
|
809
756
|
blocks[name].push(this.fn(callback));
|
|
810
757
|
if (this.getExtend()) return
|
|
811
758
|
const list = Object.assign([], blocks[name]);
|
|
812
|
-
const
|
|
813
|
-
return list.shift()
|
|
814
|
-
};
|
|
759
|
+
const shift = () => list.shift();
|
|
815
760
|
const next = () => {
|
|
816
|
-
const parent =
|
|
761
|
+
const parent = shift();
|
|
817
762
|
if (parent) {
|
|
818
763
|
return () => {
|
|
819
764
|
this.echo(parent(next()));
|
|
820
765
|
}
|
|
821
766
|
} else {
|
|
822
|
-
return
|
|
767
|
+
return () => {}
|
|
823
768
|
}
|
|
824
769
|
};
|
|
825
|
-
this.echo(
|
|
826
|
-
}
|
|
770
|
+
this.echo(shift()(next()));
|
|
771
|
+
},
|
|
827
772
|
},
|
|
828
773
|
/** @type {function} */
|
|
829
774
|
hasBlock: {
|
|
830
775
|
value(name) {
|
|
831
776
|
return this.getBlocks().hasOwnProperty(name)
|
|
832
|
-
}
|
|
777
|
+
},
|
|
833
778
|
},
|
|
834
779
|
/** @type {function} */
|
|
835
780
|
include: {
|
|
836
781
|
value(path, data, cx) {
|
|
837
782
|
const context = cx === false ? {} : this.clone(true);
|
|
838
|
-
const params =
|
|
783
|
+
const params = Object.assign(context, data || {});
|
|
839
784
|
const promise = this.render(path, params);
|
|
840
785
|
this.echo(promise);
|
|
841
|
-
}
|
|
786
|
+
},
|
|
842
787
|
},
|
|
843
788
|
/** @type {function} */
|
|
844
789
|
use: {
|
|
845
790
|
value(path, namespace) {
|
|
846
791
|
this.echo(
|
|
847
|
-
Promise.resolve(this.require(path)).then((exports) => {
|
|
792
|
+
Promise.resolve(this.require(path)).then((exports$1) => {
|
|
848
793
|
const list = this.getMacro();
|
|
849
|
-
each(exports,
|
|
794
|
+
each(exports$1, (macro, name) => {
|
|
850
795
|
list[[namespace, name].join('.')] = macro;
|
|
851
796
|
});
|
|
852
|
-
})
|
|
797
|
+
}),
|
|
853
798
|
);
|
|
854
|
-
}
|
|
799
|
+
},
|
|
855
800
|
},
|
|
856
801
|
/** @type {function} */
|
|
857
802
|
async: {
|
|
858
803
|
value(promise, callback) {
|
|
859
804
|
this.echo(Promise.resolve(promise).then(callback));
|
|
860
|
-
}
|
|
805
|
+
},
|
|
861
806
|
},
|
|
862
807
|
/** @type {function} */
|
|
863
808
|
get: {
|
|
@@ -866,7 +811,7 @@ const createContextScope = (config, methods) => {
|
|
|
866
811
|
const result = path.shift();
|
|
867
812
|
const prop = path.pop();
|
|
868
813
|
return hasProp(result, prop) ? result[prop] : defaults
|
|
869
|
-
}
|
|
814
|
+
},
|
|
870
815
|
},
|
|
871
816
|
/** @type {function} */
|
|
872
817
|
set: {
|
|
@@ -878,17 +823,17 @@ const createContextScope = (config, methods) => {
|
|
|
878
823
|
return result[prop]
|
|
879
824
|
}
|
|
880
825
|
return (result[prop] = value)
|
|
881
|
-
}
|
|
826
|
+
},
|
|
882
827
|
},
|
|
883
828
|
/** @type {function} */
|
|
884
829
|
each: {
|
|
885
|
-
value
|
|
830
|
+
value(object, callback) {
|
|
886
831
|
if (isString(object)) {
|
|
887
832
|
object = this.get(object, []);
|
|
888
833
|
}
|
|
889
834
|
each(object, callback);
|
|
890
835
|
},
|
|
891
|
-
writable: true
|
|
836
|
+
writable: true,
|
|
892
837
|
},
|
|
893
838
|
/** @type {function} */
|
|
894
839
|
el: {
|
|
@@ -896,131 +841,163 @@ const createContextScope = (config, methods) => {
|
|
|
896
841
|
content = isFunction(content) ? this.fn(content)() : content;
|
|
897
842
|
this.echo(
|
|
898
843
|
Promise.resolve(content).then((content) =>
|
|
899
|
-
element(tag, attr, content)
|
|
900
|
-
)
|
|
844
|
+
element(tag, attr, content),
|
|
845
|
+
),
|
|
901
846
|
);
|
|
902
847
|
},
|
|
903
|
-
writable: true
|
|
848
|
+
writable: true,
|
|
904
849
|
},
|
|
905
850
|
/** @type {function} */
|
|
906
851
|
ui: {
|
|
907
|
-
value(layout) {
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
}
|
|
852
|
+
value(layout) {},
|
|
853
|
+
writable: true,
|
|
854
|
+
},
|
|
911
855
|
});
|
|
912
|
-
return
|
|
856
|
+
return EjsContext
|
|
913
857
|
};
|
|
914
858
|
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
return new Scope(data)
|
|
922
|
-
};
|
|
923
|
-
const helpers = (methods) => {
|
|
924
|
-
extend(Scope.prototype, methods || {});
|
|
925
|
-
};
|
|
926
|
-
const configure = (options, methods) => {
|
|
927
|
-
Scope = createContextScope(options, methods);
|
|
928
|
-
};
|
|
929
|
-
configure(options, methods);
|
|
930
|
-
return {
|
|
931
|
-
configure,
|
|
932
|
-
create,
|
|
933
|
-
helpers
|
|
859
|
+
class Context {
|
|
860
|
+
#context
|
|
861
|
+
static exports = ['create', 'globals', 'helpers']
|
|
862
|
+
constructor(options, methods) {
|
|
863
|
+
bindContext(this, this.constructor.exports);
|
|
864
|
+
this.configure(options, methods);
|
|
934
865
|
}
|
|
935
|
-
|
|
866
|
+
create(data) {
|
|
867
|
+
return new this.#context(data)
|
|
868
|
+
}
|
|
869
|
+
helpers(methods) {
|
|
870
|
+
Object.assign(this.#context.prototype, methods);
|
|
871
|
+
}
|
|
872
|
+
configure(options, methods) {
|
|
873
|
+
this.#context = createContext$1(options, methods);
|
|
874
|
+
}
|
|
875
|
+
}
|
|
936
876
|
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
}
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
877
|
+
class EjsInstance {
|
|
878
|
+
#cache
|
|
879
|
+
#context
|
|
880
|
+
#compiler
|
|
881
|
+
#template
|
|
882
|
+
#config = {}
|
|
883
|
+
#methods = {}
|
|
884
|
+
static exports = [
|
|
885
|
+
'configure',
|
|
886
|
+
'create',
|
|
887
|
+
'createContext',
|
|
888
|
+
'render',
|
|
889
|
+
'require',
|
|
890
|
+
'preload',
|
|
891
|
+
'compile',
|
|
892
|
+
'helpers',
|
|
893
|
+
]
|
|
894
|
+
constructor(options = {}) {
|
|
895
|
+
bindContext(this, this.constructor.exports);
|
|
896
|
+
this.#methods = {};
|
|
897
|
+
this.#config = configSchema({}, options);
|
|
898
|
+
this.#context = new Context(this.#config, this.#methods);
|
|
899
|
+
this.#compiler = new Compiler(this.#config);
|
|
900
|
+
this.#cache = new Cache(this.#config);
|
|
901
|
+
this.#template = new Template(this.#config, this.#cache, this.#compiler);
|
|
902
|
+
this.helpers({ render: this.render, require: this.require });
|
|
903
|
+
}
|
|
904
|
+
create(options) {
|
|
905
|
+
return new this.constructor(options)
|
|
906
|
+
}
|
|
907
|
+
configure(options) {
|
|
908
|
+
if (options) {
|
|
909
|
+
configSchema(this.#config, options);
|
|
910
|
+
this.#context.configure(this.#config, this.#methods);
|
|
911
|
+
this.#compiler.configure(this.#config);
|
|
912
|
+
this.#cache.configure(this.#config);
|
|
913
|
+
this.#template.configure(this.#config);
|
|
914
|
+
}
|
|
915
|
+
return this.#config
|
|
916
|
+
}
|
|
917
|
+
createContext(data) {
|
|
918
|
+
return this.#context.create(data)
|
|
919
|
+
}
|
|
920
|
+
preload(list) {
|
|
921
|
+
return this.#cache.load(list || {})
|
|
922
|
+
}
|
|
923
|
+
compile(content, path) {
|
|
924
|
+
return this.#compiler.compile(content, path)
|
|
925
|
+
}
|
|
926
|
+
helpers(methods) {
|
|
927
|
+
this.#context.helpers(Object.assign(this.#methods, methods));
|
|
928
|
+
}
|
|
929
|
+
async render(name, params) {
|
|
930
|
+
const data = this.createContext(params);
|
|
931
|
+
return this.#output(this.#path(name), data).then(
|
|
932
|
+
this.#outputContent(name, data),
|
|
933
|
+
)
|
|
934
|
+
}
|
|
935
|
+
async require(name) {
|
|
936
|
+
const data = this.createContext({});
|
|
937
|
+
return this.#output(this.#path(name), data).then(() => data.getMacro())
|
|
938
|
+
}
|
|
939
|
+
#path(name) {
|
|
940
|
+
const ext = name.split('.').pop();
|
|
941
|
+
if (ext !== this.#config.extension) {
|
|
942
|
+
name = [name, this.#config.extension].join('.');
|
|
943
|
+
}
|
|
944
|
+
return name
|
|
945
|
+
}
|
|
946
|
+
#output(path, data) {
|
|
947
|
+
return this.#template
|
|
948
|
+
.get(path)
|
|
949
|
+
.then((callback) =>
|
|
950
|
+
callback.apply(data, [
|
|
951
|
+
data,
|
|
952
|
+
data.useComponent,
|
|
953
|
+
data.useElement,
|
|
954
|
+
data.useBuffer,
|
|
955
|
+
data.useSafeValue,
|
|
956
|
+
]),
|
|
957
|
+
)
|
|
958
|
+
}
|
|
959
|
+
#renderLayout(name, params, parentTemplate) {
|
|
960
|
+
const data = this.createContext(params);
|
|
961
|
+
if (parentTemplate) data.setParentTemplate(parentTemplate);
|
|
962
|
+
return this.#output(this.#path(name), data).then(
|
|
963
|
+
this.#outputContent(name, data),
|
|
964
|
+
)
|
|
965
|
+
}
|
|
966
|
+
#outputContent(name, data) {
|
|
964
967
|
return (content) => {
|
|
965
|
-
if (
|
|
966
|
-
|
|
967
|
-
return renderLayout(
|
|
968
|
+
if (data.getExtend()) {
|
|
969
|
+
data.setExtend(false);
|
|
970
|
+
return this.#renderLayout(data.getLayout(), data, name)
|
|
968
971
|
}
|
|
969
972
|
return content
|
|
970
973
|
}
|
|
971
|
-
};
|
|
972
|
-
const renderLayout = (name, data, parent) => {
|
|
973
|
-
const scope = createContext(data);
|
|
974
|
-
if (parent) scope.setParentTemplate(parent);
|
|
975
|
-
return output(filePath(name), scope).then(outputContent(name, scope))
|
|
976
|
-
};
|
|
977
|
-
const helpers = (extendMethods) => {
|
|
978
|
-
context.helpers(extend(methods, extendMethods));
|
|
979
|
-
};
|
|
980
|
-
const createContext = (data) => {
|
|
981
|
-
return context.create(data)
|
|
982
|
-
};
|
|
983
|
-
const compile = (content, path) => {
|
|
984
|
-
return compiler.compile(content, path)
|
|
985
|
-
};
|
|
986
|
-
const preload = (list) => {
|
|
987
|
-
return cache.load(list || {})
|
|
988
|
-
};
|
|
989
|
-
const create = (config) => {
|
|
990
|
-
return EJS(config)
|
|
991
|
-
};
|
|
992
|
-
const output = (path, scope) => {
|
|
993
|
-
const params = [scope, scope.useComponent, scope.useElement, scope.getBuffer(), scope.useSafeValue];
|
|
994
|
-
const globals = config.globalHelpers
|
|
995
|
-
.filter((name) => isFunction(scope[name]))
|
|
996
|
-
.map((name) => scope[name].bind(scope));
|
|
997
|
-
return template
|
|
998
|
-
.get(path)
|
|
999
|
-
.then((callback) => callback.apply(scope, params.concat(globals)))
|
|
1000
|
-
};
|
|
1001
|
-
helpers({ render, require });
|
|
1002
|
-
return {
|
|
1003
|
-
configure,
|
|
1004
|
-
create,
|
|
1005
|
-
createContext,
|
|
1006
|
-
render,
|
|
1007
|
-
require,
|
|
1008
|
-
preload,
|
|
1009
|
-
compile,
|
|
1010
|
-
helpers
|
|
1011
974
|
}
|
|
1012
|
-
}
|
|
975
|
+
}
|
|
1013
976
|
|
|
1014
977
|
const httpRequest = (path, template) => {
|
|
1015
978
|
return fetch(joinPath(path, template)).then(
|
|
1016
|
-
(response) =>
|
|
1017
|
-
|
|
979
|
+
(response) => {
|
|
980
|
+
if (response.ok) return response.text()
|
|
981
|
+
throw new TemplateNotFound(
|
|
982
|
+
`template ${path} / ${template} not found`,
|
|
983
|
+
)
|
|
984
|
+
},
|
|
985
|
+
(reason) => {
|
|
986
|
+
return new TemplateError(reason)
|
|
987
|
+
},
|
|
1018
988
|
)
|
|
1019
989
|
};
|
|
1020
990
|
|
|
1021
|
-
const {
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
991
|
+
const {
|
|
992
|
+
render,
|
|
993
|
+
createContext,
|
|
994
|
+
compile,
|
|
995
|
+
helpers,
|
|
996
|
+
preload,
|
|
997
|
+
configure,
|
|
998
|
+
create,
|
|
999
|
+
} = new EjsInstance({
|
|
1000
|
+
resolver: httpRequest,
|
|
1001
|
+
});
|
|
1025
1002
|
|
|
1026
1003
|
export { TemplateError, TemplateNotFound, TemplateSyntaxError, compile, configure, create, createContext, helpers, preload, render };
|