Joplin 富文本编辑器中的 joplinLists 插件:TinyMCE 列表插件的分支改造与构建流程

发布时间:2026/9/7 14:12:01

Joplin 富文本编辑器中的 joplinLists 插件:TinyMCE 列表插件的分支改造与构建流程
Joplin 富文本编辑器中的 joplinLists 插件TinyMCE 列表插件的分支改造与构建流程【免费下载链接】joplinJoplin - the privacy-focused note taking app with sync capabilities for Windows, macOS, Linux, Android and iOS.项目地址: https://gitcode.com/GitHub_Trending/jo/joplinJoplin 桌面端Electron在富文本模式下使用 TinyMCE 作为底层编辑器而其中处理列表缩进、键盘删除与列表切换的lists插件并不直接使用官方原版而是由 Joplin 仓库内 fork 改造而来的joplinLists插件注册名为joplinLists。本文基于仓库文档Assets/TinyMCE/JoplinLists/README.md完整梳理该插件的来历、构建与调试流程并结合插件源码Plugin.ts、Commands.ts、JoplinListUtil.ts与 Gruntfile 构建脚本说明 Joplin 复选框checklist在富文本列表体系中的实现方式与产物去向。读完本文读者将理解该插件如何注册编辑器命令、joplin-checklist类名如何驱动“插入/勾选清单条目”两个自定义命令以及如何用npm run build与buildAndStart完成编译与桌面端联调。插件定位官方 TinyMCE lists 插件的 Joplin 分支README 开门见山地说明了该模块的两点关键信息代码来源它基于 TinyMCE 官方lists插件的某一历史提交tinymce/tinymce仓库中modules/tinymce/src/plugins/lists路径下的代码在 Joplin 仓库内以独立目录Assets/TinyMCE/JoplinLists/维护改造目标在保留官方列表能力的基础上增加对Joplin 复选框checklist的支持——这正是 Joplin 笔记中- [ ]/- [x]语法在富文本编辑器内的表现载体。从源码结构看该插件是一个标准的 TinyMCE 插件工程src/main/ts/下按 TinyMCE 官方插件的典型目录组织划分为actions/如ToggleList.ts、Indendation.ts、api/Api.ts、Commands.ts、Events.ts、Settings.ts、core/Keyboard.ts、Mouse.ts、Delete.ts、SplitList.ts等与listModel/列表模型层含ParseLists.ts、NormalizeEntries.ts等。官方插件中的核心逻辑键盘操作、鼠标拖拽缩进、列表拆分与规范化被整体保留Joplin 的改造集中在两处api/Commands.ts与listModel/JoplinListUtil.ts。一个需要特别留意的仓库事实来自 README 顶部的警告自 2020-11-02 起该模块已无法直接构建出现大量 TypeScript 报错且作者表示未查明原因。这意味着当前仓库中的Assets/TinyMCE/JoplinLists/处于“源码在位、但构建链路已断”的状态桌面端实际使用的插件产物是此前构建并拷贝进去的编译文件。这一点决定了后文“构建”一节只能作为流程性参考而非当前可直接跑通的构建脚本。插件注册机制joplinLists名称从何而来入口文件 Main.ts 仅做一件事——调用Plugin()完成副作用式注册并明确注释“不要导出任何内容否则 Rollup 会在页面上留下全局变量”import Plugin from ./Plugin; Plugin();Plugin.ts 通过 TinyMCE 的PluginManager.add把插件注册为joplinLists而非官方lists这是 Joplin 能够与官方列表插件并存、互不覆盖的关键export default function () { PluginManager.add(joplinLists, function (editor) { Keyboard.setup(editor); Mouse.setup(editor); Buttons.register(editor); Commands.register(editor); return Api.get(editor); }); }注册时依次挂载了四个子系统键盘快捷键Tab/ShiftTab 缩进、Delete/Backspace 删除、鼠标行为、工具栏按钮与编辑器命令。其中Commands.register(editor)是本文重点它把官方的InsertUnorderedList/InsertOrderedList/InsertDefinitionList/RemoveList命令桥接到ToggleList.toggleList与缩进动作上并在末尾调用了 Joplin 的扩展入口addJoplinChecklistCommands(editor, ToggleList)见 Commands.ts。该插件名最终在桌面端编辑器配置中生效。TinyMCE.tsx 在初始化 TinyMCE 时加载本地脚本gui/NoteEditor/NoteBody/TinyMCE/plugins/lists.js约 L382并将插件列表配置为plugins: link joplinLists searchreplace codesample table约 L732。从源码结构看joplinLists替代了官方lists的位置成为富文本编辑器中列表行为的唯一提供方。Joplin 复选框扩展joplin-checklist类名与两条自定义命令Joplin 清单在 HTML 中的表示方式是在无序列表ul上添加joplin-checklist类被勾选的条目li上再添加checked类。整个扩展逻辑集中在 JoplinListUtil.ts核心函数包括isCheckboxListItem(element)判断某个元素是否带有joplin-checklist类以此区分“普通列表容器”与“清单容器”findContainerListTypeFromEvent/findContainerListTypeFromElement从事件元素或 DOM 节点向上查找最近的UL/OL祖先返回joplinChecklist或regular供点击、键盘等交互判断当前所处列表类型isJoplinChecklistItem(element)确认某li是否属于清单节点名必须是LI且容器类型为清单。在此基础上addJoplinChecklistCommands(editor, ToggleList)向编辑器注入两条 TinyMCE 自定义命令editor.addCommand(ToggleJoplinChecklistItem, function (ui, detail) { const element detail.element; if (!isJoplinChecklistItem(element)) return; if (!element.classList || !element.classList.contains(checked)) { element.classList.add(checked); } else { element.classList.remove(checked); } }); editor.addCommand(InsertJoplinChecklist, function (ui, detail) { detail { ...detail, listType: joplinChecklist }; ToggleList.toggleList(editor, UL, detail); });两条命令的分工清晰命令触发语义实现行为ToggleJoplinChecklistItem点击/切换已有清单条目的勾选状态校验目标LI确属清单后对checked类做增删实现勾选/取消勾选InsertJoplinChecklist插入一个新的清单复用官方ToggleList.toggleList(editor, UL, ...)仅把detail.listType标记为joplinChecklist使生成的UL带上清单类名这种“复用官方 toggleList、仅改 detail 参数”的做法保证了清单的插入路径与普通无序列表共用同一套列表规范化与缩进逻辑Joplin 的侵入面被控制在Commands.ts的一个注册调用与JoplinListUtil.ts的少量工具函数内。与渲染层的呼应同样可见于 renderer 的复选框样式 与 MdToHtml 的 checkbox 规则Markdown 侧的- [ ]/- [x]与 HTML 侧的joplin-checklist/checked类名构成一条完整的往返链路。构建流程npm i npm run build与buildAndStart回到 README 给出的两条核心命令。对照 package.json其含义如下npm i npm run buildnpm i安装该子工程的 devDependencies关键依赖为 TinyMCE 官方开发链工具grunt、ephox/swagTinyMCE 构建工具集、rollup经 swag 提供、ts-loader/awesome-typescript-loader、typescript^3.1.6、webpack^4.25.1等npm run build实际执行grunt即运行 Gruntfile.js 中注册的default任务clean → shell → rollup → uglify → concat → copy。各步骤职责依据 Gruntfile.jsclean清理dist与scratch目录shell执行tsc --project tsconfig.json将src/main/ts编译为lib/Main.jsrollup把lib/Main.js打包为 IIFE 模块scratch/compiled/joplinLists.js外部化externaltinymce/core/api/*一系列模块并映射到tinymce.PluginManager、tinymce.util.VK等运行时全局——这保证产物不内嵌 TinyMCE 核心体积小且不产生双实例uglify压缩生成scratch/compiled/joplinLists.min.jsconcat拼接src/text/license-header.js头注释替换BUILD_NUMBER占位符产出dist/joplinLists.js与dist/joplinLists.min.jscopy对 Joplin 而言最关键的一步将dist/joplinLists.js拷贝到../../../packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/plugins/lists.js即 packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/plugins/lists.js。这正是上文TinyMCE.tsx中src字段指向的文件——构建脚本直接完成了“插件产物进入桌面应用”的最后一公里无需人工搬运。第二条命令用于插件改动后的端到端联调npm run buildAndStart在 package.json 中其定义为buildAndStart: yarn build cd .. cd .. cd .. cd packages/app-desktop npm start先完成上述整套插件构建含拷贝到 app-desktop再进入packages/app-desktop执行npm start启动桌面端应用。流程上这是“改插件 → 自动落位 → 起桌面端验证”的闭环对应 README 所说的 “build the plugin and start the desktop application”。需要再次强调的前提由于 README 明确记载 2020-11-02 后该模块出现大量 TypeScript 错误而无法构建上述流程描述的是仓库中脚本所定义的设计流程在当前代码状态下直接执行npm run build是否可通过以实际运行结果为准仓库并未给出修复说明。对修改该插件的实操建议综合以上源码证据若未来需要再次修改该插件可以按以下路径推进定位行为归属列表切换/缩进/命令层改动看 src/main/ts/api/Commands.ts 与 actions/ 目录ToggleList.ts、Indendation.ts清单专属逻辑集中在 listModel/JoplinListUtil.ts键盘/删除行为在 core/ 目录Keyboard.ts、Delete.ts、SplitList.ts等保持注册名不变Plugin.ts中注册的joplinLists名称与TinyMCE.tsx的plugins配置一一对应改名会直接导致插件失效保持产物路径不变构建后必须仍落在packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/plugins/lists.js否则桌面端加载的是旧产物调试时会误判“改动未生效”验证闭环优先用npm run buildAndStart在真实桌面端验证键盘缩进、清单勾选、跨列表复制粘贴等行为依赖编辑器运行时上下文单看单元测试无法覆盖 TinyMCE 的 DOM 交互细节——该子工程的test脚本bedrock-auto同样依赖 TinyMCE 官方测试框架且受构建链路阻塞影响实际可用性需以运行时行为为准注意 TypeScript 版本约束devDependencies 锁定typescript^3.1.6与webpack^4.25.1README 所述“大量 TS 错误”很可能与 TinyMCE 类型定义升级后不兼容有关重建构建链时应优先对齐这些旧版本约束或使用transpileOnly类策略绕过严格检查webpack 配置中ts-loader已设置transpileOnly: true即为同类思路的体现。小结Assets/TinyMCE/JoplinLists/是 Joplin 桌面端富文本编辑器列表能力的定制层它以 TinyMCE 官方lists插件为基座在 Plugin.ts 中以joplinLists之名注册在 JoplinListUtil.ts 中用joplin-checklist/checked类名和InsertJoplinChecklist、ToggleJoplinChecklistItem两条命令扩展出 Joplin 清单能力并通过 Gruntfile.js 的clean → tsc → rollup → uglify → concat → copy流水线把产物直接投放到packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/plugins/lists.js。npm i npm run build与npm run buildAndStart分别对应“纯构建落位”和“构建 启动桌面端”两种工作方式。由于仓库文档明确标注该模块自 2020-11-02 起构建已中断当前仓库中桌面端使用的lists.js属于历史构建产物理解上述注册、命令与拷贝链路是后续排查清单行为或重建构建流程的基础。【免费下载链接】joplinJoplin - the privacy-focused note taking app with sync capabilities for Windows, macOS, Linux, Android and iOS.项目地址: https://gitcode.com/GitHub_Trending/jo/joplin创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

