Keep editor open across in-site navigation, retargeting to the new page
load() closed the editor on every navigation, and the close raced the
navigation: the shell's close-time loadPlain re-render resolved last,
swapping the old page back in and replaceStating its URL. Navigation now
leaves the panel open and the existing pagerite:switch-editor retarget
fires while editing; the exception is /_a, where closeEditor({ navigating:
true }) closes the panel without the re-swap or title restore.
This commit is contained in:
@@ -44,11 +44,13 @@ function openShell() {
|
|||||||
editorLang.value = session
|
editorLang.value = session
|
||||||
pinPreviewLang()
|
pinPreviewLang()
|
||||||
}
|
}
|
||||||
function unpinPreviewLang() {
|
function unpinPreviewLang(ev) {
|
||||||
if (!pinned) return
|
if (!pinned) return
|
||||||
pinned = false
|
pinned = false
|
||||||
setLangOverride(null)
|
setLangOverride(null)
|
||||||
loadPlain(currentPath.value)
|
// A close caused by navigation (to /_a) must not re-render the page the
|
||||||
|
// editor was on: the navigation itself is swapping in the target page.
|
||||||
|
if (!ev?.detail?.navigating) loadPlain(currentPath.value)
|
||||||
}
|
}
|
||||||
watch(editorLang, () => { if (pinned) pinPreviewLang() })
|
watch(editorLang, () => { if (pinned) pinPreviewLang() })
|
||||||
// The page's primary may be (re)learned while pinned on it (doc accept,
|
// The page's primary may be (re)learned while pinned on it (doc accept,
|
||||||
|
|||||||
@@ -125,7 +125,11 @@ function showEditor() {
|
|||||||
dispatchEvent(new CustomEvent('pagerite:editor-shown'))
|
dispatchEvent(new CustomEvent('pagerite:editor-shown'))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function closeEditor() {
|
// navigating: the close is part of a fetch-navigation (to /_a) — the shell
|
||||||
|
// must not re-swap the page it was previewing back in, and the navigation
|
||||||
|
// itself sets the new title, so both the unpin re-render and the title
|
||||||
|
// restore are skipped.
|
||||||
|
export function closeEditor({ navigating = false } = {}) {
|
||||||
if (!visible) return
|
if (!visible) return
|
||||||
visible = false
|
visible = false
|
||||||
stopTrackingPanel()
|
stopTrackingPanel()
|
||||||
@@ -136,7 +140,8 @@ export function closeEditor() {
|
|||||||
host.firstElementChild?.classList.add('closing')
|
host.firstElementChild?.classList.add('closing')
|
||||||
const h = host
|
const h = host
|
||||||
setTimeout(() => { h.style.display = 'none' }, 250)
|
setTimeout(() => { h.style.display = 'none' }, 250)
|
||||||
dispatchEvent(new CustomEvent('pagerite:editor-hidden'))
|
dispatchEvent(new CustomEvent('pagerite:editor-hidden', { detail: { navigating } }))
|
||||||
|
if (navigating) return
|
||||||
// The editor may have dropped the prefetch cache; warm it again for the
|
// The editor may have dropped the prefetch cache; warm it again for the
|
||||||
// now-final page so navigation stays instant.
|
// now-final page so navigation stays instant.
|
||||||
dispatchEvent(new CustomEvent('pagerite:preload-pages'))
|
dispatchEvent(new CustomEvent('pagerite:preload-pages'))
|
||||||
|
|||||||
@@ -843,13 +843,16 @@ import { reconnectPolicy, socketSlot, watchConnecting } from "./reconnect";
|
|||||||
|
|
||||||
// --- Fetch navigation ------------------------------------------------
|
// --- Fetch navigation ------------------------------------------------
|
||||||
async function load(url, push = true, back = false) {
|
async function load(url, push = true, back = false) {
|
||||||
// Navigating with the editor open closes it; unsaved edits are lost
|
// Navigating with the editor open keeps it open: the shell retargets to
|
||||||
// (the region swap discards the previewed changes anyway). Cache must be
|
// the new page once the swap lands (below). The exception is /_a
|
||||||
// bypassed for this navigation because the editor may have invalidated
|
// (analytics), where the panel does not apply — close it there, with
|
||||||
// the prefetched copies of other pages.
|
// navigating: true so the close does not re-swap/re-title the page it
|
||||||
|
// was previewing (this navigation is already swapping). The cache is
|
||||||
|
// bypassed while editing because the editor may have invalidated the
|
||||||
|
// prefetched copies of other pages.
|
||||||
const editing = document.body.classList.contains("editing");
|
const editing = document.body.classList.contains("editing");
|
||||||
if (editing) {
|
if (editing && new URL(url, location.href).pathname === "/_a") {
|
||||||
editorModule?.then((m) => m.closeEditor());
|
await editorModule?.then((m) => m.closeEditor({ navigating: true }));
|
||||||
}
|
}
|
||||||
teardownAnalytics();
|
teardownAnalytics();
|
||||||
let doc;
|
let doc;
|
||||||
@@ -936,7 +939,11 @@ import { reconnectPolicy, socketSlot, watchConnecting } from "./reconnect";
|
|||||||
// own lang="en" dir="ltr", so it is unaffected).
|
// own lang="en" dir="ltr", so it is unaffected).
|
||||||
document.documentElement.lang = doc.documentElement.lang;
|
document.documentElement.lang = doc.documentElement.lang;
|
||||||
document.documentElement.dir = doc.documentElement.dir;
|
document.documentElement.dir = doc.documentElement.dir;
|
||||||
document.title = doc.title;
|
// The editor keeps its own title while open (the retargeted tab
|
||||||
|
// re-applies it); only inherit the server title when not editing.
|
||||||
|
if (!document.body.classList.contains("editing")) {
|
||||||
|
document.title = doc.title;
|
||||||
|
}
|
||||||
// Banners may contain scripts (canvas etc.), content pages may too.
|
// Banners may contain scripts (canvas etc.), content pages may too.
|
||||||
runScripts(document.getElementById("page-banner"));
|
runScripts(document.getElementById("page-banner"));
|
||||||
runScripts(document.getElementById("main"));
|
runScripts(document.getElementById("main"));
|
||||||
|
|||||||
Reference in New Issue
Block a user