# 沙拉查词项目规范 > 架构原则、代码风格、通信协议、安全规范 --- ## 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 = `
...
`; ``` **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)