参考手册

这是 ProseMirror 富文本编辑器的参考手册。它列出并描述了该库导出的全部公共 API。如需更多入门材料,请参阅指南

ProseMirror 由多个独立的模块组成。本参考手册按模块描述导出的 API。例如,如果你想使用 prosemirror-state 模块中的某个东西,你可以这样导入它:

var EditorState = require("prosemirror-state").EditorState
var state = EditorState.create({schema: mySchema})

或者,使用 ES6 语法:

import {EditorState} from "prosemirror-state"
let state = EditorState.create({schema: mySchema})

prosemirror-state 模块

该模块实现了 ProseMirror 编辑器的状态对象,以及选区的表示和插件抽象。

编辑器状态(Editor State)

ProseMirror 把所有编辑器状态(基本上就是创建一个与当前完全相同的编辑器所需的那些东西)保存在一个对象中。该对象通过向其应用事务来更新(创建一个新状态)。

class EditorState

ProseMirror 编辑器的状态由这种类型的对象表示。状态是一种持久数据结构——它不会被更新,而是通过 apply 方法从旧状态计算出一个新的状态值。

状态持有许多内置字段,插件也可以定义额外的字段。

doc: Node

当前文档。

selection: Selection

选区。

storedMarks: readonly Mark[] | null

要应用到下一次输入的一组标记。当没有显式设置标记时,该值为 null。

schema: Schema

状态文档的 schema。

plugins: readonly Plugin[]

在此状态下激活的插件。

apply(trTransaction) → EditorState

应用给定的事务以产生新状态。

applyTransaction(rootTrTransaction) → {stateEditorState, transactionsreadonly Transaction[]}

apply 的详细版本,返回实际应用的事务(可能受插件事务钩子的影响)以及新状态。

tr: Transaction

从该状态构造并返回一个新事务的访问器。

reconfigure(configObject) → EditorState

基于此状态创建新状态,但使用调整后的激活插件集。两个插件集中都存在的状态字段保持不变,不再存在的被丢弃,新加入的则用其 init 方法初始化,并传入新的配置对象。

config
plugins⁠?: readonly Plugin[]

新的激活插件集。

toJSON(pluginFields⁠?: Object<Plugin>) → any

将该状态序列化为 JSON。如果你想序列化插件状态,请传入一个对象,把要在结果 JSON 对象中使用的属性名映射到插件对象。该参数也可以是字符串或数字,此时它会被忽略,以支持 JSON.stringify 调用 toString 方法的方式。

static create(configEditorStateConfig) → EditorState

创建新状态。

static fromJSON(
jsonany,
) → EditorState

反序列化状态的 JSON 表示。config 至少应有一个 schema 字段,并应包含用于初始化状态的插件数组。pluginFields 可用于反序列化插件状态,通过把插件实例与它们在 JSON 对象中使用的属性名关联起来。

config
schema: Schema

要使用的 schema。

plugins⁠?: readonly Plugin[]

激活插件集。

interface EditorStateConfig

传给 EditorState.create 的对象类型。

schema⁠?: Schema

要使用的 schema(仅当未指定 doc 时才相关)。

doc⁠?: Node

起始文档。此字段与 schema 必须提供其一。

selection⁠?: Selection

文档中的一个合法选区。

storedMarks⁠?: readonly Mark[]

初始的存储标记集。

plugins⁠?: readonly Plugin[]

应在此状态下激活的插件。

class Transaction extends Transform

一个编辑器状态事务,可应用于状态以创建更新后的状态。使用 EditorState.tr 创建实例。

事务跟踪文档的更改(它们是 Transform 的子类),也跟踪其他状态更改,如选区更新和存储标记集的调整。此外,你可以在事务中存储元数据属性,这些是客户端代码或插件可以用来描述事务含义的额外信息,以便它们相应地更新自己的状态。

编辑器视图使用几个元数据属性:它会给由鼠标或触摸输入直接引起的选区事务附加值为 true 的 "pointer" 属性,给由组合 DOM 输入引起的事务附加一个持有组合 ID 的 "composition" 属性,以及一个 "uiEvent" 属性,其值可能是 "paste""cut""drop"

time: number

与此事务关联的时间戳,格式与 Date.now() 相同。

storedMarks: readonly Mark[] | null

此事务设置的存储标记(如果有)。

selection: Selection

事务当前的选区。默认是编辑器选区映射过事务中的步骤后得到的,但可以用 setSelection 覆盖。

setSelection(selectionSelection) → Transaction

更新事务的当前选区。将决定事务被应用时编辑器得到的选区。

selectionSet: boolean

选区是否被此事务显式更新过。

setStoredMarks(marksreadonly Mark[] | null) → Transaction

设置当前的存储标记。

ensureMarks(marksreadonly Mark[]) → Transaction

确保当前的存储标记(如果为 null,则为选区处的标记)与给定的标记集匹配。如果已经匹配则什么都不做。

addStoredMark(markMark) → Transaction

向存储标记集添加一个标记。

removeStoredMark(markMark | MarkType) → Transaction

从存储标记集中移除一个标记或标记类型。

storedMarksSet: boolean

存储标记是否为此事务显式设置过。

setTime(timenumber) → Transaction

更新事务的时间戳。

replaceSelection(sliceSlice) → Transaction

用给定的切片替换当前选区。

replaceSelectionWith(nodeNode, inheritMarks⁠?: boolean = true) → Transaction

用给定的节点替换选区。当 inheritMarks 为 true 且内容是行内内容时,它会继承插入位置的标记。

deleteSelection() → Transaction

删除选区。

insertText(textstring, from⁠?: number, to⁠?: number) → Transaction

用包含给定字符串的文本节点替换给定范围(或未给范围时的选区)。

setMeta(
valueany
) → Transaction

在此事务中存储一个元数据属性,按名称或插件作为键。

getMeta(keystring | Plugin | PluginKey) → any

按给定名称或插件检索元数据属性。

isGeneric: boolean

如果此事务不包含任何元数据,并且因此可以安全地扩展,则返回 true。

scrollIntoView() → Transaction

指示编辑器在更新到由此事务产生的状态时,应将选区滚动到可见区域。

scrolledIntoView: boolean

此事务是否调用过 scrollIntoView

type Command = fn(
dispatch⁠?: fn(trTransaction),
) → boolean

命令是接收一个状态和一个可选的事务派发函数并……的函数。

  • determine whether they apply to this state
  • if not, return false
  • if dispatch was passed, perform their effect, possibly by passing a transaction to dispatch
  • return true

在某些情况下,编辑器视图会作为第三个参数传入。

选区(Selection)

ProseMirror 选区可以是几种类型之一。此模块定义了经典文本选区(其中光标是特例)和节点选区(选中特定文档节点)的类型。可以用自定义选区类型扩展编辑器。

abstract class Selection

编辑器选区的父类。每种选区类型都应扩展它。不应直接实例化。

new Selection(
ranges⁠?: readonly SelectionRange[]
)

用 head、anchor 和 ranges 初始化选区。如果未给出 ranges,则构造一个横跨 $anchor$head 的单一范围。

$anchor: ResolvedPos

选区的已解析锚点(选区被修改时保持不动的一侧)。

$head: ResolvedPos

选区的已解析头部(选区被修改时移动的一侧)。

ranges: readonly SelectionRange[]

选区覆盖的范围。

anchor: number

选区的锚点,作为未解析位置。

head: number

选区的头部。

from: number

选区主范围的下界。

to: number

选区主范围的上界。

$from: ResolvedPos

选区主范围的已解析下界。

$to: ResolvedPos

选区主范围的已解析上界。

empty: boolean

指示选区是否包含任何内容。

abstract eq(selectionSelection) → boolean

测试该选区是否与另一个选区相同。

abstract map(docNode, mappingMappable) → Selection

将选区映射过一个可映射对象。doc 应是我们映射到的新文档。

content() → Slice

将该选区的内容作为切片获取。

replace(
content⁠?: Slice = Slice.empty
)

用切片替换选区,或(未给切片时)删除选区。将追加到给定事务中。

replaceWith(trTransaction, nodeNode)

用给定节点替换选区,将更改追加到给定事务。

abstract toJSON() → any

将选区转换为 JSON 表示。为自定义选区类实现此方法时,务必给对象一个 type 属性,其值与你注册该类所用的 ID 匹配。

getBookmark() → SelectionBookmark

获取该选区的书签,它是一个无需访问当前文档即可映射、之后可再解析为给定文档的真实选区的值。(这主要用于历史记录追踪和恢复旧选区。)此方法的默认实现只是把选区转换为文本选区并返回其书签。

visible: boolean

控制当此类型的选区在浏览器中激活时,选中的范围是否应对用户可见。默认为 true。

static findFrom(
textOnly⁠?: boolean = false
) → Selection | null

从给定位置开始查找有效的光标或叶子节点选区,dir 为负时向后搜索,为正时向前搜索。当 textOnly 为 true 时,只考虑光标选区。未找到有效选区位置时返回 null。

static near($posResolvedPos, bias⁠?: number = 1) → Selection

在给定位置附近查找有效的光标或叶子节点选区。默认先向前搜索,但若 bias 为负,则先向后搜索。

static atStart(docNode) → Selection

查找最接近给定文档开头的光标或叶子节点选区。若无有效位置,将返回 AllSelection。

static atEnd(docNode) → Selection

查找最接近给定文档末尾的光标或叶子节点选区。

static fromJSON(docNode, jsonany) → Selection

反序列化选区的 JSON 表示。必须为自定义类实现(作为静态类方法)。

static jsonID(
selectionClass: {fromJSONfn(docNode, jsonany) → Selection}
) → {fromJSONfn(docNode, jsonany) → Selection}

为了能从 JSON 反序列化选区,自定义选区类必须用 ID 字符串注册自己,以便消除歧义。尽量选择不太可能与其他模块的类冲突的 ID。

class TextSelection extends Selection

文本选区表示经典的编辑器选区,具有 head(移动侧)和 anchor(不动侧),两者都指向 textblock 节点。它可以是空的(普通光标位置)。

new TextSelection(
$head⁠?: ResolvedPos = $anchor
)

在给定点之间构造文本选区。

$cursor: ResolvedPos | null

如果这是光标选区(空文本选区),返回已解析位置,否则返回 null。

static create(
docNode,
head⁠?: number = anchor
) → TextSelection

从非解析位置创建文本选区。

static between(
bias⁠?: number
) → Selection

返回跨越给定位置的文本选区,或者(如果它们不是文本位置)在它们附近找一个文本选区。bias 决定方法是先向前搜索(默认)还是向后搜索(负数)。当文档中不含有效文本位置时,将回退到调用 Selection.near

class NodeSelection extends Selection

节点选区是指向单个节点的选区。所有标记为可选择的节点都可以作为节点选区的目标。在这种选区中,fromto 直接指向所选节点的前后,anchor 等于 fromhead 等于 to

new NodeSelection($posResolvedPos)

创建节点选区。不验证其参数的有效性。

node: Node

选中的节点。

static create(docNode, fromnumber) → NodeSelection

从非解析位置创建节点选区。

static isSelectable(nodeNode) → boolean

判断给定节点是否可以作为节点选区被选中。

class AllSelection extends Selection

一种表示选中整个文档的选区类型(当文档开头或结尾有叶子块节点等情况下,这不一定能用文本选区表达)。

new AllSelection(docNode)

在给定文档上创建全选选区。

class SelectionRange

表示文档中的一个选中范围。

new SelectionRange($fromResolvedPos, $toResolvedPos)

创建范围。

$from: ResolvedPos

范围的下界。

$to: ResolvedPos

范围的上界。

interface SelectionBookmark

一种轻量级、与文档无关的选区表示。你可以为自定义选区类定义自定义书签类型,使历史记录能很好地处理它。

map(mappingMappable) → SelectionBookmark

将书签映射过一组更改。

resolve(docNode) → Selection

将书签重新解析为真实选区。这可能需要做一些错误检查,如果映射使书签无效,可能回退到默认值(通常是 TextSelection.between)。

插件系统(Plugin System)

为了方便打包和启用额外的编辑器功能,ProseMirror 提供了插件系统。

interface PluginSpec<PluginState>

这是传给 Plugin 构造函数的类型。它为插件提供定义。

props⁠?: EditorProps<Plugin<PluginState>>

此插件添加的视图 props。作为函数的 props 会被绑定为以插件实例作为其 this 绑定。

state⁠?: StateField<PluginState>

允许插件定义一个状态字段,即状态对象中一个用于保存自己数据的额外槽位。

key⁠?: PluginKey

可用于使其成为带键插件。在给定状态中,给定键只能有一个插件,但可以通过键访问插件的配置和状态,而无需访问插件实例对象。

view⁠?: fn(viewEditorView) → PluginView

当插件需要与编辑器视图交互,或在 DOM 中设置某些东西时,使用此字段。当插件状态与编辑器视图关联时,该函数会被调用。

filterTransaction⁠?: fn(trTransaction, stateEditorState) → boolean

当存在时,这会在状态应用事务之前被调用,允许插件取消它(通过返回 false)。

appendTransaction⁠?: fn(
transactionsreadonly Transaction[],
) → Transaction | null | undefined

允许插件追加另一个事务,在给定事务数组之后被应用。当另一个插件在此调用之后追加事务时,它会再次用新状态和新事务被调用——但只传入新的事务,即不会传入它已经见过的事务。

[string]: any

插件 spec 上允许有其他属性,可以通过 Plugin.spec 读取。

interface StateField<T>

插件 spec 可以在其 state 属性下提供此类型的状态字段,描述它想保持的状态。这里提供的函数总是以插件实例作为其 this 绑定被调用。

init() → T

初始化字段的值。config 是传给 EditorState.create 的对象。注意,instance 是一个半初始化的状态实例,在其之后初始化的插件字段还没有值。

apply(
valueT,
) → T

