UNPKG

@danielkalen/simplybind

Version:

Magically simple, framework-less one-way/two-way data binding for frontend/backend in ~5kb.

64 lines (52 loc) 1.83 kB
import {Expression} from './ast'; import {createOverrideContext} from './scope'; import {ExpressionObserver} from './expression-observer'; export function hasDeclaredDependencies(descriptor) { return !!(descriptor && descriptor.get && descriptor.get.dependencies); } export function declarePropertyDependencies(ctor, propertyName, dependencies) { let descriptor = Object.getOwnPropertyDescriptor(ctor.prototype, propertyName); descriptor.get.dependencies = dependencies; } export function computedFrom(...rest) { return function(target, key, descriptor) { descriptor.get.dependencies = rest; return descriptor; }; } export class ComputedExpression extends Expression { constructor(name, dependencies) { super(); this.name = name; this.dependencies = dependencies; this.isAssignable = true; } evaluate(scope, lookupFunctions) { return scope.bindingContext[this.name]; } assign(scope, value) { scope.bindingContext[this.name] = value; } accept(visitor) { throw new Error('not implemented'); } connect(binding, scope) { let dependencies = this.dependencies; let i = dependencies.length; while (i--) { dependencies[i].connect(binding, scope); } } } export function createComputedObserver(obj, propertyName, descriptor, observerLocator) { let dependencies = descriptor.get.dependencies; if (!(dependencies instanceof ComputedExpression)) { let i = dependencies.length; while (i--) { dependencies[i] = observerLocator.parser.parse(dependencies[i]); } dependencies = descriptor.get.dependencies = new ComputedExpression(propertyName, dependencies); } let scope = { bindingContext: obj, overrideContext: createOverrideContext(obj) }; return new ExpressionObserver(scope, dependencies, observerLocator); }