1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
import Exception from "../exception";
export function SourceLocation(source, locInfo) {
this.source = source;
this.start = {
line: locInfo.first_line,
column: locInfo.first_column
};
this.end = {
line: locInfo.last_line,
column: locInfo.last_column
};
}
export function stripFlags(open, close) {
return {
open: open.charAt(2) === '~',
close: close.charAt(close.length-3) === '~'
};
}
export function stripComment(comment) {
return comment.replace(/^\{\{~?\!-?-?/, '')
.replace(/-?-?~?\}\}$/, '');
}
export function preparePath(data, parts, locInfo) {
/*jshint -W040 */
locInfo = this.locInfo(locInfo);
var original = data ? '@' : '',
dig = [],
depth = 0,
depthString = '';
for(var i=0,l=parts.length; i<l; i++) {
var part = parts[i].part;
original += (parts[i].separator || '') + part;
if (part === '..' || part === '.' || part === 'this') {
if (dig.length > 0) {
throw new Exception('Invalid path: ' + original, {loc: locInfo});
} else if (part === '..') {
depth++;
depthString += '../';
}
} else {
dig.push(part);
}
}
return new this.PathExpression(data, depth, dig, original, locInfo);
}
export function prepareMustache(sexpr, open, strip, locInfo) {
/*jshint -W040 */
// Must use charAt to support IE pre-10
var escapeFlag = open.charAt(3) || open.charAt(2),
escaped = escapeFlag !== '{' && escapeFlag !== '&';
return new this.MustacheStatement(sexpr, escaped, strip, this.locInfo(locInfo));
}
export function prepareRawBlock(openRawBlock, content, close, locInfo) {
/*jshint -W040 */
if (openRawBlock.sexpr.path.original !== close) {
var errorNode = {loc: openRawBlock.sexpr.loc};
throw new Exception(openRawBlock.sexpr.path.original + " doesn't match " + close, errorNode);
}
locInfo = this.locInfo(locInfo);
var program = new this.Program([content], null, {}, locInfo);
return new this.BlockStatement(
openRawBlock.sexpr, program, undefined,
{}, {}, {},
locInfo);
}
export function prepareBlock(openBlock, program, inverseAndProgram, close, inverted, locInfo) {
/*jshint -W040 */
// When we are chaining inverse calls, we will not have a close path
if (close && close.path && openBlock.sexpr.path.original !== close.path.original) {
var errorNode = {loc: openBlock.sexpr.loc};
throw new Exception(openBlock.sexpr.path.original + ' doesn\'t match ' + close.path.original, errorNode);
}
program.blockParams = openBlock.blockParams;
var inverse,
inverseStrip;
if (inverseAndProgram) {
if (inverseAndProgram.chain) {
inverseAndProgram.program.body[0].closeStrip = close.strip || close.openStrip;
}
inverseStrip = inverseAndProgram.strip;
inverse = inverseAndProgram.program;
}
if (inverted) {
inverted = inverse;
inverse = program;
program = inverted;
}
return new this.BlockStatement(
openBlock.sexpr, program, inverse,
openBlock.strip, inverseStrip, close && (close.strip || close.openStrip),
this.locInfo(locInfo));
}
|