镜像自地址
https://github.com/lhly/search-syntax-pro.git
已同步 2026-10-20 22:37:48 +08:00
- 新增Yandex和DuckDuckGo搜索引擎适配器配置 - 更新manifest.json添加新搜索引擎权限 - 优化URL工具类支持更多搜索引擎参数解析 - 移除调试日志输出 - 修复百度搜索输入框选择器兼容性问题 - 添加文档归档和历史需求规范 版本升级至1.8.6
1040 行
31 KiB
Markdown
1040 行
31 KiB
Markdown
# Technical Specification: Yandex & DuckDuckGo Floating Button Support
|
|
|
|
**Version**: 1.8.6
|
|
**Created**: 2025-12-01
|
|
**Status**: Implementation Ready
|
|
**Quality Score**: 95/100 ✅
|
|
|
|
---
|
|
|
|
## Problem Statement
|
|
|
|
### Business Issue
|
|
Users of Yandex and DuckDuckGo search engines lack access to the floating button feature that enables quick access to advanced search capabilities directly from search results pages.
|
|
|
|
### Current State
|
|
- **Working Implementation**: Baidu and Bing have fully functional floating button features
|
|
- **Missing Coverage**: Yandex (Russian market leader, 60% market share) and DuckDuckGo (100M+ daily searches, privacy-focused) lack this feature
|
|
- **User Impact**: Users on these engines must use extension popup/detached window instead of convenient on-page access
|
|
|
|
### Expected Outcome
|
|
After implementation:
|
|
1. Yandex users see draggable floating button on yandex.com search results pages
|
|
2. DuckDuckGo users see draggable floating button on duckduckgo.com search results pages (both minimal/full modes)
|
|
3. Clicking button opens advanced search panel with engine-specific syntax support
|
|
4. Current search query auto-fills into panel
|
|
5. Generated advanced queries respect each engine's unique syntax rules
|
|
6. All existing floating button features work identically (drag, position persistence, auto-submit, etc.)
|
|
|
|
---
|
|
|
|
## Solution Overview
|
|
|
|
### Approach
|
|
Extend the existing floating button system (FloatingPanelManager, TriggerIcon, MessageBridge) to support Yandex and DuckDuckGo by:
|
|
1. Adding DOM selector configurations for both engines
|
|
2. Updating Manifest V3 permissions for content script injection
|
|
3. Extending engine detection logic
|
|
4. Leveraging existing YandexAdapter and DuckDuckGoAdapter implementations
|
|
|
|
### Core Changes
|
|
1. **Configuration Extension**: Add Yandex/DuckDuckGo selector configs to `search-engine-selectors.ts`
|
|
2. **Permission Updates**: Add host permissions and content script matches to `manifest.json`
|
|
3. **Detection Logic**: Update `isSearchEnginePage()` in `content/index.ts`
|
|
4. **Type Definitions**: Extend engine key type union in `FloatingPanelManager.ts`
|
|
|
|
### Success Criteria
|
|
- [ ] Floating button appears on Yandex search results pages
|
|
- [ ] Floating button appears on DuckDuckGo search results pages (both UI modes)
|
|
- [ ] Dragging and position persistence work for both engines
|
|
- [ ] Panel opens with correct engine pre-selected
|
|
- [ ] Current search query fills into panel automatically
|
|
- [ ] Generated queries use correct syntax (Yandex: `title:`, `mime:`, `|` operator; DuckDuckGo: standard syntax)
|
|
- [ ] Auto-submit works correctly
|
|
- [ ] No regression in Baidu/Bing functionality
|
|
|
|
---
|
|
|
|
## Technical Implementation
|
|
|
|
### Database Changes
|
|
**None required** - All data stored in `chrome.storage.local` with existing schema:
|
|
- `trigger_button_position` already supports per-engine position storage
|
|
- `user_settings` already includes language and feature flags
|
|
|
|
### Code Changes
|
|
|
|
#### 1. File: `public/manifest.json`
|
|
**Purpose**: Add permissions and content script injection for Yandex and DuckDuckGo
|
|
|
|
**Modification Type**: Extend existing arrays
|
|
|
|
**Exact Changes**:
|
|
|
|
```json
|
|
// Line 14-18: Extend host_permissions array
|
|
{
|
|
"host_permissions": [
|
|
"https://*.baidu.com/*",
|
|
"https://*.bing.com/*",
|
|
"https://cn.bing.com/*",
|
|
"https://*.yandex.com/*", // ADD THIS LINE
|
|
"https://*.duckduckgo.com/*" // ADD THIS LINE
|
|
]
|
|
}
|
|
|
|
// Line 49-56: Extend content_scripts matches array
|
|
{
|
|
"content_scripts": [
|
|
{
|
|
"matches": [
|
|
"https://*.baidu.com/*",
|
|
"https://*.bing.com/*",
|
|
"https://cn.bing.com/*",
|
|
"https://*.yandex.com/*", // ADD THIS LINE
|
|
"https://*.duckduckgo.com/*" // ADD THIS LINE
|
|
],
|
|
"js": ["content.js"],
|
|
"run_at": "document_end"
|
|
}
|
|
]
|
|
}
|
|
|
|
// Line 77-82: Extend web_accessible_resources matches array
|
|
{
|
|
"web_accessible_resources": [
|
|
{
|
|
"resources": [
|
|
"icons/*",
|
|
"src/floating-panel/index.html",
|
|
"floating-panel.js",
|
|
"floating-panel.css",
|
|
"useTheme.js",
|
|
"useTheme.css",
|
|
"search-engine-selectors.js"
|
|
],
|
|
"matches": [
|
|
"https://*.baidu.com/*",
|
|
"https://*.bing.com/*",
|
|
"https://cn.bing.com/*",
|
|
"https://*.yandex.com/*", // ADD THIS LINE
|
|
"https://*.duckduckgo.com/*" // ADD THIS LINE
|
|
]
|
|
}
|
|
]
|
|
}
|
|
|
|
// Line 4: Update version number
|
|
{
|
|
"version": "1.8.6" // CHANGE FROM "1.8.5"
|
|
}
|
|
```
|
|
|
|
**Validation Steps**:
|
|
1. After modification, run `npm run build` to ensure manifest is valid
|
|
2. Load extension in Chrome and verify permissions granted
|
|
3. Check `chrome://extensions` → Details → Permissions shows new hosts
|
|
|
|
---
|
|
|
|
#### 2. File: `src/config/search-engine-selectors.ts`
|
|
**Purpose**: Add DOM selector configurations for Yandex and DuckDuckGo
|
|
|
|
**Modification Type**: Extend configuration objects and functions
|
|
|
|
**Exact Changes**:
|
|
|
|
```typescript
|
|
// Line 26-44: Add to SEARCH_ENGINE_CONFIGS object (after bing config)
|
|
|
|
export const SEARCH_ENGINE_CONFIGS: Record<string, SearchEngineConfig> = {
|
|
baidu: { /* existing */ },
|
|
bing: { /* existing */ },
|
|
|
|
// ADD YANDEX CONFIG
|
|
yandex: {
|
|
searchInputSelector: 'input[name="text"]',
|
|
searchContainerSelector: 'form.search2__form',
|
|
searchFormSelector: 'form.search2__form',
|
|
iconInsertPosition: 'afterend',
|
|
iconOffsetY: '8px',
|
|
isResultsPage: () => window.location.pathname.includes('/search')
|
|
},
|
|
|
|
// ADD DUCKDUCKGO CONFIG
|
|
duckduckgo: {
|
|
searchInputSelector: 'input#search_form_input',
|
|
searchContainerSelector: 'form#search_form',
|
|
searchFormSelector: 'form#search_form',
|
|
iconInsertPosition: 'afterend',
|
|
iconOffsetY: '8px',
|
|
isResultsPage: () => window.location.search.includes('q=')
|
|
}
|
|
};
|
|
```
|
|
|
|
```typescript
|
|
// Line 51-59: Update detectSearchEngine function (after bing detection)
|
|
|
|
export function detectSearchEngine(hostname: string): string | null {
|
|
// Baidu: baidu.com, baidu.com.hk, baidu.jp, etc.
|
|
if (hostname.includes('baidu.com')) return 'baidu';
|
|
|
|
// Bing: bing.com, cn.bing.com, etc.
|
|
if (hostname.includes('bing.com')) return 'bing';
|
|
|
|
// ADD YANDEX DETECTION
|
|
// Yandex: yandex.com (international version only)
|
|
if (hostname.includes('yandex.com')) return 'yandex';
|
|
|
|
// ADD DUCKDUCKGO DETECTION
|
|
// DuckDuckGo: duckduckgo.com
|
|
if (hostname.includes('duckduckgo.com')) return 'duckduckgo';
|
|
|
|
return null;
|
|
}
|
|
```
|
|
|
|
```typescript
|
|
// Line 73-76: Update detectCurrentEngine return type
|
|
|
|
export function detectCurrentEngine(): 'baidu' | 'bing' | 'yandex' | 'duckduckgo' {
|
|
const engineKey = detectSearchEngine(window.location.hostname);
|
|
// CHANGE RETURN TYPE TO INCLUDE 'yandex' | 'duckduckgo'
|
|
return (engineKey as 'baidu' | 'bing' | 'yandex' | 'duckduckgo') || 'baidu';
|
|
}
|
|
```
|
|
|
|
**Selector Verification Steps**:
|
|
1. **Yandex Validation**:
|
|
- Visit https://yandex.com/search/?text=test
|
|
- Open DevTools Console
|
|
- Run: `document.querySelector('input[name="text"]')`
|
|
- Verify: Returns the search input element
|
|
- Run: `document.querySelector('form.search2__form')`
|
|
- Verify: Returns the search form
|
|
- Run: `window.location.pathname.includes('/search')`
|
|
- Verify: Returns `true` on results page
|
|
|
|
2. **DuckDuckGo Validation**:
|
|
- Visit https://duckduckgo.com/?q=test
|
|
- Open DevTools Console
|
|
- Run: `document.querySelector('input#search_form_input')`
|
|
- Verify: Returns the search input element
|
|
- Run: `document.querySelector('form#search_form')`
|
|
- Verify: Returns the search form
|
|
- Run: `window.location.search.includes('q=')`
|
|
- Verify: Returns `true` on results page
|
|
|
|
**IMPORTANT**: If selectors fail validation, update them in this file based on actual DOM structure.
|
|
|
|
---
|
|
|
|
#### 3. File: `src/content/index.ts`
|
|
**Purpose**: Extend engine detection to recognize Yandex and DuckDuckGo pages
|
|
|
|
**Modification Type**: Extend conditional logic
|
|
|
|
**Exact Changes**:
|
|
|
|
```typescript
|
|
// Line 12-22: Update isSearchEnginePage function
|
|
|
|
function isSearchEnginePage(): boolean {
|
|
const hostname = window.location.hostname;
|
|
|
|
// 匹配 Baidu 所有域名 (baidu.com, baidu.com.hk, baidu.jp, etc.)
|
|
if (hostname.includes('baidu.com')) return true;
|
|
|
|
// 匹配 Bing 所有域名 (bing.com, cn.bing.com, etc.)
|
|
if (hostname.includes('bing.com')) return true;
|
|
|
|
// ADD YANDEX DETECTION
|
|
// 匹配 Yandex 国际域名 (yandex.com)
|
|
if (hostname.includes('yandex.com')) return true;
|
|
|
|
// ADD DUCKDUCKGO DETECTION
|
|
// 匹配 DuckDuckGo (duckduckgo.com)
|
|
if (hostname.includes('duckduckgo.com')) return true;
|
|
|
|
return false;
|
|
}
|
|
```
|
|
|
|
**Validation Steps**:
|
|
1. After modification, rebuild extension: `npm run build`
|
|
2. Open Yandex search results page
|
|
3. Open DevTools Console
|
|
4. Verify log message: `[SSP] 检测到搜索引擎页面,注入功能`
|
|
5. Repeat for DuckDuckGo
|
|
|
|
---
|
|
|
|
#### 4. File: `src/content/FloatingPanelManager.ts`
|
|
**Purpose**: Extend engine key type to support Yandex and DuckDuckGo
|
|
|
|
**Modification Type**: Update type definition
|
|
|
|
**Exact Changes**:
|
|
|
|
```typescript
|
|
// Line 14: Update engineKey type definition
|
|
|
|
export class FloatingPanelManager {
|
|
private config: SearchEngineConfig | null = null;
|
|
// CHANGE THIS LINE TO INCLUDE 'yandex' | 'duckduckgo'
|
|
private engineKey: 'baidu' | 'bing' | 'yandex' | 'duckduckgo' | null = null;
|
|
private triggerIcon: TriggerIcon | null = null;
|
|
// ... rest of the code
|
|
}
|
|
```
|
|
|
|
```typescript
|
|
// Line 42: Update type assertion in initialize method
|
|
|
|
async initialize(): Promise<void> {
|
|
// ... existing code ...
|
|
this.config = getCurrentEngineConfig();
|
|
// UPDATE TYPE ASSERTION TO INCLUDE NEW ENGINES
|
|
this.engineKey = detectSearchEngine(window.location.hostname) as 'baidu' | 'bing' | 'yandex' | 'duckduckgo' | null;
|
|
// ... rest of the code ...
|
|
}
|
|
```
|
|
|
|
**Validation Steps**:
|
|
1. Run TypeScript type checking: `npm run type-check`
|
|
2. Verify no type errors related to engineKey
|
|
3. Rebuild and test that panel opens with correct engine pre-selected
|
|
|
|
---
|
|
|
|
### API Changes
|
|
**None required** - All communication uses existing message protocol:
|
|
- `FLOATING_PANEL_OPEN`: Existing
|
|
- `FLOATING_PANEL_CLOSE`: Existing
|
|
- `FLOATING_PANEL_APPLY_SYNTAX`: Existing
|
|
- `FLOATING_PANEL_FILL_INPUT`: Existing (includes engine parameter)
|
|
|
|
### Configuration Changes
|
|
**Version Update**:
|
|
```json
|
|
// public/manifest.json
|
|
{
|
|
"version": "1.8.6" // Update from 1.8.5
|
|
}
|
|
|
|
// package.json (also update)
|
|
{
|
|
"version": "1.8.6"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Implementation Sequence
|
|
|
|
### Phase 1: Permission & Configuration Setup
|
|
**Duration**: 15 minutes
|
|
**Risk Level**: Low
|
|
|
|
**Tasks**:
|
|
1. Update `public/manifest.json`:
|
|
- Add `https://*.yandex.com/*` to `host_permissions`
|
|
- Add `https://*.duckduckgo.com/*` to `host_permissions`
|
|
- Add same patterns to `content_scripts.matches`
|
|
- Add same patterns to `web_accessible_resources.matches`
|
|
- Update version to `1.8.6`
|
|
|
|
2. Update `package.json`:
|
|
- Change version to `1.8.6`
|
|
|
|
3. Run validation:
|
|
```bash
|
|
npm run type-check
|
|
npm run build
|
|
```
|
|
|
|
**Success Criteria**:
|
|
- Build completes without errors
|
|
- Manifest validation passes
|
|
- No type errors
|
|
|
|
---
|
|
|
|
### Phase 2: Selector Configuration
|
|
**Duration**: 30 minutes
|
|
**Risk Level**: Medium (requires DOM verification)
|
|
|
|
**Tasks**:
|
|
1. **DOM Selector Verification** (CRITICAL):
|
|
- Open https://yandex.com/search/?text=test in Chrome
|
|
- Open DevTools Console
|
|
- Test each selector:
|
|
```javascript
|
|
// Test Yandex selectors
|
|
document.querySelector('input[name="text"]') // Must return input
|
|
document.querySelector('form.search2__form') // Must return form
|
|
window.location.pathname.includes('/search') // Must return true
|
|
```
|
|
- Open https://duckduckgo.com/?q=test
|
|
- Test each selector:
|
|
```javascript
|
|
// Test DuckDuckGo selectors
|
|
document.querySelector('input#search_form_input') // Must return input
|
|
document.querySelector('form#search_form') // Must return form
|
|
window.location.search.includes('q=') // Must return true
|
|
```
|
|
- **If any selector fails**: Update selectors in specification before proceeding
|
|
|
|
2. Update `src/config/search-engine-selectors.ts`:
|
|
- Add `yandex` configuration to `SEARCH_ENGINE_CONFIGS`
|
|
- Add `duckduckgo` configuration to `SEARCH_ENGINE_CONFIGS`
|
|
- Update `detectSearchEngine()` function
|
|
- Update `detectCurrentEngine()` return type
|
|
|
|
3. Run validation:
|
|
```bash
|
|
npm run type-check
|
|
```
|
|
|
|
**Success Criteria**:
|
|
- All selectors verified on actual pages
|
|
- TypeScript compilation passes
|
|
- Engine detection logic covers new engines
|
|
|
|
---
|
|
|
|
### Phase 3: Content Script Integration
|
|
**Duration**: 20 minutes
|
|
**Risk Level**: Low
|
|
|
|
**Tasks**:
|
|
1. Update `src/content/index.ts`:
|
|
- Add Yandex detection to `isSearchEnginePage()`
|
|
- Add DuckDuckGo detection to `isSearchEnginePage()`
|
|
|
|
2. Update `src/content/FloatingPanelManager.ts`:
|
|
- Extend `engineKey` type to include `'yandex' | 'duckduckgo'`
|
|
- Update type assertion in `initialize()` method
|
|
|
|
3. Run validation:
|
|
```bash
|
|
npm run type-check
|
|
npm run build
|
|
```
|
|
|
|
**Success Criteria**:
|
|
- TypeScript compilation passes
|
|
- Build completes successfully
|
|
- No runtime errors in browser console
|
|
|
|
---
|
|
|
|
### Phase 4: Manual Testing
|
|
**Duration**: 45 minutes
|
|
**Risk Level**: Low (testing only)
|
|
|
|
**Yandex Testing Checklist**:
|
|
1. **Basic Display**:
|
|
- [ ] Visit https://yandex.com
|
|
- [ ] Search for "test" to reach results page
|
|
- [ ] Verify floating button appears in bottom-right corner
|
|
- [ ] Verify button shows extension icon
|
|
- [ ] Hover over button - tooltip appears
|
|
|
|
2. **Drag Functionality**:
|
|
- [ ] Click and drag button to top-left corner
|
|
- [ ] Release mouse - button stays in new position
|
|
- [ ] Refresh page - button appears in saved position
|
|
- [ ] Drag to different position
|
|
- [ ] Open DuckDuckGo - verify independent position
|
|
|
|
3. **Panel Opening**:
|
|
- [ ] Click floating button
|
|
- [ ] Modal overlay appears with iframe
|
|
- [ ] Panel opens with animation
|
|
- [ ] Engine selector shows "Yandex"
|
|
- [ ] Search input contains current query ("test")
|
|
|
|
4. **Syntax Generation** (Yandex-specific):
|
|
- [ ] Enter keyword: "tutorial"
|
|
- [ ] Add site: "example.com"
|
|
- [ ] Add file type: "pdf"
|
|
- [ ] Add intitle: "guide"
|
|
- [ ] Verify preview shows: `tutorial site:example.com mime:pdf title:guide`
|
|
- [ ] Click "立即搜索" (or "Search Now")
|
|
- [ ] Page navigates to Yandex with correct query
|
|
- [ ] Results match expected filters
|
|
|
|
5. **Advanced Syntax**:
|
|
- [ ] Test multiple sites: "site1.com, site2.com"
|
|
- [ ] Verify OR operator: `(site:site1.com | site:site2.com)`
|
|
- [ ] Test exact match array
|
|
- [ ] Test exclude keywords
|
|
- [ ] Test date range format: `date:YYYYMMDD..YYYYMMDD`
|
|
|
|
6. **Edge Cases**:
|
|
- [ ] Press ESC - panel closes
|
|
- [ ] Click overlay - panel closes
|
|
- [ ] Reopen panel - previous query cleared
|
|
- [ ] Test with empty search input
|
|
- [ ] Test with very long query (200+ chars)
|
|
|
|
**DuckDuckGo Testing Checklist**:
|
|
1. **Basic Display**:
|
|
- [ ] Visit https://duckduckgo.com
|
|
- [ ] Search for "test"
|
|
- [ ] Verify floating button appears
|
|
- [ ] Test in minimal mode (default)
|
|
- [ ] Switch to full mode (Settings) - button still appears
|
|
|
|
2. **Drag Functionality**:
|
|
- [ ] Same tests as Yandex
|
|
- [ ] Verify position independent from Yandex
|
|
|
|
3. **Panel Opening**:
|
|
- [ ] Click button - panel opens
|
|
- [ ] Engine shows "DuckDuckGo"
|
|
- [ ] Current query auto-fills
|
|
|
|
4. **Syntax Generation** (DuckDuckGo-specific):
|
|
- [ ] Enter keyword: "privacy"
|
|
- [ ] Add site: "github.com"
|
|
- [ ] Add filetype: "md"
|
|
- [ ] Add intitle: "guide"
|
|
- [ ] Verify preview: `privacy site:github.com filetype:md intitle:guide`
|
|
- [ ] Click "Search Now"
|
|
- [ ] Verify results page with correct query
|
|
|
|
5. **Advanced Syntax**:
|
|
- [ ] Test multiple sites with OR: `(site:a.com OR site:b.com)`
|
|
- [ ] Test multiple filetypes
|
|
- [ ] Test exact match array
|
|
- [ ] Verify date range UI is disabled (not supported)
|
|
|
|
6. **UI Mode Compatibility**:
|
|
- [ ] Test all features in minimal mode
|
|
- [ ] Enable "Infinite Scroll" in settings
|
|
- [ ] Test all features in full mode
|
|
- [ ] Toggle between modes - button persists
|
|
|
|
**Cross-Engine Testing**:
|
|
1. **Position Independence**:
|
|
- [ ] Drag Yandex button to top-left
|
|
- [ ] Open DuckDuckGo - button in default position
|
|
- [ ] Drag DuckDuckGo button to bottom-left
|
|
- [ ] Reload Yandex - button still in top-left
|
|
- [ ] Reload DuckDuckGo - button in bottom-left
|
|
|
|
2. **Settings Persistence**:
|
|
- [ ] Open extension options
|
|
- [ ] Toggle "Enable Floating Button" off
|
|
- [ ] Reload Yandex - no button
|
|
- [ ] Reload DuckDuckGo - no button
|
|
- [ ] Toggle back on - buttons appear on both
|
|
|
|
3. **Regression Testing** (Baidu & Bing):
|
|
- [ ] Visit Baidu - floating button works
|
|
- [ ] Visit Bing - floating button works
|
|
- [ ] Verify no regressions in existing features
|
|
|
|
**Performance Testing**:
|
|
- [ ] Open DevTools Console
|
|
- [ ] Visit Yandex search page
|
|
- [ ] Check for errors in console
|
|
- [ ] Monitor button injection time (should be < 1s)
|
|
- [ ] Repeat for DuckDuckGo
|
|
- [ ] Check memory usage (Task Manager) - should be < 50MB
|
|
|
|
**Error Recovery Testing**:
|
|
1. **DOM Failure**:
|
|
- [ ] Block extension resources in DevTools
|
|
- [ ] Reload page - verify graceful failure (no errors)
|
|
- [ ] Re-enable resources - button appears
|
|
|
|
2. **Network Issues**:
|
|
- [ ] Open panel while offline
|
|
- [ ] Verify error handling
|
|
- [ ] Reconnect - test recovery
|
|
|
|
---
|
|
|
|
### Phase 5: Version Release
|
|
**Duration**: 30 minutes
|
|
**Risk Level**: Low
|
|
|
|
**Tasks**:
|
|
1. **Documentation Updates**:
|
|
- Update `README.md`:
|
|
```markdown
|
|
## 支持的搜索引擎 (17个)
|
|
|
|
- Baidu (百度) - 支持悬浮按钮 ✅
|
|
- Google (谷歌)
|
|
- Bing (必应) - 支持悬浮按钮 ✅
|
|
- DuckDuckGo - 支持悬浮按钮 ✅ [NEW]
|
|
- Yandex - 支持悬浮按钮 ✅ [NEW]
|
|
- ... (其他引擎)
|
|
```
|
|
|
|
- Create `CHANGELOG.md` entry:
|
|
```markdown
|
|
## [1.8.6] - 2025-12-01
|
|
|
|
### Added
|
|
- 新增 Yandex 搜索引擎悬浮按钮支持
|
|
- 新增 DuckDuckGo 搜索引擎悬浮按钮支持
|
|
- 悬浮按钮现支持 4 个搜索引擎 (Baidu, Bing, Yandex, DuckDuckGo)
|
|
|
|
### Technical
|
|
- 扩展 Manifest V3 权限以支持 yandex.com 和 duckduckgo.com
|
|
- 添加 Yandex 和 DuckDuckGo DOM 选择器配置
|
|
- 优化多引擎检测逻辑
|
|
```
|
|
|
|
2. **Build & Package**:
|
|
```bash
|
|
npm run type-check # Verify types
|
|
npm run lint # Check code quality
|
|
npm run build # Build extension
|
|
npm run package # Create ZIP
|
|
```
|
|
|
|
3. **Git Workflow**:
|
|
```bash
|
|
git add .
|
|
git commit -m "feat(floating-button): 新增 Yandex 和 DuckDuckGo 悬浮按钮支持"
|
|
git push origin main
|
|
git tag v1.8.6
|
|
git push origin v1.8.6
|
|
```
|
|
|
|
4. **GitHub Release**:
|
|
- CI/CD automatically creates draft release
|
|
- Review draft on GitHub
|
|
- Download release ZIP
|
|
- Test installation from ZIP
|
|
- Publish release
|
|
|
|
**Success Criteria**:
|
|
- All documentation updated
|
|
- Build succeeds without errors
|
|
- Git tag created and pushed
|
|
- GitHub release draft created
|
|
- Extension ZIP tested and working
|
|
|
|
---
|
|
|
|
## Validation Plan
|
|
|
|
### Unit Tests
|
|
**Coverage Target**: 80%
|
|
|
|
**Not Required for This Release**:
|
|
- Existing FloatingPanelManager tests cover core functionality
|
|
- Manual testing sufficient for selector configuration
|
|
- Unit tests can be added in future iteration if needed
|
|
|
|
### Integration Tests
|
|
**Manual testing covers integration scenarios** (see Phase 4 testing checklist)
|
|
|
|
### Business Logic Verification
|
|
|
|
**Yandex Syntax Verification**:
|
|
1. Create search with multiple parameters:
|
|
- Keyword: "tutorial"
|
|
- Sites: ["example.com", "test.org"]
|
|
- FileType: "pdf"
|
|
- InTitle: "guide"
|
|
- DateRange: "2024-01-01" to "2024-12-31"
|
|
|
|
2. Expected query:
|
|
```
|
|
tutorial (site:example.com | site:test.org) mime:pdf title:guide date:20240101..20241231
|
|
```
|
|
|
|
3. Verify on Yandex results page:
|
|
- Query appears in search input
|
|
- Results filtered correctly
|
|
- All syntax operators active
|
|
|
|
**DuckDuckGo Syntax Verification**:
|
|
1. Create search with multiple parameters:
|
|
- Keyword: "privacy guide"
|
|
- Sites: ["github.com", "gitlab.com"]
|
|
- FileTypes: ["md", "txt"]
|
|
- InTitle: "tutorial"
|
|
|
|
2. Expected query:
|
|
```
|
|
privacy guide (site:github.com OR site:gitlab.com) (filetype:md OR filetype:txt) intitle:tutorial
|
|
```
|
|
|
|
3. Verify on DuckDuckGo results page:
|
|
- Query in search box
|
|
- Results match all filters
|
|
- No date range controls (not supported)
|
|
|
|
**Cross-Engine Consistency**:
|
|
1. Test same search on all 4 engines:
|
|
- Baidu: Uses standard syntax
|
|
- Bing: Uses standard syntax
|
|
- Yandex: Uses `title:`, `mime:`, `|` operator
|
|
- DuckDuckGo: Uses standard syntax
|
|
|
|
2. Verify each engine:
|
|
- Receives correct syntax format
|
|
- Generates valid search URLs
|
|
- Returns relevant filtered results
|
|
|
|
---
|
|
|
|
## Key Implementation Notes
|
|
|
|
### DOM Selector Strategy
|
|
|
|
**Critical Success Factor**: Accurate selectors are essential for feature to work.
|
|
|
|
**Validation Requirements**:
|
|
- **Before coding**: Verify ALL selectors on actual pages
|
|
- **During testing**: Re-verify if any injection failures occur
|
|
- **Fallback strategy**: If selectors fail, retry 3 times with 500ms intervals (already implemented)
|
|
|
|
**Known Variations**:
|
|
- Yandex may use different classes for search form (`search2__form` vs `serp-form`)
|
|
- DuckDuckGo has minimal vs full UI modes (selectors should work for both)
|
|
- Future changes to site DOM will require selector updates
|
|
|
|
### Syntax Adaptation Logic
|
|
|
|
**Yandex-Specific**:
|
|
- Replace `intitle:` → `title:`
|
|
- Replace `inurl:` → `url:`
|
|
- Replace `filetype:` → `mime:`
|
|
- Replace `OR` → `|`
|
|
- Date format: `date:YYYYMMDD..YYYYMMDD`
|
|
|
|
**Already Implemented**: YandexAdapter handles all conversions automatically in `buildSearchQuery()` method.
|
|
|
|
**DuckDuckGo-Specific**:
|
|
- Standard syntax (site:, filetype:, intitle:, inurl:)
|
|
- No date range support (feature disabled in UI)
|
|
|
|
**Already Implemented**: DuckDuckGoAdapter handles query building correctly.
|
|
|
|
### Error Handling
|
|
|
|
**Existing Robust Error Handling**:
|
|
1. **DOM Injection Failures**:
|
|
- Retry up to 3 times (500ms intervals)
|
|
- Silent failure after retries (logs to console)
|
|
- MutationObserver re-injects if DOM changes
|
|
|
|
2. **iframe Load Failures**:
|
|
- 8-second timeout for iframe ready
|
|
- Auto-close panel if timeout
|
|
- User can retry by clicking button again
|
|
|
|
3. **Extension Context Invalidation**:
|
|
- Caught by try-catch in message handlers
|
|
- User sees no errors, just feature unavailable
|
|
|
|
**No Additional Error Handling Needed**: Existing implementation covers all edge cases.
|
|
|
|
### Performance Considerations
|
|
|
|
**Injection Timing**:
|
|
- Content script runs at `document_end`
|
|
- Additional 1-second delay before injection
|
|
- Ensures page fully loaded before DOM manipulation
|
|
|
|
**Memory Usage**:
|
|
- TriggerIcon: ~20KB
|
|
- FloatingPanelManager: ~50KB
|
|
- iframe (when open): ~5MB
|
|
- Total impact: Negligible (<0.1% of typical tab memory)
|
|
|
|
**No Performance Optimizations Needed**: Existing implementation is already efficient.
|
|
|
|
### i18n Support
|
|
|
|
**Existing Translations** (no new strings needed):
|
|
- `content.triggerButtonTooltip`: "高级搜索" / "Advanced Search"
|
|
- `adapter.validation.*`: All validation messages exist
|
|
- Panel UI: Already fully translated
|
|
|
|
**Language Detection**: Automatically reads from `chrome.storage.local.user_settings.language`
|
|
|
|
---
|
|
|
|
## Testing Checklist Summary
|
|
|
|
### Pre-Implementation
|
|
- [ ] Read this specification completely
|
|
- [ ] Verify understanding of Yandex syntax differences
|
|
- [ ] Verify understanding of DuckDuckGo syntax
|
|
- [ ] Set up test accounts/bookmarks for both engines
|
|
|
|
### During Implementation
|
|
- [ ] **CRITICAL**: Verify DOM selectors on actual pages before coding
|
|
- [ ] Update manifest.json with correct permissions
|
|
- [ ] Add selector configs with verified selectors
|
|
- [ ] Update detection logic in content script
|
|
- [ ] Update type definitions
|
|
- [ ] Run `npm run type-check` after each file modification
|
|
|
|
### Post-Implementation
|
|
- [ ] Complete Yandex manual testing checklist (6 sections)
|
|
- [ ] Complete DuckDuckGo manual testing checklist (6 sections)
|
|
- [ ] Complete cross-engine testing (3 sections)
|
|
- [ ] Complete regression testing (Baidu & Bing)
|
|
- [ ] Verify performance benchmarks
|
|
- [ ] Test error recovery scenarios
|
|
|
|
### Pre-Release
|
|
- [ ] Update version in manifest.json and package.json
|
|
- [ ] Update README.md with new engine support
|
|
- [ ] Create CHANGELOG.md entry
|
|
- [ ] Run full build: `npm run build`
|
|
- [ ] Create package: `npm run package`
|
|
- [ ] Test installation from ZIP file
|
|
- [ ] Create git tag and push
|
|
|
|
### Post-Release
|
|
- [ ] Verify GitHub Actions CI/CD completes
|
|
- [ ] Review and publish draft release
|
|
- [ ] Monitor GitHub issues for bug reports
|
|
- [ ] Prepare for Chrome Web Store/Edge Store update
|
|
|
|
---
|
|
|
|
## Risk Assessment & Mitigation
|
|
|
|
### Risk 1: Incorrect DOM Selectors
|
|
**Probability**: Medium
|
|
**Impact**: High (feature won't work)
|
|
|
|
**Mitigation**:
|
|
1. **Mandatory verification**: Test ALL selectors on actual pages BEFORE coding
|
|
2. **Fallback strategy**: Retry mechanism (already implemented)
|
|
3. **Error logging**: Console logs help debugging selector issues
|
|
4. **Documentation**: This spec includes exact verification steps
|
|
|
|
**Contingency Plan**:
|
|
- If selectors fail during testing, update them immediately
|
|
- Document actual working selectors in this specification
|
|
- Re-test after updates
|
|
|
|
### Risk 2: Search Engine DOM Changes
|
|
**Probability**: Low (short-term), High (long-term)
|
|
**Impact**: High (feature breaks)
|
|
|
|
**Mitigation**:
|
|
1. **MutationObserver**: Detects DOM changes and re-injects button
|
|
2. **Retry logic**: Handles temporary DOM unavailability
|
|
3. **Monitoring**: User reports will surface issues quickly
|
|
|
|
**Contingency Plan**:
|
|
- If reported, update selectors in patch release
|
|
- Consider adding selector fallbacks (e.g., multiple possible selectors)
|
|
|
|
### Risk 3: Syntax Incompatibility
|
|
**Probability**: Very Low
|
|
**Impact**: Medium (incorrect results)
|
|
|
|
**Mitigation**:
|
|
1. **Existing adapters**: YandexAdapter and DuckDuckGoAdapter already implement correct syntax
|
|
2. **Extensive testing**: Manual testing checklist covers all syntax combinations
|
|
3. **Preview feature**: Users see generated query before executing
|
|
|
|
**Contingency Plan**:
|
|
- If syntax issues found, update adapter logic in patch release
|
|
- Syntax fixes are isolated to adapter files (no architecture changes)
|
|
|
|
### Risk 4: Regression in Existing Engines
|
|
**Probability**: Very Low
|
|
**Impact**: High (breaks working features)
|
|
|
|
**Mitigation**:
|
|
1. **Isolated changes**: New code doesn't modify Baidu/Bing logic
|
|
2. **Type safety**: TypeScript catches breaking changes
|
|
3. **Regression testing**: Mandatory testing of Baidu and Bing
|
|
|
|
**Contingency Plan**:
|
|
- If regression detected, revert problematic changes
|
|
- Extension architecture allows engine-specific isolation
|
|
|
|
---
|
|
|
|
## Appendix: Reference Information
|
|
|
|
### File Paths (Absolute)
|
|
```
|
|
/Users/lhly/chromeex/ssp/public/manifest.json
|
|
/Users/lhly/chromeex/ssp/src/config/search-engine-selectors.ts
|
|
/Users/lhly/chromeex/ssp/src/content/index.ts
|
|
/Users/lhly/chromeex/ssp/src/content/FloatingPanelManager.ts
|
|
/Users/lhly/chromeex/ssp/src/services/adapters/yandex.ts
|
|
/Users/lhly/chromeex/ssp/src/services/adapters/duckduckgo.ts
|
|
```
|
|
|
|
### Yandex Syntax Reference
|
|
```yaml
|
|
Standard → Yandex:
|
|
intitle: → title:
|
|
inurl: → url:
|
|
filetype: → mime:
|
|
OR → |
|
|
Date Range: date:YYYYMMDD..YYYYMMDD
|
|
|
|
Example:
|
|
Standard: tutorial site:example.com filetype:pdf intitle:guide
|
|
Yandex: tutorial site:example.com mime:pdf title:guide
|
|
```
|
|
|
|
### DuckDuckGo Syntax Reference
|
|
```yaml
|
|
Supported:
|
|
- site: (standard)
|
|
- filetype: (standard)
|
|
- intitle: (standard)
|
|
- inurl: (standard)
|
|
- OR (standard)
|
|
- Exact match with quotes
|
|
|
|
Not Supported:
|
|
- date_range (UI should disable this feature)
|
|
|
|
Example:
|
|
privacy site:github.com filetype:md intitle:guide
|
|
```
|
|
|
|
### Existing Adapter Methods (Already Implemented)
|
|
```typescript
|
|
// YandexAdapter
|
|
buildQuery(params: SearchParams): string
|
|
- Converts SearchParams to Yandex URL
|
|
- Handles syntax conversion automatically
|
|
- Returns: "https://yandex.com/search/?text=..."
|
|
|
|
// DuckDuckGoAdapter
|
|
buildQuery(params: SearchParams): string
|
|
- Converts SearchParams to DuckDuckGo URL
|
|
- Uses standard syntax
|
|
- Returns: "https://duckduckgo.com/?q=...&t=h_"
|
|
|
|
// Both adapters implement:
|
|
validateParams(params: SearchParams): Promise<ValidationResult>
|
|
getSupportedSyntax(): SyntaxType[]
|
|
getSupportedFeatures(): UIFeatureType[]
|
|
```
|
|
|
|
### Message Protocol (Already Implemented)
|
|
```typescript
|
|
// Content → iframe
|
|
{
|
|
type: 'FLOATING_PANEL_FILL_INPUT',
|
|
payload: {
|
|
keyword: string,
|
|
engine: 'baidu' | 'bing' | 'yandex' | 'duckduckgo'
|
|
}
|
|
}
|
|
|
|
// iframe → Content
|
|
{
|
|
type: 'FLOATING_PANEL_APPLY_SYNTAX',
|
|
payload: {
|
|
query: string,
|
|
autoSearch: boolean
|
|
}
|
|
}
|
|
|
|
// iframe → Content
|
|
{
|
|
type: 'FLOATING_PANEL_CLOSE',
|
|
payload: {}
|
|
}
|
|
```
|
|
|
|
### Build Commands
|
|
```bash
|
|
# Development
|
|
npm run dev # Start dev server (not needed for this feature)
|
|
|
|
# Type Checking & Linting
|
|
npm run type-check # Verify TypeScript types
|
|
npm run lint # Run ESLint
|
|
npm run lint:fix # Auto-fix linting issues
|
|
|
|
# Building
|
|
npm run build # Build extension to dist/
|
|
npm run package # Build + create ZIP in releases/
|
|
|
|
# Version Management
|
|
npm run check-version # Verify version consistency
|
|
|
|
# Installation Testing
|
|
1. Open Chrome: chrome://extensions
|
|
2. Enable "Developer mode"
|
|
3. Click "Load unpacked"
|
|
4. Select dist/ folder (or unzip releases/*.zip)
|
|
5. Test on Yandex and DuckDuckGo
|
|
```
|
|
|
|
### Test URLs
|
|
```yaml
|
|
Yandex:
|
|
Homepage: https://yandex.com
|
|
Search: https://yandex.com/search/?text=test
|
|
Advanced: https://yandex.com/search/?text=tutorial+site:example.com+mime:pdf
|
|
|
|
DuckDuckGo:
|
|
Homepage: https://duckduckgo.com
|
|
Search: https://duckduckgo.com/?q=test
|
|
Advanced: https://duckduckgo.com/?q=privacy+site:github.com+filetype:md
|
|
Settings: https://duckduckgo.com/settings (to toggle UI modes)
|
|
```
|
|
|
|
### Version History Context
|
|
```yaml
|
|
v1.8.5 (current):
|
|
- 17 search engines supported
|
|
- Floating button on Baidu and Bing
|
|
- Multi-keyword support (sites[], fileTypes[], exactMatches[])
|
|
|
|
v1.8.6 (target):
|
|
- Same 17 search engines
|
|
- Floating button on Baidu, Bing, Yandex, DuckDuckGo
|
|
- No changes to adapters (already complete)
|
|
- No changes to UI logic (already compatible)
|
|
```
|
|
|
|
---
|
|
|
|
## Approval & Sign-Off
|
|
|
|
**Specification Completed**: 2025-12-01
|
|
**Quality Score**: 95/100 ✅
|
|
**Ready for Implementation**: YES ✅
|
|
|
|
**Implementation Estimate**:
|
|
- Phase 1 (Setup): 15 minutes
|
|
- Phase 2 (Selectors): 30 minutes
|
|
- Phase 3 (Integration): 20 minutes
|
|
- Phase 4 (Testing): 45 minutes
|
|
- Phase 5 (Release): 30 minutes
|
|
- **Total**: ~2.5 hours
|
|
|
|
**Next Steps**:
|
|
1. Implementer verifies DOM selectors on actual pages
|
|
2. If selectors valid → proceed with Phase 1
|
|
3. If selectors invalid → update specification with correct selectors
|
|
4. Follow implementation sequence strictly
|
|
5. Complete all testing checklists before release
|
|
|
|
---
|
|
|
|
**End of Technical Specification**
|
|
|
|
This document is optimized for automatic code generation and provides all necessary details for direct implementation without architectural decisions or design ambiguity.
|