1'use strict'; 2 3var ArrayProto = Array.prototype; 4var ObjProto = Object.prototype; 5var escapeMap = { 6 '&': '&', 7 '"': '"', 8 '\'': ''', 9 '<': '<', 10 '>': '>', 11 '\\': '\' 12}; 13var escapeRegex = /[&"'<>\\]/g; 14var _exports = module.exports = {}; 15function hasOwnProp(obj, k) { 16 return ObjProto.hasOwnProperty.call(obj, k); 17} 18_exports.hasOwnProp = hasOwnProp; 19function lookupEscape(ch) { 20 return escapeMap[ch]; 21} 22function _prettifyError(path, withInternals, err) { 23 if (!err.Update) { 24 // not one of ours, cast it 25 err = new _exports.TemplateError(err); 26 } 27 err.Update(path); 28 29 // Unless they marked the dev flag, show them a trace from here 30 if (!withInternals) { 31 var old = err; 32 err = new Error(old.message); 33 err.name = old.name; 34 } 35 return err; 36} 37_exports._prettifyError = _prettifyError; 38function TemplateError(message, lineno, colno) { 39 var err; 40 var cause; 41 if (message instanceof Error) { 42 cause = message; 43 message = cause.name + ": " + cause.message; 44 } 45 if (Object.setPrototypeOf) { 46 err = new Error(message); 47 Object.setPrototypeOf(err, TemplateError.prototype); 48 } else { 49 err = this; 50 Object.defineProperty(err, 'message', { 51 enumerable: false, 52 writable: true, 53 value: message 54 }); 55 } 56 Object.defineProperty(err, 'name', { 57 value: 'Template render error' 58 }); 59 if (Error.captureStackTrace) { 60 Error.captureStackTrace(err, this.constructor); 61 } 62 var getStack; 63 if (cause) { 64 var stackDescriptor = Object.getOwnPropertyDescriptor(cause, 'stack'); 65 getStack = stackDescriptor && (stackDescriptor.get || function () { 66 return stackDescriptor.value; 67 }); 68 if (!getStack) { 69 getStack = function getStack() { 70 return cause.stack; 71 }; 72 } 73 } else { 74 var stack = new Error(message).stack; 75 getStack = function getStack() { 76 return stack; 77 }; 78 } 79 Object.defineProperty(err, 'stack', { 80 get: function get() { 81 return getStack.call(err); 82 } 83 }); 84 Object.defineProperty(err, 'cause', { 85 value: cause 86 }); 87 err.lineno = lineno; 88 err.colno = colno; 89 err.firstUpdate = true; 90 err.Update = function Update(path) { 91 var msg = '(' + (path || 'unknown path') + ')'; 92 93 // only show lineno + colno next to path of template 94 // where error occurred 95 if (this.firstUpdate) { 96 if (this.lineno && this.colno) { 97 msg += " [Line " + this.lineno + ", Column " + this.colno + "]"; 98 } else if (this.lineno) { 99 msg += " [Line " + this.lineno + "]"; 100 } 101 } 102 msg += '\n '; 103 if (this.firstUpdate) { 104 msg += ' '; 105 } 106 this.message = msg + (this.message || ''); 107 this.firstUpdate = false; 108 return this; 109 }; 110 return err; 111} 112if (Object.setPrototypeOf) { 113 Object.setPrototypeOf(TemplateError.prototype, Error.prototype); 114} else { 115 TemplateError.prototype = Object.create(Error.prototype, { 116 constructor: { 117 value: TemplateError 118 } 119 }); 120} 121_exports.TemplateError = TemplateError; 122function escape(val) { 123 return val.replace(escapeRegex, lookupEscape); 124} 125_exports.escape = escape; 126function isFunction(obj) { 127 return ObjProto.toString.call(obj) === '[object Function]'; 128} 129_exports.isFunction = isFunction; 130function isArray(obj) { 131 return ObjProto.toString.call(obj) === '[object Array]'; 132} 133_exports.isArray = isArray; 134function isString(obj) { 135 return ObjProto.toString.call(obj) === '[object String]'; 136} 137_exports.isString = isString; 138function isObject(obj) { 139 return ObjProto.toString.call(obj) === '[object Object]'; 140} 141_exports.isObject = isObject; 142 143/** 144 * @param {string|number} attr 145 * @returns {(string|number)[]} 146 * @private 147 */ 148function _prepareAttributeParts(attr) { 149 if (!attr) { 150 return []; 151 } 152 if (typeof attr === 'string') { 153 return attr.split('.'); 154 } 155 return [attr]; 156} 157 158/** 159 * @param {string} attribute Attribute value. Dots allowed. 160 * @returns {function(Object): *} 161 */ 162function getAttrGetter(attribute) { 163 var parts = _prepareAttributeParts(attribute); 164 return function attrGetter(item) { 165 var _item = item; 166 for (var i = 0; i < parts.length; i++) { 167 var part = parts[i]; 168 169 // If item is not an object, and we still got parts to handle, it means 170 // that something goes wrong. Just roll out to undefined in that case. 171 if (hasOwnProp(_item, part)) { 172 _item = _item[part]; 173 } else { 174 return undefined; 175 } 176 } 177 return _item; 178 }; 179} 180_exports.getAttrGetter = getAttrGetter; 181function groupBy(obj, val, throwOnUndefined) { 182 var result = {}; 183 var iterator = isFunction(val) ? val : getAttrGetter(val); 184 for (var i = 0; i < obj.length; i++) { 185 var value = obj[i]; 186 var key = iterator(value, i); 187 if (key === undefined && throwOnUndefined === true) { 188 throw new TypeError("groupby: attribute \"" + val + "\" resolved to undefined"); 189 } 190 (result[key] || (result[key] = [])).push(value); 191 } 192 return result; 193} 194_exports.groupBy = groupBy; 195function toArray(obj) { 196 return Array.prototype.slice.call(obj); 197} 198_exports.toArray = toArray; 199function without(array) { 200 var result = []; 201 if (!array) { 202 return result; 203 } 204 var length = array.length; 205 var contains = toArray(arguments).slice(1); 206 var index = -1; 207 while (++index < length) { 208 if (indexOf(contains, array[index]) === -1) { 209 result.push(array[index]); 210 } 211 } 212 return result; 213} 214_exports.without = without; 215function repeat(char_, n) { 216 var str = ''; 217 for (var i = 0; i < n; i++) { 218 str += char_; 219 } 220 return str; 221} 222_exports.repeat = repeat; 223function each(obj, func, context) { 224 if (obj == null) { 225 return; 226 } 227 if (ArrayProto.forEach && obj.forEach === ArrayProto.forEach) { 228 obj.forEach(func, context); 229 } else if (obj.length === +obj.length) { 230 for (var i = 0, l = obj.length; i < l; i++) { 231 func.call(context, obj[i], i, obj); 232 } 233 } 234} 235_exports.each = each; 236function map(obj, func) { 237 var results = []; 238 if (obj == null) { 239 return results; 240 } 241 if (ArrayProto.map && obj.map === ArrayProto.map) { 242 return obj.map(func); 243 } 244 for (var i = 0; i < obj.length; i++) { 245 results[results.length] = func(obj[i], i); 246 } 247 if (obj.length === +obj.length) { 248 results.length = obj.length; 249 } 250 return results; 251} 252_exports.map = map; 253function asyncIter(arr, iter, cb) { 254 var i = -1; 255 function next() { 256 i++; 257 if (i < arr.length) { 258 iter(arr[i], i, next, cb); 259 } else { 260 cb(); 261 } 262 } 263 next(); 264} 265_exports.asyncIter = asyncIter; 266function asyncFor(obj, iter, cb) { 267 var keys = keys_(obj || {}); 268 var len = keys.length; 269 var i = -1; 270 function next() { 271 i++; 272 var k = keys[i]; 273 if (i < len) { 274 iter(k, obj[k], i, len, next); 275 } else { 276 cb(); 277 } 278 } 279 next(); 280} 281_exports.asyncFor = asyncFor; 282function indexOf(arr, searchElement, fromIndex) { 283 return Array.prototype.indexOf.call(arr || [], searchElement, fromIndex); 284} 285_exports.indexOf = indexOf; 286function keys_(obj) { 287 /* eslint-disable no-restricted-syntax */ 288 var arr = []; 289 for (var k in obj) { 290 if (hasOwnProp(obj, k)) { 291 arr.push(k); 292 } 293 } 294 return arr; 295} 296_exports.keys = keys_; 297function _entries(obj) { 298 return keys_(obj).map(function (k) { 299 return [k, obj[k]]; 300 }); 301} 302_exports._entries = _entries; 303function _values(obj) { 304 return keys_(obj).map(function (k) { 305 return obj[k]; 306 }); 307} 308_exports._values = _values; 309function extend(obj1, obj2) { 310 obj1 = obj1 || {}; 311 keys_(obj2).forEach(function (k) { 312 obj1[k] = obj2[k]; 313 }); 314 return obj1; 315} 316_exports._assign = _exports.extend = extend; 317function inOperator(key, val) { 318 if (isArray(val) || isString(val)) { 319 return val.indexOf(key) !== -1; 320 } else if (isObject(val)) { 321 return key in val; 322 } 323 throw new Error('Cannot use "in" operator to search for "' + key + '" in unexpected types.'); 324} 325_exports.inOperator = inOperator;