UNPKG

nunjucks

Version:

A powerful templating engine with inheritance, asynchronous control, and more (jinja2 inspired)

370 lines (280 loc) 6.86 kB
'use strict'; var ArrayProto = Array.prototype; var ObjProto = Object.prototype; var escapeMap = { '&': '&amp;', '"': '&quot;', '\'': '&#39;', '<': '&lt;', '>': '&gt;' }; var escapeRegex = /[&"'<>]/g; var exports = module.exports = {}; function hasOwnProp(obj, k) { return ObjProto.hasOwnProperty.call(obj, k); } exports.hasOwnProp = hasOwnProp; function lookupEscape(ch) { return escapeMap[ch]; } function _prettifyError(path, withInternals, err) { if (!err.Update) { // not one of ours, cast it err = new exports.TemplateError(err); } err.Update(path); // Unless they marked the dev flag, show them a trace from here if (!withInternals) { var old = err; err = new Error(old.message); err.name = old.name; } return err; } exports._prettifyError = _prettifyError; function TemplateError(message, lineno, colno) { var _this = this; var err; var cause; if (message instanceof Error) { cause = message; message = cause.name + ": " + cause.message; } if (Object.setPrototypeOf) { err = new Error(message); Object.setPrototypeOf(err, TemplateError.prototype); } else { err = this; Object.defineProperty(err, 'message', { enumerable: false, writable: true, value: message }); } Object.defineProperty(err, 'name', { value: 'Template render error' }); if (Error.captureStackTrace) { Error.captureStackTrace(err, this.constructor); } var getStack; if (cause) { var stackDescriptor = Object.getOwnPropertyDescriptor(cause, 'stack'); getStack = stackDescriptor && (stackDescriptor.get || function () { return stackDescriptor.value; }); if (!getStack) { getStack = function getStack() { return cause.stack; }; } } else { var stack = new Error(message).stack; getStack = function getStack() { return stack; }; } Object.defineProperty(err, 'stack', { get: function get() { return getStack.call(_this); } }); Object.defineProperty(err, 'cause', { value: cause }); err.lineno = lineno; err.colno = colno; err.firstUpdate = true; err.Update = function (path) { var msg = '(' + (path || 'unknown path') + ')'; // only show lineno + colno next to path of template // where error occurred if (_this.firstUpdate) { if (_this.lineno && _this.colno) { msg += " [Line " + _this.lineno + ", Column " + _this.colno + "]"; } else if (_this.lineno) { msg += " [Line " + _this.lineno + "]"; } } msg += '\n '; if (_this.firstUpdate) { msg += ' '; } _this.message = msg + (_this.message || ''); _this.firstUpdate = false; return _this; }; return err; } if (Object.setPrototypeOf) { Object.setPrototypeOf(TemplateError.prototype, Error.prototype); } else { TemplateError.prototype = Object.create(Error.prototype, { constructor: { value: TemplateError } }); } exports.TemplateError = TemplateError; function escape(val) { return val.replace(escapeRegex, lookupEscape); } exports.escape = escape; function isFunction(obj) { return ObjProto.toString.call(obj) === '[object Function]'; } exports.isFunction = isFunction; function isArray(obj) { return ObjProto.toString.call(obj) === '[object Array]'; } exports.isArray = isArray; function isString(obj) { return ObjProto.toString.call(obj) === '[object String]'; } exports.isString = isString; function isObject(obj) { return ObjProto.toString.call(obj) === '[object Object]'; } exports.isObject = isObject; function groupBy(obj, val) { var result = {}; var iterator = isFunction(val) ? val : function (o) { return o[val]; }; for (var i = 0; i < obj.length; i++) { var value = obj[i]; var key = iterator(value, i); (result[key] || (result[key] = [])).push(value); } return result; } exports.groupBy = groupBy; function toArray(obj) { return Array.prototype.slice.call(obj); } exports.toArray = toArray; function without(array) { var result = []; if (!array) { return result; } var length = array.length; var contains = toArray(arguments).slice(1); var index = -1; while (++index < length) { if (indexOf(contains, array[index]) === -1) { result.push(array[index]); } } return result; } exports.without = without; function repeat(char_, n) { var str = ''; for (var i = 0; i < n; i++) { str += char_; } return str; } exports.repeat = repeat; function each(obj, func, context) { if (obj == null) { return; } if (ArrayProto.forEach && obj.forEach === ArrayProto.forEach) { obj.forEach(func, context); } else if (obj.length === +obj.length) { for (var i = 0, l = obj.length; i < l; i++) { func.call(context, obj[i], i, obj); } } } exports.each = each; function map(obj, func) { var results = []; if (obj == null) { return results; } if (ArrayProto.map && obj.map === ArrayProto.map) { return obj.map(func); } for (var i = 0; i < obj.length; i++) { results[results.length] = func(obj[i], i); } if (obj.length === +obj.length) { results.length = obj.length; } return results; } exports.map = map; function asyncIter(arr, iter, cb) { var i = -1; function next() { i++; if (i < arr.length) { iter(arr[i], i, next, cb); } else { cb(); } } next(); } exports.asyncIter = asyncIter; function asyncFor(obj, iter, cb) { var keys = keys_(obj || {}); var len = keys.length; var i = -1; function next() { i++; var k = keys[i]; if (i < len) { iter(k, obj[k], i, len, next); } else { cb(); } } next(); } exports.asyncFor = asyncFor; function indexOf(arr, searchElement, fromIndex) { return Array.prototype.indexOf.call(arr || [], searchElement, fromIndex); } exports.indexOf = indexOf; function keys_(obj) { /* eslint-disable no-restricted-syntax */ var arr = []; for (var k in obj) { if (hasOwnProp(obj, k)) { arr.push(k); } } return arr; } exports.keys = keys_; function _entries(obj) { return keys_(obj).map(function (k) { return [k, obj[k]]; }); } exports._entries = _entries; function _values(obj) { return keys_(obj).map(function (k) { return obj[k]; }); } exports._values = _values; function extend(obj1, obj2) { obj1 = obj1 || {}; keys_(obj2).forEach(function (k) { obj1[k] = obj2[k]; }); return obj1; } exports._assign = exports.extend = extend; function inOperator(key, val) { if (isArray(val) || isString(val)) { return val.indexOf(key) !== -1; } else if (isObject(val)) { return key in val; } throw new Error('Cannot use "in" operator to search for "' + key + '" in unexpected types.'); } exports.inOperator = inOperator;