将给定事务应用到此状态字段,产生新字段值。注意,newState 参数同样是一个部分构造的状态,尚未包含此插件之后的插件的状态。

toJSON⁠?: fn(valueT) → any

将此字段转换为 JSON。可选,可省略以禁用该字段的 JSON 序列化。

fromJSON⁠?: fn(
valueany,
) → T

反序列化此字段的 JSON 表示。注意,state 参数同样是一个半初始化的状态。

type PluginView

一个可由插件安装在编辑器中的有状态对象。

update⁠?: fn(viewEditorView, prevStateEditorState)

每当视图状态更新时调用。

destroy⁠?: fn()

当视图被销毁或收到具有不同插件的状态时调用。

class Plugin<PluginState = any>

插件捆绑可添加到编辑器的功能。它们是编辑器状态的一部分,并可能影响该状态以及包含它的视图。

new Plugin(specPluginSpec<PluginState>)

创建插件。

spec: PluginSpec<PluginState>

插件的 spec 对象

props: EditorProps<Plugin<PluginState>>

此插件导出的 props。

getState(stateEditorState) → PluginState | undefined

从编辑器状态提取插件的状态字段。

class PluginKey<PluginState = any>

键用于给插件打标签,使得给定编辑器状态时能够找到它们。分配键确实意味着给定类型只能有一个插件在状态中激活。

new PluginKey(name⁠?: string = "key")

创建插件键。

get(stateEditorState) → Plugin<PluginState> | undefined

从编辑器状态获取此键下的激活插件(如果有)。

getState(stateEditorState) → PluginState | undefined

从编辑器状态获取插件状态。

prosemirror-view 模块

ProseMirror 的 view 模块在 DOM 中显示给定的编辑器状态,并处理用户事件。

使用此模块时,务必加载 style/prosemirror.css 作为样式表。

class EditorView

编辑器视图管理表示可编辑文档的 DOM 结构。其状态和行为由它的props 决定。

new EditorView(
placeDOMNode |
{mountHTMLElement} |
,
)

创建视图。place 可以是编辑器应追加到的 DOM 节点、一个将其放入文档的函数,或一个 mount 属性保存文档容器节点的对象。如果为 null,编辑器不会被添加到文档中。

state: EditorState

视图的当前状态

dom: HTMLElement

包含文档的可编辑 DOM 节点。(你大概不应该直接干预其内容。)

editable: boolean

指示编辑器当前是否可编辑

dragging: {sliceSlice, moveboolean} | null

当编辑器内容被拖动时,此对象包含被拖动切片以及它是复制还是移动的信息。其他任何时候,它都是 null。

composing: boolean

当组合输入(composition)激活时,此值为 true。

props: DirectEditorProps

视图的当前 props

update(propsDirectEditorProps)

更新视图的 props。会立即引起 DOM 更新。

setProps(propsPartial<DirectEditorProps>)

用给定参数对象更新现有 props 对象来更新视图。等价于 view.update(Object.assign({}, view.props, props))

updateState(stateEditorState)

更新编辑器的 state prop,不触及任何其他 props。

someProp<PropName extends keyof EditorProps, Result>() → Result | undefined

遍历某个 prop 的值,先是直接提供的,然后是给视图的插件,然后是状态中的插件(按顺序),每次找到非 undefined 的值就调用 f。当 f 返回真值时立即返回。未提供 f 时,视为恒等函数(直接返回 prop 值)。

hasFocus() → boolean

查询视图是否有焦点。

focus()

聚焦编辑器。

root: Document | ShadowRoot

获取编辑器所在的文档根。通常是顶层 document,但如果编辑器位于 shadow DOM 中,则可能是 shadow root。

updateRoot()

当现有编辑器视图被移到新的文档或 shadow 树中时,调用此方法使其重新计算根。

posAtCoords(coords: {leftnumber, topnumber}) → {posnumber, insidenumber} | null

给定一对视口坐标,返回它们对应的文档位置。如果给定坐标不在编辑器内部,可能返回 null。返回对象时,其 pos 属性是最接近坐标的位置,inside 属性保存该位置落入的内部节点的位置,若在顶层(不在任何节点中)则为 -1。

coordsAtPos(posnumber, side⁠?: number = 1) → {leftnumber, rightnumber, topnumber, bottomnumber}

返回给定文档位置处的视口矩形。leftright 会是同一个数,因为这返回一个扁平的光标状矩形。如果位置位于两个不直接相邻的东西之间,side 决定使用哪个元素。当小于 0 时,使用位置之前的元素,否则使用之后的元素。

domAtPos(posnumber, side⁠?: number = 0) → {nodeDOMNode, offsetnumber}

查找与给定文档位置对应的 DOM 位置。当 side 为负时,尽量找位置之前内容附近的位置。为正时,优先找位置之后内容附近的位置。为零时,尽量找尽可能浅的位置。

注意,你不应修改编辑器的内部 DOM,只能检查它(而且通常连检查都不必要)。

nodeDOM(posnumber) → DOMNode | null

查找表示给定位置之后文档节点的 DOM 节点。当位置不指向节点之前,或该节点位于不透明的节点视图内时,可能返回 null。

这是为了能对该 DOM 节点调用 getBoundingClientRect 之类的方法。不要直接修改编辑器 DOM,或以此方式添加样式,因为编辑器重绘该节点时会立即覆盖。

posAtDOM(
bias⁠?: number = -1
) → number

查找与给定 DOM 位置对应的文档位置。(只要可能,最好直接检查文档结构,而不是在 DOM 中翻找,但有时——例如解释事件目标时——你别无选择。)

bias 参数可用于在位置位于叶子节点内时影响使用 DOM 节点的哪一侧。

endOfTextblock(
dir"up" |
"down" |
"left" |
"right" |
"forward" |
"backward"
,
) → boolean

判断当向给定方向移动时,选区是否在 textblock 的末尾。例如给定 "left",如果从当前光标位置向左移动会离开该位置的父 textblock,则返回 true。默认作用于视图的当前状态,但也可以传入不同的状态。

pasteHTML(htmlstring, event⁠?: ClipboardEvent) → boolean

用给定 HTML 字符串运行编辑器的粘贴逻辑。如果给出 event,将传给 handlePaste 钩子。

pasteText(textstring, event⁠?: ClipboardEvent) → boolean

用给定的纯文本输入运行编辑器的粘贴逻辑。

serializeForClipboard(sliceSlice) → {domHTMLElement, textstring, sliceSlice}

将该切片按从编辑器复制时的样子序列化。返回一个 DOM 元素,其子节点是切片的表示、文本表示,以及变换后的切片(由于 transformCopied 之类的钩子,可能与给定输入不同)。

destroy()

将编辑器从 DOM 中移除,并销毁所有节点视图

isDestroyed: boolean

当视图已被销毁(因此不应再使用)时,此值为 true。

dispatchEvent(eventEvent)

用于测试。

dispatch(trTransaction)

派发一个事务。若给定 dispatchTransaction 则调用它,否则默认将事务应用到当前状态并用结果调用 updateState。此方法绑定到视图实例,便于到处传递。

Props

interface EditorProps<P = any>

Props 是可以传给编辑器视图或包含在插件中的配置值。此接口列出受支持的 props。

各种事件处理函数都可以返回 true 表示它们处理了给定事件。视图随后会负责对事件调用 preventDefaulthandleDOMEvents 除外,它由处理函数自己负责。

prop 如何解析取决于该 prop。处理函数一次调用一个,从基础 props 开始,然后按出现顺序搜索插件,直到其中一个返回 true。对于某些 props,第一个产生值的插件获得优先权。

可选类型参数指 prop 函数中 this 的类型,用于在定义插件时传入插件类型。

handleDOMEvents⁠?: {}

可以是一个把 DOM 事件类型名映射到处理函数的对象。这些函数会在 ProseMirror 对可编辑 DOM 元素上触发的事件做任何处理之前被调用。与其他事件处理 props 相反,从此类函数返回 true 时,你要自己负责调用 preventDefault(或者不调用,如果你想允许默认行为)。

handleKeyDown⁠?: fn(viewEditorView, eventKeyboardEvent) → boolean | undefined

编辑器收到 keydown 事件时调用。

handleKeyPress⁠?: fn(viewEditorView, eventKeyboardEvent) → boolean | undefined

keypress 事件的处理函数。

handleTextInput⁠?: fn(
defltfn() → Transaction
) → boolean | undefined

每当用户直接输入文本时,此处理函数会在输入被应用之前调用。如果返回 true,则抑制实际插入文本的默认行为。

handleClickOn⁠?: fn() → boolean | undefined

对点击周围的每个节点调用,从内到外。对内部节点,direct 标志为 true。

handleClick⁠?: fn() → boolean | undefined

编辑器被点击时调用,在 handleClickOn 处理函数之后。

handleDoubleClickOn⁠?: fn() → boolean | undefined

对双击周围的每个节点调用。

handleDoubleClick⁠?: fn() → boolean | undefined

编辑器被双击时调用,在 handleDoubleClickOn 之后。

handleTripleClickOn⁠?: fn() → boolean | undefined

对三击周围的每个节点调用。

handleTripleClick⁠?: fn() → boolean | undefined

编辑器被三击时调用,在 handleTripleClickOn 之后。

handlePaste⁠?: fn() → boolean | undefined

可用于覆盖粘贴行为。slice 是编辑器解析的粘贴内容,但你也可以直接访问事件以获取原始内容。

handleDrop⁠?: fn() → boolean | undefined

当有东西被放到编辑器上时调用。如果此放置是从当前选区移动,moved 为 true(因此应删除选区)。

handleScrollToSelection⁠?: fn(viewEditorView) → boolean

当视图更新其状态后尝试将选区滚动到可见区域时调用。处理函数可返回 false 表示它没有处理滚动,应尝试其他处理函数或默认行为。

dragCopies⁠?: fn(eventDragEvent) → boolean

决定编辑器内拖动事件应复制还是移动选区。未给定时,在 macOS 上使用事件的 altKey 属性,其他平台使用 ctrlKey

createSelectionBetween⁠?: fn() → Selection | null

可用于覆盖在给定 anchor 和 head 之间读取 DOM 选区时创建选区的方式。

domParser⁠?: DOMParser

从 DOM 读取编辑器变化时使用的解析器。默认在编辑器 schema 上调用 DOMParser.fromSchema

transformPastedHTML⁠?: fn(htmlstring, viewEditorView) → string

可用于在解析之前变换粘贴的 HTML 文本,例如清理它。

clipboardParser⁠?: DOMParser

从剪贴板读取内容时使用的解析器。未给定时,使用 domParser prop 的值。

transformPastedText⁠?: fn() → string

变换粘贴的纯文本。当文本以纯文本粘贴时,plain 标志为 true。

clipboardTextParser⁠?: fn() → Slice

把剪贴板中的文本解析为文档切片的函数。在 transformPastedText 之后调用。默认行为是把文本按行拆分,用 <p> 标签包裹,然后对其调用 clipboardParser。当文本以纯文本粘贴时,plain 标志为 true。

transformPasted⁠?: fn() → Slice

可用于在粘贴或拖放内容被应用到文档之前变换它。当文本以纯文本粘贴时,plain 标志为 true。

transformCopied⁠?: fn(sliceSlice, viewEditorView) → Slice

可用于在复制或剪切内容被序列化到剪贴板之前变换它。

nodeViews⁠?: Object<NodeViewConstructor>

允许你为节点传入自定义渲染和行为逻辑。应把节点名映射到产生实现节点显示行为的 NodeView 对象的构造函数。第三个参数 getPos 是一个函数,可调用来获取节点当前位置,在创建更新节点的事务时很有用。注意,如果节点不在文档中,此函数返回的位置将是 undefined

decorations 是节点周围激活的节点或行内装饰数组。它们会自动以正常方式绘制,你通常只需忽略它,但它也可以作为向节点视图提供上下文信息的一种方式,而无需将其添加到文档本身。

innerDecorations 保存节点内容的装饰。如果你的视图没有内容或没有 contentDOM 属性,你可以安全地忽略它,因为编辑器会在内容上绘制装饰。但如果你,例如,想用内容创建嵌套编辑器,把内部装饰提供给它可能是有意义的。

(出于向后兼容的原因,标记视图也可以包含在此对象中。)

markViews⁠?: Object<MarkViewConstructor>

传入自定义标记渲染函数。注意,这些不能提供节点视图那样的动态行为——它们只提供自定义渲染逻辑。第三个参数指示标记的内容是否为行内内容。

clipboardSerializer⁠?: DOMSerializer

把内容放到剪贴板时使用的 DOM 序列化器。若未给定,将使用 DOMSerializer.fromSchema 的结果。此对象只会调用其 serializeFragment 方法,你可以提供实现兼容方法的替代对象类型。

clipboardTextSerializer⁠?: fn(contentSlice, viewEditorView) → string

一个函数,在把文本复制到剪贴板时被调用,以获取当前选区的文本。默认情况下,编辑器对选中范围使用 textBetween

decorations⁠?: fn(stateEditorState) → DecorationSource | null | undefined

要在视图中显示的文档装饰集。

editable⁠?: fn(stateEditorState) → boolean

当它返回 false 时,视图内容不可直接编辑。

attributes⁠?: Object<string> |

控制可编辑元素的 DOM 属性。可以是对象,也可以是从编辑器状态到对象的函数。默认情况下,该元素会得到 class "ProseMirror",其 contentEditable 属性由 editable prop 决定。这里提供的其他 class 会追加到 class 中。对于其他属性,使用第一个提供的值(如 someProp)。

scrollThreshold⁠?: number |
{topnumber, rightnumber, bottomnumber, leftnumber}

决定光标与可见视口末端的距离(像素),当把光标滚动到可见区域时,达到该距离就开始滚动。默认为 0。

scrollMargin⁠?: number |
{topnumber, rightnumber, bottomnumber, leftnumber}

决定光标被滚动到可见区域时在其上方或下方留出的额外空间(像素)。默认为 5。

