ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Milkdown 光标插件深度解析:@milkdown/plugin-cursor 的 drop indicator、gap cursor 配置与源码实现

Milkdown 光标插件深度解析:@milkdown/plugin-cursor 的 drop indicator、gap cursor 配置与源码实现 Milkdown 光标插件深度解析milkdown/plugin-cursor 的 drop indicator、gap cursor 配置与源码实现【免费下载链接】milkdown Plugin driven WYSIWYG markdown editor framework.项目地址: https://gitcode.com/GitHub_Trending/mi/milkdown本文围绕 Milkdown 编辑器框架中的milkdown/plugin-cursor插件展开系统梳理它在 WYSIWYG Markdown 编辑器中的定位通过 drop cursor放置指示条与 gap cursor间隙光标补齐 ProseMirror 核心未覆盖的光标交互能力。读完本文你将掌握该插件的安装接入方式、dropIndicatorConfig与dropIndicatorState两个核心 Ctx 的配置方法、四个底层插件的协作架构以及如何从源码与版本记录中追溯其能力演进。插件定位为编辑器补齐两种关键光标能力milkdown/plugin-cursor是 Milkdown 生态中的光标能力插件。它本身不渲染任何文档内容而是把两类光标体验接入编辑器Drop cursor放置指示条拖拽块级节点时在目标插入位置显示一条细线指示条帮助用户精确判断放到哪里Gap cursor间隙光标允许用户将光标移动到文档块与块之间的空白间隙中例如标题与段落之间的空隙在这些原本点不进去的位置定位并输入内容。其官方 API 文档docs/api/plugin-cursor.md开篇即说明该插件Add drop cursor and gap cursor support分别对应 ProseMirror 生态中的prosemirror-dropcursor与prosemirror-gapcursor两个经典方案。值得注意的是该插件没有沿用这两个历史实现而是在 7.16.0 起引入了基于prosemirror-drop-indicator的全新 drop indicator 实现见 package.json 的依赖声明使指示条的样式与渲染完全可配置。快速上手安装与最小接入示例该插件已内置于milkdown/kit聚合包中推荐通过 kit 导入。官方文档给出了最小可用示例import { Editor } from milkdown/kit/core import { cursor } from milkdown/kit/plugin/cursor import { commonmark } from milkdown/kit/preset/commonmark import { nord } from milkdown/theme-nord Editor.make().use(nord).use(commonmark).use(cursor).create()其中cursor是插件包的聚合导出一次.use(cursor)即同时注册 gap cursor 与 drop indicator 相关的全部 ProseMirror 插件。若直接以 npm 包形式使用milkdown/plugin-cursor其运行时依赖为milkdown/ctx、milkdown/prose、milkdown/utils与prosemirror-drop-indicator^0.1.0包本身声明为type: module且sideEffects: false可以安全地被构建工具做 tree-shaking。配置项详解dropIndicatorConfig指示条的视觉表现完全由dropIndicatorConfig这一个 Ctx 控制。其类型与默认值定义在 src/drop-indicator/state.ts配置项类型默认值说明widthnumber2指示条的宽度像素。水平指示条时作为高度垂直指示条时作为宽度colorstring \| falsefalse指示条的背景色传false时由 CSS 类控制颜色classstringmilkdown-drop-indicator附加到指示条 DOM 元素上的 CSS 类名修改配置的方式与其他 Milkdown Ctx 一致例如通过ctx.set或直接使用配置化的插件工厂覆盖默认值import { dropIndicatorConfig } from milkdown/kit/plugin/cursor // 通过 ctx 覆写配置 editor.action((ctx) { ctx.set(dropIndicatorConfig.key, { width: 3, color: #1e80ff, class: my-drop-indicator, }) })从源码看dropIndicatorConfig通过$ctx创建键名为dropIndicatorConfig默认color为false意味着若希望完全用 CSS 控制指示条观感无需改动配置直接为.milkdown-drop-indicator类编写样式即可。另外为兼容旧版本命名源码中保留了dropCursorConfig作为dropIndicatorConfig的向后兼容导出标有deprecated见 src/index.ts新代码应统一使用dropIndicatorConfig。运行时状态dropIndicatorStatedropIndicatorState是插件内部用于流转指示条信息的 Ctx slice类型为ShowHandlerOptions | null来自prosemirror-drop-indicator默认值为nullsrc/drop-indicator/state.ts。它的生命周期由dropIndicatorPlugin维护用户拖拽经过可放置位置时底层库回调onShow插件把携带目标位置几何信息line的两端点坐标的ShowHandlerOptions写入 state拖拽结束或移出有效区域时onHide把 state 重置为null。dropIndicatorDOMPlugin则通过ctx.use(dropIndicatorState.key)订阅该 slicestateSlice.on(...)state 一旦更新便触发 DOM 重绘并在销毁时通过stateSlice.off(...)解绑。这套状态切片 订阅的机制与 Milkdown 的插件系统高度契合——指示条的数据与渲染被拆成两个独立的 ProseMirror 插件职责单一、可单独复用。源码架构四个插件如何协作在 src/index.ts 中cursor聚合导出由四个插件组成export const cursor: MilkdownPlugin[] [ gapCursorPlugin, dropIndicatorConfig, dropIndicatorState, dropIndicatorDOMPlugin, dropIndicatorPlugin, ].flat()dropIndicatorConfig配置 Ctx承载用户对指示条的自定义dropIndicatorState状态 Ctx承载此刻指示条是否显示、显示在哪的运行时数据dropIndicatorPlugin一个$prose插件负责与prosemirror-drop-indicator对接监听拖拽事件并更新 statesrc/drop-indicator/plugin.tsdropIndicatorDOMPlugin另一个$prose插件负责真正把指示条渲染为 DOM 元素src/drop-indicator/drop-indicator-dom.tsgapCursorPlugin包装 ProseMirror 的 gap cursor 能力。每个插件都通过withMeta标记了便于调试的displayName如CtxdropIndicatorConfig、ProsedropIndicator在 Milkdown 的 inspector / telemetry 工具中可以据此识别。底层实现drop indicator 的 DOM 渲染原理dropIndicatorDOMPlugin的渲染逻辑非常直观值得展开。它通过PluginKey(MILKDOWN_DROP_INDICATOR_DOM)创建了一个带view的插件在编辑器挂载时执行以下动作读取dropIndicatorConfig创建一个position: fixed、pointerEvents: none、默认display: none的div并追加到编辑器的父节点中将配置的class与固定的milkdown-drop-indicator同时添加到元素上订阅dropIndicatorStatestate 变化时调用renderIndicator重绘编辑器销毁时移除元素并解绑监听。renderIndicator根据拖拽位置的几何信息绘制指示条若两个端点y坐标相等则这是一条水平指示条说明目标位于两个块之间宽度取两点 x 轴距离、高度取配置的width并向上平移半个线宽使线条垂直居中反之则为垂直指示条说明目标位于行内某个位置宽高对调、向左平移半个线宽。最后通过transform: translate(...)精确定位。由于元素使用pointer-events: none指示条永远不会拦截用户的鼠标事件这也是该类 UI 的通用做法。值得一提的细节是dropIndicatorPlugin中onDrag: () true的返回约定——它向底层库确认当前拖拽被接受从而驱动指示条持续跟随拖拽位置刷新。gap cursor在文档空白间隙移动光标gapCursorPlugin的实现非常精简src/gap-cursor.tsexport const gapCursorPlugin $prose(() gapCursor())它只是把milkdown/prose/gapcursor中重新导出的 ProseMirror gap cursor 包装成 Milkdown 的$prose插件。启用后当光标处于块级元素之间的空隙时浏览器会显示一个提示光标光标样式根据主题而定此时点击即可将光标定位到间隙中并直接开始输入ProseMirror 会自动将输入内容落位到正确的块节点中。这在处理标题与正文之间想补一行、列表项与段落之间想插入内容等场景时非常实用。版本演进从 4.6.5 到 7.22.1该插件的 CHANGELOG.md 由 changesets 自动生成记录了从 v4.6.5 到 v7.22.1 的完整发布历史每个版本还列出了同步更新的milkdown/ctx、milkdown/prose、milkdown/utils等依赖版本。其中与光标能力直接相关的里程碑如下版本变更内容CHANGELOG 记录性质4.6.5Add cursor package and fix config bug.引入 cursor 包首个版本6.1.3修复内联节点inline nodes光标问题Fix7.4.0better drop cursor for crepe优化 crepe 的放置光标体验7.6.4修复多块手柄multi block handle问题Fix7.8.0新增 bike-style 虚拟光标、修复 crepe 列表项光标样式Feat / Fix7.16.0新增 drop indicator 插件#2097Feat本包最重要的能力升级7.22.1keep the dragged node on view.dragging when using the block handle#2452Fix拖拽节点与块手柄协同需要说明的是该仓库的 changelog 采用聚合发布模式因此部分条目如 crepe、preset、components 的改动属于同批次 monorepo 全量发布的记录而光标相关的条目集中在上述表格中。从演进脉络可以清晰看到插件从早期仅提供基础的 drop cursor / gap cursor 包装逐步演进到 7.16.0 引入可配置、可定制样式的 drop indicator 体系并在后续版本中持续打磨与块手柄block handle、列表项光标、内联节点等交互的协同细节。使用注意事项与常见问题基于源码与变更记录使用该插件时有几点值得注意样式优先级指示条元素同时带有配置的class与固定的milkdown-drop-indicator类。若color配置为false务必在主题 CSS 中为指示条提供颜色否则可能不可见与块手柄的协同从 7.22.1 的修复#2452可见使用 plugin-block 的块手柄拖拽节点时需要保证被拖拽节点保持在view.dragging上指示条才会与拖拽过程正确联动——升级插件版本可自动获得该修复旧命名迁移dropCursorConfig仅为向后兼容别名被标记为deprecated迁移到新配置名dropIndicatorConfig即可依赖对齐插件依赖prosemirror-drop-indicator而milkdown/prose是它封装的 ProseMirror 聚合层请保持milkdown/*相关包版本一致避免多版本 ProseMirror 共存导致的状态异常。小结milkdown/plugin-cursor以极低的接入成本为 Milkdown 编辑器带来了完整的光标交互体验通过dropIndicatorConfig可自由定制放置指示条的宽、色、类通过dropIndicatorState实现了数据与渲染的解耦gap cursor 则补足了块间隙编辑的盲区。阅读源码时建议按 src/index.ts → src/drop-indicator/state.ts → src/drop-indicator/plugin.ts → src/drop-indicator/drop-indicator-dom.ts 的顺序追踪数据流即可完整还原拖拽 → 状态更新 → DOM 重绘的整条链路。【免费下载链接】milkdown Plugin driven WYSIWYG markdown editor framework.项目地址: https://gitcode.com/GitHub_Trending/mi/milkdown创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表