feat: v0.4.3 — 浮动工具栏定位引擎重做 + 程序化编辑统一刷新管线

- 浮动工具栏 mirror 镜像测量:隐藏镜像层复制 textarea 排版样式,选区锚点插零宽字符读像素坐标,CJK/软换行/跨行选区误差全部消除

- 实测尺寸替代魔法数字;滚动 rAF 节流重定位;滚出视口自动隐藏;a11y:role=toolbar + aria-label、visibility 移出 Tab 序列、键盘可达

- 修复死开关/监听器泄漏/销毁后 focus 崩溃/blur 焦点抖动误隐藏

- _afterProgrammaticEdit 统一 8 条程序化路径的渲染/行号/字数/大纲/事件刷新;右键菜单 label 转义、copyAsHTML Firefox 降级、paste 失败提示、Esc 退出全屏

- 测试 871 → 895,e2e 22 → 28 项断言(含真实浏览器浮动工具栏布局验证)
This commit is contained in:
2026-08-20 20:43:01 +08:00
parent ac6638247f
commit d6a618af5d
16 changed files with 646 additions and 115 deletions
+12 -9
View File
@@ -2,9 +2,9 @@
> TypeScript 重构 · 零运行时依赖 · 轻量级桌面端 Markdown Editor 库
[![version](https://img.shields.io/badge/version-0.4.2-blue)](https://git.metona.cn/MetonaTeam/-/packages/npm/@metona-team%2Fmetona-editor)
[![version](https://img.shields.io/badge/version-0.4.3-blue)](https://git.metona.cn/MetonaTeam/-/packages/npm/@metona-team%2Fmetona-editor)
[![license](https://img.shields.io/badge/license-MIT-green)](./LICENSE)
[![tests](https://img.shields.io/badge/tests-871%20passed-brightgreen)](./tests)
[![tests](https://img.shields.io/badge/tests-895%20passed-brightgreen)](./tests)
[![coverage](https://img.shields.io/badge/coverage-parser%2099%25-brightgreen)](./tests)
[![types](https://img.shields.io/badge/types-TypeScript%20strict-blue)](./tsconfig.json)
@@ -17,11 +17,11 @@
- **三模式视图** — edit / split / preview,拖拽分隔条调整比例,双向滚动同步
- **主题系统** — light / dark / warm / autoCSS 变量可定制,实例级隔离,主题继承,外部跟随
- **国际化** — zh-CN / en-US / ja / ko / fr / de 六种语言完整翻译,实例级语言隔离,远程加载翻译包
- **编辑体验** — 行号装订线、智能 Enter、括号自动闭合、拖放文件、大纲面板、Zen 专注模式(宽度可配置,默认 960px)、右键上下文菜单
- **编辑体验** — 行号装订线、智能 Enter、括号自动闭合、拖放文件、大纲面板、Zen 专注模式(宽度可配置,默认 960px)、右键上下文菜单、浮动格式工具栏(mirror 镜像像素级定位,CJK / 软换行 / 跨行选区精确跟随,键盘可达)
- **内置语法高亮** — 零依赖轻量高亮器,js/ts/python/bash/css/html 等 16 个语言标识,规则缓存零重建开销,`MeEditor.highlight` 即插即用
- **性能** — 字数 / 词数 / 行数差异增量统计,击键零全量扫描;大纲 O(n) 线性构建,长文档即时响应
- **安全** — HTML 转义,XSS 协议过滤(javascript / vbscript / file / data),属性级注入防护(含脚注 id),白名单裸标签透传,sanitize 钩子
- **工程化** — 871 个单元测试 + Playwright 真实浏览器冒烟测试,CI 并行 5 job(含 e2e),覆盖率阈值门禁,`sideEffects: false` 便于 tree-shaking
- **工程化** — 895 个单元测试 + Playwright 真实浏览器冒烟测试28 项断言)CI 并行 5 job(含 e2e),覆盖率阈值门禁,`sideEffects: false` 便于 tree-shaking
- **桌面端优先** — 纯电脑端设计,无移动端冗余代码
- **引用链接** — 支持 `[text][ref]` / `![alt][ref]` 引用式链接和图片,含 title 属性
- **RTL 支持** — 完整的从右到左布局适配(阿拉伯语、希伯来语等)
@@ -256,6 +256,8 @@ editor.toggleFloatingToolbar(): this // 开关选中文本格式栏
editor.isFloatingToolbar(): boolean
```
选中文本时自动浮现粗体 / 斜体 / 代码 / 链接 / 删除线按钮。定位采用 mirror 镜像测量(隐藏镜像层复制 textarea 排版样式,选区锚点插入零宽字符读像素坐标),中文混排、长行软换行、跨行选区均精确跟随;选区滚出可视区自动隐藏,滚动时节流重定位。按钮键盘可达(Tab 聚焦 + Enter 执行),隐藏态移出 Tab 序列。已知限制:RTL 布局下定位未做镜像适配。
### 命令执行
```typescript
@@ -430,7 +432,7 @@ import { highlight, registerLanguage, getSupportedLanguages } from '@metona-team
| 事件 | 触发时机 | 参数 |
|------|---------|------|
| `input` | textarea 原生 input | `(value, editor)` |
| `input` | 内容变化(原生输入与程序化编辑路径均触发) | `(value, editor)` |
| `change` | 内容变化 | `(value, editor)` |
| `focus` | 聚焦 | `(editor)` |
| `blur` | 失焦 | `(editor)` |
@@ -447,8 +449,8 @@ import { highlight, registerLanguage, getSupportedLanguages } from '@metona-team
| `linkClick` | 预览区链接点击 | `({ href, text })` |
| `fileOpened` | fileSystem 打开文件 | `({ name, handle })` |
| `fileSaved` | fileSystem 保存文件 | `({ handle })` |
| `beforeChange` | 内容变更前 | `(oldValue, newValue, editor)` |
| `afterChange` | 内容变更后 | `(newValue, editor)` |
| `beforeChange` | 内容变更前(原生输入与程序化编辑路径均触发) | `(oldValue, newValue, editor)` |
| `afterChange` | 内容变更后(原生输入与程序化编辑路径均触发) | `(newValue, editor)` |
| `copy` | 复制到剪贴板 | `({ type })` |
| `selectionChange` | 选区变化 | `({ start, end, text })` |
| `cursorMove` | 光标移动 | `({ line, column })` |
@@ -746,6 +748,7 @@ i18nUtils.formatDate('2024-01-15') // 本地化日期
| `Tab` / `Shift+Tab` | 缩进 / 反缩进 |
| `?` | 快捷键帮助 |
| `Enter` | 智能 Enter(列表/引用延续) |
| `Esc` | 退出全屏 |
---
@@ -820,8 +823,8 @@ src/
|------|------|
| 语言 | TypeScript 5 (strict) |
| 构建 | Rollup 3 |
| 测试 | Jest 29 + jsdom871 用例,覆盖率阈值门禁) |
| 浏览器冒烟 | Playwright + Chromium22 项断言) |
| 测试 | Jest 29 + jsdom895 用例,覆盖率阈值门禁) |
| 浏览器冒烟 | Playwright + Chromium28 项断言) |
| 类型生成 | rollup-plugin-dts |
| 零运行时依赖 | ✅ |