handlebars-jaylinski 4.7.8
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/LICENSE +19 -0
- package/README.markdown +169 -0
- package/bin/.eslintrc.js +6 -0
- package/bin/handlebars +176 -0
- package/dist/amd/handlebars/base.js +106 -0
- package/dist/amd/handlebars/compiler/ast.js +31 -0
- package/dist/amd/handlebars/compiler/base.js +45 -0
- package/dist/amd/handlebars/compiler/code-gen.js +165 -0
- package/dist/amd/handlebars/compiler/compiler.js +562 -0
- package/dist/amd/handlebars/compiler/helpers.js +228 -0
- package/dist/amd/handlebars/compiler/javascript-compiler.js +1150 -0
- package/dist/amd/handlebars/compiler/parser.js +737 -0
- package/dist/amd/handlebars/compiler/printer.js +186 -0
- package/dist/amd/handlebars/compiler/visitor.js +138 -0
- package/dist/amd/handlebars/compiler/whitespace-control.js +219 -0
- package/dist/amd/handlebars/decorators/inline.js +25 -0
- package/dist/amd/handlebars/decorators.js +16 -0
- package/dist/amd/handlebars/exception.js +64 -0
- package/dist/amd/handlebars/helpers/block-helper-missing.js +35 -0
- package/dist/amd/handlebars/helpers/each.js +99 -0
- package/dist/amd/handlebars/helpers/helper-missing.js +22 -0
- package/dist/amd/handlebars/helpers/if.js +41 -0
- package/dist/amd/handlebars/helpers/log.js +24 -0
- package/dist/amd/handlebars/helpers/lookup.js +14 -0
- package/dist/amd/handlebars/helpers/with.js +38 -0
- package/dist/amd/handlebars/helpers.js +44 -0
- package/dist/amd/handlebars/internal/create-new-lookup-object.js +22 -0
- package/dist/amd/handlebars/internal/proto-access.js +71 -0
- package/dist/amd/handlebars/internal/wrapHelper.js +21 -0
- package/dist/amd/handlebars/logger.js +44 -0
- package/dist/amd/handlebars/no-conflict.js +28 -0
- package/dist/amd/handlebars/runtime.js +356 -0
- package/dist/amd/handlebars/safe-string.js +15 -0
- package/dist/amd/handlebars/utils.js +126 -0
- package/dist/amd/handlebars.js +52 -0
- package/dist/amd/handlebars.runtime.js +44 -0
- package/dist/amd/precompiler.js +314 -0
- package/dist/cjs/handlebars/base.js +116 -0
- package/dist/cjs/handlebars/compiler/ast.js +31 -0
- package/dist/cjs/handlebars/compiler/base.js +57 -0
- package/dist/cjs/handlebars/compiler/code-gen.js +168 -0
- package/dist/cjs/handlebars/compiler/compiler.js +566 -0
- package/dist/cjs/handlebars/compiler/helpers.js +228 -0
- package/dist/cjs/handlebars/compiler/javascript-compiler.js +1158 -0
- package/dist/cjs/handlebars/compiler/parser.js +737 -0
- package/dist/cjs/handlebars/compiler/printer.js +186 -0
- package/dist/cjs/handlebars/compiler/visitor.js +140 -0
- package/dist/cjs/handlebars/compiler/whitespace-control.js +221 -0
- package/dist/cjs/handlebars/decorators/inline.js +29 -0
- package/dist/cjs/handlebars/decorators.js +16 -0
- package/dist/cjs/handlebars/exception.js +64 -0
- package/dist/cjs/handlebars/helpers/block-helper-missing.js +39 -0
- package/dist/cjs/handlebars/helpers/each.js +104 -0
- package/dist/cjs/handlebars/helpers/helper-missing.js +25 -0
- package/dist/cjs/handlebars/helpers/if.js +46 -0
- package/dist/cjs/handlebars/helpers/log.js +26 -0
- package/dist/cjs/handlebars/helpers/lookup.js +16 -0
- package/dist/cjs/handlebars/helpers/with.js +43 -0
- package/dist/cjs/handlebars/helpers.js +56 -0
- package/dist/cjs/handlebars/internal/create-new-lookup-object.js +22 -0
- package/dist/cjs/handlebars/internal/proto-access.js +73 -0
- package/dist/cjs/handlebars/internal/wrapHelper.js +19 -0
- package/dist/cjs/handlebars/logger.js +47 -0
- package/dist/cjs/handlebars/no-conflict.js +30 -0
- package/dist/cjs/handlebars/runtime.js +372 -0
- package/dist/cjs/handlebars/safe-string.js +15 -0
- package/dist/cjs/handlebars/utils.js +124 -0
- package/dist/cjs/handlebars.js +66 -0
- package/dist/cjs/handlebars.runtime.js +66 -0
- package/dist/cjs/precompiler.js +328 -0
- package/dist/handlebars.amd.js +4639 -0
- package/dist/handlebars.amd.min.js +29 -0
- package/dist/handlebars.js +5972 -0
- package/dist/handlebars.min.js +29 -0
- package/dist/handlebars.runtime.amd.js +1302 -0
- package/dist/handlebars.runtime.amd.min.js +27 -0
- package/dist/handlebars.runtime.js +2563 -0
- package/dist/handlebars.runtime.min.js +27 -0
- package/lib/.eslintrc.js +8 -0
- package/lib/handlebars/base.js +94 -0
- package/lib/handlebars/compiler/ast.js +32 -0
- package/lib/handlebars/compiler/base.js +34 -0
- package/lib/handlebars/compiler/code-gen.js +171 -0
- package/lib/handlebars/compiler/compiler.js +594 -0
- package/lib/handlebars/compiler/helpers.js +219 -0
- package/lib/handlebars/compiler/javascript-compiler.js +1293 -0
- package/lib/handlebars/compiler/parser.js +622 -0
- package/lib/handlebars/compiler/printer.js +178 -0
- package/lib/handlebars/compiler/visitor.js +136 -0
- package/lib/handlebars/compiler/whitespace-control.js +234 -0
- package/lib/handlebars/decorators/inline.js +22 -0
- package/lib/handlebars/decorators.js +5 -0
- package/lib/handlebars/exception.js +68 -0
- package/lib/handlebars/helpers/block-helper-missing.js +35 -0
- package/lib/handlebars/helpers/each.js +101 -0
- package/lib/handlebars/helpers/helper-missing.js +15 -0
- package/lib/handlebars/helpers/if.js +33 -0
- package/lib/handlebars/helpers/log.js +19 -0
- package/lib/handlebars/helpers/lookup.js +9 -0
- package/lib/handlebars/helpers/with.js +39 -0
- package/lib/handlebars/helpers.js +26 -0
- package/lib/handlebars/internal/create-new-lookup-object.js +11 -0
- package/lib/handlebars/internal/proto-access.js +70 -0
- package/lib/handlebars/internal/wrapHelper.js +13 -0
- package/lib/handlebars/logger.js +39 -0
- package/lib/handlebars/no-conflict.js +23 -0
- package/lib/handlebars/runtime.js +450 -0
- package/lib/handlebars/safe-string.js +10 -0
- package/lib/handlebars/utils.js +116 -0
- package/lib/handlebars.js +46 -0
- package/lib/handlebars.runtime.js +37 -0
- package/lib/index.js +26 -0
- package/lib/precompiler.js +341 -0
- package/package.json +135 -0
- package/release-notes.md +1101 -0
- package/runtime.d.ts +5 -0
- package/runtime.js +3 -0
- package/types/index.d.ts +422 -0
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
import * as Utils from './utils';
|
|
2
|
+
import Exception from './exception';
|
|
3
|
+
import {
|
|
4
|
+
COMPILER_REVISION,
|
|
5
|
+
createFrame,
|
|
6
|
+
LAST_COMPATIBLE_COMPILER_REVISION,
|
|
7
|
+
REVISION_CHANGES
|
|
8
|
+
} from './base';
|
|
9
|
+
import { moveHelperToHooks } from './helpers';
|
|
10
|
+
import { wrapHelper } from './internal/wrapHelper';
|
|
11
|
+
import {
|
|
12
|
+
createProtoAccessControl,
|
|
13
|
+
resultIsAllowed
|
|
14
|
+
} from './internal/proto-access';
|
|
15
|
+
|
|
16
|
+
export function checkRevision(compilerInfo) {
|
|
17
|
+
const compilerRevision = (compilerInfo && compilerInfo[0]) || 1,
|
|
18
|
+
currentRevision = COMPILER_REVISION;
|
|
19
|
+
|
|
20
|
+
if (
|
|
21
|
+
compilerRevision >= LAST_COMPATIBLE_COMPILER_REVISION &&
|
|
22
|
+
compilerRevision <= COMPILER_REVISION
|
|
23
|
+
) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (compilerRevision < LAST_COMPATIBLE_COMPILER_REVISION) {
|
|
28
|
+
const runtimeVersions = REVISION_CHANGES[currentRevision],
|
|
29
|
+
compilerVersions = REVISION_CHANGES[compilerRevision];
|
|
30
|
+
throw new Exception(
|
|
31
|
+
'Template was precompiled with an older version of Handlebars than the current runtime. ' +
|
|
32
|
+
'Please update your precompiler to a newer version (' +
|
|
33
|
+
runtimeVersions +
|
|
34
|
+
') or downgrade your runtime to an older version (' +
|
|
35
|
+
compilerVersions +
|
|
36
|
+
').'
|
|
37
|
+
);
|
|
38
|
+
} else {
|
|
39
|
+
// Use the embedded version info since the runtime doesn't know about this revision yet
|
|
40
|
+
throw new Exception(
|
|
41
|
+
'Template was precompiled with a newer version of Handlebars than the current runtime. ' +
|
|
42
|
+
'Please update your runtime to a newer version (' +
|
|
43
|
+
compilerInfo[1] +
|
|
44
|
+
').'
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function template(templateSpec, env) {
|
|
50
|
+
/* istanbul ignore next */
|
|
51
|
+
if (!env) {
|
|
52
|
+
throw new Exception('No environment passed to template');
|
|
53
|
+
}
|
|
54
|
+
if (!templateSpec || !templateSpec.main) {
|
|
55
|
+
throw new Exception('Unknown template object: ' + typeof templateSpec);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
templateSpec.main.decorator = templateSpec.main_d;
|
|
59
|
+
|
|
60
|
+
// Note: Using env.VM references rather than local var references throughout this section to allow
|
|
61
|
+
// for external users to override these as pseudo-supported APIs.
|
|
62
|
+
env.VM.checkRevision(templateSpec.compiler);
|
|
63
|
+
|
|
64
|
+
// backwards compatibility for precompiled templates with compiler-version 7 (<4.3.0)
|
|
65
|
+
const templateWasPrecompiledWithCompilerV7 =
|
|
66
|
+
templateSpec.compiler && templateSpec.compiler[0] === 7;
|
|
67
|
+
|
|
68
|
+
function invokePartialWrapper(partial, context, options) {
|
|
69
|
+
if (options.hash) {
|
|
70
|
+
context = Utils.extend({}, context, options.hash);
|
|
71
|
+
if (options.ids) {
|
|
72
|
+
options.ids[0] = true;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
partial = env.VM.resolvePartial.call(this, partial, context, options);
|
|
76
|
+
|
|
77
|
+
let extendedOptions = Utils.extend({}, options, {
|
|
78
|
+
hooks: this.hooks,
|
|
79
|
+
protoAccessControl: this.protoAccessControl
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
let result = env.VM.invokePartial.call(
|
|
83
|
+
this,
|
|
84
|
+
partial,
|
|
85
|
+
context,
|
|
86
|
+
extendedOptions
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
if (result == null && env.compile) {
|
|
90
|
+
options.partials[options.name] = env.compile(
|
|
91
|
+
partial,
|
|
92
|
+
templateSpec.compilerOptions,
|
|
93
|
+
env
|
|
94
|
+
);
|
|
95
|
+
result = options.partials[options.name](context, extendedOptions);
|
|
96
|
+
}
|
|
97
|
+
if (result != null) {
|
|
98
|
+
if (options.indent) {
|
|
99
|
+
let lines = result.split('\n');
|
|
100
|
+
for (let i = 0, l = lines.length; i < l; i++) {
|
|
101
|
+
if (!lines[i] && i + 1 === l) {
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
lines[i] = options.indent + lines[i];
|
|
106
|
+
}
|
|
107
|
+
result = lines.join('\n');
|
|
108
|
+
}
|
|
109
|
+
return result;
|
|
110
|
+
} else {
|
|
111
|
+
throw new Exception(
|
|
112
|
+
'The partial ' +
|
|
113
|
+
options.name +
|
|
114
|
+
' could not be compiled when running in runtime-only mode'
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Just add water
|
|
120
|
+
let container = {
|
|
121
|
+
strict: function(obj, name, loc) {
|
|
122
|
+
if (!obj || !(name in obj)) {
|
|
123
|
+
throw new Exception('"' + name + '" not defined in ' + obj, {
|
|
124
|
+
loc: loc
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
return container.lookupProperty(obj, name);
|
|
128
|
+
},
|
|
129
|
+
lookupProperty: function(parent, propertyName) {
|
|
130
|
+
let result = parent[propertyName];
|
|
131
|
+
if (result == null) {
|
|
132
|
+
return result;
|
|
133
|
+
}
|
|
134
|
+
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (resultIsAllowed(result, container.protoAccessControl, propertyName)) {
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
141
|
+
return undefined;
|
|
142
|
+
},
|
|
143
|
+
lookup: function(depths, name) {
|
|
144
|
+
const len = depths.length;
|
|
145
|
+
for (let i = 0; i < len; i++) {
|
|
146
|
+
let result = depths[i] && container.lookupProperty(depths[i], name);
|
|
147
|
+
if (result != null) {
|
|
148
|
+
return depths[i][name];
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
lambda: function(current, context) {
|
|
153
|
+
return typeof current === 'function' ? current.call(context) : current;
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
escapeExpression: Utils.escapeExpression,
|
|
157
|
+
invokePartial: invokePartialWrapper,
|
|
158
|
+
|
|
159
|
+
fn: function(i) {
|
|
160
|
+
let ret = templateSpec[i];
|
|
161
|
+
ret.decorator = templateSpec[i + '_d'];
|
|
162
|
+
return ret;
|
|
163
|
+
},
|
|
164
|
+
|
|
165
|
+
programs: [],
|
|
166
|
+
program: function(i, data, declaredBlockParams, blockParams, depths) {
|
|
167
|
+
let programWrapper = this.programs[i],
|
|
168
|
+
fn = this.fn(i);
|
|
169
|
+
if (data || depths || blockParams || declaredBlockParams) {
|
|
170
|
+
programWrapper = wrapProgram(
|
|
171
|
+
this,
|
|
172
|
+
i,
|
|
173
|
+
fn,
|
|
174
|
+
data,
|
|
175
|
+
declaredBlockParams,
|
|
176
|
+
blockParams,
|
|
177
|
+
depths
|
|
178
|
+
);
|
|
179
|
+
} else if (!programWrapper) {
|
|
180
|
+
programWrapper = this.programs[i] = wrapProgram(this, i, fn);
|
|
181
|
+
}
|
|
182
|
+
return programWrapper;
|
|
183
|
+
},
|
|
184
|
+
|
|
185
|
+
data: function(value, depth) {
|
|
186
|
+
while (value && depth--) {
|
|
187
|
+
value = value._parent;
|
|
188
|
+
}
|
|
189
|
+
return value;
|
|
190
|
+
},
|
|
191
|
+
mergeIfNeeded: function(param, common) {
|
|
192
|
+
let obj = param || common;
|
|
193
|
+
|
|
194
|
+
if (param && common && param !== common) {
|
|
195
|
+
obj = Utils.extend({}, common, param);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return obj;
|
|
199
|
+
},
|
|
200
|
+
// An empty object to use as replacement for null-contexts
|
|
201
|
+
nullContext: Object.seal({}),
|
|
202
|
+
|
|
203
|
+
noop: env.VM.noop,
|
|
204
|
+
compilerInfo: templateSpec.compiler
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
function ret(context, options = {}) {
|
|
208
|
+
let data = options.data;
|
|
209
|
+
|
|
210
|
+
ret._setup(options);
|
|
211
|
+
if (!options.partial && templateSpec.useData) {
|
|
212
|
+
data = initData(context, data);
|
|
213
|
+
}
|
|
214
|
+
let depths,
|
|
215
|
+
blockParams = templateSpec.useBlockParams ? [] : undefined;
|
|
216
|
+
if (templateSpec.useDepths) {
|
|
217
|
+
if (options.depths) {
|
|
218
|
+
depths =
|
|
219
|
+
context != options.depths[0]
|
|
220
|
+
? [context].concat(options.depths)
|
|
221
|
+
: options.depths;
|
|
222
|
+
} else {
|
|
223
|
+
depths = [context];
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function main(context /*, options*/) {
|
|
228
|
+
return (
|
|
229
|
+
'' +
|
|
230
|
+
templateSpec.main(
|
|
231
|
+
container,
|
|
232
|
+
context,
|
|
233
|
+
container.helpers,
|
|
234
|
+
container.partials,
|
|
235
|
+
data,
|
|
236
|
+
blockParams,
|
|
237
|
+
depths
|
|
238
|
+
)
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
main = executeDecorators(
|
|
243
|
+
templateSpec.main,
|
|
244
|
+
main,
|
|
245
|
+
container,
|
|
246
|
+
options.depths || [],
|
|
247
|
+
data,
|
|
248
|
+
blockParams
|
|
249
|
+
);
|
|
250
|
+
return main(context, options);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
ret.isTop = true;
|
|
254
|
+
|
|
255
|
+
ret._setup = function(options) {
|
|
256
|
+
if (!options.partial) {
|
|
257
|
+
let mergedHelpers = Utils.extend({}, env.helpers, options.helpers);
|
|
258
|
+
wrapHelpersToPassLookupProperty(mergedHelpers, container);
|
|
259
|
+
container.helpers = mergedHelpers;
|
|
260
|
+
|
|
261
|
+
if (templateSpec.usePartial) {
|
|
262
|
+
// Use mergeIfNeeded here to prevent compiling global partials multiple times
|
|
263
|
+
container.partials = container.mergeIfNeeded(
|
|
264
|
+
options.partials,
|
|
265
|
+
env.partials
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
if (templateSpec.usePartial || templateSpec.useDecorators) {
|
|
269
|
+
container.decorators = Utils.extend(
|
|
270
|
+
{},
|
|
271
|
+
env.decorators,
|
|
272
|
+
options.decorators
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
container.hooks = {};
|
|
277
|
+
container.protoAccessControl = createProtoAccessControl(options);
|
|
278
|
+
|
|
279
|
+
let keepHelperInHelpers =
|
|
280
|
+
options.allowCallsToHelperMissing ||
|
|
281
|
+
templateWasPrecompiledWithCompilerV7;
|
|
282
|
+
moveHelperToHooks(container, 'helperMissing', keepHelperInHelpers);
|
|
283
|
+
moveHelperToHooks(container, 'blockHelperMissing', keepHelperInHelpers);
|
|
284
|
+
} else {
|
|
285
|
+
container.protoAccessControl = options.protoAccessControl; // internal option
|
|
286
|
+
container.helpers = options.helpers;
|
|
287
|
+
container.partials = options.partials;
|
|
288
|
+
container.decorators = options.decorators;
|
|
289
|
+
container.hooks = options.hooks;
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
ret._child = function(i, data, blockParams, depths) {
|
|
294
|
+
if (templateSpec.useBlockParams && !blockParams) {
|
|
295
|
+
throw new Exception('must pass block params');
|
|
296
|
+
}
|
|
297
|
+
if (templateSpec.useDepths && !depths) {
|
|
298
|
+
throw new Exception('must pass parent depths');
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return wrapProgram(
|
|
302
|
+
container,
|
|
303
|
+
i,
|
|
304
|
+
templateSpec[i],
|
|
305
|
+
data,
|
|
306
|
+
0,
|
|
307
|
+
blockParams,
|
|
308
|
+
depths
|
|
309
|
+
);
|
|
310
|
+
};
|
|
311
|
+
return ret;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export function wrapProgram(
|
|
315
|
+
container,
|
|
316
|
+
i,
|
|
317
|
+
fn,
|
|
318
|
+
data,
|
|
319
|
+
declaredBlockParams,
|
|
320
|
+
blockParams,
|
|
321
|
+
depths
|
|
322
|
+
) {
|
|
323
|
+
function prog(context, options = {}) {
|
|
324
|
+
let currentDepths = depths;
|
|
325
|
+
if (
|
|
326
|
+
depths &&
|
|
327
|
+
context != depths[0] &&
|
|
328
|
+
!(context === container.nullContext && depths[0] === null)
|
|
329
|
+
) {
|
|
330
|
+
currentDepths = [context].concat(depths);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
return fn(
|
|
334
|
+
container,
|
|
335
|
+
context,
|
|
336
|
+
container.helpers,
|
|
337
|
+
container.partials,
|
|
338
|
+
options.data || data,
|
|
339
|
+
blockParams && [options.blockParams].concat(blockParams),
|
|
340
|
+
currentDepths
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
prog = executeDecorators(fn, prog, container, depths, data, blockParams);
|
|
345
|
+
|
|
346
|
+
prog.program = i;
|
|
347
|
+
prog.depth = depths ? depths.length : 0;
|
|
348
|
+
prog.blockParams = declaredBlockParams || 0;
|
|
349
|
+
return prog;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* This is currently part of the official API, therefore implementation details should not be changed.
|
|
354
|
+
*/
|
|
355
|
+
export function resolvePartial(partial, context, options) {
|
|
356
|
+
if (!partial) {
|
|
357
|
+
if (options.name === '@partial-block') {
|
|
358
|
+
partial = options.data['partial-block'];
|
|
359
|
+
} else {
|
|
360
|
+
partial = options.partials[options.name];
|
|
361
|
+
}
|
|
362
|
+
} else if (!partial.call && !options.name) {
|
|
363
|
+
// This is a dynamic partial that returned a string
|
|
364
|
+
options.name = partial;
|
|
365
|
+
partial = options.partials[partial];
|
|
366
|
+
}
|
|
367
|
+
return partial;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
export function invokePartial(partial, context, options) {
|
|
371
|
+
// Use the current closure context to save the partial-block if this partial
|
|
372
|
+
const currentPartialBlock = options.data && options.data['partial-block'];
|
|
373
|
+
options.partial = true;
|
|
374
|
+
if (options.ids) {
|
|
375
|
+
options.data.contextPath = options.ids[0] || options.data.contextPath;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
let partialBlock;
|
|
379
|
+
if (options.fn && options.fn !== noop) {
|
|
380
|
+
options.data = createFrame(options.data);
|
|
381
|
+
// Wrapper function to get access to currentPartialBlock from the closure
|
|
382
|
+
let fn = options.fn;
|
|
383
|
+
partialBlock = options.data['partial-block'] = function partialBlockWrapper(
|
|
384
|
+
context,
|
|
385
|
+
options = {}
|
|
386
|
+
) {
|
|
387
|
+
// Restore the partial-block from the closure for the execution of the block
|
|
388
|
+
// i.e. the part inside the block of the partial call.
|
|
389
|
+
options.data = createFrame(options.data);
|
|
390
|
+
options.data['partial-block'] = currentPartialBlock;
|
|
391
|
+
return fn(context, options);
|
|
392
|
+
};
|
|
393
|
+
if (fn.partials) {
|
|
394
|
+
options.partials = Utils.extend({}, options.partials, fn.partials);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (partial === undefined && partialBlock) {
|
|
399
|
+
partial = partialBlock;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
if (partial === undefined) {
|
|
403
|
+
throw new Exception('The partial ' + options.name + ' could not be found');
|
|
404
|
+
} else if (partial instanceof Function) {
|
|
405
|
+
return partial(context, options);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
export function noop() {
|
|
410
|
+
return '';
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
function initData(context, data) {
|
|
414
|
+
if (!data || !('root' in data)) {
|
|
415
|
+
data = data ? createFrame(data) : {};
|
|
416
|
+
data.root = context;
|
|
417
|
+
}
|
|
418
|
+
return data;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
function executeDecorators(fn, prog, container, depths, data, blockParams) {
|
|
422
|
+
if (fn.decorator) {
|
|
423
|
+
let props = {};
|
|
424
|
+
prog = fn.decorator(
|
|
425
|
+
prog,
|
|
426
|
+
props,
|
|
427
|
+
container,
|
|
428
|
+
depths && depths[0],
|
|
429
|
+
data,
|
|
430
|
+
blockParams,
|
|
431
|
+
depths
|
|
432
|
+
);
|
|
433
|
+
Utils.extend(prog, props);
|
|
434
|
+
}
|
|
435
|
+
return prog;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
function wrapHelpersToPassLookupProperty(mergedHelpers, container) {
|
|
439
|
+
Object.keys(mergedHelpers).forEach(helperName => {
|
|
440
|
+
let helper = mergedHelpers[helperName];
|
|
441
|
+
mergedHelpers[helperName] = passLookupPropertyOption(helper, container);
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
function passLookupPropertyOption(helper, container) {
|
|
446
|
+
const lookupProperty = container.lookupProperty;
|
|
447
|
+
return wrapHelper(helper, options => {
|
|
448
|
+
return Utils.extend({ lookupProperty }, options);
|
|
449
|
+
});
|
|
450
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
const escape = {
|
|
2
|
+
'&': '&',
|
|
3
|
+
'<': '<',
|
|
4
|
+
'>': '>',
|
|
5
|
+
'"': '"',
|
|
6
|
+
"'": ''',
|
|
7
|
+
'`': '`',
|
|
8
|
+
'=': '='
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const badChars = /[&<>"'`=]/g,
|
|
12
|
+
possible = /[&<>"'`=]/;
|
|
13
|
+
|
|
14
|
+
function escapeChar(chr) {
|
|
15
|
+
return escape[chr];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function extend(obj /* , ...source */) {
|
|
19
|
+
for (let i = 1; i < arguments.length; i++) {
|
|
20
|
+
for (let key in arguments[i]) {
|
|
21
|
+
if (Object.prototype.hasOwnProperty.call(arguments[i], key)) {
|
|
22
|
+
obj[key] = arguments[i][key];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return obj;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export let toString = Object.prototype.toString;
|
|
31
|
+
|
|
32
|
+
// Sourced from lodash
|
|
33
|
+
// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
|
|
34
|
+
/* eslint-disable func-style */
|
|
35
|
+
let isFunction = function(value) {
|
|
36
|
+
return typeof value === 'function';
|
|
37
|
+
};
|
|
38
|
+
// fallback for older versions of Chrome and Safari
|
|
39
|
+
/* istanbul ignore next */
|
|
40
|
+
if (isFunction(/x/)) {
|
|
41
|
+
isFunction = function(value) {
|
|
42
|
+
return (
|
|
43
|
+
typeof value === 'function' &&
|
|
44
|
+
toString.call(value) === '[object Function]'
|
|
45
|
+
);
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export { isFunction };
|
|
49
|
+
/* eslint-enable func-style */
|
|
50
|
+
|
|
51
|
+
/* istanbul ignore next */
|
|
52
|
+
export const isArray =
|
|
53
|
+
Array.isArray ||
|
|
54
|
+
function(value) {
|
|
55
|
+
return value && typeof value === 'object'
|
|
56
|
+
? toString.call(value) === '[object Array]'
|
|
57
|
+
: false;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Older IE versions do not directly support indexOf so we must implement our own, sadly.
|
|
61
|
+
export function indexOf(array, value) {
|
|
62
|
+
for (let i = 0, len = array.length; i < len; i++) {
|
|
63
|
+
if (array[i] === value) {
|
|
64
|
+
return i;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return -1;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function escapeExpression(string) {
|
|
71
|
+
if (typeof string !== 'string') {
|
|
72
|
+
// don't escape SafeStrings, since they're already safe
|
|
73
|
+
if (string && string.toHTML) {
|
|
74
|
+
return string.toHTML();
|
|
75
|
+
} else if (string == null) {
|
|
76
|
+
return '';
|
|
77
|
+
} else if (!string) {
|
|
78
|
+
return string + '';
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Force a string conversion as this will be done by the append regardless and
|
|
82
|
+
// the regex test will do this transparently behind the scenes, causing issues if
|
|
83
|
+
// an object's to string has escaped characters in it.
|
|
84
|
+
string = '' + string;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (!possible.test(string)) {
|
|
88
|
+
return string;
|
|
89
|
+
}
|
|
90
|
+
return string.replace(badChars, escapeChar);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function isEmpty(value) {
|
|
94
|
+
if (!value && value !== 0) {
|
|
95
|
+
return true;
|
|
96
|
+
} else if (isArray(value) && value.length === 0) {
|
|
97
|
+
return true;
|
|
98
|
+
} else {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function createFrame(object) {
|
|
104
|
+
let frame = extend({}, object);
|
|
105
|
+
frame._parent = object;
|
|
106
|
+
return frame;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function blockParams(params, ids) {
|
|
110
|
+
params.path = ids;
|
|
111
|
+
return params;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function appendContextPath(contextPath, id) {
|
|
115
|
+
return (contextPath ? contextPath + '.' : '') + id;
|
|
116
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import runtime from './handlebars.runtime';
|
|
2
|
+
|
|
3
|
+
// Compiler imports
|
|
4
|
+
import AST from './handlebars/compiler/ast';
|
|
5
|
+
import {
|
|
6
|
+
parser as Parser,
|
|
7
|
+
parse,
|
|
8
|
+
parseWithoutProcessing
|
|
9
|
+
} from './handlebars/compiler/base';
|
|
10
|
+
import { Compiler, compile, precompile } from './handlebars/compiler/compiler';
|
|
11
|
+
import JavaScriptCompiler from './handlebars/compiler/javascript-compiler';
|
|
12
|
+
import Visitor from './handlebars/compiler/visitor';
|
|
13
|
+
|
|
14
|
+
import noConflict from './handlebars/no-conflict';
|
|
15
|
+
|
|
16
|
+
let _create = runtime.create;
|
|
17
|
+
function create() {
|
|
18
|
+
let hb = _create();
|
|
19
|
+
|
|
20
|
+
hb.compile = function(input, options) {
|
|
21
|
+
return compile(input, options, hb);
|
|
22
|
+
};
|
|
23
|
+
hb.precompile = function(input, options) {
|
|
24
|
+
return precompile(input, options, hb);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
hb.AST = AST;
|
|
28
|
+
hb.Compiler = Compiler;
|
|
29
|
+
hb.JavaScriptCompiler = JavaScriptCompiler;
|
|
30
|
+
hb.Parser = Parser;
|
|
31
|
+
hb.parse = parse;
|
|
32
|
+
hb.parseWithoutProcessing = parseWithoutProcessing;
|
|
33
|
+
|
|
34
|
+
return hb;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let inst = create();
|
|
38
|
+
inst.create = create;
|
|
39
|
+
|
|
40
|
+
noConflict(inst);
|
|
41
|
+
|
|
42
|
+
inst.Visitor = Visitor;
|
|
43
|
+
|
|
44
|
+
inst['default'] = inst;
|
|
45
|
+
|
|
46
|
+
export default inst;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as base from './handlebars/base';
|
|
2
|
+
|
|
3
|
+
// Each of these augment the Handlebars object. No need to setup here.
|
|
4
|
+
// (This is done to easily share code between commonjs and browse envs)
|
|
5
|
+
import SafeString from './handlebars/safe-string';
|
|
6
|
+
import Exception from './handlebars/exception';
|
|
7
|
+
import * as Utils from './handlebars/utils';
|
|
8
|
+
import * as runtime from './handlebars/runtime';
|
|
9
|
+
|
|
10
|
+
import noConflict from './handlebars/no-conflict';
|
|
11
|
+
|
|
12
|
+
// For compatibility and usage outside of module systems, make the Handlebars object a namespace
|
|
13
|
+
function create() {
|
|
14
|
+
let hb = new base.HandlebarsEnvironment();
|
|
15
|
+
|
|
16
|
+
Utils.extend(hb, base);
|
|
17
|
+
hb.SafeString = SafeString;
|
|
18
|
+
hb.Exception = Exception;
|
|
19
|
+
hb.Utils = Utils;
|
|
20
|
+
hb.escapeExpression = Utils.escapeExpression;
|
|
21
|
+
|
|
22
|
+
hb.VM = runtime;
|
|
23
|
+
hb.template = function(spec) {
|
|
24
|
+
return runtime.template(spec, hb);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
return hb;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
let inst = create();
|
|
31
|
+
inst.create = create;
|
|
32
|
+
|
|
33
|
+
noConflict(inst);
|
|
34
|
+
|
|
35
|
+
inst['default'] = inst;
|
|
36
|
+
|
|
37
|
+
export default inst;
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// USAGE:
|
|
2
|
+
// var handlebars = require('handlebars');
|
|
3
|
+
/* eslint-env node */
|
|
4
|
+
/* eslint-disable no-var */
|
|
5
|
+
|
|
6
|
+
// var local = handlebars.create();
|
|
7
|
+
|
|
8
|
+
var handlebars = require('../dist/cjs/handlebars')['default'];
|
|
9
|
+
|
|
10
|
+
var printer = require('../dist/cjs/handlebars/compiler/printer');
|
|
11
|
+
handlebars.PrintVisitor = printer.PrintVisitor;
|
|
12
|
+
handlebars.print = printer.print;
|
|
13
|
+
|
|
14
|
+
module.exports = handlebars;
|
|
15
|
+
|
|
16
|
+
// Publish a Node.js require() handler for .handlebars and .hbs files
|
|
17
|
+
function extension(module, filename) {
|
|
18
|
+
var fs = require('fs');
|
|
19
|
+
var templateString = fs.readFileSync(filename, 'utf8');
|
|
20
|
+
module.exports = handlebars.compile(templateString);
|
|
21
|
+
}
|
|
22
|
+
/* istanbul ignore else */
|
|
23
|
+
if (typeof require !== 'undefined' && require.extensions) {
|
|
24
|
+
require.extensions['.handlebars'] = extension;
|
|
25
|
+
require.extensions['.hbs'] = extension;
|
|
26
|
+
}
|