Skip to content

Commit 509f27e

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 a3e9c99 commit 509f27e

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
@@ -5984,8 +5984,6 @@ export class PresentationEditor extends EventEmitter {
59845984

59855985
if (!this.#editor) return false;
59865986

5987-
let enteredHeaderFooter = false;
5988-
59895987
try {
59905988
if (story.storyType === 'headerFooterSlot' || story.storyType === 'headerFooterPart') {
59915989
const region = this.#findHeaderFooterRegionForStory(story);
@@ -5994,17 +5992,24 @@ export class PresentationEditor extends EventEmitter {
59945992
this.#scrollPageIntoView(region.pageIndex);
59955993
await this.#waitForPageMount(region.pageIndex, { timeout: PresentationEditor.ANCHOR_NAV_TIMEOUT_MS });
59965994
this.#activateHeaderFooterRegion(region);
5997-
enteredHeaderFooter = true;
5998-
5999-
const activeEditor = await this.#waitForHeaderFooterEditor(PresentationEditor.ANCHOR_NAV_TIMEOUT_MS);
6000-
if (!activeEditor?.commands?.setTextSelection) return false;
60015995

6002-
// Resolve position in the live editor — the story runtime editor used
6003-
// before activation may be a different instance with different state.
6004-
const resolved = resolveBookmarkTarget(activeEditor.state.doc, target);
6005-
activeEditor.commands.setTextSelection({ from: resolved.pos, to: resolved.pos });
6006-
activeEditor.view?.focus?.();
6007-
return true;
5996+
try {
5997+
const activeEditor = await this.#waitForHeaderFooterEditor(PresentationEditor.ANCHOR_NAV_TIMEOUT_MS);
5998+
if (!activeEditor?.commands?.setTextSelection) return false;
5999+
6000+
// Resolve position in the live editor — the story runtime editor used
6001+
// before activation may be a different instance with different state.
6002+
const resolved = resolveBookmarkTarget(activeEditor.state.doc, target);
6003+
activeEditor.commands.setTextSelection({ from: resolved.pos, to: resolved.pos });
6004+
activeEditor.view?.focus?.();
6005+
return true;
6006+
} finally {
6007+
// If navigation did not succeed, exit header/footer mode so the
6008+
// editor is not left in a stale activation state.
6009+
if (!this.#headerFooterSession?.activeEditor) {
6010+
this.#exitHeaderFooterMode();
6011+
}
6012+
}
60086013
}
60096014

60106015
const runtime = resolveStoryRuntime(this.#editor, story);
@@ -6014,7 +6019,7 @@ export class PresentationEditor extends EventEmitter {
60146019
runtime.editor.view?.focus?.();
60156020
return true;
60166021
} catch (error) {
6017-
if (enteredHeaderFooter) this.#exitHeaderFooterMode();
6022+
this.#exitHeaderFooterMode();
60186023
console.error('[PresentationEditor] navigateTo bookmark failed:', error);
60196024
this.emit('error', {
60206025
error,

0 commit comments

Comments
 (0)