vendor/assets/javascripts/hogan.js in hogan_assets-1.5.1 vs vendor/assets/javascripts/hogan.js in hogan_assets-1.6.0
- old
+ new
@@ -1,6 +1,6 @@
-/*
+/*!
* Copyright 2011 Twitter, Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
@@ -20,11 +20,11 @@
(function (Hogan, useArrayBuffer) {
Hogan.Template = function (codeObj, text, compiler, options) {
codeObj = codeObj || {};
this.r = codeObj.code || this.r;
this.c = compiler;
- this.options = options;
+ this.options = options || {};
this.text = text || '';
this.partials = codeObj.partials || {};
this.subs = codeObj.subs || {};
this.ib();
}
@@ -71,18 +71,22 @@
// We use this to check whether the partials dictionary has changed
this.partials[symbol].base = template;
if (partial.subs) {
- template = createSpecializedPartial(template, partial.subs, partial.partials);
- }
-
+ // Make sure we consider parent template now
+ if (this.activeSub === undefined) {
+ // Store parent template text in partials.stackText to perform substitutions in child templates correctly
+ partials.stackText = this.text;
+ }
+ template = createSpecializedPartial(template, partial.subs, partial.partials, partials.stackText || this.text);
+ }
this.partials[symbol].instance = template;
return template;
},
- // tries to find a partial in the curent scope and render it
+ // tries to find a partial in the current scope and render it
rp: function(symbol, context, partials, indent) {
var partial = this.ep(symbol, partials);
if (!partial) {
return '';
}
@@ -116,35 +120,38 @@
if (typeof val == 'function') {
val = this.ms(val, ctx, partials, inverted, start, end, tags);
}
- pass = (val === '') || !!val;
+ pass = !!val;
if (!inverted && pass && ctx) {
ctx.push((typeof val == 'object') ? val : ctx[ctx.length - 1]);
}
return pass;
},
// find values with dotted names
d: function(key, ctx, partials, returnFound) {
- var names = key.split('.'),
+ var found,
+ names = key.split('.'),
val = this.f(names[0], ctx, partials, returnFound),
+ doModelGet = this.options.modelGet,
cx = null;
if (key === '.' && isArray(ctx[ctx.length - 2])) {
- return ctx[ctx.length - 1];
- }
-
- for (var i = 1; i < names.length; i++) {
- if (val && typeof val == 'object' && val[names[i]] != null) {
- cx = val;
- val = val[names[i]];
- } else {
- val = '';
+ val = ctx[ctx.length - 1];
+ } else {
+ for (var i = 1; i < names.length; i++) {
+ found = findInScope(names[i], val, doModelGet);
+ if (found != null) {
+ cx = val;
+ val = found;
+ } else {
+ val = '';
+ }
}
}
if (returnFound && !val) {
return false;
@@ -161,16 +168,17 @@
// find values with normal names
f: function(key, ctx, partials, returnFound) {
var val = false,
v = null,
- found = false;
+ found = false,
+ doModelGet = this.options.modelGet;
for (var i = ctx.length - 1; i >= 0; i--) {
v = ctx[i];
- if (v && typeof v == 'object' && v[key] != null) {
- val = v[key];
+ val = findInScope(key, v, doModelGet);
+ if (val != null) {
found = true;
break;
}
}
@@ -215,18 +223,20 @@
this.buf = (useArrayBuffer) ? [] : '';
},
// method replace section
ms: function(func, ctx, partials, inverted, start, end, tags) {
- var cx = ctx[ctx.length - 1],
+ var textSource,
+ cx = ctx[ctx.length - 1],
result = func.call(cx);
if (typeof result == 'function') {
if (inverted) {
return true;
} else {
- return this.ls(result, cx, partials, this.text.substring(start, end), tags);
+ textSource = (this.activeSub && this.subsText[this.activeSub]) ? this.subsText[this.activeSub] : this.text;
+ return this.ls(result, cx, partials, textSource.substring(start, end), tags);
}
}
return result;
},
@@ -244,28 +254,50 @@
},
sub: function(name, context, partials, indent) {
var f = this.subs[name];
if (f) {
+ this.activeSub = name;
f(context, partials, this, indent);
+ this.activeSub = false;
}
}
};
- function createSpecializedPartial(instance, subs, partials) {
+ //Find a key in an object
+ function findInScope(key, scope, doModelGet) {
+ var val, checkVal;
+
+ if (scope && typeof scope == 'object') {
+
+ if (scope[key] != null) {
+ val = scope[key];
+
+ // try lookup with get for backbone or similar model data
+ } else if (doModelGet && scope.get && typeof scope.get == 'function') {
+ val = scope.get(key);
+ }
+ }
+
+ return val;
+ }
+
+ function createSpecializedPartial(instance, subs, partials, childText) {
function PartialTemplate() {};
PartialTemplate.prototype = instance;
function Substitutions() {};
Substitutions.prototype = instance.subs;
var key;
var partial = new PartialTemplate();
partial.subs = new Substitutions();
+ partial.subsText = {}; //hehe. substext.
partial.ib();
for (key in subs) {
partial.subs[key] = subs[key];
+ partial.subsText[key] = childText;
}
for (key in partials) {
partial.partials[key] = partials[key];
}
@@ -274,26 +306,26 @@
}
var rAmp = /&/g,
rLt = /</g,
rGt = />/g,
- rApos =/\'/g,
+ rApos = /\'/g,
rQuot = /\"/g,
- hChars =/[&<>\"\']/;
+ hChars = /[&<>\"\']/;
function coerceToString(val) {
return String((val === null || val === undefined) ? '' : val);
}
function hoganEscape(str) {
str = coerceToString(str);
return hChars.test(str) ?
str
- .replace(rAmp,'&')
- .replace(rLt,'<')
- .replace(rGt,'>')
- .replace(rApos,''')
+ .replace(rAmp, '&')
+ .replace(rLt, '<')
+ .replace(rGt, '>')
+ .replace(rApos, ''')
.replace(rQuot, '"') :
str;
}
var isArray = Array.isArray || function(a) {
@@ -383,11 +415,11 @@
delimiters = trim(
text.substring(text.indexOf('=', index) + 1, closeIndex)
).split(' ');
otag = delimiters[0];
- ctag = delimiters[1];
+ ctag = delimiters[delimiters.length - 1];
return closeIndex + close.length - 1;
}
if (delimiters) {
@@ -669,11 +701,11 @@
function write(s) {
return 't.b(' + s + ');';
}
- Hogan.walk = function (nodelist, context) {
+ Hogan.walk = function(nodelist, context) {
var func;
for (var i = 0, l = nodelist.length; i < l; i++) {
func = Hogan.codegen[nodelist[i].tag];
func && func(nodelist[i], context);
}
@@ -681,17 +713,17 @@
}
Hogan.parse = function(tokens, text, options) {
options = options || {};
return buildTree(tokens, '', [], options.sectionTags || []);
- },
+ }
Hogan.cache = {};
Hogan.cacheKey = function(text, options) {
- return [text, !!options.asString, !!options.disableLambda].join('||');
- },
+ return [text, !!options.asString, !!options.disableLambda, options.delimiters, !!options.modelGet].join('||');
+ }
Hogan.compile = function(text, options) {
options = options || {};
var key = Hogan.cacheKey(text, options);
var template = this.cache[key];
@@ -700,8 +732,8 @@
return template;
}
template = this.generate(this.parse(this.scan(text, options.delimiters), text, options), text, options);
return this.cache[key] = template;
- };
+ }
})(typeof exports !== 'undefined' ? exports : Hogan);