diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 5095088..4cc975e 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -99,6 +99,5 @@ jobs: run: npm run typecheck - name: Lint run: npm run lint - continue-on-error: true - name: Build run: npm run build diff --git a/CHANGELOG.md b/CHANGELOG.md index d66f6bb..490cbaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,32 @@ All notable changes to MetonaEditor will be documented in this file. +## [0.4.2] - 2026-08-19 + +### Fixed +- **插件面板文案未跟随实例 locale**: searchReplace / shortcutHelp / imagePaste 面板与提示此前使用全局 `t()`,实例 `locale` 与全局语言不一致时显示错误语言(v0.4.0 修复了核心 UI,插件面板遗漏);现统一经实例 `editor.t()` 取词。 +- **undo/redo 后预览区跳顶**: `_applyHistory` 此前硬编码 `previewPane.scrollTop = 0`,分屏下长文档撤销时预览跳回顶部;现按滚动比例保存/恢复。 +- **shortcutHelp 卸载面板残留**: `unuse('shortcutHelp')` / `destroy()` 此前保存的是 install 时刻的面板引用(null),已打开的快捷键面板不随之移除;现经 holder 取实时引用清理。 +- **大纲点击在无 CSS.escape 环境崩溃**: `outline.ts` 直接调用全局 `CSS.escape()`,jsdom 等未暴露 `window.CSS` 的环境下点击大纲链接抛 `ReferenceError`,光标定位静默失效;现能力检测 + 简易转义兜底。 +- **大纲点击光标定位不准**: 此前用 `indexOf(标题文本)` 定位,重复标题永远跳第一个;`data-line` 属性误存标题 id 而非行号。现构建时计算各标题源码行号(跳过围栏代码块),点击按行号精确定位,`data-line` 记录 1 基行号。 +- **setLocale 不刷新已渲染 UI**: 状态栏统计标签、大纲标题要等下一次输入才切换语言;现切换即时刷新。 +- **浮动工具栏中文选区定位偏左**: 列宽估算固定按 ASCII 0.6em,中文全角字符约 1em;现逐字符按 CJK 判定累计宽度。 +- **ko 语言包 imageTooLarge 混用中文全角括号**: 统一为半角括号。 + +### Added +- **运行时大纲 API**: `editor.setOutline(on)` / `editor.isOutline()`,运行时开关大纲面板(替代直接操作 `config.outline` + `_buildOutline()` 的私有用法)。 +- **`getRenderCacheSize()`**: 暴露行内渲染缓存当前条目数(parser 导出),供观测 FIFO 淘汰。 +- 回归与补强测试 30 个(7 个此前零断言事件:beforeRender / afterRender / zenChange / fullscreen / copy / fileOpened / fileSaved;全局钩子 beforeCreate / beforeDestroy / afterDestroy;5 个零测试配置项:placeholder / height / spellcheck / tabSize(含 0 与 4)/ historyDebounce;修复 3 处恒真/弱断言:同步滚动(含新增反向联动验证)、渲染缓存 FIFO 真实淘汰、搜索 findNext/prev 选中内容),总数 841 → 871。 +- jest 覆盖率阈值:全局 lines 85% / branches 70%,parser lines 95%(基线 94.95% / 75.72% / 98.93%)。 + +### Changed +- **CI lint 改为阻断**: 移除 verify job 中 lint 步骤的 `continue-on-error`,lint 失败不再静默放行。 +- **build.sh 依赖安装**: `npm install` → `npm ci`,保证构建可重现。 +- **rollup.config.js 死代码清理**: 移除从未被引用的 `terserPlugin` / `isProd` 变量。 +- 文档全面同步:README / docs.html / index.html 修正 "CI 4 job"(实际 5 个)、`document.body()` 错误写法、`afterChange` / `fileSaved` 事件参数(以源码为准)、docs.html 补齐约 15 处缺失 API(`editor.t()`、`MeEditor.getStatus()` / `destroy()`、`configureToolbar` / `removeToolbarButton`、PluginManager & pluginUtils、`safeUrl` / `slugify` / `getSupportedLanguages`、`formatCurrency`、全局 beforeChange / afterChange 钩子、`data:image` 500KB 限制等);demo.html 私有 API hack 改用 `setOutline()` 公开 API。 + +--- + ## [0.4.1] - 2026-08-11 ### Added diff --git a/README.md b/README.md index c53411d..a8da152 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ > TypeScript 重构 · 零运行时依赖 · 轻量级桌面端 Markdown Editor 库 -[![version](https://img.shields.io/badge/version-0.4.1-blue)](https://git.metona.cn/MetonaTeam/-/packages/npm/@metona-team%2Fmetona-editor) +[![version](https://img.shields.io/badge/version-0.4.2-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-841%20passed-brightgreen)](./tests) +[![tests](https://img.shields.io/badge/tests-871%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) @@ -21,7 +21,7 @@ - **内置语法高亮** — 零依赖轻量高亮器,js/ts/python/bash/css/html 等 16 个语言标识,规则缓存零重建开销,`MeEditor.highlight` 即插即用 - **性能** — 字数 / 词数 / 行数差异增量统计,击键零全量扫描;大纲 O(n) 线性构建,长文档即时响应 - **安全** — HTML 转义,XSS 协议过滤(javascript / vbscript / file / data),属性级注入防护(含脚注 id),白名单裸标签透传,sanitize 钩子 -- **工程化** — 841 个单元测试 + Playwright 真实浏览器冒烟测试,CI 并行 4 job,`sideEffects: false` 便于 tree-shaking +- **工程化** — 871 个单元测试 + Playwright 真实浏览器冒烟测试,CI 并行 5 job(含 e2e),覆盖率阈值门禁,`sideEffects: false` 便于 tree-shaking - **桌面端优先** — 纯电脑端设计,无移动端冗余代码 - **引用链接** — 支持 `[text][ref]` / `![alt][ref]` 引用式链接和图片,含 title 属性 - **RTL 支持** — 完整的从右到左布局适配(阿拉伯语、希伯来语等) @@ -348,7 +348,7 @@ editor.configureToolbar(tools: string[]): this editor.removeToolbarButton(action: string): this ``` -### Zen / Word Wrap +### Zen / Word Wrap / Outline ```typescript editor.toggleZen(): this @@ -358,6 +358,8 @@ editor.getZenMaxWidth(): number | string | false editor.toggleWordWrap(): this editor.setWordWrap(on: boolean): this editor.isWordWrap(): boolean +editor.setOutline(on: boolean): this // 运行时开关大纲面板 +editor.isOutline(): boolean ``` ### Toast @@ -414,7 +416,7 @@ MeEditor.getStatus() MeEditor.destroy() // 解析器独立使用 -import { parseMarkdown, parseTokens, renderTokens, safeUrl, slugify, registerBlockHandler } from '@metona-team/metona-editor'; +import { parseMarkdown, parseTokens, renderTokens, safeUrl, slugify, clearRenderCache, getRenderCacheSize, registerBlockHandler } from '@metona-team/metona-editor'; // 内置语法高亮 import { highlight, registerLanguage, getSupportedLanguages } from '@metona-team/metona-editor'; @@ -818,7 +820,7 @@ src/ |------|------| | 语言 | TypeScript 5 (strict) | | 构建 | Rollup 3 | -| 测试 | Jest 29 + jsdom(841 用例) | +| 测试 | Jest 29 + jsdom(871 用例,覆盖率阈值门禁) | | 浏览器冒烟 | Playwright + Chromium(22 项断言) | | 类型生成 | rollup-plugin-dts | | 零运行时依赖 | ✅ | diff --git a/build.sh b/build.sh index ae342c5..b1729fa 100644 --- a/build.sh +++ b/build.sh @@ -20,7 +20,7 @@ echo "✅ npm版本: $(npm -v)" echo "" echo "📦 安装依赖..." -npm install +npm ci if [ $? -ne 0 ]; then echo "❌ 依赖安装失败" diff --git a/jest.config.cjs b/jest.config.cjs index ec74d4e..4549fdb 100644 --- a/jest.config.cjs +++ b/jest.config.cjs @@ -13,5 +13,16 @@ module.exports = { ], coverageDirectory: 'coverage', coverageReporters: ['text', 'lcov'], + coverageThreshold: { + global: { + statements: 85, + branches: 70, + functions: 85, + lines: 85, + }, + 'src/parser.ts': { + lines: 95, + }, + }, verbose: true, }; diff --git a/package.json b/package.json index d2bdcb3..5109e98 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@metona-team/metona-editor", - "version": "0.4.1", + "version": "0.4.2", "description": "Type-safe, lightweight, zero-dependency Markdown Editor. Desktop-first. React-free. Single-file bundle.", "type": "module", "main": "dist/metona-editor.cjs", diff --git a/rollup.config.js b/rollup.config.js index 7e1b7e1..5906c46 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -7,7 +7,6 @@ import serve from 'rollup-plugin-serve'; import livereload from 'rollup-plugin-livereload'; const isDev = process.env.ROLLUP_WATCH; -const isProd = process.env.NODE_ENV === 'production'; const basePlugins = [ resolve(), @@ -29,19 +28,6 @@ const devPlugins = isDev ? [ }), ] : []; -const terserPlugin = isProd ? [ - terser({ - compress: { - drop_console: true, - drop_debugger: true, - pure_funcs: ['console.log', 'console.warn'], - }, - format: { - comments: false, - }, - }), -] : []; - export default [ // UMD development { diff --git a/site/demo.html b/site/demo.html index 752152b..aa25dca 100644 --- a/site/demo.html +++ b/site/demo.html @@ -4,7 +4,7 @@ -MetonaEditor v0.4.1 — 全功能演示 +MetonaEditor v0.4.2 — 全功能演示