MCP协议详解:从零搭建MCP Server并接入Cursor等AI客户端

MCP协议详解:从零搭建MCP Server并接入Cursor等AI客户端

2026/9/7 14:02:00

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

GPU电压噪声排查指南:从瞬态跌落到压测复现

GPU电压噪声排查指南:从瞬态跌落到压测复现

2026/9/7 14:02:00

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

3 步落地电子书转有声书:ebook2audiobook 本地实操笔记

3 步落地电子书转有声书:ebook2audiobook 本地实操笔记

2026/9/7 14:02:00

3 步落地电子书转有声书:ebook2audiobook 本地实操笔记 【免费下载链接】ebook2audiobook Generate audiobooks from e-books, voice cloning & 1158 languages! 项目地址: https://gitcode.com/GitHub_Trending/eb/ebook2audiobook ebook2audiobook 做电…

ComfyUI零基础入门:节点式工作流、自定义节点与报错排查指南

ComfyUI零基础入门:节点式工作流、自定义节点与报错排查指南

2026/9/7 15:22:04

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

C++函数返回右值引用:语法合法却暗藏陷阱,正确用法与误区深度解析

C++函数返回右值引用:语法合法却暗藏陷阱,正确用法与误区深度解析

2026/9/7 15:22:04

如果你在C11里写过一段时间代码,大概会碰上这么个问题:函数的返回值到底能不能声明成右值引用?网上说法很多,有人直接说不行,有人拿std::move说事,还有人搬出完美转发讲一通。今天这篇内容就围绕这个点展开…

