mossmd 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +87 -0
- package/LICENSE +21 -0
- package/README.md +336 -0
- package/dist/collab/index.d.ts +14 -0
- package/dist/collab/index.d.ts.map +1 -0
- package/dist/collab/index.js +6 -0
- package/dist/collab/index.js.map +1 -0
- package/dist/core/code-languages.d.ts +3 -0
- package/dist/core/code-languages.d.ts.map +1 -0
- package/dist/core/code-languages.js +130 -0
- package/dist/core/code-languages.js.map +1 -0
- package/dist/core/decoration-utils.d.ts +4 -0
- package/dist/core/decoration-utils.d.ts.map +1 -0
- package/dist/core/decoration-utils.js +25 -0
- package/dist/core/decoration-utils.js.map +1 -0
- package/dist/core/edit-helpers.d.ts +13 -0
- package/dist/core/edit-helpers.d.ts.map +1 -0
- package/dist/core/edit-helpers.js +318 -0
- package/dist/core/edit-helpers.js.map +1 -0
- package/dist/core/icons.d.ts +16 -0
- package/dist/core/icons.d.ts.map +1 -0
- package/dist/core/icons.js +86 -0
- package/dist/core/icons.js.map +1 -0
- package/dist/core/inline-preview.d.ts +32 -0
- package/dist/core/inline-preview.d.ts.map +1 -0
- package/dist/core/inline-preview.js +925 -0
- package/dist/core/inline-preview.js.map +1 -0
- package/dist/core/list-editing.d.ts +10 -0
- package/dist/core/list-editing.d.ts.map +1 -0
- package/dist/core/list-editing.js +244 -0
- package/dist/core/list-editing.js.map +1 -0
- package/dist/core/list-model.d.ts +40 -0
- package/dist/core/list-model.d.ts.map +1 -0
- package/dist/core/list-model.js +114 -0
- package/dist/core/list-model.js.map +1 -0
- package/dist/core/list-navigation.d.ts +3 -0
- package/dist/core/list-navigation.d.ts.map +1 -0
- package/dist/core/list-navigation.js +234 -0
- package/dist/core/list-navigation.js.map +1 -0
- package/dist/core/markdown-context.d.ts +3 -0
- package/dist/core/markdown-context.d.ts.map +1 -0
- package/dist/core/markdown-context.js +10 -0
- package/dist/core/markdown-context.js.map +1 -0
- package/dist/core/preview-activity.d.ts +18 -0
- package/dist/core/preview-activity.d.ts.map +1 -0
- package/dist/core/preview-activity.js +199 -0
- package/dist/core/preview-activity.js.map +1 -0
- package/dist/core/preview-widgets.d.ts +65 -0
- package/dist/core/preview-widgets.d.ts.map +1 -0
- package/dist/core/preview-widgets.js +359 -0
- package/dist/core/preview-widgets.js.map +1 -0
- package/dist/core/read-only.d.ts +26 -0
- package/dist/core/read-only.d.ts.map +1 -0
- package/dist/core/read-only.js +49 -0
- package/dist/core/read-only.js.map +1 -0
- package/dist/core/tree-progress.d.ts +29 -0
- package/dist/core/tree-progress.d.ts.map +1 -0
- package/dist/core/tree-progress.js +143 -0
- package/dist/core/tree-progress.js.map +1 -0
- package/dist/editor.d.ts +219 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +551 -0
- package/dist/editor.js.map +1 -0
- package/dist/features/callout/index.d.ts +9 -0
- package/dist/features/callout/index.d.ts.map +1 -0
- package/dist/features/callout/index.js +223 -0
- package/dist/features/callout/index.js.map +1 -0
- package/dist/features/file-blocks/index.d.ts +12 -0
- package/dist/features/file-blocks/index.d.ts.map +1 -0
- package/dist/features/file-blocks/index.js +397 -0
- package/dist/features/file-blocks/index.js.map +1 -0
- package/dist/features/image/index.d.ts +28 -0
- package/dist/features/image/index.d.ts.map +1 -0
- package/dist/features/image/index.js +699 -0
- package/dist/features/image/index.js.map +1 -0
- package/dist/features/index.d.ts +17 -0
- package/dist/features/index.d.ts.map +1 -0
- package/dist/features/index.js +9 -0
- package/dist/features/index.js.map +1 -0
- package/dist/features/search/index.d.ts +4 -0
- package/dist/features/search/index.d.ts.map +1 -0
- package/dist/features/search/index.js +131 -0
- package/dist/features/search/index.js.map +1 -0
- package/dist/features/slash-commands/index.d.ts +52 -0
- package/dist/features/slash-commands/index.d.ts.map +1 -0
- package/dist/features/slash-commands/index.js +422 -0
- package/dist/features/slash-commands/index.js.map +1 -0
- package/dist/features/table/index.d.ts +44 -0
- package/dist/features/table/index.d.ts.map +1 -0
- package/dist/features/table/index.js +1262 -0
- package/dist/features/table/index.js.map +1 -0
- package/dist/features/upload/index.d.ts +80 -0
- package/dist/features/upload/index.d.ts.map +1 -0
- package/dist/features/upload/index.js +790 -0
- package/dist/features/upload/index.js.map +1 -0
- package/dist/features/wiki-links/index.d.ts +27 -0
- package/dist/features/wiki-links/index.d.ts.map +1 -0
- package/dist/features/wiki-links/index.js +577 -0
- package/dist/features/wiki-links/index.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/styles/content.css +247 -0
- package/dist/styles/inline-preview.css +2116 -0
- package/dist/styles/tokens.css +234 -0
- package/dist/syntax/highlight.d.ts +10 -0
- package/dist/syntax/highlight.d.ts.map +1 -0
- package/dist/syntax/highlight.js +75 -0
- package/dist/syntax/highlight.js.map +1 -0
- package/dist/syntax/index.d.ts +16 -0
- package/dist/syntax/index.d.ts.map +1 -0
- package/dist/syntax/index.js +29 -0
- package/dist/syntax/index.js.map +1 -0
- package/dist/theme/index.d.ts +6 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +204 -0
- package/dist/theme/index.js.map +1 -0
- package/package.json +237 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 未发布
|
|
4
|
+
|
|
5
|
+
### 新增
|
|
6
|
+
|
|
7
|
+
- 新增 `data-theme="blue"` 和 `data-theme="blue-light"` 蓝色主题 preset。
|
|
8
|
+
- 蓝色主题覆盖编辑器与内容渲染共用的 `--moss-*` token,并同步调整链接、选区、搜索高亮、代码背景和语法高亮。
|
|
9
|
+
- 新增水平分隔线对称图标语法,例如 `---⭐---` 和 `***🌿***`。
|
|
10
|
+
|
|
11
|
+
### 调整
|
|
12
|
+
|
|
13
|
+
- 无序列表预览态 marker 改为按嵌套层级轮换 `✦` / `✧`。
|
|
14
|
+
- 移除 `inlinePreviewConfig.horizontalRule.glyph`,水平分隔线图标改由 Markdown 原文语法表达。
|
|
15
|
+
|
|
16
|
+
### 修复
|
|
17
|
+
|
|
18
|
+
- 修复表格单元格内 `==highlight==` 点击后未显露源码分隔符的问题。
|
|
19
|
+
|
|
20
|
+
### 文档
|
|
21
|
+
|
|
22
|
+
- README 增加蓝色主题 preset 的使用示例。
|
|
23
|
+
- Demo 将配色切换与明暗切换拆成两个独立按钮,可组合预览默认/蓝色与深色/浅色。
|
|
24
|
+
- 默认 `---`、`***`、`___` 不再自动附加图标,图标由 Markdown 原文显式提供。
|
|
25
|
+
|
|
26
|
+
## 0.8.1 - 2026-09-22
|
|
27
|
+
|
|
28
|
+
### 新增
|
|
29
|
+
|
|
30
|
+
- 水平分隔线内置支持三种视觉样式:`---` 普通实线、`***` 舒缓波浪线、`___` 中间带符号的分隔线。
|
|
31
|
+
- 新增 `inlinePreviewConfig.horizontalRule.glyph`,支持自定义文本或 emoji 作为分隔线中间符号。
|
|
32
|
+
|
|
33
|
+
### 调整
|
|
34
|
+
|
|
35
|
+
- 将 HR 的波浪线和符号渲染从 Demo 私有实现收回编辑器核心样式。
|
|
36
|
+
- 删除 Demo 中独立的 `wavy-hr.ts` 自定义语法示例,避免消费者为内置 HR 样式额外注册扩展。
|
|
37
|
+
- Demo 使用 `🌿` 演示自定义 HR 符号。
|
|
38
|
+
|
|
39
|
+
### 修复
|
|
40
|
+
|
|
41
|
+
- 放宽波浪线重复周期,降低视觉密集和尖锐感。
|
|
42
|
+
|
|
43
|
+
## 0.8.0 - 2026-09-22
|
|
44
|
+
|
|
45
|
+
### 新增
|
|
46
|
+
|
|
47
|
+
- 新增顶层 `MossMDProps.icons` 配置,统一覆盖图片块、文件块和上传进度块的用户可见图标。
|
|
48
|
+
- 新增 `mossmd/icons` 子路径,导出 `MossIconRenderer`、`mossLucideIcon`、`renderLucideIcon` 和 `renderMossIcon`。
|
|
49
|
+
- 新增图片块、文件块、上传块的图标配置类型,并允许 Slash Command 直接使用自定义 `MossIconRenderer`。
|
|
50
|
+
- Demo 正文新增自定义图标代码示例。
|
|
51
|
+
|
|
52
|
+
### 调整
|
|
53
|
+
|
|
54
|
+
- 图标渲染从 `lucideSvg` 字符串方案切换为 DOM renderer 协议,不再依赖 `react-dom/server`。
|
|
55
|
+
- `MossMDProps.icons` 作为 React 入口的推荐配置方式,保留 feature 级 `imagesConfig.icons`、`fileBlocksConfig.icons`、`fileUpload.icons` 作为更细粒度覆盖。
|
|
56
|
+
- `mossFileUpload(config)` 复用 `mossUploadBlocks(config)` 的上传块视觉配置,上传行为和上传块展示配置边界更清晰。
|
|
57
|
+
|
|
58
|
+
### 修复
|
|
59
|
+
|
|
60
|
+
- 修复 Lucide SVG 的 `viewBox` 属性被错误转换导致图标裁切的问题。
|
|
61
|
+
- 修复默认 `fill` 被覆盖后部分图标填充颜色异常的问题。
|
|
62
|
+
- 修复 CodeMirror autocomplete 默认 icon 样式导致 slash command 图标尺寸异常和显示不全的问题。
|
|
63
|
+
|
|
64
|
+
### 文档
|
|
65
|
+
|
|
66
|
+
- 新增 `docs/icon-customization.md`,记录编辑器图标协议、开放范围、配置优先级和上传块配置关系。
|
|
67
|
+
- README 增加顶层 `icons` 配置示例。
|
|
68
|
+
|
|
69
|
+
## 0.7.2 - 2026-09-22
|
|
70
|
+
|
|
71
|
+
### Added
|
|
72
|
+
|
|
73
|
+
- Added unified image and file upload handling for paste, drag-and-drop, and batch input.
|
|
74
|
+
- Added `MossMDProps.fileUpload` with upload limits, MIME filtering, kind resolution, concurrency control, retry, cancel, and abort support.
|
|
75
|
+
- Added the public `mossmd/features/upload` subpath export.
|
|
76
|
+
|
|
77
|
+
### Fixed
|
|
78
|
+
|
|
79
|
+
- Preserved image Markdown compatibility with `` while allowing users to add `|caption` or `|width=...` afterward.
|
|
80
|
+
- Prevented file drops from falling through to CodeMirror's default text insertion.
|
|
81
|
+
- Preserved batch upload order and placed the caret on a new editable line after uploaded blocks.
|
|
82
|
+
- Cleaned up upload runtime state and object URLs when uploads finish, are cancelled, or the editor is destroyed.
|
|
83
|
+
|
|
84
|
+
### Internal
|
|
85
|
+
|
|
86
|
+
- Added upload coverage for paste, drop, batch ordering, selection replacement, cancellation, read-only mode, and image block caret placement.
|
|
87
|
+
- Fixed the package consumer smoke script so its temporary Vite app builds correctly.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
# MossMD
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/mossmd)
|
|
4
|
+
[](./LICENSE)
|
|
5
|
+
|
|
6
|
+
MossMD (苔藓 markdown) 是一个基于 CodeMirror 6 的 Obsidian live-view 风格 Markdown 编辑器,支持自定义块语法扩展。
|
|
7
|
+
|
|
8
|
+
起初是想在自己的博客系统中集成一款 markdown 编辑器,使用过 milkdown 等,但是与 obsidian 在书写体验上还是有差距,且或多或少存在不顺畅的点,于是想自己构建一款 live-view 风格的编辑器。
|
|
9
|
+
|
|
10
|
+
ChatGPT 推荐了 [atomic-editor](https://github.com/kenforthewin/atomic-editor), 当前项目可以看作是它的 fork 版本,不过后续会在 AI 协作下添加了更多自定义功能,贴近 obsidian 的使用体验,构造一些自己需要的功能点。
|
|
11
|
+
|
|
12
|
+
## 特性
|
|
13
|
+
|
|
14
|
+
- **实时预览**:标题、强调、`==高亮==`、链接、图片和表格会直接在编辑区内渲染,语法只在光标所在行显露。
|
|
15
|
+
- **原始 Markdown 为唯一数据源**:所有装饰都只读,复制、保存、往返其它 Markdown 工具时都保持原文。
|
|
16
|
+
- **布局稳定**:行高只由 CSS 类决定,点击、编辑、滚动不会让页面抖动。
|
|
17
|
+
- **所见即所得表格**:单元格可直接编辑,宽表会在自身容器内横向滚动。
|
|
18
|
+
- **图片块**:`Image` 节点在源码行下方渲染为块级 Widget,并缓存自然尺寸以减少虚拟滚动抖动。
|
|
19
|
+
- **文件块**:单独成段的非图片文件链接渲染为带图标和扩展名徽章的卡片。
|
|
20
|
+
- **Wiki 链接**:支持 `[[target]]`、`[[target|label]]`、异步解析、自动补全和点击打开。
|
|
21
|
+
- **斜杠命令**:行首输入 `/` 或点击行首 `+` 触发命令面板,内置上传图片 / 文件骨架,可拼装自己的片段集。
|
|
22
|
+
- **上传块**:上传过程中显示带进度与状态的块级 Widget,成功后落回最终 Markdown,失败可重试或取消;上传器由消费方注入。
|
|
23
|
+
- **Callout**:识别 `> [!TYPE]` 形式的 Obsidian 风格块,非激活行收起为标签。
|
|
24
|
+
- **智能列表**:Enter 可延续紧凑列表和任务列表,空条目上按 Enter 会缩出列表。
|
|
25
|
+
- **代码高亮**:围栏代码块的语法在首次使用时才动态加载。
|
|
26
|
+
- **自定义语法**:通过 `MossCustomSyntax` 注册额外块,适合 Callout、Mermaid、Kanban 等扩展。
|
|
27
|
+
- **主题可配置**:全部颜色、字体、字号都来自 `--moss-*` CSS 变量。
|
|
28
|
+
- **查找面板**:内置轻量查找面板,样式与编辑器统一。
|
|
29
|
+
- **阅读模式**:`readOnly` 会把编辑器切成阅读表面,保留滚动和搜索状态。
|
|
30
|
+
- **协作接口**:`CollabAdapter` 预留给 yjs、Automerge 或自定义同步层。
|
|
31
|
+
|
|
32
|
+
## 安装
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
bun add mossmd \
|
|
36
|
+
@codemirror/state @codemirror/view @codemirror/commands \
|
|
37
|
+
@codemirror/autocomplete @codemirror/language @codemirror/search \
|
|
38
|
+
@codemirror/lang-markdown \
|
|
39
|
+
@lezer/common @lezer/highlight @lezer/markdown \
|
|
40
|
+
react react-dom
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
CodeMirror 和 React 相关包都是对等依赖,需要和编辑器一起安装。围栏代码语言语法包(例如 `@codemirror/lang-javascript`、`@codemirror/lang-python`)也是按需安装。
|
|
44
|
+
|
|
45
|
+
## 使用
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
import { MossMD } from 'mossmd';
|
|
49
|
+
import 'mossmd/editor.css';
|
|
50
|
+
|
|
51
|
+
export function App() {
|
|
52
|
+
return (
|
|
53
|
+
<MossMD
|
|
54
|
+
markdownSource={'# Hello\n\nA paragraph.'}
|
|
55
|
+
onMarkdownChange={(md) => console.log(md)}
|
|
56
|
+
/>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
编辑器会撑满父容器,外层请放在有高度约束的 flex 或 grid 容器里。渲染后的 Markdown 内容如果要在编辑器外复用,请配合 `mossmd/content.css` 和 `mossmd/tokens.css`。
|
|
62
|
+
|
|
63
|
+
## 命令式句柄
|
|
64
|
+
|
|
65
|
+
如果需要从外部控制编辑器,可以传 `editorHandleRef`。
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
import { useRef } from 'react';
|
|
69
|
+
import { MossMD, type MossMDHandle } from 'mossmd';
|
|
70
|
+
|
|
71
|
+
export function ToolbarDemo() {
|
|
72
|
+
const editor = useRef<MossMDHandle | null>(null);
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<>
|
|
76
|
+
<button onClick={() => editor.current?.openSearch()}>搜索</button>
|
|
77
|
+
<MossMD markdownSource={'…'} editorHandleRef={editor} />
|
|
78
|
+
</>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
可用方法包括:`focus`、`undo`、`redo`、`openSearch(query?)`、`closeSearch`、`revealText(query)`、`isSearchOpen`、`getMarkdown`、`getContentDOM`、`setReadOnly(readOnly)`、`setCollabAdapter(adapter)`。
|
|
84
|
+
|
|
85
|
+
## 斜杠命令与上传
|
|
86
|
+
|
|
87
|
+
`slashCommandsConfig` 接收一个命令数组和一个 `sideButton` 开关。行首输入 `/` 或点击行首 `+` 会弹出命令面板;选中后 `apply` 回调负责把 `/query` 范围替换成最终片段。
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
import { MossMD } from 'mossmd';
|
|
91
|
+
import { mossDefaultSlashCommands, mossUploadCommands } from 'mossmd/features';
|
|
92
|
+
import type { MossUploader } from 'mossmd/features';
|
|
93
|
+
|
|
94
|
+
const uploader: MossUploader = async (file, onProgress) => {
|
|
95
|
+
const form = new FormData();
|
|
96
|
+
form.append('file', file);
|
|
97
|
+
const res = await fetch('/api/upload', { method: 'POST', body: form });
|
|
98
|
+
onProgress(1);
|
|
99
|
+
return { url: (await res.json()).url };
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const uploadCommands = mossUploadCommands(uploader);
|
|
103
|
+
|
|
104
|
+
<MossMD
|
|
105
|
+
markdownSource={'…'}
|
|
106
|
+
slashCommandsConfig={{
|
|
107
|
+
commands: [...mossDefaultSlashCommands, ...uploadCommands],
|
|
108
|
+
sideButton: true,
|
|
109
|
+
}}
|
|
110
|
+
/>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
上传在 pending 期间显示一个块级进度 Widget,成功后落回最终 Markdown,失败可重试或取消。pending 状态只活在编辑器内部,不会污染原文。
|
|
114
|
+
|
|
115
|
+
如果需要直接支持图片和普通文件的粘贴、拖拽及批量上传,可以把同一个 uploader
|
|
116
|
+
传给 `fileUpload`。输入统一为 `File[]`,默认按 MIME 类型分流:图片生成
|
|
117
|
+
``,普通文件生成 `[name](url)`;图片不会自动生成空的 `|caption`,
|
|
118
|
+
用户仍可在图片名后输入 `|caption` 或 `|width=72%`。
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
<MossMD
|
|
122
|
+
markdownSource={'…'}
|
|
123
|
+
fileUpload={{
|
|
124
|
+
uploader,
|
|
125
|
+
maxConcurrency: 3,
|
|
126
|
+
maxFiles: 20,
|
|
127
|
+
maxFileSize: 20 * 1024 * 1024,
|
|
128
|
+
}}
|
|
129
|
+
/>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
用户可见的图标可以通过顶层 `icons` 统一替换;底层仍接受返回 DOM 节点的
|
|
133
|
+
`MossIconRenderer`,不绑定 Lucide。使用 Lucide 时可用 `mossLucideIcon`
|
|
134
|
+
做适配:
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
import { mossLucideIcon } from 'mossmd/icons';
|
|
138
|
+
import { DownloadCloud, Paperclip } from 'lucide-react';
|
|
139
|
+
|
|
140
|
+
<MossMD
|
|
141
|
+
markdownSource={'…'}
|
|
142
|
+
icons={{
|
|
143
|
+
file: {
|
|
144
|
+
file: mossLucideIcon(Paperclip, { size: 40 }),
|
|
145
|
+
download: mossLucideIcon(DownloadCloud, { size: 16 }),
|
|
146
|
+
},
|
|
147
|
+
upload: {
|
|
148
|
+
file: mossLucideIcon(Paperclip, { size: 22 }),
|
|
149
|
+
},
|
|
150
|
+
}}
|
|
151
|
+
/>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## 阅读模式
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
<MossMD markdownSource={'…'} readOnly />
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
阅读模式会保持整篇文档渲染,不显示光标下的源码。链接可直接打开,任务复选框仍可切换,查找功能也正常工作。`readOnly` 通过 `Compartment` 动态切换,不会重挂载编辑器。
|
|
161
|
+
|
|
162
|
+
## 搜索结果落地
|
|
163
|
+
|
|
164
|
+
两个 prop 可以在挂载时把用户带到相关位置:
|
|
165
|
+
|
|
166
|
+
- `initialSearchText`:预填查询并打开搜索面板。
|
|
167
|
+
- `initialRevealText`:直接滚动到第一个命中处,并给一个淡出高亮,不打开面板。
|
|
168
|
+
|
|
169
|
+
两者都接受 `string | null`。`revealText(query)` 也可以在挂载后通过句柄触发。
|
|
170
|
+
|
|
171
|
+
搜索面板默认显示在编辑器顶部,也可以放到中间或底部:
|
|
172
|
+
|
|
173
|
+
```tsx
|
|
174
|
+
<MossMD markdownSource={'…'} searchPanelPosition="center" />
|
|
175
|
+
<MossMD markdownSource={'…'} searchPanelPosition="bottom" />
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## 语法高亮
|
|
179
|
+
|
|
180
|
+
围栏代码块默认只是等宽文本。要启用高亮,传入 `codeLanguages` 数组。
|
|
181
|
+
|
|
182
|
+
```tsx
|
|
183
|
+
import { MossMD } from 'mossmd';
|
|
184
|
+
import { MOSS_CODE_LANGUAGES } from 'mossmd/code-languages';
|
|
185
|
+
|
|
186
|
+
<MossMD markdownSource={'…'} codeLanguages={MOSS_CODE_LANGUAGES} />
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
如果你想自己组装语言列表,也可以直接传 `LanguageDescription[]`。
|
|
190
|
+
|
|
191
|
+
## Wiki 链接
|
|
192
|
+
|
|
193
|
+
```tsx
|
|
194
|
+
import { MossMD } from 'mossmd';
|
|
195
|
+
import { mossWikiLinks } from 'mossmd/features';
|
|
196
|
+
|
|
197
|
+
<MossMD
|
|
198
|
+
markdownSource={'See [[project-atlas|the design doc]] for details.'}
|
|
199
|
+
extensions={[
|
|
200
|
+
mossWikiLinks({
|
|
201
|
+
suggest: async (query) => store.search(query),
|
|
202
|
+
resolve: async (target) => store.resolve(target),
|
|
203
|
+
onOpen: (target) => router.open(target),
|
|
204
|
+
}),
|
|
205
|
+
]}
|
|
206
|
+
/>
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## 自定义语法
|
|
210
|
+
|
|
211
|
+
MossMD 提供自定义语法注册层。公开入口是 `mossmd/syntax`,源码对应的协议实现落在 `src/syntax/index.ts`。语法模块会把 `markdown` 交给 `@codemirror/lang-markdown`,把 `extensions` 追加到编辑器扩展集合之后。
|
|
212
|
+
|
|
213
|
+
```tsx
|
|
214
|
+
import { MossMD } from 'mossmd';
|
|
215
|
+
import { mossCalloutSyntax } from 'mossmd/features';
|
|
216
|
+
|
|
217
|
+
<MossMD
|
|
218
|
+
markdownSource={markdown}
|
|
219
|
+
customSyntax={[mossCalloutSyntax()]}
|
|
220
|
+
/>
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
如果你要自己定义模块,可以从 `mossmd/syntax` 引入 `defineMossSyntax`:
|
|
224
|
+
|
|
225
|
+
```ts
|
|
226
|
+
import { defineMossSyntax } from 'mossmd/syntax';
|
|
227
|
+
|
|
228
|
+
export const calloutSyntax = defineMossSyntax({
|
|
229
|
+
name: 'callout',
|
|
230
|
+
description: 'Callout 块',
|
|
231
|
+
markdown: calloutMarkdown,
|
|
232
|
+
extensions: calloutDecorations(),
|
|
233
|
+
});
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
内置的 Callout 模块识别 `> [!TYPE]` 这种 blockquote 结构。非激活行会显示紧凑标签,点回首行后再恢复原始标记,方便继续编辑。
|
|
237
|
+
|
|
238
|
+
## 主题
|
|
239
|
+
|
|
240
|
+
所有颜色、字体、字号都来自 CSS 自定义属性。你可以在编辑器祖先节点上覆盖这些变量,也可以通过 `data-theme="light"` 切换到浅色配色。MossMD 还提供两个蓝色 preset:`data-theme="blue"` 是深海蓝主题,`data-theme="blue-light"` 是浅蓝主题;它们只改变主题 token,不增加编辑器配置。蓝色 preset 与明暗模式是两个独立维度,可以分别选择配色和明暗:
|
|
241
|
+
|
|
242
|
+
- `data-theme="blue"`:蓝色深色
|
|
243
|
+
- `data-theme="blue-light"`:蓝色浅色
|
|
244
|
+
- `data-theme="dark"`:默认深色
|
|
245
|
+
- `data-theme="light"`:默认浅色
|
|
246
|
+
|
|
247
|
+
`mossmd/tokens.css` 提供共享主题令牌,`mossmd/editor.css` 负责编辑器表面样式,`mossmd/content.css` 负责渲染后的 Markdown。
|
|
248
|
+
|
|
249
|
+
```tsx
|
|
250
|
+
import { MossMD } from 'mossmd';
|
|
251
|
+
import 'mossmd/editor.css';
|
|
252
|
+
|
|
253
|
+
export function BlueMoss() {
|
|
254
|
+
return (
|
|
255
|
+
<div data-theme="blue">
|
|
256
|
+
<MossMD markdownSource="# Blue Moss" />
|
|
257
|
+
</div>
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
图片块会在图片上显示预览按钮;点击后在编辑器外打开大图预览,不会修改 Markdown 或改变文档布局。编辑模式下还会显示编辑和缩放按钮,可修改 alt 文本、图片标题、宽度和 URL。点击图片会选中完整的原始图片语法,因此复制、删除仍然作用于 Markdown 源文。触摸设备上按钮会自动使用较大的常驻触控目标;如需关闭编辑、缩放或预览,可以传入 `imagesConfig={{ editable: false, resizable: false, previewable: false }}`。
|
|
263
|
+
|
|
264
|
+
宽度会使用 MossMD 的扩展图片语法保存,例如 ``。旧的 `` 和 `` 格式仍然兼容。
|
|
265
|
+
|
|
266
|
+
独立成行的文件链接会渲染为文件块并始终隐藏源码。编辑模式下文件块提供下载和删除操作;只读模式下仅提供下载操作。
|
|
267
|
+
|
|
268
|
+
任务列表支持扩展状态,例如 `- [/] In Progress`、`- [!] Important` 和
|
|
269
|
+
`- [\\*] Star`。内置状态会直接渲染为对应图标;也可以通过
|
|
270
|
+
`inlinePreviewConfig.taskCheckboxes` 覆盖图标、名称、是否填充,或增加自定义状态:
|
|
271
|
+
|
|
272
|
+
```tsx
|
|
273
|
+
import { CircleAlert } from 'lucide-react';
|
|
274
|
+
|
|
275
|
+
<MossMD
|
|
276
|
+
markdownSource={'- [!] Important'}
|
|
277
|
+
inlinePreviewConfig={{
|
|
278
|
+
taskCheckboxes: {
|
|
279
|
+
'!': { icon: CircleAlert, label: 'Important' },
|
|
280
|
+
},
|
|
281
|
+
}}
|
|
282
|
+
/>
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
标准 `[ ]`/`[x]` 会互相切换;自定义状态使用状态字符和带 `-` 前缀的状态字符表示填充态与空白态,例如 `[A]` 和 `[-A]`。用户也可以通过 `toggleTo` 自定义两个状态之间的切换。
|
|
286
|
+
|
|
287
|
+
水平分隔线支持普通语法和对称图标语法。默认语法不带图标:`---` 为普通直线,`***` 为舒缓波浪线,`___` 为普通分隔线。需要图标时,将图标放在两侧相同的分隔符之间:
|
|
288
|
+
|
|
289
|
+
```tsx
|
|
290
|
+
<MossMD
|
|
291
|
+
markdownSource={'---⭐---\n***🌿***'}
|
|
292
|
+
/>
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
`---⭐---` 会渲染为带 `⭐` 的直线,`***🌿***` 会渲染为带 `🌿` 的波浪线。图标内容来自 Markdown 原文,因此复制、保存和协作同步都能保留它。
|
|
296
|
+
|
|
297
|
+
## 底层组合
|
|
298
|
+
|
|
299
|
+
如果你不想使用完整的 React 包装,可以直接把各个模块拼起来:
|
|
300
|
+
|
|
301
|
+
```ts
|
|
302
|
+
import {
|
|
303
|
+
mossInlinePreview,
|
|
304
|
+
mossTheme,
|
|
305
|
+
mossSyntax,
|
|
306
|
+
extendEmphasisPair,
|
|
307
|
+
} from 'mossmd';
|
|
308
|
+
import {
|
|
309
|
+
mossImages,
|
|
310
|
+
mossFileBlocks,
|
|
311
|
+
mossTables,
|
|
312
|
+
mossWikiLinks,
|
|
313
|
+
mossCallouts,
|
|
314
|
+
mossSlashCommands,
|
|
315
|
+
mossUploadBlocks,
|
|
316
|
+
} from 'mossmd/features';
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
上述函数都是独立的 CM6 模块,可以按需组合。
|
|
320
|
+
|
|
321
|
+
## 协作
|
|
322
|
+
|
|
323
|
+
`CollabAdapter` 预留给协作同步层。默认实现是 `noopCollabAdapter`,只是不做任何事。未来如果接入 yjs 或别的同步方案,只要实现 `attach`、`detach`、`onRemoteChange` 就行。
|
|
324
|
+
|
|
325
|
+
## 设计说明
|
|
326
|
+
|
|
327
|
+
更完整的架构说明见 [docs/architecture.md](./docs/architecture.md)。
|
|
328
|
+
|
|
329
|
+
- 原始 Markdown 是唯一数据源
|
|
330
|
+
- 行高只由 CSS 类控制
|
|
331
|
+
- 鼠标按下后会短暂冻结装饰重建
|
|
332
|
+
- 装饰重建只覆盖受影响的范围
|
|
333
|
+
|
|
334
|
+
## 许可证
|
|
335
|
+
|
|
336
|
+
MIT。见 [LICENSE](./LICENSE)。
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { EditorView } from '@codemirror/view';
|
|
2
|
+
export interface CollabAdapter {
|
|
3
|
+
attach(view: EditorView): Promise<void>;
|
|
4
|
+
detach(): void | Promise<void>;
|
|
5
|
+
/**
|
|
6
|
+
* Subscribe to full-document snapshots produced by a remote source.
|
|
7
|
+
* The editor applies snapshots as `Transaction.remote` replacements
|
|
8
|
+
* so local change listeners still see the new markdown.
|
|
9
|
+
*/
|
|
10
|
+
onRemoteChange(cb: (doc: string) => void): () => void;
|
|
11
|
+
getAwareness?(): unknown;
|
|
12
|
+
}
|
|
13
|
+
export declare const noopCollabAdapter: CollabAdapter;
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/collab/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B;;;;OAIG;IACH,cAAc,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACtD,YAAY,CAAC,IAAI,OAAO,CAAC;CAC1B;AAED,eAAO,MAAM,iBAAiB,EAAE,aAI/B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/collab/index.ts"],"names":[],"mappings":"AAcA,MAAM,CAAC,MAAM,iBAAiB,GAAkB;IAC9C,MAAM,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;IACtB,MAAM,EAAE,GAAG,EAAE,GAAE,CAAC;IAChB,cAAc,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC;CAC/B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-languages.d.ts","sourceRoot":"","sources":["../../src/core/code-languages.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EAIpB,MAAM,sBAAsB,CAAC;AAe9B,eAAO,MAAM,mBAAmB,EAAE,mBAAmB,EAsHpD,CAAC"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { LanguageDescription, LanguageSupport, StreamLanguage, } from '@codemirror/language';
|
|
2
|
+
// Curated list of languages offered for fenced code blocks. Each `load()` is a
|
|
3
|
+
// dynamic import so Rollup splits the grammar into its own lazy chunk — users
|
|
4
|
+
// only download the ones they actually use.
|
|
5
|
+
//
|
|
6
|
+
// We deliberately avoid `@codemirror/language-data`'s full catalog (50+
|
|
7
|
+
// grammars, ~1 MB) and ship only what we write. To add a language: install
|
|
8
|
+
// `@codemirror/lang-<name>` (or pull a stream parser from
|
|
9
|
+
// `@codemirror/legacy-modes`) and append an entry here.
|
|
10
|
+
function legacy(parser) {
|
|
11
|
+
return new LanguageSupport(StreamLanguage.define(parser));
|
|
12
|
+
}
|
|
13
|
+
export const MOSS_CODE_LANGUAGES = [
|
|
14
|
+
LanguageDescription.of({
|
|
15
|
+
name: 'JavaScript',
|
|
16
|
+
alias: ['js', 'jsx'],
|
|
17
|
+
extensions: ['js', 'mjs', 'cjs', 'jsx'],
|
|
18
|
+
load: () => import('@codemirror/lang-javascript').then((m) => m.javascript({ jsx: true })),
|
|
19
|
+
}),
|
|
20
|
+
LanguageDescription.of({
|
|
21
|
+
name: 'TypeScript',
|
|
22
|
+
alias: ['ts', 'tsx'],
|
|
23
|
+
extensions: ['ts', 'mts', 'cts', 'tsx'],
|
|
24
|
+
load: () => import('@codemirror/lang-javascript').then((m) => m.javascript({ typescript: true, jsx: true })),
|
|
25
|
+
}),
|
|
26
|
+
LanguageDescription.of({
|
|
27
|
+
name: 'Python',
|
|
28
|
+
alias: ['py'],
|
|
29
|
+
extensions: ['py'],
|
|
30
|
+
load: () => import('@codemirror/lang-python').then((m) => m.python()),
|
|
31
|
+
}),
|
|
32
|
+
LanguageDescription.of({
|
|
33
|
+
name: 'Go',
|
|
34
|
+
extensions: ['go'],
|
|
35
|
+
load: () => import('@codemirror/lang-go').then((m) => m.go()),
|
|
36
|
+
}),
|
|
37
|
+
LanguageDescription.of({
|
|
38
|
+
name: 'Rust',
|
|
39
|
+
alias: ['rs'],
|
|
40
|
+
extensions: ['rs'],
|
|
41
|
+
load: () => import('@codemirror/lang-rust').then((m) => m.rust()),
|
|
42
|
+
}),
|
|
43
|
+
LanguageDescription.of({
|
|
44
|
+
name: 'Ruby',
|
|
45
|
+
alias: ['rb'],
|
|
46
|
+
extensions: ['rb'],
|
|
47
|
+
load: () => import('@codemirror/legacy-modes/mode/ruby').then((m) => legacy(m.ruby)),
|
|
48
|
+
}),
|
|
49
|
+
LanguageDescription.of({
|
|
50
|
+
name: 'Java',
|
|
51
|
+
extensions: ['java'],
|
|
52
|
+
load: () => import('@codemirror/lang-java').then((m) => m.java()),
|
|
53
|
+
}),
|
|
54
|
+
LanguageDescription.of({
|
|
55
|
+
name: 'C',
|
|
56
|
+
extensions: ['c', 'h'],
|
|
57
|
+
load: () => import('@codemirror/lang-cpp').then((m) => m.cpp()),
|
|
58
|
+
}),
|
|
59
|
+
LanguageDescription.of({
|
|
60
|
+
name: 'C++',
|
|
61
|
+
alias: ['cpp'],
|
|
62
|
+
extensions: ['cpp', 'c++', 'cc', 'cxx', 'hpp', 'h++', 'hh', 'hxx'],
|
|
63
|
+
load: () => import('@codemirror/lang-cpp').then((m) => m.cpp()),
|
|
64
|
+
}),
|
|
65
|
+
LanguageDescription.of({
|
|
66
|
+
name: 'PHP',
|
|
67
|
+
extensions: ['php'],
|
|
68
|
+
load: () => import('@codemirror/lang-php').then((m) => m.php()),
|
|
69
|
+
}),
|
|
70
|
+
LanguageDescription.of({
|
|
71
|
+
name: 'Swift',
|
|
72
|
+
extensions: ['swift'],
|
|
73
|
+
load: () => import('@codemirror/legacy-modes/mode/swift').then((m) => legacy(m.swift)),
|
|
74
|
+
}),
|
|
75
|
+
LanguageDescription.of({
|
|
76
|
+
name: 'Shell',
|
|
77
|
+
alias: ['bash', 'sh', 'zsh'],
|
|
78
|
+
extensions: ['sh', 'bash', 'zsh'],
|
|
79
|
+
load: () => import('@codemirror/legacy-modes/mode/shell').then((m) => legacy(m.shell)),
|
|
80
|
+
}),
|
|
81
|
+
LanguageDescription.of({
|
|
82
|
+
name: 'SQL',
|
|
83
|
+
extensions: ['sql'],
|
|
84
|
+
load: () => import('@codemirror/lang-sql').then((m) => m.sql()),
|
|
85
|
+
}),
|
|
86
|
+
LanguageDescription.of({
|
|
87
|
+
name: 'HTML',
|
|
88
|
+
alias: ['htm'],
|
|
89
|
+
extensions: ['html', 'htm'],
|
|
90
|
+
load: () => import('@codemirror/lang-html').then((m) => m.html()),
|
|
91
|
+
}),
|
|
92
|
+
LanguageDescription.of({
|
|
93
|
+
name: 'CSS',
|
|
94
|
+
extensions: ['css'],
|
|
95
|
+
load: () => import('@codemirror/lang-css').then((m) => m.css()),
|
|
96
|
+
}),
|
|
97
|
+
LanguageDescription.of({
|
|
98
|
+
name: 'XML',
|
|
99
|
+
extensions: ['xml'],
|
|
100
|
+
load: () => import('@codemirror/lang-xml').then((m) => m.xml()),
|
|
101
|
+
}),
|
|
102
|
+
LanguageDescription.of({
|
|
103
|
+
name: 'JSON',
|
|
104
|
+
extensions: ['json'],
|
|
105
|
+
load: () => import('@codemirror/lang-json').then((m) => m.json()),
|
|
106
|
+
}),
|
|
107
|
+
LanguageDescription.of({
|
|
108
|
+
name: 'YAML',
|
|
109
|
+
alias: ['yml'],
|
|
110
|
+
extensions: ['yaml', 'yml'],
|
|
111
|
+
load: () => import('@codemirror/lang-yaml').then((m) => m.yaml()),
|
|
112
|
+
}),
|
|
113
|
+
LanguageDescription.of({
|
|
114
|
+
name: 'TOML',
|
|
115
|
+
extensions: ['toml'],
|
|
116
|
+
load: () => import('@codemirror/legacy-modes/mode/toml').then((m) => legacy(m.toml)),
|
|
117
|
+
}),
|
|
118
|
+
LanguageDescription.of({
|
|
119
|
+
name: 'Dockerfile',
|
|
120
|
+
filename: /^Dockerfile$/,
|
|
121
|
+
load: () => import('@codemirror/legacy-modes/mode/dockerfile').then((m) => legacy(m.dockerFile)),
|
|
122
|
+
}),
|
|
123
|
+
LanguageDescription.of({
|
|
124
|
+
name: 'Markdown',
|
|
125
|
+
alias: ['md'],
|
|
126
|
+
extensions: ['md', 'markdown', 'mkd'],
|
|
127
|
+
load: () => import('@codemirror/lang-markdown').then((m) => m.markdown()),
|
|
128
|
+
}),
|
|
129
|
+
];
|
|
130
|
+
//# sourceMappingURL=code-languages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-languages.js","sourceRoot":"","sources":["../../src/core/code-languages.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Decoration } from '@codemirror/view';
|
|
2
|
+
import type { Range, Text } from '@codemirror/state';
|
|
3
|
+
export declare function pushReplace(ranges: Range<Decoration>[], doc: Text, from: number, to: number, spec?: Parameters<typeof Decoration.replace>[0]): void;
|
|
4
|
+
//# sourceMappingURL=decoration-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decoration-utils.d.ts","sourceRoot":"","sources":["../../src/core/decoration-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAKrD,wBAAgB,WAAW,CACzB,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,EAAE,EAC3B,GAAG,EAAE,IAAI,EACT,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,IAAI,GAAE,UAAU,CAAC,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAM,GAClD,IAAI,CAqBN"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Decoration } from '@codemirror/view';
|
|
2
|
+
// ViewPlugin-sourced Decoration.replace ranges cannot cross a line break.
|
|
3
|
+
// Split multiline syntax into per-line ranges while keeping the newline in
|
|
4
|
+
// the document flow for stable height and position mapping.
|
|
5
|
+
export function pushReplace(ranges, doc, from, to, spec = {}) {
|
|
6
|
+
if (from >= to)
|
|
7
|
+
return;
|
|
8
|
+
const startLine = doc.lineAt(from);
|
|
9
|
+
if (to <= startLine.to) {
|
|
10
|
+
ranges.push(Decoration.replace(spec).range(from, to));
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
let cursor = from;
|
|
14
|
+
let firstSegment = true;
|
|
15
|
+
while (cursor < to) {
|
|
16
|
+
const line = doc.lineAt(cursor);
|
|
17
|
+
const segmentEnd = Math.min(to, line.to);
|
|
18
|
+
if (segmentEnd > cursor) {
|
|
19
|
+
ranges.push(Decoration.replace(firstSegment ? spec : {}).range(cursor, segmentEnd));
|
|
20
|
+
firstSegment = false;
|
|
21
|
+
}
|
|
22
|
+
cursor = line.to + 1;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=decoration-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decoration-utils.js","sourceRoot":"","sources":["../../src/core/decoration-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,0EAA0E;AAC1E,2EAA2E;AAC3E,4DAA4D;AAC5D,MAAM,UAAU,WAAW,CACzB,MAA2B,EAC3B,GAAS,EACT,IAAY,EACZ,EAAU,EACV,OAAiD,EAAE;IAEnD,IAAI,IAAI,IAAI,EAAE;QAAE,OAAO;IACvB,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,EAAE,IAAI,SAAS,CAAC,EAAE,EAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;QACtD,OAAO;IACT,CAAC;IAED,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,IAAI,YAAY,GAAG,IAAI,CAAC;IACxB,OAAO,MAAM,GAAG,EAAE,EAAE,CAAC;QACnB,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QACzC,IAAI,UAAU,GAAG,MAAM,EAAE,CAAC;YACxB,MAAM,CAAC,IAAI,CACT,UAAU,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CACvE,CAAC;YACF,YAAY,GAAG,KAAK,CAAC;QACvB,CAAC;QACD,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC"}
|