mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-16 20:24:01 +02:00
Fix improper selection after insertFragment (#2976)
* Fix typo & remove useless check * No need to check the end of the selection, as this part is called after the `deleteExpanded` call. Selection is collapsed at this point. * Fix insertFragment selection not place properly
This commit is contained in:
committed by
Ian Storm Taylor
parent
3ed981aedf
commit
2ea6d40ad0
@@ -735,7 +735,7 @@ Commands.insertFragmentAtRange = (editor, range, fragment) => {
|
|||||||
|
|
||||||
// Regenerate the keys for all of the fragments nodes, so that they're
|
// Regenerate the keys for all of the fragments nodes, so that they're
|
||||||
// guaranteed not to collide with the existing keys in the document. Otherwise
|
// guaranteed not to collide with the existing keys in the document. Otherwise
|
||||||
// they will be rengerated automatically and we won't have an easy way to
|
// they will be regenerated automatically and we won't have an easy way to
|
||||||
// reference them.
|
// reference them.
|
||||||
fragment = fragment.mapDescendants(child => child.regenerateKey())
|
fragment = fragment.mapDescendants(child => child.regenerateKey())
|
||||||
|
|
||||||
|
@@ -252,46 +252,41 @@ Commands.insertFragment = (editor, fragment) => {
|
|||||||
|
|
||||||
let { value } = editor
|
let { value } = editor
|
||||||
let { document, selection } = value
|
let { document, selection } = value
|
||||||
const { start, end } = selection
|
const { start } = selection
|
||||||
const { startText, endText, startInline } = value
|
|
||||||
const lastText = fragment.getLastText()
|
|
||||||
const lastInline = fragment.getClosestInline(lastText.key)
|
|
||||||
const lastBlock = fragment.getClosestBlock(lastText.key)
|
|
||||||
const firstChild = fragment.nodes.first()
|
|
||||||
const lastChild = fragment.nodes.last()
|
|
||||||
const keys = Array.from(document.texts(), ([text]) => text.key)
|
const keys = Array.from(document.texts(), ([text]) => text.key)
|
||||||
const isAppending =
|
|
||||||
!startInline ||
|
|
||||||
(start.isAtStartOfNode(startText) || end.isAtStartOfNode(startText)) ||
|
|
||||||
(start.isAtEndOfNode(endText) || end.isAtEndOfNode(endText))
|
|
||||||
|
|
||||||
const isInserting =
|
|
||||||
firstChild.hasBlockChildren() || lastChild.hasBlockChildren()
|
|
||||||
|
|
||||||
editor.insertFragmentAtRange(selection, fragment)
|
editor.insertFragmentAtRange(selection, fragment)
|
||||||
value = editor.value
|
value = editor.value
|
||||||
document = value.document
|
document = value.document
|
||||||
|
|
||||||
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()
|
if (newTexts.size === 0) return
|
||||||
|
const fragmentLength = fragment.text.length
|
||||||
|
|
||||||
if (newText && (lastInline || isInserting)) {
|
// Either startText is still here, or we want the first un-previously known text
|
||||||
editor.moveToEndOfNode(newText)
|
const startText = document.getNode(start.key) || newTexts.first()
|
||||||
} else if (newText) {
|
// We want the last un-previously known text
|
||||||
// The position within the last text node needs to be calculated. This is the length
|
let endText = newTexts.last() || startText
|
||||||
// of all text nodes within the last block, but if the last block contains inline nodes,
|
|
||||||
// these have to be skipped.
|
if (startText === endText) {
|
||||||
const { nodes } = lastBlock
|
editor.moveTo(endText.key, fragmentLength)
|
||||||
const lastIndex = nodes.findLastIndex(
|
return
|
||||||
node => node && node.object === 'inline'
|
|
||||||
)
|
|
||||||
const remainingTexts = nodes.takeLast(nodes.size - lastIndex - 1)
|
|
||||||
const remainingTextLength = remainingTexts.reduce(
|
|
||||||
(acc, val) => acc + val.text.length,
|
|
||||||
0
|
|
||||||
)
|
|
||||||
editor.moveToStartOfNode(newText).moveForward(remainingTextLength)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Everything will be calculated relative to the first common ancestor to optimize speed
|
||||||
|
const parent = document.getCommonAncestor(startText.key, endText.key)
|
||||||
|
|
||||||
|
const startOffset =
|
||||||
|
parent.getOffset(startText.key) +
|
||||||
|
(start.key === startText.key ? start.offset : 0)
|
||||||
|
|
||||||
|
// endText might not be the last un-previously known text node, so we precisely pick it by offset
|
||||||
|
endText = parent.getTextAtOffset(startOffset + fragmentLength - 1) || endText
|
||||||
|
|
||||||
|
editor.moveTo(
|
||||||
|
endText.key,
|
||||||
|
startOffset + fragmentLength - parent.getOffset(endText.key)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -0,0 +1,41 @@
|
|||||||
|
/** @jsx h */
|
||||||
|
|
||||||
|
import h from '../../../helpers/h'
|
||||||
|
|
||||||
|
export default function(editor) {
|
||||||
|
editor.insertFragment(
|
||||||
|
<document>
|
||||||
|
<paragraph>
|
||||||
|
<b>b</b>
|
||||||
|
<u>u</u>
|
||||||
|
<i>i</i>
|
||||||
|
</paragraph>
|
||||||
|
</document>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const input = (
|
||||||
|
<value>
|
||||||
|
<document>
|
||||||
|
<paragraph>
|
||||||
|
wo<cursor />rd
|
||||||
|
</paragraph>
|
||||||
|
</document>
|
||||||
|
</value>
|
||||||
|
)
|
||||||
|
|
||||||
|
export const output = (
|
||||||
|
<value>
|
||||||
|
<document>
|
||||||
|
<paragraph>
|
||||||
|
wo
|
||||||
|
<b>b</b>
|
||||||
|
<u>u</u>
|
||||||
|
<i>
|
||||||
|
i<cursor />
|
||||||
|
</i>
|
||||||
|
rd
|
||||||
|
</paragraph>
|
||||||
|
</document>
|
||||||
|
</value>
|
||||||
|
)
|
@@ -29,11 +29,11 @@ export const output = (
|
|||||||
<paragraph>wo</paragraph>
|
<paragraph>wo</paragraph>
|
||||||
<quote>
|
<quote>
|
||||||
<quote>one</quote>
|
<quote>one</quote>
|
||||||
<quote>two</quote>
|
<quote>
|
||||||
|
two<cursor />
|
||||||
|
</quote>
|
||||||
</quote>
|
</quote>
|
||||||
<paragraph>
|
<paragraph>rd</paragraph>
|
||||||
rd<cursor />
|
|
||||||
</paragraph>
|
|
||||||
</document>
|
</document>
|
||||||
</value>
|
</value>
|
||||||
)
|
)
|
||||||
|
@@ -0,0 +1,41 @@
|
|||||||
|
/** @jsx h */
|
||||||
|
|
||||||
|
import h from '../../../helpers/h'
|
||||||
|
|
||||||
|
export default function(editor) {
|
||||||
|
editor.insertFragment(
|
||||||
|
<document>
|
||||||
|
<paragraph>
|
||||||
|
<inline type="link">bar</inline>
|
||||||
|
</paragraph>
|
||||||
|
</document>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const input = (
|
||||||
|
<value>
|
||||||
|
<document>
|
||||||
|
<code>
|
||||||
|
<paragraph>
|
||||||
|
Foo<cursor />baz
|
||||||
|
</paragraph>
|
||||||
|
</code>
|
||||||
|
</document>
|
||||||
|
</value>
|
||||||
|
)
|
||||||
|
|
||||||
|
export const output = (
|
||||||
|
<value>
|
||||||
|
<document>
|
||||||
|
<code>
|
||||||
|
<paragraph>
|
||||||
|
Foo
|
||||||
|
<inline type="link">
|
||||||
|
bar<cursor />
|
||||||
|
</inline>
|
||||||
|
baz
|
||||||
|
</paragraph>
|
||||||
|
</code>
|
||||||
|
</document>
|
||||||
|
</value>
|
||||||
|
)
|
@@ -0,0 +1,41 @@
|
|||||||
|
/** @jsx h */
|
||||||
|
|
||||||
|
import h from '../../../helpers/h'
|
||||||
|
|
||||||
|
export default function(editor) {
|
||||||
|
editor.insertFragment(
|
||||||
|
<document>
|
||||||
|
<paragraph>
|
||||||
|
<b>bar</b>
|
||||||
|
</paragraph>
|
||||||
|
</document>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const input = (
|
||||||
|
<value>
|
||||||
|
<document>
|
||||||
|
<code>
|
||||||
|
<paragraph>
|
||||||
|
Foo<cursor />baz
|
||||||
|
</paragraph>
|
||||||
|
</code>
|
||||||
|
</document>
|
||||||
|
</value>
|
||||||
|
)
|
||||||
|
|
||||||
|
export const output = (
|
||||||
|
<value>
|
||||||
|
<document>
|
||||||
|
<code>
|
||||||
|
<paragraph>
|
||||||
|
Foo
|
||||||
|
<b>
|
||||||
|
bar<cursor />
|
||||||
|
</b>
|
||||||
|
baz
|
||||||
|
</paragraph>
|
||||||
|
</code>
|
||||||
|
</document>
|
||||||
|
</value>
|
||||||
|
)
|
@@ -29,8 +29,9 @@ export const output = (
|
|||||||
<document>
|
<document>
|
||||||
<paragraph>
|
<paragraph>
|
||||||
<link>wo</link>
|
<link>wo</link>
|
||||||
<hashtag>fragment</hashtag>
|
<hashtag>
|
||||||
<cursor />
|
fragment<cursor />
|
||||||
|
</hashtag>
|
||||||
<link>rd</link>
|
<link>rd</link>
|
||||||
</paragraph>
|
</paragraph>
|
||||||
</document>
|
</document>
|
||||||
|
@@ -31,7 +31,7 @@ export const output = (
|
|||||||
<quote>
|
<quote>
|
||||||
<paragraph>woone</paragraph>
|
<paragraph>woone</paragraph>
|
||||||
<quote>
|
<quote>
|
||||||
tword<cursor />
|
two<cursor />rd
|
||||||
</quote>
|
</quote>
|
||||||
</quote>
|
</quote>
|
||||||
</document>
|
</document>
|
||||||
|
Reference in New Issue
Block a user