2026云进销存选型避坑指南:共享云、独享云、私有化实测对比

2026云进销存选型避坑指南:共享云、独享云、私有化实测对比

2026/9/7 15:22:04

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

降重降得语句全废、AI率越改越高?论文季四类工具分工指南:各司其职,终稿双检稳稳过

降重降得语句全废、AI率越改越高?论文季四类工具分工指南:各司其职,终稿双检稳稳过

2026/9/7 15:22:04

又到论文季,最近被问得最多的问题不是"论文怎么写",而是"我该用哪个AI工具"。有人拿着ChatGPT改了三轮,重复率没动;有人重复率压到8%,维普AIGC一跑46%,直接被导师打回;还有…

OBS Studio 色彩校正 LUT 调色:4 类直播场景的风格选择与强度参考

OBS Studio 色彩校正 LUT 调色:4 类直播场景的风格选择与强度参考

2026/9/7 15:22:04

OBS Studio 色彩校正 LUT 调色:4 类直播场景的风格选择与强度参考 【免费下载链接】obs-studio OBS Studio - Free and open source software for live streaming and screen recording 项目地址: https://gitcode.com/GitHub_Trending/ob/obs-studio 开播半…

准备Java面试时,我如何整理项目中的亮点

准备Java面试时,我如何整理项目中的亮点

