1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-30 02:19:52 +02:00

fix to nudge selection outside of inline nodes, closes #349

This commit is contained in:
Ian Storm Taylor
2016-12-01 15:51:25 -08:00
parent 6d93af8e66
commit 4c79d68cd2
2 changed files with 48 additions and 4 deletions

View File

@@ -623,6 +623,31 @@ class Content extends React.Component {
isBackward: null
}
// If the selection is at the end of a non-void inline node, and there is
// a node after it, put it in the node after instead.
const anchorText = document.getNode(anchor.key)
const focusText = document.getNode(focus.key)
const anchorInline = document.getClosestInline(anchor.key)
const focusInline = document.getClosestInline(focus.key)
if (anchorInline && anchor.offset == anchorText.length) {
const block = document.getClosestBlock(anchor.key)
const next = block.getNextText(anchor.key)
if (next) {
properties.anchorKey = next.key
properties.anchorOffset = 0
}
}
if (focusInline && focus.offset == focusText.length) {
const block = document.getClosestBlock(focus.key)
const next = block.getNextText(focus.key)
if (next) {
properties.focusKey = next.key
properties.focusOffset = 0
}
}
data.selection = selection
.merge(properties)
.normalize(document)

View File

@@ -71,7 +71,11 @@ function Plugin(options = {}) {
*/
function onBeforeInput(e, data, state, editor) {
const { document, startKey, startOffset, startInline, startText } = state
const { document, startKey, startBlock, startOffset, startInline, startText } = state
const pText = startBlock.getPreviousText(startKey)
const pInline = pText && startBlock.getClosestInline(pText.key)
const nText = startBlock.getNextText(startKey)
const nInline = nText && startBlock.getClosestInline(nText.key)
// Determine what the characters would be if natively inserted.
const schema = editor.getSchema()
@@ -103,15 +107,30 @@ function Plugin(options = {}) {
// We do not have to re-render if the current selection is collapsed, the
// current node is not empty, there are no marks on the cursor, the cursor
// is not at the edge of an inline node, and the natively inserted
// is not at the edge of an inline node, the cursor isn't at the starting
// edge of a text node after an inline node, and the natively inserted
// characters would be the same as the non-native.
const isNative = (
// If the selection is expanded, we don't know what the edit will look
// like so we can't let it happen natively.
(state.isCollapsed) &&
(state.startText.text != '') &&
// If the selection has marks, then we need to render it non-natively
// because we need to create the new marks as well.
(state.selection.marks == null) &&
// Must not be, for example, at edge of an inline link
// If the text node in question has no content, browsers might do weird
// things so we need to insert it normally instead.
(state.startText.text != '') &&
// COMPAT: Browsers do weird things when typing at the edges of inline
// nodes, so we can't let them render natively. (?)
(!startInline || !state.selection.isAtStartOf(startInline)) &&
(!startInline || !state.selection.isAtEndOf(startInline)) &&
// COMPAT: In Chrome & Safari, it isn't possible to have a selection at
// the starting edge of a text node after another inline node. It will
// have been automatically changed. So we can't render natively because
// the cursor isn't technique in the right spot. (2016/12/01)
(!(pInline && !pInline.isVoid && startOffset == 0)) &&
(!(nInline && !nInline.isVoid && startOffset == startText.length)) &&
// If the
(chars.equals(nextChars))
)