import { resolve } from '@aurelia/kernel'; import { type Scope, INodeObserverLocator, IObserverLocator } from '@aurelia/runtime'; import { type IBinding, fromView } from '../../binding/interfaces-bindings'; import { NodeObserverLocator } from '../../observation/observer-locator'; import { behaviorTypeName, type BindingBehaviorInstance, type BindingBehaviorStaticAuDefinition } from '../binding-behavior'; import { PropertyBinding } from '../../binding/property-binding'; import { ErrorNames, createMappedError } from '../../errors'; export class UpdateTriggerBindingBehavior implements BindingBehaviorInstance { public static readonly $au: BindingBehaviorStaticAuDefinition = { type: behaviorTypeName, name: 'updateTrigger', }; /** @internal */ private readonly _observerLocator = resolve(IObserverLocator); /** @internal */ private readonly _nodeObserverLocator = resolve(INodeObserverLocator) as NodeObserverLocator; public bind(_scope: Scope, binding: IBinding, ...events: string[]): void { if (!(this._nodeObserverLocator instanceof NodeObserverLocator)) { throw createMappedError(ErrorNames.update_trigger_behavior_not_supported); } if (events.length === 0) { throw createMappedError(ErrorNames.update_trigger_behavior_no_triggers); } if (!(binding instanceof PropertyBinding) || !(binding.mode & fromView)) { throw createMappedError(ErrorNames.update_trigger_invalid_usage); } // ensure the binding's target observer has been set. const targetConfig = this._nodeObserverLocator.getNodeObserverConfig( binding.target as HTMLElement, binding.targetProperty, ); // todo(bigopon): potentially updateTrigger can be used to teach Aurelia adhoc listening capability // since event names are the only thing needed if (targetConfig == null) { throw createMappedError(ErrorNames.update_trigger_behavior_node_property_not_observable, binding); } const targetObserver = this._nodeObserverLocator.getNodeObserver( binding.target as HTMLElement, binding.targetProperty, this._observerLocator, )!; // the check on targetConfig ensures it's not null, save execessive check her targetObserver.useConfig({ readonly: targetConfig.readonly, default: targetConfig.default, events }); binding.useTargetObserver(targetObserver); } }