import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // 处理 manifest.json for Safari function processManifest() { const manifestPath = path.join(__dirname, '../public/manifest.json'); const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')); // 移除本地调试相关的配置 if (manifest.host_permissions) { manifest.host_permissions = manifest.host_permissions.filter( permission => !permission.includes('localhost') ); } if (manifest.content_security_policy && manifest.content_security_policy.extension_pages) { // 移除 CSP 中的本地开发相关配置 manifest.content_security_policy.extension_pages = manifest.content_security_policy.extension_pages .replace(/script-src 'self' http:\/\/localhost:5173;\s*/g, '') .replace(/\s*http:\/\/localhost:5173\s*/g, ' ') .replace(/\s*ws:\/\/localhost:5173\s*/g, ' ') .replace(/;\s+/g, '; ') // 标准化分号后的空格 .replace(/\s+/g, ' ') // 合并多个空格为一个 .trim(); } // Safari 特殊处理:添加 appShell.html 到 content scripts 匹配 if (manifest.content_scripts && manifest.content_scripts[0]) { // 添加 appShell.html 的匹配规则 const existingMatches = manifest.content_scripts[0].matches; if (!existingMatches.includes("https://monster-siren.hypergryph.com/")) { existingMatches.push("https://monster-siren.hypergryph.com/"); } } // Safari 特殊处理:使用 background.page 而不是 service_worker if (manifest.background && manifest.background.service_worker) { // Safari 扩展在 Manifest V3 中必须使用 persistent: false // 但为了调试,我们暂时设为 true 来确保页面加载 manifest.background = { page: "background.html", persistent: true }; } // 创建 background.html 文件用于 Safari const backgroundHtmlPath = path.join(__dirname, '../public/background.html'); const backgroundHtmlContent = `
If you can see this page, the background page is loaded!
`; fs.writeFileSync(backgroundHtmlPath, backgroundHtmlContent); // 创建 Safari 兼容的 background.js const backgroundJsPath = path.join(__dirname, '../public/background.js'); let backgroundJsContent = fs.readFileSync(backgroundJsPath, 'utf8'); // 检查是否已经添加过 Safari 代码,避免重复 if (backgroundJsContent.includes('=== Safari background.js starting ===')) { console.log('Safari background.js already processed, skipping...'); } else { // 在开头添加 Safari 调试信息(只添加一次) const safariDebugCode = ` console.log("=== Safari background.js starting ==="); console.log("Available APIs:", { chrome: typeof chrome, browser: typeof browser, safari: typeof safari }); // Safari 特殊处理 if (typeof chrome === 'undefined' && typeof browser === 'undefined') { console.log("No extension APIs available in Safari"); // 如果没有扩展 API,创建一个空的对象避免错误 window.chrome = { webRequest: { onBeforeRequest: { addListener: () => {} } }, storage: { sync: { get: () => Promise.resolve({}) } }, tabs: { create: () => {}, remove: () => {}, update: () => {} }, runtime: { getURL: (path) => path, onMessage: { addListener: () => {} } } }; } // Safari 消息监听器:处理来自 content script 的重定向请求 if (typeof chrome !== 'undefined' && chrome.runtime && chrome.runtime.onMessage) { chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { console.log('Background received message:', message); if (message.action === 'redirect_to_extension') { console.log('Processing redirect request from content script'); try { // 创建新标签页并打开扩展 const extensionUrl = chrome.runtime.getURL('index.html'); chrome.tabs.create({ url: extensionUrl }, (newTab) => { console.log('New extension tab created:', newTab.id); // 关闭原始标签页 if (sender.tab && sender.tab.id) { chrome.tabs.remove(sender.tab.id); } sendResponse({ success: true, url: extensionUrl }); }); } catch (error) { console.error('Failed to redirect:', error); sendResponse({ success: false, error: error.message }); } return true; // 保持消息通道开放 } }); } `; // 替换 Safari 的重定向 URL 监听 backgroundJsContent = backgroundJsContent.replace( /{ urls: \['https:\/\/monster-siren\.hypergryph\.com\/api\/fontset', 'https:\/\/monster-siren\.hypergryph\.com\/manifest\.json'\] }/g, "{ urls: ['https://monster-siren.hypergryph.com/api/fontset', 'https://monster-siren.hypergryph.com/manifest.json', 'https://monster-siren.hypergryph.com/'] }" ); // 替换 Safari 的重定向判断逻辑 backgroundJsContent = backgroundJsContent.replace( /details\.url === 'https:\/\/monster-siren\.hypergryph\.com\/manifest\.json'/g, "(details.url === 'https://monster-siren.hypergryph.com/manifest.json' || details.url === 'https://monster-siren.hypergryph.com/')" ); // 清理可能的重复条件 backgroundJsContent = backgroundJsContent.replace( /\(\(details\.url === 'https:\/\/monster-siren\.hypergryph\.com\/manifest\.json' \|\| details\.url === 'https:\/\/monster-siren\.hypergryph\.com\/'\) \|\| details\.url === 'https:\/\/monster-siren\.hypergryph\.com\/'\)/g, "(details.url === 'https://monster-siren.hypergryph.com/manifest.json' || details.url === 'https://monster-siren.hypergryph.com/')" ); backgroundJsContent = safariDebugCode + backgroundJsContent; } fs.writeFileSync(backgroundJsPath, backgroundJsContent); console.log('✅ Safari-compatible background.js created'); // 创建 Safari 专用的 content.js const contentJsPath = path.join(__dirname, '../public/content.js'); // 检查是否已经处理过 content.js const existingContentJs = fs.existsSync(contentJsPath) ? fs.readFileSync(contentJsPath, 'utf8') : ''; if (existingContentJs.includes('checkRedirectPreference')) { console.log('Safari content.js already processed, skipping...'); } else { const contentJsContent = ` // Safari 扩展 content script for redirect console.log('MSR Mod content script loaded on:', window.location.href); // 兼容 Safari 的浏览器 API const browserAPI = typeof browser !== 'undefined' ? browser : chrome; // 异步函数:检查重定向偏好设置 async function checkRedirectPreference() { try { console.log('Checking redirect preferences...'); // 读取偏好设置 const pref = await browserAPI.storage.sync.get('preferences'); console.log('Retrieved preferences:', pref); // 检查自动重定向设置(默认为 true) const shouldRedirect = pref === undefined || pref.preferences === undefined || pref.preferences.autoRedirect === undefined || pref.preferences.autoRedirect === true; console.log('Should redirect:', shouldRedirect); return shouldRedirect; } catch (error) { console.error('Error reading preferences:', error); // 如果读取偏好设置失败,默认重定向 return true; } } // 执行重定向的函数 function performRedirect() { console.log('Performing redirect to extension...'); try { // 对于 Safari,我们需要使用消息传递来请求重定向 // 因为 content script 无法直接访问 chrome.runtime.getURL // 方案1:尝试通过消息传递 if (typeof chrome !== 'undefined' && chrome.runtime) { chrome.runtime.sendMessage({action: 'redirect_to_extension'}, (response) => { if (chrome.runtime.lastError) { console.log('Message sending failed, trying direct redirect...'); // 方案2:尝试直接重定向(可能在某些情况下有效) window.location.href = 'safari-web-extension://[extension-id]/index.html'; } }); } else { console.log('Chrome runtime not available, trying alternative redirect...'); // 方案3:显示提示让用户手动打开扩展 document.body.innerHTML = \`Please click the MSR Mod extension icon in your Safari toolbar to open the app.