mirror of
https://github.com/SickleSec/SnowEyes.git
synced 2026-10-28 19:30:50 +00:00
674 lines
21 KiB
JavaScript
674 lines
21 KiB
JavaScript
const searchEngines = [
|
|
{ id: 'baidupc', name: '百度PC' },
|
|
{ id: 'google', name: 'Google' },
|
|
{ id: '360', name: '360搜索' },
|
|
{ id: 'baidum', name: '百度移动' },
|
|
{ id: 'sougou', name: '搜狗' },
|
|
{ id: 'shenma', name: '神马' }
|
|
];
|
|
const imageCache = new WeakMap();
|
|
let tabId = null;
|
|
// 页面切换功能
|
|
function switchPage(pageName) {
|
|
// 清理旧页面的资源
|
|
if (currentPageCleanup) currentPageCleanup();
|
|
|
|
// 更新导航栏状态
|
|
document.querySelectorAll('.nav-tab').forEach(tab => {
|
|
tab.classList.remove('active');
|
|
if (tab.dataset.page === pageName) {
|
|
tab.classList.add('active');
|
|
}
|
|
});
|
|
|
|
// 更新页面显示
|
|
document.querySelectorAll('.page').forEach(page => {
|
|
page.style.display = 'none';
|
|
if (page.classList.contains(`${pageName}-page`)) {
|
|
page.style.display = 'block';
|
|
initializePage(pageName);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 统一页面初始化逻辑
|
|
function initializePage(pageName) {
|
|
switch(pageName) {
|
|
case 'config':
|
|
initConfigPage();
|
|
break;
|
|
case 'fingerprint':
|
|
initFingerprintPage();
|
|
break;
|
|
case 'analysis':
|
|
initAnalysisPage();
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 保存白名单
|
|
function saveWhitelist() {
|
|
const whitelistInput = document.getElementById('whitelistInput');
|
|
if (!whitelistInput) return;
|
|
|
|
// 获取输入的域名,过滤空行
|
|
const domains = whitelistInput.value
|
|
.split('\n')
|
|
.map(domain => domain.trim())
|
|
.filter(domain => domain && domain.length > 0);
|
|
|
|
// 保存到存储
|
|
chrome.storage.local.set({ customWhitelist: domains }, () => {
|
|
showSaveTooltip('保存成功');
|
|
});
|
|
}
|
|
|
|
// 显示保存提示
|
|
function showSaveTooltip(text) {
|
|
const saveBtn = document.getElementById('saveWhitelist');
|
|
if (!saveBtn) return;
|
|
|
|
const rect = saveBtn.getBoundingClientRect();
|
|
const tooltip = document.createElement('div');
|
|
tooltip.className = 'copy-tooltip';
|
|
tooltip.textContent = text;
|
|
tooltip.style.left = `${rect.left + rect.width / 2}px`;
|
|
tooltip.style.top = `${rect.top - 30}px`;
|
|
document.body.appendChild(tooltip);
|
|
|
|
setTimeout(() => tooltip.remove(), 1500);
|
|
}
|
|
|
|
// 检查当前域名是否在白名单中
|
|
function checkIfWhitelisted(hostname, callback) {
|
|
chrome.storage.local.get(['customWhitelist'], (result) => {
|
|
if (!result.customWhitelist || result.customWhitelist.length === 0) {
|
|
callback(false);
|
|
return;
|
|
}
|
|
|
|
const customWhitelist = result.customWhitelist.map(domain => domain.toLowerCase());
|
|
const isWhitelisted = customWhitelist.some(domain =>
|
|
hostname === domain || hostname.endsWith(`.${domain}`)
|
|
);
|
|
|
|
callback(isWhitelisted);
|
|
});
|
|
}
|
|
|
|
// 显示扫描结果的函数
|
|
function displayResults(results) {
|
|
// 定义要显示的数据部分
|
|
const sections = [
|
|
{ id: 'domain-list', data: results.domains, title: '域名' },
|
|
{ id: 'absolute-api-list', data: results.absoluteApis, title: 'API接口(绝对路径)', hasUrlCopy: true },
|
|
{ id: 'api-list', data: results.apis, title: 'API接口(相对路径)', hasUrlCopy: true },
|
|
{ id: 'module-list', data: results.moduleFiles, title: '模块路径' },
|
|
{ id: 'doc-list', data: results.docFiles, title: '文档文件' },
|
|
{ id: 'credentials-list', data: results.credentials, title: '用户名密码' },
|
|
{ id: 'cookie-list', data: results.cookies, title: 'Cookie' },
|
|
{ id: 'id-key-list', data: results.idKeys, title: 'ID密钥' },
|
|
{ id: 'phone-list', data: results.phones, title: '手机号码' },
|
|
{ id: 'email-list', data: results.emails, title: '邮箱' },
|
|
{ id: 'idcard-list', data: results.idcards, title: '身份证号' },
|
|
{ id: 'ip-list', data: results.ips, title: 'IP地址' },
|
|
{ id: 'company-list', data: results.companies, title: '公司机构' },
|
|
{ id: 'jwt-list', data: results.jwts, title: 'JWT Token' },
|
|
{ id: 'image-list', data: results.imageFiles, title: '音频图片' },
|
|
{ id: 'github-list', data: results.githubUrls, title: 'GitHub链接' },
|
|
{ id: 'vue-list', data: results.vueFiles, title: 'Vue文件' },
|
|
{ id: 'js-list', data: results.jsFiles, title: 'JS文件' },
|
|
{ id: 'url-list', data: results.urls, title: 'URL' }
|
|
];
|
|
|
|
// 获取容器
|
|
const container = document.querySelector('.scanner-page .container');
|
|
let html = '';
|
|
|
|
// 遍历所有部分
|
|
sections.forEach(({ id, data, title, hasUrlCopy }) => {
|
|
// 如果数据存在且不为空
|
|
if (data && data.length > 0) {
|
|
html += `
|
|
<div class="section">
|
|
<div class="section-header">
|
|
<div class="title-wrapper">
|
|
<span class="title">${title}</span>
|
|
<span class="count">(${data.length})</span>
|
|
</div>
|
|
<div class="button-group">
|
|
<button class="copy-btn" title="复制全部">
|
|
<svg viewBox="0 0 24 24"><path fill="currentColor" d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/></svg>
|
|
复制全部
|
|
</button>
|
|
${hasUrlCopy ? `
|
|
<button class="copy-url-btn" title="复制URL">
|
|
<svg viewBox="0 0 24 24"><path fill="currentColor" d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/></svg>
|
|
复制URL
|
|
</button>
|
|
` : ''}
|
|
</div>
|
|
</div>
|
|
<div class="section-content">
|
|
<div class="content-wrapper ${id}">
|
|
${Array.from(data).map(item => `
|
|
<div class="item" title="来源: ${item[1]}" data-source="${item[1]}">
|
|
${item[0]}
|
|
</div>
|
|
`).join('')}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
});
|
|
|
|
// 如果没有任何结果
|
|
if (!html) {
|
|
html = '<div class="no-results">未发现敏感信息</div>';
|
|
}
|
|
|
|
// 更新容器内容
|
|
container.innerHTML = html;
|
|
|
|
// 添加复制事件监听
|
|
container.querySelectorAll('.copy-btn').forEach(btn => {
|
|
btn.addEventListener('click', (e) => {
|
|
const section = btn.closest('.section');
|
|
const items = Array.from(section.querySelectorAll('.item'));
|
|
const text = items.map(item => item.textContent.trim()).filter(Boolean).join('\n');
|
|
copyToClipboard(text, e.clientX, e.clientY);
|
|
});
|
|
});
|
|
|
|
// 添加复制URL事件监听
|
|
container.querySelectorAll('.copy-url-btn').forEach(btn => {
|
|
btn.addEventListener('click', (e) => {
|
|
const section = btn.closest('.section');
|
|
const items = Array.from(section.querySelectorAll('.item'));
|
|
const sectionId = section.querySelector('.content-wrapper').className.split(' ')[1];
|
|
|
|
getCurrentTab().then(tab => {
|
|
if (tab) {
|
|
const baseUrl = new URL(tab.url).origin;
|
|
const currentUrl = new URL(tab.url);
|
|
|
|
const urls = items.map(item => {
|
|
const path = item.textContent.trim();
|
|
if (sectionId === 'absolute-api-list') {
|
|
// 绝对路径:直接拼接域名
|
|
return baseUrl + path;
|
|
} else if (sectionId === 'api-list') {
|
|
// 相对路径:基于当前页面URL进行解析
|
|
try {
|
|
const fullUrl = new URL(path, currentUrl.href);
|
|
return fullUrl.href;
|
|
} catch (e) {
|
|
// 如果解析失败,使用简单拼接
|
|
const currentDir = currentUrl.pathname.substring(0, currentUrl.pathname.lastIndexOf('/'));
|
|
return baseUrl + currentDir + '/' + path;
|
|
}
|
|
}
|
|
return path;
|
|
}).filter(Boolean).join('\n');
|
|
|
|
copyToClipboard(urls, e.clientX, e.clientY);
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
// 添加悬浮提示和点击复制来源事件监听
|
|
container.querySelectorAll('.item').forEach(item => {
|
|
item.addEventListener('click', (e) => {
|
|
const source = item.dataset.source;
|
|
if (source) {
|
|
copyToClipboard(source, e.clientX, e.clientY);
|
|
}
|
|
});
|
|
|
|
item.addEventListener('contextmenu', (e) => {
|
|
e.preventDefault();
|
|
copyToClipboard(item.textContent.trim(), e.clientX, e.clientY);
|
|
});
|
|
});
|
|
|
|
}
|
|
|
|
// 复制文本到剪贴板
|
|
async function copyToClipboard(text, x, y) {
|
|
try {
|
|
await navigator.clipboard.writeText(text);
|
|
showCopyTooltip('复制成功', x, y);
|
|
} catch (err) {
|
|
showCopyTooltip('复制失败', x, y);
|
|
}
|
|
}
|
|
|
|
// 显示复制成功提示
|
|
function showCopyTooltip(text, x, y) {
|
|
const tooltip = document.createElement('div');
|
|
tooltip.className = 'copy-tooltip';
|
|
tooltip.textContent = text;
|
|
tooltip.style.left = `${x}px`;
|
|
tooltip.style.top = `${y}px`;
|
|
document.body.appendChild(tooltip);
|
|
|
|
setTimeout(() => tooltip.remove(), 1500);
|
|
}
|
|
|
|
// 页面加载完成时的初始化
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
const activePage = document.querySelector('.nav-tab.active').dataset.page;
|
|
switchPage(activePage);
|
|
|
|
// 初始化扫描页面
|
|
const container = document.querySelector('.scanner-page .container');
|
|
container.innerHTML = '<div class="loading">正在扫描...</div>';
|
|
|
|
getCurrentTab().then(tab => {
|
|
if (tab) {
|
|
const hostname = new URL(tab.url).hostname.toLowerCase();
|
|
// 先检查自定义白名单
|
|
checkIfWhitelisted(hostname, (isWhitelisted) => {
|
|
if (isWhitelisted) {
|
|
container.innerHTML = '<div class="whitelisted">当前域名在白名单中,已跳过扫描</div>';
|
|
updateProgress(100);
|
|
return;
|
|
}
|
|
|
|
// 如果不在自定义白名单中,再发送消息获取结果
|
|
chrome.tabs.sendMessage(tab.id, {type: 'GET_RESULTS', tabId: tab.id, from: 'popup'}, response => {
|
|
if (chrome.runtime.lastError) {
|
|
container.innerHTML = '<div class="error">无法连接到页面,尝试刷新页面后再试吧</div>';
|
|
}else{
|
|
displayResults(response);
|
|
updateProgress(response.progress[0][1]);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
});
|
|
|
|
initConfigPage();
|
|
initEventListeners();
|
|
});
|
|
|
|
// 更新进度显示
|
|
function updateProgress(percent) {
|
|
const progressTab = document.querySelector('.progress-tab');
|
|
if (progressTab) {
|
|
progressTab.textContent = `${percent}%`;
|
|
}
|
|
}
|
|
|
|
// 监听来自 content script 的消息
|
|
chrome.runtime.onMessage.addListener((message) => {
|
|
if (message.type === 'SCAN_UPDATE' && message.tabId === tabId) {
|
|
if (message.results) {
|
|
displayResults(message.results);
|
|
}
|
|
updateProgress(message.results.progress[0][1]);
|
|
}
|
|
});
|
|
|
|
// 初始化配置页面
|
|
function initConfigPage() {
|
|
// 获取扫描设置和自定义白名单
|
|
chrome.storage.local.get(['dynamicScan', 'deepScan', 'customWhitelist'], (result) => {
|
|
const dynamicScanCheckbox = document.getElementById('dynamicScan');
|
|
const deepScanCheckbox = document.getElementById('deepScan');
|
|
const whitelistInput = document.getElementById('whitelistInput');
|
|
|
|
if (dynamicScanCheckbox) {
|
|
dynamicScanCheckbox.checked = result.dynamicScan === true;
|
|
}
|
|
if (deepScanCheckbox) {
|
|
deepScanCheckbox.checked = result.deepScan === true;
|
|
}
|
|
|
|
// 显示自定义白名单
|
|
if (whitelistInput && result.customWhitelist) {
|
|
whitelistInput.value = result.customWhitelist.join('\n');
|
|
}
|
|
});
|
|
}
|
|
|
|
// 更新服务器指纹信息
|
|
function updateServerFingerprints(fingerprints) {
|
|
const fingerprintSection = document.querySelector('.fingerprint-section');
|
|
fingerprintSection.innerHTML = '';
|
|
|
|
// 检查是否有任何指纹
|
|
let hasFingerprints = false;
|
|
for (const type in fingerprints) {
|
|
if (fingerprints[type] && fingerprints[type].length > 0) {
|
|
hasFingerprints = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 如果没有识别到任何指纹,显示提示信息
|
|
if (!hasFingerprints) {
|
|
fingerprintSection.innerHTML = `
|
|
<div class="notice">
|
|
暂未识别到指纹
|
|
</div>
|
|
`;
|
|
return;
|
|
}
|
|
|
|
// 遍历所有指纹类型
|
|
for (const [type, fingerprintData] of Object.entries(fingerprints)) {
|
|
if(fingerprintData.length === 0 || type === 'nameMap') continue;
|
|
for (const fingerprint of fingerprintData) {
|
|
addFingerprint(fingerprintSection, {
|
|
type: type,
|
|
name: fingerprint.name,
|
|
description: fingerprint.description,
|
|
value: fingerprint.version || fingerprint.name
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
// 添加单个指纹组
|
|
function addFingerprint(container, info) {
|
|
const group = document.createElement('div');
|
|
group.className = `fingerprint-group ${info.type}-group`;
|
|
group.innerHTML = `
|
|
<h3>
|
|
<span class="tag ${info.type}-tag">${info.type[0].toUpperCase()+info.type.slice(1)}</span>
|
|
${info.name}
|
|
</h3>
|
|
<div class="fingerprint-item">
|
|
<div class="fingerprint-label">${info.description}</div>
|
|
<div class="fingerprint-value server-value detected">${info.value}</div>
|
|
</div>
|
|
`;
|
|
container.appendChild(group);
|
|
}
|
|
|
|
// 初始化指纹页面
|
|
function initFingerprintPage() {
|
|
getCurrentTab().then(tab => {
|
|
if (tab) {
|
|
console.log('Requesting fingerprints for tab:', tab.id);
|
|
chrome.runtime.sendMessage({
|
|
type: 'GET_FINGERPRINTS',
|
|
tabId: tab.id,
|
|
from: 'popup',
|
|
to: 'background'
|
|
}, response => {
|
|
console.log('Received response:', response);
|
|
if (response) {
|
|
updateServerFingerprints(response);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
// 初始化网站解析页面
|
|
function initAnalysisPage() {
|
|
const container = document.querySelector('.analysis-section');
|
|
container.innerHTML = '<div class="loading">正在获取网站信息...</div>';
|
|
|
|
let timeoutId = null;
|
|
|
|
getCurrentTab().then(tab => {
|
|
if (tab) {
|
|
const domain = new URL(tab.url).hostname;
|
|
timeoutId = setTimeout(() => {
|
|
container.innerHTML = '<div class="error">请求超时,请重试</div>';
|
|
}, 10000);
|
|
|
|
chrome.runtime.sendMessage({
|
|
type: 'GET_SITE_ANALYSIS',
|
|
domain: domain,
|
|
tabId: tab.id,
|
|
from: 'popup',
|
|
to: 'background'
|
|
}, (response) => {
|
|
clearTimeout(timeoutId);
|
|
if (!response) {
|
|
container.innerHTML = '<div class="error">获取网站信息失败</div>';
|
|
return;
|
|
}
|
|
if (response.isPrivateIP) {
|
|
container.innerHTML = '<div class="notice">内网地址无需解析</div>';
|
|
return;
|
|
}
|
|
updateAnalysisPage(response, domain);
|
|
});
|
|
}
|
|
});
|
|
return () => {
|
|
if (timeoutId) clearTimeout(timeoutId);
|
|
};
|
|
}
|
|
|
|
// 更新网站解析页面内容
|
|
function updateAnalysisPage(data, domain) {
|
|
const container = document.querySelector('.analysis-section');
|
|
const icpData = data.icp;
|
|
container.innerHTML = `
|
|
<!-- 基本信息 -->
|
|
<div class="analysis-group basic-group">
|
|
<h3>基本信息</h3>
|
|
<div class="basic-info">
|
|
<div class="info-item">
|
|
<span class="info-label">域名</span>
|
|
<span class="info-value">${icpData?.domain || domain}</span>
|
|
</div>
|
|
<div class="info-item">
|
|
<span class="info-label">备案号</span>
|
|
<span class="info-value">${icpData?.icp || '暂无备案信息'}</span>
|
|
</div>
|
|
<div class="info-item">
|
|
<span class="info-label">主办单位</span>
|
|
<span class="info-value">${icpData?.unit || '未知'}</span>
|
|
</div>
|
|
<div class="info-item">
|
|
<span class="info-label">备案时间</span>
|
|
<span class="info-value">${icpData?.time || '未知'}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 域名权重信息 -->
|
|
<div class="analysis-group weight-group">
|
|
<h3>搜索引擎权重</h3>
|
|
<div class="weight-grid"></div>
|
|
</div>
|
|
|
|
<!-- IP地址信息 -->
|
|
<div class="analysis-group ip-group">
|
|
<h3>IP信息</h3>
|
|
<div class="ip-info"></div>
|
|
</div>
|
|
`;
|
|
|
|
// 更新权重信息
|
|
if (data.weight) {
|
|
const weightData = data.weight.data;
|
|
updateWeightInfo(weightData);
|
|
}
|
|
|
|
// 更新IP信息
|
|
if (data.ip) {
|
|
const ipData = data.ip.data;
|
|
updateIpInfo(ipData);
|
|
}
|
|
}
|
|
|
|
// 创建文档碎片批量更新
|
|
function updateElementsWithFragment(container, elements) {
|
|
const fragment = document.createDocumentFragment();
|
|
elements.forEach(element => fragment.appendChild(element));
|
|
container.innerHTML = '';
|
|
container.appendChild(fragment);
|
|
}
|
|
|
|
// 修改updateWeightInfo函数
|
|
function updateWeightInfo(weightData) {
|
|
const container = document.querySelector('.weight-grid');
|
|
|
|
if (weightData?.error) {
|
|
container.textContent = weightData.error;
|
|
return;
|
|
}
|
|
|
|
const elements = searchEngines.map(engine => {
|
|
const element = document.createElement('div');
|
|
element.className = 'weight-item';
|
|
|
|
// 直接使用原始值
|
|
const rawValue = weightData[engine.id] || 'n';
|
|
|
|
const displayValue = rawValue;
|
|
const imgValue = rawValue;
|
|
|
|
const img = document.createElement('img');
|
|
img.className = 'weight-img';
|
|
img.dataset.engine = engine.id;
|
|
img.dataset.src = `https://api.mir6.com/data/quanzhong_img/${engine.id}/${imgValue}.png`;
|
|
img.alt = engine.name;
|
|
|
|
const label = document.createElement('span');
|
|
label.className = 'weight-label';
|
|
label.textContent = engine.name;
|
|
|
|
const valueSpan = document.createElement('span');
|
|
valueSpan.className = 'weight-value';
|
|
valueSpan.textContent = displayValue;
|
|
|
|
element.append(img, label, valueSpan);
|
|
|
|
// 立即加载图片
|
|
const tempImg = new Image();
|
|
tempImg.src = img.dataset.src;
|
|
|
|
tempImg.onload = () => {
|
|
img.src = tempImg.src;
|
|
img.classList.add('loaded');
|
|
};
|
|
|
|
tempImg.onerror = () => {
|
|
img.src = `https://api.mir6.com/data/quanzhong_img/${engine.id}/0.png`;
|
|
img.classList.add('loaded');
|
|
};
|
|
|
|
return element;
|
|
});
|
|
|
|
updateElementsWithFragment(container, elements);
|
|
}
|
|
|
|
// 更新IP信息
|
|
function updateIpInfo(ipData) {
|
|
const ipInfo = document.querySelector('.ip-info');
|
|
const data = ipData;
|
|
ipInfo.innerHTML = `
|
|
<div class="info-item">
|
|
<span class="info-label">IPv4/6</span>
|
|
<span class="info-value">${data.ip || '无'}</span>
|
|
</div>
|
|
<div class="info-item">
|
|
<span class="info-label">地理位置</span>
|
|
<span class="info-value">${data.location || '无'}</span>
|
|
</div>
|
|
<div class="info-item">
|
|
<span class="info-label">邮政编码</span>
|
|
<span class="info-value">${data.zipcode || '无'}</span>
|
|
</div>
|
|
<div class="info-item">
|
|
<span class="info-label">运营商</span>
|
|
<span class="info-value">${data.isp || '无'}</span>
|
|
</div>
|
|
<div class="info-item">
|
|
<span class="info-label">协议</span>
|
|
<span class="info-value">${data.protocol || '无'}</span>
|
|
</div>
|
|
<div class="info-item">
|
|
<span class="info-label">网络类型</span>
|
|
<span class="info-value">${data.net || '无'}</span>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
// 统一事件管理
|
|
const eventListeners = {
|
|
'click .nav-tab': handleNavClick,
|
|
'change #dynamicScan': handleDynamicScan,
|
|
'change #deepScan': handleDeepScan,
|
|
'error .weight-img': handleImageError,
|
|
'click #saveWhitelist': saveWhitelist
|
|
};
|
|
|
|
function initEventListeners() {
|
|
// 清除可能存在的旧事件监听器
|
|
document.body.removeEventListener('click', handleNavClick);
|
|
document.body.removeEventListener('change', handleDynamicScan);
|
|
document.body.removeEventListener('error', handleImageError);
|
|
|
|
Object.entries(eventListeners).forEach(([eventKey, handler]) => {
|
|
const [event, selector] = eventKey.split(' ');
|
|
document.body.addEventListener(event, e => {
|
|
if (!selector || e.target.matches(selector)) handler(e);
|
|
});
|
|
});
|
|
}
|
|
|
|
// 统一使用handleNavClick处理页面切换
|
|
function handleNavClick(e) {
|
|
const tab = e.target.closest('.nav-tab');
|
|
if (tab) {
|
|
const pageName = tab.dataset.page;
|
|
switchPage(pageName);
|
|
}
|
|
}
|
|
|
|
// 添加通用的标签页查询函数
|
|
async function getCurrentTab() {
|
|
const tabs = await chrome.tabs.query({active: true, currentWindow: true});
|
|
tabId = tabs[0].id;
|
|
return tabs[0] || null;
|
|
}
|
|
|
|
// 修改使用标签页查询的函数
|
|
function handleDynamicScan(e) {
|
|
const enabled = e.target.checked;
|
|
chrome.storage.local.set({ dynamicScan: enabled });
|
|
|
|
getCurrentTab().then(tab => {
|
|
if (tab) {
|
|
chrome.tabs.sendMessage(tab.id, {
|
|
type: 'UPDATE_DYNAMIC_SCAN',
|
|
enabled: enabled
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
function handleDeepScan(e) {
|
|
const enabled = e.target.checked;
|
|
chrome.storage.local.set({ deepScan: enabled });
|
|
|
|
getCurrentTab().then(tab => {
|
|
if (tab) {
|
|
chrome.tabs.sendMessage(tab.id, {
|
|
type: 'UPDATE_DEEP_SCAN',
|
|
enabled: enabled
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
function handleImageError(e) {
|
|
if (e.target.classList.contains('weight-img')) {
|
|
const engine = e.target.dataset.engine;
|
|
e.target.src = `https://api.mir6.com/data/quanzhong_img/${engine}/0.png`;
|
|
}
|
|
}
|
|
|
|
let currentPageCleanup = null; // 添加页面清理函数存储
|