type NodeViewConstructor = fn(
getPosfn() → number | undefined,
decorationsreadonly Decoration[],
) → NodeView

用于创建节点视图的函数类型。

type MarkViewConstructor = fn() → MarkView

用于创建标记视图的函数类型。

interface DirectEditorProps extends EditorProps

直接给编辑器视图的 props 对象支持一些不能在插件中使用的字段:

state: EditorState

编辑器的当前状态。

plugins⁠?: readonly Plugin[]

要在视图中使用的一组插件,应用它们的插件视图和 props。传入带有状态组件(状态字段、事务过滤器或追加器)的插件会导致错误,因为这类插件必须存在于状态中才能工作。

dispatchTransaction⁠?: fn(trTransaction)

视图产生的事务(状态更新)所要发送到的回调。如果你指定它,你大概要确保它最终用应用了事务的新状态调用视图的 updateState 方法。回调会被绑定为以视图实例作为其 this 绑定。

interface NodeView

默认情况下,文档节点用其 spec 的 toDOM 方法结果渲染,并完全由编辑器管理。对于某些用例,例如嵌入的节点专用编辑界面,你想对节点在编辑器内表示的行为有更多控制,就需要定义自定义节点视图。

作为节点视图返回的对象必须符合此接口。

dom: HTMLElement

表示文档节点的外层 DOM 节点。

contentDOM⁠?: HTMLElement

应保存节点内容的 DOM 节点。仅当节点视图也定义了 dom 属性且其节点类型不是叶子节点类型时才有意义。当它存在时,ProseMirror 会负责把节点的子节点渲染到其中。当它不存在时,节点视图自己负责渲染(或决定不渲染)其子节点。

update⁠?: fn(
decorationsreadonly Decoration[],
) → boolean

当给定时,这会在视图更新自身时被调用。它会得到一个节点、节点周围激活的装饰数组(自动绘制,节点视图若不感兴趣可忽略),以及一个表示应用于节点内容装饰的装饰源(同样可忽略)。如果它能更新到该节点,应返回 true,否则返回 false。如果节点视图有 contentDOM 属性(或没有 dom 属性),更新其子节点由 ProseMirror 处理。

multiType⁠?: boolean

默认情况下,update 只会在相同节点类型的节点出现在此视图位置时被调用。当你把它设为 true 时,它会对任何节点被调用,使节点视图能够表示多种类型的节点。你需要检查在 update 中得到的节点类型,并对无法处理的类型返回 false。

selectNode⁠?: fn()

可用于覆盖节点选中状态(作为节点选区)的显示方式。

deselectNode⁠?: fn()

定义 selectNode 方法时,你也应提供 deselectNode 方法来移除效果。

setSelection⁠?: fn()

这会被调用来处理节点内部选区的设置。anchor 和 head 位置相对于节点开头。默认会在这两个位置对应的 DOM 位置之间创建 DOM 选区,但如果你覆盖它,可以做别的事。

stopEvent⁠?: fn(eventEvent) → boolean

可用于阻止编辑器视图处理从节点视图冒泡上来的一些或全部 DOM 事件。此方法返回 true 的事件不会被编辑器处理。

ignoreMutation⁠?: fn(mutationViewMutationRecord) → boolean

当视图内发生变更(mutation)时调用。若编辑器应重新读取选区或重新解析变更周围的范围,返回 false;若能安全忽略,返回 true。

destroy⁠?: fn()

当节点视图从编辑器移除或整个编辑器被销毁时调用。

interface MarkView

默认情况下,文档标记用其 spec 的 toDOM 方法结果渲染,并完全由编辑器管理。对于某些用例,你想对标记在编辑器内表示的行为有更多控制,就需要定义自定义标记视图。

作为标记视图返回的对象必须符合此接口。

dom: HTMLElement

表示文档节点的外层 DOM 节点。

contentDOM⁠?: HTMLElement

应保存标记内容的 DOM 节点。当它不存在时,使用 dom 属性作为内容 DOM。

update⁠?: fn(markMark) → boolean

当给定时,这会在视图更新自身时被调用。它会得到一个标记(与当前标记同类型)。当它返回 true 时,保留并复用现有 DOM(其内容仍由 ProseMirror 管理);当它返回 false 时,重建标记视图。

ignoreMutation⁠?: fn(mutationViewMutationRecord) → boolean

当视图内发生变更(mutation)时调用。若编辑器应重新读取选区或重新解析变更周围的范围,返回 false;若能安全忽略,返回 true。

destroy⁠?: fn()

当标记视图从编辑器移除或整个编辑器被销毁时调用。

type ViewMutationRecord = MutationRecord |
{type"selection", targetDOMNode}

ViewMutationRecord 表示视图内发生的 DOM 变更或选区变化。当变化是选区变化时,记录会有值为 "selection"type 属性(原生 mutation 记录不会有此情况)。

interface DOMEventMap extends HTMLElementEventMap

把事件名映射到事件对象类型的辅助类型,但包含 TypeScript 的 HTMLElementEventMap 不知道的事件。

[string]: any

装饰(Decorations)

装饰使你能够影响文档的绘制方式,而无需实际更改文档。

class Decoration

装饰对象可以通过 decorations prop 提供给视图。它们有几种变体——详见此类的静态成员。

from: number

装饰的开始位置。

to: number

结束位置。对于 widget 装饰,与 from 相同。

spec: any

创建此装饰时提供的 spec。如果你在该对象中存储了额外信息,这会很有用。

static widget(
toDOMfn(
getPosfn() → number | undefined
) → DOMNode | ,
spec⁠?: Object
) → Decoration

创建 widget 装饰,即在文档给定位置显示的一个 DOM 节点。建议传入一个函数(在 widget 实际被绘制到视图中时才调用)来延迟渲染,但你也可以直接传 DOM 节点。getPos 可用于查找 widget 当前的文档位置。

spec
side⁠?: number

控制此 widget 关联文档位置的哪一侧。为负时,它绘制在该位置光标之前,插入到该位置的内容会落到 widget 之后。为零(默认)或正时,widget 绘制在光标之后,插入到那里的内容会落到 widget 之前。

当给定位置有多个 widget 时,它们的 side 值决定出现顺序。值较低的先出现。相同 side 值的 widget 顺序未指定。

marks 为 null 时,side 还决定 widget 被包裹在哪些标记中——为负时是前面节点的标记,为正时是后面节点的标记。

relaxedSide⁠?: boolean

默认情况下,光标在 widget 位置时会被严格保持在 side 指示的一侧。设为 true 允许 DOM 选区在客户端将其设置到另一侧时停留在那一侧。

注意:此装饰的映射(决定在其位置插入的内容出现在哪一侧)仍会按 side 进行,而键盘光标移动在没有进一步自定义处理的情况下不会访问 widget 的两侧。

marks⁠?: readonly Mark[]

要绘制在 widget 周围的精确标记集。

stopEvent⁠?: fn(eventEvent) → boolean

可用于控制哪些 DOM 事件在从该 widget 冒泡出来时,编辑器视图应忽略。

ignoreSelection⁠?: boolean

当设置(默认 false)时,widget 内部的选区变化会被忽略,不会导致 ProseMirror 尝试将其选区与选区状态重新同步。

key⁠?: string

当比较此类型的装饰(以决定是否需要重绘)时,ProseMirror 默认按身份比较 widget DOM 节点。如果你传入一个 key,则改为比较该键,这在即时生成装饰且不想存储和复用 DOM 节点时很有用。确保任何具有相同键的 widget 可以互换——如果 widget 在例如某个事件处理器的行为上不同,它们应该得到不同的键。

destroy⁠?: fn(nodeDOMNode)

当 widget 装饰被移除或编辑器被销毁时调用。

[string]: any

spec 允许任意附加属性。

static inline(
spec⁠?: Object
) → Decoration

创建行内装饰,把给定属性添加到 fromto 之间的每个行内节点上。

spec
inclusiveStart⁠?: boolean

决定当内容直接插入到该位置时,装饰的左侧如何映射。默认装饰不包含新内容,但你可以设为 true 使其包容。

inclusiveEnd⁠?: boolean

决定装饰右侧如何映射。见 inclusiveStart

[string]: any

spec 可以有任意附加属性。

static node(
spec⁠?: any
) → Decoration

创建节点装饰。fromto 应精确指向文档中某节点的前后。该节点(且只有该节点)会得到给定属性。

type DecorationAttrs

要添加到被装饰节点的一组属性。大多数属性直接对应同名 DOM 属性,会被设为该属性的值。以下为例外:

nodeName⁠?: string

当非 null 时,目标节点被包裹在此类型的 DOM 元素中(其他属性应用到此元素)。

class⁠?: string

要添加到节点已有 class 中的 CSS 类名或空格分隔的一组类名。

style⁠?: string

要添加到节点现有 style 属性的 CSS 字符串。

[string]: string | undefined

任何其他属性都被视为常规 DOM 属性。

class DecorationSet implements DecorationSource

一个装饰集合,其组织方式使绘制算法能高效地使用和比较它们。这是持久数据结构——它不被修改,更新创建新值。

find(
start⁠?: number,
end⁠?: number,
predicate⁠?: fn(specany) → boolean
) → Decoration[]

查找此集合中触及给定范围(包括正好在边界处开始或结束的装饰)且 spec 匹配给定谓词的所有装饰。省略 startend 时考虑集合中所有装饰。未给谓词时,假定所有装饰都匹配。

map(mappingMapping, docNode, options⁠?: Object) → DecorationSet

响应文档更改而映射装饰集。

options
onRemove⁠?: fn(decorationSpecany)

当给定时,此函数会对每个因映射而被丢弃的装饰调用,传入该装饰的 spec。

add(docNode, decorationsDecoration[]) → DecorationSet

把给定装饰数组加入集合中的装饰,产生新集合。会消费装饰数组。需要访问当前文档以创建适当的树结构。

remove(decorationsDecoration[]) → DecorationSet

创建包含此集合中的装饰、减去给定数组中的装饰的新集合。

static create(docNode, decorationsDecoration[]) → DecorationSet

使用给定文档的结构创建装饰集。这会消费(修改)装饰数组,所以如果你想保留它,必须先复制。

static empty: DecorationSet

空装饰集。

interface DecorationSource

可以提供装饰的对象。由 DecorationSet 实现,并传给节点视图

map(mappingMapping, nodeNode) → DecorationSource

响应文档更改而映射装饰集。

forChild(offsetnumber, childNode) → DecorationSource

提取包含给定偏移处给定子节点装饰的 DecorationSource。

forEachSet(ffn(setDecorationSet))

对组中的每个装饰集调用给定函数。

prosemirror-model 模块

此模块定义 ProseMirror 的内容模型,即用于表示和处理文档的数据结构。

文档结构(Document Structure)

ProseMirror 文档是一棵树。在每一层,一个节点描述内容类型,并持有一个包含其子节点的片段。

class Node

此类表示构成 ProseMirror 文档的树中的节点。所以文档是 Node 的实例,其子节点也是 Node 的实例。

节点是持久数据结构。与其修改它们,不如用你想要的内容创建新节点。旧节点继续指向旧文档形状。通过在旧数据和新数据之间尽可能共享结构,这变得更廉价——像这样(没有反向指针)的树形结构使之容易实现。

不要直接修改 Node 对象的属性。更多信息见指南。

type: NodeType

该节点的类型。

attrs: Attrs

把属性名映射到值的对象。允许和需要的属性种类由节点类型决定。

marks: readonly Mark[]

应用到该节点的标记(比如是否强调或是链接的一部分)。

content: Fragment

保存节点子节点的容器。

children: readonly Node[]

该节点子节点的数组。

text: string | undefined

对于文本节点,这包含节点的文本内容。

nodeSize: number

该节点的大小,按基于整数的索引方案定义。对于文本节点,是字符数量。对于其他叶子节点,是 1。对于非叶子节点,是内容大小加 2(开始和结束标记)。

childCount: number

节点的子节点数量。

child(indexnumber) → Node

获取给定索引处的子节点。索引越界时抛出错误。

maybeChild(indexnumber) → Node | null

获取给定索引处的子节点(如果存在)。

forEach()

对每个子节点调用 f,传入节点、它在父节点中的偏移量以及它的索引。

nodesBetween(
startPos⁠?: number = 0
)

对递归重叠给定两个位置(相对于该节点内容开头)的所有后代节点调用回调。这包括包含这两个位置的节点的所有祖先。回调会被传入节点、它相对于原始节点(方法接收者)的位置、它的父节点以及它的子索引。当回调对某节点返回 false 时,不会递归该节点的子节点。最后一个参数可用于指定起始计数的位置。

descendants()

对每个后代节点调用给定回调。回调返回 false 时不深入该节点。

textContent: string

连接该片段及其子节点中找到的所有文本节点。

textBetween(
leafText⁠?: string | fn(leafNodeNode) → string | null
) → string

获取位置 fromto 之间的所有文本。给定时,blockSeparator 会被插入以分隔不同块节点的文本。若给出 leafText,遇到每个非文本叶子节点时插入它,否则使用 leafText

firstChild: Node | null

返回该节点的第一个子节点,若无子节点则返回 null。

lastChild: Node | null

返回该节点的最后一个子节点,若无子节点则返回 null。

eq(otherNode) → boolean

测试两个节点是否表示同一段文档。

sameMarkup(otherNode) → boolean

比较该节点与另一个节点的标记(类型、属性和标记)。两者标记相同时返回 true。

hasMarkup(
attrs⁠?: Attrs,
marks⁠?: readonly Mark[]
) → boolean

检查该节点的标记是否与给定类型、属性和标记相符。

copy(content⁠?: Fragment | null = null) → Node

创建与该节点标记相同、包含给定内容(若未给内容则为空)的新节点。

mark(marksreadonly Mark[]) → Node

创建该节点的副本,使用给定标记集而不是节点自己的标记。

