-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparse.js
More file actions
79 lines (57 loc) · 1.8 KB
/
parse.js
File metadata and controls
79 lines (57 loc) · 1.8 KB
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
var noop = function () { };
var setter = function (context, value, path) {
evalInContext(context, 'this.' + path + ' = value;', {'value': value});
}
var prepareContextMethod = function (method, context, source) {
return typeof method === 'function' ? function () {
return method.apply(context, arguments);
} : method;
}
var evalInContext = function (context, source, locals) {
if (source === undefined) {
return;
}
locals = locals || {};
var args = [], values = [], result, key;
for (key in context) {
args.push(key);
values.push(prepareContextMethod(context[key], context, source));
}
for (key in locals) {
args.push(key);
values.push(prepareContextMethod(locals[key], context, source));
}
args.push('return ' + source);
try {
result = Function.apply(null, args).apply(context, values);
} catch (e) {
console.error('$parse:', e);
}
return result;
}
function getValueByPath(acc, path) {
path = path.split('.');
for (var i = 0, length = path.length; i < length; i++) {
acc = typeof acc === 'object' && acc ? acc[path[i]] : undefined;
}
return acc;
}
var isExpression = /\=|\[|\(|\;/;
module.exports = function (expression) {
if (expression === undefined) {
return noop;
}
expression = expression.trim();
var isPath = !isExpression.test(expression);
var getter = function (context, locals) {
if (isPath) {
var value = getValueByPath(context, expression);
return typeof value === 'function' ? value.bind(context) : value;
}
return evalInContext(context, expression, locals);
}
getter.assign = function (context, value) {
setter(context, value, expression);
}
return getter;
};