mirror of
https://github.com/violettoolssite/CFspider.git
synced 2026-04-05 19:39:01 +08:00
fix: browser extension Clone/Download acceleration, use GitHub proxy routes
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -41,3 +41,8 @@ media/videos/1080p60/CameraFollowCursorCVScene.mp4
|
|||||||
media/images/
|
media/images/
|
||||||
media/text/
|
media/text/
|
||||||
media/videos/1080p60/partial_movie_files/
|
media/videos/1080p60/partial_movie_files/
|
||||||
|
|
||||||
|
# 大视频文件
|
||||||
|
cfspider教程.mp4
|
||||||
|
*.mp4
|
||||||
|
!media/videos/1080p60/CameraFollowCursorCV.mp4
|
||||||
|
|||||||
@@ -78,3 +78,35 @@
|
|||||||
box-shadow: 0 4px 12px rgba(0, 212, 255, 0.3);
|
box-shadow: 0 4px 12px rgba(0, 212, 255, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clone URL 加速切换按钮 */
|
||||||
|
.cfspider-accel-toggle {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-left: 8px;
|
||||||
|
padding: 4px 10px;
|
||||||
|
background: linear-gradient(135deg, #00d4ff 0%, #7b2cbf 100%);
|
||||||
|
color: #fff !important;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
white-space: nowrap;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 212, 255, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cfspider-accel-toggle:hover {
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 212, 255, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cfspider-accel-toggle.active {
|
||||||
|
background: linear-gradient(135deg, #3fb950 0%, #238636 100%);
|
||||||
|
box-shadow: 0 2px 8px rgba(63, 185, 80, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cfspider-accel-toggle.active:hover {
|
||||||
|
box-shadow: 0 4px 12px rgba(63, 185, 80, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
(function() {
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
let config = { workersUrl: '', uuid: '', enabled: true };
|
let config = { workersUrl: '', uuid: '', enabled: true, cloneAccel: true, downloadAccel: true };
|
||||||
|
|
||||||
// GitHub 下载链接匹配模式
|
// GitHub 下载链接匹配模式
|
||||||
const GITHUB_DOWNLOAD_PATTERNS = [
|
const GITHUB_DOWNLOAD_PATTERNS = [
|
||||||
@@ -21,21 +21,60 @@
|
|||||||
return GITHUB_DOWNLOAD_PATTERNS.some(pattern => pattern.test(url));
|
return GITHUB_DOWNLOAD_PATTERNS.some(pattern => pattern.test(url));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生成加速链接
|
// 检查是否是 Git clone 链接
|
||||||
function generateAcceleratedUrl(originalUrl) {
|
function isGitCloneLink(url) {
|
||||||
if (!config.workersUrl || !config.uuid) return null;
|
if (!url) return false;
|
||||||
|
if (url.includes('github.com/') && !url.includes('/releases/') && !url.includes('/blob/') && !url.includes('/tree/')) {
|
||||||
// 构建代理 URL
|
const match = url.match(/github\.com\/([^\/]+)\/([^\/\?#]+)/);
|
||||||
const workersHost = config.workersUrl.replace(/^https?:\/\//, '').replace(/\/$/, '');
|
if (match && match[1] && match[2]) {
|
||||||
const encodedUrl = encodeURIComponent(originalUrl);
|
return true;
|
||||||
|
}
|
||||||
// 使用 /proxy API
|
}
|
||||||
return `https://${workersHost}/proxy?url=${encodedUrl}&method=GET`;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建加速按钮
|
// 生成加速的 clone 链接
|
||||||
|
function generateAcceleratedCloneUrl(originalUrl) {
|
||||||
|
if (!config.workersUrl) return null;
|
||||||
|
|
||||||
|
const workersHost = config.workersUrl.replace(/^https?:\/\//, '').replace(/\/$/, '');
|
||||||
|
const githubPath = originalUrl.replace('https://github.com/', '');
|
||||||
|
|
||||||
|
return `https://${workersHost}/github/${githubPath}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成加速链接(下载)- 使用专门的 GitHub 代理路由
|
||||||
|
function generateAcceleratedUrl(originalUrl) {
|
||||||
|
if (!config.workersUrl) return null;
|
||||||
|
|
||||||
|
const workersHost = config.workersUrl.replace(/^https?:\/\//, '').replace(/\/$/, '');
|
||||||
|
|
||||||
|
// 根据不同的 GitHub 域名使用不同的代理路由
|
||||||
|
if (originalUrl.includes('raw.githubusercontent.com/')) {
|
||||||
|
const path = originalUrl.replace('https://raw.githubusercontent.com/', '');
|
||||||
|
return `https://${workersHost}/gh-raw/${path}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (originalUrl.includes('codeload.github.com/')) {
|
||||||
|
const path = originalUrl.replace('https://codeload.github.com/', '');
|
||||||
|
return `https://${workersHost}/gh-codeload/${path}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (originalUrl.includes('objects.githubusercontent.com/')) {
|
||||||
|
const path = originalUrl.replace('https://objects.githubusercontent.com/', '');
|
||||||
|
return `https://${workersHost}/gh-objects/${path}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (originalUrl.includes('github.com/')) {
|
||||||
|
const path = originalUrl.replace('https://github.com/', '');
|
||||||
|
return `https://${workersHost}/github/${path}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建下载加速按钮
|
||||||
function createAccelerateButton(link) {
|
function createAccelerateButton(link) {
|
||||||
// 检查是否已添加按钮
|
|
||||||
if (link.nextElementSibling?.classList.contains('cfspider-btn')) return;
|
if (link.nextElementSibling?.classList.contains('cfspider-btn')) return;
|
||||||
if (link.parentElement.querySelector('.cfspider-btn')) return;
|
if (link.parentElement.querySelector('.cfspider-btn')) return;
|
||||||
|
|
||||||
@@ -51,59 +90,23 @@
|
|||||||
btn.href = generateAcceleratedUrl(link.href) || '#';
|
btn.href = generateAcceleratedUrl(link.href) || '#';
|
||||||
btn.target = '_blank';
|
btn.target = '_blank';
|
||||||
|
|
||||||
// 点击事件
|
|
||||||
btn.addEventListener('click', async (e) => {
|
btn.addEventListener('click', async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
if (!config.workersUrl || !config.uuid) {
|
if (!config.workersUrl) {
|
||||||
alert('请先在 CFspider 扩展中配置 Workers 地址和 UUID');
|
alert('请先在 CFspider 扩展中配置 Workers 地址');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 开始下载
|
|
||||||
const acceleratedUrl = generateAcceleratedUrl(link.href);
|
const acceleratedUrl = generateAcceleratedUrl(link.href);
|
||||||
if (acceleratedUrl) {
|
if (acceleratedUrl) {
|
||||||
// 显示加载状态
|
window.open(acceleratedUrl, '_blank');
|
||||||
btn.classList.add('loading');
|
} else {
|
||||||
btn.innerHTML = `
|
alert('不支持加速此链接类型');
|
||||||
<svg class="spinner" viewBox="0 0 16 16" width="14" height="14" fill="currentColor">
|
|
||||||
<path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z" opacity="0.3"/>
|
|
||||||
<path d="M8 0a8 8 0 0 1 8 8h-1.5A6.5 6.5 0 0 0 8 1.5V0Z"/>
|
|
||||||
</svg>
|
|
||||||
加速中...
|
|
||||||
`;
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 直接打开加速链接
|
|
||||||
window.open(acceleratedUrl, '_blank');
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
btn.classList.remove('loading');
|
|
||||||
btn.innerHTML = `
|
|
||||||
<svg viewBox="0 0 16 16" width="14" height="14" fill="currentColor">
|
|
||||||
<path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"/>
|
|
||||||
</svg>
|
|
||||||
加速
|
|
||||||
`;
|
|
||||||
}, 1500);
|
|
||||||
} catch (err) {
|
|
||||||
console.error('CFspider 加速失败:', err);
|
|
||||||
btn.classList.remove('loading');
|
|
||||||
btn.innerHTML = '失败';
|
|
||||||
setTimeout(() => {
|
|
||||||
btn.innerHTML = `
|
|
||||||
<svg viewBox="0 0 16 16" width="14" height="14" fill="currentColor">
|
|
||||||
<path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"/>
|
|
||||||
</svg>
|
|
||||||
加速
|
|
||||||
`;
|
|
||||||
}, 2000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 插入按钮
|
|
||||||
if (link.parentElement.classList.contains('d-flex') ||
|
if (link.parentElement.classList.contains('d-flex') ||
|
||||||
link.closest('.Box-row') ||
|
link.closest('.Box-row') ||
|
||||||
link.closest('.release-main-section')) {
|
link.closest('.release-main-section')) {
|
||||||
@@ -115,7 +118,7 @@
|
|||||||
|
|
||||||
// 扫描并处理下载链接
|
// 扫描并处理下载链接
|
||||||
function scanDownloadLinks() {
|
function scanDownloadLinks() {
|
||||||
if (!config.enabled) return;
|
if (!config.enabled || !config.downloadAccel) return;
|
||||||
|
|
||||||
const links = document.querySelectorAll('a[href]');
|
const links = document.querySelectorAll('a[href]');
|
||||||
|
|
||||||
@@ -126,28 +129,178 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理 Clone URL - 直接替换输入框内容和复制按钮
|
||||||
|
function processCloneUrl() {
|
||||||
|
if (!config.enabled || !config.cloneAccel || !config.workersUrl) return;
|
||||||
|
|
||||||
|
const selectors = [
|
||||||
|
'input[readonly]',
|
||||||
|
'input[data-autoselect]',
|
||||||
|
'input.form-control[readonly]',
|
||||||
|
'input[aria-label*="clone"]',
|
||||||
|
'input[aria-label*="Clone"]',
|
||||||
|
'.input-group input',
|
||||||
|
'[data-target="get-repo-modal.cloneInput"]'
|
||||||
|
];
|
||||||
|
|
||||||
|
let cloneInputs = [];
|
||||||
|
selectors.forEach(sel => {
|
||||||
|
const inputs = document.querySelectorAll(sel);
|
||||||
|
inputs.forEach(i => {
|
||||||
|
if (!cloneInputs.includes(i)) cloneInputs.push(i);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
cloneInputs.forEach(input => {
|
||||||
|
if (input.dataset.cfspiderProcessed) return;
|
||||||
|
|
||||||
|
const value = input.value;
|
||||||
|
if (!isGitCloneLink(value)) return;
|
||||||
|
|
||||||
|
input.dataset.cfspiderProcessed = 'true';
|
||||||
|
|
||||||
|
const originalUrl = value;
|
||||||
|
const acceleratedUrl = generateAcceleratedCloneUrl(originalUrl);
|
||||||
|
if (!acceleratedUrl) return;
|
||||||
|
|
||||||
|
const inputGroup = input.closest('.input-group') || input.parentElement;
|
||||||
|
|
||||||
|
// 创建加速按钮
|
||||||
|
const accelBtn = document.createElement('button');
|
||||||
|
accelBtn.className = 'cfspider-accel-toggle';
|
||||||
|
accelBtn.type = 'button';
|
||||||
|
accelBtn.innerHTML = '⚡ 加速';
|
||||||
|
accelBtn.title = '点击切换为 CFspider 加速链接';
|
||||||
|
|
||||||
|
// 存储状态到 input 元素上
|
||||||
|
input._cfspiderState = { original: originalUrl, accelerated: acceleratedUrl, isAccelerated: false };
|
||||||
|
|
||||||
|
accelBtn.addEventListener('click', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
const state = input._cfspiderState;
|
||||||
|
|
||||||
|
if (!state.isAccelerated) {
|
||||||
|
input.value = acceleratedUrl;
|
||||||
|
accelBtn.innerHTML = '✓ 已加速';
|
||||||
|
accelBtn.classList.add('active');
|
||||||
|
state.isAccelerated = true;
|
||||||
|
} else {
|
||||||
|
input.value = originalUrl;
|
||||||
|
accelBtn.innerHTML = '⚡ 加速';
|
||||||
|
accelBtn.classList.remove('active');
|
||||||
|
state.isAccelerated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.select();
|
||||||
|
});
|
||||||
|
|
||||||
|
input.insertAdjacentElement('afterend', accelBtn);
|
||||||
|
|
||||||
|
// 拦截容器内所有按钮的点击(可能是复制按钮)
|
||||||
|
interceptCopyButtons(inputGroup, input);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拦截复制按钮
|
||||||
|
function interceptCopyButtons(container, input) {
|
||||||
|
let searchContainer = container;
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
if (searchContainer.parentElement) {
|
||||||
|
searchContainer = searchContainer.parentElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const buttons = searchContainer.querySelectorAll('button, [role="button"]');
|
||||||
|
|
||||||
|
buttons.forEach(btn => {
|
||||||
|
const ariaLabel = btn.getAttribute('aria-label') || '';
|
||||||
|
const title = btn.getAttribute('title') || '';
|
||||||
|
const text = btn.textContent || '';
|
||||||
|
|
||||||
|
if (ariaLabel.toLowerCase().includes('copy') ||
|
||||||
|
title.toLowerCase().includes('copy') ||
|
||||||
|
text.toLowerCase().includes('copy') ||
|
||||||
|
btn.querySelector('svg.octicon-copy')) {
|
||||||
|
|
||||||
|
btn.addEventListener('click', (e) => {
|
||||||
|
const state = input._cfspiderState;
|
||||||
|
if (state && state.isAccelerated) {
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
navigator.clipboard.writeText(state.accelerated).then(() => {
|
||||||
|
showCopySuccess(btn);
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示复制成功
|
||||||
|
function showCopySuccess(btn) {
|
||||||
|
const originalHTML = btn.innerHTML;
|
||||||
|
btn.innerHTML = '<svg viewBox="0 0 16 16" width="16" height="16" fill="#3fb950"><path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path></svg>';
|
||||||
|
setTimeout(() => {
|
||||||
|
btn.innerHTML = originalHTML;
|
||||||
|
}, 1500);
|
||||||
|
}
|
||||||
|
|
||||||
// 加载配置
|
// 加载配置
|
||||||
async function loadConfig() {
|
async function loadConfig() {
|
||||||
try {
|
try {
|
||||||
const result = await chrome.storage.sync.get(['workersUrl', 'uuid', 'enabled']);
|
const result = await chrome.storage.sync.get(['workersUrl', 'uuid', 'enabled', 'cloneAccel', 'downloadAccel']);
|
||||||
config = {
|
config.workersUrl = result.workersUrl || '';
|
||||||
workersUrl: result.workersUrl || '',
|
config.uuid = result.uuid || '';
|
||||||
uuid: result.uuid || '',
|
config.enabled = result.enabled !== false;
|
||||||
enabled: result.enabled !== false
|
config.cloneAccel = result.cloneAccel !== false;
|
||||||
};
|
config.downloadAccel = result.downloadAccel !== false;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('CFspider: 加载配置失败', e);
|
console.error('CFspider: 加载配置失败', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听配置更新
|
// 监听配置变化
|
||||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
chrome.storage.onChanged.addListener((changes) => {
|
||||||
if (message.type === 'CONFIG_UPDATED') {
|
if (changes.workersUrl) config.workersUrl = changes.workersUrl.newValue || '';
|
||||||
config = message.config;
|
if (changes.uuid) config.uuid = changes.uuid.newValue || '';
|
||||||
|
if (changes.enabled !== undefined) config.enabled = changes.enabled.newValue !== false;
|
||||||
|
if (changes.cloneAccel !== undefined) config.cloneAccel = changes.cloneAccel.newValue !== false;
|
||||||
|
if (changes.downloadAccel !== undefined) config.downloadAccel = changes.downloadAccel.newValue !== false;
|
||||||
|
|
||||||
|
if (config.enabled) {
|
||||||
scanDownloadLinks();
|
scanDownloadLinks();
|
||||||
|
processCloneUrl();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 防抖变量
|
||||||
|
let scanTimeout = null;
|
||||||
|
let lastScanTime = 0;
|
||||||
|
const SCAN_THROTTLE = 500;
|
||||||
|
|
||||||
|
// 节流扫描函数
|
||||||
|
function throttledScan() {
|
||||||
|
const now = Date.now();
|
||||||
|
if (now - lastScanTime < SCAN_THROTTLE) {
|
||||||
|
if (scanTimeout) clearTimeout(scanTimeout);
|
||||||
|
scanTimeout = setTimeout(() => {
|
||||||
|
lastScanTime = Date.now();
|
||||||
|
scanDownloadLinks();
|
||||||
|
processCloneUrl();
|
||||||
|
}, SCAN_THROTTLE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastScanTime = now;
|
||||||
|
scanDownloadLinks();
|
||||||
|
processCloneUrl();
|
||||||
|
}
|
||||||
|
|
||||||
// 监听 DOM 变化
|
// 监听 DOM 变化
|
||||||
const observer = new MutationObserver((mutations) => {
|
const observer = new MutationObserver((mutations) => {
|
||||||
let shouldScan = false;
|
let shouldScan = false;
|
||||||
@@ -159,7 +312,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (shouldScan) {
|
if (shouldScan) {
|
||||||
setTimeout(scanDownloadLinks, 100);
|
throttledScan();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -167,23 +320,26 @@
|
|||||||
async function init() {
|
async function init() {
|
||||||
await loadConfig();
|
await loadConfig();
|
||||||
scanDownloadLinks();
|
scanDownloadLinks();
|
||||||
|
processCloneUrl();
|
||||||
|
|
||||||
// 监听 DOM 变化
|
|
||||||
observer.observe(document.body, {
|
observer.observe(document.body, {
|
||||||
childList: true,
|
childList: true,
|
||||||
subtree: true
|
subtree: true
|
||||||
});
|
});
|
||||||
|
|
||||||
// 页面导航时重新扫描(GitHub 使用 pjax)
|
document.addEventListener('pjax:end', () => {
|
||||||
document.addEventListener('pjax:end', scanDownloadLinks);
|
scanDownloadLinks();
|
||||||
document.addEventListener('turbo:load', scanDownloadLinks);
|
processCloneUrl();
|
||||||
|
});
|
||||||
|
document.addEventListener('turbo:load', () => {
|
||||||
|
scanDownloadLinks();
|
||||||
|
processCloneUrl();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 页面加载完成后初始化
|
|
||||||
if (document.readyState === 'loading') {
|
if (document.readyState === 'loading') {
|
||||||
document.addEventListener('DOMContentLoaded', init);
|
document.addEventListener('DOMContentLoaded', init);
|
||||||
} else {
|
} else {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
// 加载配置
|
// 加载配置
|
||||||
document.addEventListener('DOMContentLoaded', async () => {
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
const config = await chrome.storage.sync.get(['workersUrl', 'uuid', 'enabled']);
|
const config = await chrome.storage.sync.get(['workersUrl', 'uuid', 'enabled', 'cloneAccel', 'downloadAccel']);
|
||||||
|
|
||||||
document.getElementById('workersUrl').value = config.workersUrl || '';
|
document.getElementById('workersUrl').value = config.workersUrl || '';
|
||||||
document.getElementById('uuid').value = config.uuid || '';
|
document.getElementById('uuid').value = config.uuid || '';
|
||||||
document.getElementById('enabled').checked = config.enabled !== false;
|
document.getElementById('enabled').checked = config.enabled !== false;
|
||||||
|
document.getElementById('cloneAccel').checked = config.cloneAccel !== false;
|
||||||
|
document.getElementById('downloadAccel').checked = config.downloadAccel !== false;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 保存配置
|
// 保存配置
|
||||||
@@ -12,32 +14,30 @@ document.getElementById('saveBtn').addEventListener('click', async () => {
|
|||||||
const workersUrl = document.getElementById('workersUrl').value.trim();
|
const workersUrl = document.getElementById('workersUrl').value.trim();
|
||||||
const uuid = document.getElementById('uuid').value.trim();
|
const uuid = document.getElementById('uuid').value.trim();
|
||||||
const enabled = document.getElementById('enabled').checked;
|
const enabled = document.getElementById('enabled').checked;
|
||||||
|
const cloneAccel = document.getElementById('cloneAccel').checked;
|
||||||
|
const downloadAccel = document.getElementById('downloadAccel').checked;
|
||||||
|
|
||||||
const statusEl = document.getElementById('status');
|
const statusEl = document.getElementById('status');
|
||||||
|
|
||||||
// 验证
|
// 验证 - Workers 地址必填
|
||||||
if (!workersUrl) {
|
if (!workersUrl) {
|
||||||
statusEl.textContent = '请填写 Workers 地址';
|
statusEl.textContent = '请填写 Workers 地址';
|
||||||
statusEl.className = 'status error';
|
statusEl.className = 'status error';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!uuid) {
|
// UUID 格式验证(如果填写了)
|
||||||
statusEl.textContent = '请填写 UUID';
|
if (uuid) {
|
||||||
statusEl.className = 'status error';
|
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
||||||
return;
|
if (!uuidRegex.test(uuid)) {
|
||||||
}
|
statusEl.textContent = 'UUID 格式不正确';
|
||||||
|
statusEl.className = 'status error';
|
||||||
// UUID 格式验证
|
return;
|
||||||
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
}
|
||||||
if (!uuidRegex.test(uuid)) {
|
|
||||||
statusEl.textContent = 'UUID 格式不正确';
|
|
||||||
statusEl.className = 'status error';
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保存
|
// 保存
|
||||||
await chrome.storage.sync.set({ workersUrl, uuid, enabled });
|
await chrome.storage.sync.set({ workersUrl, uuid, enabled, cloneAccel, downloadAccel });
|
||||||
|
|
||||||
statusEl.textContent = '配置已保存';
|
statusEl.textContent = '配置已保存';
|
||||||
statusEl.className = 'status success';
|
statusEl.className = 'status success';
|
||||||
@@ -45,11 +45,13 @@ document.getElementById('saveBtn').addEventListener('click', async () => {
|
|||||||
// 通知 content script 更新配置
|
// 通知 content script 更新配置
|
||||||
const tabs = await chrome.tabs.query({ active: true, currentWindow: true });
|
const tabs = await chrome.tabs.query({ active: true, currentWindow: true });
|
||||||
if (tabs[0] && tabs[0].url.includes('github.com')) {
|
if (tabs[0] && tabs[0].url.includes('github.com')) {
|
||||||
chrome.tabs.sendMessage(tabs[0].id, { type: 'CONFIG_UPDATED', config: { workersUrl, uuid, enabled } });
|
chrome.tabs.sendMessage(tabs[0].id, {
|
||||||
|
type: 'CONFIG_UPDATED',
|
||||||
|
config: { workersUrl, uuid, enabled, cloneAccel, downloadAccel }
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
statusEl.className = 'status';
|
statusEl.className = 'status';
|
||||||
}, 2000);
|
}, 2000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user