UNPKG

mframejs

Version:
154 lines (129 loc) 5.93 kB
import { tokenize } from './ast/tokenize'; import { generateAST } from './ast/generateAst'; import { ClassPropertyObserverCreator } from './property/classPropertyObserverCreator'; import { PropertyObserverHandler } from './property/propertyObserverHandler'; import { Cache } from '../utils/exported'; import { CONSTANTS, IBindingContext } from '../interface/exported'; import { getCorrectContext } from './contextOfObject'; /** * creates binding expression by getting tokens from the text * */ export function createBindingExpression(expression: string, _class: IBindingContext, setterClass: PropertyObserverHandler) { let attributesValues: any[] = []; let ast; if (expression) { if (!setterClass.attributesValues) { let tokens: any; let tokenValues: any = []; let tokenObject: any = []; if (Cache.expressionMap.has(expression)) { const cacheX = Cache.expressionMap.get(expression); ast = (<any>cacheX).ast; tokens = (<any>cacheX).tokens; tokenValues = (<any>cacheX).tokenValues; tokenObject = (<any>cacheX).tokenObject; } else { tokens = tokenize(expression); ast = generateAST(tokens); let curVal: any = null; let curObject: any = []; for (let next = 0; next < tokens.length; next++) { const tok = tokens[next]; if (tok.type === 'variable') { if (!curVal) { curVal = tok.value; curObject.push(tok.value); } else { curVal = curVal + tok.value; curObject.push(tok.value); } } else { if (tok.type === 'operator' && tok.value === '.') { if (curVal) { curVal = curVal + '.'; } } else { if (tok.type === 'operator' // support binding to "somevalue.array[0].name" && tok.value === '[' && tokens[next + 2] && tokens[next + 2].type === 'operator' && tokens[next + 2].value === ']') { if (curVal) { curVal = curVal + '[' + tokens[next + 1].value + ']'; } next = next + 2; } else { if (curVal) { tokenValues.push(curVal); curVal = null; tokenObject.push(curObject); curObject = []; } } } } } if (curVal) { tokenValues.push(curVal); tokenObject.push(curObject); curObject = []; curVal = null; } Cache.expressionMap.set(expression, { ast: ast, tokens: tokens, tokenValues: tokenValues, tokenObject: tokenObject }); } // for each token get the attribute on variables tokenValues.forEach((tok: any) => { const newctx = getCorrectContext(tok, _class); if (typeof tok === 'string' && tok[0] !== '$' && newctx && newctx.__bindingContext && newctx.$context.__proto__ && newctx.$context.__proto__[CONSTANTS.META_COMPUTEDFROM] && newctx.$context.__proto__[CONSTANTS.META_COMPUTEDFROM][tok]) { const computedFrom = newctx.$context.__proto__[CONSTANTS.META_COMPUTEDFROM]; computedFrom[tok].attributes.forEach((val: any) => { if (attributesValues.indexOf(val) === -1) { attributesValues.push(val); } }); } else { if (attributesValues.indexOf(tok) === -1) { attributesValues.push(tok); } } }); // set ast to setter setterClass.setAst(ast); } else { attributesValues = setterClass.attributesValues; } // for each attribute found for (let i = 0; i < attributesValues.length; i++) { const newctx = getCorrectContext(attributesValues[i], _class); ClassPropertyObserverCreator.create(newctx || _class, attributesValues[i], setterClass); } // initiate setter class setterClass.init(); setterClass.attributesValues = attributesValues; } } /** * remove binding expression * */ export function removeBindingExpression(text: string, _class: IBindingContext, handlerClass: PropertyObserverHandler) { if (text && handlerClass.attributesValues) { const attributesValues = handlerClass.attributesValues; for (let i = 0; i < attributesValues.length; i++) { const newctx = getCorrectContext(attributesValues[i], _class); ClassPropertyObserverCreator.remove(newctx || _class, attributesValues[i], handlerClass); } } }