refactor: bundle template.js respectively

This commit is contained in:
harttle
2018-08-27 21:37:39 +08:00
parent 31c39561c9
commit d6876bd9ec
19 changed files with 4386 additions and 2152 deletions
+246 -317
View File
@@ -1230,24 +1230,145 @@ function factory(ctx, opts) {
return scope;
}
function get$1(url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.responseText);
} else {
reject(new Error(xhr.statusText));
}
};
xhr.onerror = function () {
reject(new Error('An error occurred whilst sending the response.'));
};
xhr.open('GET', url);
xhr.send();
/*
* Call functions in serial until someone resolved.
* @param {Array} iterable the array to iterate with.
* @param {Array} iteratee returns a new promise.
* The iteratee is invoked with three arguments: (value, index, iterable).
*/
function anySeries(iterable, iteratee) {
var ret = Promise.reject(new Error('init'));
iterable.forEach(function (item, idx) {
ret = ret.catch(function (e) {
return iteratee(item, idx, iterable);
});
});
return ret;
}
/*
* Call functions in serial until someone rejected.
* @param {Array} iterable the array to iterate with.
* @param {Array} iteratee returns a new promise.
* The iteratee is invoked with three arguments: (value, index, iterable).
*/
function mapSeries(iterable, iteratee) {
var ret = Promise.resolve('init');
var result = [];
iterable.forEach(function (item, idx) {
ret = ret.then(function () {
return iteratee(item, idx, iterable);
}).then(function (x) {
return result.push(x);
});
});
return ret.then(function () {
return result;
});
}
function readFileAsync(filepath) {
return new Promise(function (resolve, reject) {
fs.readFile(filepath, 'utf8', function (err, content) {
err ? reject(err) : resolve(content);
});
});
}
function statFileAsync(path$$1) {
return new Promise(function (resolve, reject) {
fs.stat(path$$1, function (err, stat) {
return err ? reject(err) : resolve(stat);
});
});
}
function lookup(filepath, root, options) {
var _this = this;
root = options.root.concat(root || []);
root = uniq(root);
var paths = root.map(function (root) {
return path.resolve(root || location.href, filepath);
});
return anySeries(paths, function () {
var _ref = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(path$$1) {
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.prev = 0;
_context.next = 3;
return statFileAsync(path$$1);
case 3:
return _context.abrupt('return', path$$1);
case 6:
_context.prev = 6;
_context.t0 = _context['catch'](0);
_context.t0.message = _context.t0.code + ': Failed to lookup ' + filepath + ' in: ' + root;
throw _context.t0;
case 10:
case 'end':
return _context.stop();
}
}
}, _callee, _this, [[0, 6]]);
}));
return function (_x) {
return _ref.apply(this, arguments);
};
}());
}
var resolve = function () {
var _ref2 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(filepath, root, options) {
return regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
if (!path.extname(filepath)) {
filepath += options.extname;
}
return _context2.abrupt('return', lookup(filepath, root, options));
case 2:
case 'end':
return _context2.stop();
}
}
}, _callee2, this);
}));
return function resolve(_x2, _x3, _x4) {
return _ref2.apply(this, arguments);
};
}();
var read = function () {
var _ref3 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(filepath) {
return regeneratorRuntime.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
return _context3.abrupt('return', readFileAsync(filepath));
case 1:
case 'end':
return _context3.stop();
}
}
}, _callee3, this);
}));
return function read(_x5) {
return _ref3.apply(this, arguments);
};
}();
function whiteSpaceCtrl(tokens, options) {
options = assign({ greedy: true }, options);
var inRaw = false;
@@ -1373,61 +1494,6 @@ function LineNumber(html) {
};
}
function readFileAsync(filepath) {
return new Promise(function (resolve, reject) {
fs.readFile(filepath, 'utf8', function (err, content) {
err ? reject(err) : resolve(content);
});
});
}
function statFileAsync(path$$1) {
return new Promise(function (resolve, reject) {
fs.stat(path$$1, function (err, stat) {
return err ? reject(err) : resolve(stat);
});
});
}
var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^/]+?|)(\.[^./]*|))(?:[/]*)$/;
var urlRe = /^(?:\w+:)?\/\/([^\s.]+\.\S{2}|localhost[:?\d]*)\S*$/;
// https://github.com/jinder/path/blob/master/path.js#L567
function extname(path$$1) {
return splitPathRe.exec(path$$1).slice(1)[3];
}
// https://www.npmjs.com/package/is-url
function valid(path$$1) {
return urlRe.test(path$$1);
}
function resolve(root, path$$1) {
if (isArray(root)) {
root = root[0];
}
if (root && last(root) !== '/') {
root += '/';
}
return resolveUrl(root, path$$1);
}
function resolveUrl(root, path$$1) {
var base = document.createElement('base');
base.href = arguments[0];
var head = document.getElementsByTagName('head')[0];
head.insertBefore(base, head.firstChild);
var a = document.createElement('a');
a.href = path$$1;
var resolved = a.href;
base.href = resolved;
head.removeChild(base);
return resolved;
}
function Operators (isTruthy) {
return {
'==': function _(l, r) {
@@ -1996,43 +2062,6 @@ function Parser (Tag, Filter) {
};
}
/*
* Call functions in serial until someone resolved.
* @param {Array} iterable the array to iterate with.
* @param {Array} iteratee returns a new promise.
* The iteratee is invoked with three arguments: (value, index, iterable).
*/
function anySeries(iterable, iteratee) {
var ret = Promise.reject(new Error('init'));
iterable.forEach(function (item, idx) {
ret = ret.catch(function (e) {
return iteratee(item, idx, iterable);
});
});
return ret;
}
/*
* Call functions in serial until someone rejected.
* @param {Array} iterable the array to iterate with.
* @param {Array} iteratee returns a new promise.
* The iteratee is invoked with three arguments: (value, index, iterable).
*/
function mapSeries(iterable, iteratee) {
var ret = Promise.resolve('init');
var result = [];
iterable.forEach(function (item, idx) {
ret = ret.then(function () {
return iteratee(item, idx, iterable);
}).then(function (x) {
return result.push(x);
});
});
return ret.then(function () {
return result;
});
}
function For (liquid, Liquid) {
var render = function () {
var _ref = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(scope, hash$$1) {
@@ -2046,7 +2075,7 @@ function For (liquid, Liquid) {
collection = Liquid.evalExp(this.collection, scope);
if (!Array.isArray(collection)) {
if (!isArray(collection)) {
if (isString(collection) && collection.length > 0) {
collection = [collection];
} else if (isObject(collection)) {
@@ -2056,7 +2085,7 @@ function For (liquid, Liquid) {
}
}
if (!(!Array.isArray(collection) || !collection.length)) {
if (!(!isArray(collection) || !collection.length)) {
_context2.next = 4;
break;
}
@@ -3408,35 +3437,126 @@ var _engine = {
return parseAndRender;
}(),
renderFile: function () {
var _ref2 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(filepath, ctx, opts) {
var templates;
return regeneratorRuntime.wrap(function _callee2$(_context2) {
getTemplate: function () {
var _ref2 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(file, root) {
var _this = this;
var filepath;
return regeneratorRuntime.wrap(function _callee3$(_context3) {
while (1) {
switch (_context2.prev = _context2.next) {
switch (_context3.prev = _context3.next) {
case 0:
opts = assign({}, opts);
_context2.next = 3;
return this.getTemplate(filepath, opts.root);
_context3.next = 2;
return resolve(file, root, this.options);
case 3:
templates = _context2.sent;
return _context2.abrupt('return', this.render(templates, ctx, opts));
case 2:
filepath = _context3.sent;
return _context3.abrupt('return', this.respectCache(filepath, asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
var str;
return regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_context2.next = 2;
return read(filepath);
case 5:
case 2:
str = _context2.sent;
return _context2.abrupt('return', _this.parse(str, filepath));
case 4:
case 'end':
return _context2.stop();
}
}
}, _callee2, _this);
}))));
case 4:
case 'end':
return _context2.stop();
return _context3.stop();
}
}
}, _callee2, this);
}, _callee3, this);
}));
function renderFile(_x4, _x5, _x6) {
function getTemplate(_x4, _x5) {
return _ref2.apply(this, arguments);
}
return getTemplate;
}(),
renderFile: function () {
var _ref4 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4(file, ctx, opts) {
var templates;
return regeneratorRuntime.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
opts = assign({}, opts);
_context4.next = 3;
return this.getTemplate(file, opts.root);
case 3:
templates = _context4.sent;
return _context4.abrupt('return', this.render(templates, ctx, opts));
case 5:
case 'end':
return _context4.stop();
}
}
}, _callee4, this);
}));
function renderFile(_x6, _x7, _x8) {
return _ref4.apply(this, arguments);
}
return renderFile;
}(),
respectCache: function () {
var _ref5 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5(key, getter) {
var cacheEnabled, value;
return regeneratorRuntime.wrap(function _callee5$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
cacheEnabled = this.options.cache;
if (!(cacheEnabled && this.cache[key])) {
_context5.next = 3;
break;
}
return _context5.abrupt('return', this.cache[key]);
case 3:
_context5.next = 5;
return getter();
case 5:
value = _context5.sent;
if (cacheEnabled) {
this.cache[key] = value;
}
return _context5.abrupt('return', value);
case 8:
case 'end':
return _context5.stop();
}
}
}, _callee5, this);
}));
function respectCache(_x9, _x10) {
return _ref5.apply(this, arguments);
}
return respectCache;
}(),
evalValue: function evalValue$$1(str, scope) {
var tpl = this.parser.parseValue(str.trim());
return this.renderer.evalValue(tpl, scope);
@@ -3447,202 +3567,11 @@ var _engine = {
registerTag: function registerTag(name, tag) {
return this.tag.register(name, tag);
},
lookup: function lookup(filepath, root) {
var _this = this;
root = this.options.root.concat(root || []);
root = uniq(root);
var paths = root.map(function (root) {
return path.resolve(root, filepath);
});
return anySeries(paths, function () {
var _ref3 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(path$$1) {
return regeneratorRuntime.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
_context3.prev = 0;
_context3.next = 3;
return statFileAsync(path$$1);
case 3:
return _context3.abrupt('return', path$$1);
case 6:
_context3.prev = 6;
_context3.t0 = _context3['catch'](0);
_context3.t0.message = _context3.t0.code + ': Failed to lookup ' + filepath + ' in: ' + root;
throw _context3.t0;
case 10:
case 'end':
return _context3.stop();
}
}
}, _callee3, _this, [[0, 6]]);
}));
return function (_x7) {
return _ref3.apply(this, arguments);
};
}());
},
getTemplate: function getTemplate(filepath, root) {
return typeof XMLHttpRequest === 'undefined' ? this.getTemplateFromFile(filepath, root) : this.getTemplateFromUrl(filepath, root);
},
getTemplateFromFile: function () {
var _ref4 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5(filepath, root) {
var _this2 = this;
return regeneratorRuntime.wrap(function _callee5$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
if (!path.extname(filepath)) {
filepath += this.options.extname;
}
_context5.next = 3;
return this.lookup(filepath, root);
case 3:
filepath = _context5.sent;
return _context5.abrupt('return', this.respectCache(filepath, asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4() {
var str;
return regeneratorRuntime.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
_context4.next = 2;
return readFileAsync(filepath);
case 2:
str = _context4.sent;
return _context4.abrupt('return', _this2.parse(str, filepath));
case 4:
case 'end':
return _context4.stop();
}
}
}, _callee4, _this2);
}))));
case 5:
case 'end':
return _context5.stop();
}
}
}, _callee5, this);
}));
function getTemplateFromFile(_x8, _x9) {
return _ref4.apply(this, arguments);
}
return getTemplateFromFile;
}(),
getTemplateFromUrl: function () {
var _ref6 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee7(filepath, root) {
var _this3 = this;
var fullUrl;
return regeneratorRuntime.wrap(function _callee7$(_context7) {
while (1) {
switch (_context7.prev = _context7.next) {
case 0:
fullUrl = void 0;
if (valid(filepath)) {
fullUrl = filepath;
} else {
if (!extname(filepath)) {
filepath += this.options.extname;
}
fullUrl = resolve(root || this.options.root, filepath);
}
return _context7.abrupt('return', this.respectCache(filepath, asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee6() {
return regeneratorRuntime.wrap(function _callee6$(_context6) {
while (1) {
switch (_context6.prev = _context6.next) {
case 0:
_context6.t0 = _this3;
_context6.next = 3;
return get$1(fullUrl);
case 3:
_context6.t1 = _context6.sent;
return _context6.abrupt('return', _context6.t0.parse.call(_context6.t0, _context6.t1));
case 5:
case 'end':
return _context6.stop();
}
}
}, _callee6, _this3);
}))));
case 3:
case 'end':
return _context7.stop();
}
}
}, _callee7, this);
}));
function getTemplateFromUrl(_x10, _x11) {
return _ref6.apply(this, arguments);
}
return getTemplateFromUrl;
}(),
respectCache: function () {
var _ref8 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee8(key, getter) {
var cacheEnabled, value;
return regeneratorRuntime.wrap(function _callee8$(_context8) {
while (1) {
switch (_context8.prev = _context8.next) {
case 0:
cacheEnabled = this.options.cache;
if (!(cacheEnabled && this.cache[key])) {
_context8.next = 3;
break;
}
return _context8.abrupt('return', this.cache[key]);
case 3:
_context8.next = 5;
return getter();
case 5:
value = _context8.sent;
if (cacheEnabled) {
this.cache[key] = value;
}
return _context8.abrupt('return', value);
case 8:
case 'end':
return _context8.stop();
}
}
}, _callee8, this);
}));
function respectCache(_x12, _x13) {
return _ref8.apply(this, arguments);
}
return respectCache;
}(),
express: function express(opts) {
opts = opts || {};
var self = this;
return function (filePath, ctx, cb) {
assert(Array.isArray(this.root) || isString(this.root), 'illegal views root, are you using express.js?');
assert(isArray(this.root) || isString(this.root), 'illegal views root, are you using express.js?');
opts.root = this.root;
self.renderFile(filePath, ctx, opts).then(function (html) {
return cb(null, html);
@@ -3652,7 +3581,7 @@ var _engine = {
};
function normalizeStringArray(value) {
if (Array.isArray(value)) return value;
if (isArray(value)) return value;
if (isString(value)) return [value];
return [];
}
+1 -1
View File
File diff suppressed because one or more lines are too long
+175 -306
View File
@@ -825,19 +825,6 @@
return arr[arr.length - 1];
}
function uniq(arr) {
var u = {};
var a = [];
for (var i = 0, l = arr.length; i < l; ++i) {
if (u.hasOwnProperty(arr[i])) {
continue;
}
a.push(arr[i]);
u[arr[i]] = 1;
}
return a;
}
/*
* Checks if value is the language type of Object.
* (e.g. arrays, functions, objects, regexes, new Number(0), and new String(''))
@@ -1229,24 +1216,74 @@
return scope;
}
function get$1(url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.responseText);
} else {
reject(new Error(xhr.statusText));
}
};
xhr.onerror = function () {
reject(new Error('An error occurred whilst sending the response.'));
};
xhr.open('GET', url);
xhr.send();
function domResolve(root, path) {
var base = document.createElement('base');
base.href = root;
var head = document.getElementsByTagName('head')[0];
head.insertBefore(base, head.firstChild);
var a = document.createElement('a');
a.href = path;
var resolved = a.href;
head.removeChild(base);
return resolved;
}
function resolve(filepath, root, options) {
root = root || options.root;
if (isArray(root)) {
root = root[0];
}
if (root.length && last(root) !== '/') {
root += '/';
}
var url = domResolve(root, filepath);
return url.replace(/^(\w+:\/\/[^/]+)(\/[^?]+)/, function (str, origin, path) {
var last$$1 = path.split('/').pop();
if (/\.\w+$/.test(last$$1)) {
return str;
}
return origin + path + options.extname;
});
}
var read = function () {
var _ref = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(url) {
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
return _context.abrupt('return', new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.responseText);
} else {
reject(new Error(xhr.statusText));
}
};
xhr.onerror = function () {
reject(new Error('An error occurred whilst receiving the response.'));
};
xhr.open('GET', url);
xhr.send();
}));
case 1:
case 'end':
return _context.stop();
}
}
}, _callee, this);
}));
return function read(_x) {
return _ref.apply(this, arguments);
};
}();
function whiteSpaceCtrl(tokens, options) {
options = assign({ greedy: true }, options);
var inRaw = false;
@@ -1372,65 +1409,6 @@
};
}
var fs = {};
function readFileAsync(filepath) {
return new Promise(function (resolve, reject) {
fs.readFile(filepath, 'utf8', function (err, content) {
err ? reject(err) : resolve(content);
});
});
}
function statFileAsync(path) {
return new Promise(function (resolve, reject) {
fs.stat(path, function (err, stat) {
return err ? reject(err) : resolve(stat);
});
});
}
var path = {};
var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^/]+?|)(\.[^./]*|))(?:[/]*)$/;
var urlRe = /^(?:\w+:)?\/\/([^\s.]+\.\S{2}|localhost[:?\d]*)\S*$/;
// https://github.com/jinder/path/blob/master/path.js#L567
function extname(path) {
return splitPathRe.exec(path).slice(1)[3];
}
// https://www.npmjs.com/package/is-url
function valid(path) {
return urlRe.test(path);
}
function resolve(root, path) {
if (isArray(root)) {
root = root[0];
}
if (root && last(root) !== '/') {
root += '/';
}
return resolveUrl(root, path);
}
function resolveUrl(root, path) {
var base = document.createElement('base');
base.href = arguments[0];
var head = document.getElementsByTagName('head')[0];
head.insertBefore(base, head.firstChild);
var a = document.createElement('a');
a.href = path;
var resolved = a.href;
base.href = resolved;
head.removeChild(base);
return resolved;
}
function Operators (isTruthy) {
return {
'==': function _(l, r) {
@@ -2005,15 +1983,6 @@
* @param {Array} iteratee returns a new promise.
* The iteratee is invoked with three arguments: (value, index, iterable).
*/
function anySeries(iterable, iteratee) {
var ret = Promise.reject(new Error('init'));
iterable.forEach(function (item, idx) {
ret = ret.catch(function (e) {
return iteratee(item, idx, iterable);
});
});
return ret;
}
/*
* Call functions in serial until someone rejected.
@@ -2049,7 +2018,7 @@
collection = Liquid.evalExp(this.collection, scope);
if (!Array.isArray(collection)) {
if (!isArray(collection)) {
if (isString(collection) && collection.length > 0) {
collection = [collection];
} else if (isObject(collection)) {
@@ -2059,7 +2028,7 @@
}
}
if (!(!Array.isArray(collection) || !collection.length)) {
if (!(!isArray(collection) || !collection.length)) {
_context2.next = 4;
break;
}
@@ -3411,35 +3380,126 @@
return parseAndRender;
}(),
renderFile: function () {
var _ref2 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(filepath, ctx, opts) {
var templates;
return regeneratorRuntime.wrap(function _callee2$(_context2) {
getTemplate: function () {
var _ref2 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(file, root) {
var _this = this;
var filepath;
return regeneratorRuntime.wrap(function _callee3$(_context3) {
while (1) {
switch (_context2.prev = _context2.next) {
switch (_context3.prev = _context3.next) {
case 0:
opts = assign({}, opts);
_context2.next = 3;
return this.getTemplate(filepath, opts.root);
_context3.next = 2;
return resolve(file, root, this.options);
case 3:
templates = _context2.sent;
return _context2.abrupt('return', this.render(templates, ctx, opts));
case 2:
filepath = _context3.sent;
return _context3.abrupt('return', this.respectCache(filepath, asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
var str;
return regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_context2.next = 2;
return read(filepath);
case 5:
case 2:
str = _context2.sent;
return _context2.abrupt('return', _this.parse(str, filepath));
case 4:
case 'end':
return _context2.stop();
}
}
}, _callee2, _this);
}))));
case 4:
case 'end':
return _context2.stop();
return _context3.stop();
}
}
}, _callee2, this);
}, _callee3, this);
}));
function renderFile(_x4, _x5, _x6) {
function getTemplate(_x4, _x5) {
return _ref2.apply(this, arguments);
}
return getTemplate;
}(),
renderFile: function () {
var _ref4 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4(file, ctx, opts) {
var templates;
return regeneratorRuntime.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
opts = assign({}, opts);
_context4.next = 3;
return this.getTemplate(file, opts.root);
case 3:
templates = _context4.sent;
return _context4.abrupt('return', this.render(templates, ctx, opts));
case 5:
case 'end':
return _context4.stop();
}
}
}, _callee4, this);
}));
function renderFile(_x6, _x7, _x8) {
return _ref4.apply(this, arguments);
}
return renderFile;
}(),
respectCache: function () {
var _ref5 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5(key, getter) {
var cacheEnabled, value;
return regeneratorRuntime.wrap(function _callee5$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
cacheEnabled = this.options.cache;
if (!(cacheEnabled && this.cache[key])) {
_context5.next = 3;
break;
}
return _context5.abrupt('return', this.cache[key]);
case 3:
_context5.next = 5;
return getter();
case 5:
value = _context5.sent;
if (cacheEnabled) {
this.cache[key] = value;
}
return _context5.abrupt('return', value);
case 8:
case 'end':
return _context5.stop();
}
}
}, _callee5, this);
}));
function respectCache(_x9, _x10) {
return _ref5.apply(this, arguments);
}
return respectCache;
}(),
evalValue: function evalValue$$1(str, scope) {
var tpl = this.parser.parseValue(str.trim());
return this.renderer.evalValue(tpl, scope);
@@ -3450,202 +3510,11 @@
registerTag: function registerTag(name, tag) {
return this.tag.register(name, tag);
},
lookup: function lookup(filepath, root) {
var _this = this;
root = this.options.root.concat(root || []);
root = uniq(root);
var paths = root.map(function (root) {
return path.resolve(root, filepath);
});
return anySeries(paths, function () {
var _ref3 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(path$$1) {
return regeneratorRuntime.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
_context3.prev = 0;
_context3.next = 3;
return statFileAsync(path$$1);
case 3:
return _context3.abrupt('return', path$$1);
case 6:
_context3.prev = 6;
_context3.t0 = _context3['catch'](0);
_context3.t0.message = _context3.t0.code + ': Failed to lookup ' + filepath + ' in: ' + root;
throw _context3.t0;
case 10:
case 'end':
return _context3.stop();
}
}
}, _callee3, _this, [[0, 6]]);
}));
return function (_x7) {
return _ref3.apply(this, arguments);
};
}());
},
getTemplate: function getTemplate(filepath, root) {
return typeof XMLHttpRequest === 'undefined' ? this.getTemplateFromFile(filepath, root) : this.getTemplateFromUrl(filepath, root);
},
getTemplateFromFile: function () {
var _ref4 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5(filepath, root) {
var _this2 = this;
return regeneratorRuntime.wrap(function _callee5$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
if (!path.extname(filepath)) {
filepath += this.options.extname;
}
_context5.next = 3;
return this.lookup(filepath, root);
case 3:
filepath = _context5.sent;
return _context5.abrupt('return', this.respectCache(filepath, asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4() {
var str;
return regeneratorRuntime.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
_context4.next = 2;
return readFileAsync(filepath);
case 2:
str = _context4.sent;
return _context4.abrupt('return', _this2.parse(str, filepath));
case 4:
case 'end':
return _context4.stop();
}
}
}, _callee4, _this2);
}))));
case 5:
case 'end':
return _context5.stop();
}
}
}, _callee5, this);
}));
function getTemplateFromFile(_x8, _x9) {
return _ref4.apply(this, arguments);
}
return getTemplateFromFile;
}(),
getTemplateFromUrl: function () {
var _ref6 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee7(filepath, root) {
var _this3 = this;
var fullUrl;
return regeneratorRuntime.wrap(function _callee7$(_context7) {
while (1) {
switch (_context7.prev = _context7.next) {
case 0:
fullUrl = void 0;
if (valid(filepath)) {
fullUrl = filepath;
} else {
if (!extname(filepath)) {
filepath += this.options.extname;
}
fullUrl = resolve(root || this.options.root, filepath);
}
return _context7.abrupt('return', this.respectCache(filepath, asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee6() {
return regeneratorRuntime.wrap(function _callee6$(_context6) {
while (1) {
switch (_context6.prev = _context6.next) {
case 0:
_context6.t0 = _this3;
_context6.next = 3;
return get$1(fullUrl);
case 3:
_context6.t1 = _context6.sent;
return _context6.abrupt('return', _context6.t0.parse.call(_context6.t0, _context6.t1));
case 5:
case 'end':
return _context6.stop();
}
}
}, _callee6, _this3);
}))));
case 3:
case 'end':
return _context7.stop();
}
}
}, _callee7, this);
}));
function getTemplateFromUrl(_x10, _x11) {
return _ref6.apply(this, arguments);
}
return getTemplateFromUrl;
}(),
respectCache: function () {
var _ref8 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee8(key, getter) {
var cacheEnabled, value;
return regeneratorRuntime.wrap(function _callee8$(_context8) {
while (1) {
switch (_context8.prev = _context8.next) {
case 0:
cacheEnabled = this.options.cache;
if (!(cacheEnabled && this.cache[key])) {
_context8.next = 3;
break;
}
return _context8.abrupt('return', this.cache[key]);
case 3:
_context8.next = 5;
return getter();
case 5:
value = _context8.sent;
if (cacheEnabled) {
this.cache[key] = value;
}
return _context8.abrupt('return', value);
case 8:
case 'end':
return _context8.stop();
}
}
}, _callee8, this);
}));
function respectCache(_x12, _x13) {
return _ref8.apply(this, arguments);
}
return respectCache;
}(),
express: function express(opts) {
opts = opts || {};
var self = this;
return function (filePath, ctx, cb) {
assert(Array.isArray(this.root) || isString(this.root), 'illegal views root, are you using express.js?');
assert(isArray(this.root) || isString(this.root), 'illegal views root, are you using express.js?');
opts.root = this.root;
self.renderFile(filePath, ctx, opts).then(function (html) {
return cb(null, html);
@@ -3655,7 +3524,7 @@
};
function normalizeStringArray(value) {
if (Array.isArray(value)) return value;
if (isArray(value)) return value;
if (isString(value)) return [value];
return [];
}
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+3743 -1324
View File
File diff suppressed because it is too large Load Diff
+10 -6
View File
@@ -7,11 +7,10 @@
"browser": "dist/liquid.js",
"scripts": {
"lint": "eslint src/ test/ *.js",
"test": "npm run test:unit && npm run test:e2e",
"test:unit": "mocha test/unit",
"test:e2e": "mocha test/e2e",
"test": "mocha test/unit",
"e2e": "mocha test/e2e",
"coverage": "cross-env NODE_ENV=test nyc report --reporter=html mocha test/unit",
"coveralls": "cross-env NODE_ENV=test nyc report --reporter=text-lcov mocha | coveralls",
"coveralls": "cross-env NODE_ENV=test nyc report --reporter=text-lcov mocha test/unit | coveralls",
"dist": "rollup -c && ls -lh dist",
"demo:browser": "echo open http://localhost:8080/demo/browser && http-server -c-1",
"demo:nodejs": "node ./demo/nodejs/index.js",
@@ -66,6 +65,7 @@
"nyc": "^12.0.2",
"regenerator-runtime": "^0.12.1",
"rollup": "^0.64.1",
"rollup-plugin-alias": "^1.4.0",
"rollup-plugin-babel": "^3.0.7",
"rollup-plugin-node-resolve": "^3.3.0",
"rollup-plugin-shim": "^1.0.0",
@@ -82,7 +82,9 @@
"instrument": false
},
"babel": {
"presets": ["env"],
"presets": [
"env"
],
"plugins": [
[
"transform-runtime",
@@ -96,7 +98,9 @@
],
"env": {
"test": {
"plugins": ["istanbul"]
"plugins": [
"istanbul"
]
}
}
}
+4
View File
@@ -1,4 +1,5 @@
import shim from 'rollup-plugin-shim'
import alias from 'rollup-plugin-alias'
import babel from 'rollup-plugin-babel'
import {uglify} from 'rollup-plugin-uglify'
import pkg from './package.json'
@@ -48,6 +49,9 @@ export default [{
}],
plugins: [
shim(fake),
alias({
'./template': './template-browser'
}),
nodeResolve(),
babel(babelConf)
],
+20 -61
View File
@@ -1,18 +1,14 @@
import 'regenerator-runtime/runtime'
import * as Scope from './scope'
import {get as httpGet} from './util/http.js'
import * as template from './template'
import * as _ from './util/underscore.js'
import assert from './util/assert.js'
import * as tokenizer from './tokenizer.js'
import {statFileAsync, readFileAsync} from './util/fs.js'
import path from 'path'
import {valid as isValidUrl, extname, resolve} from './util/url.js'
import Render from './render.js'
import Tag from './tag.js'
import Filter from './filter.js'
import Parser from './parser'
import {isTruthy, isFalsy, evalExp, evalValue} from './syntax.js'
import {anySeries} from './util/promise.js'
import {ParseError, TokenizationError, RenderBreakError, AssertionError} from './util/error.js'
import tags from './tags/index.js'
import filters from './filters.js'
@@ -46,64 +42,17 @@ const _engine = {
const tpl = await this.parse(html)
return this.render(tpl, ctx, opts)
},
renderFile: async function (filepath, ctx, opts) {
opts = _.assign({}, opts)
const templates = await this.getTemplate(filepath, opts.root)
return this.render(templates, ctx, opts)
},
evalValue: function (str, scope) {
const tpl = this.parser.parseValue(str.trim())
return this.renderer.evalValue(tpl, scope)
},
registerFilter: function (name, filter) {
return this.filter.register(name, filter)
},
registerTag: function (name, tag) {
return this.tag.register(name, tag)
},
lookup: function (filepath, root) {
root = this.options.root.concat(root || [])
root = _.uniq(root)
const paths = root.map(root => path.resolve(root, filepath))
return anySeries(paths, async path => {
try {
await statFileAsync(path)
return path
} catch (e) {
e.message = `${e.code}: Failed to lookup ${filepath} in: ${root}`
throw e
}
})
},
getTemplate: function (filepath, root) {
return typeof XMLHttpRequest === 'undefined'
? this.getTemplateFromFile(filepath, root)
: this.getTemplateFromUrl(filepath, root)
},
getTemplateFromFile: async function (filepath, root) {
if (!path.extname(filepath)) {
filepath += this.options.extname
}
filepath = await this.lookup(filepath, root)
getTemplate: async function (file, root) {
const filepath = await template.resolve(file, root, this.options)
return this.respectCache(filepath, async () => {
const str = await readFileAsync(filepath)
const str = await template.read(filepath)
return this.parse(str, filepath)
})
},
getTemplateFromUrl: async function (filepath, root) {
let fullUrl
if (isValidUrl(filepath)) {
fullUrl = filepath
} else {
if (!extname(filepath)) {
filepath += this.options.extname
}
fullUrl = resolve(root || this.options.root, filepath)
}
return this.respectCache(
filepath,
async () => this.parse(await httpGet(fullUrl))
)
renderFile: async function (file, ctx, opts) {
opts = _.assign({}, opts)
const templates = await this.getTemplate(file, opts.root)
return this.render(templates, ctx, opts)
},
respectCache: async function (key, getter) {
const cacheEnabled = this.options.cache
@@ -116,11 +65,21 @@ const _engine = {
}
return value
},
evalValue: function (str, scope) {
const tpl = this.parser.parseValue(str.trim())
return this.renderer.evalValue(tpl, scope)
},
registerFilter: function (name, filter) {
return this.filter.register(name, filter)
},
registerTag: function (name, tag) {
return this.tag.register(name, tag)
},
express: function (opts) {
opts = opts || {}
const self = this
return function (filePath, ctx, cb) {
assert(Array.isArray(this.root) || _.isString(this.root),
assert(_.isArray(this.root) || _.isString(this.root),
'illegal views root, are you using express.js?')
opts.root = this.root
self.renderFile(filePath, ctx, opts).then(html => cb(null, html), cb)
@@ -129,7 +88,7 @@ const _engine = {
}
function normalizeStringArray (value) {
if (Array.isArray(value)) return value
if (_.isArray(value)) return value
if (_.isString(value)) return [value]
return []
}
+3 -3
View File
@@ -1,5 +1,5 @@
import {mapSeries} from '../util/promise.js'
import {isString, isObject} from '../util/underscore.js'
import {isString, isObject, isArray} from '../util/underscore.js'
import assert from '../util/assert.js'
import {identifier, value, hash} from '../lexical.js'
@@ -38,14 +38,14 @@ export default function (liquid, Liquid) {
async function render (scope, hash) {
let collection = Liquid.evalExp(this.collection, scope)
if (!Array.isArray(collection)) {
if (!isArray(collection)) {
if (isString(collection) && collection.length > 0) {
collection = [collection]
} else if (isObject(collection)) {
collection = Object.keys(collection).map((key) => [key, collection[key]])
}
}
if (!Array.isArray(collection) || !collection.length) {
if (!isArray(collection) || !collection.length) {
return liquid.renderer.renderTemplates(this.elseTemplates, scope)
}
+52
View File
@@ -0,0 +1,52 @@
import {last, isArray} from './util/underscore'
function domResolve (root, path) {
const base = document.createElement('base')
base.href = root
const head = document.getElementsByTagName('head')[0]
head.insertBefore(base, head.firstChild)
const a = document.createElement('a')
a.href = path
const resolved = a.href
head.removeChild(base)
return resolved
}
export function resolve (filepath, root, options) {
root = root || options.root
if (isArray(root)) {
root = root[0]
}
if (root.length && last(root) !== '/') {
root += '/'
}
const url = domResolve(root, filepath)
return url.replace(/^(\w+:\/\/[^/]+)(\/[^?]+)/, (str, origin, path) => {
const last = path.split('/').pop()
if (/\.\w+$/.test(last)) {
return str
}
return origin + path + options.extname
})
}
export async function read (url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.responseText)
} else {
reject(new Error(xhr.statusText))
}
}
xhr.onerror = () => {
reject(new Error('An error occurred whilst receiving the response.'))
}
xhr.open('GET', url)
xhr.send()
})
}
+30
View File
@@ -0,0 +1,30 @@
import * as _ from './util/underscore.js'
import path from 'path'
import {anySeries} from './util/promise.js'
import {statFileAsync, readFileAsync} from './util/fs.js'
function lookup (filepath, root, options) {
root = options.root.concat(root || [])
root = _.uniq(root)
const paths = root.map(root => path.resolve(root || location.href, filepath))
return anySeries(paths, async path => {
try {
await statFileAsync(path)
return path
} catch (e) {
e.message = `${e.code}: Failed to lookup ${filepath} in: ${root}`
throw e
}
})
}
export async function resolve (filepath, root, options) {
if (!path.extname(filepath)) {
filepath += options.extname
}
return lookup(filepath, root, options)
}
export async function read (filepath) {
return readFileAsync(filepath)
}
-17
View File
@@ -1,17 +0,0 @@
export function get (url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.responseText)
} else {
reject(new Error(xhr.statusText))
}
}
xhr.onerror = () => {
reject(new Error('An error occurred whilst sending the response.'))
}
xhr.open('GET', url)
xhr.send()
})
}
-41
View File
@@ -1,41 +0,0 @@
import {last, isArray} from './underscore'
const splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^/]+?|)(\.[^./]*|))(?:[/]*)$/
const urlRe = /^(?:\w+:)?\/\/([^\s.]+\.\S{2}|localhost[:?\d]*)\S*$/
// https://github.com/jinder/path/blob/master/path.js#L567
export function extname (path) {
return splitPathRe.exec(path).slice(1)[3]
}
// https://www.npmjs.com/package/is-url
export function valid (path) {
return urlRe.test(path)
}
export function resolve (root, path) {
if (isArray(root)) {
root = root[0]
}
if (root && last(root) !== '/') {
root += '/'
}
return resolveUrl(root, path)
}
function resolveUrl (root, path) {
const base = document.createElement('base')
base.href = arguments[0]
const head = document.getElementsByTagName('head')[0]
head.insertBefore(base, head.firstChild)
const a = document.createElement('a')
a.href = path
const resolved = a.href
base.href = resolved
head.removeChild(base)
return resolved
}
+1 -1
View File
@@ -2,7 +2,7 @@ const chai = require('chai')
const request = require('supertest')
const express = require('express')
const mock = require('mock-fs')
const Liquid = require('../..')
const Liquid = require('../../dist/liquid.common.js')
const chaiAsPromised = require('chai-as-promised')
const expect = chai.expect
+13 -9
View File
@@ -1,4 +1,4 @@
var Liquid = require('../..')
var Liquid = require('../../dist/liquid.js')
var sinon = require('sinon')
var chai = require('chai')
var expect = chai.expect
@@ -6,16 +6,17 @@ chai.use(require('chai-as-promised'))
describe('xhr', () => {
if (process.version.match(/^v(\d+)/)[1] < 8) {
console.info('jsdom not supported, skipping xhr...')
return
}
var JSDOM = require('jsdom').JSDOM
var server, engine, dom
var server, engine
beforeEach(() => {
server = sinon.createFakeServer()
server.autoRespond = true
server.respondWith('GET', 'https://example.com/views/hello.html',
[200, {'Content-Type': 'text/plain'}, 'hello {{name}}'])
dom = new JSDOM('', {
var dom = new JSDOM('', {
url: 'https://example.com/foo/bar.html',
contentType: 'text/html',
includeNodeLocations: true
@@ -65,15 +66,18 @@ describe('xhr', () => {
})
it('should throw error', function (done) {
engine.renderFile('hello.html')
.then(() => done('should not be resolved'))
.catch(function (e) {
expect(e.message).to.equal('An error occurred whilst sending the response.')
expect(e.message).to.equal('An error occurred whilst receiving the response.')
done()
})
server.requests[0].error()
global.XMLHttpRequest.onCreate = function (request) {
setTimeout(() => request.error())
}
})
})
describe('root', () => {
it('should support with null', () => {
describe('#renderFile() with root specified', () => {
it('should support undefined root', () => {
engine = Liquid({
extname: '.html'
})
@@ -82,12 +86,12 @@ describe('xhr', () => {
return expect(engine.renderFile('hello.html', {name: 'alice5'}))
.to.eventually.equal('hello alice5')
})
it('should support with empty', () => {
it('should support empty root', () => {
engine = Liquid({
root: '',
extname: '.html'
})
server.respondWith('GET', 'https://example.com/foo/hello.html',
server.respondWith('https://example.com/foo/hello.html',
[200, {'Content-Type': 'text/plain'}, 'hello {{name}}'])
return expect(engine.renderFile('hello.html', {name: 'alice5'}))
.to.eventually.equal('hello alice5')
+85
View File
@@ -0,0 +1,85 @@
import {resolve} from '../../src/template-browser.js'
import chai from 'chai'
const expect = chai.expect
describe('template-browser', function () {
if (process.version.match(/^v(\d+)/)[1] < 8) {
console.info('jsdom not supported, skipping template-browser...')
return
}
const JSDOM = require('jsdom').JSDOM
beforeEach(function () {
const dom = new JSDOM(``, {
url: 'https://example.com/foo/bar/',
contentType: 'text/html',
includeNodeLocations: true
})
global.document = dom.window.document
})
afterEach(function () {
delete global.document
})
describe('resolve', function () {
it('should support relative root', function () {
expect(resolve('foo', './views/', {
extname: '',
root: ['.']
})).to.equal('https://example.com/foo/bar/views/foo')
})
it('should treat root as directory', function () {
expect(resolve('foo', './views', {
extname: '',
root: ['.']
})).to.equal('https://example.com/foo/bar/views/foo')
})
it('should support absolute root', function () {
expect(resolve('foo', '/views', {
extname: '',
root: ['.']
})).to.equal('https://example.com/views/foo')
})
it('should support empty root', function () {
expect(resolve('page.html', '', {
extname: '',
root: ['.']
})).to.equal('https://example.com/foo/bar/page.html')
})
it('should support full url as root', function () {
expect(resolve('page.html', 'https://example.com/views/', {
extname: '',
root: ['.']
})).to.equal('https://example.com/views/page.html')
})
it('should use options.root when root argument absent', function () {
expect(resolve('page.html', null, {
extname: '',
root: ['https://example.com/views', 'https://google.com/views']
})).to.equal('https://example.com/views/page.html')
})
it('should add extname when absent', function () {
expect(resolve('page', 'https://example.com/views/', {
extname: '.html',
root: ['.']
})).to.equal('https://example.com/views/page.html')
})
it('should add extname for urls have searchParams', function () {
expect(resolve('page?foo=bar', 'https://example.com/views/', {
extname: '.html',
root: ['.']
})).to.equal('https://example.com/views/page.html?foo=bar')
})
it('should not add extname when full url is given', function () {
expect(resolve('https://google.com/page.php', 'https://example.com/views/', {
extname: '.html',
root: ['.']
})).to.equal('https://google.com/page.php')
})
it('should not add extname when already have one', function () {
expect(resolve('page.php', 'https://example.com/views/', {
extname: '.html',
root: ['.']
})).to.equal('https://example.com/views/page.php')
})
})
})
-63
View File
@@ -1,63 +0,0 @@
import {extname, resolve} from '../../../src/util/url.js'
import chai from 'chai'
const expect = chai.expect
describe('util/url', function () {
if (process.version.match(/^v(\d+)/)[1] < 8) {
return
}
const JSDOM = require('jsdom').JSDOM
let dom
beforeEach(function () {
dom = new JSDOM(``, {
url: 'https://example.com/foo/bar/',
contentType: 'text/html',
includeNodeLocations: true
})
global.document = dom.window.document
})
afterEach(function () {
delete global.document
})
describe('resolve', function () {
describe('root', function () {
it('should support relative root', function () {
expect(resolve('./views', 'foo'))
.to.equal('https://example.com/foo/bar/views/foo')
expect(resolve('./views/', 'foo'))
.to.equal('https://example.com/foo/bar/views/foo')
})
it('should support absolute root', function () {
expect(resolve('/views', 'foo'))
.to.equal('https://example.com/views/foo')
expect(resolve('/views/', 'foo'))
.to.equal('https://example.com/views/foo')
})
it('should support empty root', function () {
expect(resolve('', 'page.html'))
.to.equal('https://example.com/foo/bar/page.html')
})
it('should support full url as root', function () {
expect(resolve('https://example.com/views', 'page.html'))
.to.equal('https://example.com/views/page.html')
expect(resolve('https://example.com/views/', 'page.html'))
.to.equal('https://example.com/views/page.html')
})
it('should get the first value when argument is array', function () {
expect(resolve(['https://example.com/views', 'https://google.com/views'], 'page.html'))
.to.equal('https://example.com/views/page.html')
expect(resolve(['https://example.com/views/', 'https://google.com/views'], 'page.html'))
.to.equal('https://example.com/views/page.html')
})
})
describe('extname', function () {
it('should support relative path', function () {
expect(extname('./views/page.html')).to.equal('.html')
})
it('should support absolute path', function () {
expect(extname('/views/page.xml')).to.equal('.xml')
})
})
})
})