diff --git a/packages/gitbook/src/lib/markdownPage.test.ts b/packages/gitbook/src/lib/markdownPage.test.ts index f7eb9d9559..45a6ca6423 100644 --- a/packages/gitbook/src/lib/markdownPage.test.ts +++ b/packages/gitbook/src/lib/markdownPage.test.ts @@ -1,8 +1,11 @@ -import { describe, expect, it } from 'bun:test'; +import { describe, expect, it, mock } from 'bun:test'; + +mock.module('server-only', () => ({})); import type { GitBookAnyContext } from './context'; import { createLinker, linkerWithDirectPagePaths, linkerWithMarkdownPages } from './links'; -import { fromPageMarkdown, toPageMarkdown } from './markdownPage'; + +const { fromPageMarkdown, toPageMarkdown } = await import('./markdownPage'); const page = { id: 'designer', @@ -56,3 +59,57 @@ describe('HTML links in page markdown', () => { ); }); }); + +it('rewrites stable file references inside HTML images', async () => { + const fileId = 'WNXq6RcD2e4WTRcZEz4f'; + + const contextWithFile = { + ...context, + revision: { + pages: [page], + files: [ + { + id: fileId, + name: 'options-menu.svg', + downloadURL: 'https://cdn.example.com/options-menu.svg', + }, + ], + }, + } as unknown as GitBookAnyContext; + + const markdown = `\n`; + + const tree = await fromPageMarkdown(contextWithFile, { + markdown, + pagePath: 'workflows', + }); + + expect(toPageMarkdown(tree)).toContain('src="https://cdn.example.com/options-menu.svg"'); +}); + +it('rewrites stable file references inside HTML image srcsets', async () => { + const fileId = 'WNXq6RcD2e4WTRcZEz4f'; + + const contextWithFile = { + ...context, + revision: { + pages: [page], + files: [ + { + id: fileId, + name: 'options-menu.svg', + downloadURL: 'https://cdn.example.com/options-menu.svg', + }, + ], + }, + } as unknown as GitBookAnyContext; + + const markdown = `\n`; + + const tree = await fromPageMarkdown(contextWithFile, { + markdown, + pagePath: 'workflows', + }); + + expect(toPageMarkdown(tree)).toContain('srcset="https://cdn.example.com/options-menu.svg"'); +}); diff --git a/packages/gitbook/src/lib/markdownPage.ts b/packages/gitbook/src/lib/markdownPage.ts index 75590995e7..b0ac514a2b 100644 --- a/packages/gitbook/src/lib/markdownPage.ts +++ b/packages/gitbook/src/lib/markdownPage.ts @@ -32,6 +32,7 @@ import { getMarkdownForPagesTree } from '@/routes/llms'; const HTML_ANCHOR_RE = /]*?)href="([^"]*)"([^>]*)>([\s\S]*?)<\/a>/g; const HTML_ANCHOR_OPEN_RE = /]*?)href="([^"]*)"([^>]*)>/g; const HTML_SRC_RE = /\bsrc="([^"]*)"/g; +const HTML_SRCSET_RE = /\bsrcset="([^"]*)"/g; /** * Generate a markdown version of a page. @@ -377,6 +378,12 @@ async function rewriteHTMLRefs(context: GitBookAnyContext, node: Html): Promise< const resolved = await resolveRefURL(context, src); return resolved ? `src="${escapeHTML(resolved.url)}"` : full; }); + + node.value = await replaceAsync(node.value, HTML_SRCSET_RE, async (match) => { + const [full, srcset = ''] = match; + const resolved = await resolveRefURL(context, srcset); + return resolved ? `srcset="${escapeHTML(resolved.url)}"` : full; + }); } async function replaceAsync(