ework-web 0.10.120 → 0.10.122
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/fileview.ts +29 -2
package/package.json
CHANGED
package/src/fileview.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { realpathSync, statSync, readFileSync, openSync, readSync, closeSync, readdirSync } from "fs";
|
|
2
|
-
import { isAbsolute, relative, join, dirname } from "path";
|
|
2
|
+
import { isAbsolute, relative, join, dirname, resolve } from "path";
|
|
3
3
|
import hljs from "highlight.js";
|
|
4
4
|
import { THEME_CSS, escapeHtml, escapeAttr } from "./render/layout";
|
|
5
5
|
import { renderMarkdown } from "./render/markdown";
|
|
@@ -472,6 +472,32 @@ function buildDownloadView(cfg: Config, rp: string): { html: string } {
|
|
|
472
472
|
return { html };
|
|
473
473
|
}
|
|
474
474
|
|
|
475
|
+
export // Repo-relative refs (figures/x.png) in /file-rendered markdown 404 against /file
|
|
476
|
+
// (and DOMPurify strips relative src entirely); rewriting at markdown-source level
|
|
477
|
+
// yields rooted /file URLs that survive sanitization and re-pass the gate at request time.
|
|
478
|
+
const MD_REF_RE = /(\]\()([^)\s]+)([)\s])/g;
|
|
479
|
+
const SKIP_REF_RE = /^(?:[a-z][a-z0-9+.-]*:|\/|#)/i;
|
|
480
|
+
|
|
481
|
+
export function rewriteRelativeMdRefs(md: string, dir: string): string {
|
|
482
|
+
let out = "";
|
|
483
|
+
let last = 0;
|
|
484
|
+
for (const m of md.matchAll(/^(```|~~~)[^\n]*\n[\s\S]*?^\1[^\n]*$/gm)) {
|
|
485
|
+
out += rewriteRefs(md.slice(last, m.index!), dir) + m[0];
|
|
486
|
+
last = m.index! + m[0].length;
|
|
487
|
+
}
|
|
488
|
+
return out + rewriteRefs(md.slice(last), dir);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
function rewriteRefs(text: string, dir: string): string {
|
|
492
|
+
return text.replace(MD_REF_RE, (full: string, pre: string, ref: string, post: string) => {
|
|
493
|
+
if (SKIP_REF_RE.test(ref) || ref.startsWith("/file")) return full;
|
|
494
|
+
const abs = resolve(dir, ref);
|
|
495
|
+
const media = /\.(?:png|jpe?g|gif|webp|bmp|svg|mp3|mp4|webm|ogg|wav|pdf)$/i.test(abs);
|
|
496
|
+
const url = `${media ? "/file/raw" : "/file"}?path=${encodeURIComponent(abs)}`;
|
|
497
|
+
return `${pre}${url}${post}`;
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
|
|
475
501
|
export function buildFileView(
|
|
476
502
|
cfg: Config,
|
|
477
503
|
rawPath: string,
|
|
@@ -505,8 +531,9 @@ export function buildFileView(
|
|
|
505
531
|
const lang = extToLang(rawPath);
|
|
506
532
|
const shownBytes = chunk.rows.reduce((s, r) => s + r.t.length + 1, 0);
|
|
507
533
|
const fullText = chunk.rows.map((r) => r.t).join("\n");
|
|
534
|
+
const dir = dirname(rawPath);
|
|
508
535
|
const body = mdRender
|
|
509
|
-
? `<div class="md-render">${renderMarkdown(fullText,
|
|
536
|
+
? `<div class="md-render">${renderMarkdown(rewriteRelativeMdRefs(fullText, dir), dir)}</div>`
|
|
510
537
|
: lang && shownBytes <= 100000
|
|
511
538
|
? renderHighlighted(chunk, lang)
|
|
512
539
|
: `<pre><code>${chunk.rows.map((r) => lineRow(r.t, r.n)).join("")}</code></pre>`;
|