fix: 修复下载功能,通过background script直接下载到默认目录

- 下载改由background script处理,使用chrome.downloads.download API
- 添加chrome.runtime.sendMessage类型定义
- 修复SVG图标路径错误
- 使用Data URL方式确保下载可靠性

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
ddshi 2026-01-23 16:55:54 +08:00
parent 6045cbe6ad
commit bf3b4548b0
3 changed files with 21 additions and 24 deletions

View File

@ -1,34 +1,31 @@
// Background Service Worker
// 处理下载等后台任务
import type { ExtractedContent } from '../types';
import { generateMarkdown } from '../utils/markdown';
import { downloadMarkdown, generateFilename } from '../utils/download';
// 监听来自popup的消息
chrome.runtime.onMessage.addListener((message: any, _sender: any, sendResponse: (response?: any) => void) => {
if (message.action === 'download') {
handleDownload(message.data)
handleDownload(message.filename, message.content)
.then(() => sendResponse({ success: true }))
.catch(error => sendResponse({ success: false, error: error?.message || 'Download failed' }));
return true; // 异步响应
}
if (message.action === 'copy') {
sendResponse({ success: false, error: 'Copy should be handled in popup' });
return false;
}
return false;
});
// 处理下载
async function handleDownload(data: { content: ExtractedContent; options: { includeTitle: boolean; includeUrl: boolean } }): Promise<void> {
const { content, options } = data;
const markdown = generateMarkdown(content, options);
const filename = generateFilename(content.title);
// 处理下载 - 直接下载到默认目录
async function handleDownload(filename: string, content: string): Promise<void> {
// 使用 Data URL 方式(更可靠)
const dataUrl = `data:text/markdown;charset=utf-8,${encodeURIComponent(content)}`;
await downloadMarkdown(markdown, filename);
// 使用 chrome.downloads.download 直接下载到默认目录
const downloadId = await chrome.downloads.download({
url: dataUrl,
filename: filename,
saveAs: false // 直接保存到默认下载目录
});
console.log('ReadMD: Download initiated', downloadId, filename);
}
// 下载完成后清理

View File

@ -76,7 +76,7 @@ export function Popup() {
}
};
// 下载文件
// 下载文件 - 通过 background script 直接下载到默认目录
const handleDownload = async () => {
if (!extractedContent) return;
@ -86,16 +86,15 @@ export function Popup() {
includeUrl: settings.includeUrl
});
const blob = new Blob([markdown], { type: 'text/markdown;charset=utf-8' });
const url = URL.createObjectURL(blob);
const filename = `${extractedContent.title.replace(/[<>:"/\\|?*]/g, '_').substring(0, 100)}.md`;
await chrome.downloads.download({
url: url,
// 发送消息给 background script 处理下载
await chrome.runtime.sendMessage({
action: 'download',
filename: filename,
saveAs: false
content: markdown
});
URL.revokeObjectURL(url);
showStatus('success', '开始下载...');
setTimeout(() => {
window.close();
@ -200,7 +199,7 @@ export function Popup() {
>
<svg className="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<circle cx="12" cy="12" r="3"/>
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 2.0 1 83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/>
<path d="M12.36 6v1.2M12.36 16.8v1.2M6.36 12H5.16M18.84 12h-1.2M8.4 8.4l-.85.85M16.45 15.55l-.85.85M8.4 15.6l-.85-.85M16.45 8.45l-.85-.85"/>
</svg>
</button>

View File

@ -8,6 +8,7 @@ declare const chrome: {
onMessage: {
addListener: (callback: (message: any, sender: any, sendResponse: (response?: any) => void) => boolean | void) => void;
};
sendMessage: (message: any) => Promise<any>;
openOptionsPage: () => Promise<void>;
};
downloads: {