From c70c5b970a9d656d31358fa164c249096b2dcf29 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Sun, 1 Oct 2023 12:50:29 +0200 Subject: properly restore element order when updating --- src/element.ts | 20 +++++++++++++------- src/observable.ts | 4 ++-- 2 files changed, 15 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/element.ts b/src/element.ts index bee4ddb..354b976 100644 --- a/src/element.ts +++ b/src/element.ts @@ -16,7 +16,7 @@ interface Opts { onchange?: (e: E) => void, } -function apply_opts(e: E, o: Opts): (() => unknown) | void { +function apply_opts(e: E, o: Opts): (() => void) | void { if (o.id) e.id = o.id if (o.for) (e as unknown as HTMLLabelElement).htmlFor = o.for if (o.type && e instanceof HTMLInputElement) e.type = o.type @@ -55,7 +55,8 @@ export function e(name: K, ...children: E return el } -function e_apply>(el: HTMLElementTagNameMap[K], c: C): () => unknown { +interface RedoParams { before?: HTMLElement } +function e_apply>(el: HTMLElementTagNameMap[K], c: C, redo?: RedoParams): () => RedoParams | void { if (typeof c == "undefined") { return () => { } } @@ -66,14 +67,19 @@ function e_apply>(el: HT } } else if (c instanceof HTMLElement) { - el.append(c) - return () => el.removeChild(c) + el.insertBefore(c, redo?.before ?? null) + return () => { + const p = c.nextSibling as (HTMLElement | void); + el.removeChild(c) + return { before: p ?? undefined } + } } else if (c instanceof OVar) { - let undo_last: () => unknown; + let undo_last: () => RedoParams | void; return c.onchangeinit(val => { - if (undo_last) undo_last() - undo_last = e_apply(el, val) + let redo_param = undefined; + if (undo_last) redo_param = undo_last() + undo_last = e_apply(el, val, redo_param ?? undefined) }) } else return apply_opts(el, c) ?? (() => { }) diff --git a/src/observable.ts b/src/observable.ts index 3e1308c..f00b845 100644 --- a/src/observable.ts +++ b/src/observable.ts @@ -17,11 +17,11 @@ export class OVar { this.observers.forEach(o => o(v)) } - onchange(handler: (v: T) => unknown): () => unknown { + onchange(handler: (v: T) => unknown): () => void { this.observers.push(handler) return () => this.observers = this.observers.filter(o => o != handler) } - onchangeinit(handler: (v: T) => unknown): () => unknown { + onchangeinit(handler: (v: T) => unknown): () => void { const abort = this.onchange(handler) handler(this.value) return abort -- cgit v1.2.3-70-g09d2