-
Notifications
You must be signed in to change notification settings - Fork 0
/
jinja.js.map
1 lines (1 loc) · 27.2 KB
/
jinja.js.map
1
{"version":3,"sources":["parser.js","jinja.js","ajax.js","html.js","safe.js","comment.js","extends.js","for.js","if.js","include.js","load.js","raw.js","set.js","static.js","url.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC7UA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACPA;AACA;AACA;AACA;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACdA;AACA;ACDA;AACA;AACA;AACA;AACA;AACA;AACA;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACPA;AACA;AACA;AACA;AACA;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"jinja.js","sourcesContent":["var STRINGS = /'(\\\\.|[^'])*'|\"(\\\\.|[^\"'\"])*\"/g;\nvar IDENTS_AND_NUMS = /([$_a-z][$\\w]*)|([+-]?\\d+(\\.\\d+)?)/g;\nvar NUMBER = /^[+-]?\\d+(\\.\\d+)?$/;\n//non-primitive literals (array and object literals)\nvar NON_PRIMITIVES = /\\[[@#~](,[@#~])*\\]|\\[\\]|\\{([@i]:[@#~])(,[@i]:[@#~])*\\}|\\{\\}/g;\n//bare identifiers such as variables and in object literals: {foo: 'value'}\nvar IDENTIFIERS = /[$_a-z][$\\w]*/ig;\nvar VARIABLES = /i(\\.i|\\[[@#i]\\])*/g;\nvar ACCESSOR = /(\\.i|\\[[@#i]\\])/g;\nvar OPERATORS = /(===?|!==?|>=?|<=?|&&|\\|\\||[+\\-\\*\\/%])/g;\n//extended (english) operators\nvar EOPS = /(^|[^$\\w])(and|or|not|is|isnot)([^$\\w]|$)/g;\nvar LEADING_SPACE = /^\\s+/;\nvar TRAILING_SPACE = /\\s+$/;\n\nvar START_TOKEN = /\\{\\{\\{|\\{\\{|\\{%|\\{#/;\nvar TAGS = {\n '{{{': /^('(\\\\.|[^'])*'|\"(\\\\.|[^\"'\"])*\"|.)+?\\}\\}\\}/,\n '{{': /^('(\\\\.|[^'])*'|\"(\\\\.|[^\"'\"])*\"|.)+?\\}\\}/,\n '{%': /^('(\\\\.|[^'])*'|\"(\\\\.|[^\"'\"])*\"|.)+?%\\}/,\n '{#': /^('(\\\\.|[^'])*'|\"(\\\\.|[^\"'\"])*\"|.)+?#\\}/\n};\n\nvar delimeters = {\n '{%': 'directive',\n '{{': 'output',\n '{#': 'comment'\n};\n\nvar operators = {\n and: '&&',\n or: '||',\n not: '!',\n is: '==',\n isnot: '!='\n};\n\nvar constants = {\n 'true': true,\n 'false': false,\n 'null': null\n};\n\nfunction Parser() {\n this.nest = [];\n this.compiled = [];\n this.childBlocks = 0;\n this.parentBlocks = 0;\n this.isSilent = false;\n}\n\nParser.prototype.push = function (line) {\n if (!this.isSilent) {\n this.compiled.push(line);\n }\n};\n\nParser.prototype.parse = function (src) {\n var _this = this;\n return _this.tokenize(src).then(function () {\n return Promise.resolve(_this.compiled);\n });\n};\n\nParser.prototype.tokenize = function (src) {\n var _this = this;\n return new Promise(function (resolve, reject) {\n var lastEnd = 0, parser = _this, trimLeading = false;\n matchAll(src, START_TOKEN, function (open, index, src) {\n //here we match the rest of the src against a regex for this tag\n var match = src.slice(index + open.length).match(TAGS[open]);\n match = (match ? match[0] : '');\n //here we sub out strings so we don't get false matches\n var simplified = match.replace(STRINGS, '@');\n //if we don't have a close tag or there is a nested open tag\n if (!match || ~simplified.indexOf(open)) {\n return Promise.resolve(index + 1);\n }\n var inner = match.slice(0, 0 - open.length);\n //check for white-space collapse syntax\n if (inner.charAt(0) == '-') var wsCollapseLeft = true;\n if (inner.slice(-1) == '-') var wsCollapseRight = true;\n inner = inner.replace(/^-|-$/g, '').trim();\n \n\t\t\t//if we're in raw mode and we are not looking at an \"endraw\" tag, move along\n if (parser.rawMode && (open + inner) != '{%endraw') { // TODO: remove hardcoded tag\n return Promise.resolve(index + 1);\n }\n\t\t\t\n if (parser.commentMode) {\n \t// TODO: skip until parser.commentMode==false\n }\n\n var text = src.slice(lastEnd, index);\n lastEnd = index + open.length + match.length;\n if (trimLeading) text = trimLeft(text);\n if (wsCollapseLeft) text = trimRight(text);\n if (wsCollapseRight) trimLeading = true;\n if (open == '{{{') {\n //liquid-style: make {{{x}}} => {{x|safe}}\n open = '{{';\n inner += '|safe';\t\t// TODO: remove hardcoded filter\n } else if (open == '{#') {\n return Promise.resolve(lastEnd)\n }\n\n parser.textHandler(text);\n return parser.tokenHandler(open, inner);\n }).then(function(){\n var text = src.slice(lastEnd);\n if (trimLeading) text = trimLeft(text);\n _this.textHandler(text);\n resolve();\n });\n });\n};\n\nParser.prototype.textHandler = function (text) {\n if (text) {\n this.push('write(' + JSON.stringify(text) + ');');\n }\n};\n\nParser.prototype.tokenHandler = function (open, inner) {\n var type = delimeters[open];\n if (type == 'directive') {\n return this.compileTag(inner);\n } else if (type == 'output') {\n var extracted = this.extractEnt(inner, STRINGS, '@');\n //replace || operators with ~\n extracted.src = extracted.src.replace(/\\|\\|/g, '~').split('|');\n //put back || operators\n extracted.src = extracted.src.map(function (part) {\n return part.split('~').join('||');\n });\n var parts = this.injectEnt(extracted, '@');\n if (parts.length > 1) {\n var filters = parts.slice(1).map(this.parseFilter.bind(this));\n this.push('filter(' + this.parseExpr(parts[0]) + ',' + filters.join(',') + ');');\n } else {\n this.push('filter(' + this.parseExpr(parts[0]) + ');');\n }\n return Promise.resolve();\n } else {\n return Promise.resolve();\n }\n};\n\nParser.prototype.compileTag = function (str) {\n var directive = str.split(' ')[0];\n var handler = jinja.tag_handlers[directive];\n if (!handler) {\n throw new Error('Invalid tag: ' + str);\n }\n var r = handler.call(this, str.slice(directive.length).trim());\n if (r==undefined){\n return Promise.resolve();\n } else {\n return r;\n }\n};\n\nParser.prototype.parseFilter = function (src) {\n src = src.trim();\n var match = src.match(/[:(]/);\n var i = match ? match.index : -1;\n if (i < 0) return JSON.stringify([src]);\n var name = src.slice(0, i);\n var args = src.charAt(i) == ':' ? src.slice(i + 1) : src.slice(i + 1, -1);\n args = this.parseExpr(args, {terms: true});\n return '[' + JSON.stringify(name) + ',' + args + ']';\n};\n\nParser.prototype.extractEnt = function (src, regex, placeholder) {\n var subs = [], isFunc = typeof placeholder == 'function';\n src = src.replace(regex, function (str) {\n var replacement = isFunc ? placeholder(str) : placeholder;\n if (replacement) {\n subs.push(str);\n return replacement;\n }\n return str;\n });\n return {src: src, subs: subs};\n};\n\nParser.prototype.injectEnt = function (extracted, placeholder) {\n var src = extracted.src, subs = extracted.subs, isArr = Array.isArray(src);\n var arr = (isArr) ? src : [src];\n var re = new RegExp('[' + placeholder + ']', 'g'), i = 0;\n arr.forEach(function (src, index) {\n arr[index] = src.replace(re, function () {\n return subs[i++];\n });\n });\n return isArr ? arr : arr[0];\n};\n\n//replace complex literals without mistaking subscript notation with array literals\nParser.prototype.replaceComplex = function (s) {\n var parsed = this.extractEnt(s, /i(\\.i|\\[[@#i]\\])+/g, 'v');\n parsed.src = parsed.src.replace(NON_PRIMITIVES, '~');\n return this.injectEnt(parsed, 'v');\n};\n\n//parse expression containing literals (including objects/arrays) and variables (including dot and subscript notation)\n//valid expressions: `a + 1 > b.c or c == null`, `a and b[1] != c`, `(a < b) or (c < d and e)`, 'a || [1]`\nParser.prototype.parseExpr = function (src, opts) {\n opts = opts || {};\n //extract string literals -> @\n var parsed1 = this.extractEnt(src, STRINGS, '@');\n //note: this will catch {not: 1} and a.is; could we replace temporarily and then check adjacent chars?\n parsed1.src = parsed1.src.replace(EOPS, function (s, before, op, after) {\n return (op in operators) ? before + operators[op] + after : s;\n });\n //sub out non-string literals (numbers/true/false/null) -> #\n // the distinction is necessary because @ can be object identifiers, # cannot\n var parsed2 = this.extractEnt(parsed1.src, IDENTS_AND_NUMS, function (s) {\n return (s in constants || NUMBER.test(s)) ? '#' : null;\n });\n //sub out object/variable identifiers -> i\n var parsed3 = this.extractEnt(parsed2.src, IDENTIFIERS, 'i');\n //remove white-space\n parsed3.src = parsed3.src.replace(/\\s+/g, '');\n\n //the rest of this is simply to boil the expression down and check validity\n var simplified = parsed3.src;\n //sub out complex literals (objects/arrays) -> ~\n // the distinction is necessary because @ and # can be subscripts but ~ cannot\n while (simplified != (simplified = this.replaceComplex(simplified)));\n //now @ represents strings, # represents other primitives and ~ represents non-primitives\n //replace complex variables (those with dot/subscript accessors) -> v\n while (simplified != (simplified = simplified.replace(/i(\\.i|\\[[@#i]\\])+/, 'v')));\n //empty subscript or complex variables in subscript, are not permitted\n simplified = simplified.replace(/[iv]\\[v?\\]/g, 'x');\n //sub in \"i\" for @ and # and ~ and v (now \"i\" represents all literals, variables and identifiers)\n simplified = simplified.replace(/[@#~v]/g, 'i');\n //sub out operators\n simplified = simplified.replace(OPERATORS, '%');\n //allow 'not' unary operator\n simplified = simplified.replace(/!+[i]/g, 'i');\n var terms = opts.terms ? simplified.split(',') : [simplified];\n terms.forEach(function (term) {\n //simplify logical grouping\n while (term != (term = term.replace(/\\(i(%i)*\\)/g, 'i')));\n if (!term.match(/^i(%i)*$/)) {\n throw new Error('Invalid expression: ' + src);\n }\n });\n parsed3.src = parsed3.src.replace(VARIABLES, this.parseVar.bind(this));\n parsed2.src = this.injectEnt(parsed3, 'i');\n parsed1.src = this.injectEnt(parsed2, '#');\n return this.injectEnt(parsed1, '@');\n};\n\nParser.prototype.parseVar = function (src) {\n var args = Array.prototype.slice.call(arguments);\n var str = args.pop(), index = args.pop();\n //quote bare object identifiers (might be a reserved word like {while: 1})\n if (src == 'i' && str.charAt(index + 1) == ':') {\n return '\"i\"';\n }\n var parts = ['\"i\"'];\n src.replace(ACCESSOR, function (part) {\n if (part == '.i') {\n parts.push('\"i\"');\n } else if (part == '[i]') {\n parts.push('get(\"i\")');\n } else {\n parts.push(part.slice(1, -1));\n }\n });\n return 'get(' + parts.join(',') + ')';\n};\n\n//escapes a name to be used as a javascript identifier\nParser.prototype.escName = function (str) {\n return str.replace(/\\W/g, function (s) {\n return '$' + s.charCodeAt(0).toString(16);\n });\n};\n\nParser.prototype.parseQuoted = function (str) {\n if (str.charAt(0) == \"'\") {\n str = str.slice(1, -1).replace(/\\\\.|\"/, function (s) {\n if (s == \"\\\\'\") return \"'\";\n return s.charAt(0) == '\\\\' ? s : ('\\\\' + s);\n });\n str = '\"' + str + '\"';\n }\n try {\n return JSON.parse(str);\n } catch (e){\n console.error(\"could not parse string \"+str+\"! replacing by empty\")\n return \"\";\n }\n};\n\n/*!\n * Helpers\n */\n\nfunction trimLeft(str) {\n return str.replace(LEADING_SPACE, '');\n}\n\nfunction trimRight(str) {\n return str.replace(TRAILING_SPACE, '');\n}\n\nfunction matchAll(str, reg, fn) {\n return new Promise(function (resolve, reject) {\n //copy as global\n reg = new RegExp(reg.source, 'g' + (reg.ignoreCase ? 'i' : '') + (reg.multiline ? 'm' : ''));\n var match = reg.exec(str);\n\n function recurse_match() {\n if (match) {\n fn(match[0], match.index, str).then(function (result) {\n if (typeof result == 'number') {\n reg.lastIndex = result;\n }\n match = reg.exec(str);\n recurse_match();\n });\n } else {\n resolve();\n }\n }\n\n recurse_match();\n });\n}\n","/*!\r\n * Jinja Templating for JavaScript with asyncronous template file loader v0.1.8\r\n * https://github.com/kreopt/jinjajs\r\n * Forked from https://github.com/sstur/jinja-js\r\n */\r\nwindow.jinja = {};\r\n\r\n//the context 'this' inside tag_handlers is the parser instance\r\njinja.tag_handlers = {};\r\njinja.filter_handlers = {};\r\n\r\nvar _toString = Object.prototype.toString;\r\nvar _hasOwnProperty = Object.prototype.hasOwnProperty;\r\nvar toString = function (val) {\r\n if (val == null) return '';\r\n return (typeof val.toString == 'function') ? val.toString() : _toString.call(val);\r\n};\r\n\r\nvar getRuntime = function runtime(data, opts) {\r\n var defaults = {autoEscape: 'html'};\r\n var extend = function (dest, src) {\r\n Object.keys(src).forEach(function (key) {\r\n dest[key] = src[key];\r\n });\r\n return dest;\r\n };\r\n //get a value, lexically, starting in current context; a.b -> get(\"a\",\"b\")\r\n var get = function () {\r\n var val, n = arguments[0], c = stack.length;\r\n while (c--) {\r\n val = stack[c][n];\r\n if (typeof val != 'undefined') break;\r\n }\r\n for (var i = 1, len = arguments.length; i < len; i++) {\r\n if (val == null) continue;\r\n n = arguments[i];\r\n val = (_hasOwnProperty.call(val, n)) ? val[n] : (typeof val._get == 'function' ? (val[n] = val._get(n)) : null);\r\n }\r\n return (val == null) ? null : val;\r\n };\r\n var set = function (n, val) {\r\n stack[stack.length - 1][n] = val;\r\n };\r\n var push = function (ctx) {\r\n stack.push(ctx || {});\r\n };\r\n var pop = function () {\r\n stack.pop();\r\n };\r\n var write = function (str) {\r\n output.push(str);\r\n };\r\n var filter = function (val) {\r\n for (var i = 1, len = arguments.length; i < len; i++) {\r\n var arr = arguments[i], name = arr[0], filter = jinja.filter_handlers[name];\r\n if (filter) {\r\n arr[0] = val;\r\n //now arr looks like [val, arg1, arg2]\r\n val = filter.apply(data, arr);\r\n } else {\r\n throw new Error('Invalid filter: ' + name);\r\n }\r\n }\r\n if (opts.autoEscape && name != opts.autoEscape && name != 'safe') {\r\n //auto escape if not explicitly safe or already escaped\r\n val = jinja.filter_handlers[opts.autoEscape].call(data, val);\r\n }\r\n output.push(val);\r\n };\r\n var each = function (obj, loopvar, fn1, fn2) {\r\n if (obj == null) return;\r\n var arr = Array.isArray(obj) ? obj : Object.keys(obj), len = arr.length;\r\n var ctx = {loop: {length: len, first: arr[0], last: arr[len - 1]}};\r\n push(ctx);\r\n for (var i = 0; i < len; i++) {\r\n extend(ctx.loop, {index: i + 1, index0: i});\r\n fn1(ctx[loopvar] = arr[i]);\r\n }\r\n if (len == 0 && fn2) fn2();\r\n pop();\r\n };\r\n var block = function (fn) {\r\n push();\r\n fn();\r\n pop();\r\n };\r\n var render = function () {\r\n return output.join('');\r\n };\r\n data = data || {};\r\n opts = extend(defaults, opts || {});\r\n var stack = [Object.create(data || {})], output = [];\r\n return {get: get, set: set, push: push, pop: pop, write: write, filter: filter, each: each, block: block, render: render};\r\n};\r\n\r\nvar runtime;\r\n\r\njinja.make_tag = function(name, handler){\r\n if (typeof handler == typeof ''){\r\n jinja.tag_handlers[name] = jinja.tag_handlers[handler];\r\n } else {\r\n jinja.tag_handlers[name] = handler;\r\n }\r\n};\r\njinja.make_filter = function(name, filter){\r\n if (jinja.filter_handlers.name) {console.warn('Filter '+name+' already exists. Overriding.');}\r\n jinja.filter_handlers[name] = filter;\r\n};\r\n\r\njinja.compile = function (markup, opts) {\r\n var _this = this;\r\n return new Promise(function (resolve, reject) {\r\n opts = opts || {};\r\n var parser = new Parser();\r\n parser.readTemplateFile = _this.readTemplateFile;\r\n var code = [];\r\n code.push('function render($) {');\r\n code.push('var get = $.get, set = $.set, push = $.push, pop = $.pop, write = $.write, filter = $.filter, each = $.each, block = $.block;');\r\n parser.parse(markup).then(function (html) {\r\n code.push.apply(code, html);\r\n code.push('return $.render();');\r\n code.push('}');\r\n code = code.join('\\n');\r\n if (opts.runtime === false) {\r\n var fn = new Function('data', 'options', 'return (' + code + ')(runtime(data, options))');\r\n } else {\r\n runtime = runtime || (runtime = getRuntime.toString());\r\n fn = new Function('data', 'options', 'return (' + code + ')((' + runtime + ')(data, options))');\r\n }\r\n resolve({render: fn});\r\n });\r\n });\r\n};\r\n\r\njinja.render = function (markup, data, opts) {\r\n return new Promise(function(resolve, reject){\r\n var awaiting_data={};\r\n var promises=[];\r\n for (var d in data){\r\n if (data[d] instanceof Promise){\r\n awaiting_data[d] = promises.length;\r\n promises.push(data[d]);\r\n }\r\n }\r\n\r\n Promise.all(promises).then(function(values){\r\n\r\n for (var d in awaiting_data){\r\n data[d] = values[awaiting_data[d]];\r\n }\r\n\r\n jinja.compile(markup).then(function (tmpl) {\r\n resolve(tmpl.render(data, opts));\r\n });\r\n }).catch(function(e){\r\n console.error(e);\r\n });\r\n })\r\n};\r\n\r\njinja.templateFiles = {};\r\njinja.template_url = '/templates/';\r\njinja.readTemplateFile = function (name) {\r\n if (!jinja.loader){\r\n throw new Error(\"template loader is not set!\");\r\n }\r\n return new Promise(function (resolve, reject) {\r\n var templateFiles = jinja.templateFiles || {};\r\n var templateFile = templateFiles[name];\r\n if (templateFile == null) {\r\n return jinja.loader(jinja.template_url + name).then(function(data){\r\n resolve(data);\r\n }).catch(function (reason) {\r\n reject('Template file \"'+name+'\" not found: ' + reason);\r\n }); \r\n } else {\r\n resolve(templateFile);\r\n }\r\n });\r\n};\r\n","jinja.loader = function(path){\n return fetch(path).then(function(response){\n // status \"0\" to handle local files fetching (e.g. Cordova/Phonegap etc.)\n if (response.status === 200 || response.status === 0) {\n return response.text().then(function(data){\n console.log(data);\n jinja.templateFiles[name] = data;\n return jinja.templateFiles[name];\n }).catch(function(r){\n \"use strict\";\n console.log(\":(\")\n });\n } else {\n return Promise.reject(new Error(response.statusText))\n }\n })\n}\n","jinja.make_filter('html', function (val) {\n return toString(val)\n .split('&').join('&')\n .split('<').join('<')\n .split('>').join('>')\n .split('\"').join('"');\n});\n","jinja.make_filter('safe', function (val) {\n return val;\n});\n","jinja.make_tag('comment', function () {\n this.commentMode = true;\n});\njinja.make_tag('endcomment', function () {\n this.commentMode = false;\n});\n","jinja.make_tag('block', function (name) {\n if (this.isParent) {\n ++this.parentBlocks;\n var blockName = 'block_' + (this.escName(name) || this.parentBlocks);\n this.push('block(typeof ' + blockName + ' == \"function\" ? ' + blockName + ' : function() {');\n } else if (this.hasParent) {\n this.isSilent = false;\n ++this.childBlocks;\n blockName = 'block_' + (this.escName(name) || this.childBlocks);\n this.push('function ' + blockName + '() {');\n }\n this.nest.unshift('block');\n});\n\njinja.make_tag('endblock', function () {\n this.nest.shift();\n if (this.isParent) {\n this.push('});');\n } else if (this.hasParent) {\n this.push('}');\n this.isSilent = true;\n }\n});\n\njinja.make_tag('extends', function (name) {\n if (name[0].startsWith(\"'\") || name[0].startsWith(\"\\\"\")) {\n name = this.parseQuoted(name);\n }\n var _this = this;\n return this.readTemplateFile(name).then(function (parentSrc) {\n _this.isParent = true;\n return _this.tokenize(parentSrc).then(function(){\n _this.isParent = false;\n _this.hasParent = true;\n //silence output until we enter a child block\n _this.isSilent = true;\n });\n }).catch(function(e){\n console.error(e);\n });\n});\n","jinja.make_tag('for', function (str) {\n var i = str.indexOf(' in ');\n var name = str.slice(0, i).trim();\n var expr = str.slice(i + 4).trim();\n this.push('each(' + this.parseExpr(expr) + ',' + JSON.stringify(name) + ',function() {');\n this.nest.unshift('for');\n});\njinja.make_tag('endfor', function () {\n this.nest.shift();\n this.push('});');\n});\n","jinja.make_tag('if', function (expr) {\n this.push('if (' + this.parseExpr(expr) + ') {');\n this.nest.unshift('if');\n});\n\njinja.make_tag('else', function () {\n if (this.nest[0] == 'for') {\n this.push('}, function() {');\n } else {\n this.push('} else {');\n }\n});\n\njinja.make_tag('elseif', function (expr) {\n this.push('} else if (' + this.parseExpr(expr) + ') {');\n});\njinja.make_tag('elif', 'elseif');\n\njinja.make_tag('endif', function () {\n this.nest.shift();\n this.push('}');\n});","jinja.make_tag('include', function (name) {\n if (name[0].startsWith(\"'\") || name[0].startsWith(\"\\\"\")) {\n name = this.parseQuoted(name);\n }\n var _this = this;\n return this.readTemplateFile(name).then(function (incSrc) {\n _this.isInclude = true;\n return _this.tokenize(incSrc).then(function(){\n _this.isInclude = false;\n });\n }).catch(function(e){\n console.error(e);\n });\n});\n","jinja.make_tag('load', function (name) {});\n","jinja.make_tag('raw', function () {\n this.rawMode = true;\n});\njinja.make_tag('endraw', function () {\n this.rawMode = false;\n});\n","jinja.make_tag('set', function (stmt) {\n var i = stmt.indexOf('=');\n var name = stmt.slice(0, i).trim();\n var expr = stmt.slice(i + 1).trim();\n this.push('set(' + JSON.stringify(name) + ',' + this.parseExpr(expr) + ');');\n});\n\njinja.make_tag('assign', 'set');","jinja.make_tag('static',function(stmt){\n stmt = stmt.trim();\n this.push(\"write(\\\"\"+Fat.config.static_url + stmt.substr(1,stmt.length-2)+\"\\\")\");\n});\n","jinja.make_tag('static',function(stmt){\n stmt = stmt.trim();\n\tvar parts = stmt.split(/\\s/);\n\tif (parts.length < 1){\n\t\tconsole.warn(\"url tag should contain 1 or more parameters. ignoring. \");\n\t\treturn;\n\t}\n\t// TODO: check quotes\n\tvar name = parts[0].substr(1,parts[0].length-2);\n\tvar args={positional:[], keyword:{}};\n\tfor (var i=1; i<parts.length; i++){\t\n\t\tif (parts[i].indexOd('=')!=-1){\n\t\t\tvar kw=parts[i].split('=');\n\t\t\targs.keyword[kw[0].trim()]=kw[1].trim();\n\t\t} else {\n\t\t\targs.positional.push(parts[i].trim());\n\t\t}\n\t}\n this.push(\"write(\\\"\"+Fat.resolve_url(name, args)+\"\\\")\");\n});\n"],"sourceRoot":"/source/"}