From bed6231d6b9166e1ac3de4fb0fb00032ed25eac0 Mon Sep 17 00:00:00 2001 From: ZDDC Date: Mon, 8 Jun 2026 08:24:56 -0500 Subject: [PATCH] fix(browse): empty rename-cue box; signal sync-on-open changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The rename-cue div used an inline display:flex, which outranks the `hidden` attribute's [hidden]{display:none} — so fmWarn.hidden=true never hid it and an empty yellow box showed whenever the cue had nothing to say. Control visibility via style.display ('none'/'flex') instead of the hidden attribute. Also surface a status line when sync-on-open rewrites the front matter to match the filename, so the change isn't silent ("Front matter synced to filename — review and save"). Co-Authored-By: Claude Opus 4.8 (1M context) --- browse/js/preview-markdown.js | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/browse/js/preview-markdown.js b/browse/js/preview-markdown.js index 30a665d..bd22c82 100644 --- a/browse/js/preview-markdown.js +++ b/browse/js/preview-markdown.js @@ -450,11 +450,14 @@ // discarding the value. Populated by renderIdentityCue(). var fmWarn = document.createElement('div'); fmWarn.className = 'md-fm__warn'; - fmWarn.hidden = true; + // Visibility is controlled via style.display (toggled in + // renderIdentityCue), NOT the `hidden` attribute: an inline + // display:flex outranks [hidden]{display:none}, which would leave an + // empty box on screen whenever the cue has nothing to say. fmWarn.style.cssText = 'color:#92400e;background:#fffbeb;border:1px solid ' + '#fcd34d;border-radius:4px;padding:6px 8px;margin:0 0 4px;font-size:' - + '0.78rem;line-height:1.5;display:flex;flex-wrap:wrap;align-items:' - + 'center;gap:6px;'; + + '0.78rem;line-height:1.5;flex-wrap:wrap;align-items:center;gap:6px;' + + 'display:none;'; fmSection.appendChild(fmHeader); fmSection.appendChild(fmWarn); fmSection.appendChild(fmBody); @@ -822,7 +825,7 @@ function renderIdentityCue() { while (fmWarn.firstChild) fmWarn.removeChild(fmWarn.firstChild); var fid = filenameIdentity(node.name); - if (!fid || !canSave(node)) { fmWarn.hidden = true; return; } + if (!fid || !canSave(node)) { fmWarn.style.display = 'none'; return; } var data = parseFrontMatter('---\n' + fmTextarea.value + '\n---\n').data || {}; var edits = []; IDENTITY_FIELDS.forEach(function (f) { @@ -831,7 +834,7 @@ var want = String(fid[f.fm] == null ? '' : fid[f.fm]).trim(); if (got !== '' && got !== want) edits.push(f.label + ' → “' + got + '”'); }); - if (!edits.length) { fmWarn.hidden = true; return; } + if (!edits.length) { fmWarn.style.display = 'none'; return; } var msg = document.createElement('span'); msg.textContent = '✎ Identity comes from the filename. You changed ' + edits.join(', ') + '. '; @@ -846,7 +849,7 @@ btn.addEventListener('click', function () { renameToMatch(newName); }); fmWarn.appendChild(btn); } - fmWarn.hidden = false; + fmWarn.style.display = 'flex'; } // Rename action: persist the current buffer (so body edits aren't @@ -911,8 +914,12 @@ renderIdentityCue(); // initial state on load (clean after sync-on-open) // If sync-on-open corrected the front matter, open the buffer dirty so - // a save bakes the filename-derived identity in. - if (writableMode && fmTextarea.value !== onDiskFM) markDirty(true); + // a save bakes the filename-derived identity in — and say so, since the + // change is otherwise silent (the values just match the filename now). + if (writableMode && fmTextarea.value !== onDiskFM) { + markDirty(true); + statusEl.textContent = 'Front matter synced to filename — review and save'; + } // ── Save ─────────────────────────────────────────────────────────── // Mark a successful write: adopt the new server ETag (so the next