cut(fromnumber, to⁠?: number = this.content.size) → Node

创建该节点的副本,只保留给定位置之间的内容。未给 to 时,默认到节点末尾。

slice(
to⁠?: number = this.content.size,
includeParents⁠?: boolean = false
) → Slice

切出文档在给定位置之间的部分,作为 Slice 对象返回。

replace(fromnumber, tonumber, sliceSlice) → Node

用给定切片替换文档在给定位置之间的部分。切片必须「适配」,即其打开侧必须能连接到周围内容,且其内容节点必须是放置它们的节点的合法子节点。违反任何一点都会抛出 ReplaceError 类型的错误。

nodeAt(posnumber) → Node | null

查找给定位置之后的节点。

childAfter(posnumber) → {nodeNode | null, indexnumber, offsetnumber}

查找给定偏移量之后的(直接)子节点(如果有),连同其索引和相对于该节点的偏移量一起返回。

childBefore(posnumber) → {nodeNode | null, indexnumber, offsetnumber}

查找给定偏移量之前的(直接)子节点(如果有),连同其索引和相对于该节点的偏移量一起返回。

resolve(posnumber) → ResolvedPos

解析文档中的给定位置,返回带上下文信息的对象。

rangeHasMark() → boolean

测试给定标记或标记类型是否出现在文档两个给定位置之间。

isBlock: boolean

当这是块(非行内节点)时为 true。

isTextblock: boolean

当这是 textblock 节点(带行内内容的块节点)时为 true。

inlineContent: boolean

当该节点允许行内内容时为 true。

isInline: boolean

当这是行内节点(文本节点或可以出现在文本之间的节点)时为 true。

isText: boolean

当这是文本节点时为 true。

isLeaf: boolean

当这是叶子节点时为 true。

isAtom: boolean

当这是原子节点(atom)时为 true,即它没有可直接编辑的内容。通常与 isLeaf 相同,但可通过节点 spec 上的 atom 属性配置(通常用于节点显示为不可编辑节点视图的情况)。

toString() → string

返回该节点的字符串表示,用于调试。

contentMatchAt(indexnumber) → ContentMatch

获取该节点在给定索引处的内容匹配。

canReplace(
replacement⁠?: Fragment = Fragment.empty,
start⁠?: number = 0,
end⁠?: number = replacement.childCount
) → boolean

测试把 fromto(按子索引)之间的范围替换为给定替换片段(默认空片段)是否会使节点内容保持合法。可选地传入替换片段中的起止索引。

canReplaceWith(
marks⁠?: readonly Mark[]
) → boolean

测试把 fromto(按索引)的范围替换为给定类型的节点是否会使节点内容保持合法。

canAppend(otherNode) → boolean

测试给定节点的内容能否追加到该节点。如果该节点为空,只有当至少有一种节点类型能同时出现在两个节点中时(以避免合并完全不兼容的节点)才返回 true。

check()

检查该节点及其后代是否符合 schema,不符合时抛出异常。

toJSON() → any

返回该节点的可 JSON 序列化表示。

static fromJSON(schemaSchema, jsonany) → Node

从 JSON 表示反序列化节点。

class Fragment

片段表示节点子节点的集合。

与节点一样,片段是持久数据结构,你不应修改它们或其内容。相反,需要时创建新实例。API 尽量使这变得容易。

size: number

片段的大小,即其内容节点大小之和。

content: readonly Node[]

该片段中的子节点。

nodesBetween(
nodeStart⁠?: number = 0,
parent⁠?: Node
)

对给定两个位置之间(相对于片段开头)的所有后代节点调用回调。回调返回 false 时不深入该节点。

descendants()

对每个后代节点调用给定回调。pos 相对于片段开头。回调可返回 false 阻止遍历给定节点的子节点。

textBetween(
leafText⁠?: string | fn(leafNodeNode) → string | null
) → string

提取 fromto 之间的文本。见 Node 上的同名方法。

append(otherFragment) → Fragment

创建包含该片段与另一个片段合并内容的新片段。

cut(fromnumber, to⁠?: number = this.size) → Fragment

切出两个给定位置之间的子片段。

replaceChild(indexnumber, nodeNode) → Fragment

创建新片段,其中给定索引处的节点被给定节点替换。

addToStart(nodeNode) → Fragment

通过把给定节点前置于该片段来创建新片段。

addToEnd(nodeNode) → Fragment

通过把给定节点追加到该片段来创建新片段。

eq(otherFragment) → boolean

把该片段与另一个比较。

firstChild: Node | null

片段的第一个子节点,若为空则 null。

lastChild: Node | null

片段的最后一个子节点,若为空则 null。

childCount: number

该片段中子节点的数量。

child(indexnumber) → Node

获取给定索引处的子节点。索引越界时抛出错误。

maybeChild(indexnumber) → Node | null

获取给定索引处的子节点(如果存在)。

forEach()

对每个子节点调用 f,传入节点、它在父节点中的偏移量以及它的索引。

findDiffStart(otherFragment, pos⁠?: number = 0) → number | null

查找该片段与另一个片段第一个不同的位置,若相同则返回 null。

findDiffEnd(
pos⁠?: number = this.size,
otherPos⁠?: number = other.size
) → {anumber, bnumber} | null

从末尾向前查找该片段与给定片段第一个不同的位置,若相同则返回 null。由于该位置在两个节点中不相同,返回一个带两个独立位置的对象。

toString() → string

返回描述该片段的调试字符串。

toJSON() → any

创建该片段的可 JSON 序列化表示。

static fromJSON(schemaSchema, valueany) → Fragment

从 JSON 表示反序列化片段。

static fromArray(arrayreadonly Node[]) → Fragment

从节点数组构建片段。确保带相同标记的相邻文本节点被合并。

static from(
nodes⁠?: Fragment | Node | readonly Node[] | null
) → Fragment

从可解释为节点集的东西创建片段。对 null 返回空片段。对片段返回片段本身。对节点或节点数组返回包含那些节点的片段。

static empty: Fragment

空片段。用于节点不含任何内容时复用(而不是为每个叶子节点分配新的空片段)。

class Mark

标记是可以附加到节点的一条信息,比如强调、代码字体或链接。它有类型,以及可选的一组属性提供进一步信息(如链接目标)。标记通过 Schema 创建,它控制存在哪些类型以及它们有哪些属性。

type: MarkType

该标记的类型。

attrs: Attrs

与该标记关联的属性。

addToSet(setreadonly Mark[]) → readonly Mark[]

给定一个标记集,创建包含此标记(位于正确位置)的新集合。如果此标记已在集合中,返回集合本身。如果存在设置为与此标记互斥的标记,它们会被此标记替换。

removeFromSet(setreadonly Mark[]) → readonly Mark[]

从给定集合中移除此标记,返回新集合。如果此标记不在集合中,返回集合本身。

isInSet(setreadonly Mark[]) → boolean

测试此标记是否在给定标记集中。

eq(otherMark) → boolean

测试此标记是否与另一个标记类型和属性相同。

toJSON() → any

将该标记转换为可 JSON 序列化表示。

static fromJSON(schemaSchema, jsonany) → Mark

从 JSON 反序列化标记。

static sameSet(areadonly Mark[], breadonly Mark[]) → boolean

测试两个标记集是否相同。

static setFrom(marks⁠?: Mark | readonly Mark[] | null) → readonly Mark[]

从 null、单个标记或未排序的标记数组创建正确排序的标记集。

static none: readonly Mark[]

空标记集。

class Slice

切片表示从较大文档中切出的一块。它不仅存储片段,还存储两侧节点「打开」(被切穿)的深度。

new Slice()

创建切片。指定非零打开深度时,必须确保片段相应侧有至少该深度的节点——即如果片段是空段落节点,openStartopenEnd 不能大于 1。

打开节点的内容不必符合 schema 的内容约束,但根据打开的是哪一侧,它应是该节点的合法开头/结尾/中间。

content: Fragment

切片的内容。

openStart: number

片段开头的打开深度。

openEnd: number

结尾的打开深度。

size: number

该切片插入文档时会增加的大小。

eq(otherSlice) → boolean

测试此切片是否等于另一个切片。

toJSON() → any

将切片转换为可 JSON 序列化表示。

static fromJSON(schemaSchema, jsonany) → Slice

从 JSON 表示反序列化切片。

static maxOpen(
openIsolating⁠?: boolean = true
) → Slice

通过取片段两侧可能的最大打开值,从片段创建切片。

static empty: Slice

空切片。

type Attrs

保存节点属性的对象。

class ReplaceError extends Error

Node.replace 给定无效替换时抛出的错误类型。

已解析位置(Resolved Positions)

文档中的位置可以表示为整数偏移量。但你通常想用更方便的表示。

class ResolvedPos

你可以解析位置以获取更多信息。此类的对象表示这样的已解析位置,提供各种上下文信息以及一些辅助方法。

在整个接口中,接受可选 depth 参数的方法会把 undefined 解释为 this.depth,负数解释为 this.depth + value

depth: number

父节点距离根的层数。如果此位置直接指向根节点,为 0。指向顶层段落,为 1,以此类推。

pos: number

被解析的位置。

parentOffset: number

此位置在父节点中的偏移量。

parent: Node

位置指向的父节点。注意,即使位置指向文本节点,该节点也不被视为父节点——在此模型中文本节点是「扁平」的,没有内容。

doc: Node

位置被解析所在的根节点。

node(depth⁠?: number) → Node

给定层级的祖先节点。p.node(p.depth)p.parent 相同。

index(depth⁠?: number) → number

给定层级祖先中的索引。例如,如果这指向顶层第二个段落中的第 3 个节点,p.index(0) 是 1,p.index(1) 是 2。

indexAfter(depth⁠?: number) → number

指向该位置之后、给定层级祖先中的索引。

start(depth⁠?: number) → number

给定层级节点开头的(绝对)位置。

end(depth⁠?: number) → number

给定层级节点末尾的(绝对)位置。

before(depth⁠?: number) → number

给定层级包裹节点正前方的(绝对)位置,或当 depth 为 this.depth + 1 时是原始位置。

after(depth⁠?: number) → number

给定层级包裹节点正后方的(绝对)位置,或当 depth 为 this.depth + 1 时是原始位置。

textOffset: number

当此位置指向文本节点时,返回该位置与文本节点开头之间的距离。对于指向节点之间的位置为零。

nodeAfter: Node | null

获取位置之后的节点(如果有)。如果位置指向文本节点,只返回该节点在位置之后的部分。

nodeBefore: Node | null

获取位置之前的节点(如果有)。如果位置指向文本节点,只返回该节点在位置之前的部分。

posAtIndex(indexnumber, depth⁠?: number) → number

获取给定深度(默认 this.depth)父节点中给定索引处的位置。

marks() → readonly Mark[]

获取此位置的标记,考虑周围标记的 inclusive 属性。如果位置在非空节点开头,返回其后节点(如果有)的标记。

marksAcross($endResolvedPos) → readonly Mark[] | null

获取当前位置之后的标记(如果有),除了那些非包容且不在 $end 位置的标记。这主要用于获取删除后要保留的标记集。如果此位置在父节点末尾或父节点不是 textblock,返回 null(此时不应保留标记)。

sharedDepth(posnumber) → number

此位置与给定(未解析)位置共享相同父节点的深度。

blockRange(
other⁠?: ResolvedPos = this,
pred⁠?: fn(nodeNode) → boolean
) → NodeRange | null

基于此位置与给定位置在块内容周围分叉的位置返回范围。例如,如果两者指向同一 textblock,返回该 textblock 周围的范围。如果指向不同块,返回它们共享祖先中那些块周围的范围。可传入可选谓词,用父节点调用以判断进入该父节点的范围是否可接受。

sameParent(otherResolvedPos) → boolean

查询给定位置是否共享相同的父节点。

max(otherResolvedPos) → ResolvedPos

返回此位置与给定位置中较大的一个。

min(otherResolvedPos) → ResolvedPos

返回此位置与给定位置中较小的一个。

class NodeRange

表示内容的一个扁平范围,即在同一节点中开始和结束的范围。

new NodeRange()

构造节点范围。$from$to 至少到给定 depth 都应指向同一节点,因为节点范围表示单个父节点中相邻的一组节点。

$from: ResolvedPos

内容开头的已解析位置。其深度可能大于此对象的 depth 属性,因为这些是用于计算范围的位置,而不是直接在其边界重新解析的位置。

$to: ResolvedPos

内容末尾的位置。见 $from 的注意事项。

depth: number

此范围指向的节点的深度。

start: number

范围开头的位置。

end: number

范围末尾的位置。

parent: Node

范围指向的父节点。

startIndex: number

范围在父节点中的起始索引。

endIndex: number

范围在父节点中的结束索引。

文档 Schema(Document Schema)

每个 ProseMirror 文档都符合一个 schema,它描述文档由哪些节点和标记组成,以及它们之间的关系,例如哪个节点可以作为哪个节点的子节点出现。

class Schema<Nodes extends string = any, Marks extends string = any>

文档 schema。保存符合文档中可能出现的节点和标记的节点与标记类型对象,并提供创建和反序列化此类文档的功能。

当给定时,类型参数提供此 schema 中节点和标记的名称。

new Schema(specSchemaSpec<Nodes, Marks>)

从 schema 规范构造 schema。

spec: {
nodesOrderedMap<NodeSpec>,
marksOrderedMap<MarkSpec>,
topNode⁠?: string
}

schema 所基于的规范,并附加保证其 nodesmarks 属性是 OrderedMap 实例(而非原始对象)。

nodes: {[name in Nodes]: NodeType} & Object<NodeType>

把 schema 的节点名映射到节点类型对象的对象。

marks: {[name in Marks]: MarkType} & Object<MarkType>

从标记名到标记类型对象的映射。

linebreakReplacement: NodeType | null

此 schema 中定义的换行替换节点(如果有)。

topNodeType: NodeType

