import { Container } from "@akala/commands/browser"; import type { Composer } from "../template.js"; import { Binding, Injector, type Subscription } from "@akala/core"; import { DataBind, type DataBindPlugin } from "./context.js"; import { subscribe } from "../common.js"; import { type Expressions } from "@akala/core/expressions"; export class FormInjector extends Injector { onResolve(name: string | symbol): PromiseLike; onResolve(name: string | symbol, handler: (value: T) => void): void; onResolve(name: string | symbol, handler?: (value: T) => void): void | PromiseLike { if (!handler) { this.onResolve(name).then(handler); } return Promise.resolve(this.form.elements[name].value) } constructor(public form: HTMLFormElement) { super(); } public inspect() { console.log(this.form.elements); } resolve(param: string): T { return this.form.elements[param]?.value; } } export class FormComposer implements Composer> { constructor(private container?: Container) { } readonly selector = 'form'; optionGetter(options: object): Container { return options['container']; } apply(form: HTMLFormElement, container?: Container): Disposable//: Promise[]> { const abort = new AbortController() form.addEventListener('submit', async (ev) => { ev.preventDefault(); try { await (container || this.container).dispatch(form.action.substring(document.baseURI.length), { _trigger: 'html', params: [], form: new FormInjector(form), element: form, document: document }); } catch (e) { console.error(e); } }, { signal: abort.signal }) return { [Symbol.dispose]() { abort.abort(); } } } } export class InputValueComposer implements DataBindPlugin { readonly selector: string = 'input'; getBindings(item: HTMLInputElement, binding: Binding, context: Binding, member: TKey, source: Expressions): Subscription { if (member == 'value') { return subscribe(item, 'input', () => binding.setValue(item.value)); } } } DataBind.plugins.push(new InputValueComposer());