2026/9/7 15:12:04

面试时被问到“介绍一下你做的项目”,很多Java开发者明明做过不少项目,却要么讲得颠三倒四,漏了关键技术;要么说不出自己的贡献,最后让面试官误以为“你只是参与了执行,没什么能力”。其实,面试…

中国人民大学杨琳团队《Nature Communications》 | 全球潮汐湿地土壤有机碳时空格局与环境驱动:一项2009-2020年的全球评估

中国人民大学杨琳团队《Nature Communications》 | 全球潮汐湿地土壤有机碳时空格局与环境驱动:一项2009-2020年的全球评估

2026/9/6 1:19:56

本文首发于“生态学者”!从“湿地面积”到“土壤碳密度”:为什么需要重新认识潮汐湿地蓝碳变化?潮汐湿地位于陆地与海洋的交汇地带,包括红树林、盐沼和潮滩,是全球重要的蓝碳生态系统。其土壤能够长期储存大量有机碳&a…

adb抓包

adb抓包

2026/9/7 3:44:24

前言 本文介绍如何通过 tcpdump 在 Android 手机上抓取网络数据包,并在电脑端使用 Wireshark 进行分析。适用于需要排查 App 网络请求、分析接口调用或调试网络问题的开发与测试场景。1. 手机要有 root 权限2. 下载 tcpdump3. adb push C:\Users\zhangkuixun\Downlo…

大模型推理镜像极简瘦身:从 25GB 巨无霸到 3GB 精简镜像实战

大模型推理镜像极简瘦身:从 25GB 巨无霸到 3GB 精简镜像实战

2026/9/7 8:03:37

大模型推理镜像极简瘦身:从 25GB 巨无霸到 3GB 精简镜像实战 在云原生基础设施中,容器镜像体积直接决定了服务的部署速度与弹性扩容敏捷度。对于传统的 Go / Java 微服务,镜像体积通常被严格控制在 50MB 到 200MB 以内,拉取镜像只…

基于YOLOv8和PyQt5的麦穗稻穗检测识别系统设计与实现

基于YOLOv8和PyQt5的麦穗稻穗检测识别系统设计与实现

2026/9/7 0:01:24

这次我们来看一个把目标检测算法和桌面端工具结合得很典型的项目:基于 YOLOv8 PyQt5 的麦穗稻穗检测识别系统。这个项目本身不是新概念,但它的价值在于落地形态很完整。YOLOv8 负责核心的麦穗稻穗目标检测,PyQt5 负责提供可视化的桌面交互界…

UL 1642锂电池安全标准全解析:测试项目、认证流程与避坑指南

UL 1642锂电池安全标准全解析:测试项目、认证流程与避坑指南

2026/9/7 0:01:24

简介:UL 1642是锂电池安全领域的重要规范,本中文版资源适合锂电池制造商、检测机构工程师及产品认证相关人员阅读,用于理解电池在设计与制造层面的安全要求、测试方法与合规要点。资源共1个PDF文件,压缩包大小834KB,便…

BS EN 13814-1-2019游乐设施安全标准:设计与制造核心要点解析

BS EN 13814-1-2019游乐设施安全标准:设计与制造核心要点解析

2026/9/7 0:01:24

简介:BS EN 13814-1:2019是英国采纳欧洲标准EN 13814-1:2019的正式版本,由BSI标准出版,重点规定游乐设施和游乐设备在设计与制造环节的安全准则,与BS EN 13814-2:2019、BS EN 13814-3:2019共同取代旧版BS EN 13814:2004。该标准面…

远程协作的工作台整理

远程协作的工作台整理

2026/9/7 3:38:07

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/4 7:42:10

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/6 23:21:51

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…