67 lines
2.6 KiB
JavaScript
67 lines
2.6 KiB
JavaScript
// The page editor: one markdown editor (core.js) inside the edit form, saved
|
|
// with the header's SAVE button.
|
|
(function () {
|
|
var mount = document.getElementById('editor');
|
|
var hidden = document.getElementById('editor-content');
|
|
if (!mount || !hidden || !window.CM) return;
|
|
|
|
var form = hidden.closest('form');
|
|
var editor = MarkdownEditor.create(mount, { doc: hidden.value });
|
|
|
|
// --- Content sync ---
|
|
|
|
// Serialize the CM document into the hidden textarea on submit only — Save
|
|
// must not depend on CM focus or async state (decision 8). requestSubmit
|
|
// fires this listener even for the ALT+SHIFT+S path.
|
|
function syncContent() {
|
|
hidden.value = editor.getValue();
|
|
}
|
|
|
|
// Save POSTs via fetch and then rewrites the *editor's* history entry with
|
|
// the resulting page, so the edit session and its result share a single
|
|
// entry (see history-nav.js). A plain form submit would push a second one
|
|
// and leave the editor sitting in history behind the saved page.
|
|
//
|
|
// The server answers 204 + X-Target instead of a 303 because the target may
|
|
// carry a #section anchor the client cannot compute, and fetch drops the
|
|
// fragment from a followed redirect.
|
|
function postSave() {
|
|
syncContent();
|
|
var body = new URLSearchParams(new FormData(form)).toString();
|
|
fetch(form.action, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
'X-Save-Mode': 'replace',
|
|
},
|
|
body: body,
|
|
}).then(function (res) {
|
|
if (!res.ok) {
|
|
return res.text().then(function (msg) {
|
|
alert(msg || ('Save failed (' + res.status + ')'));
|
|
});
|
|
}
|
|
var target = res.headers.get('X-Target') || form.action;
|
|
// replaceState + reload rather than location.replace: if target
|
|
// differs from the current URL only by fragment the browser would
|
|
// skip the re-fetch and show pre-save content.
|
|
window.history.replaceState(null, '', target);
|
|
window.location.reload();
|
|
}).catch(function () {
|
|
alert('Network error — the page was not saved');
|
|
});
|
|
}
|
|
|
|
form.addEventListener('submit', function (e) {
|
|
e.preventDefault();
|
|
postSave();
|
|
});
|
|
|
|
// --- Actions ---
|
|
|
|
editor.actions.save = function () { form.requestSubmit(); };
|
|
|
|
// The toolbar and the header SAVE button both name actions.
|
|
MarkdownEditor.bind(document.body, function () { return editor.actions; });
|
|
})();
|