此 schema 默认顶层节点的类型。

cached: Object<any>

用于存储各模块想按 schema 计算和缓存的值的对象。(如果你想在其中存东西,尽量使用不太可能冲突的属性名。)

node(
attrs⁠?: Attrs | null = null,
content⁠?: Fragment | Node | readonly Node[],
marks⁠?: readonly Mark[]
) → Node

在此 schema 中创建节点。type 可以是字符串或 NodeType 实例。属性会用默认值扩展,content 可以是 FragmentnullNode 或节点数组。

text(textstring, marks⁠?: readonly Mark[]) → Node

在 schema 中创建文本节点。不允许空文本节点。

mark(typestring | MarkType, attrs⁠?: Attrs) → Mark

用给定类型和属性创建标记。

nodeFromJSON(jsonany) → Node

从 JSON 表示反序列化节点。此方法已绑定。

markFromJSON(jsonany) → Mark

从 JSON 表示反序列化标记。此方法已绑定。

interface SchemaSpec<Nodes extends string = any, Marks extends string = any>

描述 schema 的对象,传给 Schema 构造函数。

nodes: {[name in Nodes]: NodeSpec} | OrderedMap<NodeSpec>

此 schema 中的节点类型。把名称映射到描述该名称关联节点类型的 NodeSpec 对象。顺序很重要——它决定哪些解析规则默认优先,以及哪些节点在给定组中排在前面。

marks⁠?: {[name in Marks]: MarkSpec} | OrderedMap<MarkSpec>

此 schema 中存在的标记类型。它们被提供的顺序决定标记集排序的顺序和解析规则尝试的顺序。

topNode⁠?: string

schema 默认顶层节点的名称。默认为 "doc"

interface NodeSpec

节点类型的描述,用于定义 schema。

content⁠?: string

该节点的内容表达式,如 schema 指南所述。未给定时,节点不允许任何内容。

marks⁠?: string

该节点内部允许的标记。可以是以空格分隔的标记名或组字符串,"_" 显式允许所有标记,"" 禁止标记。未给定时,带行内内容的节点默认允许所有标记,其他节点默认不允许标记。

group⁠?: string

该节点所属的组或空格分隔的组,可在 schema 的内容表达式中引用。

inline⁠?: boolean

对行内节点应设为 true。(文本节点隐含为 true。)

atom⁠?: boolean

可设为 true 表示虽然这不是叶子节点,但它没有可直接编辑的内容,在视图中应作为单个单元处理。

attrs⁠?: Object<AttributeSpec>

该类型节点获得的属性。

selectable⁠?: boolean

控制该类型节点能否被选为节点选区。对非文本节点默认为 true。

draggable⁠?: boolean

决定该类型节点能否在不被选中的情况下被拖动。默认为 false。

code⁠?: boolean

可用于指示该节点包含代码,使某些命令表现不同。

whitespace⁠?: "pre" | "normal"

控制该节点中空白的解析方式。默认是 "normal",使 DOM 解析器在普通模式下折叠空白,否则规范化空白(用空格替换换行等)。"pre" 使解析器保留节点内的空格。未给此选项但 code 为 true 时,空白默认为 "pre"。注意,此选项不影响节点渲染方式——那应由 toDOM 和/或样式处理。

definingAsContext⁠?: boolean

决定在替换操作(如粘贴)期间该节点是否被视为重要的父节点。非 defining(默认)节点在其全部内容被替换时被丢弃,而 defining 节点会保留并包裹插入的内容。

definingForContent⁠?: boolean

在插入的内容中,内容的 defining 父节点在可能时被保留。通常,非默认段落的 textblock 类型(以及可能的列表项)被标记为 defining。

defining⁠?: boolean

启用时,同时启用 definingAsContextdefiningForContent

isolating⁠?: boolean

启用时(默认 false),该类型节点的两侧计为常规编辑操作(如退格或提升)不会跨越的边界。应启用此属性的节点例子是表格单元格。

toDOM⁠?: fn(nodeNode) → DOMOutputSpec

定义该类型节点默认序列化到 DOM/HTML 的方式(供 DOMSerializer.fromSchema 使用)。应返回一个 DOM 节点或描述它的数组结构,其中可选数字零(「洞」)指示节点内容应插入的位置。

对于文本节点,默认创建文本 DOM 节点。虽然可以创建文本渲染方式不同的序列化器,但这在编辑器内部不受支持,所以你不应在文本节点 spec 中覆盖它。

parseDOM⁠?: readonly TagParseRule[]

将 DOM 解析器信息与此节点关联,可供 DOMParser.fromSchema 自动派生解析器。规则中的 node 字段是隐含的(会自动填入此节点的名称)。如果你提供自己的解析器,则无需在 schema 中也指定解析规则。

toDebugString⁠?: fn(nodeNode) → string

定义该类型节点默认序列化为字符串表示(用于调试,如错误消息中)的方式。

leafText⁠?: fn(nodeNode) → string

定义该类型叶子节点默认序列化为字符串的方式(供 Node.textBetweenNode.textContent 使用)。

linebreakReplacement⁠?: boolean

schema 中单个行内节点可设为换行等价物。在支持该节点的块类型与不支持但 whitespace 设为 "pre" 的块类型之间转换时,setBlockType 会酌情在换行字符与换行节点之间转换。

[string]: any

节点 spec 可包含任意属性,其他代码可通过 NodeType.spec 读取。

interface MarkSpec

用于在创建 schema 时定义标记。

attrs⁠?: Object<AttributeSpec>

该类型标记获得的属性。

inclusive⁠?: boolean

当光标位于其末尾(或其开头同时也是父节点开头时)时,此标记是否应激活。默认为 true。

excludes⁠?: string

决定此标记可与哪些其他标记共存。应是以空格分隔的字符串,命名其他标记或标记组。当标记被加入集合时,它排除的所有标记在过程中被移除。如果集合中包含排除新标记但本身不被新标记排除的标记,则新标记不能被加入。可以用值 "_" 表示该标记排除 schema 中所有标记。

默认只与同类型标记互斥。你可以设为空字符串(或任何不含标记自身名称的字符串)以允许多个给定类型的标记共存(只要它们属性不同)。

group⁠?: string

该标记所属的组或空格分隔的组。

spanning⁠?: boolean

决定该类型标记在序列化到 DOM/HTML 时能否跨越多个相邻节点。默认为 true。

code⁠?: boolean

将此 span 的内容标记为代码,使某些命令和扩展对其处理不同。

toDOM⁠?: fn(markMark, inlineboolean) → DOMOutputSpec

定义该类型标记默认序列化到 DOM/HTML 的方式。当结果 spec 包含洞时,被标记的内容放在那里。否则,追加到顶层节点。

parseDOM⁠?: readonly ParseRule[]

将 DOM 解析器信息与此标记关联(见相应的节点 spec 字段)。规则中的 mark 字段是隐含的。

[string]: any

标记 spec 可包含附加属性,可通过 MarkType.spec 在使用该标记时检查。

interface AttributeSpec

用于定义节点或标记上的属性。

default⁠?: any

此属性的默认值,在未提供显式值时使用。没有默认值的属性在创建具有它们的节点或标记时必须提供。

validate⁠?: string | fn(valueany)

用于验证此属性值的函数或类型名。在从 JSON 反序列化属性和运行 Node.check 时使用。为函数时,值不符合预期类型或形状时应抛出异常。为字符串时,应是以 | 分隔的原始类型列表("number""string""boolean""null""undefined"),值不是其中一种类型时库会抛错。

class NodeType

节点类型是每个 Schema 分配一次、用于给 Node 实例打标签的对象。它们包含节点类型的信息,如其名称以及它表示的节点种类。

name: string

节点类型在此 schema 中的名称。

schema: Schema

指向节点类型所属 Schema 的链接。

spec: NodeSpec

此类型所基于的 spec。

inlineContent: boolean

此节点类型是否有行内内容。

isBlock: boolean

这是否是块类型。

isText: boolean

这是否是文本节点类型。

isInline: boolean

这是否是行内类型。

isTextblock: boolean

这是否是 textblock 类型(包含行内内容的块)。

isLeaf: boolean

对不允许内容的节点类型为 true。

isAtom: boolean

当此节点是原子节点时(即没有可直接编辑的内容)为 true。

isInGroup(groupstring) → boolean

当此节点类型属于给定组时返回 true。

contentMatch: ContentMatch

节点类型内容表达式的起始匹配。

markSet: readonly MarkType[] | null

此节点中允许的标记集。null 表示允许所有标记。

whitespace: "pre" | "normal"

节点类型的空白选项。

hasRequiredAttrs() → boolean

告诉你此节点类型是否有任何必需属性。

compatibleContent(otherNodeType) → boolean

指示此节点是否允许与给定节点类型相同的一些内容。

create(
attrs⁠?: Attrs | null = null,
content⁠?: Fragment | Node | readonly Node[] | null,
marks⁠?: readonly Mark[]
) → Node

创建此类型的 Node。给定属性会被检查并填默认值(若无必需属性,可传 null 完全使用类型默认值)。content 可以是 Fragment、节点、节点数组或 null。类似地,marks 可为 null 默认为空标记集。

createChecked(
attrs⁠?: Attrs | null = null,
content⁠?: Fragment | Node | readonly Node[] | null,
marks⁠?: readonly Mark[]
) → Node

类似 create,但检查给定内容是否符合节点类型的内容限制,不符合则抛错。

createAndFill(
attrs⁠?: Attrs | null = null,
content⁠?: Fragment | Node | readonly Node[] | null,
marks⁠?: readonly Mark[]
) → Node | null

类似 create,但看是否需要在给定片段开头或结尾添加节点以使其适配。找不到适配的包裹时返回 null。注意,由于必需节点总能被创建,若传 null 或 Fragment.empty 作为内容,这总会成功。

validContent(contentFragment) → boolean

如果给定片段是该节点类型的合法内容,返回 true。

allowsMarkType(markTypeMarkType) → boolean

检查给定标记类型是否允许在此节点中。

allowsMarks(marksreadonly Mark[]) → boolean

测试给定标记集是否允许在此节点中。

allowedMarks(marksreadonly Mark[]) → readonly Mark[]

从给定集合中移除此节点不允许的标记。

class MarkType

与节点一样,标记(与节点关联以表示强调或作为链接的一部分等)用类型对象打标签,每个 Schema 实例化一次。

name: string

标记类型的名称。

schema: Schema

此标记类型实例所属的 schema。

spec: MarkSpec

类型所基于的 spec。

create(attrs⁠?: Attrs | null = null) → Mark

创建此类型的标记。attrs 可为 null 或只包含部分标记属性的对象。其余(有默认值的)会被添加。

removeFromSet(setreadonly Mark[]) → readonly Mark[]

当给定集合中有此类型的标记时,返回不含它的新集合。否则返回输入集合。

isInSet(setreadonly Mark[]) → Mark | undefined

测试给定集合中是否有此类型的标记。

excludes(otherMarkType) → boolean

查询给定标记类型是否被此标记排除。

class ContentMatch

此类的实例表示节点类型内容表达式的匹配状态,可用于查明进一步内容是否在此匹配,以及给定位置是否是节点的合法结尾。

validEnd: boolean

当此匹配状态表示节点的合法结尾时为 true。

matchType(typeNodeType) → ContentMatch | null

匹配一个节点类型,成功则返回该节点之后的匹配。

matchFragment(
start⁠?: number = 0,
end⁠?: number = frag.childCount
) → ContentMatch | null

尝试匹配片段。成功则返回结果匹配。

defaultType: NodeType | null

获取此匹配位置处可生成的第一个匹配节点类型。

fillBefore(
toEnd⁠?: boolean = false,
startIndex⁠?: number = 0
) → Fragment | null

尝试匹配给定片段,若失败,看能否通过在它前面插入节点使其匹配。成功时,返回插入节点的片段(若无需插入则为空)。当 toEnd 为 true 时,仅当结果匹配到达内容表达式末尾才返回片段。

findWrapping(targetNodeType) → readonly NodeType[] | null

查找一组包裹节点类型,使给定类型的节点能出现在此位置。结果可能为空(直接适配时),无此类包裹时返回 null。

edgeCount: number

描述内容表达式的有限自动机中该节点的出边数量。

edge(nnumber) → {typeNodeType, nextContentMatch}

获取描述内容表达式的有限自动机中该节点第 n 条出边。

DOM 表示(DOM Representation)

因为把文档表示为 DOM 节点树是 ProseMirror 运作方式的核心,DOM 解析和序列化与模型集成在一起。

(但注意,使用此模块不需要加载 DOM 实现。)

class DOMParser

DOM 解析器表示把 DOM 内容解析为符合给定 schema 的 ProseMirror 文档的策略。其行为由一组规则定义。

new DOMParser(
rulesreadonly ParseRule[]
)

创建针对给定 schema、使用给定解析规则的解析器。

schema: Schema

解析器解析到的 schema。

rules: readonly ParseRule[]

解析器使用的解析规则集,按优先级顺序。

parse(domDOMNode, options⁠?: ParseOptions = {}) → Node

从 DOM 节点的内容解析文档。

parseSlice(domDOMNode, options⁠?: ParseOptions = {}) → Slice

parse 一样解析给定 DOM 节点的内容,接受相同的选项集。但与产生整个节点的方法不同,此方法返回两侧打开的切片,意味着 schema 约束不应用于输入左侧节点的开头和末尾节点的结尾。

static fromSchema(schemaSchema) → DOMParser

使用 schema 节点 spec 中列出的解析规则、按优先级重排后构造 DOM 解析器。

interface ParseOptions

这些是 parseparseSlice 方法识别的选项。

preserveWhitespace⁠?: boolean | "full"

默认按 HTML 规则折叠空白。传 true 保留空白但把换行规范化为空格(或可用的换行替换),传 "full" 完全保留空白。

findPositions⁠?: {nodeDOMNode, offsetnumber, pos⁠?: number}[]

