@itrocks/template 0.0.24 → 0.0.26
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 +15 -1
- package/cjs/template.d.ts +3 -0
- package/cjs/template.js +39 -8
- package/esm/template.d.ts +3 -0
- package/esm/template.js +39 -8
- package/package.json +1 -1
package/README.md
CHANGED
@@ -377,13 +377,27 @@ Result:
|
|
377
377
|
|
378
378
|
### Including Another Template
|
379
379
|
|
380
|
-
Any expression starting with `./` or `../` is considered a template include:
|
380
|
+
Any expression starting with `/`, `./` or `../` is considered a template include:
|
381
381
|
```html
|
382
382
|
<div>
|
383
383
|
{./another-template.html}
|
384
384
|
</div>
|
385
385
|
```
|
386
386
|
|
387
|
+
The default contextual data is the one in the current scope.
|
388
|
+
|
389
|
+
You can pass parent or sub-data to your included template as an alternative context:
|
390
|
+
```html
|
391
|
+
<div>
|
392
|
+
<!--subData-->
|
393
|
+
{./another-template.html-}
|
394
|
+
{./another-template.html(-)}
|
395
|
+
<!--end-->
|
396
|
+
{./another-template.html(subData)}
|
397
|
+
</div>
|
398
|
+
```
|
399
|
+
In this example, `-` refers to the parent block context. Parentheses are optional in this specific case.
|
400
|
+
|
387
401
|
#### Delimiting Rendered Content in an Included Template
|
388
402
|
|
389
403
|
To keep templates W3C-compliant and browser-viewable, each HTML template may contain full HTML structure.
|
package/cjs/template.d.ts
CHANGED
@@ -31,6 +31,7 @@ export default class Template {
|
|
31
31
|
literalParts: string[];
|
32
32
|
literalPartStack: string[][];
|
33
33
|
lockLiteral: boolean;
|
34
|
+
addLinks: SortedArray<string>;
|
34
35
|
doHeadLinks: boolean;
|
35
36
|
doneLinks: SortedArray<string>;
|
36
37
|
headLinks: SortedArray<string>;
|
@@ -54,6 +55,7 @@ export default class Template {
|
|
54
55
|
combineLiterals(text: string, parts?: string[]): string;
|
55
56
|
debugEvents(): void;
|
56
57
|
getCleanContext(): {
|
58
|
+
addLinks: SortedArray<string>;
|
57
59
|
doHeadLinks: boolean;
|
58
60
|
doneLinks: SortedArray<string>;
|
59
61
|
headLinks: SortedArray<string>;
|
@@ -73,6 +75,7 @@ export default class Template {
|
|
73
75
|
target: string;
|
74
76
|
};
|
75
77
|
getContext(): {
|
78
|
+
addLinks: SortedArray<string>;
|
76
79
|
doHeadLinks: boolean;
|
77
80
|
doneLinks: SortedArray<string>;
|
78
81
|
headLinks: SortedArray<string>;
|
package/cjs/template.js
CHANGED
@@ -34,6 +34,7 @@ class Template {
|
|
34
34
|
literalPartStack = [];
|
35
35
|
lockLiteral = false;
|
36
36
|
// html head
|
37
|
+
addLinks = new sorted_array_1.SortedArray();
|
37
38
|
doHeadLinks = false;
|
38
39
|
doneLinks = new sorted_array_1.SortedArray();
|
39
40
|
headLinks = new sorted_array_1.SortedArray();
|
@@ -61,6 +62,7 @@ class Template {
|
|
61
62
|
constructor(data, containerData) {
|
62
63
|
this.data = data;
|
63
64
|
this.containerData = containerData;
|
65
|
+
this.addLinks.distinct = true;
|
64
66
|
this.doneLinks.distinct = true;
|
65
67
|
this.headLinks.distinct = true;
|
66
68
|
this.blockStack = [];
|
@@ -112,11 +114,14 @@ class Template {
|
|
112
114
|
this.onTagClose = (name) => console.log('tag.closed =', name);
|
113
115
|
}
|
114
116
|
getCleanContext() {
|
117
|
+
const addLinks = new sorted_array_1.SortedArray;
|
115
118
|
const doneLinks = new sorted_array_1.SortedArray;
|
116
119
|
const headLinks = new sorted_array_1.SortedArray;
|
120
|
+
addLinks.distinct = true;
|
117
121
|
doneLinks.distinct = true;
|
118
122
|
headLinks.distinct = true;
|
119
123
|
return {
|
124
|
+
addLinks: addLinks,
|
120
125
|
doHeadLinks: false,
|
121
126
|
doneLinks: doneLinks,
|
122
127
|
headLinks: headLinks,
|
@@ -136,6 +141,7 @@ class Template {
|
|
136
141
|
}
|
137
142
|
getContext() {
|
138
143
|
return {
|
144
|
+
addLinks: this.addLinks,
|
139
145
|
doHeadLinks: this.doHeadLinks,
|
140
146
|
doneLinks: this.doneLinks,
|
141
147
|
headLinks: this.headLinks,
|
@@ -166,14 +172,23 @@ class Template {
|
|
166
172
|
const parsed = await template.parseFile(((path[0] === node_path_1.sep) || (path[1] === ':'))
|
167
173
|
? path
|
168
174
|
: (this.filePath + node_path_1.sep + path));
|
175
|
+
if (!this.doHeadLinks) {
|
176
|
+
this.addLinks.push(...template.headLinks);
|
177
|
+
}
|
169
178
|
this.headLinks.push(...template.headLinks);
|
170
179
|
this.headTitle = template.headTitle;
|
171
|
-
|
180
|
+
const beginPosition = parsed.indexOf('<!--BEGIN-->');
|
181
|
+
const endPosition = parsed.indexOf('<!--END-->');
|
182
|
+
return (beginPosition > -1)
|
183
|
+
? parsed.slice(beginPosition + 12, (endPosition > -1) ? endPosition : parsed.length)
|
184
|
+
: parsed;
|
172
185
|
}
|
173
186
|
isContextClean() {
|
174
187
|
const clean = this.getCleanContext();
|
175
188
|
const context = this.getContext();
|
176
189
|
return context.doHeadLinks === clean.doHeadLinks
|
190
|
+
&& context.addLinks.distinct === clean.addLinks.distinct
|
191
|
+
&& context.addLinks.length === clean.addLinks.length
|
177
192
|
&& context.doneLinks.distinct === clean.doneLinks.distinct
|
178
193
|
&& context.doneLinks.length === clean.doneLinks.length
|
179
194
|
&& context.headLinks.distinct === clean.headLinks.distinct
|
@@ -210,9 +225,9 @@ class Template {
|
|
210
225
|
if (this.doHeadLinks) {
|
211
226
|
return this.target;
|
212
227
|
}
|
213
|
-
if (this.
|
228
|
+
if (this.addLinks.length) {
|
214
229
|
const position = this.target.lastIndexOf('>', this.target.indexOf('</head>')) + 1;
|
215
|
-
this.target = this.target.slice(0, position) + '\n\t' + this.
|
230
|
+
this.target = this.target.slice(0, position) + '\n\t' + this.addLinks.join('\n\t') + this.target.slice(position);
|
216
231
|
}
|
217
232
|
if (this.headTitle && !this.included) {
|
218
233
|
const position = this.target.indexOf('>', this.target.indexOf('<title') + 6) + 1;
|
@@ -290,7 +305,7 @@ class Template {
|
|
290
305
|
if (conditional && !parsed) {
|
291
306
|
if ((typeof this.target)[0] === 's') {
|
292
307
|
this.target = this.target.substring(0, this.target.lastIndexOf(' '));
|
293
|
-
while ((this.index < this.length) && !'
|
308
|
+
while ((this.index < this.length) && !' >\n\r\t\f'.includes(this.source[this.index])) {
|
294
309
|
this.index++;
|
295
310
|
this.start++;
|
296
311
|
}
|
@@ -333,7 +348,23 @@ class Template {
|
|
333
348
|
if (expression === '') {
|
334
349
|
return undefined;
|
335
350
|
}
|
336
|
-
if ((expression[0] === '.') && (expression
|
351
|
+
if (((expression[0] === '.') && ((expression[1] === '/') || ((expression[1] === '.') && (expression[2] === '/'))))
|
352
|
+
|| (expression[0] === '/')) {
|
353
|
+
let expressionEnd = expression.length - 1;
|
354
|
+
if (expression[expressionEnd] === '-') {
|
355
|
+
let blockBack = 1;
|
356
|
+
expressionEnd--;
|
357
|
+
while (expression[expressionEnd] === '-') {
|
358
|
+
blockBack++;
|
359
|
+
expressionEnd--;
|
360
|
+
}
|
361
|
+
const blockStack = this.blockStack;
|
362
|
+
return this.include(expression.slice(0, expressionEnd), blockStack[blockStack.length - blockBack].data);
|
363
|
+
}
|
364
|
+
if (expression[expressionEnd] === ')') {
|
365
|
+
const openPosition = expression.lastIndexOf('(');
|
366
|
+
return this.include(expression.slice(0, openPosition), await this.parsePath(expression.slice(openPosition + 1, expression.length - 1), data));
|
367
|
+
}
|
337
368
|
return this.include(expression, data);
|
338
369
|
}
|
339
370
|
this.blockBack = 0;
|
@@ -344,7 +375,7 @@ class Template {
|
|
344
375
|
}
|
345
376
|
async parseVariable(variable, data) {
|
346
377
|
if (variable === '') {
|
347
|
-
return (typeof data === '
|
378
|
+
return (((typeof data)[0] === 'f') && ((data + '')[0] !== 'c'))
|
348
379
|
? data.call()
|
349
380
|
: data;
|
350
381
|
}
|
@@ -372,7 +403,7 @@ class Template {
|
|
372
403
|
data = new rename_1.default(data);
|
373
404
|
}
|
374
405
|
let value = data[variable];
|
375
|
-
return ((typeof value === '
|
406
|
+
return (((typeof value)[0] === 'f') && ((value + '')[0] !== 'c'))
|
376
407
|
? value.call(data)
|
377
408
|
: value;
|
378
409
|
}
|
@@ -446,7 +477,6 @@ class Template {
|
|
446
477
|
continue;
|
447
478
|
}
|
448
479
|
// begin condition / loop block
|
449
|
-
this.blockStack.push({ blockStart, collection, data, iteration, iterations });
|
450
480
|
if (tagIndex > this.start) {
|
451
481
|
this.target += this.trimEndLine(this.source.substring(this.start, tagIndex));
|
452
482
|
this.start = tagIndex;
|
@@ -457,6 +487,7 @@ class Template {
|
|
457
487
|
this.target = '';
|
458
488
|
this.inLiteral = false;
|
459
489
|
const condition = await this.parseExpression(data, '}', '-->');
|
490
|
+
this.blockStack.push({ blockStart, collection, data, iteration, iterations });
|
460
491
|
let blockData = condition ? (this.target ? data : undefined) : this.target;
|
461
492
|
blockStart = this.index;
|
462
493
|
iteration = 0;
|
package/esm/template.d.ts
CHANGED
@@ -31,6 +31,7 @@ export default class Template {
|
|
31
31
|
literalParts: string[];
|
32
32
|
literalPartStack: string[][];
|
33
33
|
lockLiteral: boolean;
|
34
|
+
addLinks: SortedArray<string>;
|
34
35
|
doHeadLinks: boolean;
|
35
36
|
doneLinks: SortedArray<string>;
|
36
37
|
headLinks: SortedArray<string>;
|
@@ -54,6 +55,7 @@ export default class Template {
|
|
54
55
|
combineLiterals(text: string, parts?: string[]): string;
|
55
56
|
debugEvents(): void;
|
56
57
|
getCleanContext(): {
|
58
|
+
addLinks: SortedArray<string>;
|
57
59
|
doHeadLinks: boolean;
|
58
60
|
doneLinks: SortedArray<string>;
|
59
61
|
headLinks: SortedArray<string>;
|
@@ -73,6 +75,7 @@ export default class Template {
|
|
73
75
|
target: string;
|
74
76
|
};
|
75
77
|
getContext(): {
|
78
|
+
addLinks: SortedArray<string>;
|
76
79
|
doHeadLinks: boolean;
|
77
80
|
doneLinks: SortedArray<string>;
|
78
81
|
headLinks: SortedArray<string>;
|
package/esm/template.js
CHANGED
@@ -29,6 +29,7 @@ export default class Template {
|
|
29
29
|
literalPartStack = [];
|
30
30
|
lockLiteral = false;
|
31
31
|
// html head
|
32
|
+
addLinks = new SortedArray();
|
32
33
|
doHeadLinks = false;
|
33
34
|
doneLinks = new SortedArray();
|
34
35
|
headLinks = new SortedArray();
|
@@ -56,6 +57,7 @@ export default class Template {
|
|
56
57
|
constructor(data, containerData) {
|
57
58
|
this.data = data;
|
58
59
|
this.containerData = containerData;
|
60
|
+
this.addLinks.distinct = true;
|
59
61
|
this.doneLinks.distinct = true;
|
60
62
|
this.headLinks.distinct = true;
|
61
63
|
this.blockStack = [];
|
@@ -107,11 +109,14 @@ export default class Template {
|
|
107
109
|
this.onTagClose = (name) => console.log('tag.closed =', name);
|
108
110
|
}
|
109
111
|
getCleanContext() {
|
112
|
+
const addLinks = new SortedArray;
|
110
113
|
const doneLinks = new SortedArray;
|
111
114
|
const headLinks = new SortedArray;
|
115
|
+
addLinks.distinct = true;
|
112
116
|
doneLinks.distinct = true;
|
113
117
|
headLinks.distinct = true;
|
114
118
|
return {
|
119
|
+
addLinks: addLinks,
|
115
120
|
doHeadLinks: false,
|
116
121
|
doneLinks: doneLinks,
|
117
122
|
headLinks: headLinks,
|
@@ -131,6 +136,7 @@ export default class Template {
|
|
131
136
|
}
|
132
137
|
getContext() {
|
133
138
|
return {
|
139
|
+
addLinks: this.addLinks,
|
134
140
|
doHeadLinks: this.doHeadLinks,
|
135
141
|
doneLinks: this.doneLinks,
|
136
142
|
headLinks: this.headLinks,
|
@@ -161,14 +167,23 @@ export default class Template {
|
|
161
167
|
const parsed = await template.parseFile(((path[0] === sep) || (path[1] === ':'))
|
162
168
|
? path
|
163
169
|
: (this.filePath + sep + path));
|
170
|
+
if (!this.doHeadLinks) {
|
171
|
+
this.addLinks.push(...template.headLinks);
|
172
|
+
}
|
164
173
|
this.headLinks.push(...template.headLinks);
|
165
174
|
this.headTitle = template.headTitle;
|
166
|
-
|
175
|
+
const beginPosition = parsed.indexOf('<!--BEGIN-->');
|
176
|
+
const endPosition = parsed.indexOf('<!--END-->');
|
177
|
+
return (beginPosition > -1)
|
178
|
+
? parsed.slice(beginPosition + 12, (endPosition > -1) ? endPosition : parsed.length)
|
179
|
+
: parsed;
|
167
180
|
}
|
168
181
|
isContextClean() {
|
169
182
|
const clean = this.getCleanContext();
|
170
183
|
const context = this.getContext();
|
171
184
|
return context.doHeadLinks === clean.doHeadLinks
|
185
|
+
&& context.addLinks.distinct === clean.addLinks.distinct
|
186
|
+
&& context.addLinks.length === clean.addLinks.length
|
172
187
|
&& context.doneLinks.distinct === clean.doneLinks.distinct
|
173
188
|
&& context.doneLinks.length === clean.doneLinks.length
|
174
189
|
&& context.headLinks.distinct === clean.headLinks.distinct
|
@@ -205,9 +220,9 @@ export default class Template {
|
|
205
220
|
if (this.doHeadLinks) {
|
206
221
|
return this.target;
|
207
222
|
}
|
208
|
-
if (this.
|
223
|
+
if (this.addLinks.length) {
|
209
224
|
const position = this.target.lastIndexOf('>', this.target.indexOf('</head>')) + 1;
|
210
|
-
this.target = this.target.slice(0, position) + '\n\t' + this.
|
225
|
+
this.target = this.target.slice(0, position) + '\n\t' + this.addLinks.join('\n\t') + this.target.slice(position);
|
211
226
|
}
|
212
227
|
if (this.headTitle && !this.included) {
|
213
228
|
const position = this.target.indexOf('>', this.target.indexOf('<title') + 6) + 1;
|
@@ -285,7 +300,7 @@ export default class Template {
|
|
285
300
|
if (conditional && !parsed) {
|
286
301
|
if ((typeof this.target)[0] === 's') {
|
287
302
|
this.target = this.target.substring(0, this.target.lastIndexOf(' '));
|
288
|
-
while ((this.index < this.length) && !'
|
303
|
+
while ((this.index < this.length) && !' >\n\r\t\f'.includes(this.source[this.index])) {
|
289
304
|
this.index++;
|
290
305
|
this.start++;
|
291
306
|
}
|
@@ -328,7 +343,23 @@ export default class Template {
|
|
328
343
|
if (expression === '') {
|
329
344
|
return undefined;
|
330
345
|
}
|
331
|
-
if ((expression[0] === '.') && (expression
|
346
|
+
if (((expression[0] === '.') && ((expression[1] === '/') || ((expression[1] === '.') && (expression[2] === '/'))))
|
347
|
+
|| (expression[0] === '/')) {
|
348
|
+
let expressionEnd = expression.length - 1;
|
349
|
+
if (expression[expressionEnd] === '-') {
|
350
|
+
let blockBack = 1;
|
351
|
+
expressionEnd--;
|
352
|
+
while (expression[expressionEnd] === '-') {
|
353
|
+
blockBack++;
|
354
|
+
expressionEnd--;
|
355
|
+
}
|
356
|
+
const blockStack = this.blockStack;
|
357
|
+
return this.include(expression.slice(0, expressionEnd), blockStack[blockStack.length - blockBack].data);
|
358
|
+
}
|
359
|
+
if (expression[expressionEnd] === ')') {
|
360
|
+
const openPosition = expression.lastIndexOf('(');
|
361
|
+
return this.include(expression.slice(0, openPosition), await this.parsePath(expression.slice(openPosition + 1, expression.length - 1), data));
|
362
|
+
}
|
332
363
|
return this.include(expression, data);
|
333
364
|
}
|
334
365
|
this.blockBack = 0;
|
@@ -339,7 +370,7 @@ export default class Template {
|
|
339
370
|
}
|
340
371
|
async parseVariable(variable, data) {
|
341
372
|
if (variable === '') {
|
342
|
-
return (typeof data === '
|
373
|
+
return (((typeof data)[0] === 'f') && ((data + '')[0] !== 'c'))
|
343
374
|
? data.call()
|
344
375
|
: data;
|
345
376
|
}
|
@@ -367,7 +398,7 @@ export default class Template {
|
|
367
398
|
data = new Str(data);
|
368
399
|
}
|
369
400
|
let value = data[variable];
|
370
|
-
return ((typeof value === '
|
401
|
+
return (((typeof value)[0] === 'f') && ((value + '')[0] !== 'c'))
|
371
402
|
? value.call(data)
|
372
403
|
: value;
|
373
404
|
}
|
@@ -441,7 +472,6 @@ export default class Template {
|
|
441
472
|
continue;
|
442
473
|
}
|
443
474
|
// begin condition / loop block
|
444
|
-
this.blockStack.push({ blockStart, collection, data, iteration, iterations });
|
445
475
|
if (tagIndex > this.start) {
|
446
476
|
this.target += this.trimEndLine(this.source.substring(this.start, tagIndex));
|
447
477
|
this.start = tagIndex;
|
@@ -452,6 +482,7 @@ export default class Template {
|
|
452
482
|
this.target = '';
|
453
483
|
this.inLiteral = false;
|
454
484
|
const condition = await this.parseExpression(data, '}', '-->');
|
485
|
+
this.blockStack.push({ blockStart, collection, data, iteration, iterations });
|
455
486
|
let blockData = condition ? (this.target ? data : undefined) : this.target;
|
456
487
|
blockStart = this.index;
|
457
488
|
iteration = 0;
|
package/package.json
CHANGED