Relative non-image links should go to blob view, not raw #185

Closed
opened 2026-09-06 23:17:09 +00:00 by crueber · 3 comments
Owner

Relative non-image links resolve to raw instead of the blob view

[MIT @ Christopher Rueber](LICENSE) renders as …/api/blob/main/LICENSE?raw — a raw download. It should go to the blob view page …/blob/main/LICENSE, exactly like .md links do.

Fix

Change the resolver rule: images → raw bytes; every other relative link → in-app blob view at the same ref (directories → tree view where the target resolves to a tree? If cheap; otherwise blob route handles it or 404s honestly — decide in the change). This amends the #183 "others → raw" trade-off (document the amendment). Raw remains one click away via the blob page's raw pill.

Acceptance criteria

  • LICENSE-style links land on the blob view; images still load inline via raw.
  • node --test green (updated URL-matrix expectations); browser check both themes, zero console errors; no new deps.
# Relative non-image links resolve to raw instead of the blob view `[MIT @ Christopher Rueber](LICENSE)` renders as `…/api/blob/main/LICENSE?raw` — a raw download. It should go to the blob view page `…/blob/main/LICENSE`, exactly like `.md` links do. ## Fix Change the resolver rule: **images → raw bytes; every other relative link → in-app blob view** at the same ref (directories → tree view where the target resolves to a tree? If cheap; otherwise blob route handles it or 404s honestly — decide in the change). This amends the #183 "others → raw" trade-off (document the amendment). Raw remains one click away via the blob page's raw pill. ## Acceptance criteria - [ ] LICENSE-style links land on the blob view; images still load inline via raw. - [ ] `node --test` green (updated URL-matrix expectations); browser check both themes, zero console errors; no new deps.
Author
Owner

Fixed by PR #186 (branch fix/issue-185): non-image relative links now resolve to the blob view; trailing-slash/repo-root → tree view. node --test 379/379 green; browser proof (dark+light, zero console errors) in the PR description.

Fixed by PR #186 (branch fix/issue-185): non-image relative links now resolve to the blob view; trailing-slash/repo-root → tree view. node --test 379/379 green; browser proof (dark+light, zero console errors) in the PR description.
Author
Owner

Review of PR #186 (0cb0f49, fix for #185) — verified in scratch worktree /tmp/pr186, main worktree untouched.

Images still → raw: YES. rewriteUrl isImage branch (web/src/lib/render-md.js:140) is the only rawBase/withRaw consumer; image matrix pins it incl. i → /api/blob ?raw (md-urls.test.js:90-95). No straggler rule sends links to raw — grep confirms rawBase/withRaw referenced only on the isImage path.

Every other relative link → blob view: YES. Non-image fallthrough (render-md.js:151) builds /{o}/{r}/blob/{ref}/{path}; LICENSE-style case pinned (md-urls.test.js:55). .md-leaf test (md-urls.test.js:66-69) now redundant but harmless — still passes since all links share one rule.

Trailing-slash → tree: SANE. render-md.js:146-150: empty resolved (repo root, incl. / and over-climbed ..) or path ending in / → /tree/{ref}[/{path}]. Tests pin sub/, /docs/, ./, /, suffix-verbatim sub/?a=b#L10 (md-urls.test.js:58-64). Slash-less dir → blob route, 404s honestly as documented — verified: a → /o/r/blob/main/docs.

Suffix ?raw on blob link: VERBATIM preserved (a → /o/r/blob/main/docs/f.zip?raw) — matches documented no-merge rule; &raw merge is images-only now (render-md.js:113-121 + test :75).

MD_EXT_RE deletion: COMPLETE. Zero matches in web/ (grep).

Sanitizer ordering: UNCHANGED. renderBody = sanitize(renderMarkdownHtml(...)) (render-md.js:174-177); dangerous-scheme passthrough pins intact (md-urls.test.js:134-142).

