fix(browse): don't inject front matter on open; no conflict modal on rename
Two fixes to the markdown editor's identity handling: - Sync-on-open now only RECONCILES front-matter identity keys the author already wrote (correcting a stale title/revision/…); it never ADDS them. A blank or new file opens blank instead of getting an auto-generated title at the top. The converter derives identity from the filename regardless, so an empty front matter needs nothing baked in. (Cancel/revert likewise only touches existing keys.) - The "Rename file & reopen" flow force-writes the buffer (no If-Match) instead of routing through save(), which raised the conflict-resolution modal on a (spurious) 412. The rename is a deliberate user action and the identity edit that triggered it is consumed by the new filename, so we commit the buffer rather than interrupting with a merge dialog. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
cfe379d4f9
commit
84f93ba56d
1 changed files with 34 additions and 10 deletions
|
|
@ -603,16 +603,22 @@
|
|||
// even if we tweak whitespace in the YAML lines.
|
||||
var initialParsed = parseFrontMatter(text);
|
||||
var bodyText = initialParsed.body;
|
||||
// On open, mirror the filename-derived identity into the front matter
|
||||
// (the filename is the single source of truth; this keeps the values
|
||||
// baked in for the converter). No-op for non-ZDDC filenames. The dirty
|
||||
// On open, RECONCILE existing front-matter identity keys with the
|
||||
// filename (the single source of truth) — but never ADD them. A blank
|
||||
// or new file opens blank (we don't inject a title etc.); a file whose
|
||||
// author already wrote a now-stale title/revision/… gets corrected.
|
||||
// The converter derives identity from the filename regardless, so
|
||||
// there's nothing to "bake in" for an empty front matter. The dirty
|
||||
// baseline stays the ON-DISK state, so a correction opens the buffer
|
||||
// dirty and a save persists it.
|
||||
var onDiskFM = stringifyFrontMatter(initialParsed.data);
|
||||
var fid = filenameIdentity(node.name);
|
||||
if (fid) {
|
||||
for (var ik in fid) {
|
||||
if (Object.prototype.hasOwnProperty.call(fid, ik)) initialParsed.data[ik] = fid[ik];
|
||||
if (Object.prototype.hasOwnProperty.call(fid, ik)
|
||||
&& Object.prototype.hasOwnProperty.call(initialParsed.data, ik)) {
|
||||
initialParsed.data[ik] = fid[ik];
|
||||
}
|
||||
}
|
||||
}
|
||||
var syncedFM = stringifyFrontMatter(initialParsed.data);
|
||||
|
|
@ -891,7 +897,10 @@
|
|||
if (!fid) return;
|
||||
var data = parseFrontMatter('---\n' + fmCM.getValue() + '\n---\n').data || {};
|
||||
for (var k in fid) {
|
||||
if (Object.prototype.hasOwnProperty.call(fid, k)) data[k] = fid[k];
|
||||
if (Object.prototype.hasOwnProperty.call(fid, k)
|
||||
&& Object.prototype.hasOwnProperty.call(data, k)) {
|
||||
data[k] = fid[k];
|
||||
}
|
||||
}
|
||||
fmCM.setValue(stringifyFrontMatter(data));
|
||||
var body = editor.getMarkdown();
|
||||
|
|
@ -909,11 +918,26 @@
|
|||
async function renameToMatch(newName) {
|
||||
var up = window.app.modules.upload;
|
||||
if (!up || !up.renameNode || !newName) return;
|
||||
// 1. Save first so body/FM edits survive the rename. A failed save
|
||||
// (conflict, ACL) leaves the buffer dirty — abort the rename.
|
||||
if (instance.dirty) {
|
||||
await save();
|
||||
if (currentInstance !== instance || instance.dirty) return;
|
||||
// 1. Persist the current buffer first so body edits survive the
|
||||
// rename. Force the write (no If-Match) — the user deliberately
|
||||
// initiated this rename, so we commit their version rather than
|
||||
// interrupting with the conflict-resolution modal (which save()
|
||||
// raises on a 412). The identity edit that triggered the rename
|
||||
// is consumed by the new filename, so there's nothing to merge.
|
||||
if (instance.dirty && canSave(node)) {
|
||||
try {
|
||||
var content = assembleContent(fmCM.getValue(), editor.getMarkdown());
|
||||
statusEl.textContent = 'Saving…';
|
||||
var res = await saveContent(node, content, { force: true });
|
||||
await markSaved(content, res);
|
||||
if (currentInstance !== instance) return;
|
||||
} catch (e) {
|
||||
statusEl.textContent = '';
|
||||
if (window.zddc && window.zddc.toast) {
|
||||
window.zddc.toast('Save failed: ' + (e.message || e), 'error');
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 2. Rename on disk.
|
||||
try {
|
||||
|
|
|
|||
Loading…
Reference in a new issue