ckeditor5/engine:position

path的概念

@ckeditor/ckeditor5-engine 中,path 是一个核心概念,用于表示在文档模型或视图树中某个节点的位置。path 的主要作用是帮助引擎精确地定位文档结构中的特定节点、元素或文本片段。

path 的定义

path 是一个数组,每个数组元素代表从树的根节点到目标节点的逐层索引。例如,在模型或视图树中,从根节点到某个子节点的路径可能是 [2, 3, 1],表示从根节点的第 2 个子节点开始,然后再从该子节点的第 3 个子节点进入,最后从这里进入第 1 个子节点。

path 的工作机制

  1. 层级结构的索引

    • 文档的模型或视图树是一个嵌套的层级结构,类似于 DOM 树。每个节点可以包含多个子节点,而 path 就是通过逐层索引来找到目标节点的路径。
    • path 数组中的每个元素代表在当前层级中目标节点的索引。例如,[2, 3, 1] 表示从根节点的第 2 个子节点(索引为 2 的子节点)出发,进入该子节点的第 3 个子节点,再进入该节点的第 1 个子节点。
  2. 模型中的 path

    • 在模型层中,path 用于标识文档结构中的位置。CKEditor 5 的文档模型是一棵树,path 是描述树中节点相对根节点位置的唯一方法。
    • 例如,假设模型文档结构如下:
      root
      ├── paragraph (0)
      │   ├── text "Hello" (0)
      └── paragraph (1)
          └── text "World" (0)
      
      • 在这个模型中,path[0, 0] 表示的是第一段落中的 "Hello" 文本节点,而 [1, 0] 表示的是第二段落中的 "World" 文本节点。
  3. 视图中的 path

    • 在视图层中,path 同样用于描述节点的层级关系。视图层的结构与模型类似,因此 path 在视图层的作用也类似,即用于定位 DOM 树中的具体节点或元素。

使用场景

  1. 定位节点path 用于标识和定位特定的节点,尤其是在需要修改文档内容或处理用户交互时。引擎会通过 path 来找到需要操作的模型或视图节点。

  2. 节点操作:操作(Operation)机制依赖 path 来描述文档的变更位置。例如,插入、删除、移动元素等操作都需要明确指出变更发生的位置,而 path 就是用于指定这些位置。

  3. 选区管理path 在选区管理中也至关重要。编辑器中的选区可以通过起始 path 和结束 path 来定义。通过记录选区的 path,编辑器能够在模型和视图之间保持精确的同步。

  4. 变更监听:在监听文档的变更时,path 用来标识发生变更的位置,开发者可以通过 path 来判断某个节点的具体位置,并根据需要进行操作。

例子:如何解析 path

假设你有以下模型结构:

root
├── heading (0)
│   ├── text "Title" (0)
├── paragraph (1)
│   ├── text "This is a test." (0)
└── paragraph (2)
    ├── text "Another paragraph." (0)
  • path = [0, 0] 表示 heading 下的 "Title" 文本节点。
  • path = [1, 0] 表示 paragraph 下的 "This is a test." 文本节点。
  • path = [2, 0] 表示第二个段落中的 "Another paragraph." 文本节点。

总结path的作用

@ckeditor/ckeditor5-engine 中,path 是用于表示文档树中节点位置的关键工具。它通过层级索引的方式提供了一种准确、灵活的定位方法,能够有效地处理复杂文档结构中的节点操作、选区管理和变更监听。

before和after

在 CKEditor 5 的 @ckeditor/ckeditor5-engine 中,path 不仅用于表示特定节点的位置,还提供了一些相关的辅助工具和概念,如 beforeafter,用于描述相对于当前节点位置的特定插入点。这两个概念通常用于操作模型(Model)或视图(View)的节点,例如插入、删除、移动操作时,确保准确定位。

beforeafter 的含义

  1. before:指当前节点之前的位置,即在树结构中该节点的左侧。它描述的是“在该节点的前一个位置”进行某种操作。

  2. after:指当前节点之后的位置,即在树结构中该节点的右侧。它表示“在该节点的后一个位置”进行某种操作。

