fix(links): resolve a relative link to a local file against the document - #409
Merged
Merged
Conversation
PathGao
force-pushed
the
fix/local-file-links
branch
2 times, most recently
from
August 2, 2026 23:11
328d330 to
ce5af0b
Compare
`[data](./data.csv)` was handed to `openUrl(anchor.href)`, and `anchor.href` is what the DOM resolved against the webview origin, not a path on disk. The two platforms then failed differently: on macOS and Linux the origin is `tauri://localhost`, which the opener scope refuses, so the click did nothing and left an uncaught promise rejection; on Windows it is `http://tauri.localhost`, which matches `http://*`, so the browser really opened onto a dead link. `resolveLocalFileLinkPath` reuses `resolveExportImagePath` from #363 for the whole scheme, drive-letter, UNC and query-suffix decision table, and adds two rules a link needs that an image does not: `//host/path` is a web address, matching what `getMarkdownLinkTarget` already assumes, and a relative link in an unsaved buffer resolves to nothing rather than to something relative to the process working directory. Both OS calls are now inside try/catch with a toast, which removes the uncaught rejection and makes the macOS failure visible. The file still will not open until the opener path scope is decided (#399, #403); everything above is an improvement regardless. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
PathGao
force-pushed
the
fix/local-file-links
branch
from
August 2, 2026 23:13
ce5af0b to
4b0d467
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The defect
[data](./data.csv)was handed toopenUrl(anchor.href)— andanchor.hrefis what the DOM resolved against the webview origin, not a path on disk.The two platforms then failed differently:
tauri://localhostForbiddenUrl→ the click does nothing, and sincehandleDocumentClickhad no try/catch, an uncaught promise rejectionhttp://tauri.localhosthttp://*→ the browser really opens onto a dead linkThe fix
resolveLocalFileLinkPath(rawHref, currentFile)reusesresolveExportImagePathfrom #363 for the entire scheme / drive-letter / UNC / query-suffix decision table, and adds the two rules a link needs that an image does not://host/pathis a web address — matching what the app's owngetMarkdownLinkTargetalready assumes, where the image resolver would read it as UNC;The branch sits after the markdown-target branch and before the
openUrlfallback. Both OS calls are now inside try/catch with a toast, which removes the uncaught rejection and turns the silent macOS click into a visible failure.The file still will not open yet
open_pathis refused by the opener scope for every path — see #399, fixed in #403. Without that, this PR is still a strict improvement: no silent click, no uncaught rejection, and Windows no longer hands a dead link to the browser. With it, the link works.The test here asserts only that
opener:allow-open-pathis still granted; it deliberately does not assert the scope's shape, so it does not prejudge whichever scope is chosen in #399.Tests
scripts/localFileLinks.test.ts— the resolver tests run the real function.Not covered
openPath; a missing file surfaces as the toast.🤖 Generated with Claude Code