mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-03-07 14:30:04 +01:00
Fix selection replacement and marks (#1473)
* Fix selection replacement and marks * Create `getInsertMarks` method for text insertion
This commit is contained in:
parent
7d5a33025b
commit
4e8dd7405a
packages
@ -492,7 +492,7 @@ function AfterPlugin() {
|
||||
if (startBlock.isVoid) return
|
||||
|
||||
const defaultBlock = startBlock
|
||||
const defaultMarks = document.getMarksAtRange(selection.collapseToStart())
|
||||
const defaultMarks = document.getInsertMarksAtRange(selection)
|
||||
const frag = Plain.deserialize(text, { defaultBlock, defaultMarks }).document
|
||||
change.insertFragment(frag)
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ Changes.insertInline = (change, inline) => {
|
||||
Changes.insertText = (change, text, marks) => {
|
||||
const { value } = change
|
||||
const { document, selection } = value
|
||||
marks = marks || value.marks
|
||||
marks = marks || selection.marks || document.getInsertMarksAtRange(selection)
|
||||
change.insertTextAtRange(selection, text, marks)
|
||||
|
||||
// If the text was successfully inserted, and the selection had marks on it,
|
||||
|
@ -881,8 +881,10 @@ Changes.insertTextAtRange = (change, range, text, marks, options = {}) => {
|
||||
change.deleteAtRange(range, { normalize: false })
|
||||
|
||||
// Update range start after delete
|
||||
key = change.value.startKey
|
||||
offset = change.value.startOffset
|
||||
if (change.value.startKey !== key) {
|
||||
key = change.value.startKey
|
||||
offset = change.value.startOffset
|
||||
}
|
||||
}
|
||||
|
||||
// PERF: Unless specified, don't normalize if only inserting text.
|
||||
|
@ -1018,6 +1018,18 @@ class Node {
|
||||
return new Set(array)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a set of the marks in a `range`.
|
||||
*
|
||||
* @param {Range} range
|
||||
* @return {Set<Mark>}
|
||||
*/
|
||||
|
||||
getInsertMarksAtRange(range) {
|
||||
const array = this.getInsertMarksAtRangeAsArray(range)
|
||||
return new Set(array)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a set of the marks in a `range`.
|
||||
*
|
||||
@ -1052,25 +1064,8 @@ class Node {
|
||||
getMarksAtRangeAsArray(range) {
|
||||
range = range.normalize(this)
|
||||
if (range.isUnset) return []
|
||||
if (range.isCollapsed) return this.getMarksAtCollaspsedRangeAsArray(range)
|
||||
|
||||
const { startKey, startOffset } = range
|
||||
|
||||
// If the range is collapsed at the start of the node, check the previous.
|
||||
if (range.isCollapsed && startOffset == 0) {
|
||||
const previous = this.getPreviousText(startKey)
|
||||
if (!previous || previous.text.length == 0) return []
|
||||
const char = previous.characters.get(previous.text.length - 1)
|
||||
return char.marks.toArray()
|
||||
}
|
||||
|
||||
// If the range is collapsed, check the character before the start.
|
||||
if (range.isCollapsed) {
|
||||
const text = this.getDescendant(startKey)
|
||||
const char = text.characters.get(range.startOffset - 1)
|
||||
return char.marks.toArray()
|
||||
}
|
||||
|
||||
// Otherwise, get a set of the marks for each character in the range.
|
||||
return this
|
||||
.getCharactersAtRange(range)
|
||||
.reduce((memo, char) => {
|
||||
@ -1079,6 +1074,47 @@ class Node {
|
||||
}, [])
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a set of the marks in a `range` for insertion behavior.
|
||||
*
|
||||
* @param {Range} range
|
||||
* @return {Array}
|
||||
*/
|
||||
|
||||
getInsertMarksAtRangeAsArray(range) {
|
||||
range = range.normalize(this)
|
||||
if (range.isUnset) return []
|
||||
if (range.isCollapsed) return this.getMarksAtCollaspsedRangeAsArray(range)
|
||||
|
||||
const text = this.getDescendant(range.startKey)
|
||||
const char = text.characters.get(range.startOffset)
|
||||
return char.marks.toArray()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a set of marks in a `range`, by treating it as collapsed.
|
||||
*
|
||||
* @param {Range} range
|
||||
* @return {Array}
|
||||
*/
|
||||
|
||||
getMarksAtCollaspsedRangeAsArray(range) {
|
||||
if (range.isUnset) return []
|
||||
|
||||
const { startKey, startOffset } = range
|
||||
|
||||
if (startOffset == 0) {
|
||||
const previous = this.getPreviousText(startKey)
|
||||
if (!previous || previous.text.length == 0) return []
|
||||
const char = previous.characters.get(previous.text.length - 1)
|
||||
return char.marks.toArray()
|
||||
}
|
||||
|
||||
const text = this.getDescendant(startKey)
|
||||
const char = text.characters.get(startOffset - 1)
|
||||
return char.marks.toArray()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a set of marks in a `range`, by intersecting.
|
||||
*
|
||||
@ -1089,23 +1125,7 @@ class Node {
|
||||
getActiveMarksAtRangeAsArray(range) {
|
||||
range = range.normalize(this)
|
||||
if (range.isUnset) return []
|
||||
|
||||
const { startKey, startOffset } = range
|
||||
|
||||
// If the range is collapsed at the start of the node, check the previous.
|
||||
if (range.isCollapsed && startOffset == 0) {
|
||||
const previous = this.getPreviousText(startKey)
|
||||
if (!previous || previous.text.length == 0) return []
|
||||
const char = previous.characters.get(previous.text.length - 1)
|
||||
return char.marks.toArray()
|
||||
}
|
||||
|
||||
// If the range is collapsed, check the character before the start.
|
||||
if (range.isCollapsed) {
|
||||
const text = this.getDescendant(startKey)
|
||||
const char = text.characters.get(range.startOffset - 1)
|
||||
return char.marks.toArray()
|
||||
}
|
||||
if (range.isCollapsed) return this.getMarksAtCollaspsedRangeAsArray(range)
|
||||
|
||||
// Otherwise, get a set of the marks for each character in the range.
|
||||
const chars = this.getCharactersAtRange(range)
|
||||
@ -1981,8 +2001,10 @@ memoize(Node.prototype, [
|
||||
'getInlinesByType',
|
||||
'getInlinesByTypeAsArray',
|
||||
'getMarksAtRange',
|
||||
'getInsertMarksAtRange',
|
||||
'getOrderedMarksAtRange',
|
||||
'getMarksAtRangeAsArray',
|
||||
'getInsertMarksAtRangeAsArray',
|
||||
'getMarksByType',
|
||||
'getOrderedMarksByType',
|
||||
'getMarksByTypeAsArray',
|
||||
|
Loading…
x
Reference in New Issue
Block a user