@surface/custom-element
Version:
Provides support of directives and data binding on custom elements.
50 lines (49 loc) • 2.03 kB
JavaScript
import { CancellationTokenSource } from "@surface/core";
import { scheduler } from "../../singletons.js";
import TemplateMetadata from "../metadata/template-metadata.js";
import observe from "../observe.js";
export default class InjectStatement {
constructor(context) {
this.context = context;
this.cancellationTokenSource = new CancellationTokenSource();
this.disposed = false;
this.key = "";
this.task = () => {
this.disposeCurrentInjection();
this.key = this.context.key(this.context.scope);
const injectionContext = {
directives: this.context.directives,
factory: this.context.factory,
host: this.context.host,
parent: this.context.parent,
pattern: this.context.value,
scope: this.context.scope,
};
this.metadata.injections.set(this.key, injectionContext);
const action = this.metadata.placeholders.get(this.key);
if (action) {
action(injectionContext);
}
};
this.metadata = TemplateMetadata.from(context.parent);
const listener = () => void scheduler.enqueue(this.task, "normal", this.cancellationTokenSource.token);
this.keySubscription = observe(context.scope, context.observables[0], listener, true);
this.subscription = observe(context.scope, context.observables[1], 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;
}
}
}