给定时,解析器除了解析内容,还会记录给定 DOM 位置的文档位置。通过写入这些对象(添加保存文档位置的 pos 属性)实现。不在解析内容中的 DOM 位置不会被写入。

from⁠?: number

开始解析的子节点索引。

to⁠?: number

停止解析的子节点索引。

topNode⁠?: Node

默认内容解析到 schema 的默认顶层节点类型。可传此选项使用不同节点的类型和属性作为顶层容器。

topMatch⁠?: ContentMatch

提供起始内容匹配,解析到顶层节点的内容与之匹配。

context⁠?: ResolvedPos

解析时在给定顶层节点之上计为上下文的一组额外节点。

interface GenericParseRule

可出现在 tag 和 style 解析规则中的字段。

priority⁠?: number

可用于改变 schema 中解析规则的尝试顺序。优先级高的先试。无优先级的规则计为 50。此属性只在 schema 中有意义——直接构造解析器时,使用规则数组的顺序。

consuming⁠?: boolean

默认当规则匹配元素或样式后,其他规则不再有机会匹配它。设为 false 表示即使此规则匹配,其后的其他规则也应运行。

context⁠?: string

给定时,限制此规则只在当前上下文(内容被解析进入的父节点)匹配此表达式时匹配。应包含一个或多个后跟单斜杠或双斜杠的节点名或节点组名。例如 "paragraph/" 表示规则只在父节点是段落时匹配,"blockquote/paragraph/" 限制为在 blockquote 内的段落中,"section//" 匹配 section 内任何位置——双斜杠匹配任意祖先节点序列。要允许多个不同上下文,用竖线(|)分隔,如 "blockquote/|list_item/"

mark⁠?: string

要包裹匹配内容的标记类型名称。

ignore⁠?: boolean

为 true 时,忽略匹配此规则的内容。任何 <head><noscript><script><object><style><title> 标签在无规则匹配时会被自动忽略。

closeParent⁠?: boolean

为 true 时,找到匹配此规则的元素会关闭当前节点。

skip⁠?: boolean

为 true 时,忽略匹配此规则的节点,但解析其内容。

attrs⁠?: Attrs

此规则创建的节点或标记的属性。提供 getAttrs 时它优先。

interface TagParseRule extends GenericParseRule

针对 DOM 元素的解析规则。

tag: string

描述要匹配的 DOM 元素种类的 CSS 选择器。

namespace⁠?: string

要匹配的命名空间。仅当命名空间匹配或此属性为 null 时节点才匹配。

node⁠?: string

此规则匹配时要创建的节点类型名。每条规则都应有 nodemarkignore 属性之一(除非它出现在节点或标记 spec 中,此时 nodemark 属性从其位置派生)。

getAttrs⁠?: fn(nodeHTMLElement) → false | Attrs | null

用于计算此规则创建的节点或标记属性的函数。也可用于描述 DOM 元素或样式必须匹配的进一步条件。返回 false 时规则不匹配。返回 null 或 undefined 解释为空/默认属性集。

contentElement⁠?: string |

对于产生非叶子节点的规则,默认把 DOM 元素的内容解析为节点内容。如果子节点在某个后代节点中,这可以是解析器必须用来找到实际内容元素的 CSS 选择器字符串,或返回实际内容元素给解析器的函数。

getContent⁠?: fn(nodeDOMNode, schemaSchema) → Fragment

可用于覆盖匹配节点的内容。存在时,不解析节点的子节点,而是使用此函数的结果。

preserveWhitespace⁠?: boolean | "full"

控制解析匹配元素内容时是否保留空白。false 表示空白可能被折叠,true 表示保留空白但把换行规范化为空格,"full" 表示换行也被保留。

interface StyleParseRule extends GenericParseRule

针对样式属性的解析规则。

style: string

要匹配的 CSS 属性名。此规则匹配列出该属性的行内样式。也可采用 "property=value" 形式,此时仅当属性值恰好等于给定值时规则才匹配。(更复杂的过滤,使用 getAttrs 并返回 false 表示匹配失败。)匹配样式的规则只能产生标记,不能产生节点。

clearMark⁠?: fn(markMark) → boolean

样式规则可从激活标记集中移除标记。

getAttrs⁠?: fn(nodestring) → false | Attrs | null

用于计算此规则创建的节点或标记属性的函数。以样式值调用。

type ParseRule = TagParseRule | StyleParseRule

描述如何把给定 DOM 节点或行内样式解析为 ProseMirror 节点或标记的值。

class DOMSerializer

DOM 序列化器知道如何把各种类型的 ProseMirror 节点和标记转换为 DOM 节点。

new DOMSerializer()

创建序列化器。nodes 应把节点名映射到接收节点并返回相应 DOM 描述的函数。marks 对标记名做同样的事,但还得到一个参数指示标记内容是块还是行内内容(通常总是行内)。标记序列化器可为 null 表示该类型标记不应序列化。

nodes: Object<fn(nodeNode) → DOMOutputSpec>

节点序列化函数。

marks: Object<>

标记序列化函数。

serializeFragment(
options⁠?: {document⁠?: Document} = {},
) → HTMLElement | DocumentFragment

把该片段的内容序列化为 DOM 片段。不在浏览器中时,应传入含 DOM document 的 document 选项,使序列化器能创建节点。

serializeNode(
options⁠?: {document⁠?: Document} = {}
) → HTMLElement | Text

把该节点序列化为 DOM 节点。当你需要序列化文档的一部分(而非整个文档)时很有用。要序列化整个文档,对其内容使用 serializeFragment

static renderSpec() → {domHTMLElement, contentDOM⁠?: HTMLElement}

把输出 spec 渲染为 DOM 节点。如果 spec 中有洞(零),contentDOM 指向带洞的节点。

static fromSchema(schemaSchema) → DOMSerializer

使用 schema 节点和标记 spec 中的 toDOM 属性构建序列化器。

static nodesFromSchema(schemaSchema) → Object<fn(nodeNode) → DOMOutputSpec>

收集 schema 节点 spec 中的序列化器到一个对象。这可作为构建自定义序列化器的基础。

static marksFromSchema(schemaSchema) → Object<>

收集 schema 标记 spec 中的序列化器到一个对象。

type DOMOutputSpec = Element |
{domElement, contentDOM⁠?: Element} |
[string, any]

DOM 结构的描述。可以是 DOM 元素、{dom, contentDOM} 对象或数组。

数组描述一个 DOM 元素。数组第一个值应是字符串——DOM 元素名,可选地前置命名空间 URL 和空格。如果第二个元素是普通对象,解释为该元素的一组属性。其后的任何元素(包括第二个元素,如果它不是属性对象)解释为 DOM 元素的子节点,必须是合法的 DOMOutputSpec 值、字符串(文本节点)或数字零。

数字零(读作「洞」)用于指示节点子节点应插入的位置。如果它出现在输出 spec 中,应是其父节点中唯一的子元素。

prosemirror-transform 模块

此模块定义一种修改文档的方式,使更改可被记录、重放和重排。更多信息见指南中的变换部分。

步骤(Steps)

变换以 Step 进行,它们是对文档的原子、定义明确的修改。应用步骤产生新文档。

每个步骤提供一个变更映射,把旧文档中的位置映射到变换后文档中的位置。步骤可被反转以创建撤销其效果的步骤,并可在称为 Transform 的便捷对象中链接在一起。

abstract class Step

步骤对象表示原子更改。它通常只适用于为其创建的文档,因为其中存储的位置只对该文档有意义。

定义新步骤的方式是创建扩展 Step 的类,覆盖 applyinvertmapgetMapfromJSON 方法,并用 Step.jsonID 为你的类注册唯一的 JSON 序列化标识符。

abstract apply(docNode) → StepResult

把此步骤应用到给定文档,返回结果对象,要么指示失败(步骤不能应用于此文档),要么通过包含变换后的文档指示成功。

getMap() → StepMap

获取表示此步骤所做更改的步骤映射,可用于在旧文档和新文档的位置之间转换。

abstract invert(docNode) → Step

创建此步骤的反转版本。需要步骤之前的文档作为参数。

abstract map(mappingMappable) → Step | null

把此步骤映射过可映射对象,返回位置调整后的步骤版本,或(步骤被映射完全删除时)null。

merge(otherStep) → Step | null

尝试把此步骤与另一个步骤合并(应用到它之后)。可能时返回合并后的步骤,不能合并时返回 null。

abstract toJSON() → any

创建此步骤的可 JSON 序列化表示。为自定义子类定义此方法时,确保结果对象在 stepType 属性下包含步骤类型的 JSON id。

static fromJSON(schemaSchema, jsonany) → Step

从 JSON 表示反序列化步骤。会调用到步骤类自己对此方法的实现。

static jsonID(
stepClass: {fromJSONfn(schemaSchema, jsonany) → Step}
) → {fromJSONfn(schemaSchema, jsonany) → Step}

为了能把步骤序列化为 JSON,每个步骤需要一个字符串 ID 附加到其 JSON 表示。用此方法为你的步骤类注册 ID。尽量选择不太可能与其他模块步骤冲突的 ID。

class StepResult

应用步骤的结果。包含新文档或失败值。

doc: Node | null

变换后的文档(成功时)。

failed: string | null

失败消息(不成功时)。

static ok(docNode) → StepResult

创建成功的步骤结果。

static fail(messagestring) → StepResult

创建失败的步骤结果。

static fromReplace(
docNode,
) → StepResult

用给定参数调用 Node.replace。成功创建成功结果,抛出 ReplaceError 时创建失败结果。

class ReplaceStep extends Step

用新内容切片替换文档的一部分。

new ReplaceStep(
structure⁠?: boolean = false
)

给定切片应适配 fromto 之间的「间隙」——深度必须对齐,周围节点必须能与切片的打开侧连接。当 structure 为 true 时,若 fromto 之间的内容不只是连续闭合再打开的标记序列,步骤将失败(这是为了防止 rebase 后的替换步骤覆盖它们不该覆盖的内容)。

from: number

被替换范围的开始位置。

to: number

被替换范围的结束位置。

slice: Slice

要插入的切片。

static MAP_BIAS: -1 | 1

默认情况下,为向后兼容,映射到同一位置插入处的插入步骤会移到插入内容之后。在协同编辑场景中,这可能使重做的插入出现在意外位置。可设为 -1 使这种映射让步骤保持在插入之前。

class ReplaceAroundStep extends Step

用内容切片替换文档的一部分,但通过把替换内容的某个范围移入切片来保留它。

new ReplaceAroundStep(
structure⁠?: boolean = false
)

用给定范围和间隙创建 replace-around 步骤。insert 应是间隙内容应移入的切片中的点。structure 的含义与 ReplaceStep 类中相同。

from: number

被替换范围的开始位置。

to: number

被替换范围的结束位置。

gapFrom: number

保留范围的开始。

gapTo: number

保留范围的结束。

slice: Slice

要插入的切片。

insert: number

保留范围应插入的切片中的位置。

class AddMarkStep extends Step

给两个位置之间的所有行内内容添加标记。

new AddMarkStep(fromnumber, tonumber, markMark)

创建标记步骤。

from: number

被标记范围的开始。

to: number

被标记范围的结束。

mark: Mark

要添加的标记。

class RemoveMarkStep extends Step

从两个位置之间的所有行内内容移除标记。

new RemoveMarkStep(fromnumber, tonumber, markMark)

创建移除标记的步骤。

from: number

被取消标记范围的开始。

to: number

被取消标记范围的结束。

mark: Mark

要移除的标记。

class AddNodeMarkStep extends Step

给特定节点添加标记。

new AddNodeMarkStep(posnumber, markMark)

创建节点标记步骤。

pos: number

目标节点的位置。

mark: Mark

要添加的标记。

class RemoveNodeMarkStep extends Step

从特定节点移除标记。

new RemoveNodeMarkStep(posnumber, markMark)

创建移除标记的步骤。

pos: number

目标节点的位置。

mark: Mark

要移除的标记。

class AttrStep extends Step

更新特定节点中的属性。

new AttrStep(posnumber, attrstring, valueany)

构造属性步骤。

pos: number

目标节点的位置。

attr: string

要设置的属性。

value: any
static fromJSON(schemaSchema, jsonany) → AttrStep

class DocAttrStep extends Step

更新 doc 节点中的属性。

new DocAttrStep(attrstring, valueany)

构造属性步骤。

attr: string

要设置的属性。

value: any
static fromJSON(schemaSchema, jsonany) → DocAttrStep

位置映射(Position Mapping)

通过步骤产生的步骤映射把位置从一个文档映射到另一个文档,是 ProseMirror 中一项重要操作。例如,文档变化时更新选区就用它。

interface Mappable

位置可以映射过多种东西。这类对象符合此接口。

map(posnumber, assoc⁠?: number) → number

把位置映射过此对象。给定时,assoc(应为 -1 或 1,默认 1)决定位置关联哪一侧,这决定当一块内容插入到映射位置时向哪个方向移动。

mapResult(posnumber, assoc⁠?: number) → MapResult

映射位置,并返回包含映射额外信息的对象。结果的 deleted 字段告诉你该位置在映射期间是否被删除(完全被替换范围包围)。当只有一侧内容被删除时,仅当 assoc 指向被删除内容方向时该位置本身才算被删除。

class MapResult

表示带额外信息的映射位置的对象。

pos: number

位置的映射版本。

deleted: boolean

告诉你位置是否被删除,即步骤是否从文档移除了所查询一侧(通过 assoc 参数)的标记。

deletedBefore: boolean

告诉你映射位置之前的标记是否被删除。

deletedAfter: boolean

映射位置之后的标记被删除时为 true。

deletedAcross: boolean

告诉映射过的任何步骤是否跨越该位置删除(包括位置前后的标记)。

class StepMap implements Mappable

描述步骤所做删除和插入的映射,可用于查找步骤前文档版本中的位置与步骤后版本中相同位置的对应关系。