这两个概念通常结合 path 来定义插入点或操作位置,用于在文档结构中进行各种修改操作,比如插入新内容或移动现有内容。

示例解析

假设有以下文档模型结构:

root
├── paragraph (0)
│   ├── text "Hello" (0)
├── paragraph (1)
│   ├── text "World" (0)
└── paragraph (2)
    ├── text "!" (0)

before

假设我们要在第一个段落之前插入一个新的段落:

  • 段落 "Hello" 的 path[0],即它在根节点的第 0 个位置。
  • before 就是指在这个 path 之前的插入点。
  • 如果我们要在段落 "Hello" 之前插入一个新的段落,我们可以选择 [0] 作为插入点。这意味着新段落将插入到现有段落 "Hello" 的 path = [0] 之前,即 [0]before 位置。

after

假设我们要在段落 "World" 之后插入一个新的段落:

  • 段落 "World" 的 path[1]
  • after 指的是在这个段落之后的位置,即段落 path = [1] 之后。
  • 如果我们想在段落 "World" 之后插入一个新的段落,插入点将是 [2],因为这是 path = [1]after 位置,即在它的后面进行插入。

使用 beforeafter 的实际场景

  1. 插入操作

    • 当我们想在某个节点之前或之后插入内容时,beforeafter 提供了精确的插入点。例如,在处理列表、段落、表格等结构时,通常会用到这些概念。
    • 例如,插入一个段落到另一个段落之前,可以使用该段落的 before 位置作为目标路径。
  2. 节点移动

    • beforeafter 也可以用于移动节点。假设要将一个节点移动到文档的某个位置,它可以被移动到目标节点的 beforeafter 位置,从而控制新节点的位置。
  3. 选择管理

    • 在管理用户选区时,选区的起点和终点也可以根据 beforeafter 来确定。例如,在光标位于某个位置时,插入文本可以发生在当前选区的 after 位置,或者在选中的内容 before 的位置。

beforeafter 的工作机制

  1. path.before()

    • 此方法用于返回表示该节点前面位置的 path。即通过调整 path 中最后一个索引减 1,来生成目标节点之前的位置。例如:
      const path = [2]; // 目标节点的路径
      const beforePath = path.before(); // 结果为 [1]
      
  2. path.after()

    • 此方法返回表示该节点后面位置的 path。即通过调整 path 中最后一个索引加 1,生成目标节点之后的位置。例如:
      const path = [2]; // 目标节点的路径
      const afterPath = path.after(); // 结果为 [3]
      

这些方法允许你轻松地获取某个节点前面或后面的插入点,尤其是在处理复杂文档结构时,能够帮助开发者精确定位操作位置。

实际代码示例

假设我们有一个段落和需要在它之前或之后插入一个新的段落,我们可以这样使用 beforeafter

const root = editor.model.document.getRoot(); // 获取模型的根节点
const paragraphPath = [0]; // 假设我们定位到第一个段落

// 获取 before 和 after 的路径
const beforeParagraphPath = paragraphPath.before(); // 在段落之前
const afterParagraphPath = paragraphPath.after(); // 在段落之后

// 插入新段落到 before 位置
editor.model.change( writer => {
    const newParagraph = writer.createElement( 'paragraph' );
    writer.insert( newParagraph, root, beforeParagraphPath );
});

// 插入新段落到 after 位置
editor.model.change( writer => {
    const newParagraph = writer.createElement( 'paragraph' );
    writer.insert( newParagraph, root, afterParagraphPath );
});

before和after的总结

  • before:表示当前节点的前一个位置,通常用于在该节点之前插入或操作。
  • after:表示当前节点的后一个位置,通常用于在该节点之后插入或操作。

这些概念在 @ckeditor/ckeditor5-engine 中非常有用,尤其是在处理复杂的文档编辑、插入节点和移动节点时,可以确保操作精确、可靠。

参考:
官网:indexes-and-offsets
ckeditor5/engine:model tree的几个概念

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容