first
This commit is contained in:
333
node_modules/nunjucks/src/runtime.js
generated
vendored
Normal file
333
node_modules/nunjucks/src/runtime.js
generated
vendored
Normal file
@ -0,0 +1,333 @@
|
||||
'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
|
||||
};
|
||||
Reference in New Issue
Block a user