mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-19 13:41:19 +02:00
fix selection logic for non-merging fragments
This commit is contained in:
@@ -150,12 +150,17 @@ Changes.insertFragment = (change, fragment) => {
|
|||||||
const { startText, endText, startInline } = value
|
const { startText, endText, startInline } = value
|
||||||
const lastText = fragment.getLastText()
|
const lastText = fragment.getLastText()
|
||||||
const lastInline = fragment.getClosestInline(lastText.key)
|
const lastInline = fragment.getClosestInline(lastText.key)
|
||||||
|
const firstChild = fragment.nodes.first()
|
||||||
|
const lastChild = fragment.nodes.last()
|
||||||
const keys = document.getTexts().map(text => text.key)
|
const keys = document.getTexts().map(text => text.key)
|
||||||
const isAppending =
|
const isAppending =
|
||||||
!startInline ||
|
!startInline ||
|
||||||
selection.hasEdgeAtStartOf(startText) ||
|
selection.hasEdgeAtStartOf(startText) ||
|
||||||
selection.hasEdgeAtEndOf(endText)
|
selection.hasEdgeAtEndOf(endText)
|
||||||
|
|
||||||
|
const isInserting =
|
||||||
|
fragment.hasBlocks(firstChild.key) || fragment.hasBlocks(lastChild.key)
|
||||||
|
|
||||||
change.insertFragmentAtRange(selection, fragment)
|
change.insertFragmentAtRange(selection, fragment)
|
||||||
value = change.value
|
value = change.value
|
||||||
document = value.document
|
document = value.document
|
||||||
@@ -163,7 +168,7 @@ Changes.insertFragment = (change, fragment) => {
|
|||||||
const newTexts = document.getTexts().filter(n => !keys.includes(n.key))
|
const newTexts = document.getTexts().filter(n => !keys.includes(n.key))
|
||||||
const newText = isAppending ? newTexts.last() : newTexts.takeLast(2).first()
|
const newText = isAppending ? newTexts.last() : newTexts.takeLast(2).first()
|
||||||
|
|
||||||
if (newText && lastInline) {
|
if ((newText && lastInline) || isInserting) {
|
||||||
change.select(selection.collapseToEndOf(newText))
|
change.select(selection.collapseToEndOf(newText))
|
||||||
} else if (newText) {
|
} else if (newText) {
|
||||||
change.select(
|
change.select(
|
||||||
|
@@ -698,6 +698,8 @@ Changes.insertFragmentAtRange = (change, range, fragment, options = {}) => {
|
|||||||
const parent = document.getParent(startBlock.key)
|
const parent = document.getParent(startBlock.key)
|
||||||
const index = parent.nodes.indexOf(startBlock)
|
const index = parent.nodes.indexOf(startBlock)
|
||||||
const blocks = fragment.getBlocks()
|
const blocks = fragment.getBlocks()
|
||||||
|
const firstChild = fragment.nodes.first()
|
||||||
|
const lastChild = fragment.nodes.last()
|
||||||
const firstBlock = blocks.first()
|
const firstBlock = blocks.first()
|
||||||
const lastBlock = blocks.last()
|
const lastBlock = blocks.last()
|
||||||
|
|
||||||
@@ -709,13 +711,8 @@ Changes.insertFragmentAtRange = (change, range, fragment, options = {}) => {
|
|||||||
|
|
||||||
// If the fragment starts or ends with single nested block, (e.g., table),
|
// If the fragment starts or ends with single nested block, (e.g., table),
|
||||||
// do not merge this fragment with existing blocks.
|
// do not merge this fragment with existing blocks.
|
||||||
if (
|
if (fragment.hasBlocks(firstChild.key) || fragment.hasBlocks(lastChild.key)) {
|
||||||
firstBlock != lastBlock &&
|
fragment.nodes.reverse().forEach(node => {
|
||||||
Block.isBlock(fragment.nodes.first()) &&
|
|
||||||
Block.isBlock(fragment.nodes.last()) &&
|
|
||||||
(firstBlock != fragment.nodes.first() || lastBlock != fragment.nodes.last())
|
|
||||||
) {
|
|
||||||
fragment.nodes.reverse().forEach((node) => {
|
|
||||||
change.insertBlockAtRange(range, node, options)
|
change.insertBlockAtRange(range, node, options)
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
|
@@ -1662,6 +1662,32 @@ class Node {
|
|||||||
return !!this.getChild(key)
|
return !!this.getChild(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a node has block node children.
|
||||||
|
*
|
||||||
|
* @param {String} key
|
||||||
|
* @return {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
hasBlocks(key) {
|
||||||
|
const node = this.assertNode(key)
|
||||||
|
return !!(node.nodes && node.nodes.find(n => n.object === 'block'))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a node has inline node children.
|
||||||
|
*
|
||||||
|
* @param {String} key
|
||||||
|
* @return {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
hasInlines(key) {
|
||||||
|
const node = this.assertNode(key)
|
||||||
|
return !!(
|
||||||
|
node.nodes && node.nodes.find(n => Inline.isInline(n) || Text.isText(n))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursively check if a child node exists by `key`.
|
* Recursively check if a child node exists by `key`.
|
||||||
*
|
*
|
||||||
|
@@ -26,12 +26,14 @@ export const input = (
|
|||||||
export const output = (
|
export const output = (
|
||||||
<value>
|
<value>
|
||||||
<document>
|
<document>
|
||||||
<paragraph>woone</paragraph>
|
<paragraph>wo</paragraph>
|
||||||
<quote>
|
<quote>
|
||||||
<quote>
|
<quote>one</quote>
|
||||||
two<cursor />rd
|
<quote>two</quote>
|
||||||
</quote>
|
|
||||||
</quote>
|
</quote>
|
||||||
|
<paragraph>
|
||||||
|
rd<cursor />
|
||||||
|
</paragraph>
|
||||||
</document>
|
</document>
|
||||||
</value>
|
</value>
|
||||||
)
|
)
|
||||||
|
@@ -29,12 +29,14 @@ export const output = (
|
|||||||
<value>
|
<value>
|
||||||
<document>
|
<document>
|
||||||
<quote>
|
<quote>
|
||||||
<paragraph>woone</paragraph>
|
<paragraph>wo</paragraph>
|
||||||
<quote>
|
<quote>
|
||||||
<quote>
|
<quote>one</quote>
|
||||||
two<cursor />rd
|
<quote>two</quote>
|
||||||
</quote>
|
|
||||||
</quote>
|
</quote>
|
||||||
|
<paragraph>
|
||||||
|
rd<cursor />
|
||||||
|
</paragraph>
|
||||||
</quote>
|
</quote>
|
||||||
</document>
|
</document>
|
||||||
</value>
|
</value>
|
||||||
|
Reference in New Issue
Block a user