123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 |
- 'use strict';
-
- var lib = require('./lib');
-
- var arrayFrom = Array.from;
- var supportsIterators = typeof Symbol === 'function' && Symbol.iterator && typeof arrayFrom === 'function'; // Frames keep track of scoping both at compile-time and run-time so
- // we know how to access variables. Block tags can introduce special
- // variables, for example.
-
- var Frame = /*#__PURE__*/function () {
- function Frame(parent, isolateWrites) {
- this.variables = Object.create(null);
- this.parent = parent;
- this.topLevel = false; // if this is true, writes (set) should never propagate upwards past
- // this frame to its parent (though reads may).
-
- this.isolateWrites = isolateWrites;
- }
-
- var _proto = Frame.prototype;
-
- _proto.set = function set(name, val, resolveUp) {
- // Allow variables with dots by automatically creating the
- // nested structure
- var parts = name.split('.');
- var obj = this.variables;
- var frame = this;
-
- if (resolveUp) {
- if (frame = this.resolve(parts[0], true)) {
- frame.set(name, val);
- return;
- }
- }
-
- for (var i = 0; i < parts.length - 1; i++) {
- var id = parts[i];
-
- if (!obj[id]) {
- obj[id] = {};
- }
-
- obj = obj[id];
- }
-
- obj[parts[parts.length - 1]] = val;
- };
-
- _proto.get = function get(name) {
- var val = this.variables[name];
-
- if (val !== undefined) {
- return val;
- }
-
- return null;
- };
-
- _proto.lookup = function lookup(name) {
- var p = this.parent;
- var val = this.variables[name];
-
- if (val !== undefined) {
- return val;
- }
-
- return p && p.lookup(name);
- };
-
- _proto.resolve = function resolve(name, forWrite) {
- var p = forWrite && this.isolateWrites ? undefined : this.parent;
- var val = this.variables[name];
-
- if (val !== undefined) {
- return this;
- }
-
- return p && p.resolve(name);
- };
-
- _proto.push = function push(isolateWrites) {
- return new Frame(this, isolateWrites);
- };
-
- _proto.pop = function pop() {
- return this.parent;
- };
-
- return Frame;
- }();
-
- function makeMacro(argNames, kwargNames, func) {
- return function macro() {
- for (var _len = arguments.length, macroArgs = new Array(_len), _key = 0; _key < _len; _key++) {
- macroArgs[_key] = arguments[_key];
- }
-
- var argCount = numArgs(macroArgs);
- var args;
- var kwargs = getKeywordArgs(macroArgs);
-
- if (argCount > argNames.length) {
- args = macroArgs.slice(0, argNames.length); // Positional arguments that should be passed in as
- // keyword arguments (essentially default values)
-
- macroArgs.slice(args.length, argCount).forEach(function (val, i) {
- if (i < kwargNames.length) {
- kwargs[kwargNames[i]] = val;
- }
- });
- args.push(kwargs);
- } else if (argCount < argNames.length) {
- args = macroArgs.slice(0, argCount);
-
- for (var i = argCount; i < argNames.length; i++) {
- var arg = argNames[i]; // Keyword arguments that should be passed as
- // positional arguments, i.e. the caller explicitly
- // used the name of a positional arg
-
- args.push(kwargs[arg]);
- delete kwargs[arg];
- }
-
- args.push(kwargs);
- } else {
- args = macroArgs;
- }
-
- return func.apply(this, args);
- };
- }
-
- function makeKeywordArgs(obj) {
- obj.__keywords = true;
- return obj;
- }
-
- function isKeywordArgs(obj) {
- return obj && Object.prototype.hasOwnProperty.call(obj, '__keywords');
- }
-
- function getKeywordArgs(args) {
- var len = args.length;
-
- if (len) {
- var lastArg = args[len - 1];
-
- if (isKeywordArgs(lastArg)) {
- return lastArg;
- }
- }
-
- return {};
- }
-
- function numArgs(args) {
- var len = args.length;
-
- if (len === 0) {
- return 0;
- }
-
- var lastArg = args[len - 1];
-
- if (isKeywordArgs(lastArg)) {
- return len - 1;
- } else {
- return len;
- }
- } // A SafeString object indicates that the string should not be
- // autoescaped. This happens magically because autoescaping only
- // occurs on primitive string objects.
-
-
- function SafeString(val) {
- if (typeof val !== 'string') {
- return val;
- }
-
- this.val = val;
- this.length = val.length;
- }
-
- SafeString.prototype = Object.create(String.prototype, {
- length: {
- writable: true,
- configurable: true,
- value: 0
- }
- });
-
- SafeString.prototype.valueOf = function valueOf() {
- return this.val;
- };
-
- SafeString.prototype.toString = function toString() {
- return this.val;
- };
-
- function copySafeness(dest, target) {
- if (dest instanceof SafeString) {
- return new SafeString(target);
- }
-
- return target.toString();
- }
-
- function markSafe(val) {
- var type = typeof val;
-
- if (type === 'string') {
- return new SafeString(val);
- } else if (type !== 'function') {
- return val;
- } else {
- return function wrapSafe(args) {
- var ret = val.apply(this, arguments);
-
- if (typeof ret === 'string') {
- return new SafeString(ret);
- }
-
- return ret;
- };
- }
- }
-
- function suppressValue(val, autoescape) {
- val = val !== undefined && val !== null ? val : '';
-
- if (autoescape && !(val instanceof SafeString)) {
- val = lib.escape(val.toString());
- }
-
- return val;
- }
-
- function ensureDefined(val, lineno, colno) {
- if (val === null || val === undefined) {
- throw new lib.TemplateError('attempted to output null or undefined value', lineno + 1, colno + 1);
- }
-
- return val;
- }
-
- function memberLookup(obj, val) {
- if (obj === undefined || obj === null) {
- return undefined;
- }
-
- if (typeof obj[val] === 'function') {
- return function () {
- for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
- args[_key2] = arguments[_key2];
- }
-
- return obj[val].apply(obj, args);
- };
- }
-
- return obj[val];
- }
-
- function callWrap(obj, name, context, args) {
- if (!obj) {
- throw new Error('Unable to call `' + name + '`, which is undefined or falsey');
- } else if (typeof obj !== 'function') {
- throw new Error('Unable to call `' + name + '`, which is not a function');
- }
-
- return obj.apply(context, args);
- }
-
- function contextOrFrameLookup(context, frame, name) {
- var val = frame.lookup(name);
- return val !== undefined ? val : context.lookup(name);
- }
-
- function handleError(error, lineno, colno) {
- if (error.lineno) {
- return error;
- } else {
- return new lib.TemplateError(error, lineno, colno);
- }
- }
-
- function asyncEach(arr, dimen, iter, cb) {
- if (lib.isArray(arr)) {
- var len = arr.length;
- lib.asyncIter(arr, function iterCallback(item, i, next) {
- switch (dimen) {
- case 1:
- iter(item, i, len, next);
- break;
-
- case 2:
- iter(item[0], item[1], i, len, next);
- break;
-
- case 3:
- iter(item[0], item[1], item[2], i, len, next);
- break;
-
- default:
- item.push(i, len, next);
- iter.apply(this, item);
- }
- }, cb);
- } else {
- lib.asyncFor(arr, function iterCallback(key, val, i, len, next) {
- iter(key, val, i, len, next);
- }, cb);
- }
- }
-
- function asyncAll(arr, dimen, func, cb) {
- var finished = 0;
- var len;
- var outputArr;
-
- function done(i, output) {
- finished++;
- outputArr[i] = output;
-
- if (finished === len) {
- cb(null, outputArr.join(''));
- }
- }
-
- if (lib.isArray(arr)) {
- len = arr.length;
- outputArr = new Array(len);
-
- if (len === 0) {
- cb(null, '');
- } else {
- for (var i = 0; i < arr.length; i++) {
- var item = arr[i];
-
- switch (dimen) {
- case 1:
- func(item, i, len, done);
- break;
-
- case 2:
- func(item[0], item[1], i, len, done);
- break;
-
- case 3:
- func(item[0], item[1], item[2], i, len, done);
- break;
-
- default:
- item.push(i, len, done);
- func.apply(this, item);
- }
- }
- }
- } else {
- var keys = lib.keys(arr || {});
- len = keys.length;
- outputArr = new Array(len);
-
- if (len === 0) {
- cb(null, '');
- } else {
- for (var _i = 0; _i < keys.length; _i++) {
- var k = keys[_i];
- func(k, arr[k], _i, len, done);
- }
- }
- }
- }
-
- function fromIterator(arr) {
- if (typeof arr !== 'object' || arr === null || lib.isArray(arr)) {
- return arr;
- } else if (supportsIterators && Symbol.iterator in arr) {
- return arrayFrom(arr);
- } else {
- return arr;
- }
- }
-
- module.exports = {
- Frame: Frame,
- makeMacro: makeMacro,
- makeKeywordArgs: makeKeywordArgs,
- numArgs: numArgs,
- suppressValue: suppressValue,
- ensureDefined: ensureDefined,
- memberLookup: memberLookup,
- contextOrFrameLookup: contextOrFrameLookup,
- callWrap: callWrap,
- handleError: handleError,
- isArray: lib.isArray,
- keys: lib.keys,
- SafeString: SafeString,
- copySafeness: copySafeness,
- markSafe: markSafe,
- asyncEach: asyncEach,
- asyncAll: asyncAll,
- inOperator: lib.inOperator,
- fromIterator: fromIterator
- };
|