-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathif.js
87 lines (72 loc) · 1.93 KB
/
if.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/**
*
* Modified version of the If logic used in DomBuilder
*
* Copyright (c) 2011, Jonathan Buchanan
*
* https://github.com/insin/DOMBuilder/blob/master/lib/dombuilder/template.js#L732-L775
*
*/
var ops = '( ) && || == === <= < >= > != !== !! !'.split(' '),
opsRE = /(\(|\)|&&|\|\||={2,3}|<=|<|>=|>|!={1,2}|!{1,2})/,
numberRE = /^-?(?:\d+(?:\.\d+)?|(?:\d+)?\.\d+)$/,
isQuotedString = function(s) {
var q = s.charAt(0);
return (s.length > 1 &&
['\'', '"'].indexOf(q) !== -1 &&
s.lastIndexOf(q) === s.length - 1);
},
isBoolean = function(s) {
return s === 'true' || s === 'false'
};
/** RegExp for trimming whitespace. */
var TRIM_RE = /^\s+|\s+$/g;
function validVar(bit, keys) {
var r;
for(var i = 0; i < keys.length; i++) {
r = new RegExp('^' + keys[i] + '(\.|$)')
if(r.test(bit)) {
return true;
}
}
return false;
}
function parseExpr(expr, vars) {
var bit;
var bits = expr.split(opsRE);
var keys = Object.keys(vars);
var code = ['return function(' + keys.join(',') + ') { return (' ];
for(var i = 0; i < bits.length; i++) {
bit = bits[i];
if(ops.indexOf(bit) !== -1) {
code.push(bit);
} else {
bit = bit.replace(TRIM_RE, '');
if(bit) {
if(numberRE.test(bit) ||
isQuotedString(bit) ||
isBoolean(bit) ||
bit === 'typeof' ||
bit === 'undefined' ||
bit === 'null'
) {
code.push(bit);
} else if(validVar(bit, keys)) {
code.push(bit);
} else {
throw new Error("Unspecified value: " + bit);
}
}
}
}
code.push('); }');
try {
var func = new Function(code.join(' '))();
var v = [];
for(var key in vars) { v.push(vars[key]); }
return func.apply(null, v);
} catch (e) {
throw new Error('Invalid if expression (' + e.message + '): ' + expr);
}
}
module.exports = parseExpr;