Skip to content

Commit 12aa601

Browse files
fix(navigation): exit header/footer mode on all bookmark navigation failure paths
The cleanup that exits header/footer mode only ran inside the catch block, so non-exceptional early returns (editor timeout, missing setTextSelection) left the editor stuck in header/footer mode. Wrap post-activation logic in try/finally to guarantee cleanup.
1 parent 0443332 commit 12aa601

1 file changed

Lines changed: 18 additions & 13 deletions

File tree

packages/super-editor/src/editors/v1/core/presentation-editor/PresentationEditor.ts

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6020,8 +6020,6 @@ export class PresentationEditor extends EventEmitter {
60206020

60216021
if (!this.#editor) return false;
60226022

6023-
let enteredHeaderFooter = false;
6024-
60256023
try {
60266024
if (story.storyType === 'headerFooterSlot' || story.storyType === 'headerFooterPart') {
60276025
const region = this.#findHeaderFooterRegionForStory(story);
@@ -6030,17 +6028,24 @@ export class PresentationEditor extends EventEmitter {
60306028
this.#scrollPageIntoView(region.pageIndex);
60316029
await this.#waitForPageMount(region.pageIndex, { timeout: PresentationEditor.ANCHOR_NAV_TIMEOUT_MS });
60326030
this.#activateHeaderFooterRegion(region);
6033-
enteredHeaderFooter = true;
6034-
6035-
const activeEditor = await this.#waitForHeaderFooterEditor(PresentationEditor.ANCHOR_NAV_TIMEOUT_MS);
6036-
if (!activeEditor?.commands?.setTextSelection) return false;
60376031

6038-
// Resolve position in the live editor — the story runtime editor used
6039-
// before activation may be a different instance with different state.
6040-
const resolved = resolveBookmarkTarget(activeEditor.state.doc, target);
6041-
activeEditor.commands.setTextSelection({ from: resolved.pos, to: resolved.pos });
6042-
activeEditor.view?.focus?.();
6043-
return true;
6032+
try {
6033+
const activeEditor = await this.#waitForHeaderFooterEditor(PresentationEditor.ANCHOR_NAV_TIMEOUT_MS);
6034+
if (!activeEditor?.commands?.setTextSelection) return false;
6035+
6036+
// Resolve position in the live editor — the story runtime editor used
6037+
// before activation may be a different instance with different state.
6038+
const resolved = resolveBookmarkTarget(activeEditor.state.doc, target);
6039+
activeEditor.commands.setTextSelection({ from: resolved.pos, to: resolved.pos });
6040+
activeEditor.view?.focus?.();
6041+
return true;
6042+
} finally {
6043+
// If navigation did not succeed, exit header/footer mode so the
6044+
// editor is not left in a stale activation state.
6045+
if (!this.#headerFooterSession?.activeEditor) {
6046+
this.#exitHeaderFooterMode();
6047+
}
6048+
}
60446049
}
60456050

60466051
const runtime = resolveStoryRuntime(this.#editor, story);
@@ -6050,7 +6055,7 @@ export class PresentationEditor extends EventEmitter {
60506055
runtime.editor.view?.focus?.();
60516056
return true;
60526057
} catch (error) {
6053-
if (enteredHeaderFooter) this.#exitHeaderFooterMode();
6058+
this.#exitHeaderFooterMode();
60546059
console.error('[PresentationEditor] navigateTo bookmark failed:', error);
60556060
this.emit('error', {
60566061
error,

0 commit comments

Comments
 (0)