new StepMap(
rangesreadonly number[],
inverted⁠?: boolean = false
)

创建位置映射。对文档的修改表示为一组数字,其中每三个数字表示一个修改块 [start, oldSize, newSize]

forEach()

对映射中包含的每个变化范围调用给定函数。

invert() → StepMap

创建此映射的反转版本。结果可用于把步骤后文档中的位置映射到步骤前文档。

static offset(nnumber) → StepMap

创建把所有位置移动偏移量 n(可为负)的映射。这在把为子文档准备的步骤应用到更大文档(或反之)时有用。

static empty: StepMap

不含变化范围的 StepMap。

class Mapping implements Mappable

映射表示零个或多个步骤映射的管道。它对无损地处理一系列步骤(其中一些步骤是较早步骤的反转)中的位置映射有特殊规定。(这在为协同或历史管理「rebase」步骤时出现。)

new Mapping(
maps⁠?: readonly StepMap[],
mirror⁠?: number[],
from⁠?: number = 0,
to⁠?: number = maps ? maps.length : 0
)

用给定的位置映射创建新映射。

from: number

调用 mapmapResult 时使用的 maps 数组中的起始位置。

to: number

maps 数组中的结束位置。

maps: readonly StepMap[]

此映射中的步骤映射。

slice(
from⁠?: number = 0,
to⁠?: number = this.maps.length
) → Mapping

创建只映射过此映射一部分的映射。

appendMap(mapStepMap, mirrors⁠?: number)

向此映射末尾添加步骤映射。若给 mirrors,它应是此步骤映射镜像的索引。

appendMapping(mappingMapping)

把给定映射中的所有步骤映射添加到此映射(保留镜像信息)。

getMirror(nnumber) → number | undefined

查找此映射中镜像给定偏移处映射的步骤映射的偏移(按 appendMap 的第二个参数)。

appendMappingInverted(mappingMapping)

把给定映射的逆添加到此映射。

invert() → Mapping

创建此映射的反转版本。

map(posnumber, assoc⁠?: number = 1) → number

把位置映射过此映射。

mapResult(posnumber, assoc⁠?: number = 1) → MapResult

把位置映射过此映射,返回映射结果。

文档变换(Document transforms)

因为你经常需要把多个步骤收集在一起以完成复合更改,ProseMirror 提供了一种抽象使这变得容易。状态事务是变换的子类。

class Transform

用于构建和跟踪表示文档变换的步骤数组的抽象。

大多数变换方法返回 Transform 对象本身,以便链式调用。

new Transform(docNode)

创建从给定文档开始的变换。

steps: Step[]

此变换中的步骤。

docs: Node[]

每个步骤之前的文档。

mapping: Mapping

带此变换中每个步骤映射的映射。

doc: Node

当前文档(应用变换中步骤的结果)。

before: Node

起始文档。

step(stepStep) → Transform

在此变换中应用新步骤,保存结果。步骤失败时抛错。

maybeStep(stepStep) → StepResult

尝试在此变换中应用步骤,失败则忽略。返回步骤结果。

docChanged: boolean

文档被更改(存在任何步骤)时为 true。

changedRange() → {fromnumber, tonumber} | null

返回单个范围(变换后文档位置),覆盖此变换更改的所有内容。未做替换时返回 null。注意,这会忽略不替换底层内容而只添加/移除标记的更改。

replace(
to⁠?: number = from,
slice⁠?: Slice = Slice.empty
) → Transform

用给定切片替换文档 fromto 之间的部分。

replaceWith(
contentFragment | Node | readonly Node[]
) → Transform

用给定内容替换给定范围,内容可为片段、节点或节点数组。

delete(fromnumber, tonumber) → Transform

删除给定位置之间的内容。

insert(
contentFragment | Node | readonly Node[]
) → Transform

在给定位置插入给定内容。

replaceRange(fromnumber, tonumber, sliceSlice) → Transform

用给定切片替换文档的某个范围,使用 fromto 和切片的 openStart 属性作为提示,而非固定的起止点。此方法可能扩大替换区域或关闭切片中的打开节点,以获得更符合所见即所得预期的适配——当被替换区域的完全覆盖父节点被标记为上下文非 defining 时丢弃它们,或包含切片中被标记为定义其内容的打开父节点。

例如,处理粘贴用的就是此方法。类似的 replace 方法是更原始的工具,不移动其给定范围的起止,在你需要对发生的事情有更精确控制时有用。

replaceRangeWith(fromnumber, tonumber, nodeNode) → Transform

用节点替换给定范围,但使用 fromto 作为提示而非精确位置。当 fromto 相同且位于给定节点不适配的父节点的开头或末尾时,此方法可能把它们移向允许放置给定节点的父节点。当给定范围完全覆盖父节点时,此方法可能完全替换该父节点。

deleteRange(fromnumber, tonumber) → Transform

删除给定范围,扩展它以覆盖被完全覆盖的父节点,直到找到合法替换。

lift(rangeNodeRange, targetnumber) → Transform

把给定范围中的内容从其父节点分离(如果它前后有兄弟内容),并按 target 指定的深度在树中上移。你可能想用 liftTarget 计算 target,以确保提升合法。

join(posnumber, depth⁠?: number = 1) → Transform

合并给定位置周围的块。若 depth 为 2,它们的最后和第一个兄弟也会被合并,以此类推。

wrap(
wrappersreadonly {typeNodeType, attrs⁠?: Attrs}[]
) → Transform

用给定的一组包裹节点包裹给定范围。包裹节点被假定在此位置合法,并且大概应该用 findWrapping 计算。

setBlockType(
to⁠?: number = from,
attrs⁠?: Attrs | fn(oldNodeNode) → Attrs | null = null
) → Transform

fromto 之间(部分)的所有 textblock 设置为带给定属性的给定节点类型。

setNodeMarkup(
type⁠?: NodeType,
attrs⁠?: Attrs | null = null,
marks⁠?: readonly Mark[]
) → Transform

更改 pos 处节点的类型、属性和/或标记。未给 type 时保留现有节点类型。

setNodeAttribute(posnumber, attrstring, valueany) → Transform

把给定节点上的单个属性设为新值。pos 指向文档内容。用 setDocAttribute 设置文档本身的属性。

setDocAttribute(attrstring, valueany) → Transform

把文档上的单个属性设为新值。

addNodeMark(posnumber, markMark) → Transform

给位置 pos 处的节点添加标记。

removeNodeMark(posnumber, markMark | MarkType) → Transform

从位置 pos 处的节点移除标记(或给定类型的所有标记)。

split(
depth⁠?: number = 1,
typesAfter⁠?: ({typeNodeType, attrs⁠?: Attrs} | null)[]
) → Transform

在给定位置拆分节点,可选地(若 depth 大于 1)拆分其上任意数量的节点。默认拆分出的部分继承原节点的节点类型。可通过传入拆分后使用的类型和属性数组来改变(最外层节点在前)。

addMark(fromnumber, tonumber, markMark) → Transform

fromto 之间的行内内容添加给定标记。

removeMark() → Transform

fromto 之间的行内节点移除标记。当 mark 是单个标记时,精确移除该标记。是标记类型时,移除该类型所有标记。是 null 时,移除所有类型的所有标记。

clearIncompatible() → Transform

pos 处节点的内容中移除所有与给定新父节点类型不匹配的标记和节点。接受可选起始内容匹配作为第三个参数。

创建变换或判断其是否可能时,以下辅助函数会很有用。

replaceStep(
docNode,
to⁠?: number = from,
slice⁠?: Slice = Slice.empty
) → Step | null

把切片「适配」到文档中的给定位置,产生插入它的步骤。若无法以有意义的方式在此插入切片,或插入是空操作(空范围上的空切片),返回 null。

liftTarget(rangeNodeRange) → number | null

尝试找到给定范围内内容可被提升到的目标深度。不会跨越隔离父节点。

findWrapping(
attrs⁠?: Attrs | null = null,
innerRange⁠?: NodeRange = range
) → {typeNodeType, attrsAttrs | null}[] |

尝试找到把给定范围内内容包裹在给定类型节点中的合法方式。必要时可在包裹节点周围和内部引入额外节点。找不到合法包裹时返回 null。给 innerRange 时,用该范围的内容作为适配进包裹的内容,而非 range 的内容。

canSplit(
docNode,
depth⁠?: number = 1,
typesAfter⁠?: ({typeNodeType, attrs⁠?: Attrs} | null)[]
) → boolean

检查在给定位置拆分是否允许。

canJoin(docNode, posnumber) → boolean

测试给定位置前后的块能否合并。

joinPoint(docNode, posnumber, dir⁠?: number = -1) → number | undefined

查找给定位置的祖先中可与前面块(或 dir 为正时后面块)合并的祖先。返回可合并点(如果有)。

insertPoint(docNode, posnumber, nodeTypeNodeType) → number | null

尝试在 pos 附近找到可插入给定类型节点的点,当 pos 本身不合法但位于节点开头或末尾时,沿节点层级向上搜索。未找到位置返回 null。

dropPoint(docNode, posnumber, sliceSlice) → number | null

在给定位置处或附近查找给定切片可插入的位置。会查看父节点的最近边界并在那里尝试,即使原位置不直接在该节点开头或末尾。未找到位置返回 null。

prosemirror-commands 模块

此模块导出许多命令,它们是封装编辑动作的构建块函数。命令函数接收编辑器状态,可选一个可用于派发事务的 dispatch 函数,以及可选的 EditorView 实例。它应返回布尔值指示能否执行任何动作。未传 dispatch 回调时,命令应做「干运行」,判断它是否可用但不实际做任何事。

这些主要用于绑定按键和定义菜单项。

chainCommands(...commandsreadonly Command[]) → Command

把多个命令函数合并为单个函数(逐个调用直到一个返回 true)。

deleteSelection: Command

删除选区(如果有)。

joinBackward: Command

如果选区为空且位于 textblock 开头,尝试缩小该块与其前一块的距离——若它前面直接有可合并的块,合并它们。若不能,尝试通过把选中块从父节点提升或移入前一块的父节点,使其在文档结构中更接近下一块。给定时,使用视图进行精确的(感知双向文本的)textblock 开头检测。

selectNodeBackward: Command

当选区为空且位于 textblock 开头时,如可能则选中该 textblock 之前的节点。这旨在绑定到 backspace 等键,在 joinBackward 或其他删除命令之后作为 schema 不允许在选中点删除时的回退行为。

joinTextblockBackward: Command

joinBackward 的受限形式,只在光标位于 textblock 开头时尝试把当前 textblock 合并到前一个。

joinForward: Command

如果选区为空且光标位于 textblock 末尾,尝试减少或消除该块与其后一块之间的边界,要么合并它们,要么在树结构中将另一块移近此块。给定时,使用视图进行精确的 textblock 开头检测。

selectNodeForward: Command

当选区为空且位于 textblock 末尾时,如可能则选中该 textblock 之后的节点。这旨在绑定到 delete 等键,在 joinForward 和类似删除命令之后提供回退行为。

joinTextblockForward: Command

joinForward 的受限形式,只在光标位于 textblock 末尾时尝试把当前 textblock 合并到后一个。

joinUp: Command

把选中块(若有文本选区则为选区最近的可合并祖先块)与其上方兄弟合并。

joinDown: Command

把选中块(或选区最近的可合并祖先)与其后方兄弟合并。

lift: Command

把选中块(或选区最近的可提升祖先块)从其父节点提升出来。

newlineInCode: Command

如果选区位于 spec 中 code 属性为真值的节点中,用换行字符替换选区。

exitCode: Command

当选区位于 spec 中 code 属性为真值的节点中时,在代码块之后创建默认块,并把光标移到那里。

createParagraphNear: Command

若选中块节点,在其前(若它是父节点的第一个子节点)或其后创建空段落。

liftEmptyBlock: Command

若光标位于可提升的空 textblock 中,提升该块。

splitBlock: Command

拆分选区的父块。若选区是文本选区,也删除其内容。

splitBlockAs(
splitNode⁠?: fn() → {typeNodeType, attrs⁠?: Attrs} | null
) → Command

创建 splitBlock 的变体,使用自定义函数确定新拆分块的类型。

splitBlockKeepMarks: Command

类似 splitBlock,但不重置光标处的激活标记集。

selectParentNode: Command

把选区移到包裹当前选区的节点(如果有)。(不会选中文档节点。)

selectAll: Command

选中整个文档。

selectTextblockStart: Command

把光标移到当前文本块开头。

selectTextblockEnd: Command

把光标移到当前文本块末尾。

wrapIn(
attrs⁠?: Attrs | null = null
) → Command

用给定类型和给定属性包裹选区。

setBlockType(
attrs⁠?: Attrs | null = null
) → Command

返回尝试把选中 textblock 设为带给定属性的给定节点类型的命令。

toggleMark(
attrs⁠?: Attrs | null = null,
) → Command

创建切换带给定属性的给定标记的命令函数。当前选区不支持该标记时返回 false。若选区中存在该类型的标记则移除它,否则添加它。若选区为空,则作用于存储标记而非文档范围。

options
removeWhenPresent⁠?: boolean

控制当选区中一部分已有该标记而另一部分没有时,是移除标记(true,默认)还是添加标记(false)。

enterInlineAtoms⁠?: boolean

设为 false 时,阻止命令作用于被选区完全覆盖的标记为原子(atom)的行内节点内容。

includeWhitespace⁠?: boolean

默认此命令不作用于选区中首尾的空白。设为 true 改变这一点。

autoJoin(
isJoinablefn(beforeNode, afterNode) → boolean |
readonly string[]
) → Command

包裹命令,使其产生的变换导致两个可合并节点相邻时合并它们。当节点同类型且 isJoinable 谓词对它们返回 true,或(传入字符串数组时)其节点类型名在该数组中时,视为可合并。

baseKeymap: Object<Command>

