Repository navigation
Conversation
Upstream PRs applied (all diff-reviewed, tests included and passing): - marktext#4776: preserve ordered-list source markers — opening and saving no longer rewrites 1./1./1. to 1./2./3. (marktext#4772, silent doc mutation) - marktext#4788: UNC/WSL paths become valid file:// authority URLs (file://server/share/…, not file:////…) so network images load (marktext#4577, marktext#4563) - marktext#4952: table columns size to content (min-width 10em → 2em, marktext#4894) - marktext#4773: malformed percent-escape in a clicked link no longer throws an unhandled URIError (marktext#4749) - marktext#4873: Shift+digit/punctuation keybindings recordable and matchable again (patch-package fix for @hfelix/electron-localshortcut, marktext#4863) - marktext#4910: sidebar icons match by extension first, so Dockerfile-Notes.md gets the markdown icon (marktext#4890) - marktext#4317: restored windows are clamped to the target display's work area (multi-monitor / DPI, marktext#2928, marktext#1947) Found while integrating marktext#4776: cloneStateTree shallow-copied meta, so array-valued fields (order-list sourceMarkers, table aligns) stayed SHARED between a getState() clone and the live document — mutating a returned tree corrupted the document. Meta arrays are now copied, and the clone walks an explicit work list instead of recursing, so pathological nesting (600-level lists, marktext#4747) can no longer overflow the call stack (10k-depth regression test). Also: folder search debounces its per-keystroke ripgrep run (300ms, Enter searches immediately, IME-composing keys ignored) (marktext#3556), and a new undoFloor spec pins that undoing past the opened baseline never empties the document (marktext#5028 — legacy-engine bug, does not reproduce on @muyajs/core). muya 1536/1536, desktop 783/783, lint/tsc/madge clean. PLANS.md gains a prioritized backlog from the full 563-item issue/PR survey.
|
Thanks for digging into this, @jianongHe, and apologies for the slow reply on a PR that has been open for a while. The semantics you picked are the right ones: Unfortunately the code this patch edits no longer exists. While reviewing I also found that the same unguarded
So the guard needs to live inside Thank you for the write-up in #4749; the reproduction cases you listed there are in the new regression spec, and the analysis in this PR is what pointed at the right fallback behaviour. |
|
Replacement PR: #5506. It keeps your literal-path fallback, moves the guard into |
…folder (#5506) `resolveLocalLinkTarget` joined the document folder with the link target and then percent-decoded the joined string, unguarded. The target is URL-encoded text taken from the document, but `dirname` is a raw filesystem path that may legally contain `%`, so decoding the join misread the document's own folder name: a folder called `50%off` made every ordinary link inside it throw `URIError` out of the `mt::format-link-click` handler, and one called `my%20docs` resolved to `my docs`. Decode the target alone and join the raw dirname — the mirror of `encodeDirnameForUrl` on the renderer side (#5212). `isAbsolute` keeps testing the encoded target so a `%2F` cannot turn a relative link into an absolute one. A target that is not valid percent-encoding threw as well: `bad%zz.md`, `%.md`, `%E0%A4%A.md`, and also `other.md#100%`, since `toPathname` runs before the `#` split. `%` is a legal filename character, so fall back to the target as written, the same guard the renderer already applies in `SCROLL_TO_ANCHOR`. Keeping it inside `toPathname` is what lets the fragment case resolve: the literal path does not exist, so the `#` split runs and `other.md` opens with `100%` handed to the renderer, which tolerates an undecodable anchor. Since #5298 made this handler `async` the throw surfaced as an unhandled rejection rather than the error dialog reported in #4749, so the symptom on develop was a click that did nothing at all. A click on a target that does not exist stays a no-op, as it already is for any other broken local link. Closes #4749 Supersedes #4773 Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Closes #4749.
Summary
This PR moves local format-link path normalization into a small helper and handles
URIErrorfromdecodeURIComponent(). Valid CommonMark percent-encoded local paths such asbad%20name.mdstill decode, while malformed percent escapes such asbad%zz.md,%.md, and invalid UTF-8 escape sequences are kept as literal path text instead of throwing from the main-process IPC handler.Type of change
Test plan
Verification:
corepack pnpm exec vitest run test/unit/specs/format-link-path.spec.tscorepack pnpm --filter marktext typecheckcorepack pnpm exec vitest run --testTimeout=20000Note:
corepack pnpm teststill fails locally in existingpdf.spec.tstests under the default 5s timeout. The same full Vitest suite passes with--testTimeout=20000(38files,684tests).Notes for reviewers [optional]
No UI screenshot is included because the visible behavior is avoiding a main-process exception for malformed local link paths. The regression tests cover valid percent-decoding and malformed percent escape inputs.
By submitting this pull request, I confirm that my contribution is made under the terms of the MIT license.