mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-02-01 05:16:10 +01:00
fix getFragmentAtRange to use paths properly (#2012)
#### Is this adding or improving a _feature_ or fixing a _bug_? Bug. #### What's the new behavior? Fixes `Node.getFragmentAtRange` to use the proper argument signature when calling `Node.splitNode`, and refactors it to use paths for all of its logic. #### Have you checked that...? <!-- Please run through this checklist for your pull request: --> * [x] The new code matches the existing patterns and styles. * [x] The tests pass with `yarn test`. * [x] The linter passes with `yarn lint`. (Fix errors with `yarn prettier`.) * [x] The relevant examples still work. (Run examples with `yarn watch`.) #### Does this fix any issues or need any specific reviewers? Fixes: #2009
This commit is contained in:
parent
638d3e8e61
commit
06bca539dc
@ -673,64 +673,35 @@ class Node {
|
||||
|
||||
getFragmentAtRange(range) {
|
||||
range = range.normalize(this)
|
||||
if (range.isUnset) return Document.create()
|
||||
|
||||
if (range.isUnset) {
|
||||
return Document.create()
|
||||
}
|
||||
|
||||
const { startPath, startOffset, endPath, endOffset } = range
|
||||
let node = this
|
||||
let targetPath = endPath
|
||||
let targetPosition = endOffset
|
||||
let mode = 'end'
|
||||
|
||||
// Make sure the children exist.
|
||||
const { startKey, startOffset, endKey, endOffset } = range
|
||||
const startText = node.assertDescendant(startKey)
|
||||
const endText = node.assertDescendant(endKey)
|
||||
while (targetPath.size) {
|
||||
const index = targetPath.last()
|
||||
node = node.splitNode(targetPath, targetPosition)
|
||||
targetPosition = index + 1
|
||||
targetPath = PathUtils.lift(targetPath)
|
||||
|
||||
// Split at the start and end.
|
||||
let child = startText
|
||||
let previous
|
||||
let parent
|
||||
|
||||
while ((parent = node.getParent(child.key))) {
|
||||
const index = parent.nodes.indexOf(child)
|
||||
const position =
|
||||
child.object == 'text' ? startOffset : child.nodes.indexOf(previous)
|
||||
|
||||
parent = parent.splitNode(index, position)
|
||||
node = node.replaceNode(parent.key, parent)
|
||||
previous = parent.nodes.get(index + 1)
|
||||
child = parent
|
||||
if (!targetPath.size && mode === 'end') {
|
||||
targetPath = startPath
|
||||
targetPosition = startOffset
|
||||
mode = 'start'
|
||||
}
|
||||
}
|
||||
|
||||
child = startKey == endKey ? node.getNextText(startKey) : endText
|
||||
|
||||
while ((parent = node.getParent(child.key))) {
|
||||
const index = parent.nodes.indexOf(child)
|
||||
const position =
|
||||
child.object == 'text'
|
||||
? startKey == endKey ? endOffset - startOffset : endOffset
|
||||
: child.nodes.indexOf(previous)
|
||||
|
||||
parent = parent.splitNode(index, position)
|
||||
node = node.replaceNode(parent.key, parent)
|
||||
previous = parent.nodes.get(index + 1)
|
||||
child = parent
|
||||
}
|
||||
|
||||
// Get the start and end nodes.
|
||||
const startNode = node.getNextSibling(
|
||||
node.getFurthestAncestor(startKey).key
|
||||
)
|
||||
const endNode =
|
||||
startKey == endKey
|
||||
? node.getNextSibling(
|
||||
node.getNextSibling(node.getFurthestAncestor(endKey).key).key
|
||||
)
|
||||
: node.getNextSibling(node.getFurthestAncestor(endKey).key)
|
||||
|
||||
// Get children range of nodes from start to end nodes
|
||||
const startIndex = node.nodes.indexOf(startNode)
|
||||
const endIndex = node.nodes.indexOf(endNode)
|
||||
const startIndex = startPath.first() + 1
|
||||
const endIndex = endPath.first() + 2
|
||||
const nodes = node.nodes.slice(startIndex, endIndex)
|
||||
|
||||
// Return a new document fragment.
|
||||
return Document.create({ nodes })
|
||||
const fragment = Document.create({ nodes })
|
||||
return fragment
|
||||
}
|
||||
|
||||
/**
|
||||
|
28
packages/slate/test/models/node/get-fragment-at-range.js
Normal file
28
packages/slate/test/models/node/get-fragment-at-range.js
Normal file
@ -0,0 +1,28 @@
|
||||
/** @jsx h */
|
||||
|
||||
import h from '../../helpers/h'
|
||||
import assert from 'assert'
|
||||
|
||||
export default function() {
|
||||
const value = (
|
||||
<value>
|
||||
<document>
|
||||
<paragraph>
|
||||
one <anchor />two<focus /> three
|
||||
</paragraph>
|
||||
</document>
|
||||
</value>
|
||||
)
|
||||
|
||||
const { document, selection } = value
|
||||
const actual = document.getFragmentAtRange(selection)
|
||||
const expected = (
|
||||
<document>
|
||||
<paragraph>two</paragraph>
|
||||
</document>
|
||||
)
|
||||
|
||||
const a = actual.toJSON()
|
||||
const e = expected.toJSON()
|
||||
assert.deepEqual(a, e)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user