简介
prosemirror-transform 是一个操作文档树的库,用于对 ProseMirror 文档进行变换和操作。它提供了一些可以逐步应用到 document tree 上的操作函数,以及一个简单的 diff 函数。
安装
你可以通过 npm 安装 prosemirror-transform 包:
npm install prosemirror-transform
使用方式
转换操作
对于文档树的变换操作,prosemirror-transform 提供了一些方法以便于开发人员进行操作。下面是这些方法的一些简单介绍:
- replace:用新的节点替换当前节点
- addMark:在一个 node 或者 slice 的节点上添加一个 mark,如果已经有了相同类型的 mark,则 merge 它们
- removeMark:在 node 或者 slice 上移除 mark
- setNodeMarkup:将一个节点的属性全部更新为指定的属性
- splitNode:拆分节点
- joinNode:将两个相邻的同类型节点合并为一个
- liftTarget:移动节点到相邻的外层类型相同的节点下
- wrap:包裹节点
- setBlockType:用新的类型替换给定节点的节点类型
- replaceWith:使用一个给定的 slice 替换该节点
- remove:将该节点从上下文中删除
- addListNodes:
- removeListNodes:
- addToSet:
- removeFromSet:
示例代码
以下是一个示例代码,用于将文档树中所有的 headings (例如
、) 替换为相应的 paragraph 标签。
-- -------------------- ---- -------
------ - ------- --------- - ---- --------------------
------ - --------- - ---- ------------------------
-- -- --------------------- ------
----- ------ - --- --------
------ -
---- - -------- -------- --
---------- - -------- ---------- ------ ------- --
-------- - ------ - ------ - -------- - - -- -------- ---------- ------ -------- --------- ---- --
----- - ------- ---- --
------ - ------- ----- ------ - ---- -- - --
--
---
----- --- - -----------------------------------------------------------------------
-- --------
-------- ------------------------------- ----- -
------------------------- ------------------------
-
-- -----------
----- -------------- - -------------- -----------------------------------
---------------------------------------
深度解析
replace
-- -------------------- ---- ------- ------ - ------- --------- - ---- -------------------- ------ - --------- - ---- ------------------------ -- -- --------------------- ------ ----- ------ - --- -------- ------ - ---- - -------- -------- -- ---------- - -------- ---------- ------ ------- -- -------- - ------ - ------ - -------- - - -- -------- ---------- ------ -------- --------- ---- -- ----- - ------- ---- -- ------ - ------- ----- ------ - ---- -- - -- -- --- ----- --- - ----------------------------------------------------------------------- -- -------- -------- ------------------------------- ----- - ------------------------- ------------------------ - -- ----------- ----- -------------- - -------------- ----------------------------------- ---------------------------------------
深度解析
replace
replace
方法用新的节点替换当前节点。
示例代码:
-- -------------------- ---- ------- -------- ------------------ ----- - -- --------------- --- ---------- - ----- ----------- - ----------------- -- - -------- ------------ ------------------------ -------- - -------------- ----------------------------------- -------------- - - ----- -------------- - -------------- ---------------------- ---------------------------------------
addMark
addMark
在一个 node 或者 slice 的节点上添加一个 mark,如果已经有了相同类型的 mark,则 merge 它们。
示例代码:
function addMyCustomMark(tr, node) { const marks = node.marks || []; const newMarks = marks.concat(schema.mark('my-custom-mark-type')); tr.addMark(node.pos, node.pos + node.nodeSize, schema.nodes.create({ marks: newMarks })); } const transformedDoc = transform(doc, [addMyCustomMark]).doc; console.log(transformedDoc.toString());
removeMark
removeMark
从 node 或者 slice 上移除 mark。
示例代码:
function removeMyCustomMark(tr, node) { const marks = node.marks || []; const newMarks = marks.filter(mark => mark.type.name === 'my-custom-mark-type'); tr.addMark(node.pos, node.pos + node.nodeSize, schema.nodes.create({ marks: newMarks })); } const transformedDoc = transform(doc, [removeMyCustomMark]).doc; console.log(transformedDoc.toString());
setNodeMarkup
setNodeMarkup
将一个节点的属性全部更新为指定的属性。
示例代码:
-- -------------------- ---- ------- -------- ----------------- ----- - -- --------------- --- ------------ - -------------------------- ----- - ---------------- ----- -- -- ------ ----------- --- - - ----- -------------- - -------------- --------------------- ---------------------------------------
splitNode
splitNode
将一个节点拆分成多个节点。
示例代码:
function splitMyCustomNode(tr, node) { if (node.type.name === 'paragraph') { tr.split(node.pos + 10); } } const transformedDoc = transform(doc, [splitMyCustomNode]).doc; console.log(transformedDoc.toString());
joinNode
joinNode
将两个相邻的同类型节点合并为一个。
示例代码:
-- -------------------- ---- ------- -------- -------------------- ----- - ----- ---------- - ---------------------- - --- ----- --------- - ---------------------- - --------------- -- ---------- -- ---------- -- ------------------- --- --------------------- - ---------------- - --------------- - - ----- -------------- - -------------- ------------------------ ---------------------------------------
liftTarget
liftTarget
将一个节点移动到相邻的外层类型相同的节点下。
示例代码:
-- -------------------- ---- ------- -------- -------------------- ----- - -- --------------- --- ------------ - ----- ------ - -------------------------------- -- ----------------- --- ------------ - ----------------- -------- - -------------- --- - - - ----- -------------- - -------------- ------------------------ ---------------------------------------
wrap
wrap
可以将节点包裹起来。
示例代码:
-- -------------------- ---- ------- -------- -------------------- ----- - -- --------------- --- ------------ - ----- ------------- - ---------- - -- ----- ----------- - -------- - ------------- - -- ----- ------------ - ------------------------------------------ ------ ---------------------- ------------ ------------------- - - ----- -------------- - -------------- ------------------------ ---------------------------------------
setBlockType
setBlockType
可以用新的类型替换给定节点的节点类型。
示例代码:
function setCustomBlockType(tr, node) { if (node.type.name === 'paragraph') { tr.setBlockType(node.pos, schema.nodes.myCustomBlockType); } } const transformedDoc = transform(doc, [setCustomBlockType]).doc; console.log(transformedDoc.toString());
replaceWith
replaceWith
使用一个给定的 slice 替换该节点。
示例代码:
-- -------------------- ---- ------- -------- ----------------------- ----- - -- --------------- --- -------------------- - ----- ----- - ---------------------- ------------------------ -------- - -------------- ------- - - ----- -------------- - -------------- --------------------------- ---------------------------------------
remove
remove
将该节点从上下文中删除。
示例代码:
function removeMyCustomNode(tr, node) { if (node.type.name === 'myCustomType') { tr.delete(node.pos, node.pos + node.nodeSize); } } const transformedDoc = transform(doc, [removeMyCustomNode]).doc; console.log(transformedDoc.toString());
addListNodes
addListNodes
可以在列表节点中添加新的列表项。
示例代码:
-- -------------------- ---- ------- -------- --------------------- ----- - -- -------------- -- ----------------------------------------------- - ------- - ----- -------- - ----------------------------------------- ----------------------- ----- -------- - -------------------------------------- ----- ------- - ------------------------------------------------ ---------- ------------------------ -------- - -------------- --------- - ----- -------------- - -------------- ------------------------- ---------------------------------------
removeFromSet
removeFromSet
是用来向一个节点的属性集合中删除一个成员。
示例代码:
-- -------------------- ---- ------- -------- --------------------------- ----- - -- ---------------------------- - ----- -------- - ----------------- ------------ ------ ------------------------- -------------------------- ---------- --------- ------------ - - ----- -------------- - -------------- ------------------------------- ---------------------------------------
总结
prosemirror-transform 提供了很多的操作函数,能够方便地对 document tree 进行变换和操作,使得文档的变换和操作变得更加容易和灵活。在编写复杂文本编辑器时,它是必不可少的一个库。我们从丰富的 API 中介绍了如何使用它来完成各种文档操作。它在使用时需要注意节点的类型和层级关系,灵活使用不同的操作函数,以达到最佳的文档操作效果。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/prosemirror-transform