mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-04-21 13:51:59 +02:00
add split inline with tests
This commit is contained in:
parent
24dd5ba34c
commit
1c68ab5d5c
@ -237,10 +237,7 @@ const Node = {
|
||||
getBlocksAtRange(range) {
|
||||
range = range.normalize(this)
|
||||
const texts = this.getTextsAtRange(range)
|
||||
const blocks = texts.map((text) => {
|
||||
return this.getClosest(text, p => p.kind == 'block')
|
||||
})
|
||||
|
||||
const blocks = texts.map(text => this.getClosestBlock(text))
|
||||
return blocks
|
||||
},
|
||||
|
||||
@ -266,23 +263,80 @@ const Node = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Get closest parent of `node` that matches `iterator`.
|
||||
* Get closest parent of node by `key` that matches `iterator`.
|
||||
*
|
||||
* @param {Node} node
|
||||
* @param {String or Node} key
|
||||
* @param {Function} iterator
|
||||
* @return {Node or Null} node
|
||||
* @return {Node or Null} parent
|
||||
*/
|
||||
|
||||
getClosest(node, iterator) {
|
||||
while (node) {
|
||||
getClosest(key, iterator) {
|
||||
key = normalizeKey(key)
|
||||
this.assertHasDeep(key)
|
||||
|
||||
let node = this.getDeep(key)
|
||||
|
||||
while (node = this.getParent(node)) {
|
||||
if (node == this) return null
|
||||
if (iterator(node)) return node
|
||||
node = this.getParent(node)
|
||||
}
|
||||
|
||||
return null
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the closest block parent of a `node`.
|
||||
*
|
||||
* @param {String or Node} key
|
||||
* @return {Node or Null} parent
|
||||
*/
|
||||
|
||||
getClosestBlock(key) {
|
||||
key = normalizeKey(key)
|
||||
this.assertHasDeep(key)
|
||||
|
||||
const match = this.getClosest(key, parent => parent.kind == 'block')
|
||||
return match
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the closest inline parent of a `node`.
|
||||
*
|
||||
* @param {String or Node} key
|
||||
* @return {Node or Null} parent
|
||||
*/
|
||||
|
||||
getClosestInline(key) {
|
||||
key = normalizeKey(key)
|
||||
this.assertHasDeep(key)
|
||||
|
||||
const match = this.getClosest(key, parent => parent.kind == 'inline')
|
||||
return match
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the furthest inline parent of a node by `key`.
|
||||
*
|
||||
* @param {String or Node} key
|
||||
* @return {Node or Null} parent
|
||||
*/
|
||||
|
||||
getFurthestInline(key) {
|
||||
key = normalizeKey(key)
|
||||
this.assertHasDeep(key)
|
||||
|
||||
let child = this.getDeep(key)
|
||||
let furthest = null
|
||||
let next
|
||||
|
||||
while (next = this.getClosestInline(child)) {
|
||||
furthest = next
|
||||
child = next
|
||||
}
|
||||
|
||||
return furthest
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a child node by `key`.
|
||||
*
|
||||
@ -306,6 +360,8 @@ const Node = {
|
||||
|
||||
getDepth(key, startAt = 1) {
|
||||
key = normalizeKey(key)
|
||||
this.assertHasDeep(key)
|
||||
|
||||
if (this.nodes.has(key)) return startAt
|
||||
|
||||
const child = this.nodes.find(node => {
|
||||
@ -407,6 +463,7 @@ const Node = {
|
||||
|
||||
getNextSibling(key) {
|
||||
key = normalizeKey(key)
|
||||
this.assertHasDeep(key)
|
||||
|
||||
if (this.nodes.has(key)) {
|
||||
return this.nodes
|
||||
@ -430,6 +487,8 @@ const Node = {
|
||||
|
||||
getNextText(key) {
|
||||
key = normalizeKey(key)
|
||||
this.assertHasDeep(key)
|
||||
|
||||
return this.getTextNodes()
|
||||
.skipUntil(text => text.key == key)
|
||||
.take(2)
|
||||
@ -444,7 +503,9 @@ const Node = {
|
||||
*/
|
||||
|
||||
getOffset(key) {
|
||||
key = normalizeKey(key)
|
||||
this.assertHasDeep(key)
|
||||
|
||||
const match = this.getDeep(key)
|
||||
|
||||
// Find the shallow matching child.
|
||||
@ -479,8 +540,9 @@ const Node = {
|
||||
|
||||
getParent(key) {
|
||||
key = normalizeKey(key)
|
||||
// this.assertHasDeep(key)
|
||||
|
||||
if (this.nodes.get(key)) return this
|
||||
if (this.nodes.has(key)) return this
|
||||
|
||||
let node = null
|
||||
this.nodes.forEach((child) => {
|
||||
@ -501,6 +563,7 @@ const Node = {
|
||||
|
||||
getPreviousSibling(key) {
|
||||
key = normalizeKey(key)
|
||||
this.assertHasDeep(key)
|
||||
|
||||
if (this.nodes.has(key)) {
|
||||
return this.nodes
|
||||
@ -523,6 +586,8 @@ const Node = {
|
||||
|
||||
getPreviousText(key) {
|
||||
key = normalizeKey(key)
|
||||
this.assertHasDeep(key)
|
||||
|
||||
return this.getTextNodes()
|
||||
.takeUntil(text => text.key == key)
|
||||
.last()
|
||||
@ -596,6 +661,7 @@ const Node = {
|
||||
|
||||
hasDeep(key) {
|
||||
key = normalizeKey(key)
|
||||
|
||||
return !! this.nodes.find((node) => {
|
||||
return node.kind == 'text'
|
||||
? node.key == key
|
||||
@ -762,6 +828,7 @@ const Node = {
|
||||
|
||||
removeDeep(key) {
|
||||
key = normalizeKey(key)
|
||||
this.assertHasDeep(key)
|
||||
|
||||
let nodes = this.nodes.remove(key)
|
||||
return this.merge({ nodes })
|
||||
@ -854,52 +921,134 @@ const Node = {
|
||||
range = range.moveToStart()
|
||||
}
|
||||
|
||||
const { startKey, startOffset } = range
|
||||
const startNode = node.getDeep(startKey)
|
||||
// Split the inline nodes at the range.
|
||||
node = node.splitInlineAtRange(range)
|
||||
|
||||
// Split the text node's characters.
|
||||
const { characters, length } = startNode
|
||||
const firstCharacters = characters.take(startOffset)
|
||||
const secondCharacters = characters.takeLast(length - startOffset)
|
||||
// Find the highest inline elements that were split.
|
||||
const { startKey } = range
|
||||
const firstText = node.getDeep(startKey)
|
||||
const firstChild = node.getFurthestInline(firstText) || firstText
|
||||
const secondText = node.getNextText(startKey)
|
||||
const secondChild = node.getFurthestInline(secondText) || secondText
|
||||
|
||||
// Create a new first element with only the first set of characters.
|
||||
const parent = node.getParent(startNode)
|
||||
const firstText = startNode.set('characters', firstCharacters)
|
||||
const firstElement = parent.updateDeep(firstText)
|
||||
// Remove the second inline child from the first block.
|
||||
let firstBlock = node.getBlocksAtRange(range).first()
|
||||
firstBlock = firstBlock.removeDeep(secondChild)
|
||||
|
||||
// Create a brand new second element with the second set of characters.
|
||||
let secondText = Text.create({})
|
||||
let secondElement = Block.create({
|
||||
type: firstElement.type,
|
||||
data: firstElement.data
|
||||
// Create a new block with the second inline child in it.
|
||||
const secondBlock = Block.create({
|
||||
type: firstBlock.type,
|
||||
data: firstBlock.data,
|
||||
nodes: Block.createMap([secondChild])
|
||||
})
|
||||
|
||||
secondText = secondText.set('characters', secondCharacters)
|
||||
secondElement = secondElement.merge({
|
||||
nodes: secondElement.nodes.set(secondText.key, secondText)
|
||||
});
|
||||
// Replace the block in the parent with the two new blocks.
|
||||
let parent = node.getParent(firstBlock)
|
||||
const nodes = parent.nodes.takeUntil(n => n.key == firstBlock.key)
|
||||
.set(firstBlock.key, firstBlock)
|
||||
.set(secondBlock.key, secondBlock)
|
||||
.concat(parent.nodes.skipUntil(n => n.key == firstBlock.key).rest())
|
||||
|
||||
// Replace the old parent node in the grandparent with the two new ones.
|
||||
let grandparent = node.getParent(parent)
|
||||
const befores = grandparent.nodes.takeUntil(child => child.key == parent.key)
|
||||
const afters = grandparent.nodes.skipUntil(child => child.key == parent.key).rest()
|
||||
const nodes = befores
|
||||
.set(firstElement.key, firstElement)
|
||||
.set(secondElement.key, secondElement)
|
||||
.concat(afters)
|
||||
|
||||
// If the node is the grandparent, just merge, otherwise deep merge.
|
||||
if (grandparent == node) {
|
||||
// If the node is the parent, just merge, otherwise deep merge.
|
||||
if (parent == node) {
|
||||
node = node.merge({ nodes })
|
||||
} else {
|
||||
grandparent = grandparent.merge({ nodes })
|
||||
node = node.updateDeep(grandparent)
|
||||
parent = parent.merge({ nodes })
|
||||
node = node.updateDeep(parent)
|
||||
}
|
||||
|
||||
// Normalize the node.
|
||||
return node.normalize()
|
||||
},
|
||||
|
||||
splitInlineAtRange(range) {
|
||||
debugger
|
||||
range = range.normalize(this)
|
||||
const Inline = require('./inline').default
|
||||
let node = this
|
||||
|
||||
// If the range is expanded, remove it first.
|
||||
if (range.isExpanded) {
|
||||
node = node.deleteAtRange(range)
|
||||
range = range.moveToStart()
|
||||
}
|
||||
|
||||
// First split the text nodes.
|
||||
node = node.splitTextAtRange(range)
|
||||
let firstChild = node.getDeep(range.startKey)
|
||||
let secondChild = node.getNextText(firstChild)
|
||||
let parent
|
||||
|
||||
// While the parent is an inline parent, split the inline nodes.
|
||||
while (parent = node.getClosestInline(firstChild)) {
|
||||
debugger
|
||||
const firstNodes = Inline.createMap([firstChild])
|
||||
const secondNodes = Inline.createMap([secondChild])
|
||||
firstChild = parent.merge({ nodes: firstNodes })
|
||||
secondChild = Inline.create({
|
||||
nodes: secondNodes,
|
||||
type: parent.type,
|
||||
data: parent.data
|
||||
})
|
||||
|
||||
// Split the children.
|
||||
const isGrandparent = node.nodes.has(parent.key)
|
||||
const grandparent = isGrandparent ? node : node.getParent(parent)
|
||||
const nodes = grandparent.nodes
|
||||
.takeUntil(c => c.key == firstChild.key)
|
||||
.set(firstChild.key, firstChild)
|
||||
.set(secondChild.key, secondChild)
|
||||
.concat(grandparent.nodes.skipUntil(n => n.key == firstChild.key).rest())
|
||||
|
||||
// Update the grandparent.
|
||||
node = isGrandparent
|
||||
? node.merge({ nodes })
|
||||
: node.updateDeep(grandparent.merge({ nodes }))
|
||||
}
|
||||
|
||||
return node
|
||||
},
|
||||
|
||||
/**
|
||||
* Split the text nodes at a `range`.
|
||||
*
|
||||
* @param {Selection} range
|
||||
* @return {Node} node
|
||||
*/
|
||||
|
||||
splitTextAtRange(range) {
|
||||
range = range.normalize(this)
|
||||
let node = this
|
||||
|
||||
// If the range is expanded, remove it first.
|
||||
if (range.isExpanded) {
|
||||
node = node.deleteAtRange(range)
|
||||
range = range.moveToStart()
|
||||
}
|
||||
|
||||
// Split the text node's characters.
|
||||
const { startKey, startOffset } = range
|
||||
const text = node.getDeep(startKey)
|
||||
const { characters } = text
|
||||
const firstChars = characters.take(startOffset)
|
||||
const secondChars = characters.skip(startOffset)
|
||||
let firstChild = text.merge({ characters: firstChars })
|
||||
let secondChild = Text.create({ characters: secondChars })
|
||||
|
||||
// Split the text nodes.
|
||||
let parent = node.getParent(text)
|
||||
const nodes = parent.nodes
|
||||
.takeUntil(c => c.key == firstChild.key)
|
||||
.set(firstChild.key, firstChild)
|
||||
.set(secondChild.key, secondChild)
|
||||
.concat(parent.nodes.skipUntil(n => n.key == firstChild.key).rest())
|
||||
|
||||
// Update the nodes.
|
||||
parent = parent.merge({ nodes })
|
||||
node = node.updateDeep(parent)
|
||||
return node
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove an existing `mark` to the characters at `range`.
|
||||
*
|
||||
@ -957,6 +1106,8 @@ const Node = {
|
||||
key = normalizeKey(key)
|
||||
}
|
||||
|
||||
// this.assertHasDeep(key)
|
||||
|
||||
if (this.nodes.get(key)) {
|
||||
const nodes = this.nodes.set(key, node)
|
||||
return this.set('nodes', nodes)
|
||||
@ -1091,105 +1242,6 @@ const Node = {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
getClosestInline(child) {
|
||||
return this.getClosest(child, p => p.kind == 'inline')
|
||||
},
|
||||
|
||||
getFurthestInline(child) {
|
||||
let furthest = null
|
||||
let next
|
||||
|
||||
while (next = this.getClosestInline(child)) {
|
||||
furthest = next
|
||||
child = next
|
||||
}
|
||||
|
||||
return furthest
|
||||
},
|
||||
|
||||
splitTextAtRange(range) {
|
||||
range = range.normalize(this)
|
||||
let node = this
|
||||
|
||||
// If the range is expanded, remove it first.
|
||||
if (range.isExpanded) {
|
||||
node = node.deleteAtRange(range)
|
||||
range = range.moveToStart()
|
||||
}
|
||||
|
||||
// Split the text node's characters.
|
||||
const { startKey, startOffset } = range
|
||||
const text = node.getDeep(startKey)
|
||||
const { characters } = text
|
||||
const firstChars = characters.take(startOffset)
|
||||
const secondChars = characters.skip(startOffset)
|
||||
let firstChild = text.merge({ characters: firstChars })
|
||||
let secondChild = Text.create({ characters: secondChars })
|
||||
|
||||
// Split the text nodes.
|
||||
let parent = node.getParent(text)
|
||||
const nodes = parent.nodes
|
||||
.takeUntil(c => c.key == firstChild.key)
|
||||
.set(firstChild.key, firstChild)
|
||||
.set(secondChild.key, secondChild)
|
||||
.concat(parent.nodes.skipUntil(n => n.key == firstChild.key).rest())
|
||||
|
||||
// Update the nodes.
|
||||
parent = parent.merge({ nodes })
|
||||
node = node.updateDeep(parent)
|
||||
return node
|
||||
},
|
||||
|
||||
splitInlineAtRange(range) {
|
||||
range = range.normalize(this)
|
||||
const Inline = require('./inline').default
|
||||
let node = this
|
||||
|
||||
// If the range is expanded, remove it first.
|
||||
if (range.isExpanded) {
|
||||
node = node.deleteAtRange(range)
|
||||
range = range.moveToStart()
|
||||
}
|
||||
|
||||
// First split the text nodes.
|
||||
node = node.splitTextAtRange(range)
|
||||
let firstChild = node.getDeep(range.startKey)
|
||||
let secondChild = node.getNextText(firstChild)
|
||||
let parent
|
||||
|
||||
// While the parent is an inline parent, split the inline nodes.
|
||||
while (parent = node.getClosestInline(firstChild)) {
|
||||
const firstNodes = Inline.createMap([firstChild])
|
||||
const secondNodes = Inline.createMap([secondChild])
|
||||
firstChild = parent.merge({ nodes: firstNodes })
|
||||
secondChild = Inline.create({
|
||||
nodes: secondNodes,
|
||||
type: parent.type,
|
||||
data: parent.data
|
||||
})
|
||||
|
||||
// Split the children.
|
||||
const isGrandparent = node.nodes.has(parent.key)
|
||||
const grandparent = isGrandparent ? node : node.getParent(parent)
|
||||
const nodes = grandparent.nodes
|
||||
.takeUntil(c => c.key == firstChild.key)
|
||||
.set(firstChild.key, firstChild)
|
||||
.set(secondChild.key, secondChild)
|
||||
.concat(parent.nodes.skipUntil(n => n.key == firstChild.key).rest())
|
||||
|
||||
// Update the parent.
|
||||
node = isGrandparent
|
||||
? node.merge({ nodes })
|
||||
: node.updateDeep(parent.merge({ nodes }))
|
||||
}
|
||||
|
||||
return node
|
||||
},
|
||||
|
||||
wrapInlineAtRange(range, type, data = new Map()) {
|
||||
range = range.normalize(this)
|
||||
|
||||
|
@ -0,0 +1,17 @@
|
||||
|
||||
export default function (state) {
|
||||
const { document, selection } = state
|
||||
const texts = document.getTextNodes()
|
||||
const first = texts.first()
|
||||
const range = selection.merge({
|
||||
anchorKey: first.key,
|
||||
anchorOffset: 2,
|
||||
focusKey: first.key,
|
||||
focusOffset: 2
|
||||
})
|
||||
|
||||
return state
|
||||
.transform()
|
||||
.splitBlockAtRange(range)
|
||||
.apply()
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
nodes:
|
||||
- kind: text
|
||||
ranges:
|
||||
- text: word
|
@ -0,0 +1,20 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
nodes:
|
||||
- kind: text
|
||||
ranges:
|
||||
- text: wo
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
nodes:
|
||||
- kind: text
|
||||
ranges:
|
||||
- text: rd
|
@ -0,0 +1,17 @@
|
||||
|
||||
export default function (state) {
|
||||
const { document, selection } = state
|
||||
const texts = document.getTextNodes()
|
||||
const first = texts.first()
|
||||
const range = selection.merge({
|
||||
anchorKey: first.key,
|
||||
anchorOffset: first.length,
|
||||
focusKey: first.key,
|
||||
focusOffset: first.length
|
||||
})
|
||||
|
||||
return state
|
||||
.transform()
|
||||
.splitInlineAtRange(range)
|
||||
.apply()
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
nodes:
|
||||
- kind: text
|
||||
ranges:
|
||||
- text: word
|
@ -0,0 +1,17 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
nodes:
|
||||
- kind: text
|
||||
ranges:
|
||||
- text: word
|
||||
- kind: inline
|
||||
type: link
|
||||
nodes:
|
||||
- kind: text
|
||||
ranges:
|
||||
- text: ""
|
@ -0,0 +1,17 @@
|
||||
|
||||
export default function (state) {
|
||||
const { document, selection } = state
|
||||
const texts = document.getTextNodes()
|
||||
const first = texts.first()
|
||||
const range = selection.merge({
|
||||
anchorKey: first.key,
|
||||
anchorOffset: 2,
|
||||
focusKey: first.key,
|
||||
focusOffset: 2
|
||||
})
|
||||
|
||||
return state
|
||||
.transform()
|
||||
.splitInlineAtRange(range)
|
||||
.apply()
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
nodes:
|
||||
- kind: text
|
||||
ranges:
|
||||
- text: word
|
@ -0,0 +1,17 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
nodes:
|
||||
- kind: text
|
||||
ranges:
|
||||
- text: wo
|
||||
- kind: inline
|
||||
type: link
|
||||
nodes:
|
||||
- kind: text
|
||||
ranges:
|
||||
- text: rd
|
@ -0,0 +1,17 @@
|
||||
|
||||
export default function (state) {
|
||||
const { document, selection } = state
|
||||
const texts = document.getTextNodes()
|
||||
const first = texts.first()
|
||||
const range = selection.merge({
|
||||
anchorKey: first.key,
|
||||
anchorOffset: 0,
|
||||
focusKey: first.key,
|
||||
focusOffset: 0
|
||||
})
|
||||
|
||||
return state
|
||||
.transform()
|
||||
.splitInlineAtRange(range)
|
||||
.apply()
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
nodes:
|
||||
- kind: text
|
||||
ranges:
|
||||
- text: word
|
@ -0,0 +1,17 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
nodes:
|
||||
- kind: text
|
||||
ranges:
|
||||
- text: ""
|
||||
- kind: inline
|
||||
type: link
|
||||
nodes:
|
||||
- kind: text
|
||||
ranges:
|
||||
- text: word
|
@ -0,0 +1,18 @@
|
||||
|
||||
export default function (state) {
|
||||
const { document, selection } = state
|
||||
const texts = document.getTextNodes()
|
||||
const first = texts.first()
|
||||
const second = texts.last()
|
||||
const range = selection.merge({
|
||||
anchorKey: first.key,
|
||||
anchorOffset: 2,
|
||||
focusKey: second.key,
|
||||
focusOffset: 2
|
||||
})
|
||||
|
||||
return state
|
||||
.transform()
|
||||
.splitInlineAtRange(range)
|
||||
.apply()
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
nodes:
|
||||
- kind: text
|
||||
ranges:
|
||||
- text: word
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
nodes:
|
||||
- kind: text
|
||||
ranges:
|
||||
- text: another
|
@ -0,0 +1,17 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
nodes:
|
||||
- kind: text
|
||||
ranges:
|
||||
- text: wo
|
||||
- kind: inline
|
||||
type: link
|
||||
nodes:
|
||||
- kind: text
|
||||
ranges:
|
||||
- text: other
|
@ -0,0 +1,17 @@
|
||||
|
||||
export default function (state) {
|
||||
const { document, selection } = state
|
||||
const texts = document.getTextNodes()
|
||||
const first = texts.first()
|
||||
const range = selection.merge({
|
||||
anchorKey: first.key,
|
||||
anchorOffset: 1,
|
||||
focusKey: first.key,
|
||||
focusOffset: 3
|
||||
})
|
||||
|
||||
return state
|
||||
.transform()
|
||||
.splitInlineAtRange(range)
|
||||
.apply()
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
nodes:
|
||||
- kind: text
|
||||
ranges:
|
||||
- text: word
|
@ -0,0 +1,17 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
nodes:
|
||||
- kind: text
|
||||
ranges:
|
||||
- text: w
|
||||
- kind: inline
|
||||
type: link
|
||||
nodes:
|
||||
- kind: text
|
||||
ranges:
|
||||
- text: d
|
@ -0,0 +1,17 @@
|
||||
|
||||
export default function (state) {
|
||||
const { document, selection } = state
|
||||
const texts = document.getTextNodes()
|
||||
const first = texts.first()
|
||||
const range = selection.merge({
|
||||
anchorKey: first.key,
|
||||
anchorOffset: 2,
|
||||
focusKey: first.key,
|
||||
focusOffset: 2
|
||||
})
|
||||
|
||||
return state
|
||||
.transform()
|
||||
.splitInlineAtRange(range)
|
||||
.apply()
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
nodes:
|
||||
- kind: text
|
||||
ranges:
|
||||
- text: word
|
||||
marks:
|
||||
- type: bold
|
@ -0,0 +1,21 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
nodes:
|
||||
- kind: text
|
||||
ranges:
|
||||
- text: wo
|
||||
marks:
|
||||
- type: bold
|
||||
- kind: inline
|
||||
type: link
|
||||
nodes:
|
||||
- kind: text
|
||||
ranges:
|
||||
- text: rd
|
||||
marks:
|
||||
- type: bold
|
Loading…
x
Reference in New Issue
Block a user