13 Commits
Author SHA1 Message Date
GitHub Action 00ee7e6592 chore: 更新版本到 2.0.5 [skip ci] 2025-11-09 07:57:51 +00:00
xixu-me 1fb387a32d Add Firefox compatibility layer and improve API detection
Introduces firefox-compat.js to handle Firefox-specific messaging and storage, and updates background.js and popup.js to robustly detect and use the appropriate extension APIs for both Chrome and Firefox environments. Manifest and popup files are updated to load the new compatibility script, ensuring reliable settings management and messaging across browsers.
2025-11-09 15:56:34 +08:00
xixu-me 38e8d54129 Merge pull request #18 from xixu-me/dependabot/github_actions/github-actions-dc500464ed
actions(deps): bump actions/upload-artifact from 4 to 5 in the github-actions group
2025-10-27 21:00:51 +08:00
dependabot[bot] 4f6eff4173 actions(deps): bump actions/upload-artifact in the github-actions group
Bumps the github-actions group with 1 update: [actions/upload-artifact](https://github.com/actions/upload-artifact).


Updates `actions/upload-artifact` from 4 to 5
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 09:58:46 +00:00
xixu-me bec2770f2e Merge pull request #16 from xixu-me/dependabot/github_actions/github-actions-5e51f74d5c
actions(deps): bump actions/setup-node from 5 to 6 in the github-actions group
2025-10-21 20:01:43 +08:00
dependabot[bot] ca45a98bab actions(deps): bump actions/setup-node in the github-actions group
Bumps the github-actions group with 1 update: [actions/setup-node](https://github.com/actions/setup-node).


Updates `actions/setup-node` from 5 to 6
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-20 10:25:31 +00:00
xixu-me bf3ef0427c Rename 'Microsoft Edge' to 'Edge' in docs and workflows
Updated all references from 'Microsoft Edge' to 'Edge' across issue templates, pull request templates, workflow files, privacy policy, and README for consistency and brevity.
2025-10-01 16:07:19 +08:00
xixu-me c68c2e0efa Merge pull request #14 from xixu-me/dependabot/github_actions/github-actions-9c09232849
actions(deps): bump the github-actions group with 2 updates
2025-09-08 19:06:16 +08:00
dependabot[bot] bdd7327292 actions(deps): bump the github-actions group with 2 updates
Bumps the github-actions group with 2 updates: [actions/setup-python](https://github.com/actions/setup-python) and [actions/setup-node](https://github.com/actions/setup-node).


Updates `actions/setup-python` from 5 to 6
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5...v6)

Updates `actions/setup-node` from 4 to 5
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/setup-node
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 10:07:20 +00:00
xixu-me 1682b76967 Update funding configuration in FUNDING.yml
Added custom sponsorship URL and Buy Me a Coffee username.
2025-08-24 17:42:10 +08:00
GitHub Action b2a96c9027 chore: 更新版本到 2.0.4 [skip ci] 2025-08-24 09:17:33 +00:00
xixu-me a6d62103c1 Move and restyle 'URL 转换器' link in header
The 'URL 转换器' link was moved from the bottom of the popup to the header section and given new styles for improved visibility and consistency with other header elements.
2025-08-24 17:16:36 +08:00
xixu-me 440b27b1b7 Add Chrome Web Store mirror link to README
A mirror link for the Chrome Web Store has been added to the 商店可用性 section to provide an alternative download source.
2025-08-19 19:19:18 +08:00
14 changed files with 387 additions and 101 deletions

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
custom: https://xi-xu.me/#sponsorships
buy_me_a_coffee: xixu
+1 -1
View File
@@ -24,7 +24,7 @@ body:
description: Which browser are you using? description: Which browser are you using?
options: options:
- Chrome - Chrome
- Microsoft Edge - Edge
- Brave - Brave
- Other Chromium-based browser - Other Chromium-based browser
validations: validations:
+1 -1
View File
@@ -40,7 +40,7 @@
## 浏览器测试 ## 浏览器测试
<!-- 检查你测试过的浏览器 --> <!-- 检查你测试过的浏览器 -->
- [ ] Chrome - [ ] Chrome
- [ ] Microsoft Edge - [ ] Edge
- [ ] Brave - [ ] Brave
- [ ] 其他:____________ - [ ] 其他:____________
+8 -8
View File
@@ -25,13 +25,13 @@ jobs:
# 第二步:设置 Python 环境用于构建脚本 # 第二步:设置 Python 环境用于构建脚本
- name: 设置 Python - name: 设置 Python
uses: actions/setup-python@v5 uses: actions/setup-python@v6
with: with:
python-version: "3.11" python-version: "3.11"
# 第三步:设置 Node.js 环境用于 JSON 验证 # 第三步:设置 Node.js 环境用于 JSON 验证
- name: 设置 Node.js - name: 设置 Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v6
with: with:
node-version: "18" node-version: "18"
@@ -145,7 +145,7 @@ jobs:
refresh-token: ${{ secrets.CHROME_REFRESH_TOKEN }} refresh-token: ${{ secrets.CHROME_REFRESH_TOKEN }}
publish: true publish: true
- name: 发布到 Microsoft Edge 加载项 - name: 发布到 Edge 加载项
continue-on-error: true continue-on-error: true
id: edge-publish id: edge-publish
uses: wdzeng/edge-addon@v2 uses: wdzeng/edge-addon@v2
@@ -184,7 +184,7 @@ jobs:
### Chromium ### Chromium
- **文件**: `Xget-Now_${{ steps.version.outputs.version }}.chromium.zip` - **文件**: `Xget-Now_${{ steps.version.outputs.version }}.chromium.zip`
- **支持**: Chrome、Microsoft Edge 等基于 Chromium 的浏览器 - **支持**: Chrome、Edge 等基于 Chromium 的浏览器
- **Manifest**: v3 - **Manifest**: v3
### Firefox ### Firefox
@@ -219,11 +219,11 @@ jobs:
fi fi
if [ "${{ steps.edge-publish.outcome }}" = "success" ]; then if [ "${{ steps.edge-publish.outcome }}" = "success" ]; then
echo "✅ Microsoft Edge 加载项: 发布成功" echo "✅ Edge 加载项: 发布成功"
elif [ "${{ steps.edge-publish.outcome }}" = "failure" ]; then elif [ "${{ steps.edge-publish.outcome }}" = "failure" ]; then
echo "❌ Microsoft Edge 加载项: 发布失败" echo "❌ Edge 加载项: 发布失败"
else else
echo "⚠️ Microsoft Edge 加载项: 已跳过(缺少密钥或其他原因)" echo "⚠️ Edge 加载项: 已跳过(缺少密钥或其他原因)"
fi fi
if [ "${{ steps.firefox-publish.outcome }}" = "success" ]; then if [ "${{ steps.firefox-publish.outcome }}" = "success" ]; then
@@ -244,7 +244,7 @@ jobs:
echo "🎉 成功发布 Xget Now ${{ steps.version.outputs.version }}!" echo "🎉 成功发布 Xget Now ${{ steps.version.outputs.version }}!"
echo "================================" echo "================================"
echo "🔗 Chrome 应用商店: https://chrome.google.com/webstore/detail/${{ secrets.CHROME_EXTENSION_ID }}" echo "🔗 Chrome 应用商店: https://chrome.google.com/webstore/detail/${{ secrets.CHROME_EXTENSION_ID }}"
echo "🔗 Microsoft Edge 加载项: 查看发布页面获取最新信息" echo "🔗 Edge 加载项: 查看发布页面获取最新信息"
echo "🦊 Firefox 附加组件: 查看 Mozilla Add-ons 获取最新信息" echo "🦊 Firefox 附加组件: 查看 Mozilla Add-ons 获取最新信息"
echo "📦 GitHub 发布: https://github.com/${{ github.repository }}/releases/tag/v${{ steps.version.outputs.version }}" echo "📦 GitHub 发布: https://github.com/${{ github.repository }}/releases/tag/v${{ steps.version.outputs.version }}"
echo "📖 安装指南: https://github.com/${{ github.repository }}#installation" echo "📖 安装指南: https://github.com/${{ github.repository }}#installation"
+3 -3
View File
@@ -18,12 +18,12 @@ jobs:
uses: actions/checkout@v5 uses: actions/checkout@v5
- name: 设置 Python - name: 设置 Python
uses: actions/setup-python@v5 uses: actions/setup-python@v6
with: with:
python-version: "3.11" python-version: "3.11"
- name: 设置 Node.js - name: 设置 Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v6
with: with:
node-version: "18" node-version: "18"
@@ -173,7 +173,7 @@ jobs:
" "
- name: 上传构建结果 - name: 上传构建结果
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v5
with: with:
name: extension-builds-${{ github.sha }} name: extension-builds-${{ github.sha }}
path: | path: |
+1 -1
View File
@@ -46,7 +46,7 @@ Xget Now 扩展遵循“隐私优先”的设计原则,所有处理都在您
### 数据同步 ### 数据同步
如果您已登录 Chrome/Microsoft Edge 并启用了扩展同步,您的扩展设置可能会在您的设备之间同步。这是由 Google/Microsoft 的 Chrome/Microsoft Edge 同步服务处理的,不涉及我们的服务器。 如果您已登录 Chrome/Edge 并启用了扩展同步,您的扩展设置可能会在您的设备之间同步。这是由 Google/Microsoft 的 Chrome/Edge 同步服务处理的,不涉及我们的服务器。
## 数据处理 ## 数据处理
+8 -7
View File
@@ -16,8 +16,9 @@
### 商店可用性 ### 商店可用性
- [Chrome 应用商店](https://chromewebstore.google.com/detail/ajiejgobfcifcikbahpijopolfjoodgf?hl=zh-CN) - [Chrome 应用商店](https://chromewebstore.google.com/detail/ajiejgobfcifcikbahpijopolfjoodgf?hl=zh-CN)
- [Chrome 应用商店镜像](https://chromewebstore.xi-xu.me/detail/ajiejgobfcifcikbahpijopolfjoodgf)
- [Firefox 附加组件](https://addons.mozilla.org/zh-CN/firefox/addon/xget-now/) - [Firefox 附加组件](https://addons.mozilla.org/zh-CN/firefox/addon/xget-now/)
- [Microsoft Edge 加载项](https://microsoftedge.microsoft.com/addons/detail/jigpfhbegabdenhihpplcjhpfdcgnalc?hl=zh-CN&gl=CN) - [Edge 加载项](https://microsoftedge.microsoft.com/addons/detail/jigpfhbegabdenhihpplcjhpfdcgnalc?hl=zh-CN&gl=CN)
### 手动安装 ### 手动安装
@@ -28,7 +29,7 @@
1. **下载扩展** 1. **下载扩展**
- 前往 [Releases 页面](https://github.com/xixu-me/Xget-Now/releases/latest) - 前往 [Releases 页面](https://github.com/xixu-me/Xget-Now/releases/latest)
- 下载对应浏览器的扩展文件: - 下载对应浏览器的扩展文件:
- `Xget-Now_x.x.x.chromium.zip` - 适用于所有基于 Chromium 的浏览器(Chrome、Microsoft Edge、Opera 等) - `Xget-Now_x.x.x.chromium.zip` - 适用于所有基于 Chromium 的浏览器(Chrome、Edge、Opera 等)
- `Xget-Now_x.x.x.firefox.zip` - 适用于 Firefox 浏览器 - `Xget-Now_x.x.x.firefox.zip` - 适用于 Firefox 浏览器
2. **在 Chrome 中安装** 2. **在 Chrome 中安装**
@@ -43,15 +44,15 @@
- 点击「临时载入附加组件」 - 点击「临时载入附加组件」
- 选择下载的 Firefox 版本 ZIP 文件或解压后的 `manifest.json` 文件 - 选择下载的 Firefox 版本 ZIP 文件或解压后的 `manifest.json` 文件
4. **在 Microsoft Edge 中安装** 4. **在 Edge 中安装**
- 解压下载的 Chromium 版本 ZIP 文件 - 解压下载的 Chromium 版本 ZIP 文件
- 打开 Microsoft Edge 并前往 `edge://extensions/` - 打开 Edge 并前往 `edge://extensions/`
- 启用「开发人员模式」(左侧边栏的切换开关) - 启用「开发人员模式」(左侧边栏的切换开关)
- 点击「加载解压缩的扩展」并选择解压的文件夹 - 点击「加载解压缩的扩展」并选择解压的文件夹
5. **在其他基于 Chromium 的浏览器中安装** 5. **在其他基于 Chromium 的浏览器中安装**
- 使用 Chromium 版本的扩展包 - 使用 Chromium 版本的扩展包
- 遵循与 Chrome 或 Microsoft Edge 类似的步骤,确保首先启用「开发者模式」 - 遵循与 Chrome 或 Edge 类似的步骤,确保首先启用「开发者模式」
- 按照相应浏览器的扩展安装指南进行操作 - 按照相应浏览器的扩展安装指南进行操作
#### 选项 2:从源码安装 #### 选项 2:从源码安装
@@ -146,7 +147,7 @@
**Chromium 浏览器:** **Chromium 浏览器:**
- **Chrome**:版本 88+(Manifest V3 支持) - **Chrome**:版本 88+(Manifest V3 支持)
- **Microsoft Edge**:版本 88+ - **Edge**:版本 88+
- **Opera**:版本 74+ - **Opera**:版本 74+
- **其他基于 Chromium 的浏览器**:支持 Manifest V3 的版本 - **其他基于 Chromium 的浏览器**:支持 Manifest V3 的版本
@@ -290,6 +291,6 @@ Xget 是基于 Cloudflare Workers 构建的高性能、安全的代理服务,
- 📝 留下评价: - 📝 留下评价:
- [Chrome 应用商店](https://chromewebstore.google.com/detail/ajiejgobfcifcikbahpijopolfjoodgf?hl=zh-CN) - [Chrome 应用商店](https://chromewebstore.google.com/detail/ajiejgobfcifcikbahpijopolfjoodgf?hl=zh-CN)
- [Firefox 附加组件](https://addons.mozilla.org/zh-CN/firefox/addon/xget-now/) - [Firefox 附加组件](https://addons.mozilla.org/zh-CN/firefox/addon/xget-now/)
- [Microsoft Edge 加载项](https://microsoftedge.microsoft.com/addons/detail/jigpfhbegabdenhihpplcjhpfdcgnalc?hl=zh-CN&gl=CN) - [Edge 加载项](https://microsoftedge.microsoft.com/addons/detail/jigpfhbegabdenhihpplcjhpfdcgnalc?hl=zh-CN&gl=CN)
- 🐛 通过 [GitHub Issues](https://github.com/xixu-me/Xget-Now/issues) 报告错误或建议功能 - 🐛 通过 [GitHub Issues](https://github.com/xixu-me/Xget-Now/issues) 报告错误或建议功能
- 📢 与其他可能受益于更快下载的人分享 - 📢 与其他可能受益于更快下载的人分享
+121 -36
View File
@@ -8,15 +8,37 @@
* - 管理扩展状态和配置 * - 管理扩展状态和配置
*/ */
// 导入兼容层 // 对于Firefox Manifest V2,webext-compat.js 通过manifest加载
importScripts("webext-compat.js"); // 对于Chrome Manifest V3,通过importScripts加载
if (typeof importScripts !== "undefined") {
try {
importScripts("webext-compat.js");
} catch (e) {
console.log("Running in Firefox/Manifest V2 environment");
}
}
// 确保兼容层可用 // 确保兼容层可用
if (typeof webext === "undefined") { if (typeof webext === "undefined") {
// 在非模块环境中,兼容层应该已经通过脚本标签加载
console.error("WebExt compatibility layer not found"); console.error("WebExt compatibility layer not found");
// 尝试使用全局的browser或chrome API
if (typeof browser !== "undefined") {
console.log("Using Firefox browser API directly");
self.webext = browser;
self.webextFlavor = { soup: new Set(["firefox"]) };
} else if (typeof chrome !== "undefined") {
console.log("Using Chrome API directly");
self.webext = chrome;
self.webextFlavor = { soup: new Set(["chromium"]) };
}
} }
// 确认API可用性
console.log("Background script initializing...");
console.log("WebExt API available:", typeof webext !== "undefined");
console.log("Storage API available:", webext && webext.storage ? "yes" : "no");
console.log("Runtime API available:", webext && webext.runtime ? "yes" : "no");
/** /**
* 平台配置定义 * 平台配置定义
* 支持的下载加速平台列表 * 支持的下载加速平台列表
@@ -226,12 +248,26 @@ const DEFAULT_SETTINGS = {
webext.runtime.onInstalled.addListener(async () => { webext.runtime.onInstalled.addListener(async () => {
console.log("Xget Now 已安装"); console.log("Xget Now 已安装");
// 使用本地存储而不是同步存储以确保兼容性 // 对于Firefox,优先使用local存储,因为sync可能不可用或有限制
const storageAPI = webext.storage.sync || webext.storage.local; const isFirefox =
webextFlavor && webextFlavor.soup && webextFlavor.soup.has("firefox");
const storageAPI = isFirefox
? webext.storage.local
: webext.storage.sync || webext.storage.local;
// 如果尚未设置,则设置默认设置 try {
const settings = await storageAPI.get(DEFAULT_SETTINGS); // 如果尚未设置,则设置默认设置
await storageAPI.set(settings); const settings = await storageAPI.get(DEFAULT_SETTINGS);
await storageAPI.set(settings);
} catch (error) {
console.error("初始化设置时出错:", error);
// 尝试使用local storage作为后备
try {
await webext.storage.local.set(DEFAULT_SETTINGS);
} catch (localError) {
console.error("使用本地存储初始化设置时出错:", localError);
}
}
}); });
// 防止监听器被多次注册 // 防止监听器被多次注册
@@ -253,7 +289,12 @@ function handleDownload(downloadItem, suggest) {
async function processDownloadRedirect(downloadItem) { async function processDownloadRedirect(downloadItem) {
try { try {
const storageAPI = webext.storage.sync || webext.storage.local; // 对于Firefox,优先使用local存储
const isFirefox =
webextFlavor && webextFlavor.soup && webextFlavor.soup.has("firefox");
const storageAPI = isFirefox
? webext.storage.local
: webext.storage.sync || webext.storage.local;
const settings = await storageAPI.get(DEFAULT_SETTINGS); const settings = await storageAPI.get(DEFAULT_SETTINGS);
// 检查扩展是否已启用并配置了域名 // 检查扩展是否已启用并配置了域名
@@ -324,37 +365,81 @@ function transformUrlLegacy(url, settings) {
} }
// 监听来自弹出窗口/选项的消息 // 监听来自弹出窗口/选项的消息
webext.runtime.onMessage.addListener((request, sender, sendResponse) => { const messageListener = (request, sender, sendResponse) => {
const storageAPI = webext.storage.sync || webext.storage.local; console.log("Received message:", request.action);
// 对于Firefox,优先使用local存储,因为sync可能不可用或有限制
const isFirefox =
webextFlavor && webextFlavor.soup && webextFlavor.soup.has("firefox");
const storageAPI = isFirefox
? webext.storage.local
: webext.storage.sync || webext.storage.local;
if (request.action === "getSettings") { if (request.action === "getSettings") {
storageAPI.get(DEFAULT_SETTINGS).then(sendResponse); // 使用Promise处理异步操作
return true; (async () => {
} else if (request.action === "saveSettings") {
storageAPI.set(request.settings).then(async () => {
// 通知相关标签页刷新
try { try {
const tabs = await webext.tabs.query({ const settings = await storageAPI.get(DEFAULT_SETTINGS);
url: Object.values(PLATFORMS).map((platform) => platform.base + "/*"), console.log("Settings retrieved:", settings);
}); sendResponse(settings || DEFAULT_SETTINGS);
for (const tab of tabs) {
try {
await webext.tabs.sendMessage(tab.id, {
action: "showNotification",
message: "设置已更新!点击刷新页面",
showRefreshButton: true,
});
} catch (error) {
// 标签页可能没有加载内容脚本,忽略
}
}
} catch (error) { } catch (error) {
console.log("无法通知标签页设置更新"); console.error("获取设置时出错:", error);
sendResponse(DEFAULT_SETTINGS);
} }
})();
return true; // 保持消息通道开放
} else if (request.action === "saveSettings") {
// 确保设置对象有效
const settingsToSave = {
...DEFAULT_SETTINGS,
...request.settings,
};
sendResponse({ success: true }); (async () => {
}); try {
return true; await storageAPI.set(settingsToSave);
console.log("Settings saved successfully");
// 通知相关标签页刷新
try {
const tabs = await webext.tabs.query({
url: Object.values(PLATFORMS).map(
(platform) => platform.base + "/*"
),
});
for (const tab of tabs) {
try {
await webext.tabs.sendMessage(tab.id, {
action: "showNotification",
message: "设置已更新!点击刷新页面",
showRefreshButton: true,
});
} catch (error) {
// 标签页可能没有加载内容脚本,忽略
}
}
} catch (error) {
console.log("无法通知标签页设置更新");
}
sendResponse({ success: true });
} catch (error) {
console.error("保存设置时出错:", error);
sendResponse({ success: false, error: error.message });
}
})();
return true; // 保持消息通道开放
} }
});
// 未知消息
return false;
};
// 添加消息监听器
if (webext && webext.runtime && webext.runtime.onMessage) {
webext.runtime.onMessage.addListener(messageListener);
console.log("Message listener registered");
} else {
console.error("Cannot register message listener - runtime API not available");
}
+86
View File
@@ -0,0 +1,86 @@
/**
* Firefox 特定兼容性修复
* 直接使用 browser API 处理 Firefox 中的消息传递问题
*/
// 在 Firefox 中,直接使用 browser API
if (
typeof browser !== "undefined" &&
browser.runtime &&
browser.runtime.sendMessage
) {
console.log("Firefox environment detected, using native browser API");
// 为popup.js提供一个简化的API
window.firefoxAPI = {
sendMessage: function (message) {
return new Promise((resolve, reject) => {
try {
browser.runtime.sendMessage(message, (response) => {
if (browser.runtime.lastError) {
console.error(
"Firefox sendMessage error:",
browser.runtime.lastError
);
reject(browser.runtime.lastError);
} else {
resolve(response);
}
});
} catch (error) {
console.error("Firefox sendMessage exception:", error);
reject(error);
}
});
},
getSettings: async function () {
try {
return await browser.storage.local.get({
enabled: true,
xgetDomain: "xget.xi-xu.me",
enabledPlatforms: {
gh: true,
gl: true,
gitea: true,
codeberg: true,
sf: true,
aosp: true,
hf: true,
npm: true,
pypi: true,
"pypi-files": true,
conda: true,
"conda-community": true,
maven: true,
apache: true,
gradle: true,
rubygems: true,
cran: true,
cpan: true,
ctan: true,
golang: true,
nuget: true,
crates: true,
packagist: true,
arxiv: true,
fdroid: true,
},
});
} catch (error) {
console.error("Failed to get settings from storage:", error);
throw error;
}
},
saveSettings: async function (settings) {
try {
await browser.storage.local.set(settings);
return { success: true };
} catch (error) {
console.error("Failed to save settings to storage:", error);
return { success: false, error: error.message };
}
},
};
}
+23 -23
View File
@@ -1,8 +1,11 @@
{ {
"manifest_version": 2, "background": {
"name": "Xget Now", "persistent": true,
"version": "2.0.3", "scripts": [
"description": "为 Firefox 浏览器提供的 Xget 下载加速扩展,支持 GitHub、GitLab、npm、PyPI 等众多平台的文件下载加速", "webext-compat.js",
"background.js"
]
},
"browser_action": { "browser_action": {
"default_icon": { "default_icon": {
"16": "icons/icon16.png", "16": "icons/icon16.png",
@@ -13,12 +16,11 @@
"default_popup": "popup.html", "default_popup": "popup.html",
"default_title": "Xget Now" "default_title": "Xget Now"
}, },
"background": { "browser_specific_settings": {
"scripts": [ "gecko": {
"webext-compat.js", "id": "i@xi-xu.me",
"background.js" "strict_min_version": "109.0"
], }
"persistent": false
}, },
"content_scripts": [ "content_scripts": [
{ {
@@ -56,6 +58,15 @@
"run_at": "document_end" "run_at": "document_end"
} }
], ],
"description": "为 Firefox 浏览器提供的 Xget 下载加速扩展,支持 GitHub、GitLab、npm、PyPI 等众多平台的文件下载加速",
"icons": {
"16": "icons/icon16.png",
"32": "icons/icon32.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"manifest_version": 2,
"name": "Xget Now",
"permissions": [ "permissions": [
"downloads", "downloads",
"storage", "storage",
@@ -86,19 +97,8 @@
"https://arxiv.org/*", "https://arxiv.org/*",
"https://f-droid.org/*" "https://f-droid.org/*"
], ],
"icons": { "version": "2.0.5",
"16": "icons/icon16.png",
"32": "icons/icon32.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"web_accessible_resources": [ "web_accessible_resources": [
"icons/*" "icons/*"
], ]
"browser_specific_settings": {
"gecko": {
"id": "i@xi-xu.me",
"strict_min_version": "109.0"
}
}
} }
+1 -1
View File
@@ -89,7 +89,7 @@
"storage", "storage",
"activeTab" "activeTab"
], ],
"version": "2.0.3", "version": "2.0.5",
"web_accessible_resources": [ "web_accessible_resources": [
{ {
"matches": [ "matches": [
+1 -1
View File
@@ -59,5 +59,5 @@
"build": "echo 'No build process needed for Chrome extension'", "build": "echo 'No build process needed for Chrome extension'",
"test": "echo 'No tests specified'" "test": "echo 'No tests specified'"
}, },
"version": "2.0.3" "version": "2.0.5"
} }
+42 -4
View File
@@ -55,6 +55,38 @@
background: rgba(255, 255, 255, 0.05); background: rgba(255, 255, 255, 0.05);
} }
.header .link-item {
display: inline-flex;
align-items: center;
justify-content: center;
margin-bottom: 10px;
padding: 6px 12px;
font-size: 12px;
opacity: 0.8;
transition: opacity 0.2s ease;
border-radius: 6px;
background: var(--container-bg);
border: 1px solid var(--container-border);
text-decoration: none;
color: var(--text-color);
}
.header .link-item:hover {
opacity: 1;
background: var(--hover-bg);
border-color: rgba(255, 255, 255, 0.3);
transform: translateY(-1px);
}
.header .link-item .link-icon {
margin-right: 6px;
font-size: 14px;
}
.header .link-item .link-text {
font-size: 12px;
}
.header h1 { .header h1 {
margin: 0; margin: 0;
font-size: 20px; font-size: 20px;
@@ -371,6 +403,15 @@
</head> </head>
<body> <body>
<div class="header"> <div class="header">
<a
href="https://xuc.xi-xu.me/"
target="_blank"
class="link-item"
style="margin-bottom: 10px; display: inline-block"
>
<span class="link-icon">🔗</span>
<span class="link-text">URL 转换器</span>
</a>
<h1>Xget Now</h1> <h1>Xget Now</h1>
</div> </div>
@@ -570,10 +611,6 @@
<span class="link-icon">📖</span> <span class="link-icon">📖</span>
<span class="link-text">扩展存储库</span> <span class="link-text">扩展存储库</span>
</a> </a>
<a href="https://xuc.xi-xu.me/" target="_blank" class="link-item">
<span class="link-icon">🔗</span>
<span class="link-text">URL 转换器</span>
</a>
</div> </div>
</div> </div>
@@ -581,6 +618,7 @@
</div> </div>
<script src="webext-compat.js"></script> <script src="webext-compat.js"></script>
<script src="firefox-compat.js"></script>
<script src="popup.js"></script> <script src="popup.js"></script>
</body> </body>
</html> </html>
+89 -15
View File
@@ -9,17 +9,30 @@
*/ */
document.addEventListener("DOMContentLoaded", async () => { document.addEventListener("DOMContentLoaded", async () => {
// 确保兼容层可用 // 确保有可用的API
if (typeof webext === "undefined") { if (
console.error("WebExt compatibility layer not found in popup"); typeof webext === "undefined" &&
typeof browser === "undefined" &&
!window.firefoxAPI
) {
console.error("No compatible extension API found");
showStatus("扩展API加载失败", "error");
return; return;
} }
// 加载当前设置 // 延迟执行以确保background脚本已准备就绪
await loadSettings(); setTimeout(async () => {
try {
// 加载当前设置
await loadSettings();
// 设置事件监听器 // 设置事件监听器
setupEventListeners(); setupEventListeners();
} catch (error) {
console.error("Initialization error:", error);
showStatus("初始化失败,请重新打开扩展", "error");
}
}, 100);
}); });
/** /**
@@ -27,9 +40,41 @@ document.addEventListener("DOMContentLoaded", async () => {
*/ */
async function loadSettings() { async function loadSettings() {
try { try {
const settings = await webext.runtime.sendMessage({ console.log("Loading settings...");
action: "getSettings",
}); let settings;
// Firefox 特殊处理
if (window.firefoxAPI && typeof browser !== "undefined") {
console.log("Using Firefox direct storage API");
try {
// 首先尝试消息传递
settings = await window.firefoxAPI.sendMessage({
action: "getSettings",
});
} catch (msgError) {
console.log(
"Message passing failed, using direct storage access:",
msgError
);
// 如果消息传递失败,直接从存储读取
settings = await window.firefoxAPI.getSettings();
}
} else if (webext && webext.runtime && webext.runtime.sendMessage) {
// 标准 webext API
console.log("Using standard webext API");
settings = await webext.runtime.sendMessage({
action: "getSettings",
});
} else {
throw new Error("No compatible API available");
}
console.log("Settings received:", settings);
if (!settings) {
throw new Error("No response from background script");
}
// 使用当前设置更新 UI // 使用当前设置更新 UI
const domainValue = settings.xgetDomain || ""; const domainValue = settings.xgetDomain || "";
@@ -301,12 +346,34 @@ async function saveSettings() {
settings.xgetDomain = cleanupDomain(settings.xgetDomain); settings.xgetDomain = cleanupDomain(settings.xgetDomain);
} }
const response = await webext.runtime.sendMessage({ let response;
action: "saveSettings",
settings: settings,
});
if (response.success) { // Firefox 特殊处理
if (window.firefoxAPI && typeof browser !== "undefined") {
console.log("Saving settings using Firefox API");
try {
// 首先尝试消息传递
response = await window.firefoxAPI.sendMessage({
action: "saveSettings",
settings: settings,
});
} catch (msgError) {
console.log("Message passing failed, using direct storage:", msgError);
// 如果消息传递失败,直接写入存储
response = await window.firefoxAPI.saveSettings(settings);
}
} else if (webext && webext.runtime && webext.runtime.sendMessage) {
// 标准 webext API
console.log("Saving settings using standard webext API");
response = await webext.runtime.sendMessage({
action: "saveSettings",
settings: settings,
});
} else {
throw new Error("No compatible API available for saving settings");
}
if (response && response.success) {
// 显示适当的状态 // 显示适当的状态
if (!settings.xgetDomain && settings.enabled) { if (!settings.xgetDomain && settings.enabled) {
showStatus("请配置你的 Xget 域名", "error"); showStatus("请配置你的 Xget 域名", "error");
@@ -315,6 +382,13 @@ async function saveSettings() {
} else { } else {
showStatus("✅ 设置已保存!查看页面通知中的刷新按钮", "success"); showStatus("✅ 设置已保存!查看页面通知中的刷新按钮", "success");
} }
} else if (response && response.error) {
console.error("保存设置失败:", response.error);
showStatus("保存设置时出错: " + response.error, "error");
} else {
// 如果没有响应,可能是消息传递失败
console.error("未收到后台脚本的响应");
showStatus("保存设置时出错:无法与后台脚本通信", "error");
} }
} catch (error) { } catch (error) {
console.error("保存设置时出错:", error); console.error("保存设置时出错:", error);