feat(M1.1): 项目初始化 (v0.0.1)

This commit is contained in:
李岩岩 2026-02-09 15:52:45 +08:00
commit 8ffb8a941d
31 changed files with 1873 additions and 0 deletions

41
.gitignore vendored Normal file
View File

@ -0,0 +1,41 @@
# Dependencies
node_modules/
.pnpm-store/
# Build output
dist/
dist-ssr/
*.local
# IDE
.vscode/*
!.vscode/extensions.json
.idea/
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# OS
.DS_Store
Thumbs.db
# Logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Testing
coverage/
# Environment
.env
.env.local
.env.*.local
# Chrome Extension
*.zip
*.crx
*.pem

319
docs/AGENTS.md Normal file
View File

@ -0,0 +1,319 @@
# 沙拉查词项目规范
> 架构原则、代码风格、通信协议、安全规范
---
## 1. 架构原则
### 模块职责
| 模块 | 职责 | 禁止行为 |
|------|------|----------|
| **Background** | 网络请求、数据持久化、右键菜单 | 操作DOM |
| **Content Script** | 读取页面文本、注入UI、用户交互 | 直接跨域请求 |
| **Popup** | 独立查词、快速设置、历史记录 | 访问页面DOM |
| **Options** | 配置管理、生词本、词典账号 | 操作页面内容 |
| **Shared** | 工具函数、常量、基类 | 依赖特定模块 |
### 通信规则
```
Content ↔ Background: chrome.runtime.sendMessage
Popup ↔ Background: chrome.runtime.sendMessage
Options → Background: chrome.runtime.sendMessage
```
---
## 2. 代码风格
### 命名规范
| 类型 | 规范 | 示例 |
|------|------|------|
| 文件 | 小写+连字符 | `salad-icon.js` |
| 类 | PascalCase | `DictionaryBase` |
| 函数 | camelCase+动词开头 | `getSelectionCoords()` |
| 常量 | UPPER_SNAKE_CASE | `DEFAULT_TIMEOUT` |
| 私有 | 下划线前缀 | `_handleMessage()` |
| 消息类型 | 大写+点分隔 | `DICT.SEARCH` |
### JavaScript 规范
**必须使用**:
- `const` / `let`,禁止 `var`
- 箭头函数作为回调
- 模板字符串
- 解构赋值
- 可选链 `?.`
**禁止**:
- `eval()`, `new Function()`
- `innerHTML` 插入不可信内容
- 同步的 `chrome.storage` 调用
**异步规范**:
```javascript
// ✅ async/await
async function searchWord(word) {
try {
const result = await dict.search(word);
return result;
} catch (error) {
console.error('Search failed:', error);
throw error;
}
}
```
### CSS 规范
**Shadow DOM 隔离**:
```javascript
const shadow = element.attachShadow({ mode: 'open' });
shadow.innerHTML = `
<style>
:host { display: block; }
.container { background: var(--salad-bg, #fff); }
</style>
<div class="container">...</div>
`;
```
**CSS 变量**:
```css
:root {
--salad-primary: #4CAF50;
--salad-bg: #ffffff;
--salad-text: #333333;
}
[data-theme="dark"] {
--salad-bg: #1a1a1a;
--salad-text: #e0e0e0;
}
```
---
## 3. 通信协议
### 消息格式
```javascript
// 请求
{
type: 'NAMESPACE.ACTION',
payload: { },
meta: { timestamp, requestId }
}
// 响应
{
type: 'NAMESPACE.ACTION_RESPONSE',
payload: { },
error: null,
meta: { requestId }
}
```
### 标准消息类型
```javascript
DICT.SEARCH / DICT.SEARCH_RESPONSE
CONFIG.GET / CONFIG.SET / CONFIG.CHANGED
WORD.ADD_FAVORITE / WORD.REMOVE_FAVORITE
CLIPBOARD.READ / CLIPBOARD.WRITE
HTTP.GET / HTTP.POST
```
### 通信封装
```javascript
// shared/messaging.js
class MessageClient {
async send(type, payload, timeout = 5000) {
return new Promise((resolve, reject) => {
// 实现:发送消息,监听响应,超时处理
});
}
}
export const messaging = new MessageClient();
```
---
## 4. 词典开发规范
### 基类定义
```javascript
export class DictionaryBase {
constructor(config = {}) {
this.name = config.name || 'Unknown';
this.icon = config.icon || '';
this.languages = config.languages || ['en', 'zh'];
}
async search(word) {
throw new Error('search() must be implemented');
}
supports(lang) {
return this.languages.includes(lang);
}
}
```
### 返回格式
```javascript
{
word: 'hello',
phonetic: '/həˈləʊ/',
meanings: [
{ partOfSpeech: 'int.', definitions: ['你好', '喂'] }
],
examples: [
{ sentence: 'Hello, world!', translation: '你好,世界!' }
],
url: 'https://...'
}
```
### 实现模板
```javascript
export class XxxDictionary extends DictionaryBase {
constructor(config = {}) {
super({ name: '词典名', icon: 'icon.png', languages: ['en', 'zh'], ...config });
}
async search(word) {
if (!word?.trim()) throw new Error('Word is empty');
const html = await messaging.send('HTTP.GET', {
url: `https://api.example.com?q=${encodeURIComponent(word)}`
});
return this.parse(html, word);
}
parse(html, word) {
const doc = new DOMParser().parseFromString(html, 'text/html');
return {
word,
phonetic: this.extractPhonetic(doc),
meanings: this.extractMeanings(doc),
examples: this.extractExamples(doc),
url: ''
};
}
}
```
---
## 5. UI 组件规范
### 组件基类
```javascript
export class ComponentBase extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: 'open' });
this._isVisible = false;
}
render() {
throw new Error('render() must be implemented');
}
show(x, y) {
this._isVisible = true;
this.style.display = 'block';
this.style.left = `${x}px`;
this.style.top = `${y}px`;
}
hide() {
this._isVisible = false;
this.style.display = 'none';
}
destroy() {
this.hide();
this.remove();
}
}
```
---
## 6. 存储规范
### 存储分层
```javascript
chrome.storage.local // 配置、生词本
chrome.storage.session // 临时数据
IndexedDB // 大数据量
Memory // 运行时缓存
```
### 配置结构
```javascript
const DEFAULT_CONFIG = {
version: '7.20.0',
general: {
enableSelection: true,
enableAnimation: true,
darkMode: false,
language: 'zh_CN'
},
searchMode: {
triggerMode: 'icon', // icon/direct/double/key
iconHoverSearch: false,
shortcutKeys: []
},
dictionaries: [
{ id: 'bing', enabled: true, order: 0 }
]
};
```
---
## 7. 安全规范
### XSS 防护
```javascript
// ✅ textContent
element.textContent = userInput;
// ❌ innerHTML 插入不可信内容
element.innerHTML = userInput;
// ✅ 必须使用时转义
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
```
### CSP
```json
{
"content_security_policy": {
"extension_pages": "script-src 'self'; object-src 'self'"
}
}
```
---
## 8. 版本号规范
遵循 SemVer**PATCH 与验收点关联**:
```
MAJOR.MINOR.PATCH
│ │ └─ 每个任务完成 +1
│ └─ 模块完成进入下一模块 +1
└─ 正式发布 = 1
```
详见 [README.md](./README.md) 版本规则部分和 [VERSION.md](./VERSION.md)

62
docs/M1.md Normal file
View File

@ -0,0 +1,62 @@
# M1 基础架构模块 (v0.0.1-0.0.5)
## 模块概述
- **版本范围**: 0.0.1 ~ 0.0.5
- **任务数**: 5
- **目标**: 搭建浏览器扩展插件的基础框架和开发环境
## 关键产出
- 完整的项目目录结构src/ 及其子目录)
- Manifest V3 配置文件
- Vite + @crxjs 构建工具链
- 模块间通信工具类messaging.js
- 支持 HMR 的完整开发流程
## 任务列表
### M1.1 项目初始化 [目标版本: 0.0.1]
**任务**: 创建项目目录结构
**验收标准**:
- [ ] 存在 `src/` 目录,包含 `background/`, `content/`, `popup/`, `options/`, `shared/` 子目录
- [ ] 存在 `package.json`,已初始化 npm 项目
- [ ] 存在 `.gitignore`,排除 node_modules 和 dist
### M1.2 Manifest V3 配置 [目标版本: 0.0.2]
**任务**: 编写 manifest.json
**验收标准**:
- [ ] manifest.json 位于项目根目录
- [ ] 声明 `manifest_version: 3`
- [ ] 声明 `action` (popup) 入口
- [ ] 声明 `background` (service_worker) 入口
- [ ] 声明 `content_scripts` 匹配所有 URL (`<all_urls>`)
- [ ] 声明必要权限:`storage`, `contextMenus`, `clipboardWrite`
### M1.3 构建工具配置 [目标版本: 0.0.3]
**任务**: 配置 Vite + @crxjs/vite-plugin
**验收标准**:
- [ ] 运行 `npm run dev` 能启动开发服务器
- [ ] 运行 `npm run build` 能生成 `dist/` 目录
- [ ] dist 目录包含所有必要文件,可直接加载到 Chrome
### M1.4 模块间通信工具 [目标版本: 0.0.4]
**任务**: 创建通信工具类
**验收标准**:
- [ ] `src/shared/messaging.js` 存在
- [ ] 封装 `sendToBackground()` 方法content 可向 background 发消息
- [ ] 封装 `sendToContent()` 方法background 可向 content 发消息
- [ ] 提供简单的 ping/pong 测试,验证通信链路通畅
### M1.5 开发环境验证 [目标版本: 0.0.5]
**任务**: 验证完整开发流程
**验收标准**:
- [ ] Chrome 扩展管理页能加载 dist 目录
- [ ] 修改代码后扩展自动刷新HMR
- [ ] Console 无报错,各模块控制台能打印日志
## 依赖
- **前置模块**: 无
- **后置模块**: M2 划词核心模块
## 参考资料
- [AGENTS.md](./AGENTS.md) - 规范文档
- [QUICK_REF.md](./QUICK_REF.md) - 快速参考

74
docs/M10.md Normal file
View File

@ -0,0 +1,74 @@
# M10 高级功能模块 (v0.9.1-0.9.8)
## 模块概述
- **版本范围**: 0.9.1 ~ 0.9.8
- **任务数**: 8
- **目标**: 实现剪贴板操作、PDF支持和独立窗口等高级功能
## 关键产出
- 权限管理页面
- 剪贴板读取/写入权限及功能
- 剪贴板快速查词
- 复制原文/译文功能
- PDF 划词支持
- 独立窗口完善
## 任务列表
### M10.1 权限管理页面 [目标版本: 0.9.1]
**任务**: 权限说明和开关
**验收标准**:
- [ ] 设置页"权限管理"菜单
- [ ] 列出所需权限及用途说明
### M10.2 读取剪贴板权限 [目标版本: 0.9.2]
**任务**: 申请剪贴板读取权限
**验收标准**:
- [ ] "读取剪贴板"开关
- [ ] 开启时申请 `clipboardRead` 权限
- [ ] 说明用途:快捷查词时读取剪贴板
### M10.3 剪贴板快速查词 [目标版本: 0.9.3]
**任务**: 打开Popup时自动查剪贴板内容
**验收标准**:
- [ ] 开启权限后打开Popup自动读取剪贴板
- [ ] 如果剪贴板是单词,自动查询显示结果
### M10.4 写入剪贴板权限 [目标版本: 0.9.4]
**任务**: 申请剪贴板写入权限
**验收标准**:
- [ ] "写入剪贴板"开关
- [ ] 开启时申请 `clipboardWrite` 权限
### M10.5 复制原文功能 [目标版本: 0.9.5]
**任务**: 复制单词到剪贴板
**验收标准**:
- [ ] 结果面板有"复制"按钮
- [ ] 点击复制单词原文
### M10.6 复制译文功能 [目标版本: 0.9.6]
**任务**: 复制释义到剪贴板
**验收标准**:
- [ ] 可复制单个释义,或全部释义
- [ ] 复制后显示"已复制"提示
### M10.7 PDF支持 [目标版本: 0.9.7]
**任务**: 在PDF中启用划词
**验收标准**:
- [ ] 在浏览器打开PDF文件时划词功能可用
- [ ] 可能需要适配 PDF.js 的文本层
### M10.8 独立窗口完善 [目标版本: 0.9.8]
**任务**: 独立查词窗口功能完整
**验收标准**:
- [ ] 独立窗口有完整的搜索、历史、收藏功能
- [ ] 窗口可置顶always on top如浏览器支持
- [ ] 支持快捷键呼出(如 Alt+Shift+S
## 依赖
- **前置模块**: M1 基础架构模块, M2 划词核心模块, M5 设置系统模块
- **后置模块**: 无
## 参考资料
- [AGENTS.md](./AGENTS.md) - 规范文档
- [QUICK_REF.md](./QUICK_REF.md) - 快速参考

90
docs/M11.md Normal file
View File

@ -0,0 +1,90 @@
# M11 优化发布模块 (v0.10.1-1.0.0)
## 模块概述
- **版本范围**: 0.10.1 ~ 1.0.0
- **任务数**: 10
- **目标**: 性能优化、国际化、文档编写和发布准备
## 关键产出
- 请求去重和取消机制
- 虚拟滚动性能优化
- 错误日志系统
- 国际化i18n框架和英文翻译
- 用户使用文档和开发文档
- 生产环境打包配置
- Chrome 商店发布素材
## 任务列表
### M11.1 请求去重 [目标版本: 0.10.1]
**任务**: 避免重复查询
**验收标准**:
- [ ] 连续查询同一单词,使用缓存结果
- [ ] 缓存有效期 5 分钟
### M11.2 请求取消 [目标版本: 0.10.2]
**任务**: 快速切换时取消旧请求
**验收标准**:
- [ ] 使用 AbortController 取消未完成请求
- [ ] 连续划词不同单词,旧查询不显示结果
### M11.3 虚拟滚动 [目标版本: 0.10.3]
**任务**: 生词本大量数据优化
**验收标准**:
- [ ] 生词本超过100条时使用虚拟滚动
- [ ] 滚动流畅,不卡顿
### M11.4 错误日志 [目标版本: 0.10.4]
**任务**: 记录错误信息
**验收标准**:
- [ ] 错误信息保存到 storage
- [ ] 设置页可查看最近错误日志
- [ ] 提供"导出日志"功能
### M11.5 国际化i18n框架 [目标版本: 0.10.5]
**任务**: 多语言支持
**验收标准**:
- [ ] `src/_locales/` 目录,含 zh_CN、en
- [ ] 所有界面文字使用 i18n 方式
- [ ] 可切换界面语言
### M11.6 英文翻译 [目标版本: 0.10.6]
**任务**: 提供英文界面
**验收标准**:
- [ ] 所有菜单、按钮有英文翻译
- [ ] 设置页选择 English 后全部显示英文
### M11.7 使用文档 [目标版本: 0.10.7]
**任务**: 编写用户文档
**验收标准**:
- [ ] README.md 说明安装使用方法
- [ ] 功能介绍截图
### M11.8 开发文档 [目标版本: 0.10.8]
**任务**: 编写开发文档
**验收标准**:
- [ ] 项目结构说明
- [ ] 如何添加新词典的指南
- [ ] 贡献指南
### M11.9 打包配置 [目标版本: 0.10.9]
**任务**: 生产环境打包
**验收标准**:
- [ ] `npm run build:prod` 生成生产包
- [ ] 代码压缩、去除 sourcemap
- [ ] 生成 zip 文件供上传
### M11.10 图标和素材 [目标版本: 1.0.0]
**任务**: 准备发布素材
**验收标准**:
- [ ] 图标尺寸16x16, 32x32, 48x48, 128x128
- [ ] 截图展示划词、Popup、设置页
- [ ] 宣传图Chrome商店用
## 依赖
- **前置模块**: M1 基础架构模块, M2 划词核心模块
- **后置模块**: 无
## 参考资料
- [AGENTS.md](./AGENTS.md) - 规范文档
- [QUICK_REF.md](./QUICK_REF.md) - 快速参考

95
docs/M2.md Normal file
View File

@ -0,0 +1,95 @@
# M2 划词核心模块 (v0.1.1-0.1.9)
## 模块概述
- **版本范围**: 0.1.1 ~ 0.1.9
- **任务数**: 9
- **目标**: 实现网页文本选择检测和沙拉图标/面板交互功能
## 关键产出
- 文本选择检测系统selection.js
- 沙拉图标组件Shadow DOM 封装)
- 词典结果面板组件DictPanel.js
- 智能位置计算和视口适配
- Popup 中的划词总开关
## 任务列表
### M2.1 文本选择检测 [目标版本: 0.1.1]
**任务**: 监听网页文本选择事件
**验收标准**:
- [ ] `src/content/selection.js` 存在
- [ ] 监听 `mouseup` 事件
- [ ] 当选中文本长度 > 0 时,打印选中文本到控制台
- [ ] 在任意网页划词Console 能看到选中的文本
### M2.2 获取选中文本坐标 [目标版本: 0.1.2]
**任务**: 计算选中文本的位置信息
**验收标准**:
- [ ] 函数 `getSelectionCoords()` 返回 `{x, y, width, height}`
- [ ] 支持单行文本选择
- [ ] 支持多行文本选择(返回首行或整个选区的矩形)
- [ ] 坐标值正确(相对于视口)
### M2.3 沙拉图标组件(基础) [目标版本: 0.1.3]
**任务**: 创建浮动图标元素
**验收标准**:
- [ ] `src/content/components/SaladIcon.js` 存在
- [ ] 图标为 24x24px 的 div背景色为绿色先不用真实Logo
- [ ] 使用 Shadow DOM 封装,样式不泄露到页面
- [ ] 图标 `position: fixed`,可定位到任意坐标
### M2.4 图标定位显示 [目标版本: 0.1.4]
**任务**: 划词后图标出现在选中文本附近
**验收标准**:
- [ ] 划词后图标显示在选中文本右上角x + width, y
- [ ] 图标不随页面滚动而偏移(使用 fixed 定位)
- [ ] 再次划词时,先隐藏旧图标,再显示新图标
- [ ] 点击页面空白处,图标消失
### M2.5 图标点击事件 [目标版本: 0.1.5]
**任务**: 点击图标触发回调
**验收标准**:
- [ ] 点击图标时,打印 "icon clicked" 到控制台
- [ ] 回调函数可配置(通过参数传入)
- [ ] 点击后图标不消失(后续再处理)
### M2.6 基础面板组件 [目标版本: 0.1.6]
**任务**: 创建词典结果展示面板
**验收标准**:
- [ ] `src/content/components/DictPanel.js` 存在
- [ ] 面板尺寸 400x300px白色背景带阴影
- [ ] 使用 Shadow DOM 封装
- [ ] 面板内显示标题 "词典结果"
- [ ] 提供 `show(x, y)``hide()` 方法
### M2.7 面板位置计算 [目标版本: 0.1.7]
**任务**: 面板智能定位,不超出视口
**验收标准**:
- [ ] 面板默认显示在图标右下方
- [ ] 如果右侧超出视口,显示在左侧
- [ ] 如果下方超出视口,显示在上方
- [ ] 面板边界与视口保留 10px 边距
### M2.8 图标-面板联动 [目标版本: 0.1.8]
**任务**: 点击图标显示面板
**验收标准**:
- [ ] 点击图标,面板显示在图标附近
- [ ] 面板显示时,图标保持可见
- [ ] 点击面板外部区域,面板关闭
- [ ] 按 ESC 键,面板关闭
### M2.9 图标显示开关 [目标版本: 0.1.9]
**任务**: Popup 中添加总开关
**验收标准**:
- [ ] Popup 中有一个 Toggle 开关,标签"启用划词"
- [ ] 开关状态保存到 `chrome.storage.local`
- [ ] 关闭开关后,网页划词不再显示图标
- [ ] 打开开关后,恢复划词显示图标
## 依赖
- **前置模块**: M1 基础架构模块
- **后置模块**: M3 词典系统模块, M5 设置系统模块
## 参考资料
- [AGENTS.md](./AGENTS.md) - 规范文档
- [QUICK_REF.md](./QUICK_REF.md) - 快速参考

107
docs/M3.md Normal file
View File

@ -0,0 +1,107 @@
# M3 词典系统模块 (v0.2.1-0.2.11)
## 模块概述
- **版本范围**: 0.2.1 ~ 0.2.11
- **任务数**: 11
- **目标**: 构建词典接口体系,支持多词典源查询和结果展示
## 关键产出
- 词典接口基类设计DictionaryBase
- 词典管理器(支持多词典注册和查询)
- 必应词典和有道词典实现
- 后台查询接口Background Service Worker
- 结果展示组件(支持折叠/展开)
## 任务列表
### M3.1 词典接口基类设计 [目标版本: 0.2.1]
**任务**: 定义词典抽象接口
**验收标准**:
- [ ] `src/shared/dictionary/base.js` 存在
- [ ] 定义 `DictionaryBase`
- [ ] 要求子类实现 `search(word)` 方法
- [ ] 定义统一的返回格式:`{word, phonetic, meanings[], examples[]}`
### M3.2 词典管理器 [目标版本: 0.2.2]
**任务**: 管理多个词典实例
**验收标准**:
- [ ] `src/shared/dictionary/manager.js` 存在
- [ ] 提供 `register(name, dictionaryInstance)` 注册词典
- [ ] 提供 `search(word, dictNames[])` 查询指定词典
- [ ] 提供 `getAll()` 获取所有已注册词典
### M3.3 必应词典实现Mock版 [目标版本: 0.2.3]
**任务**: 先实现假数据版本
**验收标准**:
- [ ] `src/shared/dictionary/bing.js` 存在
- [ ] 继承 `DictionaryBase`
- [ ] `search(word)` 返回模拟数据不调用真实API
- [ ] 模拟数据包含:单词、音标、词性、中文释义、例句
### M3.4 后台查询接口 [目标版本: 0.2.4]
**任务**: background 处理词典查询请求
**验收标准**:
- [ ] background 监听 `DICT_SEARCH` 消息
- [ ] 调用词典管理器执行查询
- [ ] 返回查询结果给 content script
- [ ] Console 可看到查询结果
### M3.5 结果展示组件(静态) [目标版本: 0.2.5]
**任务**: 面板中显示词典结果
**验收标准**:
- [ ] 面板内显示单词标题(大字)
- [ ] 显示音标(如果有)
- [ ] 显示词性和中文释义列表
- [ ] 显示1-2个例句英文+中文翻译)
### M3.6 点击图标查词Mock数据 [目标版本: 0.2.6]
**任务**: 打通完整流程
**验收标准**:
- [ ] 网页划词,点击图标
- [ ] 面板显示该单词的 Mock 查询结果
- [ ] 结果显示格式正确,可读
### M3.7 必应词典真实API [目标版本: 0.2.7]
**任务**: 调用必应词典接口
**验收标准**:
- [ ] 使用 fetch 请求必应词典网页
- [ ] 解析 HTML 提取释义数据
- [ ] 错误时返回友好提示(如"查询失败,请检查网络"
- [ ] 替换 Mock 数据,显示真实结果
### M3.8 加载状态显示 [目标版本: 0.2.8]
**任务**: 查询时显示 loading
**验收标准**:
- [ ] 点击图标后,面板先显示 loading 动画
- [ ] 查询完成后loading 消失,显示结果
- [ ] 查询超时5秒显示"查询超时"
### M3.9 有道词典实现 [目标版本: 0.2.9]
**任务**: 添加第二个词典源
**验收标准**:
- [ ] `src/shared/dictionary/youdao.js` 存在
- [ ] 实现 `search(word)` 调用有道API或网页
- [ ] 注册到词典管理器
- [ ] 面板中可同时显示必应和有道结果
### M3.10 结果折叠/展开 [目标版本: 0.2.10]
**任务**: 词典结果可折叠
**验收标准**:
- [ ] 每个词典结果区域有标题栏(词典名+展开/折叠按钮)
- [ ] 点击标题栏可折叠/展开该词典结果
- [ ] 折叠状态用图标表示(▼/▶)
### M3.11 词典图标标识 [目标版本: 0.2.11]
**任务**: 每个词典显示对应Logo
**验收标准**:
- [ ] 必应结果前有必应图标(或颜色标识)
- [ ] 有道结果前有道图标
- [ ] 图标使用小尺寸16x16px
## 依赖
- **前置模块**: M1 基础架构模块, M2 划词核心模块
- **后置模块**: M4 Popup查词模块, M6 触发方式模块, M9 API账号模块
## 参考资料
- [AGENTS.md](./AGENTS.md) - 规范文档
- [QUICK_REF.md](./QUICK_REF.md) - 快速参考

82
docs/M4.md Normal file
View File

@ -0,0 +1,82 @@
# M4 Popup查词模块 (v0.3.1-0.3.8)
## 模块概述
- **版本范围**: 0.3.1 ~ 0.3.8
- **任务数**: 8
- **目标**: 构建独立弹窗界面,支持搜索、历史记录和独立窗口
## 关键产出
- Popup 页面框架HTML/JS/CSS
- 搜索功能和自动补全建议
- 查询历史记录系统
- 前进后退导航功能
- 独立窗口支持
## 任务列表
### M4.1 Popup基础界面 [目标版本: 0.3.1]
**任务**: 创建 Popup 页面框架
**验收标准**:
- [ ] `src/popup/` 目录存在,含 HTML/JS/CSS
- [ ] Popup 宽度 400px高度自适应最小400px
- [ ] 顶部有搜索输入框
- [ ] 中间为结果展示区
- [ ] 底部有"启用划词"开关
### M4.2 Popup搜索功能 [目标版本: 0.3.2]
**任务**: 输入单词查询
**验收标准**:
- [ ] 在输入框输入单词,按 Enter 触发查询
- [ ] 查询结果显示在下方(复用 content 的结果组件)
- [ ] 支持查询多个词典
### M4.3 搜索建议Autocomplete [目标版本: 0.3.3]
**任务**: 输入时显示单词建议
**验收标准**:
- [ ] 输入时,下拉显示匹配单词列表
- [ ] 使用简单的内置词库100个常用词
- [ ] 点击建议项,自动填入并查询
- [ ] 键盘上下键可选择建议项
### M4.4 查询历史记录 [目标版本: 0.3.4]
**任务**: 保存查询历史
**验收标准**:
- [ ] 每次查询保存到 `chrome.storage.local`
- [ ] 最多保存 50 条历史
- [ ] Popup 顶部有历史记录按钮
### M4.5 历史记录展示 [目标版本: 0.3.5]
**任务**: 查看和选择历史
**验收标准**:
- [ ] 点击历史按钮,显示历史单词列表
- [ ] 点击历史单词,直接查询该单词
- [ ] 历史列表可清空
### M4.6 前进后退导航 [目标版本: 0.3.6]
**任务**: 像浏览器一样前进后退
**验收标准**:
- [ ] Popup 顶部有前进、后退按钮
- [ ] 查询新单词后,可后退到上一个结果
- [ ] 支持键盘快捷键 Alt+←/→
### M4.7 收藏按钮UI占位 [目标版本: 0.3.7]
**任务**: 添加心形收藏按钮
**验收标准**:
- [ ] 结果区域右上角有心形图标
- [ ] 点击切换空心/实心状态
- [ ] 暂不需要实际存储仅UI
### M4.8 独立窗口打开 [目标版本: 0.3.8]
**任务**: Popup 可打开独立窗口
**验收标准**:
- [ ] Popup 有"打开独立窗口"按钮
- [ ] 点击后打开新窗口URL 为 `chrome-extension://.../standalone.html`
- [ ] 独立窗口尺寸 600x500px可调整大小
## 依赖
- **前置模块**: M1 基础架构模块, M2 划词核心模块, M3 词典系统模块
- **后置模块**: M8 生词本模块
## 参考资料
- [AGENTS.md](./AGENTS.md) - 规范文档
- [QUICK_REF.md](./QUICK_REF.md) - 快速参考

134
docs/M5.md Normal file
View File

@ -0,0 +1,134 @@
# M5 设置系统模块 (v0.4.1-0.4.16)
## 模块概述
- **版本范围**: 0.4.1 ~ 0.4.16
- **任务数**: 16
- **目标**: 构建完整的设置页面和配置管理系统
## 关键产出
- Options 设置页面框架
- 配置存储工具config.js
- 基本选项(开关、动画、主题、语言)
- 查词习惯设置
- 词典管理(添加、排序、删除)
## 任务列表
### M5.1 设置页面框架 [目标版本: 0.4.1]
**任务**: 创建 Options 页面
**验收标准**:
- [ ] `src/options/` 目录存在
- [ ] 点击"扩展选项"能打开设置页
- [ ] 左侧为导航菜单,右侧为内容区
- [ ] 菜单项:基本选项、查词习惯、词典设置、词典账号、右键菜单、权限管理
### M5.2 配置存储工具 [目标版本: 0.4.2]
**任务**: 封装配置读写
**验收标准**:
- [ ] `src/shared/config.js` 存在
- [ ] `getConfig(key)` 读取配置,支持默认值
- [ ] `setConfig(key, value)` 保存配置
- [ ] 配置变更时触发事件通知
### M5.3 基本选项-划词翻译开关 [目标版本: 0.4.3]
**任务**: 总开关设置
**验收标准**:
- [ ] 设置页"基本选项"中有"启用划词翻译"开关
- [ ] 开关状态与 Popup 中的开关同步
- [ ] 关闭后,所有页面划词不再触发
### M5.4 基本选项-动画开关 [目标版本: 0.4.4]
**任务**: 控制动画效果
**验收标准**:
- [ ] "开启动画过渡"开关
- [ ] 开启时,图标/面板有淡入淡出动画
- [ ] 关闭时,瞬间显示/隐藏
### M5.5 基本选项-后台运行 [目标版本: 0.4.5]
**任务**: 后台保持运行
**验收标准**:
- [ ] "后台保持运行"开关
- [ ] 开启后,浏览器关闭后扩展仍响应快捷键
- [ ] V3限制可能需要 keep-alive 技巧)
### M5.6 基本选项-黑暗模式 [目标版本: 0.4.6]
**任务**: 主题切换
**验收标准**:
- [ ] "黑暗模式"开关
- [ ] 开启后面板、Popup、设置页变为深色主题
- [ ] 颜色对比度正常,可读
### M5.7 基本选项-界面语言 [目标版本: 0.4.7]
**任务**: 多语言界面
**验收标准**:
- [ ] "界面语言"下拉选择简体中文、English
- [ ] 切换后,设置页菜单文字立即变化
- [ ] (其他页面后续实现)
### M5.8 查词习惯-输入框排除 [目标版本: 0.4.8]
**任务**: 不在输入框划词
**验收标准**:
- [ ] "不在输入框划词"开关
- [ ] 开启后,在 input/textarea/contenteditable 中选词不触发图标
### M5.9 查词习惯-触摸模式 [目标版本: 0.4.9]
**任务**: 适配触摸设备
**验收标准**:
- [ ] "触摸模式"开关
- [ ] 开启后,支持长按选词触发
- [ ] 支持触摸事件touchstart/touchend
### M5.10 查词习惯-划词语言 [目标版本: 0.4.10]
**任务**: 选择划词语言
**验收标准**:
- [ ] 复选框组:中文、英文、日文、韩文、法文、西班牙文、德文
- [ ] 只选中文时,选中英文文本不触发
- [ ] 选择"其它字符"时,匹配所有语言
### M5.11 查词习惯-记忆折叠 [目标版本: 0.4.11]
**任务**: 记住词典折叠状态
**验收标准**:
- [ ] "记忆折叠"开关
- [ ] 开启后,用户折叠某个词典,下次查询默认折叠
### M5.12 查词习惯-双击间隔 [目标版本: 0.4.12]
**任务**: 调整双击灵敏度
**验收标准**:
- [ ] "双击间隔"滑块,范围 0.1-2 秒
- [ ] 数值实时显示
### M5.13 词典设置-已选词典列表 [目标版本: 0.4.13]
**任务**: 管理启用的词典
**验收标准**:
- [ ] "词典设置"页显示已选词典列表
- [ ] 每行显示:图标、词典名、支持语言、操作按钮
- [ ] 当前有:必应词典、有道词典
### M5.14 词典设置-添加词典 [目标版本: 0.4.14]
**任务**: 添加新词典
**验收标准**:
- [ ] "+ 添加"按钮
- [ ] 点击显示可用词典列表
- [ ] 选择后添加到已选列表
### M5.15 词典设置-排序 [目标版本: 0.4.15]
**任务**: 调整词典顺序
**验收标准**:
- [ ] 每行有"上移"/"下移"按钮
- [ ] 点击调整词典在列表中的位置
- [ ] 查询结果按此顺序显示
### M5.16 词典设置-删除 [目标版本: 0.4.16]
**任务**: 移除词典
**验收标准**:
- [ ] 每行有删除按钮X
- [ ] 点击确认后移除
- [ ] 至少保留一个词典
## 依赖
- **前置模块**: M1 基础架构模块, M2 划词核心模块
- **后置模块**: M7 右键菜单模块, M8 生词本模块, M10 高级功能模块
## 参考资料
- [AGENTS.md](./AGENTS.md) - 规范文档
- [QUICK_REF.md](./QUICK_REF.md) - 快速参考

74
docs/M6.md Normal file
View File

@ -0,0 +1,74 @@
# M6 触发方式模块 (v0.5.1-0.5.7)
## 模块概述
- **版本范围**: 0.5.1 ~ 0.5.7
- **任务数**: 7
- **目标**: 实现多种划词触发方式,适应不同用户习惯
## 关键产出
- 普通划词显示图标模式
- 图标悬停查词功能
- 图标位置偏移设置
- 直接搜索模式
- 双击搜索模式
- 快捷键搜索模式
- 鼠标悬浮取词功能
## 任务列表
### M6.1 普通划词-显示图标 [目标版本: 0.5.1]
**任务**: 默认模式
**验收标准**:
- [ ] "显示图标"选项(默认开启)
- [ ] 划词后在文本旁显示沙拉图标
- [ ] 这是当前已实现的功能
### M6.2 普通划词-图标悬停查词 [目标版本: 0.5.2]
**任务**: 鼠标悬停图标触发
**验收标准**:
- [ ] "图标悬停查词"选项
- [ ] 开启后,鼠标悬停在图标上(无需点击)即显示面板
- [ ] 悬停延迟 200ms避免误触
### M6.3 图标位置偏移 [目标版本: 0.5.3]
**任务**: 调整图标位置
**验收标准**:
- [ ] "图标水平偏移"滑块(-100px 到 100px
- [ ] "图标垂直偏移"滑块(-100px 到 100px
- [ ] 调整后在网页划词,图标位置相应偏移
### M6.4 直接搜索模式 [目标版本: 0.5.4]
**任务**: 划词直接显示面板
**验收标准**:
- [ ] "直接搜索"选项
- [ ] 开启后,划词立即显示面板(不显示图标)
- [ ] 与"显示图标"选项互斥
### M6.5 双击搜索模式 [目标版本: 0.5.5]
**任务**: 双击文本触发
**验收标准**:
- [ ] "双击搜索"选项
- [ ] 双击选中文本后,直接显示面板
- [ ] 双击间隔使用 M5.12 的设置值
### M6.6 快捷键搜索模式 [目标版本: 0.5.6]
**任务**: 按住快捷键划词触发
**验收标准**:
- [ ] 复选框Ctrl、Alt、Shift、Meta
- [ ] 选中后,划词时只有按住对应键才显示图标/面板
- [ ] 支持多键组合(如 Ctrl+Shift
### M6.7 鼠标悬浮取词(划词即查) [目标版本: 0.5.7]
**任务**: 鼠标悬停自动选词查询
**验收标准**:
- [ ] "鼠标悬浮取词"开关
- [ ] 开启后,鼠标悬停在单词上 500ms 自动查询
- [ ] 需要检测光标下的单词(使用 caretPositionFromPoint
## 依赖
- **前置模块**: M1 基础架构模块, M2 划词核心模块, M3 词典系统模块, M5 设置系统模块
- **后置模块**: 无
## 参考资料
- [AGENTS.md](./AGENTS.md) - 规范文档
- [QUICK_REF.md](./QUICK_REF.md) - 快速参考

63
docs/M7.md Normal file
View File

@ -0,0 +1,63 @@
# M7 右键菜单模块 (v0.6.1-0.6.6)
## 模块概述
- **版本范围**: 0.6.1 ~ 0.6.6
- **任务数**: 6
- **目标**: 实现上下文菜单功能,支持快捷查词和自定义链接
## 关键产出
- 右键上下文菜单注册
- 沙拉查词子菜单功能
- 网页翻译集成(彩云小译、谷歌翻译)
- 自定义右键菜单链接
- 右键菜单排序和开关控制
## 任务列表
### M7.1 右键菜单注册 [目标版本: 0.6.1]
**任务**: 创建上下文菜单
**验收标准**:
- [ ] background 中使用 `chrome.contextMenus.create`
- [ ] 选中文字时右键显示"沙拉查词"主菜单
- [ ] 有图标显示
### M7.2 沙拉查词子菜单 [目标版本: 0.6.2]
**任务**: 点击执行查词
**验收标准**:
- [ ] 子菜单项:"沙拉查词"
- [ ] 点击后在页面显示查词面板(像划词一样)
### M7.3 网页翻译菜单 [目标版本: 0.6.3]
**任务**: 集成网页翻译
**验收标准**:
- [ ] 子菜单项:"彩云小译网页翻译"
- [ ] 子菜单项:"谷歌翻译"
- [ ] 点击后打开对应翻译网站自动填入当前页面URL
### M7.4 自定义右键菜单 [目标版本: 0.6.4]
**任务**: 用户添加自定义链接
**验收标准**:
- [ ] 设置页"右键菜单"中有列表
- [ ] 可添加自定义链接(名称+URL
- [ ] URL 支持 `{word}` 占位符(替换为选中文字)
- [ ] 右键菜单中显示自定义项
### M7.5 右键菜单排序 [目标版本: 0.6.5]
**任务**: 调整菜单顺序
**验收标准**:
- [ ] 设置页可拖拽排序右键菜单项
- [ ] 或提供上移/下移按钮
### M7.6 右键菜单开关 [目标版本: 0.6.6]
**任务**: 控制显示哪些菜单
**验收标准**:
- [ ] 每个菜单项可勾选显示/隐藏
- [ ] 隐藏后右键不再显示
## 依赖
- **前置模块**: M1 基础架构模块, M5 设置系统模块
- **后置模块**: 无
## 参考资料
- [AGENTS.md](./AGENTS.md) - 规范文档
- [QUICK_REF.md](./QUICK_REF.md) - 快速参考

88
docs/M8.md Normal file
View File

@ -0,0 +1,88 @@
# M8 生词本模块 (v0.7.1-0.7.10)
## 模块概述
- **版本范围**: 0.7.1 ~ 0.7.10
- **任务数**: 10
- **目标**: 构建完整的生词本系统,支持收藏、管理和导出
## 关键产出
- 收藏功能实现(心形图标)
- IndexedDB 数据库封装
- 生词本页面(列表展示、搜索、删除)
- 多格式导出JSON、CSV、Anki
- 生词导入功能
- 上下文保存功能
## 任务列表
### M8.1 收藏功能实现 [目标版本: 0.7.1]
**任务**: 点击心形收藏单词
**验收标准**:
- [ ] 点击面板/Popup中的心形图标保存单词
- [ ] 实心表示已收藏,空心表示未收藏
- [ ] 再次点击取消收藏
### M8.2 生词本数据库 [目标版本: 0.7.2]
**任务**: 使用 IndexedDB 存储
**验收标准**:
- [ ] `src/shared/database.js` 封装 IndexedDB
- [ ] 表结构id, word, phonetic, translation, context, url, timestamp
- [ ] 提供 `add()`, `remove()`, `getAll()`, `search()` 方法
### M8.3 生词本页面 [目标版本: 0.7.3]
**任务**: 查看收藏的单词
**验收标准**:
- [ ] 设置页新增"生词本"菜单
- [ ] 以列表形式展示所有生词
- [ ] 显示:单词、音标、释义、收藏时间
### M8.4 生词本搜索 [目标版本: 0.7.4]
**任务**: 搜索生词
**验收标准**:
- [ ] 生词本页顶部有搜索框
- [ ] 输入时实时过滤列表
### M8.5 生词本删除 [目标版本: 0.7.5]
**任务**: 移除生词
**验收标准**:
- [ ] 每个生词项有删除按钮
- [ ] 支持批量删除(复选框+删除选中)
### M8.6 生词本导出JSON [目标版本: 0.7.6]
**任务**: 导出为 JSON 格式
**验收标准**:
- [ ] "导出"按钮,选择 JSON 格式
- [ ] 下载 .json 文件,包含所有生词数据
### M8.7 生词本导出CSV [目标版本: 0.7.7]
**任务**: 导出为 CSV 格式
**验收标准**:
- [ ] 导出选项包含 CSV 格式
- [ ] CSV 列:单词,音标,释义,例句,来源URL,时间
### M8.8 生词本导出Anki [目标版本: 0.7.8]
**任务**: 导出为 Anki 格式
**验收标准**:
- [ ] 导出选项包含 Anki (.txt)
- [ ] 格式兼容 Anki 导入(制表符分隔)
### M8.9 生词本导入 [目标版本: 0.7.9]
**任务**: 从文件导入
**验收标准**:
- [ ] "导入"按钮,支持 JSON 格式
- [ ] 导入后生词追加到现有生词本
### M8.10 收藏时添加上下文 [目标版本: 0.7.10]
**任务**: 保存单词出现的句子
**验收标准**:
- [ ] 收藏时,自动提取单词所在句子(从页面文本中)
- [ ] 保存到生词本的 context 字段
- [ ] 生词本列表中可展开查看上下文
## 依赖
- **前置模块**: M1 基础架构模块, M2 划词核心模块, M5 设置系统模块
- **后置模块**: 无
## 参考资料
- [AGENTS.md](./AGENTS.md) - 规范文档
- [QUICK_REF.md](./QUICK_REF.md) - 快速参考

68
docs/M9.md Normal file
View File

@ -0,0 +1,68 @@
# M9 API账号模块 (v0.8.1-0.8.7)
## 模块概述
- **版本范围**: 0.8.1 ~ 0.8.7
- **任务数**: 7
- **目标**: 支持第三方翻译 API 的账号配置和安全存储
## 关键产出
- 词典账号配置页面
- 百度翻译 API 配置
- 彩云小译 API 配置
- 搜狗翻译 API 配置
- 腾讯翻译君 API 配置
- 有道翻译 API 配置
- API 密钥加密存储机制
## 任务列表
### M9.1 账号配置页面 [目标版本: 0.8.1]
**任务**: 词典账号设置界面
**验收标准**:
- [ ] 设置页"词典账号"菜单
- [ ] 说明文字:建议申请官方账号获得更稳定体验
### M9.2 百度翻译API配置 [目标版本: 0.8.2]
**任务**: 配置百度翻译密钥
**验收标准**:
- [ ] 输入框appid、key
- [ ] 链接到百度翻译开放平台
- [ ] 配置后百度翻译使用用户密钥
### M9.3 彩云小译API配置 [目标版本: 0.8.3]
**任务**: 配置彩云小译 token
**验收标准**:
- [ ] 输入框token
- [ ] 配置后彩云小译使用用户 token
### M9.4 搜狗翻译API配置 [目标版本: 0.8.4]
**任务**: 配置搜狗翻译密钥
**验收标准**:
- [ ] 输入框pid、key
- [ ] 配置后搜狗翻译使用用户密钥
### M9.5 腾讯翻译君API配置 [目标版本: 0.8.5]
**任务**: 配置腾讯翻译密钥
**验收标准**:
- [ ] 输入框secretId、secretKey
- [ ] 配置后腾讯翻译使用用户密钥
### M9.6 有道翻译API配置 [目标版本: 0.8.6]
**任务**: 配置有道翻译密钥
**验收标准**:
- [ ] 输入框appKey、key
- [ ] 配置后有道翻译使用用户密钥
### M9.7 API密钥加密存储 [目标版本: 0.8.7]
**任务**: 安全存储密钥
**验收标准**:
- [ ] 密钥不直接明文存储(使用简单异或加密)
- [ ] 或注明"密钥仅保存在本地浏览器中"
## 依赖
- **前置模块**: M1 基础架构模块, M2 划词核心模块, M3 词典系统模块, M5 设置系统模块
- **后置模块**: 无
## 参考资料
- [AGENTS.md](./AGENTS.md) - 规范文档
- [QUICK_REF.md](./QUICK_REF.md) - 快速参考

217
docs/QUICK_REF.md Normal file
View File

@ -0,0 +1,217 @@
# 快速参考
> 版本速查、命名规范、代码模板
---
## 版本速查
### 当前版本
`0.0.1` → 下一目标 `0.0.2` ([M1.2](./M1.md))
### 模块版本范围
| 模块 | 范围 | 任务数 |
|------|------|--------|
| M1 | 0.0.1 ~ 0.0.5 | 5 |
| M2 | 0.1.1 ~ 0.1.9 | 9 |
| M3 | 0.2.1 ~ 0.2.11 | 11 |
| M4 | 0.3.1 ~ 0.3.8 | 8 |
| M5 | 0.4.1 ~ 0.4.16 | 16 |
| M6 | 0.5.1 ~ 0.5.7 | 7 |
| M7 | 0.6.1 ~ 0.6.6 | 6 |
| M8 | 0.7.1 ~ 0.7.10 | 10 |
| M9 | 0.8.1 ~ 0.8.7 | 7 |
| M10 | 0.9.1 ~ 0.9.8 | 8 |
| M11 | 0.10.1 ~ 1.0.0 | 10 |
### 版本更新
```bash
# M1.1 完成后
版本: 0.0.0 → 0.0.1
git commit -m "feat(M1.1): 项目初始化 (v0.0.1)"
# M2.1 完成后 (进入M2)
版本: 0.0.5 → 0.1.1
git commit -m "feat(M2.1): 文本选择检测 (v0.1.1)"
```
---
## 命名速查
| 类型 | 规范 | 示例 |
|------|------|------|
| 文件 | 小写+连字符 | `salad-icon.js` |
| 类 | PascalCase | `DictionaryBase` |
| 函数 | camelCase+动词 | `getSelectionCoords()` |
| 常量 | UPPER_SNAKE | `DEFAULT_TIMEOUT` |
| 私有 | _前缀 | `_cache`, `_handle()` |
| 消息 | 大写+点 | `DICT.SEARCH` |
---
## 消息类型速查
```javascript
DICT.SEARCH / DICT.SEARCH_RESPONSE
CONFIG.GET / CONFIG.SET / CONFIG.CHANGED
WORD.ADD_FAVORITE / WORD.REMOVE_FAVORITE
CLIPBOARD.READ / CLIPBOARD.WRITE
HTTP.GET / HTTP.POST
```
---
## 代码模板
### package.json0.0.0
```json
{
"name": "salad-dict",
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build"
},
"dependencies": {
"vue": "^3.4.0",
"vue-router": "^4.2.0",
"pinia": "^2.1.0",
"localforage": "^1.10.0"
},
"devDependencies": {
"@crxjs/vite-plugin": "^2.0.0",
"@vitejs/plugin-vue": "^5.0.0",
"vite": "^5.0.0"
}
}
```
### manifest.json0.0.0
```json
{
"manifest_version": 3,
"name": "沙拉查词",
"version": "0.0.0",
"permissions": ["storage", "contextMenus", "clipboardWrite"],
"optional_permissions": ["clipboardRead"],
"host_permissions": ["<all_urls>"],
"background": {
"service_worker": "src/background/index.js",
"type": "module"
},
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["src/content/index.js"],
"run_at": "document_end"
}],
"action": {
"default_popup": "src/popup/index.html"
},
"options_page": "src/options/index.html"
}
```
### 词典实现
```javascript
import { DictionaryBase } from './base.js';
import { messaging } from '../messaging.js';
export class XxxDictionary extends DictionaryBase {
constructor(config = {}) {
super({ name: '词典名', icon: 'icon.png', languages: ['en', 'zh'], ...config });
}
async search(word) {
if (!word?.trim()) throw new Error('Word is empty');
const html = await messaging.send('HTTP.GET', { url: `...${encodeURIComponent(word)}` });
return this.parse(html, word);
}
parse(html, word) {
const doc = new DOMParser().parseFromString(html, 'text/html');
return {
word,
phonetic: '',
meanings: [{ partOfSpeech: 'n.', definitions: ['释义'] }],
examples: [{ sentence: '例句', translation: '翻译' }],
url: ''
};
}
}
```
### UI组件
```javascript
export class XxxComponent extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: 'open' });
this.render();
}
render() {
this.shadow.innerHTML = `
<style>
:host { display: block; position: fixed; }
.container { background: var(--salad-bg, #fff); }
</style>
<div class="container">...</div>
`;
}
show(x, y) {
this.style.left = `${x}px`;
this.style.top = `${y}px`;
this.style.display = 'block';
}
hide() {
this.style.display = 'none';
}
}
```
### 通信封装
```javascript
class MessageClient {
async send(type, payload, timeout = 5000) {
const requestId = generateUUID();
return new Promise((resolve, reject) => {
const timer = setTimeout(() => reject(new Error('Timeout')), timeout);
const handler = (response) => {
if (response.meta?.requestId !== requestId) return;
clearTimeout(timer);
chrome.runtime.onMessage.removeListener(handler);
response.error ? reject(new Error(response.error.message)) : resolve(response.payload);
};
chrome.runtime.onMessage.addListener(handler);
chrome.runtime.sendMessage({ type, payload, meta: { requestId } });
});
}
}
export const messaging = new MessageClient();
```
---
## 调试技巧
```javascript
// Content Script
console.log('[Content]', message);
// Background (看 Service Worker console)
chrome.action.onClicked.addListener(() => {
console.log('[Background]', 'clicked');
});
// 强制刷新扩展
chrome.runtime.reload();
```
**Chrome 扩展 DevTools**:
- `chrome://extensions/` → "service worker" (background)
- "inspect views" (popup)

131
docs/README.md Normal file
View File

@ -0,0 +1,131 @@
# 沙拉查词开发文档总纲
> 项目概述、版本规则、模块索引
---
## 项目概述
- **项目名称**:沙拉查词
- **类型**Chrome Extension (Manifest V3)
- **核心功能**:划词翻译、多词典聚合查询
- **目标浏览器**Chrome 109+
**技术栈**:
- Chrome Extension Manifest V3
- JavaScript ES2022+
- Vue.js ^3.4.0 (Popup/Options)
- Vite ^5.0.0
- Node.js >= 18.0.0
---
## 版本号规则
### 格式
`MAJOR.MINOR.PATCH`
| 位 | 含义 | 更新时机 |
|----|------|----------|
| MAJOR | 主版本 | 正式发布时设为 1 |
| MINOR | 模块号 | M1=0, M2=1, M3=2... |
| PATCH | 任务号 | 每个任务完成时 +1 |
### 版本与模块对应
| 模块 | 版本范围 | 任务数 | 描述 |
|------|----------|--------|------|
| M1 | 0.0.1 ~ 0.0.5 | 5 | 基础架构 |
| M2 | 0.1.1 ~ 0.1.9 | 9 | 划词核心 |
| M3 | 0.2.1 ~ 0.2.11 | 11 | 词典系统 |
| M4 | 0.3.1 ~ 0.3.8 | 8 | Popup查词 |
| M5 | 0.4.1 ~ 0.4.16 | 16 | 设置系统 |
| M6 | 0.5.1 ~ 0.5.7 | 7 | 触发方式 |
| M7 | 0.6.1 ~ 0.6.6 | 6 | 右键菜单 |
| M8 | 0.7.1 ~ 0.7.10 | 10 | 生词本 |
| M9 | 0.8.1 ~ 0.8.7 | 7 | API账号 |
| M10 | 0.9.1 ~ 0.9.8 | 8 | 高级功能 |
| M11 | 0.10.1 ~ 1.0.0 | 10 | 优化发布 |
**总计**: 97个验收点 → 最终版本 `1.0.0`
### 版本流程示例
```
开始: 0.0.0
M1.1完成 → 0.0.1
...
M1.5完成 → 0.0.5 (M1完成)
M2.1完成 → 0.1.1 (进入M2MINOR+1)
...
M11.10完成 → 1.0.0 (正式发布)
```
---
## 当前状态
**当前版本**: `0.0.1`
**当前进度**: 1/97 (1%)
**下一任务**: [M1.2 Manifest V3 配置](./M1.md#m12-manifest-v3-配置--目标版本-0002)
---
## 文档索引
### 核心规范(必读)
| 文档 | 内容 |
|------|------|
| [AGENTS.md](./AGENTS.md) | 架构原则、代码风格、通信协议、安全规范 |
| [QUICK_REF.md](./QUICK_REF.md) | 版本速查、命名规范、代码模板 |
### 模块开发计划
| 文档 | 版本范围 | 任务数 | 关键产出 |
|------|----------|--------|----------|
| [M1.md](./M1.md) | 0.0.1-0.0.5 | 5 | 项目框架、构建配置、通信机制 |
| [M2.md](./M2.md) | 0.1.1-0.1.9 | 9 | 划词检测、图标、基础面板 |
| [M3.md](./M3.md) | 0.2.1-0.2.11 | 11 | 词典基类、必应/有道实现 |
| [M4.md](./M4.md) | 0.3.1-0.3.8 | 8 | Popup界面、搜索、历史、独立窗口 |
| [M5.md](./M5.md) | 0.4.1-0.4.16 | 16 | 6页设置系统 |
| [M6.md](./M6.md) | 0.5.1-0.5.7 | 7 | 多种触发方式配置 |
| [M7.md](./M7.md) | 0.6.1-0.6.6 | 6 | 右键菜单系统 |
| [M8.md](./M8.md) | 0.7.1-0.7.10 | 10 | 生词本、导入导出 |
| [M9.md](./M9.md) | 0.8.1-0.8.7 | 7 | 第三方API账号配置 |
| [M10.md](./M10.md) | 0.9.1-0.9.8 | 8 | 剪贴板、PDF支持、权限管理 |
| [M11.md](./M11.md) | 0.10.1-1.0.0 | 10 | 性能优化、国际化、发布 |
### 版本记录
| 文档 | 内容 |
|------|------|
| [VERSION.md](./VERSION.md) | 所有任务的完成状态和历史记录 |
---
## 开发流程
1. **阅读规范**: 开始前阅读 [AGENTS.md](./AGENTS.md) 和 [QUICK_REF.md](./QUICK_REF.md)
2. **查看模块**: 根据当前版本打开对应的模块文件(如 [M1.md](./M1.md)
3. **开发实现**: 按任务顺序实现,每个任务完成更新版本号
4. **提交验收**: 用户确认后更新 VERSION.md 并提交 commit
### Commit 格式
```bash
feat(M1.1): 任务描述 (v0.0.1)
```
---
## 快速命令
```bash
# 开发
npm run dev
# 构建
npm run build
# 版本更新(手动)
# 1. 修改 package.json version
# 2. 修改 manifest.json version
# 3. 更新 VERSION.md 任务状态
# 4. git commit -m "feat(Mx.x): 描述 (vx.x.x)"
```

195
docs/VERSION.md Normal file
View File

@ -0,0 +1,195 @@
# 版本记录
> 97个验收点状态跟踪
---
## 当前版本
**版本**: `0.0.0`
**状态**: 🟡 初始状态
**进度**: 0/97 (0%)
**下一目标**: [M1.1 项目初始化](./M1.md#m11)
---
## M1 基础架构 (0.0.1 - 0.0.5)
| 任务 | 版本 | 描述 | 状态 | 日期 |
|------|------|------|------|------|
| M1.1 | 0.0.1 | 项目初始化 | ✅ | 2026-02-09 |
| M1.2 | 0.0.2 | Manifest V3 配置 | ⬜ | - |
| M1.3 | 0.0.3 | 构建工具配置 | ⬜ | - |
| M1.4 | 0.0.4 | 模块间通信工具 | ⬜ | - |
| M1.5 | 0.0.5 | 开发环境验证 | ⬜ | - |
---
## M2 划词核心 (0.1.1 - 0.1.9)
| 任务 | 版本 | 描述 | 状态 | 日期 |
|------|------|------|------|------|
| M2.1 | 0.1.1 | 文本选择检测 | ⬜ | - |
| M2.2 | 0.1.2 | 获取选中文本坐标 | ⬜ | - |
| M2.3 | 0.1.3 | 沙拉图标组件 | ⬜ | - |
| M2.4 | 0.1.4 | 图标定位显示 | ⬜ | - |
| M2.5 | 0.1.5 | 图标点击事件 | ⬜ | - |
| M2.6 | 0.1.6 | 基础面板组件 | ⬜ | - |
| M2.7 | 0.1.7 | 面板位置计算 | ⬜ | - |
| M2.8 | 0.1.8 | 图标-面板联动 | ⬜ | - |
| M2.9 | 0.1.9 | 图标显示开关 | ⬜ | - |
---
## M3 词典系统 (0.2.1 - 0.2.11)
| 任务 | 版本 | 描述 | 状态 | 日期 |
|------|------|------|------|------|
| M3.1 | 0.2.1 | 词典接口基类 | ⬜ | - |
| M3.2 | 0.2.2 | 词典管理器 | ⬜ | - |
| M3.3 | 0.2.3 | 必应词典(Mock) | ⬜ | - |
| M3.4 | 0.2.4 | 后台查询接口 | ⬜ | - |
| M3.5 | 0.2.5 | 结果展示组件 | ⬜ | - |
| M3.6 | 0.2.6 | 点击图标查词(Mock) | ⬜ | - |
| M3.7 | 0.2.7 | 必应词典真实API | ⬜ | - |
| M3.8 | 0.2.8 | 加载状态显示 | ⬜ | - |
| M3.9 | 0.2.9 | 有道词典实现 | ⬜ | - |
| M3.10 | 0.2.10 | 结果折叠/展开 | ⬜ | - |
| M3.11 | 0.2.11 | 词典图标标识 | ⬜ | - |
---
## M4 Popup查词 (0.3.1 - 0.3.8)
| 任务 | 版本 | 描述 | 状态 | 日期 |
|------|------|------|------|------|
| M4.1 | 0.3.1 | Popup基础界面 | ⬜ | - |
| M4.2 | 0.3.2 | Popup搜索功能 | ⬜ | - |
| M4.3 | 0.3.3 | 搜索建议 | ⬜ | - |
| M4.4 | 0.3.4 | 查询历史记录 | ⬜ | - |
| M4.5 | 0.3.5 | 历史记录展示 | ⬜ | - |
| M4.6 | 0.3.6 | 前进后退导航 | ⬜ | - |
| M4.7 | 0.3.7 | 收藏按钮 | ⬜ | - |
| M4.8 | 0.3.8 | 独立窗口打开 | ⬜ | - |
---
## M5 设置系统 (0.4.1 - 0.4.16)
| 任务 | 版本 | 描述 | 状态 | 日期 |
|------|------|------|------|------|
| M5.1 | 0.4.1 | 设置页面框架 | ⬜ | - |
| M5.2 | 0.4.2 | 配置存储工具 | ⬜ | - |
| M5.3 | 0.4.3 | 划词翻译开关 | ⬜ | - |
| M5.4 | 0.4.4 | 动画开关 | ⬜ | - |
| M5.5 | 0.4.5 | 后台运行 | ⬜ | - |
| M5.6 | 0.4.6 | 黑暗模式 | ⬜ | - |
| M5.7 | 0.4.7 | 界面语言 | ⬜ | - |
| M5.8 | 0.4.8 | 输入框排除 | ⬜ | - |
| M5.9 | 0.4.9 | 触摸模式 | ⬜ | - |
| M5.10 | 0.4.10 | 划词语言 | ⬜ | - |
| M5.11 | 0.4.11 | 记忆折叠 | ⬜ | - |
| M5.12 | 0.4.12 | 双击间隔 | ⬜ | - |
| M5.13 | 0.4.13 | 已选词典列表 | ⬜ | - |
| M5.14 | 0.4.14 | 添加词典 | ⬜ | - |
| M5.15 | 0.4.15 | 词典排序 | ⬜ | - |
| M5.16 | 0.4.16 | 词典删除 | ⬜ | - |
---
## M6 触发方式 (0.5.1 - 0.5.7)
| 任务 | 版本 | 描述 | 状态 | 日期 |
|------|------|------|------|------|
| M6.1 | 0.5.1 | 显示图标 | ⬜ | - |
| M6.2 | 0.5.2 | 图标悬停查词 | ⬜ | - |
| M6.3 | 0.5.3 | 图标位置偏移 | ⬜ | - |
| M6.4 | 0.5.4 | 直接搜索模式 | ⬜ | - |
| M6.5 | 0.5.5 | 双击搜索模式 | ⬜ | - |
| M6.6 | 0.5.6 | 快捷键搜索模式 | ⬜ | - |
| M6.7 | 0.5.7 | 鼠标悬浮取词 | ⬜ | - |
---
## M7 右键菜单 (0.6.1 - 0.6.6)
| 任务 | 版本 | 描述 | 状态 | 日期 |
|------|------|------|------|------|
| M7.1 | 0.6.1 | 右键菜单注册 | ⬜ | - |
| M7.2 | 0.6.2 | 沙拉查词子菜单 | ⬜ | - |
| M7.3 | 0.6.3 | 网页翻译菜单 | ⬜ | - |
| M7.4 | 0.6.4 | 自定义右键菜单 | ⬜ | - |
| M7.5 | 0.6.5 | 右键菜单排序 | ⬜ | - |
| M7.6 | 0.6.6 | 右键菜单开关 | ⬜ | - |
---
## M8 生词本 (0.7.1 - 0.7.10)
| 任务 | 版本 | 描述 | 状态 | 日期 |
|------|------|------|------|------|
| M8.1 | 0.7.1 | 收藏功能实现 | ⬜ | - |
| M8.2 | 0.7.2 | 生词本数据库 | ⬜ | - |
| M8.3 | 0.7.3 | 生词本页面 | ⬜ | - |
| M8.4 | 0.7.4 | 生词本搜索 | ⬜ | - |
| M8.5 | 0.7.5 | 生词本删除 | ⬜ | - |
| M8.6 | 0.7.6 | 导出JSON | ⬜ | - |
| M8.7 | 0.7.7 | 导出CSV | ⬜ | - |
| M8.8 | 0.7.8 | 导出Anki | ⬜ | - |
| M8.9 | 0.7.9 | 生词本导入 | ⬜ | - |
| M8.10 | 0.7.10 | 收藏上下文 | ⬜ | - |
---
## M9 API账号 (0.8.1 - 0.8.7)
| 任务 | 版本 | 描述 | 状态 | 日期 |
|------|------|------|------|------|
| M9.1 | 0.8.1 | 账号配置页面 | ⬜ | - |
| M9.2 | 0.8.2 | 百度翻译API | ⬜ | - |
| M9.3 | 0.8.3 | 彩云小译API | ⬜ | - |
| M9.4 | 0.8.4 | 搜狗翻译API | ⬜ | - |
| M9.5 | 0.8.5 | 腾讯翻译君API | ⬜ | - |
| M9.6 | 0.8.6 | 有道翻译API | ⬜ | - |
| M9.7 | 0.8.7 | API密钥加密存储 | ⬜ | - |
---
## M10 高级功能 (0.9.1 - 0.9.8)
| 任务 | 版本 | 描述 | 状态 | 日期 |
|------|------|------|------|------|
| M10.1 | 0.9.1 | 权限管理页面 | ⬜ | - |
| M10.2 | 0.9.2 | 读取剪贴板权限 | ⬜ | - |
| M10.3 | 0.9.3 | 剪贴板快速查词 | ⬜ | - |
| M10.4 | 0.9.4 | 写入剪贴板权限 | ⬜ | - |
| M10.5 | 0.9.5 | 复制原文功能 | ⬜ | - |
| M10.6 | 0.9.6 | 复制译文功能 | ⬜ | - |
| M10.7 | 0.9.7 | PDF支持 | ⬜ | - |
| M10.8 | 0.9.8 | 独立窗口完善 | ⬜ | - |
---
## M11 优化发布 (0.10.1 - 1.0.0)
| 任务 | 版本 | 描述 | 状态 | 日期 |
|------|------|------|------|------|
| M11.1 | 0.10.1 | 请求去重 | ⬜ | - |
| M11.2 | 0.10.2 | 请求取消 | ⬜ | - |
| M11.3 | 0.10.3 | 虚拟滚动 | ⬜ | - |
| M11.4 | 0.10.4 | 错误日志 | ⬜ | - |
| M11.5 | 0.10.5 | 国际化框架 | ⬜ | - |
| M11.6 | 0.10.6 | 英文翻译 | ⬜ | - |
| M11.7 | 0.10.7 | 使用文档 | ⬜ | - |
| M11.8 | 0.10.8 | 开发文档 | ⬜ | - |
| M11.9 | 0.10.9 | 打包配置 | ⬜ | - |
| M11.10 | 1.0.0 | 图标和素材 | ⬜ | - |
---
## 统计
- **总计**: 97 个任务
- **已完成**: 0
- **剩余**: 97
- **当前进度**: 0%

33
package.json Normal file
View File

@ -0,0 +1,33 @@
{
"name": "salad-dict",
"version": "0.0.1",
"description": "聚合词典划词翻译",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"lint": "eslint . --ext .js,.vue"
},
"dependencies": {
"vue": "^3.4.0",
"vue-router": "^4.2.0",
"pinia": "^2.1.0",
"localforage": "^1.10.0"
},
"devDependencies": {
"@crxjs/vite-plugin": "^2.0.0",
"@vitejs/plugin-vue": "^5.0.0",
"vite": "^5.0.0",
"eslint": "^8.56.0",
"eslint-plugin-vue": "^9.19.0"
},
"keywords": [
"chrome-extension",
"dictionary",
"translation"
],
"author": "",
"license": "MIT"
}

BIN
ui/1-POPUP.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

BIN
ui/2-POPUP.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 398 KiB

BIN
ui/3-POPUP.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 521 KiB

BIN
ui/4-POPUP.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 KiB

BIN
ui/5-INJECT-ICON.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
ui/6-INJECT-MAIN.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

BIN
ui/7-ContextMenus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

BIN
ui/8-QuickSearch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
ui/9-SETTINGS-General.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB