feat(M2.3): 沙拉图标组件(基础) (v0.1.3)

- 创建 src/content/components/SaladIcon.js
- 实现 24x24px 绿色图标组件
- 使用 Shadow DOM 封装样式
- position: fixed 定位
- 修复 Content Script 中 Custom Elements 兼容性问题
This commit is contained in:
李岩岩 2026-02-10 13:39:09 +08:00
parent b789e5255c
commit 314d9d47f8
7 changed files with 145 additions and 7 deletions

View File

@ -7,7 +7,7 @@
## 版本速查
### 当前版本
`0.1.2` → 下一目标 `0.1.3` ([M2.3](./M2.md))
`0.1.3` → 下一目标 `0.1.4` ([M2.4](./M2.md))
### 模块版本范围

View File

@ -65,9 +65,9 @@ M11.10完成 → 1.0.0 (正式发布)
## 当前状态
**当前版本**: `0.1.2`
**当前进度**: 7/97 (7%)
**下一任务**: [M2.3 沙拉图标组件(基础)](./M2.md#m23-沙拉图标组件基础--目标版本-0113)
**当前版本**: `0.1.3`
**当前进度**: 8/97 (8%)
**下一任务**: [M2.4 图标定位显示](./M2.md#m24-图标定位显示--目标版本-0114)
---

View File

@ -31,7 +31,7 @@
|------|------|------|------|------|
| M2.1 | 0.1.1 | 文本选择检测 | ✅ | 2026-02-09 |
| M2.2 | 0.1.2 | 获取选中文本坐标 | ✅ | 2026-02-09 |
| M2.3 | 0.1.3 | 沙拉图标组件 | ⬜ | - |
| M2.3 | 0.1.3 | 沙拉图标组件 | ✅ | 2026-02-09 |
| M2.4 | 0.1.4 | 图标定位显示 | ⬜ | - |
| M2.5 | 0.1.5 | 图标点击事件 | ⬜ | - |
| M2.6 | 0.1.6 | 基础面板组件 | ⬜ | - |

View File

@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "沙拉查词",
"version": "0.1.2",
"version": "0.1.3",
"description": "聚合词典划词翻译",
"permissions": [
"storage",

View File

@ -1,6 +1,6 @@
{
"name": "salad-dict",
"version": "0.1.2",
"version": "0.1.3",
"description": "聚合词典划词翻译",
"private": true,
"type": "module",

View File

@ -0,0 +1,115 @@
/**
* @file 沙拉图标组件
* @description 在选中文本旁显示浮动图标
*/
const ICON_SIZE = 24;
const ICON_COLOR = '#4CAF50'; // 绿色
/**
* 沙拉图标类
*/
export class SaladIcon {
constructor() {
this.element = this.createElement();
}
/**
* 创建图标元素
* @returns {HTMLElement} 图标元素
*/
createElement() {
// 创建容器
const container = document.createElement('div');
container.style.cssText = `
position: fixed;
z-index: 2147483647;
display: none;
`;
// 创建 Shadow DOM
const shadow = container.attachShadow({ mode: 'open' });
// Shadow DOM 内容
shadow.innerHTML = `
<style>
.icon {
width: ${ICON_SIZE}px;
height: ${ICON_SIZE}px;
background-color: ${ICON_COLOR};
border-radius: 4px;
cursor: pointer;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
transition: transform 0.1s ease, box-shadow 0.1s ease;
display: flex;
align-items: center;
justify-content: center;
}
.icon:hover {
transform: scale(1.1);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
.icon:active {
transform: scale(0.95);
}
.salad-symbol {
color: white;
font-size: 14px;
font-weight: bold;
user-select: none;
}
</style>
<div class="icon">
<span class="salad-symbol">S</span>
</div>
`;
// 添加到页面
document.body.appendChild(container);
return container;
}
/**
* 显示图标在指定位置
* @param {number} x - X坐标
* @param {number} y - Y坐标
*/
show(x, y) {
this.element.style.left = `${x}px`;
this.element.style.top = `${y}px`;
this.element.style.display = 'block';
}
/**
* 隐藏图标
*/
hide() {
this.element.style.display = 'none';
}
/**
* 销毁组件
*/
destroy() {
this.hide();
if (this.element.parentNode) {
this.element.parentNode.removeChild(this.element);
}
}
}
/**
* 创建并显示沙拉图标
* @param {number} x - X坐标
* @param {number} y - Y坐标
* @returns {SaladIcon} 图标实例
*/
export function createSaladIcon(x, y) {
const icon = new SaladIcon();
icon.show(x, y);
return icon;
}

View File

@ -4,6 +4,9 @@
*/
import { logger } from './logger.js';
import { createSaladIcon } from './components/SaladIcon.js';
let currentIcon = null;
/**
* 获取当前选中的文本
@ -97,11 +100,31 @@ function handleMouseUp(event) {
width: coords.width,
height: coords.height
});
// 显示沙拉图标在选中文本右上角
showSaladIcon(coords.x + coords.width, coords.y);
}
}
}, 10);
}
/**
* 显示沙拉图标
* @param {number} x - X坐标
* @param {number} y - Y坐标
*/
function showSaladIcon(x, y) {
// 隐藏旧图标
if (currentIcon) {
currentIcon.destroy();
currentIcon = null;
}
// 创建新图标
currentIcon = createSaladIcon(x, y);
console.log('[SaladDict] Icon shown at:', x, y);
}
/**
* 初始化文本选择监听
*/