# 插件打开方式改造:Side Panel → 页内悬浮面板 ## 架构(与 1688 参考插件一致,面板加载插件内置页面 ✅ 已确认) ``` 商品详情页(Ozon / 1688 / 淘宝 / 天猫) └─ [Shadow DOM 隔离区](不被商品页样式污染) ├─ 右下角悬浮按钮「套」 ← 点击展开/收起 └─ 面板 iframe(src = chrome-extension:///sidepanel.html,插件内置资源) 悬浮覆盖在页面上 · 贴右侧 · 滑入动画 · 原页面不被挤压 ``` - 悬浮按钮:Shadow DOM 直接渲染(同 1688 插件 Plasmo CSUI 做法),WXT 用 `createShadowRootUi` - 面板:iframe 悬浮覆盖(同 1688 插件),但加载插件内置页面——扩展页面在 iframe 里 chrome.* 权限齐全,现有采集/生成/轮询/导出逻辑**零改动**;唯一额外要求是 manifest 声明 `web_accessible_resources`(已查证:商品站 CSP 拦不住扩展 iframe) ## 改动清单 ### 1. 新增 `extension/entrypoints/panel.content.ts` —— 悬浮按钮 + 面板宿主 - `matches` 与现有采集 content script 相同(Ozon / 1688 / 淘宝 / 天猫) - `createShadowRootUi` 挂独立 Shadow DOM: - **按钮**:右下角 48px 圆钮、品牌色渐变「套」;仅在商品详情页显示(复用 `matchProfile()` 判断),监听 `pushState/popstate` 兼容站内软导航 - **面板**:fixed 贴屏幕右侧(top/bottom/right 16px),宽 `min(880px, 100vw-32px)`,圆角阴影,`translateX(110%) → 0` 滑入 0.25s,z-index 拉满 - iframe 懒加载:首次点开才设 `src=chrome.runtime.getURL('sidepanel.html')`,关闭只隐藏不销毁(同页面内重开状态保留) - 关闭通道:面板内 postMessage `{type:'sc-panel-close'}`(校验来源);工具栏图标 toggle 消息 ### 2. `App.tsx` 小改(~20 行) - `IN_PAGE = window.self !== window.top` 检测 - IN_PAGE 时:顶栏加 ✕ 关闭按钮 + ESC 关闭 → `window.parent.postMessage` 通知宿主页收起 - 其余逻辑不动 ### 3. `background.ts` - 删 `setPanelBehavior`(不再自动开 Side Panel) - 加 `chrome.action.onClicked` → 向当前 tab 发 `{action:'toggle-suite-panel'}`(点图标也能开关面板) ### 4. `wxt.config.ts` - 加 `web_accessible_resources`:`sidepanel.html`,限定 6 个商品站 host - 保留 sidePanel 权限与入口(Chrome 侧边栏仍可手动打开,作兜底) ### 5. README 使用说明更新 ## 已知限制 - 面板随页面销毁:跳转其他商品页后状态重置(生成任务在服务端继续跑,只丢进度视图)。后续可选:suite_id 存 `chrome.storage.session` 做任务恢复 ## 验证 1. `pnpm build` → Chrome 重新加载扩展 2. 商品页:按钮只在详情页出现;点击滑出面板、原页面不被挤压 3. 全流程:采集 → 方案 → 生成 → 导出 ZIP 4. 关闭方式:面板 ✕ / ESC / 工具栏图标;列表页不显示按钮