面向想修改、扩展或发布本项目的人。
┌─────────────────────────── 浏览器 ───────────────────────────┐
│ │
│ background.js (Service Worker) │
│ │ 1. contextMenus 注册「识别图中二维码」(image 上下文) │
│ │ 2. 点击菜单 → scripting.executeScript 注入 │
│ │ lib/jsQR.js + content.js 到图片所在 frame │
│ │ 3. fetch(info.srcUrl) → dataURL(host 权限绕过 CORS) │
│ │ 4. tabs.sendMessage(QR_DECODE) ──→ content.js │
│ │ 5. 收到结果后 sendMessage(QR_TOAST) ──→ content.js │
│ ▼ │
│ content.js(按需注入,非常驻) │
│ │ dataURL → Image → canvas → ImageData → jsQR 解码 │
│ │ 失败回退:按 srcUrl 找 <img> 元素直接绘制(blob: 图片 │
│ │ 只有这条路);画布被跨域污染时以 CORS 方式重载再试 │
│ ▼ │
│ 结果气泡(Shadow DOM,右上角,drop 动画,5 秒自动关闭) │
│ │
└──────────────────────────────────────────────────────────────┘
qr-reader-edge-extension/
├── manifest.json # MV3 清单(版本号在此维护)
├── background.js # Service Worker:菜单、抓图、编排
├── content.js # 解码 + 结果气泡(复制/打开)
├── lib/jsQR.js # 二维码解码库(Apache-2.0,勿改动)
├── icons/ # 扩展图标(tools/make-icons.js 生成)
├── tools/make-icons.js # 图标生成脚本(纯 Node,无依赖)
├── test/ # 解码测试 + 气泡动画预览页
├── docs/ # 本文档、隐私政策、README 图片
├── README.md # 中文说明
├── README.en.md # 英文说明
└── CHANGELOG.md # 更新日志
background ↔ content 之间共两条消息(均带 frameId 定向到图片所在帧):
| 方向 | type | 载荷 | 说明 |
|---|---|---|---|
| bg → content | QR_DECODE |
{ srcUrl, dataUrl? } |
请求解码;dataUrl 为后台抓取结果,可能为 null |
| content → bg(响应) | — | { ok: true, text } 或 { ok: false, reason: 'no_code' \| 'read_fail' } |
解码结果 |
| bg → content | QR_TOAST |
{ kind: 'success' \| 'error', text } |
弹出结果气泡 |
切换气泡动画:content.js 顶部 const ANIM = 'drop',可选 'slide' | 'fade-up' | 'drop' | 'pop',效果可在 test/toast-preview.html 预览。
修改悬浮时长:content.js 中 setTimeout(dismiss, 5000)。
修改解码尺寸上限:content.js 顶部 MAX_SIDE(默认 2400,越大越慢但小码更准)。
图标:node tools/make-icons.js 重新生成(改 buildModuleMap 里的伪随机种子会得到不同的数据点图案)。
cd test
npm install # 仅安装 pngjs(解码测试用)
node decode-test.js # 覆盖:URL / 中文文本 / 反色 / 缩放路径 / UMD 导出
测试夹具(test/fixtures/*.png)由 https://api.qrserver.com/ 生成,可按需重新生成。
manifest.json 的 version(语义化版本)CHANGELOG.md 顶部追加条目node --check background.js content.js、node test/decode-test.jscd ..
zip -r qr-reader-edge-extension.zip qr-reader-edge-extension -x "qr-reader-edge-extension/test/node_modules/*"
gh release create vX.Y.Z qr-reader-edge-extension.zip --title "vX.Y.Z - ..." --notes "..."
商店要求的 zip 与 Release zip 不同:
manifest.json 必须位于 zip 根目录(Release zip 外层有文件夹,是方便解压后直接加载)manifest.json、background.js、content.js、lib/、icons/;剔除 test/、tools/、docs/、.git*docs/privacy.md)# 商店包示例
zip qr-store.zip manifest.json background.js content.js lib icons