// fixtures/inspector-image.mjs — the two pieces of the inspector that // are about pictures (spec §2.7): the image block's file input, and the // Deck section's list of images no slide uses any more. // // The upload itself is uploads.mjs's state machine; this file is the // DOM around it. It draws nothing it was not given: every string // arrives from the page's data attributes (the catalog), and the status // line is text with role="status" on it in the template, so progress // and every refusal are read out rather than shown as a colour. // // One rule worth stating: the file input is never the thing that // changes the document. It hands the finished record to commit() as // register_asset plus a set_block naming it, both in one batch, so the // upload lands in the deck through the same op path — and one undo — // as everything else. import { registerAssetOps, removeAssetOp, unusedAssets } from './inspector-ops.mjs' // The upload states that map onto a line of text, in the order they // happen. Anything not here (idle, error) is handled at the call site. const PROGRESS = { sign: 'uploading', put: 'uploading', register: 'checking', op: 'checking', done: 'done' } /** * The words for one refusal. The server's own message wins when it sent * one — it knows why better than this does — and the client's codes * fall back to the catalog string for each. */ export function uploadMessage (err, labels) { if (!err) return '' if (err.serverMessage) return err.serverMessage switch (err.code) { case 'type': return labels.type case 'toolarge': case 'too_large': return labels.toolarge case 'altfirst': return labels.altfirst default: return labels.failed } } /** * Reconciles the Unused images list by asset id, the same way the * Blocks list is reconciled and for the same reason: fill() runs on * every document change, a colleague's included, and rebuilding would * take a focused Remove button out of the document under somebody's * finger. * * `list` is the