ElyMark: a failed editor is told, leaves nothing, and can rebuild (M-13)

A failed build removes its holder. When both editors fail, the page
tells the app and keeps the text; the next mode request rebuilds it.
mark-broken.mjs breaks the editors through setAttribute and checks
the fallback, the told failures, no leftover holders and the rebuild.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-10 14:03:53 -04:00
1 parent 0d4dd64640
commit ca5ac5bb45
6 files changed
+112 -5

No files matched your search

+22 -4
View File
@@ -17,6 +17,8 @@ let pending = null
let current = null
// A mode asked for while an editor builds.
let asked = null
// The text no editor could show; a mode retries it.
let broken = null
// A place to show once the editor is built.
let revealing = null
// The search in force, kept across modes.
@@ -67,11 +69,21 @@ function changed(text) {
revised(text)
}
/** An editor for `mode`; visual falls back to source. */
/** An editor for `mode`; a failed one leaves no holder. */
async function build(text, mode) {
const holder = document.createElement('div')
holder.hidden = true
document.getElementById('document').append(holder)
try {
return await fill(holder, text, mode)
} catch (error) {
holder.remove()
throw error
}
}
/** Builds in `holder`; visual falls back to source. */
async function fill(holder, text, mode) {
const entry = { mode, holder, fallback: false }
if (mode !== 'source') {
const [front, body] = split(text)
@@ -126,15 +138,20 @@ function drop(entry) {
async function show(text, want) {
const turn = ++latest
asked = null
broken = null
if (current) drop(current)
current = null
let entry
try {
entry = await build(text, want)
} catch (error) {
// Source failed too: tell the app, never blank.
if (turn === latest) tell({ kind: 'failed', generation, what: error.name })
return
if (turn !== latest) return
// Source failed too: tell the app, keep the text.
broken = text
tell({ kind: 'failed', generation, what: error.name })
const next = asked
asked = null
return next && mode(next)
}
if (turn !== latest) return drop(entry)
current = entry
@@ -233,6 +250,7 @@ window.addEventListener('scroll', placed, { passive: true })
/** Another mode for the same text; edits are sent first. */
function mode(next) {
if (!current) {
if (broken !== null) return show(broken, next)
asked = next
return
}