docs: update README for v0.1.3 — features, API, syntax, tests

- Feature list: add readOnly, imagePaste, emoji, render cache, print styles
- Test badge: 407 → 425
- Config: add readOnly, historyDebounce options
- API: add refresh(), setReadOnly(), isReadOnly()
- getStatus: add readOnly field
- Events: add beforeRender, afterRender instance events
- Plugins: add imagePaste preset documentation
- Syntax table: add highlight, superscript, subscript, emoji, table alignment
- Test coverage: update file descriptions and total count
This commit is contained in:
2026-07-23 21:03:02 +08:00
parent 8d2e172289
commit 70eb71623f
+37 -15
View File
@@ -4,7 +4,7 @@
[![npm version](https://img.shields.io/badge/version-0.1.3-blue.svg)](https://www.npmjs.com/package/@metona-team/metona-editor) [![npm version](https://img.shields.io/badge/version-0.1.3-blue.svg)](https://www.npmjs.com/package/@metona-team/metona-editor)
[![license](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE) [![license](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE)
[![tests](https://img.shields.io/badge/tests-407%20passed-brightgreen.svg)](./tests) [![tests](https://img.shields.io/badge/tests-425%20passed-brightgreen.svg)](./tests)
[![coverage](https://img.shields.io/badge/coverage-97%25-brightgreen.svg)](./tests) [![coverage](https://img.shields.io/badge/coverage-97%25-brightgreen.svg)](./tests)
--- ---
@@ -14,15 +14,17 @@
- **零依赖** — 单文件打包,无任何运行时依赖,UMD/ESM/CJS 三种格式 - **零依赖** — 单文件打包,无任何运行时依赖,UMD/ESM/CJS 三种格式
- **现代化** — 原生 ES2020+ 实现,CSS 变量主题系统,响应式布局,无障碍支持 - **现代化** — 原生 ES2020+ 实现,CSS 变量主题系统,响应式布局,无障碍支持
- **易扩展** — 完整插件系统(install/destroy 生命周期),自定义工具栏按钮,预设插件开箱即用 - **易扩展** — 完整插件系统(install/destroy 生命周期),自定义工具栏按钮,预设插件开箱即用
- **易维护** — 模块化源码,JSDoc 注释完整,TypeScript 类型声明,407 个单元测试覆盖 - **易维护** — 模块化源码,JSDoc 注释完整,TypeScript 类型声明,425 个单元测试覆盖
- **易使用** — 工厂函数 `create()` 一行接入,链式 API,中文优先文档与翻译 - **易使用** — 工厂函数 `create()` 一行接入,链式 API,中文优先文档与翻译
- **安全** — 内置 XSS 防护(`javascript:`/`vbscript:`/`file:` 协议过滤),HTML 转义,`safeUrl` 净化 - **安全** — 内置 XSS 防护(`javascript:`/`vbscript:`/`file:` 协议过滤),HTML 转义,`safeUrl` 净化
- **内置解析器** — 自研 CommonMark 子集 + GFM 扩展(表格、任务列表、删除线、自动链接),可整体替换 - **内置解析器** — 自研 CommonMark 子集 + GFM 扩展(表格含列对齐、任务列表、emoji 短码、上下标),可整体替换
- **三模式视图** — edit / split / preview 自由切换,分屏模式支持拖拽调整比例 - **三模式视图** — edit / split / preview 自由切换,分屏拖拽调整比例,滚动同步,模式切换保持滚动位置
- **主题系统** — light / dark / auto / warm 四套预设,CSS 变量定制,跟随系统主题 - **主题系统** — light / dark / auto / warm 四套预设,CSS 变量定制,跟随系统主题@media print 打印样式
- **国际化** — zh-CN / en-US 完整翻译,RTL 支持,`Intl` 数字/货币/日期格式化 - **国际化** — zh-CN / en-US 完整翻译,RTL 支持,`Intl` 数字/货币/日期格式化
- **历史栈** — 撤销/重做,400ms 防抖合并,可配置上限 - **历史栈** — 撤销/重做,防抖合并(可配置延迟),可配置上限
- **预设插件** — autoSave(草稿)、exportTool(导出 .md/.html)、searchReplaceCtrl+F 查找替换) - **只读模式** — `readOnly` 配置 / `setReadOnly()` API,适用于预览/展示场景
- **预设插件** — autoSave(草稿)、exportTool(导出 .md/.html)、searchReplaceCtrl+F 查找替换)、imagePaste(粘贴图片转 base64
- **性能优化** — 渲染缓存跳过重复解析,`refresh()` 强制刷新,模式切换无冗余渲染
--- ---
@@ -146,7 +148,9 @@ MeEditor.create(container, {
// 行为 // 行为
autofocus: false, // 自动聚焦 autofocus: false, // 自动聚焦
spellcheck: false, // 拼写检查 spellcheck: false, // 拼写检查
readOnly: false, // 只读模式
historyLimit: 100, // 历史栈上限 historyLimit: 100, // 历史栈上限
historyDebounce: 400, // 历史栈防抖延迟(ms
syncScroll: true, // 分屏模式同步滚动 syncScroll: true, // 分屏模式同步滚动
tabSize: 2, // 制表符空格数(0 表示 \t tabSize: 2, // 制表符空格数(0 表示 \t
@@ -213,6 +217,7 @@ MeEditor.create(container, {
editor.getValue(); // 获取 Markdown 文本 editor.getValue(); // 获取 Markdown 文本
editor.setValue(md, { silent }); // 设置内容,silent 不触发 change editor.setValue(md, { silent }); // 设置内容,silent 不触发 change
editor.getHTML(); // 获取渲染后的 HTML editor.getHTML(); // 获取渲染后的 HTML
editor.refresh(); // 强制刷新预览(内容未变时使用)
editor.insert(text, { replace }); // 在光标处插入文本 editor.insert(text, { replace }); // 在光标处插入文本
editor.wrap(before, after); // 包裹选区 editor.wrap(before, after); // 包裹选区
editor.focus(); // 聚焦编辑器 editor.focus(); // 聚焦编辑器
@@ -260,7 +265,7 @@ editor.getStats();
// 返回:{ characters, words, chineseChars, englishWords, lines, readingTime } // 返回:{ characters, words, chineseChars, englishWords, lines, readingTime }
editor.getStatus(); editor.getStatus();
// 返回:{ id, mode, theme, locale, fullscreen, disabled, destroyed, plugins } // 返回:{ id, mode, theme, locale, fullscreen, readOnly, disabled, destroyed, plugins }
``` ```
#### 事件 #### 事件
@@ -279,12 +284,14 @@ editor.getPlugins(); // 获取已安装插件列表
editor.addToolbarButton(config); // 追加工具栏按钮 editor.addToolbarButton(config); // 追加工具栏按钮
``` ```
#### 启用/禁用 #### 启用/禁用/只读
```javascript ```javascript
editor.enable(); // 启用 editor.enable(); // 启用
editor.disable(); // 禁用 editor.disable(); // 禁用
editor.isDisabled(); // 是否禁用 editor.isDisabled(); // 是否禁用
editor.setReadOnly(true); // 设置为只读
editor.isReadOnly(); // 是否只读
``` ```
#### 销毁 #### 销毁
@@ -373,6 +380,8 @@ editor.on('destroy', () => {
| `fullscreen` | 全屏切换 | `(fullscreen, editor)` | | `fullscreen` | 全屏切换 | `(fullscreen, editor)` |
| `destroy` | 销毁 | `()` | | `destroy` | 销毁 | `()` |
| `autosave` | autoSave 插件触发 | `({ key, value })` | | `autosave` | autoSave 插件触发 | `({ key, value })` |
| `beforeRender` | 渲染前(实例级) | `(editor)` |
| `afterRender` | 渲染后(实例级) | `(editor)` |
### 静态钩子(全局) ### 静态钩子(全局)
@@ -485,6 +494,15 @@ editor.use(presetPlugins.searchReplace);
// Escape — 关闭 // Escape — 关闭
``` ```
#### imagePaste — 粘贴图片转 base64
```javascript
editor.use(presetPlugins.imagePaste);
// 在编辑区 Ctrl+V 粘贴剪贴板中的图片
// 自动生成 ![](data:image/png;base64,...) 并插入
```
### 自定义工具栏按钮 ### 自定义工具栏按钮
```javascript ```javascript
@@ -518,7 +536,7 @@ pm.destroy();
pluginUtils.createPlugin({ name: 'x', install: () => {} }); pluginUtils.createPlugin({ name: 'x', install: () => {} });
pluginUtils.validatePlugin(plugin); // => { valid: boolean, errors: string[] } pluginUtils.validatePlugin(plugin); // => { valid: boolean, errors: string[] }
pluginUtils.getPreset('autoSave'); // => 副本 pluginUtils.getPreset('autoSave'); // => 副本
pluginUtils.getAllPresets(); // => { autoSave, exportTool, searchReplace } pluginUtils.getAllPresets(); // => { autoSave, exportTool, searchReplace, imagePaste }
``` ```
--- ---
@@ -666,6 +684,9 @@ MetonaEditor 内置自研轻量解析器,支持 CommonMark 子集 + GFM 扩展
| 粗体 | `**bold**` `__bold__` | `<strong>` | | 粗体 | `**bold**` `__bold__` | `<strong>` |
| 斜体 | `*italic*` `_italic_` | `<em>` | | 斜体 | `*italic*` `_italic_` | `<em>` |
| 删除线 | `~~text~~` | `<del>` | | 删除线 | `~~text~~` | `<del>` |
| 高亮标记 | `==text==` | `<mark>` |
| 上标 | `x^2^` | `<sup>` |
| 下标 | `H~2~O` | `<sub>` |
| 行内代码 | `` `code` `` | `<code>` | | 行内代码 | `` `code` `` | `<code>` |
| 代码块 | ` ```lang ` | `<pre><code class="language-lang">` | | 代码块 | ` ```lang ` | `<pre><code class="language-lang">` |
| 引用 | `> quote` | `<blockquote>` | | 引用 | `> quote` | `<blockquote>` |
@@ -673,10 +694,11 @@ MetonaEditor 内置自研轻量解析器,支持 CommonMark 子集 + GFM 扩展
| 有序列表 | `1. item` | `<ol><li>` | | 有序列表 | `1. item` | `<ol><li>` |
| 任务列表 | `- [x] done` | `<li class="me-task-item">` | | 任务列表 | `- [x] done` | `<li class="me-task-item">` |
| 水平线 | `---` `***` `___` | `<hr>` | | 水平线 | `---` `***` `___` | `<hr>` |
| 表格 | `\| a \| b \|` | `<table>` | | 表格 | `\| a \| b \|` | `<table>`(含 `:---:` 列对齐) |
| 链接 | `[text](url)` | `<a>` | | 链接 | `[text](url)` | `<a>` |
| 图片 | `![alt](url)` | `<img>` | | 图片 | `![alt](url)` | `<img>` |
| 自动链接 | `<https://...>` | `<a>` | | 自动链接 | `<https://...>` | `<a>` |
| Emoji 短码 | `:smile:` `:rocket:` | 😊 🚀(80+ 常用) |
### XSS 防护 ### XSS 防护
@@ -784,12 +806,12 @@ npm run test:coverage
| core.js | 99.5% | 96.6% | 98.2% | | core.js | 99.5% | 96.6% | 98.2% |
| **总体** | **96.9%** | **80.3%** | **94.6%** | | **总体** | **96.9%** | **80.3%** | **94.6%** |
测试文件位于 [tests/](./tests) 目录,共 **407 个测试用例**,覆盖: 测试文件位于 [tests/](./tests) 目录,共 **425 个测试用例**,覆盖:
- `parser.test.js` — Markdown 解析器全部语法 + XSS 防护 - `parser.test.js` — Markdown 解析器全部语法(含新增上下标/高亮/emoji/表格对齐) + XSS 防护
- `utils.test.js` — 工具函数(generateId / escapeHTML / debounce / throttle / deepMerge 等) - `utils.test.js` — 工具函数(generateId / escapeHTML / debounce / throttle / deepMerge 等)
- `core.test.js` — MarkdownEditor 构造、内容 API、exec 命令、历史栈、模式、事件、插件、销毁 - `core.test.js` — MarkdownEditor 构造、内容 API、exec 命令(含自定义动作)、历史栈、模式、事件、插件、销毁、readOnly
- `plugins.test.js` — 预设插件(autoSave / exportTool / searchReplace+ PluginManager + pluginUtils - `plugins.test.js` — 预设插件(autoSave / exportTool / searchReplace / imagePaste+ PluginManager + pluginUtils
- `animations.test.js` — 动画注册与查询 - `animations.test.js` — 动画注册与查询
- `themes.test.js` — 主题切换、持久化、监听、自定义注册 - `themes.test.js` — 主题切换、持久化、监听、自定义注册
- `i18n.test.js` — 翻译、语言切换、格式化、监听 - `i18n.test.js` — 翻译、语言切换、格式化、监听