UNPKG

@surface/custom-element

Version:

Provides support of directives and data binding on custom elements.

53 lines (52 loc) 2.29 kB
import { CancellationTokenSource } from "@surface/core"; import { tryEvaluateKeyExpressionByTraceable, tryObserveByObservable, tryObserveKeyByObservable, } from "../common.js"; import TemplateMetadata from "../metadata/template-metadata.js"; import { scheduler } from "../singletons.js"; export default class InjectDirective { constructor(template, descriptor, context) { this.cancellationTokenSource = new CancellationTokenSource(); this.disposed = false; this.key = ""; this.task = () => { this.disposeCurrentInjection(); this.key = `${tryEvaluateKeyExpressionByTraceable(this.context.scope, this.descriptor)}`; const injectionContext = { customDirectives: this.context.directives, descriptor: this.descriptor, host: this.context.host, parentNode: this.context.parentNode, scope: this.context.scope, template: this.template, }; this.metadata.injections.set(this.key, injectionContext); const action = this.metadata.placeholders.get(this.key); if (action) { action(injectionContext); } }; this.template = template; this.descriptor = descriptor; this.context = context; this.metadata = TemplateMetadata.from(context.parentNode); template.remove(); const listener = () => void scheduler.enqueue(this.task, "normal", this.cancellationTokenSource.token); this.keySubscription = tryObserveKeyByObservable(context.scope, descriptor, listener, true); this.subscription = tryObserveByObservable(context.scope, descriptor, listener, true); this.task(); } disposeCurrentInjection() { if (this.key) { this.metadata.injections.delete(this.key); this.metadata.defaults.get(this.key)?.(); } } dispose() { if (!this.disposed) { this.cancellationTokenSource.cancel(); this.disposeCurrentInjection(); this.keySubscription.unsubscribe(); this.subscription.unsubscribe(); this.disposed = true; } } }