@malagu/core
Version:
85 lines (73 loc) • 2.91 kB
text/typescript
import { Component, Autowired } from '../annotation';
import { JexlEngineProvider, ExpressionHandler, ExpressionContextProvider, ExpressionCompiler, ExpressionContext } from './expression-protocol';
import * as traverse from 'traverse';
export class ExpressionHandlerImpl implements ExpressionHandler {
protected readonly jexlEngineProvider: JexlEngineProvider<any>;
protected readonly expressionContextProvider: ExpressionContextProvider;
protected readonly expressionCompiler: ExpressionCompiler;
protected _ctx: ExpressionContext;
protected getContext(ctx?: ExpressionContext) {
const c = ctx || this.expressionContextProvider.provide();
if (!ctx && c !== this._ctx) {
this._ctx = c;
this.handle(c, c);
}
return c;
}
handle(textOrObj: string | Object, ctx?: ExpressionContext): any {
if (typeof textOrObj === 'string') {
return this.doHandle(textOrObj, ctx);
} else {
const self = this;
traverse(textOrObj).forEach(function (value: any) {
if (typeof value === 'string') {
this.update(self.handle(value, ctx));
} else if (value && (value as any)._ignoreEl === true) {
this.update(value, true);
}
});
return textOrObj;
}
}
protected doHandle(text: string, ctx?: ExpressionContext): any {
const sections = this.expressionCompiler.compileSections(text);
if (sections.length > 0) {
if (this.hasExpression(sections)) {
const c = this.getContext(ctx);
if (sections.length === 1) {
let value = sections[0].evalSync(c);
if (typeof value === 'string') {
value = this.handle(value, c);
}
return value;
}
const result: string[] = [];
for (const section of sections) {
if (typeof section === 'string') {
result.push(section);
} else {
let value = section.evalSync(c);
if (typeof value === 'string') {
value = this.handle(value, c);
}
result.push(value);
}
}
return result.join('');
}
}
return text;
}
protected hasExpression(sections: any[]) {
for (const section of sections) {
if (typeof section !== 'string') {
return true;
}
}
return false;
}
}