5分钟上手Docmost富文本编辑器:从TipTap到企业级扩展开发

5分钟上手Docmost富文本编辑器:从TipTap到企业级扩展开发

【免费下载链接】docmost Docmost is an open source collaborative documentation and wiki software. It is an open-source alternative to the likes of Confluence and Notion. 【免费下载链接】docmost 项目地址: https://gitcode.com/GitHub_Trending/do/docmost

Docmost作为开源协作文档平台,其核心竞争力在于基于TipTap构建的高度可扩展富文本编辑器。本文将带你从基础配置到高级扩展,掌握如何在Docmost中开发自定义编辑器功能,解决团队协作中的文档编辑痛点。

编辑器架构概览

Docmost编辑器采用模块化设计,核心扩展位于packages/editor-ext/src/lib目录,包含30+功能模块。通过分析list_code_definition_names的输出结果,可将扩展分为四大类型:

mermaid

快速开始:基础扩展开发

1. 扩展结构模板

所有编辑器扩展遵循统一的类结构,以custom-code-block.ts为例:

import { Node, mergeAttributes } from '@tiptap/core';
import { ReactNodeViewRenderer } from '@tiptap/react';

export interface CustomExtensionOptions {
  HTMLAttributes: Record<string, any>;
  view: any; // React组件视图
}

export const CustomExtension = Node.create<CustomExtensionOptions>({
  name: 'custom-extension',
  priority: 100,
  group: 'block',
  atom: true,
  
  addOptions() {
    return {
      HTMLAttributes: {},
      view: null
    };
  },
  
  addAttributes() {
    return {
      // 定义自定义属性
    };
  },
  
  parseHTML() {
    return [{ tag: `div[data-type="${this.name}"]` }];
  },
  
  renderHTML({ HTMLAttributes }) {
    return [
      'div',
      mergeAttributes({ 'data-type': this.name }, HTMLAttributes),
      // 渲染内容
    ];
  },
  
  addNodeView() {
    return ReactNodeViewRenderer(this.options.view);
  }
});

2. 注册扩展到编辑器

在编辑器初始化文件中注册自定义扩展:

import { Editor } from '@tiptap/react';
import { CustomCodeBlock } from './custom-code-block';

const editor = new Editor({
  extensions: [
    // 基础扩展
    CustomCodeBlock.configure({
      view: CodeBlockView // 自定义React组件
    }),
    // 其他扩展...
  ]
});

核心功能扩展实战

自定义代码块:支持语法高亮与一键复制

custom-code-block.ts扩展了TipTap的code-block-lowlight,实现两大增强功能:

  1. Tab键缩进:第26-37行通过重写键盘快捷键,在代码块内按Tab键插入两个非断空格
  2. 全选功能:第38-73行实现Mod+a快捷键选中整个代码块内容

关键代码片段:

addKeyboardShortcuts() {
  return {
    Tab: () => {
      if (this.editor.isActive("codeBlock")) {
        this.editor.chain().insertText("\u00A0\u00A0").run();
        return true;
      }
    },
    "Mod-a": () => {
      // 实现代码块内容全选逻辑
    }
  };
}

@提及功能:打通用户协作

mention.ts实现了类似Notion的@提及功能,支持用户和页面两种实体类型。其核心机制是通过@tiptap/suggestion插件实现实时搜索:

suggestion: {
  char: "@",
  pluginKey: MentionPluginKey,
  command: ({ editor, range, props }) => {
    editor.chain()
      .insertContentAt(range, [
        {
          type: this.name,
          attrs: {
            entityType: props.entityType,
            entityId: props.entityId,
            label: props.label
          }
        },
        { type: "text", text: " " }
      ])
      .run();
  }
}

可视化扩展开发:Excalidraw集成

excalidraw.ts实现了在线绘图功能,通过自定义Node类型支持矢量图的嵌入与编辑:

addCommands() {
  return {
    setExcalidraw: (attrs) => ({ commands }) => {
      return commands.insertContent({
        type: 'excalidraw',
        attrs: {
          src: attrs.src,
          title: attrs.title,
          attachmentId: attrs.attachmentId
        }
      });
    }
  };
}

使用方法:

// 在编辑器中插入绘图
editor.commands.setExcalidraw({
  src: 'data:image/svg+xml;base64,...',
  title: '系统架构图',
  attachmentId: 'att_123456'
});

高级扩展技巧

1. 自定义属性与DOM渲染

所有扩展支持自定义HTML属性,如excalidraw.ts定义的绘图属性:

addAttributes() {
  return {
    src: {
      default: '',
      parseHTML: (el) => el.getAttribute('data-src'),
      renderHTML: (attrs) => ({ 'data-src': attrs.src })
    },
    // 其他属性...
  };
}

2. React组件视图

通过ReactNodeViewRenderer可以将复杂React组件集成到编辑器中,如代码块的复制按钮、Excalidraw的编辑按钮等:

addNodeView() {
  return ReactNodeViewRenderer(CodeBlockView);
}

// React组件示例
const CodeBlockView = (props) => {
  return (
    <div className="code-block">
      <pre>{props.node.attrs.code}</pre>
      <button onClick={handleCopy}>复制</button>
    </div>
  );
};

扩展注册与管理

所有扩展在packages/editor-ext/src/lib/index.ts中统一导出,形成完整的扩展集合:

export * from './custom-code-block';
export * from './excalidraw';
export * from './mention';
// 其他扩展...

在客户端应用中,通过src/components/editor/Editor.tsx集成这些扩展:

import { Editor } from '@tiptap/react';
import * as DocmostExtensions from '@docmost/editor-ext';

const extensions = [
  DocmostExtensions.CustomCodeBlock.configure({ view: CodeBlockView }),
  DocmostExtensions.Mention.configure({ 
    suggestion: {
      items: fetchUsers // 自定义数据源
    }
  })
];

实战案例:开发流程图扩展

假设需要添加一个新的流程图扩展,可以参考drawio.ts的实现模式,主要步骤:

  1. 创建flowchart.ts文件,定义Node类型
  2. 实现流程图编辑器的React组件视图
  3. 添加文件上传和数据持久化逻辑
  4. 在扩展中注册命令和快捷键

扩展开发最佳实践

  1. 属性设计:所有自定义属性使用data-*前缀,避免与标准属性冲突
  2. 性能优化:复杂视图使用React.memo包装,如excalidraw.ts
  3. 测试覆盖:为关键功能编写单元测试,参考comment.service.spec.ts
  4. 文档生成:为扩展添加JSDoc注释,便于自动生成API文档

通过本文介绍的方法,你可以为Docmost开发各种自定义编辑器功能。无论是复杂的可视化工具还是简单的交互优化,Docmost的模块化架构都能支持你快速实现。查看editor-ext README获取更多扩展示例和API参考。

【免费下载链接】docmost Docmost is an open source collaborative documentation and wiki software. It is an open-source alternative to the likes of Confluence and Notion. 【免费下载链接】docmost 项目地址: https://gitcode.com/GitHub_Trending/do/docmost

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值