diff --git a/package.json b/package.json index 1547ce0..de4f974 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ssp-smart-search-plugin", - "version": "1.6.1", + "version": "1.6.2", "description": "搜索语法可视化工具 - SearchSyntax Pro", "type": "module", "scripts": { diff --git a/public/manifest.json b/public/manifest.json index 540a65d..0b2d1e5 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -1,23 +1,20 @@ { "manifest_version": 3, "name": "__MSG_app_name__", - "version": "1.6.1", + "version": "1.6.2", "description": "__MSG_app_description__", "default_locale": "zh_CN", "permissions": [ "storage", "activeTab", - "scripting", "contextMenus" ], "host_permissions": [ "https://www.baidu.com/*", "https://www.google.com/*", - "https://www.bing.com/*", - "https://www.sogou.com/*", - "https://www.so.com/*" + "https://www.bing.com/*" ], "background": { @@ -52,9 +49,7 @@ "matches": [ "https://www.baidu.com/*", "https://www.google.com/*", - "https://www.bing.com/*", - "https://www.sogou.com/*", - "https://www.so.com/*" + "https://www.bing.com/*" ], "js": ["content.js"], "run_at": "document_end" diff --git a/scripts/resize-screenshots.js b/scripts/resize-screenshots.js new file mode 100644 index 0000000..9775174 --- /dev/null +++ b/scripts/resize-screenshots.js @@ -0,0 +1,259 @@ +/** + * 截图尺寸调整工具 + * 自动将截图调整到目标分辨率,添加透明背景填充 + */ + +import sharp from 'sharp'; +import { fileURLToPath } from 'url'; +import { dirname, join } from 'path'; +import { existsSync, mkdirSync, readdirSync } from 'fs'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +// 预设的目标尺寸配置 +const PRESETS = { + 'screenshot': { width: 1280, height: 800, desc: '商店截图' }, + 'screenshot-small': { width: 640, height: 400, desc: '小尺寸截图' }, + 'logo': { width: 300, height: 300, desc: '扩展徽标' }, + 'small-promo': { width: 440, height: 280, desc: '小促销磁贴' }, + 'large-promo': { width: 1400, height: 560, desc: '大型促销磁贴' }, +}; + +/** + * 调整图片尺寸并添加透明背景 + * @param {string} inputPath - 输入图片路径 + * @param {string} outputPath - 输出图片路径 + * @param {number} targetWidth - 目标宽度 + * @param {number} targetHeight - 目标高度 + * @param {string} position - 图片位置 (center, top, bottom, left, right) + * @param {string} background - 背景颜色 (transparent, white, 或 hex 颜色) + */ +async function resizeWithPadding(inputPath, outputPath, targetWidth, targetHeight, position = 'center', background = 'transparent') { + try { + const image = sharp(inputPath); + const metadata = await image.metadata(); + + console.log(`\n📷 处理图片: ${inputPath}`); + console.log(` 原始尺寸: ${metadata.width}x${metadata.height}`); + console.log(` 目标尺寸: ${targetWidth}x${targetHeight}`); + + // 计算缩放比例(保持宽高比) + const widthRatio = targetWidth / metadata.width; + const heightRatio = targetHeight / metadata.height; + const ratio = Math.min(widthRatio, heightRatio); + + const resizedWidth = Math.round(metadata.width * ratio); + const resizedHeight = Math.round(metadata.height * ratio); + + console.log(` 缩放后: ${resizedWidth}x${resizedHeight}`); + + // 计算填充位置 + let left = 0; + let top = 0; + + switch (position) { + case 'center': + left = Math.round((targetWidth - resizedWidth) / 2); + top = Math.round((targetHeight - resizedHeight) / 2); + break; + case 'top': + left = Math.round((targetWidth - resizedWidth) / 2); + top = 0; + break; + case 'bottom': + left = Math.round((targetWidth - resizedWidth) / 2); + top = targetHeight - resizedHeight; + break; + case 'left': + left = 0; + top = Math.round((targetHeight - resizedHeight) / 2); + break; + case 'right': + left = targetWidth - resizedWidth; + top = Math.round((targetHeight - resizedHeight) / 2); + break; + } + + // 处理背景颜色 + const bgColor = background === 'transparent' + ? { r: 0, g: 0, b: 0, alpha: 0 } + : background === 'white' + ? { r: 255, g: 255, b: 255, alpha: 1 } + : parseColor(background); + + // 调整图片尺寸并添加背景 + await sharp(inputPath) + .resize(resizedWidth, resizedHeight, { + fit: 'contain', + background: bgColor + }) + .extend({ + top: top, + bottom: targetHeight - resizedHeight - top, + left: left, + right: targetWidth - resizedWidth - left, + background: bgColor + }) + .png() // 使用 PNG 格式以支持透明背景 + .toFile(outputPath); + + console.log(` ✅ 已保存: ${outputPath}`); + console.log(` 填充位置: left=${left}, top=${top}`); + + return { success: true, outputPath }; + } catch (error) { + console.error(` ❌ 处理失败: ${error.message}`); + return { success: false, error: error.message }; + } +} + +/** + * 解析颜色字符串(支持 hex 格式) + */ +function parseColor(colorStr) { + if (colorStr.startsWith('#')) { + const hex = colorStr.slice(1); + const r = parseInt(hex.slice(0, 2), 16); + const g = parseInt(hex.slice(2, 4), 16); + const b = parseInt(hex.slice(4, 6), 16); + return { r, g, b, alpha: 1 }; + } + return { r: 255, g: 255, b: 255, alpha: 1 }; +} + +/** + * 批量处理目录中的图片 + */ +async function batchResize(inputDir, outputDir, preset, options = {}) { + const { position = 'center', background = 'transparent' } = options; + + if (!existsSync(inputDir)) { + console.error(`❌ 输入目录不存在: ${inputDir}`); + return; + } + + if (!existsSync(outputDir)) { + mkdirSync(outputDir, { recursive: true }); + console.log(`📁 已创建输出目录: ${outputDir}`); + } + + const config = PRESETS[preset]; + if (!config) { + console.error(`❌ 未知的预设: ${preset}`); + console.log('可用预设:', Object.keys(PRESETS).join(', ')); + return; + } + + console.log(`\n🚀 开始批量处理 - ${config.desc}`); + console.log(` 目标尺寸: ${config.width}x${config.height}`); + console.log(` 图片位置: ${position}`); + console.log(` 背景: ${background}`); + + const files = readdirSync(inputDir).filter(file => + /\.(png|jpg|jpeg|webp)$/i.test(file) + ); + + if (files.length === 0) { + console.log('⚠️ 未找到图片文件'); + return; + } + + console.log(` 找到 ${files.length} 个图片文件`); + + const results = []; + for (const file of files) { + const inputPath = join(inputDir, file); + const outputPath = join(outputDir, file.replace(/\.(jpg|jpeg|webp)$/i, '.png')); + + const result = await resizeWithPadding( + inputPath, + outputPath, + config.width, + config.height, + position, + background + ); + + results.push({ file, ...result }); + } + + // 统计结果 + const successCount = results.filter(r => r.success).length; + const failCount = results.filter(r => !r.success).length; + + console.log('\n📊 处理完成:'); + console.log(` ✅ 成功: ${successCount}`); + if (failCount > 0) { + console.log(` ❌ 失败: ${failCount}`); + } +} + +/** + * 命令行接口 + */ +async function main() { + const args = process.argv.slice(2); + + if (args.length === 0) { + console.log(` +📐 截图尺寸调整工具 +=================== + +用法: + node scripts/resize-screenshots.js [output-dir] [options] + +预设尺寸: + screenshot 1280x800 商店截图(推荐) + screenshot-small 640x400 小尺寸截图 + logo 300x300 扩展徽标(正方形) + small-promo 440x280 小促销磁贴 + large-promo 1400x560 大型促销磁贴 + +选项: + --position= 图片位置: center, top, bottom, left, right (默认: center) + --background= 背景颜色: transparent, white, #RRGGBB (默认: transparent) + +示例: + # 处理截图,居中显示,透明背景 + node scripts/resize-screenshots.js screenshot ./screenshots ./output + + # 处理 logo,白色背景 + node scripts/resize-screenshots.js logo ./icons ./output --background=white + + # 处理促销图,顶部对齐 + node scripts/resize-screenshots.js small-promo ./images ./output --position=top + +快速使用: + 1. 将原始截图放到 screenshots/ 目录 + 2. 运行: node scripts/resize-screenshots.js screenshot ./screenshots ./screenshots-processed + 3. 在 screenshots-processed/ 目录获取处理后的图片 +`); + return; + } + + const preset = args[0]; + const inputDir = args[1] || './screenshots'; + const outputDir = args[2] || './screenshots-processed'; + + // 解析选项 + const options = {}; + args.slice(3).forEach(arg => { + if (arg.startsWith('--position=')) { + options.position = arg.split('=')[1]; + } + if (arg.startsWith('--background=')) { + options.background = arg.split('=')[1]; + } + }); + + await batchResize(inputDir, outputDir, preset, options); +} + +// 导出函数供其他脚本使用 +export { resizeWithPadding, batchResize, PRESETS }; + +// 命令行执行 +if (import.meta.url === `file://${process.argv[1]}`) { + main().catch(console.error); +} diff --git a/src/content/index.ts b/src/content/index.ts index ac07212..b45bc32 100644 --- a/src/content/index.ts +++ b/src/content/index.ts @@ -1,13 +1,18 @@ // Content Script for SearchSyntax Pro Chrome Extension +// ========== 功能开关配置 ========== +// 注意:这些开关控制实验性功能的启用状态 +const FEATURE_FLAGS = { + // 悬浮按钮功能开关(开发中,未来版本启用) + enableFloatingButton: false +} + // 检查是否在搜索引擎页面 function isSearchEnginePage(): boolean { const searchEngines = [ 'www.baidu.com', 'www.google.com', - 'www.bing.com', - 'www.sogou.com', - 'www.so.com' + 'www.bing.com' ] return searchEngines.some(engine => @@ -16,6 +21,8 @@ function isSearchEnginePage(): boolean { } // 在搜索引擎页面注入功能 +// TODO: 此功能为未来版本规划,当前通过FEATURE_FLAGS.enableFloatingButton控制 +// 计划功能:在搜索引擎页面添加悬浮按钮,提供快速访问入口 function injectSearchFeatures() { // 创建悬浮按钮 const floatingButton = document.createElement('div') @@ -217,13 +224,16 @@ function highlightSearchSyntax() { // 初始化content script function init() { console.log('SearchSyntax Pro Content Script 已加载') - + if (isSearchEnginePage()) { console.log('检测到搜索引擎页面,注入功能') - + // 延迟注入,确保页面加载完成 setTimeout(() => { - injectSearchFeatures() + // 根据功能开关决定是否注入悬浮按钮 + if (FEATURE_FLAGS.enableFloatingButton) { + injectSearchFeatures() + } analyzeSearchQuery() }, 1000) } diff --git a/src/options/App.tsx b/src/options/App.tsx index 7c5339d..8b6cdf6 100644 --- a/src/options/App.tsx +++ b/src/options/App.tsx @@ -504,6 +504,25 @@ function OptionsContent({ /> + {/* 悬浮按钮功能(开发中) */} +
+
+ +

+ 此功能正在开发中,将在未来版本启用 +

+
+ +
+ {/* 历史记录限制 */}