From d365e3f3494a843b3b0cde8dc9fcc91545812b6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Dematt=C3=A9?= Date: Sun, 12 Jan 2025 12:41:53 +0100 Subject: [PATCH] initial commit --- README.md | 166 +++---- schnauzer.js | 1055 +++++++++++++++++++++++------------------- schnauzer.min.js | 4 +- schnauzer.min.js.map | 2 +- 4 files changed, 650 insertions(+), 577 deletions(-) diff --git a/README.md b/README.md index 7fd3bb2..e8d1270 100644 --- a/README.md +++ b/README.md @@ -1,50 +1,65 @@ -# {{schnauzer.js}} - (almost) Logic-less templates with JavaScript +# {{schnauzer.js}} - Handlebars templates with JavaScript -[Schanuzer](http://github.com/PitPik/schnauzer) is largely compatible with Mustache and Handlebars templates. In most cases it is possible to swap out Mustache or Handlebars with Schanuzer and continue using your current templates. +Schanuzer is a Handlebars parser/renderer that lets you build **semantic templates** effectively with no frustration. -Schanuzer is also very small and fast. It has the power of Handlebars but is almost the size of Mustage (12.1KB minified, ~4.89KB gZip) and therefore also perfectly suitable for mobile applications. -Renderin with Schnauzer is about ~33% faster than with Handlebars, when using inline partials, up to 10x faster. Parsing is also blasting fast, almost as fast as rendering. +Schanuzer is largely compatible with Mustache and Handlebars templates. In most cases it is possible to swap out Mustache or Handlebars with Schanuzer and continue using your current templates. + +Schanuzer is also very small and fast. It has the power of Handlebars but is almost the size of Mustage (10.90KB minified, ~4.6KB compressed) and therefore also perfectly suitable for mobile applications. +Rendering with Schnauzer is about ~33% faster than Handlebars, and parsing is around as fast a rendering. ## Where to use schnauzer.js? -You can use schnauzer.js to render templates anywhere you can use JavaScript. This includes web browsers, server-side environments such as [node](http://nodejs.org/), and [CouchDB](http://couchdb.apache.org/) views. +You can use schnauzer.js to render templates anywhere you can use JavaScript. This includes web browsers (even Internet Explorer), server-side environments such as [node](http://nodejs.org/), and [CouchDB](http://couchdb.apache.org/) views. schnauzer.js ships with support for both the [CommonJS](http://www.commonjs.org/) module API and the [Asynchronous Module Definition](https://github.com/amdjs/amdjs-api/wiki/AMD) API, or AMD. -### Dynamic rendering +### Dynamic rendering, keeps you template alive. -Other than handlebars, schnauzer has 2 optional functions that get triggered with every single tag that gets rendered so the template can be kept alive even after the first rendering. -`renderHook()` and `loopHelper()`. With those functions it's possible to keep track of all the rendered variables and rendering functions including a special character `%` set infront of every variable. This way, when used in the DOM, it's possible to overwrite parts of the rendered template after it was first rendered without having to re-render the whole template. -This is perfect for developing MVC like libraries/frameworks that need to partialy update HTML on the fly. +Schnauzer has 2 optional functions that get triggered with every single tag that gets rendered so the template can be kept alive even after the initial rendering. +`renderHook()` and `loopHelper()`. With those functions it's possible to keep track of all the rendered variables and rendering functions including a special character `%` set in front of every variable. This way, when used in the DOM, it's possible to overwrite parts of the rendered template after it was first rendered without having to re-render the whole template. +This is perfect for developing MVC like libraries/frameworks that need to partially update HTML on the fly. * * * -## handlebars.js [not present any more.] - -(Handlebars facade for Schnauzer) ... maybe back one day. - ## Usage Below is a quick example how to use schnauzer.js: ```js -var viewModel = { - title: "Joe", - calc: function ($1) { - return parseFloat($1) * 0.9; - } -}; - -var output = new Schnauzer("{{title}} spends {{calc 200}}").render(viewModel); +var template = ` +

Hello, my name is {{name}}. + I am from {{hometown}}. + I have + {{kids.length}} kids: +

