feature: browser side support, close #6

This commit is contained in:
harttle
2016-09-27 02:28:20 +08:00
parent 937d213a2d
commit 16a66f2b18
20 changed files with 4108 additions and 107 deletions
+6 -3
View File
@@ -1,7 +1,6 @@
const syntax = require('./syntax.js');
const Exp = require('./expression.js');
const lexical = require('./lexical.js');
const _ = require('lodash');
function evalExp(exp, scope) {
if (!scope) throw new Error('unable to evalExp: scope undefined');
@@ -20,8 +19,12 @@ function evalExp(exp, scope) {
if (match = exp.match(lexical.rangeLine)) {
var low = evalValue(match[1], scope),
high = evalValue(match[2], scope) + 1;
return _.range(low, high);
high = evalValue(match[2], scope);
var range = [];
for (var j = low; j <= high; j++) {
range.push(j);
}
return range;
}
return evalValue(exp, scope);
-1
View File
@@ -1,5 +1,4 @@
const lexical = require('./lexical.js');
const _ = require('lodash');
const Exp = require('./expression.js');
var valueRE = new RegExp(`${lexical.value.source}`, 'g');
-2
View File
@@ -1,5 +1,3 @@
const _ = require('lodash');
// quote related
var singleQuoted = /'[^']*'/;
var doubleQuoted = /"[^"]*"/;
+2 -4
View File
@@ -2,15 +2,13 @@ const error = require('./error.js');
const Exp = require('./expression.js');
const assert = require('assert');
const Promise = require('any-promise');
const _ = require('lodash');
var render = {
renderTemplates: function(templates, scope, opts) {
assert(scope, 'unable to evalTemplates: scope undefined');
opts = _.defaults(opts, {
strict_filters: false
});
opts = opts || {};
opts.strict_filters = opts.strict_filters || false;
var html = '';
+37 -8
View File
@@ -1,4 +1,3 @@
const _ = require('lodash');
const lexical = require('./lexical.js');
var Scope = {
@@ -8,17 +7,22 @@ var Scope = {
if (str === undefined) {
var ctx = {};
for (i = this.scopes.length - 1; i >= 0; i--) {
_.merge(ctx, this.scopes[i]);
var scp = this.scopes[i];
for (var k in scp) {
if (scp.hasOwnProperty(k)) {
ctx[k] = scp[k];
}
}
}
return ctx;
}
// get one path
for (i = this.scopes.length - 1; i >= 0; i--) {
var v = _.get(this.scopes[i], str);
var v = getPropertyByPath(this.scopes[i], str);
if (v !== undefined) return v;
}
},
get: function(str){
get: function(str) {
var val = this.safeGet(str);
if (val === undefined && this.opts.strict) {
throw new Error(`[strict_variables] undefined variable: ${str}`);
@@ -26,7 +30,7 @@ var Scope = {
return val;
},
set: function(k, v) {
_.set(this.scopes[this.scopes.length - 1], k, v);
setPropertyByPath(this.scopes[this.scopes.length - 1], k, v);
return this;
},
push: function(ctx) {
@@ -38,10 +42,35 @@ var Scope = {
}
};
function setPropertyByPath(obj, path, val) {
if (path instanceof String || typeof path === 'string') {
var paths = path.replace(/\[/g, '.').replace(/\]/g, '').split('.');
for (var i = 0; i < paths.length; i++) {
var key = paths[i];
if (i === paths.length - 1) {
return obj[key] = val;
}
if (undefined === obj[key]) obj[key] = {};
// case for readonly objects
obj = obj[key] || {};
}
return obj;
}
return obj[path] = val;
}
function getPropertyByPath(obj, path) {
if (path instanceof String || typeof path === 'string') {
var paths = path.replace(/\[/g, '.').replace(/\]/g, '').split('.');
paths.forEach(p => obj = obj && obj[p]);
return obj;
}
return obj[path];
}
exports.factory = function(_ctx, opts) {
opts = _.defaults(opts, {
strict: false
});
opts = opts || {};
opts.strict = opts.strict || false;
var scope = Object.create(Scope);
scope.opts = opts;