背景
src/lib/export.ts の exportAsHtml は markdownToHtml を通して HTML ファイルを書き出すが、 などのローカル画像パスをそのまま出力するため、エクスポート後の HTML を外部ブラウザで開くと画像が表示されない (相対パス基準が保存先ディレクトリになり、workspace 内の画像に届かない)。
feature/slide-local-image-resolution ブランチで SlidePreview には resolveHtmlImageSrcs を注入済み。exportAsPdf は共通ヘルパー経由で scripta-asset:// に解決するよう対応済み。HTML export は scripta-asset:// に置換しても外部ブラウザで解決できないため意図的に対象外とした。真の portability には data URI 埋め込みが必要。
やること
-
新規 IPC readFileBase64(path): Promise<string> を追加
electron/main/ipc/file.ts に handler、electron/preload/api.ts / electron/preload/index.ts に wiring、src/lib/commands.ts にラッパー
- path-guard 必須:
isPathWithinAnyAllowedRoot(path) で workspace 内チェック (scripta-asset handler と同レベルの防御)
- MIME 判定は拡張子ベース (png / jpg / jpeg / gif / webp / svg / bmp / avif)
-
async 版 resolver を src/lib/resolve-html-images.ts に追加
export async function embedHtmlImagesAsDataUri(
html: string,
activeTabPath: string | null,
): Promise<string>
- 相対 / 絶対パスを
resolveImageSrc 相当のロジックで OS パスに変換
readFileBase64 で読み、data:${mime};base64,${b64} に置換
- http(s) / 既に data:/blob: はそのまま維持
- fetch 失敗時は元の src を残す (broken image のまま but noisy でない)
-
exportAsHtml を async ヘルパー経由に更新 (呼び出し側は既に async)
-
テスト
resolve-html-images.test.ts に async 版のケース追加 (fake IPC で base64 を返す)
export.test.ts に「exportAsHtml が data URI を埋め込む」regression 追加
スコープ外
- SlidePreview / exportAsPdf: 既に scripta-asset:// で解決済み。変更不要
- SVG の inline 化 (
<img src="./foo.svg"> を <svg>...</svg> インライン展開) は別 issue
関連
背景
src/lib/export.tsのexportAsHtmlはmarkdownToHtmlを通して HTML ファイルを書き出すが、などのローカル画像パスをそのまま出力するため、エクスポート後の HTML を外部ブラウザで開くと画像が表示されない (相対パス基準が保存先ディレクトリになり、workspace 内の画像に届かない)。feature/slide-local-image-resolutionブランチで SlidePreview にはresolveHtmlImageSrcsを注入済み。exportAsPdfは共通ヘルパー経由でscripta-asset://に解決するよう対応済み。HTML export はscripta-asset://に置換しても外部ブラウザで解決できないため意図的に対象外とした。真の portability には data URI 埋め込みが必要。やること
新規 IPC
readFileBase64(path): Promise<string>を追加electron/main/ipc/file.tsに handler、electron/preload/api.ts/electron/preload/index.tsに wiring、src/lib/commands.tsにラッパーisPathWithinAnyAllowedRoot(path)で workspace 内チェック (scripta-asset handler と同レベルの防御)async 版 resolver を
src/lib/resolve-html-images.tsに追加resolveImageSrc相当のロジックで OS パスに変換readFileBase64で読み、data:${mime};base64,${b64}に置換exportAsHtmlを async ヘルパー経由に更新 (呼び出し側は既に async)テスト
resolve-html-images.test.tsに async 版のケース追加 (fake IPC で base64 を返す)export.test.tsに「exportAsHtml が data URI を埋め込む」regression 追加スコープ外
<img src="./foo.svg">を<svg>...</svg>インライン展開) は別 issue関連