+ +`; +var schnauzer = new Schnauzer(template); +var data = { + "name": "Peter", + "hometown": "Somewhere, CA", + "kids": [ + {"name": "Jimmy", "age": "7"}, + {"name": "Sally", "age": "4"} + ]}; +var result = schnauzer.render(data); + +// Would render: +//

Hello, my name is Peter. I am from Somewhere, CA. I have 2 kids:

+// ``` -In this example `Schnauzer()` is initialized with the template as first argument (options would be the second optional argument) and the `render()` function that takes one parameters: the `viewModel` object that contains the data and code needed to render the template. +In this example `Schnauzer()` is initialised with the template as first argument (options would be the second optional argument) and `render()` that takes one parameters: the `viewModel` object that contains the data and code needed to render the template. ## API ```js -new Schnauzer(templateOrOptions: String | { [key: String]: any }, options?: { [key: String]: any }) { - tags: ['{{', '}}'], // used tags: default is {{ }} +new Schnauzer(templateOrOptions?: String | { [key: String]: any }, options?: { [key: String]: any }) { entityMap: { // characters to be escaped '&': '&', '<': '<', @@ -56,25 +71,24 @@ new Schnauzer(templateOrOptions: String | { [key: String]: any }, options?: { [k '=': '=' }, escapeHTML: true, // if false, Schnauzer renders like all tags are set to {{{ }}} - helpers: { [name: String]: Function }, // short-cut for registerHelper - partials: { [name: String]: String | Function }, // short-cut for registerPartial + helpers: { [name: String]: Function }, // short-cut for registerHelper() + partials: { [name: String]: String | [] }, // short-cut for registerPartial() self: 'self', // name of initial partial limitPartialScope: true, // sets limiting of scope inside partials (like in HBS) + strictArguments: true, // sets all arguments from a helper automatically to strict (model value before helper) renderHook: Function // called every time an inline | block element renders - loopHelper: Function // Loop cycle callback for Array | Object inside #each + loopHelper: Function // Loop cycle callback for Array | Object inside #each or #myArray }) -.render(data: { [key: String]: any }, extraData: { [key: String]: any }): string -.parse(text: String): Function // returns a partial for re-cycling, re-usage in other instance +.render(data: { [key: String]: any }, extraData: any): string +.parse(text: String): [] // returns a partial for re-cycling, re-usage in other instance .registerHelper(name: String, func: Function): void .unregisterHelper(name: String): void -.registerPartial(name: String, html: String | Function): Function // Function: pre-parsed +.registerPartial(name: String, html: String | []): [] // parsed tree .unregisterPartial(name: String): void -.setTags(tags: [String, String]): void -.escapeExpression(string): String // returns escaped text according to entityMap ``` -`parse()` is only needed if the template was not passed to `Schnauzer()` in the first place. This might be handy if you're not sure if this template will ever be used... +`parse()` is only needed if the template was not passed to `new Schnauzer()` in the first place. This might be handy if you're not sure if this template will ever be used... -In `render(data, extraData)` you can pass some extra data source needed for parsing your template. If renderer doesn't find the required data in `data` then it looks inside `extraData`. `extraData` can be and opbject or an array of objects. +In `render(data, extraData)` you can pass some extra data source needed for parsing your template. If renderer doesn't find the required data in `data` then it looks inside `extraData`. This can be very handy if you have, for example, an array of links to render where the root of the link is always the same (stored in extraModel) but the end of the link is different (stored in the array). So you don't have to put the root inside evey item of the array. ```js @@ -95,76 +109,40 @@ var output = new Schnauzer('{{#links}}{{text}}{{ .render(data, extraData); ``` -#### Functions in helpers - -All the functions used inside the model or being registered or passed in options as helpers can be used as inline or block elements that have the same arguments and scope: +## Precompiling Templates +Schnauzer allows templates to be precompiled and included as a JSON tree rather than the Schnauzer template allowing for faster startup time. -```handlebars -{{#helper foo}}some text with {{meaning}}{{/helper}} -or inline -{{helper foo}} -``` ```js -var data = { - meaning: 'some more meaning', - foo: 'This would be', - helper: helper -} - -function helper([$1, $2,...]) { // can also be passed as option or registered via .registerHelper() - var args = []; - var options = arguments[arguments.length - 1]; - - for (var i = 0; i < arguments.length - 1; i++) { - args.push(arguments[i]); - } - - return $1 + ' ' + options.fn(this); -} -``` -In this case you would get "This would be some text with some more meaning" in the block and "This would be " if used as inline helper. -$1 etc. represent the String passed with the block (here "foo"). -```options.fn()``` is the text that was rendered if it was inside a block element (empty if inline usage), ```options.inverse()``` the block after an else (if exists, else undefined). - -Options inside helper functions work almost like with Handlebars: -```js - options: { - data: { root: {…}, scope, parent, first, last index, key, number, length }, - hash: {}, // keeps all the parameters as a hash - name: "", // name of the helper - fn?: ƒ (context, options), // only on block helpers; same as with Handlebars - inverse?: ƒ (context, options), // only on block helpers; same as with Handlebars - escapeExpression: ƒ(), // like Handlebars.escapeExpression - SafeString: ƒ(), // like Handlebars.SafeString - keys: ƒ(), // like window.Object.keys() - extend: ƒ(newObject, hostObject), // like Handlebars.Utils.extend - concat: ƒ(newArray, hostArray), // Concats 2 arrays - getDataDetails: ƒ(), // returns details of the data (arguments) - } -``` - -Inline helpers can be used for something like the following: - -```handlebars -{{today}} +var template = ` + {{#*inline 'myInlinePartial'}} + {{foo}} ... + {{/inline}} + + {{> myInlinePartial}} +`; +var schnauzer = new Schnauzer(template, { + partials: { another: 'Simple {{bar}}' } +}); ``` +This would produce 3 partial trees that can be found in `schnauzer.partials` and would look like: ```js -today: function() { - return new Date().toLocaleString(); +{ + another: [{…}, {…}], + myInlinePartial: [{…}, {…}], + self: [{…}, {…}, {…}] // main partial } ``` +You could now use `JSON.stringify()` to convert this to a text file. +When received by the browser as a regular JSON again it then can be registered back like `new Schnauzer({ partials: partials })` in one go for all 3 partials. +This explains also why `.registerPartial(name, template)` can receive an array as 2nd argument. You can do: `.registerPartial('another', another)` and pass the array containing the tree of the `another` partial. -## How Schnauzer templates works - -All basic features of Schnauzer are explained in the [Handlebars decumentation](https://handlebarsjs.com/guide/). +## How Schnauzer templates works -## Pre-parsing and Caching Templates +All basic features of Schnauzer are explained in the [Handlebars documentation](https://handlebarsjs.com/guide/). -By default, when schnauzer.js first parses a template, it builds a tree of currying functions that keeps all data cached. The currying functions not only already hold the parsed HTML snippets but also the right key to the JSON being passed so it can concatenate strings on the fly. The rendering functions are highly optimised therefore Schnauzer currently renders 1/3 faster than Handlebars. Parsing is about 10x faster. -### New in 2.x.x +### New in 3.x.x -The new version 2.x.x has a new parser that is faster, it renders faster than the previous major version (from 65ms down to 52ms on a standard comparison test with 500 runs: 16K template + 1k partial and quite a bit of data), uses a lot less memory and allowes a more flexible way of using variables within tags (no limits on characters). It has better support (API) for "active rendering" after 1st rendering. All Schnauzer functionalities are now supported to be altered through the new API (renderHook, loopHelper). The "activate" API doesn't compromise speed any more if not used so you can have 99.99% of the high speed parsing/rendering if used only as a one-time template-rendering engine. -Unfortunately the new parser is a bit bigger (1.02KB source) than the old one, but we profit now from more speed, less memory usage and more flexibility. +The new version 3.x.x is completely re-programmed, has a new parser that is 2.6 times faster than in version 2.x.x, renders faster than ever and uses less memory. It is now also possible to pre-compile. \ No newline at end of file diff --git a/schnauzer.js b/schnauzer.js index 8aba465..d9e6e30 100644 --- a/schnauzer.js +++ b/schnauzer.js @@ -1,33 +1,41 @@ -/**! @license schnauzer v2.0.8; Copyright (C) 2017-2023 by Peter Dematté */ +/**! @license schnauzer v3.0.0; Copyright (C) 2017-2025 by Peter Dematté */ (function(global, factory) { - if (typeof exports === 'object' && typeof module === 'object') module.exports = factory(); + if (typeof exports === 'object' && typeof module === 'object') + module.exports = factory(global); else if (typeof define === 'function' && define.amd) - define([], function() { return factory(); }, 'schnauzer'); - else if (typeof exports === 'object') exports['Schnauzer'] = factory(); - else global.Schnauzer = factory(); -}(this && this.window || global, function factory() { 'use strict'; + define([], function() { return factory(global); }, 'schnauzer'); + else if (typeof exports === 'object') exports['Schnauzer'] = factory(global); + else global.Schnauzer = factory(global); +}(this && this.window || global, function factory(global) { 'use strict'; -var getObjectKeys = Object.keys || function(obj) { +var getKeys = Object.keys || function(obj) { var keys = [], prop = ''; for (prop in obj) if (hasOwnProperty.call(obj, prop)) keys.push(prop); return keys; }; -var cloneObjectFn = function(obj, newObj, key) { newObj[key] = obj[key] }; -var cloneObject = function(newObj, obj) { - for (var key in obj) cloneObjectFn(obj, newObj, key); +var extendFn = function(obj, newObj, key) { newObj[key] = obj[key] }; +var extend = function(newObj, obj) { + for (var key in obj) extendFn(obj, newObj, key); return newObj; }; -var concatArrays = function(array, host) { return host.push.apply(host, array), host }; -var trims = { start: /^\s*/, all: /^\s*|\s*$/g, end: /\s*$/ }; +var templateError = function() { throw('Schnauzer Error: Incorrect template') }; +var console = global.console; +var trims = { start: /^\s+/, end: /\s+$/, whitespace: /\s+/ }; var Schnauzer = function(templateOrOptions, options) { - this.version = '2.0.8'; + this.version = '3.0.0'; this.partials = {}; - this.helpers = {}; - this.regexps = {}; - this.controls = { active: false, stop: false, loop: [] }; + this.helpers = { + lookup: lookupProperty, + log: function(options) { + for (var n = 0, l = arguments.length, args = []; n < l; n++) + if (n === l - 1) options = arguments[n]; else args.push(arguments[n]); + (console[options.hash['level']] || console.log).apply(console, args); + }, + }; + this.regex = { tags: null, entity: null }; + this.controls = { partialBlocks: [] }; this.options = { - tags: ['{{', '}}'], entityMap: { '&': '&', '<': '<', @@ -42,7 +50,8 @@ var Schnauzer = function(templateOrOptions, options) { partials: {}, self: 'self', escapeHTML: true, - limitPartialScope: true, // HBS style; new in v1.6.5 + limitPartialScope: true, + strictArguments: true, loopHelper: null, renderHook: null, }; @@ -50,26 +59,32 @@ var Schnauzer = function(templateOrOptions, options) { }; var initSchnauzer = function(_this, options, template) { - if (typeof template !== 'string') { options = template; template = '' } - options = cloneObject(_this.options, options); - switchTags(_this, options.tags); - _this.helpers = options.helpers; + if (typeof template !== 'string') { options = template; template = undefined } + options = extend(_this.options, options); + _this.regex.tags = /({{2,3})([#~^/!>*-]*)\s*([^~}]*)([~}]{2,4})/; + _this.regex.entity = new RegExp( + '[' + getKeys(_this.options.entityMap).join('') + ']', 'g' + ); + _this.helpers = extend(_this.helpers, options.helpers); _this.registerPartial(options.partials); if (template !== undefined) _this.parse(template); - delete options.helpers; delete options.partials; + delete options.helpers; + delete options.partials; }; -var HBSS = Schnauzer.SafeString = function(text) { this.string = text }; // WTF -HBSS.prototype.toString = HBSS.prototype.toHTML = function() { return '' + this.string }; -Schnauzer.getObjectKeys = getObjectKeys; Schnauzer.cloneObject = cloneObject; -Schnauzer.concatArrays = concatArrays; +var SafeString = function(text) { this.string = text }; +SafeString.prototype.toString = SafeString.prototype.toHTML = + function() { return '' + this.string }; Schnauzer.prototype = { render: function(data, extra) { - var helpers = createHelper(this, '', '', 0, data, null, [{ scope: data }]); - return [this.partials[this.options.self]({ blocks: {}, - extra: extra, scopes: [{ scope: data, helpers: helpers, level: [], values: null, alias: {} }], - }), this.controls.active = true][0]; + var helpers = createHelper(this, [{ context: data }], data); + var scopes = [{ context: data, helpers: helpers, vars: {} }]; + var partial = this.partials[this.options.self]; + + return render(this, partial, { + scopes: scopes, extra: extra || {}, $vars: {}, $alias: {}, + }); }, parse: function(txt) { return this.registerPartial(this.options.self, txt) }, registerHelper: function(name, helperFn) { @@ -79,37 +94,65 @@ Schnauzer.prototype = { unregisterHelper: function(name) { delete this.helpers[name] }, registerPartial: function(name, txt) { if (typeof name === 'string') return this.partials[name] = - this.partials[name] || (txt.constructor === Function ? txt : parseTags(this, txt, [])); + this.partials[name] || + (txt.constructor === Array ? txt : parseTags(this, txt)); for (var key in name) this.registerPartial(key, name[key]); }, unregisterPartial: function(name) { delete this.partials[name] }, - setTags: function(tags) { switchTags(this, tags) }, - escapeExpression: function(txt) { return escapeHtml(this, txt, true) }, }; return Schnauzer; -function switchTags(_this, tags) { - var tgs = (function(tags) { for (var n = tags.length; n--; ) { - tags[n] = '(' + tags[n] + ')'; - } return tags; })(tags[0] === '{{' ? ['{{2,3}', '[~}]{2,4}'] : tags); +function escapeHtml(_this, string, doEscape) { + return string == null ? '' : + string.constructor === SafeString ? string.toString() : + doEscape && _this.options.escapeHTML ? String(string).replace( + _this.regex.entity, + function(char) { return _this.options.entityMap[char] } + ) : string; +} - _this.regexps = { - tags: new RegExp(tgs[0] + '([#~^/!>*-]*)\\s*([^~}]*)' + tgs[1]), - entity: new RegExp('[' + getObjectKeys(_this.options.entityMap).join('') + ']', 'g') - }; +function lookupProperty(parent, propertyName) { + var out = parent[propertyName]; + + if (out == null) return out; + if (Object.prototype.hasOwnProperty.call(parent, propertyName)) return out; + return undefined; } // ---- render data helpers -function escapeHtml(_this, string, doEscape) { - return string == null ? '' : string.constructor === Schnauzer.SafeString ? string.string : - doEscape && _this.options.escapeHTML ? String(string).replace( - _this.regexps.entity, function(char) { return _this.options.entityMap[char] } - ) : string; +function addScope(model, value, partialContent) { + var scope = model.scopes[0]; + var sav = partialContent ? {} : null; + var vars = extend({}, model.$vars); + + if (partialContent) for (var key in scope.$vars) { + vars[key] = sav[key] = scope.$vars[key]; + scope.vars[key] = undefined; + } + + if (scope.$alias) for (var key in scope.$alias) + if (!model.$alias.hasOwnProperty(key)) model.$alias[key] = scope.vars[key]; + extend(vars, model.$alias); + + model.scopes.unshift({ + context: value === undefined ? {} : value, + helpers: scope.helpers, + vars: vars, + $alias: model.$alias, + $vars: model.$vars, + }); + model.$vars = {}; + model.$alias = {}; + + return function() { + model.scopes.shift(); + if (partialContent) for (var key in sav) scope.vars[key] = sav[key]; + }; } -function createHelper(_this, idx, key, len, value, parent, scopes) { +function createHelper(_this, scopes, value, parent, idx, key, len) { return len ? { '@index': idx, '@number': idx + 1, @@ -120,526 +163,578 @@ function createHelper(_this, idx, key, len, value, parent, scopes) { '@length': len, '@depth': _this.options.limitPartialScope ? undefined : scopes.length - 2, '@loop': parent, - '@parent': scopes[1].scope, - '@root': scopes[scopes.length - 1].scope, + '@parent': scopes[1].context, + '@root': scopes[scopes.length - 1].context, 'this': value, - '.': value, - } : { '@parent': parent, '@root': scopes[scopes.length - 1].scope, 'this': value, '.': value }; + } : { + '@parent': parent, + '@root': scopes[scopes.length - 1].context, + 'this': value, + }; } -function addScope(model, data, alias) { - var scopes = model.scopes; - var newLevel = model.alias ? [model.alias] : []; - var level = concatArrays(scopes[0].level, newLevel); - var values = model.values; - var prevAlias = scopes[1] ? cloneObject({}, scopes[1].alias) : {}; - - model.alias = null; model.values = null; - alias = alias ? cloneObject(prevAlias, alias) : prevAlias; - model.scopes = concatArrays(scopes, [{ - scope: data, helpers: scopes[0].helpers, level: level, values: values, alias: alias, - }]); - return function() { model.scopes = scopes }; -} - -function tweakScope(scope, data) { - var savedScope = scope.scope; - scope.scope = data || {}; - return function() { scope.scope = savedScope; }; -} - -function getDeepData(data, main, alias) { - if (main.value === '.' || main.value === 'this') return { value: data, variable: main }; - if (main.type !== 'key') return { value: main.value, variable: main }; - for (var n = main.path[0] === '@root' ? 1 : 0, l = main.path.length; n < l; n++) - if (!(data = data[main.path[n]])) return { variable: main }; - return { value: data[main.value], parent: data, variable: main, alias: alias || false }; -} - -function getAlias(level, main, scope, data) { - for (var n = 0, l = level.length; n < l; n++) { - data = getDeepData(level[n], main, true); - if (data.value !== undefined) { - if (scope = scope.alias[data.variable.value]) { - data.parent = scope.parent; - data.key = scope.key; - } - return data; - } - } - return { variable: main }; +function createAlias(main, model, data, out) { + if (main.name) { + if (main.name === 'includeZero') return out[0].zero = main.value; + model.$vars[main.name] = data.value; + data.alias = main.name; + } else for (var n = 0, l = main.alias.length; n < l; n++) + model.$alias[main.alias[n]] = out[n] ? out[n].value : undefined; } -function createAliasMap(key, scope, model, aliasKey, data) { - if (data.value === undefined || aliasKey === undefined) return; - if (!model[key]) model[key] = {}; - model[key][aliasKey] = data.value; - if (scope) scope.alias[aliasKey] = { parent: data.parent, key: data.variable.value }; +function createDataModel(main, context, isLoop) { + var key = main.value; + var type = main.type; + var isLiteral = type !== 'key' && type !== 'helper'; + var isThis = key === 'this'; + var hasValue = false; + var noParent = false; + + if (main.path.length) context = deepData(main, context, {}).parent; + hasValue = context && context[key] !== undefined || false; + noParent = isLiteral || isThis || !hasValue; + + return { + value: isThis ? context : isLiteral ? key : context && context[key], + type: isLiteral ? type : undefined, + parent: noParent ? undefined : context, + active: noParent || type === 'helper' ? 0 : main.active, + key: isLiteral ? '' : key, + alias: '', + args: [], + isLoop: isLoop || false, + helper: main.enclosed, + // zero: false, + }; } -function getData(_this, model, tagData, out) { - var vars = tagData.vars; - var trackData = !!_this.options.renderHook; +function deepData(main, context, data) { + var n = 0; + var l = main.path.length; + var value = null; - if (!vars) return out; + for ( ; n < l; n++) if (!(context = context[main.path[n]])) return data; + if ((value = context[main.value]) === undefined) return data; - for (var n = 0, l = vars.length, help, main = {}, scope = {}, data = {}, args = []; n < l; n++) { - main = vars[n]; - scope = !main.path || main.path[0] !== '@root' ? model.scopes[main.depth || 0] : - model.scopes[model.scopes.length - 1]; - if (!scope) { out.push(data); continue; } - data = { value: scope.helpers[main.value], variable: main, - parent: help = (main.value + '').charAt(0) === '@' ? scope.helpers : scope.scope }; + data.value = value; + data.parent = context; - if (data.value === undefined && scope.values) data = getAlias([scope.values], main, scope, data); - if (data.value === undefined && !main.isStrict) data = getAlias(scope.level, main, scope, data); - if (data.value === undefined) data = !main.helper ? getDeepData(scope.scope, main) : - { value: renderHelper(_this, args = getData(_this, model, main, []), model, main) }; - if (data.value === undefined && model.extra) data = getDeepData(model.extra, main); - if (data.value === undefined && help) data.parent = scope.helpers; + return data; +} - if (main.alias) createAliasMap('alias', trackData && scope, model, main.alias[0], data); - if (main.name) createAliasMap('values', trackData && scope, model, main.name, data); +function getHelperData(_this, model, data, main, isHelper) { + if (isHelper) main.helper = true; + data.args = getData(_this, { vars: main.args }, model); +} - data.type = data.value && data.value.constructor === Array ? 'array' : typeof data.value; - if (!data.variable) data.variable = main; // nested helper functions don't - if (trackData && main.helper) data.renderArgs = args; - if (trackData && _this.controls.loop[0]) data.loop = _this.controls.loop[0]; - out.push(data); +function getData(_this, tagData, model) { + var out = []; + var main = {}; + var scopes = model.scopes; + var scope = null; + var context = {}; + var data = {}; + var helper = null; + var alias = false; + var isLoop = tagData.helper === 'each'; + + for (var n = 0, l = tagData.vars.length; n < l; n++) { + main = tagData.vars[n]; + alias = !!main.name || !!main.alias.length; + scope = scopes[main.depth]; + if (!scope) { out.push(createDataModel(main, context)); continue; } + + if (!main.strict) helper = _this.helpers[main.value]; + if (helper && main.type !== 'string') main.type = 'helper'; + context = main.value[0] === '@' || (main.path[0] || '')[0] === '@' ? + scope.helpers : helper ? _this.helpers : scope.context; + + out.push(data = createDataModel(main, context, isLoop)); + if (main.type === 'helper') getHelperData(_this, model, data, main, !n); + if (!alias || data.value === undefined) deepData(main, scope.vars, data); + if (data.value === undefined) deepData(main, model.extra, data); + + if (!data.type) data.type = data.value && data.value.constructor === Array ? + 'array' : typeof data.value; + if (!n && data.type === 'array' && !tagData.helper) data.isLoop = true; + if (alias) createAlias(main, model, data, out); } - if (trackData && tagData.helper && !tagData.tag) tagData.renderFn = - function(newData) { return renderHelper(_this, newData, model, tagData) }; + return out; } -function checkObjectLength(main, helper, objKeys) { - var value = main.value; - var isObject = main.type === 'object'; - var go = helper === 'each' || helper === 'with' || (main.type === 'array' && - (helper === 'if' || helper === 'unless')); +function checkValue(main, value, helper, keys) { + var isEach = helper === 'each'; + var isIf = helper === 'if' || helper === 'unless'; + var isLiteral = main.type === 'number' || main.type === 'string'; + var isObject = main.type === 'object' && main.value !== null; - if (!go || value === undefined) return value; - if (isObject) objKeys.keys = getObjectKeys(value); - return isObject ? objKeys.keys.length && value : value.length && value; + if (!keys) keys = {}; + + return main.type === 'array' ? !!main.value.length : + isObject ? !isEach || !!(keys.keys = getKeys(main.value)).length : + main.zero && main.value === 0 ? true : + !isIf && isLiteral ? value !== undefined : !!value; } -function getHelperArgs(_this, model, tagData, data, newData, track) { - var save = null; - var name = tagData.helper ? tagData.helper.orig : ''; +// ---- helpers functions + +function scopeFn(_this, context, model, data, fnData) { + var resetScope = addScope(model, context); + var out = ''; + var scope = model.scopes[0]; + var savedContext = scope.context; + + if (!fnData.SafeString && fnData.data) for (var key in fnData.data) + model.scopes[0].vars['@' + key] = fnData.data[key]; + + scope.context = context; + out = render(_this, data, model); + scope.context = savedContext; + resetScope(); + + return out; +} + +function helperArgs(_this, tagData, main, model) { var helpers = model.scopes[0].helpers; - var children = tagData.children; var args = { - name: name, + name: main.key, + data: {}, hash: {}, - data: { root: helpers['@root'], scope: helpers['this'], parent: helpers['@parent'] }, - escapeExpression: function(txt) { return _this.escapeExpression(txt) }, - SafeString: Schnauzer.SafeString, - keys: getObjectKeys, - extend: cloneObject, - concat: concatArrays, - getDataDetails: function() { return data }, + lookupProperty: lookupProperty, + createFrame: function(data) { return extend({}, data)}, + escapeExpression: function(txt) { return escapeHtml(_this, txt, true) }, + SafeString: SafeString, }; + var item = null; - if (helpers['@length']) cloneObject(args.data, { loop: helpers['@loop'], depth: helpers['@depth'], - index: helpers['@index'], number: helpers['@number'], length: helpers['@length'], - first: helpers['@first'], last: helpers['@last'], key: helpers['@key'], odd: helpers['@odd'] - }); - for (var n = data.length; n--; ) { - if (data[n].variable.name) args.hash[data[n].variable.name] = data[n].value; - else newData.unshift(data[n].value); - } - if (children) { - args.fn = function(context) { - track.fnIdx = 0; if (track.checkFn) track.checkFn(0); - save = tweakScope(model.scopes[0], context); - return [ children[0].text + children[0].bodyFn(model), save() ][0]; + for (var key in helpers) if (key[0] === '@' && helpers[key] !== undefined) + args.data[key.substring(1)] = helpers[key]; + for (var n = main.args.length; n--; ) if (item = main.args[n], item.alias) + args.hash[item.alias] = item.value; + + if (tagData.block) { + args.fn = function(context, fnData) { + return scopeFn(_this, context, model, tagData.children, fnData || args); }; - args.inverse = children[1] && function(context) { - track.fnIdx = 1; if (track.checkFn) track.checkFn(1); - save = tweakScope(model.scopes[0], context); - return [ children[1].text + children[1].bodyFn(model), save() ][0]; - } || function noop() { return '' }; + args.inverse = tagData.alts[0] ? function(context, fnData) { + var tags = tagData.alts; + var altTag = tags[1] ? extend({}, tags[0]) : null; + + if (altTag) { altTag.alts = tags.slice(1); tags = [altTag]; } + return scopeFn(_this, context, model, tags, fnData || args); + } : function noop() { return ''; }; } + return args; } -function getHelperFn(_this, model, tagData) { - var scope = model.scopes[tagData.helper.depth || 0].scope; - var helperFn = _this.helpers[tagData.helper.orig]; +// ---- render blocks/inlines helpers (std. HBS helpers) - return tagData.helperFn || (tagData.helper.isStrict || !helperFn ? - getDeepData(scope, tagData.helper).value : helperFn); -} +function renderPartial(_this, data, model, tagData) { + var scopes = model.scopes; + var out = ''; + var main = data[0]; + var name = main.key || main.value; + var key = main.helper ? renderHelper(_this, tagData, main, model) : name; + var content = key === '@partial-block'; + var partialBlocks = _this.controls.partialBlocks; + var children = content ? partialBlocks[0] : tagData.children; + var partial = content ? null : _this.partials[key]; + var limit = _this.options.limitPartialScope; + var scope = data[1] && !data[1].alias ? data[1].value : scopes[0].context; + var resetScope = addScope(model, scope, !partial); + + if (!tagData.block || !partial) out = render(_this, children, model); + if (tagData.block) partialBlocks.unshift(tagData.children); + + if (limit) model.scopes = [scopes[0]]; + if (partial) out += render(_this, partial, model); + if (limit) model.scopes = scopes; + if (tagData.block) partialBlocks.shift(); + if (resetScope) resetScope(); -// ---- render blocks/inlines helpers (std. HBS helpers) + return out; +} -function renderHelper(_this, data, model, tagData, track) { - var helperFn = !tagData.helper && tagData.children && - (data[0] ? renderConditions : undefined) || tagData.helperFn; - var newData = []; +function renderWith(_this, value, model, tagData) { var out = ''; - var restore = model.scopes[0].values; + var resetScope = addScope(model, value); - if (helperFn) return helperFn(_this, data, model, tagData, track); - helperFn = getHelperFn(_this, model, tagData); - if (!helperFn && data.length === 1 && data[0].type === 'function') helperFn = data.shift().value; - if (model.values) model.scopes[0].values = model.values; + out = render(_this, tagData.children, model); + resetScope(); - if (data.length) newData.push(getHelperArgs(_this, model, tagData, data, newData, track)); - out = helperFn ? helperFn.apply(model.scopes[0].scope, newData) : ''; - model.scopes[0].values = restore; - return out === undefined ? '' : out; + return out; } -function renderPartial(_this, data, model, tagData) { - var newData = tagData.partial.vars && getData(_this, model, tagData.partial, []); - var helperValue = tagData.partial.helper && renderHelper(_this, newData, model, tagData.partial); - var name = tagData.partial.orig || newData && (helperValue || newData[0].value) || ''; - var isTemplate = name === '@partial-block'; - var isBlock = !isTemplate && name.charAt(0) === '@'; - var partial = _this.partials[isBlock ? name.substring(1) : name] || (model.extra && model.extra[name]); - var scope = data[0] && !data[0].variable.name ? data[0].value : model.scopes[0].scope; - var reset = addScope(model, scope, model.scopes[0].alias); - - model.scopes[0].level = []; - if (!partial && isBlock) partial = _this.partials[name]; - if (isBlock) model.blocks[name] = _this.partials[name]; - else if (isTemplate) partial = model.blocks[name]; - if (_this.options.limitPartialScope) model.scopes = [model.scopes[0]]; - else model.scopes.splice(1, 1); - return [ partial ? partial(model) : '', reset() ][0]; -} - -function renderConditions(_this, data, model, tagData, track) { - var idx = 0; - var objKeys = { keys: [] }; - var children = tagData.children; - var tag = children[idx]; - var helper = tagData.helper; - var cond = helper === 'if' || helper === 'each' || helper === 'with'; - var isVarOnly = !helper && data.length === 1; - var main = data[0] || {}; - var value = checkObjectLength(main, helper, objKeys); - var canGo = ((cond || isVarOnly) && value) || (helper === 'unless' && !value); - var reset = null; - - while (children[idx + 1] && !canGo) { - tag = children[++idx]; - helper = tag.helper; - cond = helper === 'if' || helper === 'each' || helper === 'with'; - data = tag.vars.length ? getData(_this, model, tag, []) : []; - isVarOnly = !helper && data.length === 1; - main = data[0] || {}; - value = checkObjectLength(main, helper, objKeys); - canGo = ((cond || isVarOnly) && value) || (helper === 'unless' && !value) || - (!helper && !data.length && tag.bodyFn); // isElse - } - track.fnIdx = canGo ? idx : idx + 1; // speeds up API calls - track.checkFn && track.checkFn(idx); - if (isVarOnly && main.type === 'array') helper = 'each'; - if (_this.controls.stop && typeof _this.controls.stop !== 'string' && helper === 'each') return ''; - if (isVarOnly && !helper) helper = 'with'; - if (helper === 'with' || helper === 'each') { - reset = addScope(model, value, helper === 'with' && model.scopes[0].alias); - if (helper === 'each') return renderEach(_this, value, main, model, - tag, objKeys.keys, _this.options.loopHelper, reset); - model.scopes[0].helpers = createHelper(_this, '', '', 0, - isVarOnly ? value : model.scopes[0].scope, model.scopes[1].scope, model.scopes); +function renderEach(_this, value, model, main, tagData, objKeys) { + var out = ''; + var hook = _this.options.loopHelper; + var resetScope = addScope(model, value); + var scopes = model.scopes; + var scope = scopes[0]; + var isArray = main.type === 'array'; + var data = isArray ? value : objKeys.keys; + var alias = tagData.vars[0].alias; + + for (var n = 0, key = '', l = data.length; n < l; n++) { + key = isArray ? n : data[n]; + scope.helpers = createHelper(_this, scopes, value[key], value, n, key, l); + scope.context = value[key]; + + if (alias[0]) scope.vars[alias[0]] = value[key]; + if (alias[1]) scope.vars[alias[1]] = key; + + out += !hook ? render(_this, tagData.children, model) : + hook(_this, model, data, value, main, key, tagData, render, createHelper); } - return [canGo ? tag.text + tag.bodyFn(model) : '', reset && reset()][0]; + resetScope(); + + return out; } -function renderEach(_this, data, main, model, tagData, objKeys, loopHelper, reset) { - var bodyFn = tagData.bodyFn; - var scope = model.scopes[0]; - var alias = main.variable.alias; - var level = scope.level[0]; - var isArr = main.type === 'array'; - var value = !isArr && main.type !== 'object' ? [] : isArr ? data : objKeys; - var currentScopes = model.scopes; // loopHelper ? concatArrays([], model.scopes) : null; - var loopFn = loopHelper && function(newData, key) { // main.variable.active && - model.scopes = currentScopes; - model.scopes[0].scope = newData; - model.scopes[0].helpers = - createHelper(_this, key, key, main.value.length, newData, data, model.scopes); - _this.controls.loop.unshift(scope.helpers); - return [loopHelper(_this, tagData.text + bodyFn(model), main, +key, loopFn, true), - _this.controls.loop.shift()][0]; - }; +function renderHelper(_this, tagData, main, model) { + var fnArgs = []; + var args = main.args; + var arg = null; + var n = 0, l = args.length; + var context = model.scopes[0].context; + + if (!main.value || !main.value.apply) return main.value; + + for ( ; n < l; n++) if (arg = args[n], arg.helper) + fnArgs.push(renderHelper(_this, tagData, arg, model)); + else if (!arg.alias) fnArgs.push(arg.value); + + if (main.key[0] !== '$' && tagData.vars[0].type === 'helper') + fnArgs.push(helperArgs(_this, tagData, main, model)); + + return main.value.apply(context, fnArgs); +} + +function renderBlockData(_this, tagData, model, value) { + var isIf = tagData.vars.length !== 0 && tagData.vars[0].type !== 'helper'; + var resetScope = isIf && !tagData.helper ? addScope(model, value) : null; + var out = tagData.text; + + out += !tagData.helper && !isIf ? value : + render(_this, tagData.children, model); + + if (resetScope) resetScope(); + return out; +} - if (alias && loopHelper) scope.alias[alias[0]] = { parent: data }; - if (_this.controls.stop) return ['', loopHelper(_this, loopFn, main), reset()][0]; - if (loopHelper) _this.controls.loop.unshift(null); - for (var n = 0, l = value.length, key = '', out = ''; n < l; n++) { - key = (isArr ? n : value[n]); - scope.helpers = createHelper(_this, n, key, l, data[key], data, model.scopes); - scope.scope = data[key]; - if (alias) { - if (alias[1]) level[alias[1]] = key; - level[alias[0]] = data[key]; - if (loopHelper) scope.alias[alias[0]].key = key; - } - if (loopHelper) _this.controls.loop[0] = scope.helpers; - out += loopFn ? loopHelper(_this, (loopHelper(_this, key, main), - tagData.text + bodyFn(model)), main, n, loopFn) : tagData.text + bodyFn(model); +function renderBlocklHelper(_this, data, model, tagData) { + var main = data[0]; + var unless = tagData.helper === 'unless'; + var value = renderHelper(_this, tagData, main, model); + var keys = { keys: [] }; + var check = checkValue(main, value, tagData.helper, keys); + var alts = tagData.alts, n = 0, l = alts.length, track = tagData; + + if (check === unless) for ( ;n < l; n++) { + tagData = alts[n]; + unless = tagData.helper === 'unless'; + + if (tagData.helper) { + main = getData(_this, tagData, model)[0]; + value = renderHelper(_this, tagData, main, model); + } else value = render(_this, tagData.children, model); + + check = checkValue(main, value, tagData.helper); + if (check !== unless) { n++; break; } } - return [ out, reset(), loopHelper && _this.controls.loop.shift() ][0]; + track.index = n; + + if (tagData.helper === 'with' && value) + return renderWith(_this, value, model, tagData); + if (main.isLoop && value) + return renderEach(_this, value, model, main, tagData, keys); + if (check !== unless) return renderBlockData(_this, tagData, model, value); + return !tagData.alts ? tagData.text : ''; } // ---- render blocks and inlines; delegations only -function render(_this, model, data, tagData, out, renderFn, track) { - model.values = null; - if (_this.options.renderHook && tagData.tag === 'B') model = - { extra: model.extra, scopes: model.scopes, alias: model.alias, blocks: model.blocks }; - return !_this.options.renderHook || !data.length || _this.controls.active ? out : - _this.options.renderHook(_this, out, data, function recallBodyFn(newModel, helpers, stop) { - if (helpers) model.scopes[0].helpers = helpers; // model.scopes[newModel.variable.depth]? - if (newModel[0].parent) model.scopes[0].scope = newModel[0].parent; // dus wel - if (stop) _this.controls.stop = stop; - return [renderFn(_this, tagData, newModel, model, track || { fnIdx: 0 }), - _this.controls.stop = false, _this.controls.active = true][0]; - }, tagData, tagData.tag === 'B' ? track || { fnIdx: 0 } : undefined, - tagData.children && tagData.children[1] && tagData.children[1].tag === 'E' ? - function(tag) { return getData(_this, model, tag, []) } : null); -} - -function renderInline(_this, tagData, data, model) { - var type = data[0] && data[0].type; - var out = tagData.partial ? renderPartial(_this, data, model, tagData) : - escapeHtml(_this, tagData.helper || type === 'function' ? - renderHelper(_this, data, model, tagData) : data[0] && data[0].value, - type !== 'boolean' && type !== 'number' && tagData.isEscaped); - - return render(_this, model, data, tagData, out, renderInline, null); -} - -function renderInlines(_this, tags, model) { - for (var n = 0, l = tags.length, out = ''; n < l; n++) out += (tags[n].tag === 'B' ? renderBlock : - renderInline)(_this, tags[n], getData(_this, model, tags[n], []), model) + tags[n].text; - return out; +function renderBlock(_this, tag, model, data) { + var hook = _this.options.renderHook; + var out = tag.partial ? + renderPartial(_this, data, model, tag) : + renderBlocklHelper(_this, data, model, tag); + + return hook ? hook(_this, model, tag, data, out, renderBlock, render) : out; } -function renderBlock(_this, tagData, data, model, recursive) { - var track = recursive || { fnIdx: 0 }; - var out = renderHelper(_this, data, model, tagData, track); +function renderInline(_this, tag, model, data) { + var hook = _this.options.renderHook; + var out = tag.partial ? + renderPartial(_this, data, model, tag) : data[0].type === 'function' ? + renderHelper(_this, tag, data[0], model) : + data[0].value; - return recursive ? out : render(_this, model, data, tagData, out, renderBlock, track); + out = escapeHtml(_this, out, tag.escape) + tag.text; + + return hook ? hook(_this, model, tag, data, out, renderInline, render) : out; } -// ---- parse (pre-render) helpers +function render(_this, tags, model) { + var out = ''; + var renderFn = null; + var tag = {}; -function trim(text, start, end) { - var doStart = start.indexOf('~') !== -1; - var doEnd = end.indexOf('~') !== -1; - var regExp = !doStart && !doEnd ? '' : !doStart ? trims.end : !doEnd ? trims.start : trims.all; + for (var n = 0, l = tags.length; n < l; n++) if (tag = tags[n], tag.vars) { + renderFn = tag.block ? renderBlock : renderInline; + out += renderFn(_this, tag, model, getData(_this, tag, model)); + } else out += tag.text; - return regExp ? text.replace(regExp, '') : text; + return out; } -function convertValue(text, skip) { - return skip ? text : text === 'true' ? true : text === 'false' ? - false : isNaN(text) || text === '' ? text : +text; +// ---- parse variables + +function convertValue(text, model) { + return text === 'true' ? (model.type = 'boolean', true) : + text === 'false' ? (model.type = 'boolean', false) : + isNaN(text) || text === '' ? text : (model.type = 'number', +text); } -function cleanText(text, out) { - return text.replace(/^(?:this[/.]|\.\/|\|)/, function($) { - if ($) out.isStrict = true; - return ''; - }); +function getVarsModel() { + return { + active: 0, alias: [], args: [], depth: 0, name: '', helper: false, + path: [], strict: false, type: 'key', value: '', enclosed: false, + }; } -function parsePath(text, data, skip) { - var hasDot = false; - var name = text.replace(/@parent[/.]/, '../').replace(/\[.*?]/g, function($) { // HB - return $.substring(1, $.length - 1).replace(/\./g, function() { hasDot = true; return '^'; }); - }); - var parts = skip ? [] : name.split('../'); - var start = parts[1] ? parts[0] : ''; - var depth = parts.length - 1; - var value = skip ? name : parts[depth]; +function isStringIsolated(start, end, extra) { + return (!start || start === ' ') && (!end || end === ' ') || + end === ')' || extra === '='; +} - if (skip || value === '.' || value === 'this' || +value == value) return { - value: value, path: [], depth: depth, type: 'key' - }; - parts = cleanText(value, data).split(/[./]/); - if (hasDot) { - for (var n = parts.length; n--; ) parts[n] = parts[n].replace(/\^/g, '.'); - name = name.replace(/\^/g, '.'); - } - return { value: start + parts.pop(), path: parts, depth: depth, orig: name }; +function packageVar(model, cache, out, args) { + if (!cache) return model; + model.value = convertValue(cache, model); + if (model.type !== 'helper' && args.length) args[0].push(model); + else out.push(model); + + return getVarsModel(); } -function parseAlias(value, out, spread) { - for (var n = value.length, alias = []; n--; ) alias.unshift(value[n].value); - if (spread) { - while (alias.length) out[out.length - alias.length].name = alias.shift(); - } else { - out[out.length - 1].alias = alias; +function getVars(vars, out, isPartial, isHelper, strictArgs) { + var model = getVarsModel(); + var cache = ''; + var char = ''; + var beforeString = ''; + var quotation = ''; + var cast = false; + var args = []; + + for (var n = 0, l = vars.length; n < l; n++) { + char = vars[n]; + + if ('"' === char || '\'' === char) { + if (vars[n - 1] === '\\' && ('"' === char || '\'' === char)) { + cache = cache.substring(0, cache.length - 1) + char; + } else if (char === quotation) { + if (isStringIsolated(beforeString, vars[n + 1], beforeString)) { + model.type = 'string'; + model = packageVar(model, cache, out, args); + cache = ''; + } + quotation = ''; + } else if (!quotation) { + quotation = char; + beforeString = vars[n - 1]; + } else cache += char; + } else if (quotation) { + cache += char; + } else if ('[' === char || ']' === char) { + cast = '[' === char; + } else if (cast) { + cache += char; + } else if (' a./@=()%|'.indexOf(char) === -1) { + cache += char; + } else if ('a' === char) { + if (' as ' === vars.substring(n - 1, n + 3)) n += 2; + else cache += char; + } else if (' ' === char) { + model = packageVar(model, cache, out, args); + cache = ''; + } else if ('.' === char && '../' === vars.substring(n, n + 3)) { + model.depth++; + model.strict = true; + n += 2; + } else if ('/' === char || '.' === char) { + if ('.' === char && isStringIsolated(vars[n - 1], vars[n + 1])) { + model = packageVar(model, 'this', out, args); + continue; + } + if (cache && cache !== 'this') model.path.push(cache); + model.strict = true; + cache = ''; + } else if ('@' === char && '@parent' === vars.substring(n, n + 7)) { + if ('./'.indexOf(vars[n + 7]) !== -1) { + model.depth++; + model.strict = true; + } else cache += '@parent'; + n += 6; + } else if ('=' === char) { + model.name = cache ? cache : out.pop().value; + cache = ''; + } else if ('(' === char) { + model.type = 'helper'; + model.enclosed = true; + args.unshift(model.args); + } else if (')' === char) { + model = packageVar(model, cache, out, args); + args.shift(); + if (args.length) args[0].push(out.pop()); + cache = ''; + } else if ('%' === char) { + model.active++; + } else if ('|' === char) { + cache = vars.substring(n + 1); + cache = cache.substring(0, cache.indexOf(char)); + n += cache.length + 1; + out[out.length - 1].alias = trim(cache, '~', '~').split(' '); + cache = ''; + } else cache += char; } -} -function getVars(text, collection, out, type) { - var txtParts = type === 'string' ? [text] : text.split(/[,;]*\s+[,;]*/); - var isAliasOrString = type === 'alias' || type === 'string'; - - for (var n = 0, l = txtParts.length, match = /--(\d+)--/, replace = /%+/, dataType = '', - parts = [], value = '', data = {}, paths = {}, skipConvert = false; n < l; n++) { - if (!txtParts[n]) continue; // whitespace after - parts = txtParts[n].split('='); - value = parts[1] !== undefined ? parts[1] : parts[0]; - if (value === '' || value === 'as') continue; - - data = collection[(value.match(match) || [])[1]] || { value: value, type: 'key' }; - dataType = typeof data.value; - if (dataType === 'object' && data.value[0] && data.value[0].single) return data.value; - if (parts[1] !== undefined) data.name = parts[0]; - if (data.type === 'string') data.value = data.value[0] && data.value[0].value || ''; - else if (data.value && dataType === 'string') { - data.value = data.value.replace(replace, function($) { data.active = $.length; return '' }); - paths = parsePath(data.value, data, isAliasOrString); - skipConvert = isAliasOrString || (paths.orig && paths.orig !== paths.value); - data.value = convertValue(paths.value, skipConvert); - dataType = typeof data.value; - if (dataType !== 'string') data.type = dataType; - else if (paths.path && !isAliasOrString) cloneObject(data, paths); - } - data.type === 'alias' ? parseAlias(data.value, out, n > 3) : out.push(data); + if (args.length) templateError(); + packageVar(model, cache, out, args); + if (isPartial || !out.length) return out; + + if (!isHelper) out[0].type = 'key'; + if (out[1] && out[0].type === 'key') { + out[0].type = 'helper'; + if (strictArgs) for (var n = 1, l = out.length; n < l; n++) + if (out[n].type === 'key') out[n].strict = true; + out[0].args = out.splice(1); } + return out; } -function sizzleVars(text, out) { - var replace = /\([^()]*\)/g; - var replaceCb = function($) { - var value = { vars: getVars($.substring(1, $.length - 1), out, [], 'fn') }; - if (value.vars.length > 1) value.helper = value.vars.shift(); - return '--' + (out.push(value) - 1) + '--'; - }; +// ---- parse inline and block tags and build tree - text = text.replace(/(['"|])(?:[^\\'"]|\\+['"]|['"])*?\1/g, function($, $1) { - var value = { type: $1 !== '|' ? 'string' : 'alias', value: '' }; +function skipTag(parts, tree, index) { + var previous = tree[tree.length - 1]; + var text = previous.text; - if (text.indexOf('[' + $1) !== -1 || text.indexOf($1 + '=') !== -1) return $; - value.value = $ === text ? - [{ value: $.substring(1, $.length - 1), path: [], depth: 0, single: true, type: 'key' }] : - getVars($.substring(1, $.length - 1), out, [], value.type); - return '--' + (out.push(value) - 1) + '--'; - }); - while (text !== (text = text.replace(replace, replaceCb))); - return getVars(text, out, [], ''); + previous.text = text.substring(0, text.length - 1); + tree.push({ text: parts.slice(index, index + 5).join('') }); } -function getTagData(_this, vars, type, start, tag, text) { - var arr = vars ? sizzleVars(vars, []) : []; - var helper = type === '^' ? 'unless' : - /^(?:if|each|with|unless)$/.test((arr[0] || {}).value) ? arr.shift().value : ''; +function trim(text, start, end) { + if (start.indexOf('~') !== -1) text = text.replace(trims.start, ''); + return end && end.indexOf('~') !== -1 ? text.replace(trims.end, '') : text; +} - return { - partial: type === '>' ? arr.shift() : undefined, - helper: helper ? helper : type !== '>' && arr.length > 1 ? arr.shift() : '', - helperFn: helper ? renderConditions : undefined, - isEscaped: start.lastIndexOf(_this.options.tags[0]) < 1, - bodyFn: null, - vars: arr, - isInline: tag !== 'B', // new in v1.6.4 ... - tag: tag, - text: text, - children: null, - }; +function checkBlockStart(tree, close) { + for (var n = tree.length; n--; ) if (tree[n].alts) break; + return close === tree[n].helper || close === tree[n].block || + close === tree[n].vars[0].value; } -// ---- parse inline and block tags +function movePartialText(tagData) { + tagData.children.unshift({ text: tagData.text }); + tagData.text = ''; +} -function createExecutor(_this, tagData) { - return tagData.bodyFn = tagData.tag === 'B' ? undefined : - function executeInlines(model) { return renderInlines(_this, tagData.children, model); }; +function getTreeChildren(tree, tagData) { + tagData.children.__parent = tree; + return tagData.children; } -function buildTree(_this, tree, tagData, open) { - var errorMessage = 'Schnauzer Error: Wrong closing tag: "/' + tagData.vars + '"'; - var parent = tree.parent; - var children = []; - var getChildren = function(tagData, isFirstChild) { - tagData.children = children = []; - children.parent = tree; - tree = children; - if (isFirstChild) { - tree.push(getTagData(_this, '', '', open, '', tagData.text)); // TODO - getChildren(tree[tree.length - 1]); - tree.isElse = true; - } - }; - var getParent = function() { - delete tree.parent; delete tree.isElse; - tree = parent; - parent = tree.parent; - createExecutor(_this, tree[tree.length - 1]); - }; +function getTreeParent(tree) { + var parent = tree.__parent; + if (!parent) templateError(); + delete tree.__parent; + return parent; +} - if (tagData.tag === 'C') { - if (!tree.parent) throw(errorMessage); - if (tree.isElse) getParent(); - getParent(); - if (tree.lastBlock !== tagData.vars) throw(errorMessage); - delete tree.lastBlock; - tree[tree.length - 1].text = tagData.text; - } else if (tagData.tag === 'B') { - tree.push(tagData); - tree.lastBlock = tagData.alt || tagData.helper.value || tagData.helper || tagData.vars[0].orig; - getChildren(tagData, true); - } else if (tagData.tag === 'E') { - if (tree.isElse) getParent(); - tree.push(tagData); - getChildren(tagData); - tree.isElse = true; - } else { // tagData.tag === 'I' +function buildTree(tree, tagData) { + if (tagData.close) { + tree = getTreeParent(tree); + if (!checkBlockStart(tree, tagData.close)) templateError(); + if (tree[tree.length - 1].partial) movePartialText(tree[tree.length - 1]); + tree[tree.length - 1].index = 0; + tree.push({ text: tagData.text }); + } else if (tagData.block) { tree.push(tagData); - } + tree = getTreeChildren(tree, tagData); + } else if (!tagData.alts) { + tagData.block = true; + tree = getTreeParent(tree); + tree[tree.length - 1].alts.push(tagData); + tree = getTreeChildren(tree, tagData); + } else tree.push(tagData); + return tree; } -function parseTags(_this, text, tree) { - var split = text.split(_this.regexps.tags); - - tree.push({ text: split[0] }); - - for (var n = 1, type = '', vars = '', body = '', space = 0, root = '', tmpRoot = [], tmpVars = [], - testRegex = /^[!-]+/, elseRegex =/^else\s*/, types = { '#':'B','^':'B','/':'C','E':'E' }, - child = {}, cType = '', tag = '', tagData = {}, l = split.length; n < l; n += 5) { - type = split[1 + n].replace('~', ''); - vars = split[2 + n]; - body = trim(split[4 + n], split[3 + n], split[6 + n] || ''); +function inlineTemplate(_this, templates, tree, args, text) { + var tmpl = {}; - if (split[n].charAt(0) === '\\' || testRegex.test(type)) continue; - - space = vars.indexOf(' '); - root = type !== '/' && vars.substring(0, space) || vars; - cType = type === '^' && (space !== -1 || vars === '') || root === 'else' ? 'E' : type; - tag = types[cType.charAt(0)] || 'I'; - - if (type === '#>') { tmpRoot.unshift('@' + root); tmpVars.unshift('@' + vars); } - if (cType === 'E') vars = vars.replace(elseRegex, ''); - tagData = type === '/' ? { tag: 'C', text: body, vars: vars } : - getTagData(_this, vars, type, split[n], tag, body); - if (type === '^' && tag === 'B') tagData.alt = tagData.vars[0].orig; - if (type === '#*') tagData.isPartial = true; + if (!args[1]) { + tree = buildTree(tree, { close: args[0], text: text }); + tmpl = tree.splice(-2, 1)[0]; + tmpl.children.unshift({ text: tmpl.text }); + _this.registerPartial(tmpl.name, tmpl.children); + templates.shift(); + return tree; + } - tree = buildTree(_this, tree, tagData, split[n]); + templates.unshift(args[0]); + return buildTree(tree, { + block: args[0], + name: args[1].replace(/['"]/g, ''), + children: [], + text: text, + alts: [], + }); +} - if (tag === 'C' && (tree[tree.length - 1].isPartial || tmpRoot[0])) { // Don't like this - tagData = tree.splice(-1, 1, tmpRoot[0] ? - getTagData(_this, tmpVars[0], '>', split[n], 'I', tagData.text) : {text: tagData.text})[0]; - child = tagData.children[0]; - child.children.unshift({ text: child.text }); - _this.registerPartial(tmpRoot[0] || tagData.vars[0].value, child.bodyFn); - tmpRoot.shift(); tmpVars.shift(); - } +function parseTags(_this, templateText) { + var parts = templateText.split(_this.regex.tags); + var tree = [{ text: trim(parts[0], '', parts[2]) }]; + var open = '', type = '', args = [], text = ''; + var isPartial = false, isBlock = false, helper = ''; + var helperTester = { if: true, unless: true, each: true, with: true }; + var templates = []; + var strict = _this.options.strictArguments; + + for (var n = 1, l = parts.length; n < l; n += 5) { + open = parts[n]; + type = parts[n + 1].replace('~', ''); + if (parts[n - 1].slice(-1) === '\\') { skipTag(parts, tree, n); continue; } + if (type === '^~') { type = '^'; parts[n + 3] += '~'; } + text = trim(parts[n + 4], parts[n + 3], parts[n + 6] || ''); + if (type[0] === '!') { tree.push({ text: text }); continue; } + args = parts[n + 2].split(trims.whitespace); + isPartial = type.indexOf('>') !== -1; + isBlock = type.indexOf('#') !== -1; + + if (type === '/' && args[0] === templates[0] || type === '#*') { + tree = inlineTemplate(_this, templates, tree, args, text); continue; + } else if (type === '^' && !args[0]) { type = ''; args = ['else'] } + else if (type === '^') args.unshift('unless'); + + tree = buildTree(tree, type === '/' ? { close: args[0], text: text } : { + block: isBlock || type === '^', + partial: isPartial, + alts: args[0] === 'else' ? !!args.shift() && null : [], + helper: helper = helperTester[args[0]] ? args.shift() : '', + vars: getVars(args.join(' '), [], isPartial, !!helper, strict), + escape: open.lastIndexOf('{{') < 1 && !isPartial, + text: isBlock ? '' : text, + children: isBlock ? [{ text: text }] : [], + }); } - if (tree.parent) throw('Schnauzer Error: Missing closing tag(s)'); - split = text = null; + if (tree.__parent) templateError(); - return createExecutor(_this, { children: tree }); + return tree; } })); diff --git a/schnauzer.min.js b/schnauzer.min.js index b6e84da..43dec42 100644 --- a/schnauzer.min.js +++ b/schnauzer.min.js @@ -1,2 +1,2 @@ -/**! @license schnauzer v2.0.8; Copyright (C) 2017-2023 by Peter Dematté */ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],function(){return t()},"schnauzer"):"object"==typeof exports?exports.Schnauzer=t():e.Schnauzer=t()}(this&&this.window||global,function(){"use strict";var v=Object.keys||function(e){var t=[],r="";for(r in e)hasOwnProperty.call(e,r)&&t.push(r);return t},y=function(e,t){for(var r in t)n=t,e[s=r]=n[s];var n,s;return e},f=function(e,t){return t.push.apply(t,e),t},B={start:/^\s*/,all:/^\s*|\s*$/g,end:/\s*$/},g=function(e,t){this.version="2.0.8",this.partials={},this.helpers={},this.regexps={},this.controls={active:!1,stop:!1,loop:[]},this.options={tags:["{{","}}"],entityMap:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="},helpers:{},partials:{},self:"self",escapeHTML:!0,limitPartialScope:!0,loopHelper:null,renderHook:null},r(this,t||{},e)},r=function(e,t,r){"string"!=typeof r&&(t=r,r=""),n(e,(t=y(e.options,t)).tags),e.helpers=t.helpers,e.registerPartial(t.partials),void 0!==r&&e.parse(r),delete t.helpers,delete t.partials},e=g.SafeString=function(e){this.string=e};return e.prototype.toString=e.prototype.toHTML=function(){return""+this.string},g.getObjectKeys=v,g.cloneObject=y,g.concatArrays=f,g.prototype={render:function(e,t){var r=k(this,"","",0,e,null,[{scope:e}]);return[this.partials[this.options.self]({blocks:{},extra:t,scopes:[{scope:e,helpers:r,level:[],values:null,alias:{}}]}),this.controls.active=!0][0]},parse:function(e){return this.registerPartial(this.options.self,e)},registerHelper:function(e,t){if("string"==typeof e)return this.helpers[e]=t;for(var r in e)this.helpers[r]=e[r]},unregisterHelper:function(e){delete this.helpers[e]},registerPartial:function(e,t){if("string"==typeof e)return this.partials[e]=this.partials[e]||(t.constructor===Function?t:function(e,t,r){var n=t.split(e.regexps.tags);r.push({text:n[0]});for(var s=1,a="",l="",i="",o=0,p="",u=[],c=[],h=/^[!-]+/,v=/^else\s*/,f={"#":"B","^":"B","/":"C",E:"E"},g={},d="",y="",x={},b=n.length;s"===a&&(u.unshift("@"+p),c.unshift("@"+l)),"E"===d&&(l=l.replace(v,"")),x="/"===a?{tag:"C",text:i,vars:l}:M(e,l,a,n[s],y,i),"^"===a&&"B"===y&&(x.alt=x.vars[0].orig),"#*"===a&&(x.isPartial=!0),r=C(e,r,x,n[s]),"C"===y&&(r[r.length-1].isPartial||u[0])&&(x=r.splice(-1,1,u[0]?M(e,c[0],">",n[s],"I",x.text):{text:x.text})[0],(g=x.children[0]).children.unshift({text:g.text}),e.registerPartial(u[0]||x.vars[0].value,g.bodyFn),u.shift(),c.shift()));var k,m,E,F,S,w;if(r.parent)throw"Schnauzer Error: Missing closing tag(s)";return n=t=null,z(e,{children:r})}(this,t,[]));for(var r in e)this.registerPartial(r,e[r])},unregisterPartial:function(e){delete this.partials[e]},setTags:function(e){n(this,e)},escapeExpression:function(e){return d(this,e,!0)}},g;function n(e,t){var r=function(e){for(var t=e.length;t--;)e[t]="("+e[t]+")";return e}("{{"===t[0]?["{{2,3}","[~}]{2,4}"]:t);e.regexps={tags:new RegExp(r[0]+"([#~^/!>*-]*)\\s*([^~}]*)"+r[1]),entity:new RegExp("["+v(e.options.entityMap).join("")+"]","g")}}function d(t,e,r){return null==e?"":e.constructor===g.SafeString?e.string:r&&t.options.escapeHTML?String(e).replace(t.regexps.entity,function(e){return t.options.entityMap[e]}):e}function k(e,t,r,n,s,a,l){return n?{"@index":t,"@number":t+1,"@key":r,"@odd":t%2!=0,"@last":t===n-1,"@first":0===t,"@length":n,"@depth":e.options.limitPartialScope?void 0:l.length-2,"@loop":a,"@parent":l[1].scope,"@root":l[l.length-1].scope,this:s,".":s}:{"@parent":a,"@root":l[l.length-1].scope,this:s,".":s}}function x(e,t,r){var n=e.scopes,s=e.alias?[e.alias]:[],a=f(n[0].level,s),l=e.values,i=n[1]?y({},n[1].alias):{};return e.alias=null,e.values=null,r=r?y(i,r):i,e.scopes=f(n,[{scope:t,helpers:n[0].helpers,level:a,values:l,alias:r}]),function(){e.scopes=n}}function b(e,t){var r=e.scope;return e.scope=t||{},function(){e.scope=r}}function m(e,t,r){if("."===t.value||"this"===t.value)return{value:e,variable:t};if("key"!==t.type)return{value:t.value,variable:t};for(var n="@root"===t.path[0]?1:0,s=t.path.length;n"===r?l.shift():void 0,helper:i||(">"!==r&&1":">",'"':""","'":"'","/":"/","`":"`","=":"="},helpers:{},partials:{},self:"self",escapeHTML:!0,limitPartialScope:!0,strictArguments:!0,loopHelper:null,renderHook:null},r(this,t||{},e)},r=function(e,t,r){"string"!=typeof r&&(t=r,r=void 0),t=u(e.options,t),e.regex.tags=/({{2,3})([#~^/!>*-]*)\s*([^~}]*)([~}]{2,4})/,e.regex.entity=new RegExp("["+o(e.options.entityMap).join("")+"]","g"),e.helpers=u(e.helpers,t.helpers),e.registerPartial(t.partials),void 0!==r&&e.parse(r),delete t.helpers,delete t.partials},h=function(e){this.string=e};return h.prototype.toString=h.prototype.toHTML=function(){return""+this.string},t.prototype={render:function(e,t){var r=[{context:e,helpers:w(this,[{context:e}],e),vars:{}}];return z(this,this.partials[this.options.self],{scopes:r,extra:t||{},$vars:{},$alias:{}})},parse:function(e){return this.registerPartial(this.options.self,e)},registerHelper:function(e,t){if("string"==typeof e)return this.helpers[e]=t;for(var r in e)this.helpers[r]=e[r]},unregisterHelper:function(e){delete this.helpers[e]},registerPartial:function(e,t){if("string"==typeof e)return this.partials[e]=this.partials[e]||(t.constructor===Array?t:function(e,t){for(var r=t.split(e.regex.tags),n=[{text:L(r[0],"",r[2])}],s="",a="",i=[],l="",o=!1,p=!1,u="",h={if:!0,unless:!0,each:!0,with:!0},c=[],f=e.options.strictArguments,v=1,g=r.length;v"),p=-1!==a.indexOf("#"),"/"===a&&i[0]===c[0]||"#*"===a?n=A(e,c,n,i,l):("^"!==a||i[0]?"^"===a&&i.unshift("unless"):(a="",i=["else"]),n=M(n,"/"===a?{close:i[0],text:l}:{block:p||"^"===a,partial:o,alts:"else"===i[0]?!!i.shift()&&null:[],helper:u=h[i[0]]?i.shift():"",vars:O(i.join(" "),[],o,!!u,f),escape:s.lastIndexOf("{{")<1&&!o,text:p?"":l,children:p?[{text:l}]:[]}))):n.push({text:l})):P(r,n,v);n.__parent&&d();return n}(this,t));for(var r in e)this.registerPartial(r,e[r])},unregisterPartial:function(e){delete this.partials[e]}},t;function c(t,e,r){return null==e?"":e.constructor===h?e.toString():r&&t.options.escapeHTML?String(e).replace(t.regex.entity,function(e){return t.options.entityMap[e]}):e}function f(e,t){var r=e[t];return null==r?r:Object.prototype.hasOwnProperty.call(e,t)?r:void 0}function S(t,e,r){var n=t.scopes[0],s=r?{}:null,a=u({},t.$vars);if(r)for(var i in n.$vars)a[i]=s[i]=n.$vars[i],n.vars[i]=void 0;if(n.$alias)for(var i in n.$alias)t.$alias.hasOwnProperty(i)||(t.$alias[i]=n.vars[i]);return u(a,t.$alias),t.scopes.unshift({context:void 0===e?{}:e,helpers:n.helpers,vars:a,$alias:t.$alias,$vars:t.$vars}),t.$vars={},t.$alias={},function(){if(t.scopes.shift(),r)for(var e in s)n.vars[e]=s[e]}}function w(e,t,r,n,s,a,i){return i?{"@index":s,"@number":s+1,"@key":a,"@odd":s%2!=0,"@last":s===i-1,"@first":0===s,"@length":i,"@depth":e.options.limitPartialScope?void 0:t.length-2,"@loop":n,"@parent":t[1].context,"@root":t[t.length-1].context,this:r}:{"@parent":n,"@root":t[t.length-1].context,this:r}}function x(e,t,r,n){if(e.name){if("includeZero"===e.name)return n[0].zero=e.value;t.$vars[e.name]=r.value,r.alias=e.name}else for(var s=0,a=e.alias.length;s","\"","'","/","`","=","self","escapeHTML","limitPartialScope","loopHelper","renderHook","initSchnauzer","_this","template","switchTags","registerPartial","undefined","parse","HBSS","SafeString","text","string","prototype","toString","toHTML","render","data","extra","createHelper","scope","blocks","scopes","level","values","alias","txt","registerHelper","name","helperFn","unregisterHelper","constructor","Function","tree","split","n","type","vars","body","space","root","tmpRoot","tmpVars","testRegex","elseRegex","types","#","^","E","child","cType","tag","tagData","l","length","replace","regExp","doStart","indexOf","doEnd","charAt","test","substring","unshift","getTagData","alt","orig","isPartial","buildTree","splice","children","value","bodyFn","shift","parent","createExecutor","parseTags","unregisterPartial","setTags","escapeExpression","escapeHtml","tgs","RegExp","entity","join","doEscape","String","char","idx","len","@index","@number","@key","@odd","@last","@first","@length","@depth","@loop","@parent","@root",".","addScope","model","newLevel","prevAlias","tweakScope","savedScope","getDeepData","main","variable","path","getAlias","createAliasMap","aliasKey","getData","out","trackData","help","args","depth","isStrict","helper","renderHelper","Array","renderArgs","renderFn","newData","checkObjectLength","objKeys","isObject","track","renderConditions","restore","save","hash","extend","concat","getDataDetails","index","number","first","last","odd","fn","context","fnIdx","checkFn","inverse","getHelperArgs","cond","isVarOnly","canGo","reset","isArr","currentScopes","loopFn","renderEach","newModel","renderInline","helperValue","isTemplate","isBlock","partial","isEscaped","renderBlock","recursive","parsePath","skip","hasDot","$","parts","pop","parseAlias","spread","getVars","collection","txtParts","isAliasOrString","match","dataType","paths","skipConvert","single","isNaN","arr","replaceCb","$1","sizzleVars","lastIndexOf","isInline","renderInlines","open","errorMessage","getChildren","isFirstChild","isElse","getParent","lastBlock"],"mappings":"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"} \ No newline at end of file +{"version":3,"sources":["schnauzer.js"],"names":["global","factory","exports","module","define","amd","Schnauzer","this","window","getKeys","Object","keys","obj","prop","hasOwnProperty","call","push","extend","newObj","key","templateError","console","trims","start","end","whitespace","templateOrOptions","options","version","partials","helpers","lookup","lookupProperty","log","n","l","arguments","length","args","hash","apply","regex","tags","entity","controls","partialBlocks","entityMap","&","<",">","\"","'","/","`","=","self","escapeHTML","limitPartialScope","strictArguments","loopHelper","renderHook","initSchnauzer","_this","template","undefined","RegExp","join","registerPartial","parse","SafeString","text","string","prototype","toString","toHTML","render","data","extra","scopes","context","createHelper","vars","$vars","$alias","txt","registerHelper","name","helperFn","unregisterHelper","constructor","Array","templateText","parts","split","tree","trim","open","type","isPartial","isBlock","helper","helperTester","if","unless","each","with","templates","strict","replace","slice","indexOf","inlineTemplate","unshift","buildTree","close","block","partial","alts","shift","getVars","escape","lastIndexOf","children","skipTag","__parent","parseTags","unregisterPartial","escapeHtml","doEscape","String","char","parent","propertyName","out","addScope","model","value","partialContent","scope","sav","idx","len","@index","@number","@key","@odd","@last","@first","@length","@depth","@loop","@parent","@root","createAlias","main","zero","alias","createDataModel","isLoop","hasValue","noParent","isLiteral","isThis","path","deepData","active","enclosed","getData","tagData","depth","checkValue","isEach","isIf","isObject","scopeFn","fnData","resetScope","savedContext","renderPartial","renderHelper","content","limit","fnArgs","arg","createFrame","escapeExpression","item","substring","fn","inverse","altTag","helperArgs","renderBlocklHelper","check","track","index","objKeys","hook","isArray","renderEach","renderBlock","tag","renderInline","isStringIsolated","packageVar","cache","isNaN","isHelper","strictArgs","beforeString","quotation","cast","pop","splice","previous","getTreeChildren","getTreeParent","checkBlockStart","tmpl"],"mappings":"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"} \ No newline at end of file