Comparing version 1.2.5 to 1.3.0
module.exports = { | ||
"extends": "airbnb-base", | ||
"plugins": [ | ||
"import" | ||
], | ||
"globals": { | ||
"window": true | ||
} | ||
"extends": "airbnb-base", | ||
"plugins": [ | ||
"import" | ||
], | ||
"rules": { | ||
"no-continue": ["off"], | ||
"max-len": ["error", 1000, 2, { | ||
ignoreUrls: true, | ||
ignoreComments: false, | ||
ignoreRegExpLiterals: true, | ||
ignoreStrings: true, | ||
ignoreTemplateLiterals: true, | ||
}], | ||
}, | ||
"globals": { | ||
"window": true | ||
} | ||
}; |
# Change Log | ||
## Template7 v1.3.0 - Released on September 13, 2017 | ||
* Small performance improvements with decreased number of `eval` calls | ||
* Source-code restructure into more ES-next modules | ||
## Template7 v1.2.5 - Released on August 2, 2017 | ||
@@ -4,0 +8,0 @@ * `js_compare` helper has been renamed to `js_if` helper. `js_compare` is still available for backwards compatibility |
/** | ||
* Template7 1.2.5 | ||
* Template7 1.3.0 | ||
* Mobile-first HTML template engine | ||
@@ -13,3 +13,3 @@ * | ||
* | ||
* Released on: August 2, 2017 | ||
* Released on: September 13, 2017 | ||
*/ | ||
@@ -22,18 +22,23 @@ (function (global, factory) { | ||
var template7Context; | ||
var t7ctx; | ||
if (typeof window !== 'undefined') { | ||
template7Context = window; | ||
t7ctx = window; | ||
} else if (typeof global !== 'undefined') { | ||
template7Context = global; | ||
t7ctx = global; | ||
} else { | ||
template7Context = undefined; | ||
t7ctx = undefined; | ||
} | ||
function isArray(arr) { | ||
return Array.isArray ? Array.isArray(arr) : Object.prototype.toString.apply(arr) === '[object Array]'; | ||
} | ||
function isFunction(func) { | ||
return typeof func === 'function'; | ||
} | ||
function escape(string) { | ||
return (typeof template7Context !== 'undefined' && template7Context.escape ? template7Context.escape(string) : string) | ||
var Template7Context = t7ctx; | ||
var Template7Utils = { | ||
quoteSingleRexExp: new RegExp('\'', 'g'), | ||
quoteDoubleRexExp: new RegExp('"', 'g'), | ||
isFunction: function isFunction(func) { | ||
return typeof func === 'function'; | ||
}, | ||
escape: function escape(string) { | ||
return (typeof Template7Context !== 'undefined' && Template7Context.escape) ? | ||
Template7Context.escape(string) : | ||
string | ||
.replace(/&/g, '&') | ||
@@ -43,146 +48,160 @@ .replace(/</g, '<') | ||
.replace(/"/g, '"'); | ||
} | ||
var quoteSingleRexExp = new RegExp('\'', 'g'); | ||
var quoteDoubleRexExp = new RegExp('"', 'g'); | ||
function helperToSlices(string) { | ||
var helperParts = string.replace(/[{}#}]/g, '').split(' '); | ||
var slices = []; | ||
var shiftIndex; | ||
var i; | ||
var j; | ||
for (i = 0; i < helperParts.length; i += 1) { | ||
var part = helperParts[i]; | ||
var blockQuoteRegExp = (void 0); | ||
var openingQuote = (void 0); | ||
if (i === 0) { slices.push(part); } | ||
else if (part.indexOf('"') === 0 || part.indexOf('\'') === 0) { | ||
blockQuoteRegExp = part.indexOf('"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp; | ||
openingQuote = part.indexOf('"') === 0 ? '"' : '\''; | ||
// Plain String | ||
if (part.match(blockQuoteRegExp).length === 2) { | ||
// One word string | ||
slices.push(part); | ||
} else { | ||
// Find closed Index | ||
shiftIndex = 0; | ||
for (j = i + 1; j < helperParts.length; j += 1) { | ||
part += " " + (helperParts[j]); | ||
if (helperParts[j].indexOf(openingQuote) >= 0) { | ||
shiftIndex = j; | ||
slices.push(part); | ||
break; | ||
}, | ||
helperToSlices: function helperToSlices(string) { | ||
var quoteDoubleRexExp = Template7Utils.quoteDoubleRexExp; | ||
var quoteSingleRexExp = Template7Utils.quoteSingleRexExp; | ||
var helperParts = string.replace(/[{}#}]/g, '').split(' '); | ||
var slices = []; | ||
var shiftIndex; | ||
var i; | ||
var j; | ||
for (i = 0; i < helperParts.length; i += 1) { | ||
var part = helperParts[i]; | ||
var blockQuoteRegExp = (void 0); | ||
var openingQuote = (void 0); | ||
if (i === 0) { slices.push(part); } | ||
else if (part.indexOf('"') === 0 || part.indexOf('\'') === 0) { | ||
blockQuoteRegExp = part.indexOf('"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp; | ||
openingQuote = part.indexOf('"') === 0 ? '"' : '\''; | ||
// Plain String | ||
if (part.match(blockQuoteRegExp).length === 2) { | ||
// One word string | ||
slices.push(part); | ||
} else { | ||
// Find closed Index | ||
shiftIndex = 0; | ||
for (j = i + 1; j < helperParts.length; j += 1) { | ||
part += " " + (helperParts[j]); | ||
if (helperParts[j].indexOf(openingQuote) >= 0) { | ||
shiftIndex = j; | ||
slices.push(part); | ||
break; | ||
} | ||
} | ||
if (shiftIndex) { i = shiftIndex; } | ||
} | ||
if (shiftIndex) { i = shiftIndex; } | ||
} | ||
} else if (part.indexOf('=') > 0) { | ||
// Hash | ||
var hashParts = part.split('='); | ||
var hashName = hashParts[0]; | ||
var hashContent = hashParts[1]; | ||
if (!blockQuoteRegExp) { | ||
blockQuoteRegExp = hashContent.indexOf('"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp; | ||
openingQuote = hashContent.indexOf('"') === 0 ? '"' : '\''; | ||
} | ||
if (hashContent.match(blockQuoteRegExp).length !== 2) { | ||
shiftIndex = 0; | ||
for (j = i + 1; j < helperParts.length; j += 1) { | ||
hashContent += " " + (helperParts[j]); | ||
if (helperParts[j].indexOf(openingQuote) >= 0) { | ||
shiftIndex = j; | ||
break; | ||
} else if (part.indexOf('=') > 0) { | ||
// Hash | ||
var hashParts = part.split('='); | ||
var hashName = hashParts[0]; | ||
var hashContent = hashParts[1]; | ||
if (!blockQuoteRegExp) { | ||
blockQuoteRegExp = hashContent.indexOf('"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp; | ||
openingQuote = hashContent.indexOf('"') === 0 ? '"' : '\''; | ||
} | ||
if (hashContent.match(blockQuoteRegExp).length !== 2) { | ||
shiftIndex = 0; | ||
for (j = i + 1; j < helperParts.length; j += 1) { | ||
hashContent += " " + (helperParts[j]); | ||
if (helperParts[j].indexOf(openingQuote) >= 0) { | ||
shiftIndex = j; | ||
break; | ||
} | ||
} | ||
if (shiftIndex) { i = shiftIndex; } | ||
} | ||
if (shiftIndex) { i = shiftIndex; } | ||
var hash = [hashName, hashContent.replace(blockQuoteRegExp, '')]; | ||
slices.push(hash); | ||
} else { | ||
// Plain variable | ||
slices.push(part); | ||
} | ||
var hash = [hashName, hashContent.replace(blockQuoteRegExp, '')]; | ||
slices.push(hash); | ||
} else { | ||
// Plain variable | ||
slices.push(part); | ||
} | ||
} | ||
return slices; | ||
} | ||
function stringToBlocks(string) { | ||
var blocks = []; | ||
var i; | ||
var j; | ||
if (!string) { return []; } | ||
var stringBlocks = string.split(/({{[^{^}]*}})/); | ||
for (i = 0; i < stringBlocks.length; i += 1) { | ||
var block = stringBlocks[i]; | ||
if (block === '') { continue; } | ||
if (block.indexOf('{{') < 0) { | ||
blocks.push({ | ||
type: 'plain', | ||
content: block, | ||
}); | ||
} else { | ||
if (block.indexOf('{/') >= 0) { | ||
continue; | ||
} | ||
if (block.indexOf('{#') < 0 && block.indexOf(' ') < 0 && block.indexOf('else') < 0) { | ||
// Simple variable | ||
return slices; | ||
}, | ||
stringToBlocks: function stringToBlocks(string) { | ||
var blocks = []; | ||
var i; | ||
var j; | ||
if (!string) { return []; } | ||
var stringBlocks = string.split(/({{[^{^}]*}})/); | ||
for (i = 0; i < stringBlocks.length; i += 1) { | ||
var block = stringBlocks[i]; | ||
if (block === '') { continue; } | ||
if (block.indexOf('{{') < 0) { | ||
blocks.push({ | ||
type: 'variable', | ||
contextName: block.replace(/[{}]/g, ''), | ||
type: 'plain', | ||
content: block, | ||
}); | ||
continue; | ||
} | ||
// Helpers | ||
var helperSlices = helperToSlices(block); | ||
var helperName = helperSlices[0]; | ||
var isPartial = helperName === '>'; | ||
var helperContext = []; | ||
var helperHash = {}; | ||
for (j = 1; j < helperSlices.length; j += 1) { | ||
var slice = helperSlices[j]; | ||
if (isArray(slice)) { | ||
// Hash | ||
helperHash[slice[0]] = slice[1] === 'false' ? false : slice[1]; | ||
} else { | ||
helperContext.push(slice); | ||
} else { | ||
if (block.indexOf('{/') >= 0) { | ||
continue; | ||
} | ||
} | ||
if (block.indexOf('{#') < 0 && block.indexOf(' ') < 0 && block.indexOf('else') < 0) { | ||
// Simple variable | ||
blocks.push({ | ||
type: 'variable', | ||
contextName: block.replace(/[{}]/g, ''), | ||
}); | ||
continue; | ||
} | ||
// Helpers | ||
var helperSlices = Template7Utils.helperToSlices(block); | ||
var helperName = helperSlices[0]; | ||
var isPartial = helperName === '>'; | ||
var helperContext = []; | ||
var helperHash = {}; | ||
for (j = 1; j < helperSlices.length; j += 1) { | ||
var slice = helperSlices[j]; | ||
if (Array.isArray(slice)) { | ||
// Hash | ||
helperHash[slice[0]] = slice[1] === 'false' ? false : slice[1]; | ||
} else { | ||
helperContext.push(slice); | ||
} | ||
} | ||
if (block.indexOf('{#') >= 0) { | ||
// Condition/Helper | ||
var helperContent = ''; | ||
var elseContent = ''; | ||
var toSkip = 0; | ||
var shiftIndex = (void 0); | ||
var foundClosed = false; | ||
var foundElse = false; | ||
var depth = 0; | ||
for (j = i + 1; j < stringBlocks.length; j += 1) { | ||
if (stringBlocks[j].indexOf('{{#') >= 0) { | ||
depth += 1; | ||
} | ||
if (stringBlocks[j].indexOf('{{/') >= 0) { | ||
depth -= 1; | ||
} | ||
if (stringBlocks[j].indexOf(("{{#" + helperName)) >= 0) { | ||
helperContent += stringBlocks[j]; | ||
if (foundElse) { elseContent += stringBlocks[j]; } | ||
toSkip += 1; | ||
} else if (stringBlocks[j].indexOf(("{{/" + helperName)) >= 0) { | ||
if (toSkip > 0) { | ||
toSkip -= 1; | ||
if (block.indexOf('{#') >= 0) { | ||
// Condition/Helper | ||
var helperContent = ''; | ||
var elseContent = ''; | ||
var toSkip = 0; | ||
var shiftIndex = (void 0); | ||
var foundClosed = false; | ||
var foundElse = false; | ||
var depth = 0; | ||
for (j = i + 1; j < stringBlocks.length; j += 1) { | ||
if (stringBlocks[j].indexOf('{{#') >= 0) { | ||
depth += 1; | ||
} | ||
if (stringBlocks[j].indexOf('{{/') >= 0) { | ||
depth -= 1; | ||
} | ||
if (stringBlocks[j].indexOf(("{{#" + helperName)) >= 0) { | ||
helperContent += stringBlocks[j]; | ||
if (foundElse) { elseContent += stringBlocks[j]; } | ||
toSkip += 1; | ||
} else if (stringBlocks[j].indexOf(("{{/" + helperName)) >= 0) { | ||
if (toSkip > 0) { | ||
toSkip -= 1; | ||
helperContent += stringBlocks[j]; | ||
if (foundElse) { elseContent += stringBlocks[j]; } | ||
} else { | ||
shiftIndex = j; | ||
foundClosed = true; | ||
break; | ||
} | ||
} else if (stringBlocks[j].indexOf('else') >= 0 && depth === 0) { | ||
foundElse = true; | ||
} else { | ||
shiftIndex = j; | ||
foundClosed = true; | ||
break; | ||
if (!foundElse) { helperContent += stringBlocks[j]; } | ||
if (foundElse) { elseContent += stringBlocks[j]; } | ||
} | ||
} else if (stringBlocks[j].indexOf('else') >= 0 && depth === 0) { | ||
foundElse = true; | ||
} else { | ||
if (!foundElse) { helperContent += stringBlocks[j]; } | ||
if (foundElse) { elseContent += stringBlocks[j]; } | ||
} | ||
} | ||
if (foundClosed) { | ||
if (shiftIndex) { i = shiftIndex; } | ||
if (foundClosed) { | ||
if (shiftIndex) { i = shiftIndex; } | ||
blocks.push({ | ||
type: 'helper', | ||
helperName: helperName, | ||
contextName: helperContext, | ||
content: helperContent, | ||
inverseContent: elseContent, | ||
hash: helperHash, | ||
}); | ||
} | ||
} else if (block.indexOf(' ') > 0) { | ||
if (isPartial) { | ||
helperName = '_partial'; | ||
if (helperContext[0]) { helperContext[0] = "\"" + (helperContext[0].replace(/"|'/g, '')) + "\""; } | ||
} | ||
blocks.push({ | ||
@@ -192,58 +211,40 @@ type: 'helper', | ||
contextName: helperContext, | ||
content: helperContent, | ||
inverseContent: elseContent, | ||
hash: helperHash, | ||
}); | ||
} | ||
} else if (block.indexOf(' ') > 0) { | ||
if (isPartial) { | ||
helperName = '_partial'; | ||
if (helperContext[0]) { helperContext[0] = "\"" + (helperContext[0].replace(/"|'/g, '')) + "\""; } | ||
} | ||
blocks.push({ | ||
type: 'helper', | ||
helperName: helperName, | ||
contextName: helperContext, | ||
hash: helperHash, | ||
} | ||
} | ||
return blocks; | ||
}, | ||
parseJsVariable: function parseJsVariable(expression, replace, object) { | ||
return expression.split(/([+ -*/^])/g).map(function (part) { | ||
if (part.indexOf(replace) < 0) { return part; } | ||
if (!object) { return JSON.stringify(''); } | ||
var variable = object; | ||
if (part.indexOf((replace + ".")) >= 0) { | ||
part.split((replace + "."))[1].split('.').forEach(function (partName) { | ||
if (variable[partName]) { variable = variable[partName]; } | ||
else { variable = 'undefined'; } | ||
}); | ||
} | ||
} | ||
} | ||
return blocks; | ||
} | ||
function parseJsVariable(expression, replace, object) { | ||
return expression.split(/([+ -*/^])/g).map(function (part) { | ||
if (part.indexOf(replace) < 0) { return part; } | ||
if (!object) { return JSON.stringify(''); } | ||
var variable = object; | ||
if (part.indexOf((replace + ".")) >= 0) { | ||
part.split((replace + "."))[1].split('.').forEach(function (partName) { | ||
return JSON.stringify(variable); | ||
}).join(''); | ||
}, | ||
parseJsParents: function parseJsParents(expression, parents) { | ||
return expression.split(/([+ -*^])/g).map(function (part) { | ||
if (part.indexOf('../') < 0) { return part; } | ||
if (!parents || parents.length === 0) { return JSON.stringify(''); } | ||
var levelsUp = part.split('../').length - 1; | ||
var parentData = levelsUp > parents.length ? parents[parents.length - 1] : parents[levelsUp - 1]; | ||
var variable = parentData; | ||
var parentPart = part.replace(/..\//g, ''); | ||
parentPart.split('.').forEach(function (partName) { | ||
if (variable[partName]) { variable = variable[partName]; } | ||
else { variable = 'undefined'; } | ||
}); | ||
} | ||
return JSON.stringify(variable); | ||
}).join(''); | ||
} | ||
function parseJsParents(expression, parents) { | ||
return expression.split(/([+ -*^])/g).map(function (part) { | ||
if (part.indexOf('../') < 0) { return part; } | ||
if (!parents || parents.length === 0) { return JSON.stringify(''); } | ||
var levelsUp = part.split('../').length - 1; | ||
var parentData = levelsUp > parents.length ? parents[parents.length - 1] : parents[levelsUp - 1]; | ||
var variable = parentData; | ||
var parentPart = part.replace(/..\//g, ''); | ||
parentPart.split('.').forEach(function (partName) { | ||
if (variable[partName]) { variable = variable[partName]; } | ||
else { variable = 'undefined'; } | ||
}); | ||
return JSON.stringify(variable); | ||
}).join(''); | ||
} | ||
var Template7 = function Template7(template) { | ||
var t = this; | ||
t.template = template; | ||
function getCompileVar(name, ctx, data) { | ||
return JSON.stringify(variable); | ||
}).join(''); | ||
}, | ||
getCompileVar: function getCompileVar(name, ctx, data) { | ||
if ( data === void 0 ) data = 'data_1'; | ||
@@ -290,4 +291,4 @@ | ||
return variable; | ||
} | ||
function getCompiledArguments(contextArray, ctx, data) { | ||
}, | ||
getCompiledArguments: function getCompiledArguments(contextArray, ctx, data) { | ||
var arr = []; | ||
@@ -298,3 +299,3 @@ for (var i = 0; i < contextArray.length; i += 1) { | ||
else { | ||
arr.push(getCompileVar(contextArray[i], ctx, data)); | ||
arr.push(Template7Utils.getCompileVar(contextArray[i], ctx, data)); | ||
} | ||
@@ -304,237 +305,268 @@ } | ||
return arr.join(', '); | ||
} | ||
function compile(template, depth) { | ||
if ( template === void 0 ) template = t.template; | ||
if ( depth === void 0 ) depth = 1; | ||
}, | ||
}; | ||
if (typeof template !== 'string') { | ||
throw new Error('Template7: Template must be a string'); | ||
var Template7Helpers = { | ||
_partial: function _partial(partialName, options) { | ||
var p = Template7Class.partials[partialName]; | ||
if (!p || (p && !p.template)) { return ''; } | ||
if (!p.compiled) { | ||
p.compiled = new Template7Class(p.template).compile(); | ||
} | ||
var blocks = stringToBlocks(template); | ||
var ctx = "ctx_" + depth; | ||
var data = "data_" + depth; | ||
if (blocks.length === 0) { | ||
return function empty() { return ''; }; | ||
var ctx = this; | ||
for (var hashName in options.hash) { | ||
ctx[hashName] = options.hash[hashName]; | ||
} | ||
function getCompileFn(block, newDepth) { | ||
if (block.content) { return compile(block.content, newDepth); } | ||
return function empty() { return ''; }; | ||
return p.compiled(ctx, options.data, options.root); | ||
}, | ||
escape: function escape(context) { | ||
if (typeof context !== 'string') { | ||
throw new Error('Template7: Passed context to "escape" helper should be a string'); | ||
} | ||
function getCompileInverse(block, newDepth) { | ||
if (block.inverseContent) { return compile(block.inverseContent, newDepth); } | ||
return function empty() { return ''; }; | ||
return Template7Utils.escape(context); | ||
}, | ||
if: function if$1(context, options) { | ||
var ctx = context; | ||
if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); } | ||
if (ctx) { | ||
return options.fn(this, options.data); | ||
} | ||
var resultString = ''; | ||
if (depth === 1) { | ||
resultString += "(function (" + ctx + ", " + data + ", root) {\n"; | ||
} else { | ||
resultString += "(function (" + ctx + ", " + data + ") {\n"; | ||
return options.inverse(this, options.data); | ||
}, | ||
unless: function unless(context, options) { | ||
var ctx = context; | ||
if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); } | ||
if (!ctx) { | ||
return options.fn(this, options.data); | ||
} | ||
if (depth === 1) { | ||
resultString += 'function isArray(arr){return Object.prototype.toString.apply(arr) === \'[object Array]\';}\n'; | ||
resultString += 'function isFunction(func){return (typeof func === \'function\');}\n'; | ||
resultString += 'function c(val, ctx) {if (typeof val !== "undefined" && val !== null) {if (isFunction(val)) {return val.call(ctx);} else return val;} else return "";}\n'; | ||
resultString += 'root = root || ctx_1 || {};\n'; | ||
} | ||
resultString += 'var r = \'\';\n'; | ||
var i; | ||
for (i = 0; i < blocks.length; i += 1) { | ||
var block = blocks[i]; | ||
// Plain block | ||
if (block.type === 'plain') { | ||
resultString += "r +='" + ((block.content).replace(/\r/g, '\\r').replace(/\n/g, '\\n').replace(/'/g, '\\' + '\'')) + "';"; | ||
continue; | ||
return options.inverse(this, options.data); | ||
}, | ||
each: function each(context, options) { | ||
var ctx = context; | ||
var ret = ''; | ||
var i = 0; | ||
if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); } | ||
if (Array.isArray(ctx)) { | ||
if (options.hash.reverse) { | ||
ctx = ctx.reverse(); | ||
} | ||
var variable = (void 0); | ||
var compiledArguments = (void 0); | ||
// Variable block | ||
if (block.type === 'variable') { | ||
variable = getCompileVar(block.contextName, ctx, data); | ||
resultString += "r += c(" + variable + ", " + ctx + ");"; | ||
for (i = 0; i < ctx.length; i += 1) { | ||
ret += options.fn(ctx[i], { first: i === 0, last: i === ctx.length - 1, index: i }); | ||
} | ||
// Helpers block | ||
if (block.type === 'helper') { | ||
var parents = (void 0); | ||
if (ctx !== 'ctx_1') { | ||
var level = ctx.split('_')[1]; | ||
var parentsString = "ctx_" + (level - 1); | ||
for (var j = level - 2; j >= 1; j -= 1) { | ||
parentsString += ", ctx_" + j; | ||
} | ||
parents = "[" + parentsString + "]"; | ||
} else { | ||
parents = "[" + ctx + "]"; | ||
} | ||
if (block.helperName in t.helpers) { | ||
compiledArguments = getCompiledArguments(block.contextName, ctx, data); | ||
resultString += "r += (Template7.helpers." + (block.helperName) + ").call(" + ctx + ", " + (compiledArguments && ((compiledArguments + ", "))) + "{hash:" + (JSON.stringify(block.hash)) + ", data: " + data + " || {}, fn: " + (getCompileFn(block, depth + 1)) + ", inverse: " + (getCompileInverse(block, depth + 1)) + ", root: root, parents: " + parents + "});"; | ||
} else if (block.contextName.length > 0) { | ||
throw new Error(("Template7: Missing helper: \"" + (block.helperName) + "\"")); | ||
} else { | ||
variable = getCompileVar(block.helperName, ctx, data); | ||
resultString += "if (" + variable + ") {"; | ||
resultString += "if (isArray(" + variable + ")) {"; | ||
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)) + ", root: root, parents: " + parents + "});"; | ||
resultString += '}else {'; | ||
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)) + ", root: root, parents: " + parents + "});"; | ||
resultString += '}}'; | ||
} | ||
if (options.hash.reverse) { | ||
ctx = ctx.reverse(); | ||
} | ||
} else { | ||
for (var key in ctx) { | ||
i += 1; | ||
ret += options.fn(ctx[key], { key: key }); | ||
} | ||
} | ||
resultString += '\nreturn r;})'; | ||
return eval.call(template7Context, resultString); | ||
} | ||
t.compile = function _compile(template) { | ||
if (!t.compiled) { | ||
t.compiled = compile(template); | ||
if (i > 0) { return ret; } | ||
return options.inverse(this); | ||
}, | ||
with: function with$1(context, options) { | ||
var ctx = context; | ||
if (Template7Utils.isFunction(ctx)) { ctx = context.call(this); } | ||
return options.fn(ctx); | ||
}, | ||
join: function join(context, options) { | ||
var ctx = context; | ||
if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); } | ||
return ctx.join(options.hash.delimiter || options.hash.delimeter); | ||
}, | ||
js: function js(expression, options) { | ||
var data = options.data; | ||
var func; | ||
var execute = expression; | ||
('index first last key').split(' ').forEach(function (prop) { | ||
if (typeof data[prop] !== 'undefined') { | ||
var re1 = new RegExp(("this.@" + prop), 'g'); | ||
var re2 = new RegExp(("@" + prop), 'g'); | ||
execute = execute | ||
.replace(re1, JSON.stringify(data[prop])) | ||
.replace(re2, JSON.stringify(data[prop])); | ||
} | ||
}); | ||
if (options.root && execute.indexOf('@root') >= 0) { | ||
execute = Template7Utils.parseJsVariable(execute, '@root', options.root); | ||
} | ||
return t.compiled; | ||
}; | ||
if (execute.indexOf('@global') >= 0) { | ||
execute = Template7Utils.parseJsVariable(execute, '@global', Template7Context.Template7.global); | ||
} | ||
if (execute.indexOf('../') >= 0) { | ||
execute = Template7Utils.parseJsParents(execute, options.parents); | ||
} | ||
if (execute.indexOf('return') >= 0) { | ||
func = "(function(){" + execute + "})"; | ||
} else { | ||
func = "(function(){return (" + execute + ")})"; | ||
} | ||
return eval.call(this, func).call(this); | ||
}, | ||
js_if: function js_if(expression, options) { | ||
var data = options.data; | ||
var func; | ||
var execute = expression; | ||
('index first last key').split(' ').forEach(function (prop) { | ||
if (typeof data[prop] !== 'undefined') { | ||
var re1 = new RegExp(("this.@" + prop), 'g'); | ||
var re2 = new RegExp(("@" + prop), 'g'); | ||
execute = execute | ||
.replace(re1, JSON.stringify(data[prop])) | ||
.replace(re2, JSON.stringify(data[prop])); | ||
} | ||
}); | ||
if (options.root && execute.indexOf('@root') >= 0) { | ||
execute = Template7Utils.parseJsVariable(execute, '@root', options.root); | ||
} | ||
if (execute.indexOf('@global') >= 0) { | ||
execute = Template7Utils.parseJsVariable(execute, '@global', Template7Class.global); | ||
} | ||
if (execute.indexOf('../') >= 0) { | ||
execute = Template7Utils.parseJsParents(execute, options.parents); | ||
} | ||
if (execute.indexOf('return') >= 0) { | ||
func = "(function(){" + execute + "})"; | ||
} else { | ||
func = "(function(){return (" + execute + ")})"; | ||
} | ||
var condition = eval.call(this, func).call(this); | ||
if (condition) { | ||
return options.fn(this, options.data); | ||
} | ||
return options.inverse(this, options.data); | ||
}, | ||
}; | ||
Template7Helpers.js_compare = Template7Helpers.js_if; | ||
Template7.prototype = { | ||
options: {}, | ||
partials: {}, | ||
helpers: { | ||
_partial: function _partial(partialName, options) { | ||
var p = Template7.prototype.partials[partialName]; | ||
if (!p || (p && !p.template)) { return ''; } | ||
if (!p.compiled) { | ||
p.compiled = new Template7(p.template).compile(); | ||
} | ||
var ctx = this; | ||
for (var hashName in options.hash) { | ||
ctx[hashName] = options.hash[hashName]; | ||
} | ||
return p.compiled(ctx, options.data, options.root); | ||
}, | ||
escape: function escape$1(context, options) { | ||
if (typeof context !== 'string') { | ||
throw new Error('Template7: Passed context to "escape" helper should be a string'); | ||
} | ||
return escape(context); | ||
}, | ||
if: function if$1(context, options) { | ||
var ctx = context; | ||
if (isFunction(ctx)) { ctx = ctx.call(this); } | ||
if (ctx) { | ||
return options.fn(this, options.data); | ||
} | ||
var Template7Options = {}; | ||
var Template7Partials = {}; | ||
var script = Template7Context.document.createElement('script'); | ||
Template7Context.document.head.appendChild(script); | ||
return options.inverse(this, options.data); | ||
}, | ||
unless: function unless(context, options) { | ||
var ctx = context; | ||
if (isFunction(ctx)) { ctx = ctx.call(this); } | ||
if (!ctx) { | ||
return options.fn(this, options.data); | ||
} | ||
var Template7Class = function Template7Class(template) { | ||
var t = this; | ||
t.template = template; | ||
}; | ||
return options.inverse(this, options.data); | ||
}, | ||
each: function each(context, options) { | ||
var ctx = context; | ||
var ret = ''; | ||
var i = 0; | ||
if (isFunction(ctx)) { ctx = ctx.call(this); } | ||
if (isArray(ctx)) { | ||
if (options.hash.reverse) { | ||
ctx = ctx.reverse(); | ||
var staticAccessors = { options: {},partials: {},helpers: {} }; | ||
Template7Class.prototype.compile = function compile (template, depth) { | ||
if ( template === void 0 ) template = this.template; | ||
if ( depth === void 0 ) depth = 1; | ||
var t = this; | ||
if (t.compiled) { return t.compiled; } | ||
if (typeof template !== 'string') { | ||
throw new Error('Template7: Template must be a string'); | ||
} | ||
var stringToBlocks = Template7Utils.stringToBlocks; | ||
var getCompileVar = Template7Utils.getCompileVar; | ||
var getCompiledArguments = Template7Utils.getCompiledArguments; | ||
var blocks = stringToBlocks(template); | ||
var ctx = "ctx_" + depth; | ||
var data = "data_" + depth; | ||
if (blocks.length === 0) { | ||
return function empty() { return ''; }; | ||
} | ||
function getCompileFn(block, newDepth) { | ||
if (block.content) { return t.compile(block.content, newDepth); } | ||
return function empty() { return ''; }; | ||
} | ||
function getCompileInverse(block, newDepth) { | ||
if (block.inverseContent) { return t.compile(block.inverseContent, newDepth); } | ||
return function empty() { return ''; }; | ||
} | ||
var resultString = ''; | ||
if (depth === 1) { | ||
resultString += "(function (" + ctx + ", " + data + ", root) {\n"; | ||
} else { | ||
resultString += "(function (" + ctx + ", " + data + ") {\n"; | ||
} | ||
if (depth === 1) { | ||
resultString += 'function isArray(arr){return Array.isArray(arr);}\n'; | ||
resultString += 'function isFunction(func){return (typeof func === \'function\');}\n'; | ||
resultString += 'function c(val, ctx) {if (typeof val !== "undefined" && val !== null) {if (isFunction(val)) {return val.call(ctx);} else return val;} else return "";}\n'; | ||
resultString += 'root = root || ctx_1 || {};\n'; | ||
} | ||
resultString += 'var r = \'\';\n'; | ||
var i; | ||
for (i = 0; i < blocks.length; i += 1) { | ||
var block = blocks[i]; | ||
// Plain block | ||
if (block.type === 'plain') { | ||
resultString += "r +='" + ((block.content).replace(/\r/g, '\\r').replace(/\n/g, '\\n').replace(/'/g, '\\' + '\'')) + "';"; | ||
continue; | ||
} | ||
var variable = (void 0); | ||
var compiledArguments = (void 0); | ||
// Variable block | ||
if (block.type === 'variable') { | ||
variable = getCompileVar(block.contextName, ctx, data); | ||
resultString += "r += c(" + variable + ", " + ctx + ");"; | ||
} | ||
// Helpers block | ||
if (block.type === 'helper') { | ||
var parents = (void 0); | ||
if (ctx !== 'ctx_1') { | ||
var level = ctx.split('_')[1]; | ||
var parentsString = "ctx_" + (level - 1); | ||
for (var j = level - 2; j >= 1; j -= 1) { | ||
parentsString += ", ctx_" + j; | ||
} | ||
for (i = 0; i < ctx.length; i += 1) { | ||
ret += options.fn(ctx[i], { first: i === 0, last: i === ctx.length - 1, index: i }); | ||
} | ||
if (options.hash.reverse) { | ||
ctx = ctx.reverse(); | ||
} | ||
parents = "[" + parentsString + "]"; | ||
} else { | ||
for (var key in ctx) { | ||
i += 1; | ||
ret += options.fn(ctx[key], { key: key }); | ||
} | ||
parents = "[" + ctx + "]"; | ||
} | ||
if (i > 0) { return ret; } | ||
return options.inverse(this); | ||
}, | ||
with: function with$1(context, options) { | ||
var ctx = context; | ||
if (isFunction(ctx)) { ctx = context.call(this); } | ||
return options.fn(ctx); | ||
}, | ||
join: function join(context, options) { | ||
var ctx = context; | ||
if (isFunction(ctx)) { ctx = ctx.call(this); } | ||
return ctx.join(options.hash.delimiter || options.hash.delimeter); | ||
}, | ||
js: function js(expression, options) { | ||
var data = options.data; | ||
var func; | ||
var execute = expression; | ||
('index first last key').split(' ').forEach(function (prop) { | ||
if (typeof data[prop] !== 'undefined') { | ||
var re1 = new RegExp(("this.@" + prop), 'g'); | ||
var re2 = new RegExp(("@" + prop), 'g'); | ||
execute = execute | ||
.replace(re1, JSON.stringify(data[prop])) | ||
.replace(re2, JSON.stringify(data[prop])); | ||
} | ||
}); | ||
if (options.root && execute.indexOf('@root') >= 0) { | ||
execute = parseJsVariable(execute, '@root', options.root); | ||
} | ||
if (execute.indexOf('@global') >= 0) { | ||
execute = parseJsVariable(execute, '@global', template7Context.Template7.global); | ||
} | ||
if (execute.indexOf('../') >= 0) { | ||
execute = parseJsParents(execute, options.parents); | ||
} | ||
if (execute.indexOf('return') >= 0) { | ||
func = "(function(){" + execute + "})"; | ||
if (block.helperName in Template7Helpers) { | ||
compiledArguments = getCompiledArguments(block.contextName, ctx, data); | ||
resultString += "r += (Template7.helpers." + (block.helperName) + ").call(" + ctx + ", " + (compiledArguments && ((compiledArguments + ", "))) + "{hash:" + (JSON.stringify(block.hash)) + ", data: " + data + " || {}, fn: " + (getCompileFn(block, depth + 1)) + ", inverse: " + (getCompileInverse(block, depth + 1)) + ", root: root, parents: " + parents + "});"; | ||
} else if (block.contextName.length > 0) { | ||
throw new Error(("Template7: Missing helper: \"" + (block.helperName) + "\"")); | ||
} else { | ||
func = "(function(){return (" + execute + ")})"; | ||
variable = getCompileVar(block.helperName, ctx, data); | ||
resultString += "if (" + variable + ") {"; | ||
resultString += "if (isArray(" + variable + ")) {"; | ||
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)) + ", root: root, parents: " + parents + "});"; | ||
resultString += '}else {'; | ||
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)) + ", root: root, parents: " + parents + "});"; | ||
resultString += '}}'; | ||
} | ||
return eval.call(this, func).call(this); | ||
}, | ||
js_if: function js_if(expression, options) { | ||
var data = options.data; | ||
var func; | ||
var execute = expression; | ||
('index first last key').split(' ').forEach(function (prop) { | ||
if (typeof data[prop] !== 'undefined') { | ||
var re1 = new RegExp(("this.@" + prop), 'g'); | ||
var re2 = new RegExp(("@" + prop), 'g'); | ||
execute = execute | ||
.replace(re1, JSON.stringify(data[prop])) | ||
.replace(re2, JSON.stringify(data[prop])); | ||
} | ||
}); | ||
if (options.root && execute.indexOf('@root') >= 0) { | ||
execute = parseJsVariable(execute, '@root', options.root); | ||
} | ||
if (execute.indexOf('@global') >= 0) { | ||
execute = parseJsVariable(execute, '@global', Template7.global); | ||
} | ||
if (execute.indexOf('../') >= 0) { | ||
execute = parseJsParents(execute, options.parents); | ||
} | ||
if (execute.indexOf('return') >= 0) { | ||
func = "(function(){" + execute + "})"; | ||
} else { | ||
func = "(function(){return (" + execute + ")})"; | ||
} | ||
var condition = eval.call(this, func).call(this); | ||
if (condition) { | ||
return options.fn(this, options.data); | ||
} | ||
} | ||
} | ||
resultString += '\nreturn r;})'; | ||
return options.inverse(this, options.data); | ||
}, | ||
}, | ||
if (depth === 1) { | ||
t.compiled = eval.call(Template7Context, resultString); | ||
return t.compiled; | ||
} | ||
return resultString; | ||
}; | ||
Template7.prototype.helpers.js_compare = Template7.prototype.helpers.js_if; | ||
function t7(template, data) { | ||
if (arguments.length === 2) { | ||
var instance = new Template7(template); | ||
staticAccessors.options.get = function () { | ||
return Template7Options; | ||
}; | ||
staticAccessors.partials.get = function () { | ||
return Template7Partials; | ||
}; | ||
staticAccessors.helpers.get = function () { | ||
return Template7Helpers; | ||
}; | ||
Object.defineProperties( Template7Class, staticAccessors ); | ||
function Template7() { | ||
var args = [], len = arguments.length; | ||
while ( len-- ) args[ len ] = arguments[ len ]; | ||
var template = args[0]; | ||
var data = args[1]; | ||
if (args.length === 2) { | ||
var instance = new Template7Class(template); | ||
var rendered = instance.compile()(data); | ||
@@ -544,30 +576,30 @@ instance = null; | ||
} | ||
return new Template7(template); | ||
return new Template7Class(template); | ||
} | ||
t7.registerHelper = function registerHelper(name, fn) { | ||
Template7.prototype.helpers[name] = fn; | ||
Template7.registerHelper = function registerHelper(name, fn) { | ||
Template7Class.helpers[name] = fn; | ||
}; | ||
t7.unregisterHelper = function unregisterHelper(name) { | ||
Template7.prototype.helpers[name] = undefined; | ||
delete Template7.prototype.helpers[name]; | ||
Template7.unregisterHelper = function unregisterHelper(name) { | ||
Template7Class.helpers[name] = undefined; | ||
delete Template7Class.helpers[name]; | ||
}; | ||
t7.registerPartial = function registerPartial(name, template) { | ||
Template7.prototype.partials[name] = { template: template }; | ||
Template7.registerPartial = function registerPartial(name, template) { | ||
Template7Class.partials[name] = { template: template }; | ||
}; | ||
t7.unregisterPartial = function unregisterPartial(name) { | ||
if (Template7.prototype.partials[name]) { | ||
Template7.prototype.partials[name] = undefined; | ||
delete Template7.prototype.partials[name]; | ||
Template7.unregisterPartial = function unregisterPartial(name) { | ||
if (Template7Class.partials[name]) { | ||
Template7Class.partials[name] = undefined; | ||
delete Template7Class.partials[name]; | ||
} | ||
}; | ||
t7.compile = function compile(template, options) { | ||
var instance = new Template7(template, options); | ||
Template7.compile = function compile(template, options) { | ||
var instance = new Template7Class(template, options); | ||
return instance.compile(); | ||
}; | ||
t7.options = Template7.prototype.options; | ||
t7.helpers = Template7.prototype.helpers; | ||
t7.partials = Template7.prototype.partials; | ||
Template7.options = Template7Class.options; | ||
Template7.helpers = Template7Class.helpers; | ||
Template7.partials = Template7Class.partials; | ||
return t7; | ||
return Template7; | ||
@@ -574,0 +606,0 @@ }))); |
/** | ||
* Template7 1.2.5 | ||
* Template7 1.3.0 | ||
* Mobile-first HTML template engine | ||
@@ -13,5 +13,5 @@ * | ||
* | ||
* Released on: August 2, 2017 | ||
* Released on: September 13, 2017 | ||
*/ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Template7=t()}(this,function(){"use strict";function e(e){return Array.isArray?Array.isArray(e):"[object Array]"===Object.prototype.toString.apply(e)}function t(e){return"function"==typeof e}function r(e){return(void 0!==f&&f.escape?f.escape(e):e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function n(e){var t,r,n,i=e.replace(/[{}#}]/g,"").split(" "),a=[];for(r=0;r<i.length;r+=1){var o=i[r],l=void 0,f=void 0;if(0===r)a.push(o);else if(0===o.indexOf('"')||0===o.indexOf("'"))if(l=0===o.indexOf('"')?s:p,f=0===o.indexOf('"')?'"':"'",2===o.match(l).length)a.push(o);else{for(t=0,n=r+1;n<i.length;n+=1)if(o+=" "+i[n],i[n].indexOf(f)>=0){t=n,a.push(o);break}t&&(r=t)}else if(o.indexOf("=")>0){var c=o.split("="),u=c[0],h=c[1];if(l||(l=0===h.indexOf('"')?s:p,f=0===h.indexOf('"')?'"':"'"),2!==h.match(l).length){for(t=0,n=r+1;n<i.length;n+=1)if(h+=" "+i[n],i[n].indexOf(f)>=0){t=n;break}t&&(r=t)}var d=[u,h.replace(l,"")];a.push(d)}else a.push(o)}return a}function i(t){var r,i,a=[];if(!t)return[];var o=t.split(/({{[^{^}]*}})/);for(r=0;r<o.length;r+=1){var l=o[r];if(""!==l)if(l.indexOf("{{")<0)a.push({type:"plain",content:l});else{if(l.indexOf("{/")>=0)continue;if(l.indexOf("{#")<0&&l.indexOf(" ")<0&&l.indexOf("else")<0){a.push({type:"variable",contextName:l.replace(/[{}]/g,"")});continue}var f=n(l),p=f[0],s=">"===p,c=[],u={};for(i=1;i<f.length;i+=1){var h=f[i];e(h)?u[h[0]]="false"!==h[1]&&h[1]:c.push(h)}if(l.indexOf("{#")>=0){var d="",v="",g=0,x=void 0,y=!1,O=!1,m=0;for(i=r+1;i<o.length;i+=1)if(o[i].indexOf("{{#")>=0&&(m+=1),o[i].indexOf("{{/")>=0&&(m-=1),o[i].indexOf("{{#"+p)>=0)d+=o[i],O&&(v+=o[i]),g+=1;else if(o[i].indexOf("{{/"+p)>=0){if(!(g>0)){x=i,y=!0;break}g-=1,d+=o[i],O&&(v+=o[i])}else o[i].indexOf("else")>=0&&0===m?O=!0:(O||(d+=o[i]),O&&(v+=o[i]));y&&(x&&(r=x),a.push({type:"helper",helperName:p,contextName:c,content:d,inverseContent:v,hash:u}))}else l.indexOf(" ")>0&&(s&&(p="_partial",c[0]&&(c[0]='"'+c[0].replace(/"|'/g,"")+'"')),a.push({type:"helper",helperName:p,contextName:c,hash:u}))}}return a}function a(e,t,r){return e.split(/([+ -*\/^])/g).map(function(e){if(e.indexOf(t)<0)return e;if(!r)return JSON.stringify("");var n=r;return e.indexOf(t+".")>=0&&e.split(t+".")[1].split(".").forEach(function(e){n=n[e]?n[e]:"undefined"}),JSON.stringify(n)}).join("")}function o(e,t){return e.split(/([+ -*^])/g).map(function(e){if(e.indexOf("../")<0)return e;if(!t||0===t.length)return JSON.stringify("");var r=e.split("../").length-1,n=r>t.length?t[t.length-1]:t[r-1],i=n;return e.replace(/..\//g,"").split(".").forEach(function(e){i=i[e]?i[e]:"undefined"}),JSON.stringify(i)}).join("")}function l(e,t){if(2===arguments.length){var r=new c(e),n=r.compile()(t);return r=null,n}return new c(e)}var f;f="undefined"!=typeof window?window:"undefined"!=typeof global?global:void 0;var p=new RegExp("'","g"),s=new RegExp('"',"g"),c=function(e){function t(e,t,r){void 0===r&&(r="data_1");var n,i,a=t,o=0;0===e.indexOf("../")?(o=e.split("../").length-1,i=a.split("_")[1]-o,a="ctx_"+(i>=1?i:1),n=e.split("../")[o].split(".")):0===e.indexOf("@global")?(a="Template7.global",n=e.split("@global.")[1].split(".")):0===e.indexOf("@root")?(a="root",n=e.split("@root.")[1].split(".")):n=e.split(".");for(var l=0;l<n.length;l+=1){var f=n[l];if(0===f.indexOf("@")){var p=r.split("_")[1];o>0&&(p=i),l>0?a+="[(data_"+p+" && data_"+p+"."+f.replace("@","")+")]":a="(data_"+p+" && data_"+p+"."+f.replace("@","")+")"}else isFinite(f)?a+="["+f+"]":"this"===f||f.indexOf("this.")>=0||f.indexOf("this[")>=0||f.indexOf("this(")>=0?a=f.replace("this",t):a+="."+f}return a}function r(e,r,n){for(var i=[],a=0;a<e.length;a+=1)/^['"]/.test(e[a])?i.push(e[a]):/^(true|false|\d+)$/.test(e[a])?i.push(e[a]):i.push(t(e[a],r,n));return i.join(", ")}function n(e,o){function l(e,t){return e.content?n(e.content,t):function(){return""}}function p(e,t){return e.inverseContent?n(e.inverseContent,t):function(){return""}}if(void 0===e&&(e=a.template),void 0===o&&(o=1),"string"!=typeof e)throw new Error("Template7: Template must be a string");var s=i(e),c="ctx_"+o,u="data_"+o;if(0===s.length)return function(){return""};var h="";h+=1===o?"(function ("+c+", "+u+", root) {\n":"(function ("+c+", "+u+") {\n",1===o&&(h+="function isArray(arr){return Object.prototype.toString.apply(arr) === '[object Array]';}\n",h+="function isFunction(func){return (typeof func === 'function');}\n",h+='function c(val, ctx) {if (typeof val !== "undefined" && val !== null) {if (isFunction(val)) {return val.call(ctx);} else return val;} else return "";}\n',h+="root = root || ctx_1 || {};\n"),h+="var r = '';\n";var d;for(d=0;d<s.length;d+=1){var v=s[d];if("plain"!==v.type){var g=void 0,x=void 0;if("variable"===v.type&&(g=t(v.contextName,c,u),h+="r += c("+g+", "+c+");"),"helper"===v.type){var y=void 0;if("ctx_1"!==c){for(var O=c.split("_")[1],m="ctx_"+(O-1),b=O-2;b>=1;b-=1)m+=", ctx_"+b;y="["+m+"]"}else y="["+c+"]";if(v.helperName in a.helpers)x=r(v.contextName,c,u),h+="r += (Template7.helpers."+v.helperName+").call("+c+", "+(x&&x+", ")+"{hash:"+JSON.stringify(v.hash)+", data: "+u+" || {}, fn: "+l(v,o+1)+", inverse: "+p(v,o+1)+", root: root, parents: "+y+"});";else{if(v.contextName.length>0)throw new Error('Template7: Missing helper: "'+v.helperName+'"');g=t(v.helperName,c,u),h+="if ("+g+") {",h+="if (isArray("+g+")) {",h+="r += (Template7.helpers.each).call("+c+", "+g+", {hash:"+JSON.stringify(v.hash)+", data: "+u+" || {}, fn: "+l(v,o+1)+", inverse: "+p(v,o+1)+", root: root, parents: "+y+"});",h+="}else {",h+="r += (Template7.helpers.with).call("+c+", "+g+", {hash:"+JSON.stringify(v.hash)+", data: "+u+" || {}, fn: "+l(v,o+1)+", inverse: "+p(v,o+1)+", root: root, parents: "+y+"});",h+="}}"}}}else h+="r +='"+v.content.replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/'/g,"\\'")+"';"}return h+="\nreturn r;})",eval.call(f,h)}var a=this;a.template=e,a.compile=function(e){return a.compiled||(a.compiled=n(e)),a.compiled}};return c.prototype={options:{},partials:{},helpers:{_partial:function(e,t){var r=c.prototype.partials[e];if(!r||r&&!r.template)return"";r.compiled||(r.compiled=new c(r.template).compile());var n=this;for(var i in t.hash)n[i]=t.hash[i];return r.compiled(n,t.data,t.root)},escape:function(e,t){if("string"!=typeof e)throw new Error('Template7: Passed context to "escape" helper should be a string');return r(e)},if:function(e,r){var n=e;return t(n)&&(n=n.call(this)),n?r.fn(this,r.data):r.inverse(this,r.data)},unless:function(e,r){var n=e;return t(n)&&(n=n.call(this)),n?r.inverse(this,r.data):r.fn(this,r.data)},each:function(r,n){var i=r,a="",o=0;if(t(i)&&(i=i.call(this)),e(i)){for(n.hash.reverse&&(i=i.reverse()),o=0;o<i.length;o+=1)a+=n.fn(i[o],{first:0===o,last:o===i.length-1,index:o});n.hash.reverse&&(i=i.reverse())}else for(var l in i)o+=1,a+=n.fn(i[l],{key:l});return o>0?a:n.inverse(this)},with:function(e,r){var n=e;return t(n)&&(n=e.call(this)),r.fn(n)},join:function(e,r){var n=e;return t(n)&&(n=n.call(this)),n.join(r.hash.delimiter||r.hash.delimeter)},js:function(e,t){var r,n=t.data,i=e;return"index first last key".split(" ").forEach(function(e){if(void 0!==n[e]){var t=new RegExp("this.@"+e,"g"),r=new RegExp("@"+e,"g");i=i.replace(t,JSON.stringify(n[e])).replace(r,JSON.stringify(n[e]))}}),t.root&&i.indexOf("@root")>=0&&(i=a(i,"@root",t.root)),i.indexOf("@global")>=0&&(i=a(i,"@global",f.Template7.global)),i.indexOf("../")>=0&&(i=o(i,t.parents)),r=i.indexOf("return")>=0?"(function(){"+i+"})":"(function(){return ("+i+")})",eval.call(this,r).call(this)},js_if:function(e,t){var r,n=t.data,i=e;return"index first last key".split(" ").forEach(function(e){if(void 0!==n[e]){var t=new RegExp("this.@"+e,"g"),r=new RegExp("@"+e,"g");i=i.replace(t,JSON.stringify(n[e])).replace(r,JSON.stringify(n[e]))}}),t.root&&i.indexOf("@root")>=0&&(i=a(i,"@root",t.root)),i.indexOf("@global")>=0&&(i=a(i,"@global",c.global)),i.indexOf("../")>=0&&(i=o(i,t.parents)),r=i.indexOf("return")>=0?"(function(){"+i+"})":"(function(){return ("+i+")})",eval.call(this,r).call(this)?t.fn(this,t.data):t.inverse(this,t.data)}}},c.prototype.helpers.js_compare=c.prototype.helpers.js_if,l.registerHelper=function(e,t){c.prototype.helpers[e]=t},l.unregisterHelper=function(e){c.prototype.helpers[e]=void 0,delete c.prototype.helpers[e]},l.registerPartial=function(e,t){c.prototype.partials[e]={template:t}},l.unregisterPartial=function(e){c.prototype.partials[e]&&(c.prototype.partials[e]=void 0,delete c.prototype.partials[e])},l.compile=function(e,t){return new c(e,t).compile()},l.options=c.prototype.options,l.helpers=c.prototype.helpers,l.partials=c.prototype.partials,l}); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Template7=t()}(this,function(){"use strict";function e(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];var n=e[0],r=e[1];if(2===e.length){var i=new s(n),a=i.compile()(r);return i=null,a}return new s(n)}var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:void 0;var n=t,r={quoteSingleRexExp:new RegExp("'","g"),quoteDoubleRexExp:new RegExp('"',"g"),isFunction:function(e){return"function"==typeof e},escape:function(e){return void 0!==n&&n.escape?n.escape(e):e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")},helperToSlices:function(e){var t,n,i,a=r.quoteDoubleRexExp,l=r.quoteSingleRexExp,o=e.replace(/[{}#}]/g,"").split(" "),s=[];for(n=0;n<o.length;n+=1){var f=o[n],p=void 0,c=void 0;if(0===n)s.push(f);else if(0===f.indexOf('"')||0===f.indexOf("'"))if(p=0===f.indexOf('"')?a:l,c=0===f.indexOf('"')?'"':"'",2===f.match(p).length)s.push(f);else{for(t=0,i=n+1;i<o.length;i+=1)if(f+=" "+o[i],o[i].indexOf(c)>=0){t=i,s.push(f);break}t&&(n=t)}else if(f.indexOf("=")>0){var u=f.split("="),h=u[0],d=u[1];if(p||(p=0===d.indexOf('"')?a:l,c=0===d.indexOf('"')?'"':"'"),2!==d.match(p).length){for(t=0,i=n+1;i<o.length;i+=1)if(d+=" "+o[i],o[i].indexOf(c)>=0){t=i;break}t&&(n=t)}var g=[h,d.replace(p,"")];s.push(g)}else s.push(f)}return s},stringToBlocks:function(e){var t,n,i=[];if(!e)return[];var a=e.split(/({{[^{^}]*}})/);for(t=0;t<a.length;t+=1){var l=a[t];if(""!==l)if(l.indexOf("{{")<0)i.push({type:"plain",content:l});else{if(l.indexOf("{/")>=0)continue;if(l.indexOf("{#")<0&&l.indexOf(" ")<0&&l.indexOf("else")<0){i.push({type:"variable",contextName:l.replace(/[{}]/g,"")});continue}var o=r.helperToSlices(l),s=o[0],f=">"===s,p=[],c={};for(n=1;n<o.length;n+=1){var u=o[n];Array.isArray(u)?c[u[0]]="false"!==u[1]&&u[1]:p.push(u)}if(l.indexOf("{#")>=0){var h="",d="",g=0,v=void 0,x=!1,m=!1,O=0;for(n=t+1;n<a.length;n+=1)if(a[n].indexOf("{{#")>=0&&(O+=1),a[n].indexOf("{{/")>=0&&(O-=1),a[n].indexOf("{{#"+s)>=0)h+=a[n],m&&(d+=a[n]),g+=1;else if(a[n].indexOf("{{/"+s)>=0){if(!(g>0)){v=n,x=!0;break}g-=1,h+=a[n],m&&(d+=a[n])}else a[n].indexOf("else")>=0&&0===O?m=!0:(m||(h+=a[n]),m&&(d+=a[n]));x&&(v&&(t=v),i.push({type:"helper",helperName:s,contextName:p,content:h,inverseContent:d,hash:c}))}else l.indexOf(" ")>0&&(f&&(s="_partial",p[0]&&(p[0]='"'+p[0].replace(/"|'/g,"")+'"')),i.push({type:"helper",helperName:s,contextName:p,hash:c}))}}return i},parseJsVariable:function(e,t,n){return e.split(/([+ -*\/^])/g).map(function(e){if(e.indexOf(t)<0)return e;if(!n)return JSON.stringify("");var r=n;return e.indexOf(t+".")>=0&&e.split(t+".")[1].split(".").forEach(function(e){r=r[e]?r[e]:"undefined"}),JSON.stringify(r)}).join("")},parseJsParents:function(e,t){return e.split(/([+ -*^])/g).map(function(e){if(e.indexOf("../")<0)return e;if(!t||0===t.length)return JSON.stringify("");var n=e.split("../").length-1,r=n>t.length?t[t.length-1]:t[n-1],i=r;return e.replace(/..\//g,"").split(".").forEach(function(e){i=i[e]?i[e]:"undefined"}),JSON.stringify(i)}).join("")},getCompileVar:function(e,t,n){void 0===n&&(n="data_1");var r,i,a=t,l=0;0===e.indexOf("../")?(l=e.split("../").length-1,i=a.split("_")[1]-l,a="ctx_"+(i>=1?i:1),r=e.split("../")[l].split(".")):0===e.indexOf("@global")?(a="Template7.global",r=e.split("@global.")[1].split(".")):0===e.indexOf("@root")?(a="root",r=e.split("@root.")[1].split(".")):r=e.split(".");for(var o=0;o<r.length;o+=1){var s=r[o];if(0===s.indexOf("@")){var f=n.split("_")[1];l>0&&(f=i),o>0?a+="[(data_"+f+" && data_"+f+"."+s.replace("@","")+")]":a="(data_"+f+" && data_"+f+"."+s.replace("@","")+")"}else isFinite(s)?a+="["+s+"]":"this"===s||s.indexOf("this.")>=0||s.indexOf("this[")>=0||s.indexOf("this(")>=0?a=s.replace("this",t):a+="."+s}return a},getCompiledArguments:function(e,t,n){for(var i=[],a=0;a<e.length;a+=1)/^['"]/.test(e[a])?i.push(e[a]):/^(true|false|\d+)$/.test(e[a])?i.push(e[a]):i.push(r.getCompileVar(e[a],t,n));return i.join(", ")}},i={_partial:function(e,t){var n=s.partials[e];if(!n||n&&!n.template)return"";n.compiled||(n.compiled=new s(n.template).compile());var r=this;for(var i in t.hash)r[i]=t.hash[i];return n.compiled(r,t.data,t.root)},escape:function(e){if("string"!=typeof e)throw new Error('Template7: Passed context to "escape" helper should be a string');return r.escape(e)},if:function(e,t){var n=e;return r.isFunction(n)&&(n=n.call(this)),n?t.fn(this,t.data):t.inverse(this,t.data)},unless:function(e,t){var n=e;return r.isFunction(n)&&(n=n.call(this)),n?t.inverse(this,t.data):t.fn(this,t.data)},each:function(e,t){var n=e,i="",a=0;if(r.isFunction(n)&&(n=n.call(this)),Array.isArray(n)){for(t.hash.reverse&&(n=n.reverse()),a=0;a<n.length;a+=1)i+=t.fn(n[a],{first:0===a,last:a===n.length-1,index:a});t.hash.reverse&&(n=n.reverse())}else for(var l in n)a+=1,i+=t.fn(n[l],{key:l});return a>0?i:t.inverse(this)},with:function(e,t){var n=e;return r.isFunction(n)&&(n=e.call(this)),t.fn(n)},join:function(e,t){var n=e;return r.isFunction(n)&&(n=n.call(this)),n.join(t.hash.delimiter||t.hash.delimeter)},js:function(e,t){var i,a=t.data,l=e;return"index first last key".split(" ").forEach(function(e){if(void 0!==a[e]){var t=new RegExp("this.@"+e,"g"),n=new RegExp("@"+e,"g");l=l.replace(t,JSON.stringify(a[e])).replace(n,JSON.stringify(a[e]))}}),t.root&&l.indexOf("@root")>=0&&(l=r.parseJsVariable(l,"@root",t.root)),l.indexOf("@global")>=0&&(l=r.parseJsVariable(l,"@global",n.Template7.global)),l.indexOf("../")>=0&&(l=r.parseJsParents(l,t.parents)),i=l.indexOf("return")>=0?"(function(){"+l+"})":"(function(){return ("+l+")})",eval.call(this,i).call(this)},js_if:function(e,t){var n,i=t.data,a=e;return"index first last key".split(" ").forEach(function(e){if(void 0!==i[e]){var t=new RegExp("this.@"+e,"g"),n=new RegExp("@"+e,"g");a=a.replace(t,JSON.stringify(i[e])).replace(n,JSON.stringify(i[e]))}}),t.root&&a.indexOf("@root")>=0&&(a=r.parseJsVariable(a,"@root",t.root)),a.indexOf("@global")>=0&&(a=r.parseJsVariable(a,"@global",s.global)),a.indexOf("../")>=0&&(a=r.parseJsParents(a,t.parents)),n=a.indexOf("return")>=0?"(function(){"+a+"})":"(function(){return ("+a+")})",eval.call(this,n).call(this)?t.fn(this,t.data):t.inverse(this,t.data)}};i.js_compare=i.js_if;var a={},l={},o=n.document.createElement("script");n.document.head.appendChild(o);var s=function(e){this.template=e},f={options:{},partials:{},helpers:{}};return s.prototype.compile=function(e,t){function a(e,t){return e.content?o.compile(e.content,t):function(){return""}}function l(e,t){return e.inverseContent?o.compile(e.inverseContent,t):function(){return""}}void 0===e&&(e=this.template),void 0===t&&(t=1);var o=this;if(o.compiled)return o.compiled;if("string"!=typeof e)throw new Error("Template7: Template must be a string");var s=r.stringToBlocks,f=r.getCompileVar,p=r.getCompiledArguments,c=s(e),u="ctx_"+t,h="data_"+t;if(0===c.length)return function(){return""};var d="";d+=1===t?"(function ("+u+", "+h+", root) {\n":"(function ("+u+", "+h+") {\n",1===t&&(d+="function isArray(arr){return Array.isArray(arr);}\n",d+="function isFunction(func){return (typeof func === 'function');}\n",d+='function c(val, ctx) {if (typeof val !== "undefined" && val !== null) {if (isFunction(val)) {return val.call(ctx);} else return val;} else return "";}\n',d+="root = root || ctx_1 || {};\n"),d+="var r = '';\n";var g;for(g=0;g<c.length;g+=1){var v=c[g];if("plain"!==v.type){var x=void 0,m=void 0;if("variable"===v.type&&(x=f(v.contextName,u,h),d+="r += c("+x+", "+u+");"),"helper"===v.type){var O=void 0;if("ctx_1"!==u){for(var y=u.split("_")[1],b="ctx_"+(y-1),N=y-2;N>=1;N-=1)b+=", ctx_"+N;O="["+b+"]"}else O="["+u+"]";if(v.helperName in i)m=p(v.contextName,u,h),d+="r += (Template7.helpers."+v.helperName+").call("+u+", "+(m&&m+", ")+"{hash:"+JSON.stringify(v.hash)+", data: "+h+" || {}, fn: "+a(v,t+1)+", inverse: "+l(v,t+1)+", root: root, parents: "+O+"});";else{if(v.contextName.length>0)throw new Error('Template7: Missing helper: "'+v.helperName+'"');x=f(v.helperName,u,h),d+="if ("+x+") {",d+="if (isArray("+x+")) {",d+="r += (Template7.helpers.each).call("+u+", "+x+", {hash:"+JSON.stringify(v.hash)+", data: "+h+" || {}, fn: "+a(v,t+1)+", inverse: "+l(v,t+1)+", root: root, parents: "+O+"});",d+="}else {",d+="r += (Template7.helpers.with).call("+u+", "+x+", {hash:"+JSON.stringify(v.hash)+", data: "+h+" || {}, fn: "+a(v,t+1)+", inverse: "+l(v,t+1)+", root: root, parents: "+O+"});",d+="}}"}}}else d+="r +='"+v.content.replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/'/g,"\\'")+"';"}return d+="\nreturn r;})",1===t?(o.compiled=eval.call(n,d),o.compiled):d},f.options.get=function(){return a},f.partials.get=function(){return l},f.helpers.get=function(){return i},Object.defineProperties(s,f),e.registerHelper=function(e,t){s.helpers[e]=t},e.unregisterHelper=function(e){s.helpers[e]=void 0,delete s.helpers[e]},e.registerPartial=function(e,t){s.partials[e]={template:t}},e.unregisterPartial=function(e){s.partials[e]&&(s.partials[e]=void 0,delete s.partials[e])},e.compile=function(e,t){return new s(e,t).compile()},e.options=s.options,e.helpers=s.helpers,e.partials=s.partials,e}); | ||
//# sourceMappingURL=template7.min.js.map |
/** | ||
* Template7 1.2.5 | ||
* Template7 1.3.0 | ||
* Mobile-first HTML template engine | ||
@@ -13,20 +13,25 @@ * | ||
* | ||
* Released on: August 2, 2017 | ||
* Released on: September 13, 2017 | ||
*/ | ||
let template7Context; | ||
let t7ctx; | ||
if (typeof window !== 'undefined') { | ||
template7Context = window; | ||
t7ctx = window; | ||
} else if (typeof global !== 'undefined') { | ||
template7Context = global; | ||
t7ctx = global; | ||
} else { | ||
template7Context = undefined; | ||
t7ctx = undefined; | ||
} | ||
function isArray(arr) { | ||
return Array.isArray ? Array.isArray(arr) : Object.prototype.toString.apply(arr) === '[object Array]'; | ||
} | ||
function isFunction(func) { | ||
return typeof func === 'function'; | ||
} | ||
function escape(string) { | ||
return (typeof template7Context !== 'undefined' && template7Context.escape ? template7Context.escape(string) : string) | ||
const Template7Context = t7ctx; | ||
const Template7Utils = { | ||
quoteSingleRexExp: new RegExp('\'', 'g'), | ||
quoteDoubleRexExp: new RegExp('"', 'g'), | ||
isFunction(func) { | ||
return typeof func === 'function'; | ||
}, | ||
escape(string) { | ||
return (typeof Template7Context !== 'undefined' && Template7Context.escape) ? | ||
Template7Context.escape(string) : | ||
string | ||
.replace(/&/g, '&') | ||
@@ -36,146 +41,159 @@ .replace(/</g, '<') | ||
.replace(/"/g, '"'); | ||
} | ||
const quoteSingleRexExp = new RegExp('\'', 'g'); | ||
const quoteDoubleRexExp = new RegExp('"', 'g'); | ||
function helperToSlices(string) { | ||
const helperParts = string.replace(/[{}#}]/g, '').split(' '); | ||
const slices = []; | ||
let shiftIndex; | ||
let i; | ||
let j; | ||
for (i = 0; i < helperParts.length; i += 1) { | ||
let part = helperParts[i]; | ||
let blockQuoteRegExp; | ||
let openingQuote; | ||
if (i === 0) slices.push(part); | ||
else if (part.indexOf('"') === 0 || part.indexOf('\'') === 0) { | ||
blockQuoteRegExp = part.indexOf('"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp; | ||
openingQuote = part.indexOf('"') === 0 ? '"' : '\''; | ||
// Plain String | ||
if (part.match(blockQuoteRegExp).length === 2) { | ||
// One word string | ||
slices.push(part); | ||
} else { | ||
// Find closed Index | ||
shiftIndex = 0; | ||
for (j = i + 1; j < helperParts.length; j += 1) { | ||
part += ` ${helperParts[j]}`; | ||
if (helperParts[j].indexOf(openingQuote) >= 0) { | ||
shiftIndex = j; | ||
slices.push(part); | ||
break; | ||
}, | ||
helperToSlices(string) { | ||
const { quoteDoubleRexExp, quoteSingleRexExp } = Template7Utils; | ||
const helperParts = string.replace(/[{}#}]/g, '').split(' '); | ||
const slices = []; | ||
let shiftIndex; | ||
let i; | ||
let j; | ||
for (i = 0; i < helperParts.length; i += 1) { | ||
let part = helperParts[i]; | ||
let blockQuoteRegExp; | ||
let openingQuote; | ||
if (i === 0) slices.push(part); | ||
else if (part.indexOf('"') === 0 || part.indexOf('\'') === 0) { | ||
blockQuoteRegExp = part.indexOf('"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp; | ||
openingQuote = part.indexOf('"') === 0 ? '"' : '\''; | ||
// Plain String | ||
if (part.match(blockQuoteRegExp).length === 2) { | ||
// One word string | ||
slices.push(part); | ||
} else { | ||
// Find closed Index | ||
shiftIndex = 0; | ||
for (j = i + 1; j < helperParts.length; j += 1) { | ||
part += ` ${helperParts[j]}`; | ||
if (helperParts[j].indexOf(openingQuote) >= 0) { | ||
shiftIndex = j; | ||
slices.push(part); | ||
break; | ||
} | ||
} | ||
if (shiftIndex) i = shiftIndex; | ||
} | ||
if (shiftIndex) i = shiftIndex; | ||
} | ||
} else if (part.indexOf('=') > 0) { | ||
// Hash | ||
const hashParts = part.split('='); | ||
const hashName = hashParts[0]; | ||
let hashContent = hashParts[1]; | ||
if (!blockQuoteRegExp) { | ||
blockQuoteRegExp = hashContent.indexOf('"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp; | ||
openingQuote = hashContent.indexOf('"') === 0 ? '"' : '\''; | ||
} | ||
if (hashContent.match(blockQuoteRegExp).length !== 2) { | ||
shiftIndex = 0; | ||
for (j = i + 1; j < helperParts.length; j += 1) { | ||
hashContent += ` ${helperParts[j]}`; | ||
if (helperParts[j].indexOf(openingQuote) >= 0) { | ||
shiftIndex = j; | ||
break; | ||
} else if (part.indexOf('=') > 0) { | ||
// Hash | ||
const hashParts = part.split('='); | ||
const hashName = hashParts[0]; | ||
let hashContent = hashParts[1]; | ||
if (!blockQuoteRegExp) { | ||
blockQuoteRegExp = hashContent.indexOf('"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp; | ||
openingQuote = hashContent.indexOf('"') === 0 ? '"' : '\''; | ||
} | ||
if (hashContent.match(blockQuoteRegExp).length !== 2) { | ||
shiftIndex = 0; | ||
for (j = i + 1; j < helperParts.length; j += 1) { | ||
hashContent += ` ${helperParts[j]}`; | ||
if (helperParts[j].indexOf(openingQuote) >= 0) { | ||
shiftIndex = j; | ||
break; | ||
} | ||
} | ||
if (shiftIndex) i = shiftIndex; | ||
} | ||
if (shiftIndex) i = shiftIndex; | ||
const hash = [hashName, hashContent.replace(blockQuoteRegExp, '')]; | ||
slices.push(hash); | ||
} else { | ||
// Plain variable | ||
slices.push(part); | ||
} | ||
const hash = [hashName, hashContent.replace(blockQuoteRegExp, '')]; | ||
slices.push(hash); | ||
} else { | ||
// Plain variable | ||
slices.push(part); | ||
} | ||
} | ||
return slices; | ||
} | ||
function stringToBlocks(string) { | ||
const blocks = []; | ||
let i; | ||
let j; | ||
if (!string) return []; | ||
const stringBlocks = string.split(/({{[^{^}]*}})/); | ||
for (i = 0; i < stringBlocks.length; i += 1) { | ||
const block = stringBlocks[i]; | ||
if (block === '') continue; | ||
if (block.indexOf('{{') < 0) { | ||
blocks.push({ | ||
type: 'plain', | ||
content: block, | ||
}); | ||
} else { | ||
if (block.indexOf('{/') >= 0) { | ||
continue; | ||
} | ||
if (block.indexOf('{#') < 0 && block.indexOf(' ') < 0 && block.indexOf('else') < 0) { | ||
// Simple variable | ||
return slices; | ||
}, | ||
stringToBlocks(string) { | ||
const blocks = []; | ||
let i; | ||
let j; | ||
if (!string) return []; | ||
const stringBlocks = string.split(/({{[^{^}]*}})/); | ||
for (i = 0; i < stringBlocks.length; i += 1) { | ||
const block = stringBlocks[i]; | ||
if (block === '') continue; | ||
if (block.indexOf('{{') < 0) { | ||
blocks.push({ | ||
type: 'variable', | ||
contextName: block.replace(/[{}]/g, ''), | ||
type: 'plain', | ||
content: block, | ||
}); | ||
continue; | ||
} | ||
// Helpers | ||
const helperSlices = helperToSlices(block); | ||
let helperName = helperSlices[0]; | ||
const isPartial = helperName === '>'; | ||
const helperContext = []; | ||
const helperHash = {}; | ||
for (j = 1; j < helperSlices.length; j += 1) { | ||
const slice = helperSlices[j]; | ||
if (isArray(slice)) { | ||
// Hash | ||
helperHash[slice[0]] = slice[1] === 'false' ? false : slice[1]; | ||
} else { | ||
helperContext.push(slice); | ||
} else { | ||
if (block.indexOf('{/') >= 0) { | ||
continue; | ||
} | ||
} | ||
if (block.indexOf('{#') < 0 && block.indexOf(' ') < 0 && block.indexOf('else') < 0) { | ||
// Simple variable | ||
blocks.push({ | ||
type: 'variable', | ||
contextName: block.replace(/[{}]/g, ''), | ||
}); | ||
continue; | ||
} | ||
// Helpers | ||
const helperSlices = Template7Utils.helperToSlices(block); | ||
let helperName = helperSlices[0]; | ||
const isPartial = helperName === '>'; | ||
const helperContext = []; | ||
const helperHash = {}; | ||
for (j = 1; j < helperSlices.length; j += 1) { | ||
const slice = helperSlices[j]; | ||
if (Array.isArray(slice)) { | ||
// Hash | ||
helperHash[slice[0]] = slice[1] === 'false' ? false : slice[1]; | ||
} else { | ||
helperContext.push(slice); | ||
} | ||
} | ||
if (block.indexOf('{#') >= 0) { | ||
// Condition/Helper | ||
let helperContent = ''; | ||
let elseContent = ''; | ||
let toSkip = 0; | ||
let shiftIndex; | ||
let foundClosed = false; | ||
let foundElse = false; | ||
let depth = 0; | ||
for (j = i + 1; j < stringBlocks.length; j += 1) { | ||
if (stringBlocks[j].indexOf('{{#') >= 0) { | ||
depth += 1; | ||
} | ||
if (stringBlocks[j].indexOf('{{/') >= 0) { | ||
depth -= 1; | ||
} | ||
if (stringBlocks[j].indexOf(`{{#${helperName}`) >= 0) { | ||
helperContent += stringBlocks[j]; | ||
if (foundElse) elseContent += stringBlocks[j]; | ||
toSkip += 1; | ||
} else if (stringBlocks[j].indexOf(`{{/${helperName}`) >= 0) { | ||
if (toSkip > 0) { | ||
toSkip -= 1; | ||
if (block.indexOf('{#') >= 0) { | ||
// Condition/Helper | ||
let helperContent = ''; | ||
let elseContent = ''; | ||
let toSkip = 0; | ||
let shiftIndex; | ||
let foundClosed = false; | ||
let foundElse = false; | ||
let depth = 0; | ||
for (j = i + 1; j < stringBlocks.length; j += 1) { | ||
if (stringBlocks[j].indexOf('{{#') >= 0) { | ||
depth += 1; | ||
} | ||
if (stringBlocks[j].indexOf('{{/') >= 0) { | ||
depth -= 1; | ||
} | ||
if (stringBlocks[j].indexOf(`{{#${helperName}`) >= 0) { | ||
helperContent += stringBlocks[j]; | ||
if (foundElse) elseContent += stringBlocks[j]; | ||
toSkip += 1; | ||
} else if (stringBlocks[j].indexOf(`{{/${helperName}`) >= 0) { | ||
if (toSkip > 0) { | ||
toSkip -= 1; | ||
helperContent += stringBlocks[j]; | ||
if (foundElse) elseContent += stringBlocks[j]; | ||
} else { | ||
shiftIndex = j; | ||
foundClosed = true; | ||
break; | ||
} | ||
} else if (stringBlocks[j].indexOf('else') >= 0 && depth === 0) { | ||
foundElse = true; | ||
} else { | ||
shiftIndex = j; | ||
foundClosed = true; | ||
break; | ||
if (!foundElse) helperContent += stringBlocks[j]; | ||
if (foundElse) elseContent += stringBlocks[j]; | ||
} | ||
} else if (stringBlocks[j].indexOf('else') >= 0 && depth === 0) { | ||
foundElse = true; | ||
} else { | ||
if (!foundElse) helperContent += stringBlocks[j]; | ||
if (foundElse) elseContent += stringBlocks[j]; | ||
} | ||
} | ||
if (foundClosed) { | ||
if (shiftIndex) i = shiftIndex; | ||
if (foundClosed) { | ||
if (shiftIndex) i = shiftIndex; | ||
blocks.push({ | ||
type: 'helper', | ||
helperName, | ||
contextName: helperContext, | ||
content: helperContent, | ||
inverseContent: elseContent, | ||
hash: helperHash, | ||
}); | ||
} | ||
} else if (block.indexOf(' ') > 0) { | ||
if (isPartial) { | ||
helperName = '_partial'; | ||
if (helperContext[0]) helperContext[0] = `"${helperContext[0].replace(/"|'/g, '')}"`; | ||
} | ||
blocks.push({ | ||
@@ -185,343 +203,346 @@ type: 'helper', | ||
contextName: helperContext, | ||
content: helperContent, | ||
inverseContent: elseContent, | ||
hash: helperHash, | ||
}); | ||
} | ||
} else if (block.indexOf(' ') > 0) { | ||
if (isPartial) { | ||
helperName = '_partial'; | ||
if (helperContext[0]) helperContext[0] = `"${helperContext[0].replace(/"|'/g, '')}"`; | ||
} | ||
blocks.push({ | ||
type: 'helper', | ||
helperName, | ||
contextName: helperContext, | ||
hash: helperHash, | ||
} | ||
} | ||
return blocks; | ||
}, | ||
parseJsVariable(expression, replace, object) { | ||
return expression.split(/([+ -*/^])/g).map((part) => { | ||
if (part.indexOf(replace) < 0) return part; | ||
if (!object) return JSON.stringify(''); | ||
let variable = object; | ||
if (part.indexOf(`${replace}.`) >= 0) { | ||
part.split(`${replace}.`)[1].split('.').forEach((partName) => { | ||
if (variable[partName]) variable = variable[partName]; | ||
else variable = 'undefined'; | ||
}); | ||
} | ||
} | ||
} | ||
return blocks; | ||
} | ||
function parseJsVariable(expression, replace, object) { | ||
return expression.split(/([+ -*/^])/g).map((part) => { | ||
if (part.indexOf(replace) < 0) return part; | ||
if (!object) return JSON.stringify(''); | ||
let variable = object; | ||
if (part.indexOf(`${replace}.`) >= 0) { | ||
part.split(`${replace}.`)[1].split('.').forEach((partName) => { | ||
return JSON.stringify(variable); | ||
}).join(''); | ||
}, | ||
parseJsParents(expression, parents) { | ||
return expression.split(/([+ -*^])/g).map((part) => { | ||
if (part.indexOf('../') < 0) return part; | ||
if (!parents || parents.length === 0) return JSON.stringify(''); | ||
const levelsUp = part.split('../').length - 1; | ||
const parentData = levelsUp > parents.length ? parents[parents.length - 1] : parents[levelsUp - 1]; | ||
let variable = parentData; | ||
const parentPart = part.replace(/..\//g, ''); | ||
parentPart.split('.').forEach((partName) => { | ||
if (variable[partName]) variable = variable[partName]; | ||
else variable = 'undefined'; | ||
}); | ||
return JSON.stringify(variable); | ||
}).join(''); | ||
}, | ||
getCompileVar(name, ctx, data = 'data_1') { | ||
let variable = ctx; | ||
let parts; | ||
let levelsUp = 0; | ||
let newDepth; | ||
if (name.indexOf('../') === 0) { | ||
levelsUp = name.split('../').length - 1; | ||
newDepth = variable.split('_')[1] - levelsUp; | ||
variable = `ctx_${newDepth >= 1 ? newDepth : 1}`; | ||
parts = name.split('../')[levelsUp].split('.'); | ||
} else if (name.indexOf('@global') === 0) { | ||
variable = 'Template7.global'; | ||
parts = name.split('@global.')[1].split('.'); | ||
} else if (name.indexOf('@root') === 0) { | ||
variable = 'root'; | ||
parts = name.split('@root.')[1].split('.'); | ||
} else { | ||
parts = name.split('.'); | ||
} | ||
return JSON.stringify(variable); | ||
}).join(''); | ||
} | ||
function parseJsParents(expression, parents) { | ||
return expression.split(/([+ -*^])/g).map((part) => { | ||
if (part.indexOf('../') < 0) return part; | ||
if (!parents || parents.length === 0) return JSON.stringify(''); | ||
const levelsUp = part.split('../').length - 1; | ||
const parentData = levelsUp > parents.length ? parents[parents.length - 1] : parents[levelsUp - 1]; | ||
let variable = parentData; | ||
const parentPart = part.replace(/..\//g, ''); | ||
parentPart.split('.').forEach((partName) => { | ||
if (variable[partName]) variable = variable[partName]; | ||
else variable = 'undefined'; | ||
}); | ||
return JSON.stringify(variable); | ||
}).join(''); | ||
} | ||
class Template7 { | ||
constructor(template) { | ||
const t = this; | ||
t.template = template; | ||
function getCompileVar(name, ctx, data = 'data_1') { | ||
let variable = ctx; | ||
let parts; | ||
let levelsUp = 0; | ||
let newDepth; | ||
if (name.indexOf('../') === 0) { | ||
levelsUp = name.split('../').length - 1; | ||
newDepth = variable.split('_')[1] - levelsUp; | ||
variable = `ctx_${newDepth >= 1 ? newDepth : 1}`; | ||
parts = name.split('../')[levelsUp].split('.'); | ||
} else if (name.indexOf('@global') === 0) { | ||
variable = 'Template7.global'; | ||
parts = name.split('@global.')[1].split('.'); | ||
} else if (name.indexOf('@root') === 0) { | ||
variable = 'root'; | ||
parts = name.split('@root.')[1].split('.'); | ||
} else { | ||
parts = name.split('.'); | ||
} | ||
for (let i = 0; i < parts.length; i += 1) { | ||
const part = parts[i]; | ||
if (part.indexOf('@') === 0) { | ||
let dataLevel = data.split('_')[1]; | ||
if (levelsUp > 0) { | ||
dataLevel = newDepth; | ||
} | ||
if (i > 0) { | ||
variable += `[(data_${dataLevel} && data_${dataLevel}.${part.replace('@', '')})]`; | ||
} else { | ||
variable = `(data_${dataLevel} && data_${dataLevel}.${part.replace('@', '')})`; | ||
} | ||
} else if (isFinite(part)) { | ||
variable += `[${part}]`; | ||
} else if (part === 'this' || part.indexOf('this.') >= 0 || part.indexOf('this[') >= 0 || part.indexOf('this(') >= 0) { | ||
variable = part.replace('this', ctx); | ||
for (let i = 0; i < parts.length; i += 1) { | ||
const part = parts[i]; | ||
if (part.indexOf('@') === 0) { | ||
let dataLevel = data.split('_')[1]; | ||
if (levelsUp > 0) { | ||
dataLevel = newDepth; | ||
} | ||
if (i > 0) { | ||
variable += `[(data_${dataLevel} && data_${dataLevel}.${part.replace('@', '')})]`; | ||
} else { | ||
variable += `.${part}`; | ||
variable = `(data_${dataLevel} && data_${dataLevel}.${part.replace('@', '')})`; | ||
} | ||
} else if (isFinite(part)) { | ||
variable += `[${part}]`; | ||
} else if (part === 'this' || part.indexOf('this.') >= 0 || part.indexOf('this[') >= 0 || part.indexOf('this(') >= 0) { | ||
variable = part.replace('this', ctx); | ||
} else { | ||
variable += `.${part}`; | ||
} | ||
return variable; | ||
} | ||
function getCompiledArguments(contextArray, ctx, data) { | ||
const arr = []; | ||
for (let i = 0; i < contextArray.length; i += 1) { | ||
if (/^['"]/.test(contextArray[i])) arr.push(contextArray[i]); | ||
else if (/^(true|false|\d+)$/.test(contextArray[i])) arr.push(contextArray[i]); | ||
else { | ||
arr.push(getCompileVar(contextArray[i], ctx, data)); | ||
} | ||
return variable; | ||
}, | ||
getCompiledArguments(contextArray, ctx, data) { | ||
const arr = []; | ||
for (let i = 0; i < contextArray.length; i += 1) { | ||
if (/^['"]/.test(contextArray[i])) arr.push(contextArray[i]); | ||
else if (/^(true|false|\d+)$/.test(contextArray[i])) arr.push(contextArray[i]); | ||
else { | ||
arr.push(Template7Utils.getCompileVar(contextArray[i], ctx, data)); | ||
} | ||
} | ||
return arr.join(', '); | ||
return arr.join(', '); | ||
}, | ||
}; | ||
const Template7Helpers = { | ||
_partial(partialName, options) { | ||
const p = Template7Class.partials[partialName]; | ||
if (!p || (p && !p.template)) return ''; | ||
if (!p.compiled) { | ||
p.compiled = new Template7Class(p.template).compile(); | ||
} | ||
function compile(template = t.template, depth = 1) { | ||
if (typeof template !== 'string') { | ||
throw new Error('Template7: Template must be a string'); | ||
} | ||
const blocks = stringToBlocks(template); | ||
const ctx = `ctx_${depth}`; | ||
const data = `data_${depth}`; | ||
if (blocks.length === 0) { | ||
return function empty() { return ''; }; | ||
} | ||
const ctx = this; | ||
for (const hashName in options.hash) { | ||
ctx[hashName] = options.hash[hashName]; | ||
} | ||
return p.compiled(ctx, options.data, options.root); | ||
}, | ||
escape(context) { | ||
if (typeof context !== 'string') { | ||
throw new Error('Template7: Passed context to "escape" helper should be a string'); | ||
} | ||
return Template7Utils.escape(context); | ||
}, | ||
if(context, options) { | ||
let ctx = context; | ||
if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); } | ||
if (ctx) { | ||
return options.fn(this, options.data); | ||
} | ||
function getCompileFn(block, newDepth) { | ||
if (block.content) return compile(block.content, newDepth); | ||
return function empty() { return ''; }; | ||
return options.inverse(this, options.data); | ||
}, | ||
unless(context, options) { | ||
let ctx = context; | ||
if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); } | ||
if (!ctx) { | ||
return options.fn(this, options.data); | ||
} | ||
return options.inverse(this, options.data); | ||
}, | ||
each(context, options) { | ||
let ctx = context; | ||
let ret = ''; | ||
let i = 0; | ||
if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); } | ||
if (Array.isArray(ctx)) { | ||
if (options.hash.reverse) { | ||
ctx = ctx.reverse(); | ||
} | ||
function getCompileInverse(block, newDepth) { | ||
if (block.inverseContent) return compile(block.inverseContent, newDepth); | ||
return function empty() { return ''; }; | ||
for (i = 0; i < ctx.length; i += 1) { | ||
ret += options.fn(ctx[i], { first: i === 0, last: i === ctx.length - 1, index: i }); | ||
} | ||
let resultString = ''; | ||
if (depth === 1) { | ||
resultString += `(function (${ctx}, ${data}, root) {\n`; | ||
} else { | ||
resultString += `(function (${ctx}, ${data}) {\n`; | ||
if (options.hash.reverse) { | ||
ctx = ctx.reverse(); | ||
} | ||
if (depth === 1) { | ||
resultString += 'function isArray(arr){return Object.prototype.toString.apply(arr) === \'[object Array]\';}\n'; | ||
resultString += 'function isFunction(func){return (typeof func === \'function\');}\n'; | ||
resultString += 'function c(val, ctx) {if (typeof val !== "undefined" && val !== null) {if (isFunction(val)) {return val.call(ctx);} else return val;} else return "";}\n'; | ||
resultString += 'root = root || ctx_1 || {};\n'; | ||
} else { | ||
for (const key in ctx) { | ||
i += 1; | ||
ret += options.fn(ctx[key], { key }); | ||
} | ||
resultString += 'var r = \'\';\n'; | ||
let i; | ||
for (i = 0; i < blocks.length; i += 1) { | ||
const block = blocks[i]; | ||
// Plain block | ||
if (block.type === 'plain') { | ||
resultString += `r +='${(block.content).replace(/\r/g, '\\r').replace(/\n/g, '\\n').replace(/'/g, '\\' + '\'')}';`; | ||
continue; | ||
} | ||
let variable; | ||
let compiledArguments; | ||
// Variable block | ||
if (block.type === 'variable') { | ||
variable = getCompileVar(block.contextName, ctx, data); | ||
resultString += `r += c(${variable}, ${ctx});`; | ||
} | ||
// Helpers block | ||
if (block.type === 'helper') { | ||
let parents; | ||
if (ctx !== 'ctx_1') { | ||
const level = ctx.split('_')[1]; | ||
let parentsString = `ctx_${level - 1}`; | ||
for (let j = level - 2; j >= 1; j -= 1) { | ||
parentsString += `, ctx_${j}`; | ||
} | ||
parents = `[${parentsString}]`; | ||
} else { | ||
parents = `[${ctx}]`; | ||
} | ||
if (block.helperName in t.helpers) { | ||
compiledArguments = getCompiledArguments(block.contextName, ctx, data); | ||
resultString += `r += (Template7.helpers.${block.helperName}).call(${ctx}, ${compiledArguments && (`${compiledArguments}, `)}{hash:${JSON.stringify(block.hash)}, data: ${data} || {}, fn: ${getCompileFn(block, depth + 1)}, inverse: ${getCompileInverse(block, depth + 1)}, root: root, parents: ${parents}});`; | ||
} else if (block.contextName.length > 0) { | ||
throw new Error(`Template7: Missing helper: "${block.helperName}"`); | ||
} else { | ||
variable = getCompileVar(block.helperName, ctx, data); | ||
resultString += `if (${variable}) {`; | ||
resultString += `if (isArray(${variable})) {`; | ||
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)}, root: root, parents: ${parents}});`; | ||
resultString += '}else {'; | ||
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)}, root: root, parents: ${parents}});`; | ||
resultString += '}}'; | ||
} | ||
} | ||
} | ||
if (i > 0) return ret; | ||
return options.inverse(this); | ||
}, | ||
with(context, options) { | ||
let ctx = context; | ||
if (Template7Utils.isFunction(ctx)) { ctx = context.call(this); } | ||
return options.fn(ctx); | ||
}, | ||
join(context, options) { | ||
let ctx = context; | ||
if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); } | ||
return ctx.join(options.hash.delimiter || options.hash.delimeter); | ||
}, | ||
js(expression, options) { | ||
const data = options.data; | ||
let func; | ||
let execute = expression; | ||
('index first last key').split(' ').forEach((prop) => { | ||
if (typeof data[prop] !== 'undefined') { | ||
const re1 = new RegExp(`this.@${prop}`, 'g'); | ||
const re2 = new RegExp(`@${prop}`, 'g'); | ||
execute = execute | ||
.replace(re1, JSON.stringify(data[prop])) | ||
.replace(re2, JSON.stringify(data[prop])); | ||
} | ||
resultString += '\nreturn r;})'; | ||
return eval.call(template7Context, resultString); | ||
}); | ||
if (options.root && execute.indexOf('@root') >= 0) { | ||
execute = Template7Utils.parseJsVariable(execute, '@root', options.root); | ||
} | ||
t.compile = function _compile(template) { | ||
if (!t.compiled) { | ||
t.compiled = compile(template); | ||
if (execute.indexOf('@global') >= 0) { | ||
execute = Template7Utils.parseJsVariable(execute, '@global', Template7Context.Template7.global); | ||
} | ||
if (execute.indexOf('../') >= 0) { | ||
execute = Template7Utils.parseJsParents(execute, options.parents); | ||
} | ||
if (execute.indexOf('return') >= 0) { | ||
func = `(function(){${execute}})`; | ||
} else { | ||
func = `(function(){return (${execute})})`; | ||
} | ||
return eval.call(this, func).call(this); | ||
}, | ||
js_if(expression, options) { | ||
const data = options.data; | ||
let func; | ||
let execute = expression; | ||
('index first last key').split(' ').forEach((prop) => { | ||
if (typeof data[prop] !== 'undefined') { | ||
const re1 = new RegExp(`this.@${prop}`, 'g'); | ||
const re2 = new RegExp(`@${prop}`, 'g'); | ||
execute = execute | ||
.replace(re1, JSON.stringify(data[prop])) | ||
.replace(re2, JSON.stringify(data[prop])); | ||
} | ||
return t.compiled; | ||
}; | ||
}); | ||
if (options.root && execute.indexOf('@root') >= 0) { | ||
execute = Template7Utils.parseJsVariable(execute, '@root', options.root); | ||
} | ||
if (execute.indexOf('@global') >= 0) { | ||
execute = Template7Utils.parseJsVariable(execute, '@global', Template7Class.global); | ||
} | ||
if (execute.indexOf('../') >= 0) { | ||
execute = Template7Utils.parseJsParents(execute, options.parents); | ||
} | ||
if (execute.indexOf('return') >= 0) { | ||
func = `(function(){${execute}})`; | ||
} else { | ||
func = `(function(){return (${execute})})`; | ||
} | ||
const condition = eval.call(this, func).call(this); | ||
if (condition) { | ||
return options.fn(this, options.data); | ||
} | ||
return options.inverse(this, options.data); | ||
}, | ||
}; | ||
Template7Helpers.js_compare = Template7Helpers.js_if; | ||
const Template7Options = {}; | ||
const Template7Partials = {}; | ||
const script = Template7Context.document.createElement('script'); | ||
Template7Context.document.head.appendChild(script); | ||
class Template7Class { | ||
constructor(template) { | ||
const t = this; | ||
t.template = template; | ||
} | ||
} | ||
compile(template = this.template, depth = 1) { | ||
const t = this; | ||
if (t.compiled) return t.compiled; | ||
Template7.prototype = { | ||
options: {}, | ||
partials: {}, | ||
helpers: { | ||
_partial(partialName, options) { | ||
const p = Template7.prototype.partials[partialName]; | ||
if (!p || (p && !p.template)) return ''; | ||
if (!p.compiled) { | ||
p.compiled = new Template7(p.template).compile(); | ||
} | ||
const ctx = this; | ||
for (const hashName in options.hash) { | ||
ctx[hashName] = options.hash[hashName]; | ||
} | ||
return p.compiled(ctx, options.data, options.root); | ||
}, | ||
escape(context, options) { | ||
if (typeof context !== 'string') { | ||
throw new Error('Template7: Passed context to "escape" helper should be a string'); | ||
} | ||
return escape(context); | ||
}, | ||
if(context, options) { | ||
let ctx = context; | ||
if (isFunction(ctx)) { ctx = ctx.call(this); } | ||
if (ctx) { | ||
return options.fn(this, options.data); | ||
} | ||
if (typeof template !== 'string') { | ||
throw new Error('Template7: Template must be a string'); | ||
} | ||
const { stringToBlocks, getCompileVar, getCompiledArguments } = Template7Utils; | ||
return options.inverse(this, options.data); | ||
}, | ||
unless(context, options) { | ||
let ctx = context; | ||
if (isFunction(ctx)) { ctx = ctx.call(this); } | ||
if (!ctx) { | ||
return options.fn(this, options.data); | ||
} | ||
const blocks = stringToBlocks(template); | ||
const ctx = `ctx_${depth}`; | ||
const data = `data_${depth}`; | ||
if (blocks.length === 0) { | ||
return function empty() { return ''; }; | ||
} | ||
return options.inverse(this, options.data); | ||
}, | ||
each(context, options) { | ||
let ctx = context; | ||
let ret = ''; | ||
let i = 0; | ||
if (isFunction(ctx)) { ctx = ctx.call(this); } | ||
if (isArray(ctx)) { | ||
if (options.hash.reverse) { | ||
ctx = ctx.reverse(); | ||
} | ||
for (i = 0; i < ctx.length; i += 1) { | ||
ret += options.fn(ctx[i], { first: i === 0, last: i === ctx.length - 1, index: i }); | ||
} | ||
if (options.hash.reverse) { | ||
ctx = ctx.reverse(); | ||
} | ||
} else { | ||
for (const key in ctx) { | ||
i += 1; | ||
ret += options.fn(ctx[key], { key }); | ||
} | ||
function getCompileFn(block, newDepth) { | ||
if (block.content) return t.compile(block.content, newDepth); | ||
return function empty() { return ''; }; | ||
} | ||
function getCompileInverse(block, newDepth) { | ||
if (block.inverseContent) return t.compile(block.inverseContent, newDepth); | ||
return function empty() { return ''; }; | ||
} | ||
let resultString = ''; | ||
if (depth === 1) { | ||
resultString += `(function (${ctx}, ${data}, root) {\n`; | ||
} else { | ||
resultString += `(function (${ctx}, ${data}) {\n`; | ||
} | ||
if (depth === 1) { | ||
resultString += 'function isArray(arr){return Array.isArray(arr);}\n'; | ||
resultString += 'function isFunction(func){return (typeof func === \'function\');}\n'; | ||
resultString += 'function c(val, ctx) {if (typeof val !== "undefined" && val !== null) {if (isFunction(val)) {return val.call(ctx);} else return val;} else return "";}\n'; | ||
resultString += 'root = root || ctx_1 || {};\n'; | ||
} | ||
resultString += 'var r = \'\';\n'; | ||
let i; | ||
for (i = 0; i < blocks.length; i += 1) { | ||
const block = blocks[i]; | ||
// Plain block | ||
if (block.type === 'plain') { | ||
resultString += `r +='${(block.content).replace(/\r/g, '\\r').replace(/\n/g, '\\n').replace(/'/g, '\\' + '\'')}';`; | ||
continue; | ||
} | ||
if (i > 0) return ret; | ||
return options.inverse(this); | ||
}, | ||
with(context, options) { | ||
let ctx = context; | ||
if (isFunction(ctx)) { ctx = context.call(this); } | ||
return options.fn(ctx); | ||
}, | ||
join(context, options) { | ||
let ctx = context; | ||
if (isFunction(ctx)) { ctx = ctx.call(this); } | ||
return ctx.join(options.hash.delimiter || options.hash.delimeter); | ||
}, | ||
js(expression, options) { | ||
const data = options.data; | ||
let func; | ||
let execute = expression; | ||
('index first last key').split(' ').forEach((prop) => { | ||
if (typeof data[prop] !== 'undefined') { | ||
const re1 = new RegExp(`this.@${prop}`, 'g'); | ||
const re2 = new RegExp(`@${prop}`, 'g'); | ||
execute = execute | ||
.replace(re1, JSON.stringify(data[prop])) | ||
.replace(re2, JSON.stringify(data[prop])); | ||
} | ||
}); | ||
if (options.root && execute.indexOf('@root') >= 0) { | ||
execute = parseJsVariable(execute, '@root', options.root); | ||
let variable; | ||
let compiledArguments; | ||
// Variable block | ||
if (block.type === 'variable') { | ||
variable = getCompileVar(block.contextName, ctx, data); | ||
resultString += `r += c(${variable}, ${ctx});`; | ||
} | ||
if (execute.indexOf('@global') >= 0) { | ||
execute = parseJsVariable(execute, '@global', template7Context.Template7.global); | ||
} | ||
if (execute.indexOf('../') >= 0) { | ||
execute = parseJsParents(execute, options.parents); | ||
} | ||
if (execute.indexOf('return') >= 0) { | ||
func = `(function(){${execute}})`; | ||
} else { | ||
func = `(function(){return (${execute})})`; | ||
} | ||
return eval.call(this, func).call(this); | ||
}, | ||
js_if(expression, options) { | ||
const data = options.data; | ||
let func; | ||
let execute = expression; | ||
('index first last key').split(' ').forEach((prop) => { | ||
if (typeof data[prop] !== 'undefined') { | ||
const re1 = new RegExp(`this.@${prop}`, 'g'); | ||
const re2 = new RegExp(`@${prop}`, 'g'); | ||
execute = execute | ||
.replace(re1, JSON.stringify(data[prop])) | ||
.replace(re2, JSON.stringify(data[prop])); | ||
// Helpers block | ||
if (block.type === 'helper') { | ||
let parents; | ||
if (ctx !== 'ctx_1') { | ||
const level = ctx.split('_')[1]; | ||
let parentsString = `ctx_${level - 1}`; | ||
for (let j = level - 2; j >= 1; j -= 1) { | ||
parentsString += `, ctx_${j}`; | ||
} | ||
parents = `[${parentsString}]`; | ||
} else { | ||
parents = `[${ctx}]`; | ||
} | ||
}); | ||
if (options.root && execute.indexOf('@root') >= 0) { | ||
execute = parseJsVariable(execute, '@root', options.root); | ||
if (block.helperName in Template7Helpers) { | ||
compiledArguments = getCompiledArguments(block.contextName, ctx, data); | ||
resultString += `r += (Template7.helpers.${block.helperName}).call(${ctx}, ${compiledArguments && (`${compiledArguments}, `)}{hash:${JSON.stringify(block.hash)}, data: ${data} || {}, fn: ${getCompileFn(block, depth + 1)}, inverse: ${getCompileInverse(block, depth + 1)}, root: root, parents: ${parents}});`; | ||
} else if (block.contextName.length > 0) { | ||
throw new Error(`Template7: Missing helper: "${block.helperName}"`); | ||
} else { | ||
variable = getCompileVar(block.helperName, ctx, data); | ||
resultString += `if (${variable}) {`; | ||
resultString += `if (isArray(${variable})) {`; | ||
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)}, root: root, parents: ${parents}});`; | ||
resultString += '}else {'; | ||
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)}, root: root, parents: ${parents}});`; | ||
resultString += '}}'; | ||
} | ||
} | ||
if (execute.indexOf('@global') >= 0) { | ||
execute = parseJsVariable(execute, '@global', Template7.global); | ||
} | ||
if (execute.indexOf('../') >= 0) { | ||
execute = parseJsParents(execute, options.parents); | ||
} | ||
if (execute.indexOf('return') >= 0) { | ||
func = `(function(){${execute}})`; | ||
} else { | ||
func = `(function(){return (${execute})})`; | ||
} | ||
const condition = eval.call(this, func).call(this); | ||
if (condition) { | ||
return options.fn(this, options.data); | ||
} | ||
} | ||
resultString += '\nreturn r;})'; | ||
return options.inverse(this, options.data); | ||
}, | ||
}, | ||
}; | ||
Template7.prototype.helpers.js_compare = Template7.prototype.helpers.js_if; | ||
function t7(template, data) { | ||
if (arguments.length === 2) { | ||
let instance = new Template7(template); | ||
if (depth === 1) { | ||
t.compiled = eval.call(Template7Context, resultString); | ||
return t.compiled; | ||
} | ||
return resultString; | ||
} | ||
static get options() { | ||
return Template7Options; | ||
} | ||
static get partials() { | ||
return Template7Partials; | ||
} | ||
static get helpers() { | ||
return Template7Helpers; | ||
} | ||
} | ||
function Template7(...args) { | ||
const [template, data] = args; | ||
if (args.length === 2) { | ||
let instance = new Template7Class(template); | ||
const rendered = instance.compile()(data); | ||
@@ -531,29 +552,29 @@ instance = null; | ||
} | ||
return new Template7(template); | ||
return new Template7Class(template); | ||
} | ||
t7.registerHelper = function registerHelper(name, fn) { | ||
Template7.prototype.helpers[name] = fn; | ||
Template7.registerHelper = function registerHelper(name, fn) { | ||
Template7Class.helpers[name] = fn; | ||
}; | ||
t7.unregisterHelper = function unregisterHelper(name) { | ||
Template7.prototype.helpers[name] = undefined; | ||
delete Template7.prototype.helpers[name]; | ||
Template7.unregisterHelper = function unregisterHelper(name) { | ||
Template7Class.helpers[name] = undefined; | ||
delete Template7Class.helpers[name]; | ||
}; | ||
t7.registerPartial = function registerPartial(name, template) { | ||
Template7.prototype.partials[name] = { template }; | ||
Template7.registerPartial = function registerPartial(name, template) { | ||
Template7Class.partials[name] = { template }; | ||
}; | ||
t7.unregisterPartial = function unregisterPartial(name) { | ||
if (Template7.prototype.partials[name]) { | ||
Template7.prototype.partials[name] = undefined; | ||
delete Template7.prototype.partials[name]; | ||
Template7.unregisterPartial = function unregisterPartial(name) { | ||
if (Template7Class.partials[name]) { | ||
Template7Class.partials[name] = undefined; | ||
delete Template7Class.partials[name]; | ||
} | ||
}; | ||
t7.compile = function compile(template, options) { | ||
const instance = new Template7(template, options); | ||
Template7.compile = function compile(template, options) { | ||
const instance = new Template7Class(template, options); | ||
return instance.compile(); | ||
}; | ||
t7.options = Template7.prototype.options; | ||
t7.helpers = Template7.prototype.helpers; | ||
t7.partials = Template7.prototype.partials; | ||
Template7.options = Template7Class.options; | ||
Template7.helpers = Template7Class.helpers; | ||
Template7.partials = Template7Class.partials; | ||
export default t7; | ||
export default Template7; |
275
gulpfile.js
@@ -1,152 +0,145 @@ | ||
(function(){ | ||
'use strict'; | ||
var gulp = require('gulp'), | ||
connect = require('gulp-connect'), | ||
open = require('gulp-open'), | ||
rename = require('gulp-rename'), | ||
header = require('gulp-header'), | ||
path = require('path'), | ||
uglify = require('gulp-uglify'), | ||
sourcemaps = require('gulp-sourcemaps'), | ||
rollup = require('rollup-stream'), | ||
buble = require('rollup-plugin-buble'), | ||
source = require('vinyl-source-stream'), | ||
buffer = require('vinyl-buffer'), | ||
paths = { | ||
root: './', | ||
build: 'build/', | ||
dist: 'dist/', | ||
demo: 'demo/', | ||
source: 'src/', | ||
}, | ||
t7 = { | ||
filename: 'template7', | ||
pkg: require('./package.json'), | ||
banner: [ | ||
'/**', | ||
' * Template7 <%= pkg.version %>', | ||
' * <%= pkg.description %>', | ||
' * ', | ||
' * <%= pkg.homepage %>', | ||
' * ', | ||
' * Copyright <%= date.year %>, <%= pkg.author %>', | ||
' * The iDangero.us', | ||
' * http://www.idangero.us/', | ||
' * ', | ||
' * Licensed under <%= pkg.license.join(" & ") %>', | ||
' * ', | ||
' * Released on: <%= date.month %> <%= date.day %>, <%= date.year %>', | ||
' */', | ||
''].join('\n'), | ||
date: { | ||
year: new Date().getFullYear(), | ||
month: ('January February March April May June July August September October November December').split(' ')[new Date().getMonth()], | ||
day: new Date().getDate() | ||
} | ||
}; | ||
const gulp = require('gulp'); | ||
const connect = require('gulp-connect'); | ||
const open = require('gulp-open'); | ||
const rename = require('gulp-rename'); | ||
const header = require('gulp-header'); | ||
const uglify = require('gulp-uglify'); | ||
const sourcemaps = require('gulp-sourcemaps'); | ||
const rollup = require('rollup-stream'); | ||
const buble = require('rollup-plugin-buble'); | ||
const source = require('vinyl-source-stream'); | ||
const buffer = require('vinyl-buffer'); | ||
// Build | ||
gulp.task('build', function (cb) { | ||
rollup({ | ||
entry: './src/template7.js', | ||
plugins: [buble()], | ||
format: 'umd', | ||
moduleName: 'Template7', | ||
useStrict: true, | ||
sourceMap: true | ||
}) | ||
.pipe(source('template7.js', './src')) | ||
.pipe(buffer()) | ||
.pipe(sourcemaps.init({loadMaps: true})) | ||
.pipe(sourcemaps.write('./')) | ||
.pipe(gulp.dest('./build/')) | ||
.on('end', function () { | ||
cb(); | ||
}); | ||
}); | ||
function umd(cb) { | ||
rollup({ | ||
entry: './src/template7.js', | ||
plugins: [buble()], | ||
format: 'umd', | ||
moduleName: 'Template7', | ||
useStrict: true, | ||
sourceMap: true | ||
}) | ||
const paths = { | ||
root: './', | ||
build: 'build/', | ||
dist: 'dist/', | ||
demo: 'demo/', | ||
source: 'src/', | ||
}; | ||
const t7 = { | ||
filename: 'template7', | ||
pkg: require('./package.json'), | ||
banner: [ | ||
'/**', | ||
' * Template7 <%= pkg.version %>', | ||
' * <%= pkg.description %>', | ||
' * ', | ||
' * <%= pkg.homepage %>', | ||
' * ', | ||
' * Copyright <%= date.year %>, <%= pkg.author %>', | ||
' * The iDangero.us', | ||
' * http://www.idangero.us/', | ||
' * ', | ||
' * Licensed under <%= pkg.license.join(" & ") %>', | ||
' * ', | ||
' * Released on: <%= date.month %> <%= date.day %>, <%= date.year %>', | ||
' */', | ||
''].join('\n'), | ||
date: { | ||
year: new Date().getFullYear(), | ||
month: ('January February March April May June July August September October November December').split(' ')[new Date().getMonth()], | ||
day: new Date().getDate(), | ||
}, | ||
}; | ||
// Build | ||
gulp.task('build', (cb) => { | ||
rollup({ | ||
input: './src/template7.js', | ||
plugins: [buble()], | ||
format: 'umd', | ||
name: 'Template7', | ||
strict: true, | ||
sourcemap: true, | ||
}) | ||
.pipe(source('template7.js', './src')) | ||
.pipe(buffer()) | ||
.pipe(sourcemaps.init({loadMaps: true})) | ||
.pipe(header(t7.banner, { | ||
pkg: t7.pkg, | ||
date: t7.date | ||
})) | ||
.pipe(sourcemaps.init({ loadMaps: true })) | ||
.pipe(sourcemaps.write('./')) | ||
.pipe(gulp.dest('./dist/')) | ||
.on('end', function () { | ||
gulp.src('./dist/template7.js') | ||
.pipe(sourcemaps.init()) | ||
.pipe(uglify()) | ||
.pipe(header(t7.banner, { | ||
pkg: t7.pkg, | ||
date: t7.date | ||
})) | ||
.pipe(rename('template7.min.js')) | ||
.pipe(sourcemaps.write('./')) | ||
.pipe(gulp.dest('./dist/')) | ||
.on('end', function () { | ||
if (cb) cb(); | ||
}); | ||
.pipe(gulp.dest('./build/')) | ||
.on('end', () => { | ||
cb(); | ||
}); | ||
} | ||
function es(cb) { | ||
rollup({ | ||
entry: './src/template7.js', | ||
format: 'es', | ||
moduleName: 'Template7', | ||
useStrict: true, | ||
}) | ||
.pipe(source('template7.js', './src')) | ||
.pipe(buffer()) | ||
.pipe(header(t7.banner, { | ||
pkg: t7.pkg, | ||
date: t7.date | ||
})) | ||
.pipe(rename('template7.module.js')) | ||
.pipe(gulp.dest('./dist/')) | ||
.on('end', function () { | ||
if (cb) cb(); | ||
}); | ||
} | ||
// Dist | ||
gulp.task('dist', function (cb) { | ||
var cbs = 0; | ||
umd(function () { | ||
cbs += 1; | ||
if (cbs === 2) cb(); | ||
}); | ||
es(function () { | ||
cbs += 1; | ||
if (cbs === 2) cb(); | ||
}); | ||
}); | ||
function umd(cb) { | ||
rollup({ | ||
input: './src/template7.js', | ||
plugins: [buble()], | ||
format: 'umd', | ||
name: 'Template7', | ||
strict: true, | ||
sourcemap: true, | ||
}) | ||
.pipe(source('template7.js', './src')) | ||
.pipe(buffer()) | ||
.pipe(sourcemaps.init({ loadMaps: true })) | ||
.pipe(header(t7.banner, { | ||
pkg: t7.pkg, | ||
date: t7.date, | ||
})) | ||
.pipe(sourcemaps.write('./')) | ||
.pipe(gulp.dest('./dist/')) | ||
.on('end', () => { | ||
gulp.src('./dist/template7.js') | ||
.pipe(sourcemaps.init()) | ||
.pipe(uglify()) | ||
.pipe(header(t7.banner, { | ||
pkg: t7.pkg, | ||
date: t7.date, | ||
})) | ||
.pipe(rename('template7.min.js')) | ||
.pipe(sourcemaps.write('./')) | ||
.pipe(gulp.dest('./dist/')) | ||
.on('end', () => { | ||
if (cb) cb(); | ||
}); | ||
}); | ||
gulp.task('watch', function () { | ||
gulp.watch(paths.source + 'template7.js', [ 'build' ]); | ||
} | ||
function es(cb) { | ||
rollup({ | ||
input: './src/template7.js', | ||
format: 'es', | ||
name: 'Template7', | ||
strict: true, | ||
}) | ||
.pipe(source('template7.js', './src')) | ||
.pipe(buffer()) | ||
.pipe(header(t7.banner, { | ||
pkg: t7.pkg, | ||
date: t7.date, | ||
})) | ||
.pipe(rename('template7.module.js')) | ||
.pipe(gulp.dest('./dist/')) | ||
.on('end', () => { | ||
if (cb) cb(); | ||
}); | ||
} | ||
// Dist | ||
gulp.task('dist', (cb) => { | ||
let cbs = 0; | ||
umd(() => { | ||
cbs += 1; | ||
if (cbs === 2) cb(); | ||
}); | ||
es(() => { | ||
cbs += 1; | ||
if (cbs === 2) cb(); | ||
}); | ||
}); | ||
gulp.task('connect', function () { | ||
return connect.server({ | ||
root: [ paths.root ], | ||
livereload: true, | ||
port:'3000' | ||
}); | ||
}); | ||
gulp.task('watch', () => { | ||
gulp.watch('./src/*.js', ['build']); | ||
}); | ||
gulp.task('open', function () { | ||
return gulp.src(paths.demo + 'index.html').pipe(open({ uri: 'http://localhost:3000/' + paths.demo + 'index.html'})); | ||
}); | ||
gulp.task('connect', () => connect.server({ | ||
root: [paths.root], | ||
livereload: true, | ||
port: '3000', | ||
})); | ||
gulp.task('server', [ 'watch', 'connect', 'open' ]); | ||
gulp.task('open', () => gulp.src(`${paths.demo}index.html`).pipe(open({ uri: `http://localhost:3000/${paths.demo}index.html` }))); | ||
gulp.task('default', [ 'server' ]); | ||
})(); | ||
gulp.task('server', ['watch', 'connect', 'open']); | ||
gulp.task('default', ['server']); |
{ | ||
"name": "template7", | ||
"version": "1.2.5", | ||
"version": "1.3.0", | ||
"description": "Mobile-first HTML template engine", | ||
@@ -40,4 +40,4 @@ "main": "dist/template7.js", | ||
"eslint-config-airbnb": "^14.1.0", | ||
"eslint-config-airbnb-base": "^11.1.3", | ||
"eslint-plugin-import": "^2.2.0", | ||
"eslint-config-airbnb-base": "^11.3.2", | ||
"eslint-plugin-import": "^2.7.0", | ||
"eslint-plugin-jsx-a11y": "^4.0.0", | ||
@@ -47,9 +47,9 @@ "eslint-plugin-react": "^6.10.3", | ||
"gulp-connect": "^5.0.0", | ||
"gulp-header": "^1.8.8", | ||
"gulp-header": "^1.8.9", | ||
"gulp-open": "^2.0.0", | ||
"gulp-rename": "^1.2.2", | ||
"gulp-sourcemaps": "^2.6.0", | ||
"gulp-sourcemaps": "^2.6.1", | ||
"gulp-uglify": "^2.1.2", | ||
"rollup-plugin-buble": "^0.15.0", | ||
"rollup-stream": "^1.19.0", | ||
"rollup-stream": "^1.24.1", | ||
"vinyl-buffer": "^1.0.0", | ||
@@ -56,0 +56,0 @@ "vinyl-source-stream": "^1.1.0" |
@@ -1,510 +0,7 @@ | ||
let template7Context; | ||
if (typeof window !== 'undefined') { | ||
template7Context = window; | ||
} else if (typeof global !== 'undefined') { | ||
template7Context = global; | ||
} else { | ||
template7Context = this; | ||
} | ||
function isArray(arr) { | ||
return Array.isArray ? Array.isArray(arr) : Object.prototype.toString.apply(arr) === '[object Array]'; | ||
} | ||
function isFunction(func) { | ||
return typeof func === 'function'; | ||
} | ||
function escape(string) { | ||
return (typeof template7Context !== 'undefined' && template7Context.escape ? template7Context.escape(string) : string) | ||
.replace(/&/g, '&') | ||
.replace(/</g, '<') | ||
.replace(/>/g, '>') | ||
.replace(/"/g, '"'); | ||
} | ||
const quoteSingleRexExp = new RegExp('\'', 'g'); | ||
const quoteDoubleRexExp = new RegExp('"', 'g'); | ||
function helperToSlices(string) { | ||
const helperParts = string.replace(/[{}#}]/g, '').split(' '); | ||
const slices = []; | ||
let shiftIndex; | ||
let i; | ||
let j; | ||
for (i = 0; i < helperParts.length; i += 1) { | ||
let part = helperParts[i]; | ||
let blockQuoteRegExp; | ||
let openingQuote; | ||
if (i === 0) slices.push(part); | ||
else if (part.indexOf('"') === 0 || part.indexOf('\'') === 0) { | ||
blockQuoteRegExp = part.indexOf('"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp; | ||
openingQuote = part.indexOf('"') === 0 ? '"' : '\''; | ||
// Plain String | ||
if (part.match(blockQuoteRegExp).length === 2) { | ||
// One word string | ||
slices.push(part); | ||
} else { | ||
// Find closed Index | ||
shiftIndex = 0; | ||
for (j = i + 1; j < helperParts.length; j += 1) { | ||
part += ` ${helperParts[j]}`; | ||
if (helperParts[j].indexOf(openingQuote) >= 0) { | ||
shiftIndex = j; | ||
slices.push(part); | ||
break; | ||
} | ||
} | ||
if (shiftIndex) i = shiftIndex; | ||
} | ||
} else if (part.indexOf('=') > 0) { | ||
// Hash | ||
const hashParts = part.split('='); | ||
const hashName = hashParts[0]; | ||
let hashContent = hashParts[1]; | ||
if (!blockQuoteRegExp) { | ||
blockQuoteRegExp = hashContent.indexOf('"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp; | ||
openingQuote = hashContent.indexOf('"') === 0 ? '"' : '\''; | ||
} | ||
if (hashContent.match(blockQuoteRegExp).length !== 2) { | ||
shiftIndex = 0; | ||
for (j = i + 1; j < helperParts.length; j += 1) { | ||
hashContent += ` ${helperParts[j]}`; | ||
if (helperParts[j].indexOf(openingQuote) >= 0) { | ||
shiftIndex = j; | ||
break; | ||
} | ||
} | ||
if (shiftIndex) i = shiftIndex; | ||
} | ||
const hash = [hashName, hashContent.replace(blockQuoteRegExp, '')]; | ||
slices.push(hash); | ||
} else { | ||
// Plain variable | ||
slices.push(part); | ||
} | ||
} | ||
return slices; | ||
} | ||
function stringToBlocks(string) { | ||
const blocks = []; | ||
let i; | ||
let j; | ||
if (!string) return []; | ||
const stringBlocks = string.split(/({{[^{^}]*}})/); | ||
for (i = 0; i < stringBlocks.length; i += 1) { | ||
const block = stringBlocks[i]; | ||
if (block === '') continue; | ||
if (block.indexOf('{{') < 0) { | ||
blocks.push({ | ||
type: 'plain', | ||
content: block, | ||
}); | ||
} else { | ||
if (block.indexOf('{/') >= 0) { | ||
continue; | ||
} | ||
if (block.indexOf('{#') < 0 && block.indexOf(' ') < 0 && block.indexOf('else') < 0) { | ||
// Simple variable | ||
blocks.push({ | ||
type: 'variable', | ||
contextName: block.replace(/[{}]/g, ''), | ||
}); | ||
continue; | ||
} | ||
// Helpers | ||
const helperSlices = helperToSlices(block); | ||
let helperName = helperSlices[0]; | ||
const isPartial = helperName === '>'; | ||
const helperContext = []; | ||
const helperHash = {}; | ||
for (j = 1; j < helperSlices.length; j += 1) { | ||
const slice = helperSlices[j]; | ||
if (isArray(slice)) { | ||
// Hash | ||
helperHash[slice[0]] = slice[1] === 'false' ? false : slice[1]; | ||
} else { | ||
helperContext.push(slice); | ||
} | ||
} | ||
import Template7Class from './template7-class'; | ||
if (block.indexOf('{#') >= 0) { | ||
// Condition/Helper | ||
let helperContent = ''; | ||
let elseContent = ''; | ||
let toSkip = 0; | ||
let shiftIndex; | ||
let foundClosed = false; | ||
let foundElse = false; | ||
let depth = 0; | ||
for (j = i + 1; j < stringBlocks.length; j += 1) { | ||
if (stringBlocks[j].indexOf('{{#') >= 0) { | ||
depth += 1; | ||
} | ||
if (stringBlocks[j].indexOf('{{/') >= 0) { | ||
depth -= 1; | ||
} | ||
if (stringBlocks[j].indexOf(`{{#${helperName}`) >= 0) { | ||
helperContent += stringBlocks[j]; | ||
if (foundElse) elseContent += stringBlocks[j]; | ||
toSkip += 1; | ||
} else if (stringBlocks[j].indexOf(`{{/${helperName}`) >= 0) { | ||
if (toSkip > 0) { | ||
toSkip -= 1; | ||
helperContent += stringBlocks[j]; | ||
if (foundElse) elseContent += stringBlocks[j]; | ||
} else { | ||
shiftIndex = j; | ||
foundClosed = true; | ||
break; | ||
} | ||
} else if (stringBlocks[j].indexOf('else') >= 0 && depth === 0) { | ||
foundElse = true; | ||
} else { | ||
if (!foundElse) helperContent += stringBlocks[j]; | ||
if (foundElse) elseContent += stringBlocks[j]; | ||
} | ||
} | ||
if (foundClosed) { | ||
if (shiftIndex) i = shiftIndex; | ||
blocks.push({ | ||
type: 'helper', | ||
helperName, | ||
contextName: helperContext, | ||
content: helperContent, | ||
inverseContent: elseContent, | ||
hash: helperHash, | ||
}); | ||
} | ||
} else if (block.indexOf(' ') > 0) { | ||
if (isPartial) { | ||
helperName = '_partial'; | ||
if (helperContext[0]) helperContext[0] = `"${helperContext[0].replace(/"|'/g, '')}"`; | ||
} | ||
blocks.push({ | ||
type: 'helper', | ||
helperName, | ||
contextName: helperContext, | ||
hash: helperHash, | ||
}); | ||
} | ||
} | ||
} | ||
return blocks; | ||
} | ||
function parseJsVariable(expression, replace, object) { | ||
return expression.split(/([+ -*/^])/g).map((part) => { | ||
if (part.indexOf(replace) < 0) return part; | ||
if (!object) return JSON.stringify(''); | ||
let variable = object; | ||
if (part.indexOf(`${replace}.`) >= 0) { | ||
part.split(`${replace}.`)[1].split('.').forEach((partName) => { | ||
if (variable[partName]) variable = variable[partName]; | ||
else variable = 'undefined'; | ||
}); | ||
} | ||
return JSON.stringify(variable); | ||
}).join(''); | ||
} | ||
function parseJsParents(expression, parents) { | ||
return expression.split(/([+ -*^])/g).map((part) => { | ||
if (part.indexOf('../') < 0) return part; | ||
if (!parents || parents.length === 0) return JSON.stringify(''); | ||
const levelsUp = part.split('../').length - 1; | ||
const parentData = levelsUp > parents.length ? parents[parents.length - 1] : parents[levelsUp - 1]; | ||
let variable = parentData; | ||
const parentPart = part.replace(/..\//g, ''); | ||
parentPart.split('.').forEach((partName) => { | ||
if (variable[partName]) variable = variable[partName]; | ||
else variable = 'undefined'; | ||
}); | ||
return JSON.stringify(variable); | ||
}).join(''); | ||
} | ||
class Template7 { | ||
constructor(template) { | ||
const t = this; | ||
t.template = template; | ||
function getCompileVar(name, ctx, data = 'data_1') { | ||
let variable = ctx; | ||
let parts; | ||
let levelsUp = 0; | ||
let newDepth; | ||
if (name.indexOf('../') === 0) { | ||
levelsUp = name.split('../').length - 1; | ||
newDepth = variable.split('_')[1] - levelsUp; | ||
variable = `ctx_${newDepth >= 1 ? newDepth : 1}`; | ||
parts = name.split('../')[levelsUp].split('.'); | ||
} else if (name.indexOf('@global') === 0) { | ||
variable = 'Template7.global'; | ||
parts = name.split('@global.')[1].split('.'); | ||
} else if (name.indexOf('@root') === 0) { | ||
variable = 'root'; | ||
parts = name.split('@root.')[1].split('.'); | ||
} else { | ||
parts = name.split('.'); | ||
} | ||
for (let i = 0; i < parts.length; i += 1) { | ||
const part = parts[i]; | ||
if (part.indexOf('@') === 0) { | ||
let dataLevel = data.split('_')[1]; | ||
if (levelsUp > 0) { | ||
dataLevel = newDepth; | ||
} | ||
if (i > 0) { | ||
variable += `[(data_${dataLevel} && data_${dataLevel}.${part.replace('@', '')})]`; | ||
} else { | ||
variable = `(data_${dataLevel} && data_${dataLevel}.${part.replace('@', '')})`; | ||
} | ||
} else if (isFinite(part)) { | ||
variable += `[${part}]`; | ||
} else if (part === 'this' || part.indexOf('this.') >= 0 || part.indexOf('this[') >= 0 || part.indexOf('this(') >= 0) { | ||
variable = part.replace('this', ctx); | ||
} else { | ||
variable += `.${part}`; | ||
} | ||
} | ||
return variable; | ||
} | ||
function getCompiledArguments(contextArray, ctx, data) { | ||
const arr = []; | ||
for (let i = 0; i < contextArray.length; i += 1) { | ||
if (/^['"]/.test(contextArray[i])) arr.push(contextArray[i]); | ||
else if (/^(true|false|\d+)$/.test(contextArray[i])) arr.push(contextArray[i]); | ||
else { | ||
arr.push(getCompileVar(contextArray[i], ctx, data)); | ||
} | ||
} | ||
return arr.join(', '); | ||
} | ||
function compile(template = t.template, depth = 1) { | ||
if (typeof template !== 'string') { | ||
throw new Error('Template7: Template must be a string'); | ||
} | ||
const blocks = stringToBlocks(template); | ||
const ctx = `ctx_${depth}`; | ||
const data = `data_${depth}`; | ||
if (blocks.length === 0) { | ||
return function empty() { return ''; }; | ||
} | ||
function getCompileFn(block, newDepth) { | ||
if (block.content) return compile(block.content, newDepth); | ||
return function empty() { return ''; }; | ||
} | ||
function getCompileInverse(block, newDepth) { | ||
if (block.inverseContent) return compile(block.inverseContent, newDepth); | ||
return function empty() { return ''; }; | ||
} | ||
let resultString = ''; | ||
if (depth === 1) { | ||
resultString += `(function (${ctx}, ${data}, root) {\n`; | ||
} else { | ||
resultString += `(function (${ctx}, ${data}) {\n`; | ||
} | ||
if (depth === 1) { | ||
resultString += 'function isArray(arr){return Object.prototype.toString.apply(arr) === \'[object Array]\';}\n'; | ||
resultString += 'function isFunction(func){return (typeof func === \'function\');}\n'; | ||
resultString += 'function c(val, ctx) {if (typeof val !== "undefined" && val !== null) {if (isFunction(val)) {return val.call(ctx);} else return val;} else return "";}\n'; | ||
resultString += 'root = root || ctx_1 || {};\n'; | ||
} | ||
resultString += 'var r = \'\';\n'; | ||
let i; | ||
for (i = 0; i < blocks.length; i += 1) { | ||
const block = blocks[i]; | ||
// Plain block | ||
if (block.type === 'plain') { | ||
resultString += `r +='${(block.content).replace(/\r/g, '\\r').replace(/\n/g, '\\n').replace(/'/g, '\\' + '\'')}';`; | ||
continue; | ||
} | ||
let variable; | ||
let compiledArguments; | ||
// Variable block | ||
if (block.type === 'variable') { | ||
variable = getCompileVar(block.contextName, ctx, data); | ||
resultString += `r += c(${variable}, ${ctx});`; | ||
} | ||
// Helpers block | ||
if (block.type === 'helper') { | ||
let parents; | ||
if (ctx !== 'ctx_1') { | ||
const level = ctx.split('_')[1]; | ||
let parentsString = `ctx_${level - 1}`; | ||
for (let j = level - 2; j >= 1; j -= 1) { | ||
parentsString += `, ctx_${j}`; | ||
} | ||
parents = `[${parentsString}]`; | ||
} else { | ||
parents = `[${ctx}]`; | ||
} | ||
if (block.helperName in t.helpers) { | ||
compiledArguments = getCompiledArguments(block.contextName, ctx, data); | ||
resultString += `r += (Template7.helpers.${block.helperName}).call(${ctx}, ${compiledArguments && (`${compiledArguments}, `)}{hash:${JSON.stringify(block.hash)}, data: ${data} || {}, fn: ${getCompileFn(block, depth + 1)}, inverse: ${getCompileInverse(block, depth + 1)}, root: root, parents: ${parents}});`; | ||
} else if (block.contextName.length > 0) { | ||
throw new Error(`Template7: Missing helper: "${block.helperName}"`); | ||
} else { | ||
variable = getCompileVar(block.helperName, ctx, data); | ||
resultString += `if (${variable}) {`; | ||
resultString += `if (isArray(${variable})) {`; | ||
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)}, root: root, parents: ${parents}});`; | ||
resultString += '}else {'; | ||
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)}, root: root, parents: ${parents}});`; | ||
resultString += '}}'; | ||
} | ||
} | ||
} | ||
resultString += '\nreturn r;})'; | ||
return eval.call(template7Context, resultString); | ||
} | ||
t.compile = function _compile(template) { | ||
if (!t.compiled) { | ||
t.compiled = compile(template); | ||
} | ||
return t.compiled; | ||
}; | ||
} | ||
} | ||
Template7.prototype = { | ||
options: {}, | ||
partials: {}, | ||
helpers: { | ||
_partial(partialName, options) { | ||
const p = Template7.prototype.partials[partialName]; | ||
if (!p || (p && !p.template)) return ''; | ||
if (!p.compiled) { | ||
p.compiled = new Template7(p.template).compile(); | ||
} | ||
const ctx = this; | ||
for (const hashName in options.hash) { | ||
ctx[hashName] = options.hash[hashName]; | ||
} | ||
return p.compiled(ctx, options.data, options.root); | ||
}, | ||
escape(context, options) { | ||
if (typeof context !== 'string') { | ||
throw new Error('Template7: Passed context to "escape" helper should be a string'); | ||
} | ||
return escape(context); | ||
}, | ||
if(context, options) { | ||
let ctx = context; | ||
if (isFunction(ctx)) { ctx = ctx.call(this); } | ||
if (ctx) { | ||
return options.fn(this, options.data); | ||
} | ||
return options.inverse(this, options.data); | ||
}, | ||
unless(context, options) { | ||
let ctx = context; | ||
if (isFunction(ctx)) { ctx = ctx.call(this); } | ||
if (!ctx) { | ||
return options.fn(this, options.data); | ||
} | ||
return options.inverse(this, options.data); | ||
}, | ||
each(context, options) { | ||
let ctx = context; | ||
let ret = ''; | ||
let i = 0; | ||
if (isFunction(ctx)) { ctx = ctx.call(this); } | ||
if (isArray(ctx)) { | ||
if (options.hash.reverse) { | ||
ctx = ctx.reverse(); | ||
} | ||
for (i = 0; i < ctx.length; i += 1) { | ||
ret += options.fn(ctx[i], { first: i === 0, last: i === ctx.length - 1, index: i }); | ||
} | ||
if (options.hash.reverse) { | ||
ctx = ctx.reverse(); | ||
} | ||
} else { | ||
for (const key in ctx) { | ||
i += 1; | ||
ret += options.fn(ctx[key], { key }); | ||
} | ||
} | ||
if (i > 0) return ret; | ||
return options.inverse(this); | ||
}, | ||
with(context, options) { | ||
let ctx = context; | ||
if (isFunction(ctx)) { ctx = context.call(this); } | ||
return options.fn(ctx); | ||
}, | ||
join(context, options) { | ||
let ctx = context; | ||
if (isFunction(ctx)) { ctx = ctx.call(this); } | ||
return ctx.join(options.hash.delimiter || options.hash.delimeter); | ||
}, | ||
js(expression, options) { | ||
const data = options.data; | ||
let func; | ||
let execute = expression; | ||
('index first last key').split(' ').forEach((prop) => { | ||
if (typeof data[prop] !== 'undefined') { | ||
const re1 = new RegExp(`this.@${prop}`, 'g'); | ||
const re2 = new RegExp(`@${prop}`, 'g'); | ||
execute = execute | ||
.replace(re1, JSON.stringify(data[prop])) | ||
.replace(re2, JSON.stringify(data[prop])); | ||
} | ||
}); | ||
if (options.root && execute.indexOf('@root') >= 0) { | ||
execute = parseJsVariable(execute, '@root', options.root); | ||
} | ||
if (execute.indexOf('@global') >= 0) { | ||
execute = parseJsVariable(execute, '@global', template7Context.Template7.global); | ||
} | ||
if (execute.indexOf('../') >= 0) { | ||
execute = parseJsParents(execute, options.parents); | ||
} | ||
if (execute.indexOf('return') >= 0) { | ||
func = `(function(){${execute}})`; | ||
} else { | ||
func = `(function(){return (${execute})})`; | ||
} | ||
return eval.call(this, func).call(this); | ||
}, | ||
js_if(expression, options) { | ||
const data = options.data; | ||
let func; | ||
let execute = expression; | ||
('index first last key').split(' ').forEach((prop) => { | ||
if (typeof data[prop] !== 'undefined') { | ||
const re1 = new RegExp(`this.@${prop}`, 'g'); | ||
const re2 = new RegExp(`@${prop}`, 'g'); | ||
execute = execute | ||
.replace(re1, JSON.stringify(data[prop])) | ||
.replace(re2, JSON.stringify(data[prop])); | ||
} | ||
}); | ||
if (options.root && execute.indexOf('@root') >= 0) { | ||
execute = parseJsVariable(execute, '@root', options.root); | ||
} | ||
if (execute.indexOf('@global') >= 0) { | ||
execute = parseJsVariable(execute, '@global', Template7.global); | ||
} | ||
if (execute.indexOf('../') >= 0) { | ||
execute = parseJsParents(execute, options.parents); | ||
} | ||
if (execute.indexOf('return') >= 0) { | ||
func = `(function(){${execute}})`; | ||
} else { | ||
func = `(function(){return (${execute})})`; | ||
} | ||
const condition = eval.call(this, func).call(this); | ||
if (condition) { | ||
return options.fn(this, options.data); | ||
} | ||
return options.inverse(this, options.data); | ||
}, | ||
}, | ||
}; | ||
Template7.prototype.helpers.js_compare = Template7.prototype.helpers.js_if; | ||
function t7(template, data) { | ||
if (arguments.length === 2) { | ||
let instance = new Template7(template); | ||
function Template7(...args) { | ||
const [template, data] = args; | ||
if (args.length === 2) { | ||
let instance = new Template7Class(template); | ||
const rendered = instance.compile()(data); | ||
@@ -514,29 +11,29 @@ instance = null; | ||
} | ||
return new Template7(template); | ||
return new Template7Class(template); | ||
} | ||
t7.registerHelper = function registerHelper(name, fn) { | ||
Template7.prototype.helpers[name] = fn; | ||
Template7.registerHelper = function registerHelper(name, fn) { | ||
Template7Class.helpers[name] = fn; | ||
}; | ||
t7.unregisterHelper = function unregisterHelper(name) { | ||
Template7.prototype.helpers[name] = undefined; | ||
delete Template7.prototype.helpers[name]; | ||
Template7.unregisterHelper = function unregisterHelper(name) { | ||
Template7Class.helpers[name] = undefined; | ||
delete Template7Class.helpers[name]; | ||
}; | ||
t7.registerPartial = function registerPartial(name, template) { | ||
Template7.prototype.partials[name] = { template }; | ||
Template7.registerPartial = function registerPartial(name, template) { | ||
Template7Class.partials[name] = { template }; | ||
}; | ||
t7.unregisterPartial = function unregisterPartial(name) { | ||
if (Template7.prototype.partials[name]) { | ||
Template7.prototype.partials[name] = undefined; | ||
delete Template7.prototype.partials[name]; | ||
Template7.unregisterPartial = function unregisterPartial(name) { | ||
if (Template7Class.partials[name]) { | ||
Template7Class.partials[name] = undefined; | ||
delete Template7Class.partials[name]; | ||
} | ||
}; | ||
t7.compile = function compile(template, options) { | ||
const instance = new Template7(template, options); | ||
Template7.compile = function compile(template, options) { | ||
const instance = new Template7Class(template, options); | ||
return instance.compile(); | ||
}; | ||
t7.options = Template7.prototype.options; | ||
t7.helpers = Template7.prototype.helpers; | ||
t7.partials = Template7.prototype.partials; | ||
Template7.options = Template7Class.options; | ||
Template7.helpers = Template7Class.helpers; | ||
Template7.partials = Template7Class.partials; | ||
export default t7; | ||
export default Template7; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
159890
19
1937
4