Skip to content

Preserve reading positions across source mode - #218

Merged
Renakoni merged 2 commits into
mainfrom
fix/source-mode-resume
Sep 19, 2026
Merged

Renakoni merged 2 commits into
mainfrom
fix/source-mode-resume

Conversation

@Renakoni

@Renakoni Renakoni commented Sep 19, 2026 •

Copy link
Copy Markdown
Owner

Summary

Switching from WYSIWYG to source mode and then backgrounding the app could replace the reading position with the document end. Resume capture still measured Muya's hidden DOM, whose rectangles were zero-sized, and source edits could pair that stale structure with the textarea's newer Markdown. Capture now preserves the visible WYSIWYG position before the handoff and skips capture while source mode owns the document.

Behavior

  • Entering source mode captures the current WYSIWYG anchor before hiding its layout and dismisses its resume UI/stabilization.
  • Backgrounding or closing a source-mode session leaves the previous WYSIWYG record intact. A source-only session creates no WYSIWYG record.
  • Source edits keep using the existing content-autosave path. On reopen, the existing exact-content validation discards any now-obsolete reading position.
  • Returning to WYSIWYG enables normal live position capture again.

Design and responsibility boundaries

App.vue owns the editing-mode decision. Only the resume controller's Markdown getter returns null while source mode is active; document autosave, share/export, source-mode undo, and caret handoff retain their existing snapshot behavior. The existing nullable getter is sufficient, so this adds no mode framework or new settings.

The resume controller rechecks capture-surface availability after asynchronous hash validation. Standing down also cancels the opening-time offer across both layout settling and hash validation, so switching back to WYSIWYG cannot revive a dismissed, still-pending offer. This cancellation lasts only until the next document opening and also honors the existing menu/outline/search handoff callers. Captures already snapshotted before entry may finish under their existing per-document ordering guarantees; canceling restore does not cancel position persistence.

The storage schema, structural block/ratio anchor, manual resume behavior, and strict SHA-256 validation are unchanged. Source-text reading positions are outside this issue's scope. Foreground checkpoint scheduling is tracked separately in #216; this PR's sole fix target is #217.

Verification

  • Three new mobile regressions failed against the original implementation before the fix.
  • Web unit tests after self-review: 83 files / 709 tests passed. Two additional regressions reproduced the pending-offer race during layout settling and asynchronous hashing before the cancellation fix.
  • Resume and source-mode mobile browser E2E: 24/24 passed, including five new cross-mode regressions. The additional slow-hash case switches into and out of source mode before releasing validation, then verifies a fresh opening still offers the saved position.
  • pnpm build (includes TypeScript typecheck) passed.
  • ESLint on all tracked JavaScript/TypeScript/Vue files and focused changed-file ESLint passed.
  • git diff --check passed.

The unfiltered local pnpm lint also traverses pre-existing untracked local-archive evidence and reports errors there; tracked-file validation excludes that workstation-only archive without changing ESLint configuration. These regressions were verified in mobile Chromium, not by terminating an Android process.

Closes #217

@Renakoni
Renakoni merged commit 939c461 into main Sep 19, 2026
6 checks passed
@Renakoni
Renakoni deleted the fix/source-mode-resume branch September 19, 2026 11:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Source mode overwrites reading positions with hidden editor geometry

1 participant