mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-19 05:31:56 +02:00
fix deleting sibling inline node
This commit is contained in:
@@ -58,6 +58,8 @@ class Links extends React.Component {
|
|||||||
|
|
||||||
onChange = (state) => {
|
onChange = (state) => {
|
||||||
this.setState({ state })
|
this.setState({ state })
|
||||||
|
console.log(state.selection.toJS())
|
||||||
|
console.log(state.document.toJS())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -909,6 +909,18 @@ const Node = {
|
|||||||
removals = removals.add(desc.key)
|
removals = removals.add(desc.key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return desc
|
||||||
|
})
|
||||||
|
|
||||||
|
// Remove any nodes marked for removal.
|
||||||
|
removals.forEach((key) => {
|
||||||
|
node = node.removeDescendant(key)
|
||||||
|
})
|
||||||
|
|
||||||
|
removals = removals.clear()
|
||||||
|
|
||||||
|
// And, ensuring...
|
||||||
|
node = node.mapDescendants((desc) => {
|
||||||
if (desc.kind == 'text') {
|
if (desc.kind == 'text') {
|
||||||
let next = node.getNextSibling(desc)
|
let next = node.getNextSibling(desc)
|
||||||
|
|
||||||
|
@@ -566,7 +566,10 @@ class State extends new Record(DEFAULTS) {
|
|||||||
// Determine what the selection will be after deleting.
|
// Determine what the selection will be after deleting.
|
||||||
const { startText } = this
|
const { startText } = this
|
||||||
const { startKey, startOffset, endKey, endOffset } = selection
|
const { startKey, startOffset, endKey, endOffset } = selection
|
||||||
const previous = document.getPreviousSibling(startText)
|
const block = document.getClosestBlock(startText)
|
||||||
|
const highest = block.getHighestChild(startText)
|
||||||
|
const previous = block.getPreviousSibling(highest)
|
||||||
|
const next = block.getNextSibling(highest)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
previous &&
|
previous &&
|
||||||
@@ -574,7 +577,16 @@ class State extends new Record(DEFAULTS) {
|
|||||||
(endKey != startKey || endOffset == startText.length)
|
(endKey != startKey || endOffset == startText.length)
|
||||||
) {
|
) {
|
||||||
if (previous.kind == 'text') {
|
if (previous.kind == 'text') {
|
||||||
after = selection.collapseToEndOf(previous)
|
if (next && next.kind == 'text') {
|
||||||
|
after = selection.merge({
|
||||||
|
anchorKey: previous.key,
|
||||||
|
anchorOffset: previous.length,
|
||||||
|
focusKey: previous.key,
|
||||||
|
focusOffset: previous.length
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
after = selection.collapseToEndOf(previous)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const last = previous.getTexts().last()
|
const last = previous.getTexts().last()
|
||||||
after = selection.collapseToEndOf(last)
|
after = selection.collapseToEndOf(last)
|
||||||
@@ -631,13 +643,27 @@ class State extends new Record(DEFAULTS) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (selection.isAtEndOf(startNode) && startNode.length == 1) {
|
else if (selection.isAtEndOf(startNode) && startNode.length == 1) {
|
||||||
const previous = document.getPreviousSibling(startNode)
|
const block = document.getClosestBlock(startKey)
|
||||||
|
const highest = block.getHighestChild(startKey)
|
||||||
|
const previous = block.getPreviousSibling(highest)
|
||||||
|
const next = block.getNextSibling(highest)
|
||||||
|
|
||||||
if (previous && previous.kind == 'text') {
|
if (previous) {
|
||||||
after = selection.collapseToEndOf(previous)
|
if (previous.kind == 'text') {
|
||||||
} else if (previous) {
|
if (next && next.kind == 'text') {
|
||||||
const last = previous.getTexts().last()
|
after = selection.merge({
|
||||||
after = selection.collapseToEndOf(last)
|
anchorKey: previous.key,
|
||||||
|
anchorOffset: previous.length,
|
||||||
|
focusKey: previous.key,
|
||||||
|
focusOffset: previous.length
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
after = selection.collapseToEndOf(previous)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const last = previous.getTexts().last()
|
||||||
|
after = selection.collapseToEndOf(last)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
after = selection.moveBackward(n)
|
after = selection.moveBackward(n)
|
||||||
}
|
}
|
||||||
@@ -663,31 +689,41 @@ class State extends new Record(DEFAULTS) {
|
|||||||
|
|
||||||
deleteForward(n = 1) {
|
deleteForward(n = 1) {
|
||||||
let state = this
|
let state = this
|
||||||
let { document, selection } = state
|
let { document, selection, startText } = state
|
||||||
let { startKey, startOffset } = selection
|
let { startKey, startOffset } = selection
|
||||||
let after = selection
|
let after = selection
|
||||||
|
|
||||||
// Determine what the selection should be after deleting.
|
// Determine what the selection should be after deleting.
|
||||||
const block = document.getClosestBlock(startKey)
|
const block = document.getClosestBlock(startKey)
|
||||||
const inline = document.getClosestInline(startKey)
|
const inline = document.getClosestInline(startKey)
|
||||||
const previous = document.getPreviousSibling(startKey)
|
const highest = block.getHighestChild(startKey)
|
||||||
const startText = document.getDescendant(startKey)
|
const previous = block.getPreviousSibling(highest)
|
||||||
|
const next = block.getNextSibling(highest)
|
||||||
|
|
||||||
if (selection.isExpanded) {
|
if (selection.isExpanded) {
|
||||||
after = selection.collapseToStart()
|
after = selection.collapseToStart()
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((block && block.isVoid) || (inline && inline.isVoid)) {
|
else if ((block && block.isVoid) || (inline && inline.isVoid)) {
|
||||||
const next = document.getNextText(startKey)
|
const nextText = document.getNextText(startKey)
|
||||||
const prev = document.getPreviousText(startKey)
|
const prevText = document.getPreviousText(startKey)
|
||||||
after = next
|
after = next
|
||||||
? selection.collapseToStartOf(next)
|
? selection.collapseToStartOf(nextText)
|
||||||
: selection.collapseToEndOf(prev)
|
: selection.collapseToEndOf(prevText)
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (previous && startOffset == 0 && startText.length == 1) {
|
else if (previous && startOffset == 0 && startText.length == 1) {
|
||||||
if (previous.kind == 'text') {
|
if (previous.kind == 'text') {
|
||||||
after = selection.collapseToEndOf(previous)
|
if (next && next.kind == 'text') {
|
||||||
|
after = selection.merge({
|
||||||
|
anchorKey: previous.key,
|
||||||
|
anchorOffset: previous.length,
|
||||||
|
focusKey: previous.key,
|
||||||
|
focusOffset: previous.length
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
after = selection.collapseToEndOf(previous)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const last = previous.getTexts().last()
|
const last = previous.getTexts().last()
|
||||||
after = selection.collapseToEndOf(last)
|
after = selection.collapseToEndOf(last)
|
||||||
|
@@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
export default function (state) {
|
||||||
|
const { document, selection } = state
|
||||||
|
const texts = document.getTexts()
|
||||||
|
const second = texts.get(1)
|
||||||
|
const range = selection.merge({
|
||||||
|
anchorKey: second.key,
|
||||||
|
anchorOffset: second.length - 1,
|
||||||
|
focusKey: second.key,
|
||||||
|
focusOffset: second.length
|
||||||
|
})
|
||||||
|
|
||||||
|
return state
|
||||||
|
.transform()
|
||||||
|
.deleteAtRange(range)
|
||||||
|
.apply()
|
||||||
|
}
|
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: one
|
||||||
|
- kind: inline
|
||||||
|
type: link
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: a
|
||||||
|
- kind: text
|
||||||
|
text: two
|
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: onetwo
|
@@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
export default function (state) {
|
||||||
|
const { document, selection } = state
|
||||||
|
const texts = document.getTexts()
|
||||||
|
const second = texts.get(1)
|
||||||
|
const range = selection.merge({
|
||||||
|
anchorKey: second.key,
|
||||||
|
anchorOffset: second.length,
|
||||||
|
focusKey: second.key,
|
||||||
|
focusOffset: second.length
|
||||||
|
})
|
||||||
|
|
||||||
|
return state
|
||||||
|
.transform()
|
||||||
|
.deleteBackwardAtRange(range)
|
||||||
|
.apply()
|
||||||
|
}
|
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: one
|
||||||
|
- kind: inline
|
||||||
|
type: link
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: a
|
||||||
|
- kind: text
|
||||||
|
text: two
|
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: onetwo
|
@@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
import assert from 'assert'
|
||||||
|
|
||||||
|
export default function (state) {
|
||||||
|
const { document, selection } = state
|
||||||
|
const texts = document.getTexts()
|
||||||
|
const first = texts.get(0)
|
||||||
|
const second = texts.get(1)
|
||||||
|
const range = selection.merge({
|
||||||
|
anchorKey: second.key,
|
||||||
|
anchorOffset: second.length,
|
||||||
|
focusKey: second.key,
|
||||||
|
focusOffset: second.length
|
||||||
|
})
|
||||||
|
|
||||||
|
const next = state
|
||||||
|
.transform()
|
||||||
|
.moveTo(range)
|
||||||
|
.deleteBackward()
|
||||||
|
.apply()
|
||||||
|
|
||||||
|
const updated = next.document.getTexts().first()
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
next.selection.toJS(),
|
||||||
|
range.collapseToStartOf(updated).moveForward(first.length).toJS()
|
||||||
|
)
|
||||||
|
|
||||||
|
return next
|
||||||
|
}
|
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: one
|
||||||
|
- kind: inline
|
||||||
|
type: link
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: a
|
||||||
|
- kind: text
|
||||||
|
text: two
|
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: onetwo
|
@@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
export default function (state) {
|
||||||
|
const { document, selection } = state
|
||||||
|
const texts = document.getTexts()
|
||||||
|
const second = texts.get(1)
|
||||||
|
const range = selection.merge({
|
||||||
|
anchorKey: second.key,
|
||||||
|
anchorOffset: 0,
|
||||||
|
focusKey: second.key,
|
||||||
|
focusOffset: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
return state
|
||||||
|
.transform()
|
||||||
|
.deleteForwardAtRange(range)
|
||||||
|
.apply()
|
||||||
|
}
|
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: one
|
||||||
|
- kind: inline
|
||||||
|
type: link
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: a
|
||||||
|
- kind: text
|
||||||
|
text: two
|
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: onetwo
|
@@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
import assert from 'assert'
|
||||||
|
|
||||||
|
export default function (state) {
|
||||||
|
const { document, selection } = state
|
||||||
|
const texts = document.getTexts()
|
||||||
|
const first = texts.get(0)
|
||||||
|
const second = texts.get(1)
|
||||||
|
const range = selection.merge({
|
||||||
|
anchorKey: second.key,
|
||||||
|
anchorOffset: 0,
|
||||||
|
focusKey: second.key,
|
||||||
|
focusOffset: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
const next = state
|
||||||
|
.transform()
|
||||||
|
.moveTo(range)
|
||||||
|
.deleteForward()
|
||||||
|
.apply()
|
||||||
|
|
||||||
|
const updated = next.document.getTexts().first()
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
next.selection.toJS(),
|
||||||
|
range.collapseToStartOf(updated).moveForward(first.length).toJS()
|
||||||
|
)
|
||||||
|
|
||||||
|
return next
|
||||||
|
}
|
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: one
|
||||||
|
- kind: inline
|
||||||
|
type: link
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: a
|
||||||
|
- kind: text
|
||||||
|
text: two
|
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: onetwo
|
@@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
import assert from 'assert'
|
||||||
|
|
||||||
|
export default function (state) {
|
||||||
|
const { document, selection } = state
|
||||||
|
const texts = document.getTexts()
|
||||||
|
const first = texts.get(0)
|
||||||
|
const second = texts.get(1)
|
||||||
|
const range = selection.merge({
|
||||||
|
anchorKey: second.key,
|
||||||
|
anchorOffset: second.length - 1,
|
||||||
|
focusKey: second.key,
|
||||||
|
focusOffset: second.length
|
||||||
|
})
|
||||||
|
|
||||||
|
const next = state
|
||||||
|
.transform()
|
||||||
|
.moveTo(range)
|
||||||
|
.delete()
|
||||||
|
.apply()
|
||||||
|
|
||||||
|
const updated = next.document.getTexts().first()
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
next.selection.toJS(),
|
||||||
|
range.merge({
|
||||||
|
anchorKey: updated.key,
|
||||||
|
anchorOffset: first.length,
|
||||||
|
focusKey: updated.key,
|
||||||
|
focusOffset: first.length
|
||||||
|
}).toJS()
|
||||||
|
)
|
||||||
|
|
||||||
|
return next
|
||||||
|
}
|
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: one
|
||||||
|
- kind: inline
|
||||||
|
type: link
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: a
|
||||||
|
- kind: text
|
||||||
|
text: two
|
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: paragraph
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: onetwo
|
Reference in New Issue
Block a user