Skip to content

fix: browser API chrome.downloads.download 代码及Mock修正#1410

Draft
cyfung1031 wants to merge 4 commits intomainfrom
fix/download-api-custom-naming
Draft

fix: browser API chrome.downloads.download 代码及Mock修正#1410
cyfung1031 wants to merge 4 commits intomainfrom
fix/download-api-custom-naming

Conversation

@cyfung1031
Copy link
Copy Markdown
Collaborator

@cyfung1031 cyfung1031 commented May 6, 2026

Checklist / 检查清单

  • Fixes mentioned issues / 修复已提及的问题
  • Code reviewed by human / 代码通过人工检查
  • Changes tested / 已完成测试

Description / 描述

Close #1409

  1. 解决 扩充冲突问题,必须引入 chrome.downloads.onDeterminingFilename 。这是官方已知的 Chromium Bug。 https://issues.chromium.org/issues/40706258 。实作起来可以解决问题,所以就先这样吧。
  2. 配合 chrome.downloads.onDeterminingFilename,重新包装了 chrome.downloads.download 相关的操作。
  3. 重写了 chrome.downloads 的 mock
  4. 新增了一连串的 单元测试

Screenshots / 截图


Filename for chrome.downloads.download is ignored if onDeterminingFilename listener exists
https://issues.chromium.org/issues/40734759

@cyfung1031 cyfung1031 added the P1 🔥 重要但是不紧急的内容 label May 6, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

该 PR 旨在修复 chrome.downloads.download 在存在 onDeterminingFilename 监听器时可能忽略 filename 的 Chromium 已知问题(Close #1409),通过在 service worker 侧引入统一的下载封装来稳定处理文件名覆盖,并同步完善 chrome.downloads 的 mock 与单元测试,确保行为可回归验证。

Changes:

  • 新增 startDownload 下载封装:集中处理 onDeterminingFilename + onChanged,并为调用方提供完成/中断回调。
  • 将 service worker 中相关下载调用(如备份导出、GM_download)改为使用新封装,以规避文件名覆盖失效问题。
  • 重写 chrome.downloads mock,补齐 Promise/callback 形态与事件模拟,并新增对应单测覆盖。

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/app/service/service_worker/synchronize.ts 备份导出下载改为走 startDownload 封装
src/app/service/service_worker/gm_api/gm_api.ts GM_download 下载流程改为使用 startDownload + 回调通知
src/app/service/service_worker/download.ts 新增下载封装:注册/卸载监听、文件名覆盖与完成/中断回调
src/app/service/service_worker/download.test.ts 为下载封装与 mock 下载行为新增单测覆盖
src/app/service/content/gm_api/gm_api.ts 优化 native->browser 下载链路的 Object URL 释放时机(覆盖更多回包分支)
packages/chrome-extension-mock/index.ts chromeMock.init 时重置 downloads mock 状态
packages/chrome-extension-mock/downloads.ts 重写 downloads mock:支持 Promise/callback、事件与文件名决策流程

Comment thread src/app/service/service_worker/download.ts
Comment thread src/app/service/service_worker/download.ts
Comment on lines +200 to +203
mDownloadId = undefined;
console.error("chrome.runtime.lastError in chrome.downloads.download", chrome.runtime.lastError);
}
if (mDownloadId == undefined) detachDownloadCallback();
Comment on lines 1046 to +1072
@@ -1060,30 +1061,44 @@ export default class GMApi extends GM_Base {
} as GMTypes.DownloadDetails<string>,
]);
if (aborted) return;
let released = false;
const releaseResources = () => {
if (released) return;
released = true;
setTimeout(() => {
// 释放不需要的 URL
URL.revokeObjectURL(url);
}, 1);
};
Comment on lines +53 to +58
download(options: chrome.downloads.DownloadOptions, callback?: Callback<number>) {
this.clearLastError();
if (!options?.url) {
const error = new Error("The download url is required.");
if (callback) {
this.withLastError(error.message, () => callback(undefined as unknown as number));
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mock 的 typescript 问题不处理

Comment on lines +118 to +141
let filenameConfirmed = false;

if (!responseMap.has(id)) {
// onDeterminingFilename did not triggered. Fallback to chrome.downloads.search
const downloadItem = (await chrome.downloads.search({ id: id }))?.[0];
if (downloadItem && downloadItem.id === id) {
responseMap.set(id, {
downloadItem: {
bytesReceived: downloadItem.bytesReceived,
fileSize: downloadItem.fileSize,
totalBytes: downloadItem.totalBytes,
},
});
}
} else {
// onDeterminingFilename was triggered
filenameConfirmed = true;
}

const downloadItem = responseMap.get(id);

await notifyDownloadCallback(entry.callback, {
donwloadId: id,
state: state === "interrupted" && filenameConfirmed ? "save_cancelled" : state,
@cyfung1031 cyfung1031 marked this pull request as draft May 10, 2026 05:55
@cyfung1031
Copy link
Copy Markdown
Collaborator Author

cyfung1031 commented May 10, 2026

先研究一下 Copilot 的说法

DRAFT PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P1 🔥 重要但是不紧急的内容

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] 推特下载文件的脚本,无法正确使用重命名功能,会显示代码串

3 participants