From c0f986d5948547cf7758beec7e4e6636287adb83 Mon Sep 17 00:00:00 2001 From: Steffan Date: Mon, 27 Aug 2018 13:15:37 +0200 Subject: [PATCH] update expression parsing --- src/fields.vue | 19 +++++++++++++------ src/util.js | 25 +++++++++---------------- stories/index.js | 2 +- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/fields.vue b/src/fields.vue index 3c80167..e6cd8e6 100644 --- a/src/fields.vue +++ b/src/fields.vue @@ -18,7 +18,7 @@ import FieldSelect from './components/Select.vue'; import FieldRange from './components/Range.vue'; import FieldNumber from './components/Number.vue'; - import {assign, each, evaluate, get, isArray, isString, isUndefined, set, warn} from './util'; + import {assign, each, get, parse, isArray, isString, isUndefined, set, warn} from './util'; export default { @@ -74,16 +74,23 @@ } }, - evaluate(expr, values = this.values) { + evaluate(expression, values = this.values) { - if (isString(expr)) { + try { - const context = {$match, $values: values, $get: key => get(values, key)}; + if (isString(expression)) { + expression = parse(expression); + } + + return expression.call(this, values, { + $match, $get: key => get(values, key) + }); - return evaluate(this, expr, context); + } catch (e) { + warn(e); } - return expr.call(this, values, this); + return true; }, prepare(config = this.config, prefix = this.prefix) { diff --git a/src/util.js b/src/util.js index beffb82..5292538 100644 --- a/src/util.js +++ b/src/util.js @@ -68,24 +68,17 @@ export function set(obj, key, val) { _set(obj, parts.shift(), val); } -const quotedStringRe = /([^"']+)((.)(?:[^\3\\]|\\.)*?\3|.)?/g; +const parsedFunc = {}; const expressionRe = /((?:\d|true|false|null|undefined|(?:this\.|\$)[\S]+|\W)*)([\w][\w+.]*)?/g; -const expressions = {}; -export function evaluate(self, expr, context) { - - expressions[expr] = expressions[expr] || expr.replace(quotedStringRe, (match, unquoted, quoted = '') => - unquoted.replace(expressionRe, (match, prefix = '', expr) => - match ? `${prefix}${expr ? `$get('${expr}')` : ''}` : '' - ) + quoted - ); - - try { - return (Function('c', `with(c){return ${expressions[expr]}}`)).call(self, context); - } catch (e) { - warn(e); - } +const quotedStringRe = /([^"']+)((.)(?:[^\3\\]|\\.)*?\3|.)?/g; - return false; +export function parse(expr) { + return parsedFunc[expr] = parsedFunc[expr] || + Function('$values', '$context', `with($context){return ${expr.replace(quotedStringRe, + (match, unquoted, quoted = '') => unquoted.replace(expressionRe, + (match, prefix = '', expression) => match ? `${prefix}${expression ? `$get('${expression}')` : ''}` : '' + ) + quoted + )}}`); } export function each(obj, iterator) { diff --git a/stories/index.js b/stories/index.js index b682847..082eda5 100644 --- a/stories/index.js +++ b/stories/index.js @@ -2,4 +2,4 @@ import FieldsStory from './components/FieldsStory.vue'; import {storiesOf} from '@storybook/vue'; storiesOf('Fields', module) - .add('Default', () => ({extends: FieldsStory})); + .add('Default', () => FieldsStory);