Skip to content

Commit eafbe77

Browse files
committed
Template7 Update
1 parent 58756f2 commit eafbe77

File tree

1 file changed

+44
-172
lines changed

1 file changed

+44
-172
lines changed

src/js/template7.js

Lines changed: 44 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ window.Template7 = (function () {
4343
var helperName = helperSlices[0];
4444
var helperContext = helperSlices[1];
4545
var helperHash = {};
46-
47-
if (helperSlices.length > 2) {
46+
47+
if (helperSlices.length > 1) {
4848
var hashRes;
4949
var reg = new RegExp(/\b(\w+)=["']([^"']+)(?=["'])/g);
5050
while ((hashRes = reg.exec(block)) !== null) {
@@ -122,176 +122,92 @@ window.Template7 = (function () {
122122
t.template = template;
123123
t.context = data;
124124

125-
function getContext(contextName, context, privateData) {
126-
if (contextName === 'this' || typeof contextName === 'undefined') {
127-
return context;
128-
}
129-
130-
if (contextName.indexOf('@') >= 0) {
131-
//private data
132-
var privateVarName = contextName.replace(/[@ ]/g, '');
133-
if (privateData && typeof privateData[privateVarName] !== 'undefined') return privateData[privateVarName];
134-
}
125+
function getCompileFn(block, depth) {
126+
if (block.content) return compile(block.content, depth);
127+
else return function () {return ''; };
128+
}
129+
function getCompileInverse(block, depth) {
130+
if (block.inverseContent) return compile(block.inverseContent, depth);
131+
else return function () {return ''; };
132+
}
133+
function getCompileVar(name, ctx) {
134+
var parents, variable, context;
135135

136-
if (contextName.indexOf('.') > 0 && contextName.indexOf('../') < 0) {
137-
var dataPath = contextName.split('.');
138-
var _context = context;
139-
for (var j = 0; j < dataPath.length; j++) {
140-
if (dataPath[j] === 'this') {
141-
_context = context;
142-
}
143-
else if (typeof _context !== 'undefined' && isObject(context) && dataPath[j] in _context) {
144-
_context = _context[dataPath[j]];
145-
}
146-
else {
147-
_context = undefined;
148-
}
149-
}
150-
context = _context;
151-
}
152-
else if (contextName.indexOf('../') >= 0) {
136+
if (name.indexOf('.') > 0) {
137+
if (name.indexOf('this') === 0) variable = name.replace('this', ctx);
138+
else variable = ctx + '.' + name;
153139
}
154-
else if (context[contextName]) {
155-
context = context[contextName];
140+
else if (name.indexOf('../') === 0) {
141+
var levelUp = name.split('../').length - 1;
142+
var newName = name.split('../')[name.split('../').length - 1];
143+
var newDepth = ctx.split('_')[1] - levelUp;
144+
variable = 'ctx_' + (newDepth >= 1 ? newDepth : 1) + '.' + newName;
156145
}
157146
else {
158-
context = undefined;
159-
}
160-
return context;
161-
}
162-
function createOptions(block, privateData) {
163-
return {
164-
fn: function (newContext, privateData) {
165-
return render(block.content, newContext, privateData);
166-
},
167-
inverse: function (newContext, privateData) {
168-
return block.inverseContent ? render(block.inverseContent, newContext, privateData) : '';
169-
},
170-
hash: block.hash || {},
171-
helpers: t.helpers,
172-
data: privateData
173-
};
174-
}
175-
function render(template, data, privateData) {
176-
template = template || t.template;
177-
if (typeof template !== 'string') {
178-
throw new Error('Template7: Template must be a string');
179-
}
180-
var scope = data || t.context;
181-
var blocks = stringToBlocks(template);
182-
var resultString = '';
183-
var i, j, context;
184-
for (i = 0; i < blocks.length; i++) {
185-
var block = blocks[i];
186-
// Plain block
187-
if (block.type === 'plain') {
188-
resultString += block.content;
189-
continue;
190-
}
191-
// Variable block
192-
if (block.type === 'variable') {
193-
context = getContext(block.contextName, scope, privateData);
194-
if (typeof context !== 'undefined') {
195-
resultString += context.toString();
196-
}
197-
}
198-
// Helpers block
199-
if (block.type === 'helper') {
200-
context = getContext(block.contextName, scope, privateData);
201-
// Create options
202-
var options = createOptions(block, privateData);
203-
var helperResult;
204-
var helperName = block.helperName;
205-
if (block.helperName in t.helpers) {
206-
helperResult = t.helpers[helperName].call(scope, context, options);
207-
}
208-
else {
209-
if (!block.contextName && (helperName === 'this' || (isObject(context) && helperName in context))) {
210-
var _context = helperName === 'this' ? context : context[helperName];
211-
if (isArray(_context)) helperResult = t.helpers.each.call(scope, context[helperName], options);
212-
else helperResult = render(block.content, context[helperName]);
213-
}
214-
else {
215-
throw new Error('Template7: Missing helper: "' + helperName + '"');
216-
}
217-
}
218-
if (typeof helperResult !== 'undefined') {
219-
resultString += helperResult.toString();
220-
}
221-
}
147+
variable = name === 'this' ? ctx : ctx + '.' + name;
222148
}
223-
return resultString;
224-
}
225-
226-
var depth = 0;
227-
function getCompileFn(block) {
228-
if (block.content) return compile(block.content);
229-
else return function () {return ''; };
230-
}
231-
function getCompileInverse(block) {
232-
if (block.inverseContent) return compile(block.inverseContent);
233-
else return function () {return ''; };
234-
}
235-
function getCompileVar(name) {
236-
var variable = name === 'this' ? 'ctx' : 'ctx.' + name;
237149
if (name && name.indexOf('@') >= 0) {
238150
variable = '(data && data.' + name.replace('@', '') + ')';
239151
}
152+
240153
return variable;
241154
}
242-
function compile(template) {
155+
function compile(template, depth) {
156+
depth = depth || 1;
243157
template = template || t.template;
244158
if (typeof template !== 'string') {
245159
throw new Error('Template7: Template must be a string');
246160
}
247161
var blocks = stringToBlocks(template);
162+
248163
if (blocks.length === 0) {
249164
return function () { return ''; };
250165
}
251-
var resultString = '(function (ctx, data) {\n';
252-
if (depth === 0) {
253-
resultString += 'function c(val) {if (typeof val !== "undefined") return val; else return ""}\n';
166+
var ctx = 'ctx_' + depth;
167+
var resultString = '(function (' + ctx + ', data) {\n';
168+
if (depth === 1) {
254169
resultString += 'function isArray(arr){return Object.prototype.toString.apply(arr) === \'[object Array]\';}\n';
170+
resultString += 'function isFunction(func){return (typeof func === \'function\');}\n';
171+
resultString += 'function c(val, ctx) {if (typeof val !== "undefined") {if (isFunction(val)) {return val.call(ctx);} else return val;} else return "";}\n';
255172
}
256-
depth ++;
257-
resultString += 'var ret = \'\';\n';
173+
resultString += 'var r = \'\';\n';
258174
var i, j, context;
259175
for (i = 0; i < blocks.length; i++) {
260176
var block = blocks[i];
261177
// Plain block
262178
if (block.type === 'plain') {
263-
resultString += 'ret +=\'' + (block.content).replace(/\n/g, '\\n').replace(/'/g, '\\' + '\'') + '\';';
179+
resultString += 'r +=\'' + (block.content).replace(/\n/g, '\\n').replace(/'/g, '\\' + '\'') + '\';';
264180
continue;
265181
}
266182
var variable;
267183
// Variable block
268184
if (block.type === 'variable') {
269-
variable = getCompileVar(block.contextName);
270-
resultString += 'ret += c(' + variable + ');';
185+
variable = getCompileVar(block.contextName, ctx);
186+
resultString += 'r += c(' + variable + ', ' + ctx + ');';
271187
}
272188
// Helpers block
273189
if (block.type === 'helper') {
274190
if (block.helperName in t.helpers) {
275-
variable = getCompileVar(block.contextName);
276-
resultString += 'ret += (Template7.helpers.' + block.helperName + ').call(ctx, ' + variable + ', {hash:' + JSON.stringify(block.hash) + ', data: data || {}, fn: ' + getCompileFn(block) + ', inverse: ' + getCompileInverse(block) + '});';
191+
variable = getCompileVar(block.contextName, ctx);
192+
resultString += 'r += (Template7.helpers.' + block.helperName + ').call(' + ctx + ', ' + variable + ', {hash:' + JSON.stringify(block.hash) + ', data: data || {}, fn: ' + getCompileFn(block, depth+1) + ', inverse: ' + getCompileInverse(block, depth+1) + '});';
277193
}
278194
else {
279195
if (block.contextName) {
280196
throw new Error('Template7: Missing helper: "' + block.helperName + '"');
281197
}
282198
else {
283-
variable = getCompileVar(block.helperName);
199+
variable = getCompileVar(block.helperName, ctx);
284200
resultString += 'if (' + variable + ') {';
285201
resultString += 'if (isArray(' + variable + ')) {';
286-
resultString += 'ret += (Template7.helpers.each).call(ctx, ' + variable + ', {hash:' + JSON.stringify(block.hash) + ', data: data || {}, fn: ' + getCompileFn(block) + ', inverse: ' + getCompileInverse(block) + '});';
202+
resultString += 'r += (Template7.helpers.each).call(' + ctx + ', ' + variable + ', {hash:' + JSON.stringify(block.hash) + ', data: data || {}, fn: ' + getCompileFn(block, depth+1) + ', inverse: ' + getCompileInverse(block, depth+1) + '});';
287203
resultString += '}else {';
288-
resultString += 'ret += (Template7.helpers.with).call(ctx, ' + variable + ', {hash:' + JSON.stringify(block.hash) + ', data: data || {}, fn: ' + getCompileFn(block) + ', inverse: ' + getCompileInverse(block) + '});';
204+
resultString += 'r += (Template7.helpers.with).call(' + ctx + ', ' + variable + ', {hash:' + JSON.stringify(block.hash) + ', data: data || {}, fn: ' + getCompileFn(block, depth+1) + ', inverse: ' + getCompileInverse(block, depth+1) + '});';
289205
resultString += '}}';
290206
}
291207
}
292208
}
293209
}
294-
resultString += '\nreturn ret;})';
210+
resultString += '\nreturn r;})';
295211
return eval.call(window, resultString);
296212
}
297213
t.compile = function (template) {
@@ -300,32 +216,10 @@ window.Template7 = (function () {
300216
}
301217
return t.compiled;
302218
};
303-
t.render = function (data) {
304-
t.context = data;
305-
t.prevContext = undefined;
306-
var rendered, cached, id;
307-
if (t.options.cache) {
308-
for (var key in cache) {
309-
if (key.indexOf('template_') >= 0 && cache[key] === t.template) {
310-
id = key.split('template_')[1];
311-
if (cache['data_' + id] === JSON.stringify(data)) cached = cache['rendered_' + id];
312-
}
313-
}
314-
if (cached) return cached;
315-
}
316-
rendered = render(t.template, data);
317-
if (t.options.cache) {
318-
id = new Date().getTime();
319-
cache['template_' + id] = t.template;
320-
cache['data_' + id] = JSON.stringify(data);
321-
cache['rendered_' + id] = rendered;
322-
}
323-
return rendered;
324-
};
325219
};
326220
Template7.prototype = {
327221
options: {
328-
cache: false
222+
// cache: false
329223
},
330224
helpers: {
331225
'if': function (context, options) {
@@ -384,7 +278,7 @@ window.Template7 = (function () {
384278
var t7 = function (template, data) {
385279
if (arguments.length === 2) {
386280
var instance = new Template7(template);
387-
var rendered = instance.render(data);
281+
var rendered = instance.compile()(data);
388282
instance = null;
389283
return (rendered);
390284
}
@@ -393,34 +287,12 @@ window.Template7 = (function () {
393287
t7.registerHelper = function (name, fn) {
394288
Template7.prototype.helpers[name] = fn;
395289
};
396-
t7.render = function (template, data) {
397-
var instance = t7(template, data);
398-
};
290+
399291
t7.compile = function (template) {
400292
var instance = new Template7(template);
401293
return instance.compile();
402294
};
403-
t7.cache = cache;
404-
t7.clearCache = function (arg) {
405-
if (arguments.length === 0) {
406-
cache = {};
407-
return;
408-
}
409-
var key, id;
410-
// Clear by passed data
411-
for (key in cache) {
412-
var lookFor = typeof arg === 'string' ? 'template_' : 'data_';
413-
var compareWith = typeof arg === 'string' ? arg : JSON.strigify(arg);
414-
if (key.indexOf(lookFor) >= 0 && cache[key] === arg) {
415-
id = key.split('_')[1];
416-
}
417-
}
418-
if (id) {
419-
delete cache['template_' + id];
420-
delete cache['data_' + id];
421-
delete cache['rendered_' + id];
422-
}
423-
};
295+
424296
t7.options = Template7.prototype.options;
425297
t7.helpers = Template7.prototype.helpers;
426298
return t7;

0 commit comments

Comments
 (0)