Update the canvas detail view only when drawing is done

And remove the canvas from the view once it's destroyed.
This commit is contained in:
Calixte Denizet 2026-03-26 15:51:37 +01:00
parent 777251da85
commit c2ba6b0e33
2 changed files with 37 additions and 8 deletions

View File

@ -110,10 +110,12 @@ class CanvasContextDetailsView {
this.#ctxStates.set(label, state);
this.#ctxStateStacks.set(label, []);
this.#ctxStackViewIdx.set(label, null);
// If the panel is already visible (stepping in progress), rebuild it so
// the new context section is added and its live-update entries are
// registered.
if (this.#gfxStateValueElements.size > 0) {
// If the panel is already visible and we're at a pause point, rebuild it
// so the new context section is added and its live-update entries are
// registered. Skip the rebuild while frozen (execution is in progress
// between pauses) — the next build() call from #onStepped() will pick it
// up.
if (!this.#frozen && this.#gfxStateValueElements.size > 0) {
this.build();
}
@ -303,9 +305,29 @@ class CanvasContextDetailsView {
}
}
/** Hide the panel. */
/**
* Remove the section for a single context from the panel and all internal
* state maps. Called when a temporary canvas is destroyed.
*/
removeContext(label) {
this.#ctxStates.delete(label);
this.#ctxStateStacks.delete(label);
this.#ctxStackViewIdx.delete(label);
this.#gfxStateValueElements.delete(label);
this.#gfxStateNavElements.delete(label);
this.#panel
.querySelector(
`.gfx-state-section[data-ctx-label="${CSS.escape(label)}"]`
)
?.remove();
}
/** Hide the panel and discard all DOM state so no live updates occur. */
hide() {
this.#panel.hidden = true;
this.#gfxStateValueElements.clear();
this.#gfxStateNavElements.clear();
this.#panel.replaceChildren();
}
/**

View File

@ -355,7 +355,9 @@ class PageView {
destroy(canvasAndCtx) {
const idx = this.#alive.findIndex(e => e.canvasAndCtx === canvasAndCtx);
if (idx !== -1) {
this.#alive[idx].wrapper.remove();
const { wrapper, ctxLabel } = this.#alive[idx];
wrapper.remove();
gfxStateComp.removeContext(ctxLabel);
this.#alive.splice(idx, 1);
}
super.destroy(canvasAndCtx);
@ -393,7 +395,7 @@ class PageView {
checker.className = "canvas-checker";
checker.append(canvasAndCtx.canvas);
wrapper.append(labelEl, checker);
const entry = { canvasAndCtx, wrapper, labelEl };
const entry = { canvasAndCtx, wrapper, labelEl, ctxLabel };
this.#alive.push(entry);
this.#attachWrapper(entry);
}
@ -482,7 +484,10 @@ class PageView {
});
this.#stepButton.addEventListener("click", () => {
globalThis.StepperManager._active?.stepNext();
if (globalThis.StepperManager._active) {
this.#gfxStateComp.freeze();
globalThis.StepperManager._active.stepNext();
}
});
this.#continueButton.addEventListener("click", () => {
@ -580,9 +585,11 @@ class PageView {
}
if (e.key === "s") {
e.preventDefault();
this.#gfxStateComp.freeze();
stepper.stepNext();
} else if (e.key === "c") {
e.preventDefault();
this.#gfxStateComp.freeze();
stepper.continueToBreakpoint();
}
});