Anchors/absolute/mailto: UNTOUCHED — early return (render-md.js:137) + pins incl. empty href (md-urls.test.js:78-86).

Doc AMENDED entry: EXPLICIT. 12_web_ui.md:496 preserves old rule as history (#182 others→raw trade-off named, reason for change stated, no-merge + tree-signal + raw-pill noted).

No new deps: YES. web/package.json runtime still exactly solid-js + @solidjs/router + marked@18.0.11 + dompurify@3.4.15.

Laws: 1 (deps) OK; 7 (no silent waiting — N/A, pure render-time rewrite, no async); 8 (no new seams/registries touched) OK; 12 (doc + code in same change) OK.

VERIFY: node --test web/test/unit/*.test.js → 379 pass / 0 fail; vite build → clean (123 modules, JS 424.20 kB). No browser pass (per instructions, node + reasoning only).

No fixes needed — nothing pushed. MERGE RECOMMENDATION: ready to merge.

Review of PR #186 (0cb0f49, fix for #185) — verified in scratch worktree /tmp/pr186, main worktree untouched. Images still → raw: YES. rewriteUrl isImage branch (web/src/lib/render-md.js:140) is the only rawBase/withRaw consumer; image matrix pins it incl. ![i](a.md) → /api/blob ?raw (md-urls.test.js:90-95). No straggler rule sends links to raw — grep confirms rawBase/withRaw referenced only on the isImage path. Every other relative link → blob view: YES. Non-image fallthrough (render-md.js:151) builds /{o}/{r}/blob/{ref}/{path}; LICENSE-style case pinned (md-urls.test.js:55). .md-leaf test (md-urls.test.js:66-69) now redundant but harmless — still passes since all links share one rule. Trailing-slash → tree: SANE. render-md.js:146-150: empty resolved (repo root, incl. [/](/) and over-climbed ..) or path ending in / → /tree/{ref}[/{path}]. Tests pin sub/, /docs/, ./, /, suffix-verbatim sub/?a=b#L10 (md-urls.test.js:58-64). Slash-less dir → blob route, 404s honestly as documented — verified: [a](docs) → /o/r/blob/main/docs. Suffix ?raw on blob link: VERBATIM preserved ([a](f.zip?raw) → /o/r/blob/main/docs/f.zip?raw) — matches documented no-merge rule; &raw merge is images-only now (render-md.js:113-121 + test :75). MD_EXT_RE deletion: COMPLETE. Zero matches in web/ (grep). Sanitizer ordering: UNCHANGED. renderBody = sanitize(renderMarkdownHtml(...)) (render-md.js:174-177); dangerous-scheme passthrough pins intact (md-urls.test.js:134-142). Anchors/absolute/mailto: UNTOUCHED — early return (render-md.js:137) + pins incl. empty href (md-urls.test.js:78-86). Doc AMENDED entry: EXPLICIT. 12_web_ui.md:496 preserves old rule as history (#182 others→raw trade-off named, reason for change stated, no-merge + tree-signal + raw-pill noted). No new deps: YES. web/package.json runtime still exactly solid-js + @solidjs/router + marked@18.0.11 + dompurify@3.4.15. Laws: 1 (deps) OK; 7 (no silent waiting — N/A, pure render-time rewrite, no async); 8 (no new seams/registries touched) OK; 12 (doc + code in same change) OK. VERIFY: node --test web/test/unit/*.test.js → 379 pass / 0 fail; vite build → clean (123 modules, JS 424.20 kB). No browser pass (per instructions, node + reasoning only). No fixes needed — nothing pushed. MERGE RECOMMENDATION: ready to merge.
Author
Owner

Fixed by PR #186 (review clean; images→raw, everything else→blob view, trailing-slash→tree; 379/379), merged. Closing.

Fixed by PR #186 (review clean; images→raw, everything else→blob view, trailing-slash→tree; 379/379), merged. Closing.
crueber added this to the v1 milestone 2026-09-10 22:27:15 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
crueber/walhub#185
No description provided.