根据检测到的平台,此值保存 pcBaseKeymapmacBaseKeymap

pcBaseKeymap: Object<Command>

包含不特定于任何 schema 的绑定的基础 keymap。绑定以下按键(列多个命令时,用 chainCommands 链接):

  • Enter to newlineInCode, createParagraphNear, liftEmptyBlock, splitBlock
  • Mod-Enter to exitCode
  • Backspace and Mod-Backspace to deleteSelection, joinBackward, selectNodeBackward
  • Delete and Mod-Delete to deleteSelection, joinForward, selectNodeForward
  • Mod-Delete to deleteSelection, joinForward, selectNodeForward
  • Mod-a to selectAll
macBaseKeymap: Object<Command>

pcBaseKeymap 的副本,还绑定 Ctrl-h(如 Backspace)、Ctrl-d(如 Delete)、Alt-Backspace(如 Ctrl-Backspace),以及 Ctrl-Alt-Backspace、Alt-Delete、Alt-d(如 Ctrl-Delete)。

prosemirror-history 模块

ProseMirror 撤销/重做历史的实现。此历史是选择性的,意味着它不只是回滚到之前状态,而是可以在保持其他较晚更改不变的同时撤销某些更改。(这对协同编辑是必要的,其他场景也会遇到。)

history(config⁠?: Object = {}) → Plugin

返回为编辑器启用撤销历史的插件。插件会跟踪撤销和重做栈,可与 undoredo 命令一起使用。

你可以在事务上把 "addToHistory" 元数据属性设为 false,防止它被撤销回滚。

config
depth⁠?: number

收集的历史事件数量,超过后最旧的事件被丢弃。默认为 100。

newGroupDelay⁠?: number

更改之间开始新组的时间间隔。默认为 500(毫秒)。注意,当更改不相邻时,总是开始新组。

undo: Command

撤销最后一次更改(如果有)的命令函数。

redo: Command

重做最后一次撤销的更改(如果有)的命令函数。

undoNoScroll: Command

撤销最后一次更改的命令函数。不把选区滚动到可见区域。

redoNoScroll: Command

重做最后一次撤销的更改的命令函数。不把选区滚动到可见区域。

undoDepth(stateEditorState) → any

给定状态中可撤销事件的数量。

redoDepth(stateEditorState) → any

给定编辑器状态中可重做事件的数量。

closeHistory(trTransaction) → Transaction

在给定事务上设置标志,阻止进一步步骤追加到现有历史事件(使它们需要单独的撤销命令来撤销)。

isHistoryTransaction(trTransaction) → boolean

如果给定事务由 history 插件生成,返回 true。

prosemirror-collab 模块

此模块实现了一个 API,协同编辑的通信通道可以接入其中。更多细节和示例见指南。

collab(config⁠?: Object = {}) → Plugin

创建为编辑器启用协同编辑框架的插件。

config
version⁠?: number

协同编辑的起始版本号。默认为 0。

clientID⁠?: number | string

此客户端的 ID,用于区分其更改与其他客户端的更改。默认为随机 32 位数。

getVersion(stateEditorState) → number

获取 collab 插件已与中央权威同步到的版本。

receiveTransaction(
stepsreadonly Step[],
clientIDsreadonly (string | number)[],
options⁠?: Object = {}
) → Transaction

创建表示从权威收到的一组新步骤的事务。应用此事务使状态前进以适配权威对文档的视图。

options
mapSelectionBackward⁠?: boolean

启用时(默认 false),如果当前选区是文本选区,其两侧在此事务中按负偏置映射,使插入到光标处的内容落到光标之后。用户通常更喜欢这样,但出于向后兼容原因默认不做。

sendableSteps(stateEditorState) → {
versionnumber,
stepsreadonly Step[],
clientIDnumber | string,
originsreadonly Transaction[]
} |

提供描述编辑器未确认步骤的数据,这些步骤需要发送给中央权威。无内容可发送时返回 null。

origins 保存产生每个步骤的原始事务。这对于查找步骤的时间戳和其他元数据有用,但注意步骤可能已被 rebase,而 origin 事务仍是旧的未变对象。

prosemirror-keymap 模块

用于方便定义按键绑定的插件。

keymap(bindingsObject<Command>) → Plugin

为给定绑定集创建 keymap 插件。

绑定应把键名映射到命令风格函数,以 (EditorState, dispatch, EditorView) 参数调用,处理了该键时返回 true。注意 view 参数不是命令协议的一部分,但可在绑定需要直接与 UI 交互时作为逃生出口。

键名可以是 "Shift-Ctrl-Enter" 这样的字符串——一个键标识符,前置零个或多个修饰键。键标识符基于 KeyEvent.key 中可出现的字符串。用小写字母指字母键(或想按住 shift 时用大写字母)。可以用 "Space" 作为 " " 名称的别名。

修饰键可按任意顺序给出。识别 Shift-(或 s-)、Alt-(或 a-)、Ctrl-(或 c- 或 Control-)和 Cmd-(或 m- 或 Meta-)。对于按住 shift 产生的字符,Shift- 前缀是隐含的,不应显式添加。

可以用 Mod- 作为 Mac 上 Cmd- 和其他平台 Ctrl- 的简写。

你可以给编辑器添加多个 keymap 插件。它们出现的顺序决定优先级(数组中靠前的先派发)。

keydownHandler(bindingsObject<Command>) → fn(viewEditorView, eventKeyboardEvent) → boolean

给定一组绑定(使用与 keymap 相同的格式),返回处理它们的 keydown 处理器。

prosemirror-inputrules 模块

此模块定义一个把输入规则附加到编辑器的插件,可对用户输入的文本做出反应或变换。它还附带一堆可在此插件中启用的默认规则。

class InputRule

输入规则是描述一段文本的正则表达式,输入时触发某件事。这可能是把两个连字符变成破折号、把以 "> " 开头的段落包裹成 blockquote,或完全不同的东西。

new InputRule(
options⁠?: Object = {}
)

创建输入规则。当用户输入了某些内容且光标正前方的文本匹配 match(应以 $ 结尾)时,规则应用。

处理函数可以是字符串,此时匹配文本(或正则中第一个匹配组)被该字符串替换。

也可以是函数,用 RegExp.exec 产生的匹配数组以及匹配范围的起止调用,可返回描述规则效果的事务,或 null 表示输入未被处理。

options
undoable⁠?: boolean

设为 false 时,undoInputRule 不作用于该规则。

inCode⁠?: boolean | "only"

默认输入规则不应用于标记为代码的节点内部。设为 true 改变这一点,或设为 "only" 只在此类节点中匹配。

inCodeMark⁠?: boolean

设为 false 时,该规则不会在标记为代码的标记内部触发。默认 true。

inCode: boolean | "only"
inCodeMark: boolean | "only"
inputRules({rulesreadonly InputRule[]}) → Plugin<
{transformTransaction, fromnumber, tonumber, textstring} |
>

创建输入规则插件。启用时,使匹配任一给定规则的文本输入触发该规则的动作。

undoInputRule: Command

这是一个撤销输入规则的命令,如果应用这样的规则是用户做的最后一件事。

模块附带许多预定义规则:

emDash: InputRule

把双连字符转换为破折号。

ellipsis: InputRule

把三个点转换为省略号字符。

openDoubleQuote: InputRule

「智能」开双引号。

closeDoubleQuote: InputRule

「智能」闭双引号。

openSingleQuote: InputRule

「智能」开单引号。

closeSingleQuote: InputRule

「智能」闭单引号。

smartQuotes: readonly InputRule[]

与智能引号相关的输入规则。

这些工具函数接收 schema 特定参数,创建特定于该 schema 的输入规则。

wrappingInputRule(
getAttrs⁠?: Attrs | = null,
) → InputRule

构建在输入给定字符串时自动包裹 textblock 的输入规则。regexp 参数直接传给 InputRule 构造函数。你大概想让正则以 ^ 开头,使模式只能出现在 textblock 开头。

nodeType 是要包裹进的节点类型。若它需要属性,你可以直接传,或传一个从正则匹配计算它们的函数。

默认如果新包裹节点上方有同类型节点,规则会尝试合并这两个节点。你可以传 join 谓词,它接收正则匹配和包裹节点之前的节点,返回布尔值指示是否应合并。

textblockTypeInputRule(
getAttrs⁠?: Attrs | = null
) → InputRule

构建在匹配文本输入到 textblock 时改变其类型的输入规则。你通常想让正则以 ^ 开头,使其只在 textblock 开头匹配。可选 getAttrs 参数用于计算新节点的属性,工作方式与 wrappingInputRule 函数中相同。

prosemirror-gapcursor 模块

这是一个插件,添加一种选区类型,用于聚焦不允许常规选区的位置(例如前后都是叶子块节点、表格或文档末尾的位置)。默认叶子块和隔离节点允许 gap cursor 出现在它们旁边。你可以给块节点 spec 添加 creatGapCursor: true 属性,使其也出现在其他节点旁边。

你大概想加载 style/gapcursor.css,它包含模拟光标(一个短小的闪烁水平条)的基础样式。

默认 gap cursor 只允许出现在默认内容节点(按 schema 内容约束)是 textblock 节点的位置。你可以通过给节点 spec 添加 allowGapCursor 属性自定义——若为 true,该节点中到处允许 gap cursor,若为 false 则从不允许。

gapCursor() → Plugin

创建 gap cursor 插件。启用时,它会捕获附近没有正常可选位置的地方附近的点击和方向键移动,并为它们创建 gap cursor 选区。光标绘制为 class 为 ProseMirror-gapcursor 的元素。你可以从包目录包含 style/gapcursor.css 或添加自己的样式使其可见。

class GapCursor extends Selection

Gap cursor 选区用此类表示。其 $anchor$head 属性都指向光标位置。

new GapCursor($posResolvedPos)

创建 gap cursor。

prosemirror-schema-basic 模块

此模块定义了一个简单 schema。你可以直接使用、扩展它,或挑出几个节点和标记 spec 用于新 schema。

schema: Schema<
"blockquote" |
"doc" |
"paragraph" |
"horizontal_rule" |
"heading" |
"code_block" |
"text" |
"image" |
"hard_break"
,
"code" | "em" | "strong" | "link"
>

此 schema 大致对应 CommonMark 使用的文档 schema,减去列表元素(它们在 prosemirror-schema-list 模块中定义)。

要复用此 schema 的元素,从它的 spec.nodesspec.marks 属性扩展或读取。

nodes: Object

此 schema 中定义的节点的 spec。

doc: NodeSpec

顶层文档节点。

paragraph: NodeSpec

普通段落 textblock。在 DOM 中表示为 <p> 元素。

blockquote: NodeSpec

包裹一个或多个块的 blockquote(<blockquote>)。

horizontal_rule: NodeSpec

水平线(<hr>)。

heading: NodeSpec

标题 textblock,带 level 属性,值应为 1 到 6。解析和序列化为 <h1><h6> 元素。

code_block: NodeSpec

代码列表。默认不允许标记或非文本行内节点。表示为 <pre> 元素,内含 <code> 元素。

text: NodeSpec

文本节点。

image: NodeSpec

行内图片(<img>)节点。支持 srcalthref 属性。后两者默认为空字符串。

hard_break: NodeSpec

硬换行,DOM 中表示为 <br>

marks: Object

schema 中标记的 spec。

链接。有 hreftitle 属性。title 默认为空字符串。渲染和解析为 <a> 元素。

em: MarkSpec

强调标记。渲染为 <em> 元素。解析规则也匹配 <i> 和 font-style: italic。

strong: MarkSpec

加粗标记。渲染为 <strong>,解析规则也匹配 <b> 和 font-weight: bold。

code: MarkSpec

代码字体标记。表示为 <code> 元素。

prosemirror-schema-list 模块

此模块导出列表相关的 schema 元素和命令。命令假定列表可嵌套,限制是列表项的第一个子节点是普通段落。

这些是节点 spec:

orderedList: NodeSpec

有序列表节点 spec。有一个属性 order,决定列表开始计数的数字,默认为 1。表示为 <ol> 元素。

bulletList: NodeSpec

无序列表节点 spec,DOM 中表示为 <ul>

listItem: NodeSpec

列表项(<li>)spec。

addListNodes() → OrderedMap<NodeSpec>

把列表相关节点类型添加到指定 schema 节点映射的便捷函数。把 orderedList 添加为 "ordered_list",bulletList 添加为 "bullet_list",listItem 添加为 "list_item"

itemContent 决定列表项的内容表达式。若你想让本模块定义的命令应用于你的列表结构,其形状应类似 "paragraph block*""paragraph (ordered_list | bullet_list)*"。可给 listGroup 为列表节点类型分配组名,例如 "block"

使用它看起来像这样:

const mySchema = new Schema({
  nodes: addListNodes(baseSchema.spec.nodes, "paragraph block*", "block"),
  marks: baseSchema.spec.marks
})

以下函数是命令和工具:

wrapInList(
attrs⁠?: Attrs | null = null
) → Command

返回用给定类型和属性把选区包裹进列表的命令函数。若 dispatch 为 null,只返回值指示是否可行,不实际执行更改。

wrapRangeInList(
attrs⁠?: Attrs | null = null
) → boolean

尝试把给定节点范围包裹在给定类型的列表中。可行时返回 true,否则 false。当 tr 非 null 时,包裹加入该事务。为 null 时,函数只查询包裹是否可行。

splitListItem(itemTypeNodeType, itemAttrs⁠?: Attrs) → Command

构建拆分列表项顶层非空 textblock 时也拆分该列表项的命令。

splitListItemKeepMarks(itemTypeNodeType, itemAttrs⁠?: Attrs) → Command

类似 splitListItem,但不重置光标处的激活标记集。

liftListItem(itemTypeNodeType) → Command

创建把选区周围列表项提升到包裹列表的命令。

sinkListItem(itemTypeNodeType) → Command

创建把选区周围列表项下沉到内部列表的命令。