@itrocks/template 0.0.25 → 0.0.27
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 +4 -3
- package/cjs/template.js +34 -12
- package/esm/template.d.ts +4 -3
- package/esm/template.js +34 -12
- 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
@@ -1,11 +1,12 @@
|
|
1
1
|
import { SortedArray } from '@itrocks/sorted-array';
|
2
|
-
type
|
2
|
+
type BlockStackEntry = {
|
3
3
|
blockStart: number;
|
4
4
|
collection: any[];
|
5
|
+
condition?: boolean;
|
5
6
|
data: any;
|
6
7
|
iteration: number;
|
7
8
|
iterations: number;
|
8
|
-
}
|
9
|
+
};
|
9
10
|
export type VariableParser = [parser: string, (variable: string, data: any) => any];
|
10
11
|
export declare const frontScripts: SortedArray<string>;
|
11
12
|
export { Template };
|
@@ -13,7 +14,7 @@ export default class Template {
|
|
13
14
|
data?: any;
|
14
15
|
containerData?: any;
|
15
16
|
blockBack: number;
|
16
|
-
blockStack:
|
17
|
+
blockStack: BlockStackEntry[];
|
17
18
|
doExpression: boolean;
|
18
19
|
index: number;
|
19
20
|
length: number;
|
package/cjs/template.js
CHANGED
@@ -16,7 +16,7 @@ class Template {
|
|
16
16
|
containerData;
|
17
17
|
// block stack
|
18
18
|
blockBack = 0;
|
19
|
-
blockStack;
|
19
|
+
blockStack = [];
|
20
20
|
// parser
|
21
21
|
doExpression = true;
|
22
22
|
index = 0;
|
@@ -65,7 +65,6 @@ class Template {
|
|
65
65
|
this.addLinks.distinct = true;
|
66
66
|
this.doneLinks.distinct = true;
|
67
67
|
this.headLinks.distinct = true;
|
68
|
-
this.blockStack = [];
|
69
68
|
if (containerData) {
|
70
69
|
this.blockStack.push({ blockStart: 0, collection: [], data: containerData, iteration: 0, iterations: 1 });
|
71
70
|
}
|
@@ -177,7 +176,11 @@ class Template {
|
|
177
176
|
}
|
178
177
|
this.headLinks.push(...template.headLinks);
|
179
178
|
this.headTitle = template.headTitle;
|
180
|
-
|
179
|
+
const beginPosition = parsed.indexOf('<!--BEGIN-->');
|
180
|
+
const endPosition = parsed.indexOf('<!--END-->');
|
181
|
+
return (beginPosition > -1)
|
182
|
+
? parsed.slice(beginPosition + 12, (endPosition > -1) ? endPosition : parsed.length)
|
183
|
+
: parsed;
|
181
184
|
}
|
182
185
|
isContextClean() {
|
183
186
|
const clean = this.getCleanContext();
|
@@ -301,7 +304,7 @@ class Template {
|
|
301
304
|
if (conditional && !parsed) {
|
302
305
|
if ((typeof this.target)[0] === 's') {
|
303
306
|
this.target = this.target.substring(0, this.target.lastIndexOf(' '));
|
304
|
-
while ((this.index < this.length) && !'
|
307
|
+
while ((this.index < this.length) && !' >\n\r\t\f'.includes(this.source[this.index])) {
|
305
308
|
this.index++;
|
306
309
|
this.start++;
|
307
310
|
}
|
@@ -344,7 +347,23 @@ class Template {
|
|
344
347
|
if (expression === '') {
|
345
348
|
return undefined;
|
346
349
|
}
|
347
|
-
if ((expression[0] === '.') && (expression
|
350
|
+
if (((expression[0] === '.') && ((expression[1] === '/') || ((expression[1] === '.') && (expression[2] === '/'))))
|
351
|
+
|| (expression[0] === '/')) {
|
352
|
+
let expressionEnd = expression.length - 1;
|
353
|
+
if (expression[expressionEnd] === '-') {
|
354
|
+
let blockBack = 1;
|
355
|
+
expressionEnd--;
|
356
|
+
while (expression[expressionEnd] === '-') {
|
357
|
+
blockBack++;
|
358
|
+
expressionEnd--;
|
359
|
+
}
|
360
|
+
const blockStack = this.blockStack;
|
361
|
+
return this.include(expression.slice(0, expressionEnd), blockStack[blockStack.length - blockBack].data);
|
362
|
+
}
|
363
|
+
if (expression[expressionEnd] === ')') {
|
364
|
+
const openPosition = expression.lastIndexOf('(');
|
365
|
+
return this.include(expression.slice(0, openPosition), await this.parsePath(expression.slice(openPosition + 1, expression.length - 1), data));
|
366
|
+
}
|
348
367
|
return this.include(expression, data);
|
349
368
|
}
|
350
369
|
this.blockBack = 0;
|
@@ -355,7 +374,7 @@ class Template {
|
|
355
374
|
}
|
356
375
|
async parseVariable(variable, data) {
|
357
376
|
if (variable === '') {
|
358
|
-
return (typeof data === '
|
377
|
+
return (((typeof data)[0] === 'f') && ((data + '')[0] !== 'c'))
|
359
378
|
? data.call()
|
360
379
|
: data;
|
361
380
|
}
|
@@ -371,8 +390,12 @@ class Template {
|
|
371
390
|
return variable.substring(1, variable.length - 1);
|
372
391
|
}
|
373
392
|
if (firstChar === '-') {
|
374
|
-
|
375
|
-
|
393
|
+
let dataBack;
|
394
|
+
do {
|
395
|
+
this.blockBack++;
|
396
|
+
dataBack = this.blockStack[this.blockStack.length - this.blockBack];
|
397
|
+
} while (dataBack.condition);
|
398
|
+
return dataBack.data;
|
376
399
|
}
|
377
400
|
for (const [prefix, callback] of this.parsers) {
|
378
401
|
if (firstChar === prefix) {
|
@@ -383,7 +406,7 @@ class Template {
|
|
383
406
|
data = new rename_1.default(data);
|
384
407
|
}
|
385
408
|
let value = data[variable];
|
386
|
-
return ((typeof value === '
|
409
|
+
return (((typeof value)[0] === 'f') && ((value + '')[0] !== 'c'))
|
387
410
|
? value.call(data)
|
388
411
|
: value;
|
389
412
|
}
|
@@ -435,8 +458,7 @@ class Template {
|
|
435
458
|
continue;
|
436
459
|
}
|
437
460
|
// end condition / loop block
|
438
|
-
if ('
|
439
|
-
&& ['end-->', 'END-->'].includes(this.source.substring(this.index, this.index + 6))) {
|
461
|
+
if ((firstChar === 'e') && (this.source.substring(this.index, this.index + 6) === 'end-->')) {
|
440
462
|
this.target += this.trimEndLine(this.source.substring(this.start, tagIndex));
|
441
463
|
iteration++;
|
442
464
|
if (iteration < iterations) {
|
@@ -457,7 +479,6 @@ class Template {
|
|
457
479
|
continue;
|
458
480
|
}
|
459
481
|
// begin condition / loop block
|
460
|
-
this.blockStack.push({ blockStart, collection, data, iteration, iterations });
|
461
482
|
if (tagIndex > this.start) {
|
462
483
|
this.target += this.trimEndLine(this.source.substring(this.start, tagIndex));
|
463
484
|
this.start = tagIndex;
|
@@ -468,6 +489,7 @@ class Template {
|
|
468
489
|
this.target = '';
|
469
490
|
this.inLiteral = false;
|
470
491
|
const condition = await this.parseExpression(data, '}', '-->');
|
492
|
+
this.blockStack.push({ blockStart, collection, condition, data, iteration, iterations });
|
471
493
|
let blockData = condition ? (this.target ? data : undefined) : this.target;
|
472
494
|
blockStart = this.index;
|
473
495
|
iteration = 0;
|
package/esm/template.d.ts
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
import { SortedArray } from '@itrocks/sorted-array';
|
2
|
-
type
|
2
|
+
type BlockStackEntry = {
|
3
3
|
blockStart: number;
|
4
4
|
collection: any[];
|
5
|
+
condition?: boolean;
|
5
6
|
data: any;
|
6
7
|
iteration: number;
|
7
8
|
iterations: number;
|
8
|
-
}
|
9
|
+
};
|
9
10
|
export type VariableParser = [parser: string, (variable: string, data: any) => any];
|
10
11
|
export declare const frontScripts: SortedArray<string>;
|
11
12
|
export { Template };
|
@@ -13,7 +14,7 @@ export default class Template {
|
|
13
14
|
data?: any;
|
14
15
|
containerData?: any;
|
15
16
|
blockBack: number;
|
16
|
-
blockStack:
|
17
|
+
blockStack: BlockStackEntry[];
|
17
18
|
doExpression: boolean;
|
18
19
|
index: number;
|
19
20
|
length: number;
|
package/esm/template.js
CHANGED
@@ -11,7 +11,7 @@ export default class Template {
|
|
11
11
|
containerData;
|
12
12
|
// block stack
|
13
13
|
blockBack = 0;
|
14
|
-
blockStack;
|
14
|
+
blockStack = [];
|
15
15
|
// parser
|
16
16
|
doExpression = true;
|
17
17
|
index = 0;
|
@@ -60,7 +60,6 @@ export default class Template {
|
|
60
60
|
this.addLinks.distinct = true;
|
61
61
|
this.doneLinks.distinct = true;
|
62
62
|
this.headLinks.distinct = true;
|
63
|
-
this.blockStack = [];
|
64
63
|
if (containerData) {
|
65
64
|
this.blockStack.push({ blockStart: 0, collection: [], data: containerData, iteration: 0, iterations: 1 });
|
66
65
|
}
|
@@ -172,7 +171,11 @@ export default class Template {
|
|
172
171
|
}
|
173
172
|
this.headLinks.push(...template.headLinks);
|
174
173
|
this.headTitle = template.headTitle;
|
175
|
-
|
174
|
+
const beginPosition = parsed.indexOf('<!--BEGIN-->');
|
175
|
+
const endPosition = parsed.indexOf('<!--END-->');
|
176
|
+
return (beginPosition > -1)
|
177
|
+
? parsed.slice(beginPosition + 12, (endPosition > -1) ? endPosition : parsed.length)
|
178
|
+
: parsed;
|
176
179
|
}
|
177
180
|
isContextClean() {
|
178
181
|
const clean = this.getCleanContext();
|
@@ -296,7 +299,7 @@ export default class Template {
|
|
296
299
|
if (conditional && !parsed) {
|
297
300
|
if ((typeof this.target)[0] === 's') {
|
298
301
|
this.target = this.target.substring(0, this.target.lastIndexOf(' '));
|
299
|
-
while ((this.index < this.length) && !'
|
302
|
+
while ((this.index < this.length) && !' >\n\r\t\f'.includes(this.source[this.index])) {
|
300
303
|
this.index++;
|
301
304
|
this.start++;
|
302
305
|
}
|
@@ -339,7 +342,23 @@ export default class Template {
|
|
339
342
|
if (expression === '') {
|
340
343
|
return undefined;
|
341
344
|
}
|
342
|
-
if ((expression[0] === '.') && (expression
|
345
|
+
if (((expression[0] === '.') && ((expression[1] === '/') || ((expression[1] === '.') && (expression[2] === '/'))))
|
346
|
+
|| (expression[0] === '/')) {
|
347
|
+
let expressionEnd = expression.length - 1;
|
348
|
+
if (expression[expressionEnd] === '-') {
|
349
|
+
let blockBack = 1;
|
350
|
+
expressionEnd--;
|
351
|
+
while (expression[expressionEnd] === '-') {
|
352
|
+
blockBack++;
|
353
|
+
expressionEnd--;
|
354
|
+
}
|
355
|
+
const blockStack = this.blockStack;
|
356
|
+
return this.include(expression.slice(0, expressionEnd), blockStack[blockStack.length - blockBack].data);
|
357
|
+
}
|
358
|
+
if (expression[expressionEnd] === ')') {
|
359
|
+
const openPosition = expression.lastIndexOf('(');
|
360
|
+
return this.include(expression.slice(0, openPosition), await this.parsePath(expression.slice(openPosition + 1, expression.length - 1), data));
|
361
|
+
}
|
343
362
|
return this.include(expression, data);
|
344
363
|
}
|
345
364
|
this.blockBack = 0;
|
@@ -350,7 +369,7 @@ export default class Template {
|
|
350
369
|
}
|
351
370
|
async parseVariable(variable, data) {
|
352
371
|
if (variable === '') {
|
353
|
-
return (typeof data === '
|
372
|
+
return (((typeof data)[0] === 'f') && ((data + '')[0] !== 'c'))
|
354
373
|
? data.call()
|
355
374
|
: data;
|
356
375
|
}
|
@@ -366,8 +385,12 @@ export default class Template {
|
|
366
385
|
return variable.substring(1, variable.length - 1);
|
367
386
|
}
|
368
387
|
if (firstChar === '-') {
|
369
|
-
|
370
|
-
|
388
|
+
let dataBack;
|
389
|
+
do {
|
390
|
+
this.blockBack++;
|
391
|
+
dataBack = this.blockStack[this.blockStack.length - this.blockBack];
|
392
|
+
} while (dataBack.condition);
|
393
|
+
return dataBack.data;
|
371
394
|
}
|
372
395
|
for (const [prefix, callback] of this.parsers) {
|
373
396
|
if (firstChar === prefix) {
|
@@ -378,7 +401,7 @@ export default class Template {
|
|
378
401
|
data = new Str(data);
|
379
402
|
}
|
380
403
|
let value = data[variable];
|
381
|
-
return ((typeof value === '
|
404
|
+
return (((typeof value)[0] === 'f') && ((value + '')[0] !== 'c'))
|
382
405
|
? value.call(data)
|
383
406
|
: value;
|
384
407
|
}
|
@@ -430,8 +453,7 @@ export default class Template {
|
|
430
453
|
continue;
|
431
454
|
}
|
432
455
|
// end condition / loop block
|
433
|
-
if ('
|
434
|
-
&& ['end-->', 'END-->'].includes(this.source.substring(this.index, this.index + 6))) {
|
456
|
+
if ((firstChar === 'e') && (this.source.substring(this.index, this.index + 6) === 'end-->')) {
|
435
457
|
this.target += this.trimEndLine(this.source.substring(this.start, tagIndex));
|
436
458
|
iteration++;
|
437
459
|
if (iteration < iterations) {
|
@@ -452,7 +474,6 @@ export default class Template {
|
|
452
474
|
continue;
|
453
475
|
}
|
454
476
|
// begin condition / loop block
|
455
|
-
this.blockStack.push({ blockStart, collection, data, iteration, iterations });
|
456
477
|
if (tagIndex > this.start) {
|
457
478
|
this.target += this.trimEndLine(this.source.substring(this.start, tagIndex));
|
458
479
|
this.start = tagIndex;
|
@@ -463,6 +484,7 @@ export default class Template {
|
|
463
484
|
this.target = '';
|
464
485
|
this.inLiteral = false;
|
465
486
|
const condition = await this.parseExpression(data, '}', '-->');
|
487
|
+
this.blockStack.push({ blockStart, collection, condition, data, iteration, iterations });
|
466
488
|
let blockData = condition ? (this.target ? data : undefined) : this.target;
|
467
489
|
blockStart = this.index;
|
468
490
|
iteration = 0;
|
package/package.json
CHANGED