mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-02-24 09:13:24 +01:00
refactor for operations
This commit is contained in:
parent
9ae245ddab
commit
6af9466c60
@ -42,6 +42,20 @@ class Character extends CharacterRecord {
|
||||
return new List(array.map(Character.create))
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a characters list from a `string` and optional `marks`.
|
||||
*
|
||||
* @param {String} string
|
||||
* @param {Set} marks (optional)
|
||||
* @return {List}
|
||||
*/
|
||||
|
||||
static createListFromText(string, marks) {
|
||||
const chars = string.split('').map(text => { return { text, marks } })
|
||||
const list = Character.createList(chars)
|
||||
return list
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the kind.
|
||||
*
|
||||
|
@ -60,6 +60,23 @@ const Node = {
|
||||
return descendant
|
||||
},
|
||||
|
||||
/**
|
||||
* Assert that a node exists at `path` and return it.
|
||||
*
|
||||
* @param {Array} path
|
||||
* @return {Node}
|
||||
*/
|
||||
|
||||
assertPath(path) {
|
||||
const descendant = this.getDescendantAtPath(path)
|
||||
|
||||
if (!descendant) {
|
||||
throw new Error(`Could not find a descendant at path "${path}".`)
|
||||
}
|
||||
|
||||
return descendant
|
||||
},
|
||||
|
||||
/**
|
||||
* Concat children `nodes` on to the end of the node.
|
||||
*
|
||||
@ -405,6 +422,24 @@ const Node = {
|
||||
return child
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a descendant by `path`.
|
||||
*
|
||||
* @param {Array} path
|
||||
* @return {Node || Void}
|
||||
*/
|
||||
|
||||
getDescedantAtPath(path) {
|
||||
let descendant = this
|
||||
|
||||
for (const index of path) {
|
||||
if (!descendant.nodes) return
|
||||
descendant = descendant.nodes.get(index)
|
||||
}
|
||||
|
||||
return descendant
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the depth of a child node by `key`, with optional `startAt`.
|
||||
*
|
||||
@ -721,6 +756,27 @@ const Node = {
|
||||
return node
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the path of a descendant node by `key`.
|
||||
*
|
||||
* @param {String || Node} node
|
||||
* @return {Array}
|
||||
*/
|
||||
|
||||
getPath(key) {
|
||||
let child = this.assertDescendant(key)
|
||||
let path = []
|
||||
let parent
|
||||
|
||||
while (parent = this.getParent(child)) {
|
||||
const index = parent.nodes.indexOf(child)
|
||||
path.push(index)
|
||||
child = parent
|
||||
}
|
||||
|
||||
return path
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the node before a descendant node by `key`.
|
||||
*
|
||||
@ -911,6 +967,19 @@ const Node = {
|
||||
return this.merge({ nodes })
|
||||
},
|
||||
|
||||
/**
|
||||
* Insert a `node` at `index`.
|
||||
*
|
||||
* @param {Number} index
|
||||
* @param {Node} node
|
||||
* @return {Node}
|
||||
*/
|
||||
|
||||
insertNode(index, node) {
|
||||
const nodes = this.nodes.splice(index, 0, node)
|
||||
return this.merge({ nodes })
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the inline nodes are split at a `range`.
|
||||
*
|
||||
@ -1106,6 +1175,18 @@ const Node = {
|
||||
return node
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove a node at `index`.
|
||||
*
|
||||
* @param {Number} index
|
||||
* @return {Node}
|
||||
*/
|
||||
|
||||
removeNode(index) {
|
||||
const nodes = this.nodes.splice(index, 1)
|
||||
return this.merge({ nodes })
|
||||
},
|
||||
|
||||
/**
|
||||
* Set a new value for a child node by `key`.
|
||||
*
|
||||
|
@ -98,6 +98,28 @@ class Text extends new Record(DEFAULTS) {
|
||||
.join('')
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a `mark` at `index` and `length`.
|
||||
*
|
||||
* @param {Number} index
|
||||
* @param {Number} length
|
||||
* @param {Mark} mark
|
||||
* @return {Text}
|
||||
*/
|
||||
|
||||
addMark(index, length, mark) {
|
||||
const characters = this.characters.map((char, i) => {
|
||||
if (i < index) return char
|
||||
if (i > index + length) return char
|
||||
let { marks } = char
|
||||
marks = marks.add(mark)
|
||||
char = char.merge({ marks })
|
||||
return char
|
||||
})
|
||||
|
||||
return this.merge({ characters })
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive a set of decorated characters with `decorators`.
|
||||
*
|
||||
@ -129,6 +151,21 @@ class Text extends new Record(DEFAULTS) {
|
||||
return schema.__getDecorators(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the marks on the text at `index`.
|
||||
*
|
||||
* @param {Number} index
|
||||
* @return {Set}
|
||||
*/
|
||||
|
||||
getMarksAtIndex(index) {
|
||||
if (index == 0) return Mark.createSet()
|
||||
const { characters } = this
|
||||
const char = characters.get(index - 1)
|
||||
if (!char) return Mark.createSet()
|
||||
return char.marks
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive the ranges for a list of `characters`.
|
||||
*
|
||||
@ -181,50 +218,86 @@ class Text extends new Record(DEFAULTS) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove characters from the text node from `start` to `end`.
|
||||
* Insert `text` at `index`.
|
||||
*
|
||||
* @param {Number} start
|
||||
* @param {Number} end
|
||||
* @param {Numbder} index
|
||||
* @param {String} text
|
||||
* @param {String} marks (optional)
|
||||
* @return {Text} text
|
||||
*/
|
||||
|
||||
removeCharacters(start, end) {
|
||||
insertText(index, text, marks) {
|
||||
marks = marks || this.getMarksAtIndex(index)
|
||||
let { characters } = this
|
||||
const chars = Character.createListFromText(text, marks)
|
||||
|
||||
characters = characters.filterNot((char, i) => {
|
||||
return start <= i && i < end
|
||||
characters = characters.slice(0, index)
|
||||
.concat(chars)
|
||||
.concat(characters.slice(index))
|
||||
|
||||
return this.merge({ characters })
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a `mark` at `index` and `length`.
|
||||
*
|
||||
* @param {Number} index
|
||||
* @param {Number} length
|
||||
* @param {Mark} mark
|
||||
* @return {Text}
|
||||
*/
|
||||
|
||||
removeMark(index, length, mark) {
|
||||
const characters = this.characters.map((char, i) => {
|
||||
if (i < index) return char
|
||||
if (i > index + length) return char
|
||||
let { marks } = char
|
||||
marks = marks.remove(mark)
|
||||
char = char.merge({ marks })
|
||||
return char
|
||||
})
|
||||
|
||||
return this.merge({ characters })
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert text `string` at `index`.
|
||||
* Remove text from the text node at `index` for `length`.
|
||||
*
|
||||
* @param {Numbder} index
|
||||
* @param {String} string
|
||||
* @param {String} marks (optional)
|
||||
* @param {Number} index
|
||||
* @param {Number} length
|
||||
* @return {Text} text
|
||||
*/
|
||||
|
||||
insertText(index, string, marks) {
|
||||
removeText(index, length) {
|
||||
let { characters } = this
|
||||
|
||||
if (!marks) {
|
||||
const prev = index ? characters.get(index - 1) : null
|
||||
marks = prev ? prev.marks : Mark.createSet()
|
||||
let start = index
|
||||
let end = index + length
|
||||
characters = characters.filterNot((char, i) => start <= i && i < end)
|
||||
return this.merge({ characters })
|
||||
}
|
||||
|
||||
const chars = Character.createList(string.split('').map((char) => {
|
||||
return {
|
||||
text: char,
|
||||
marks
|
||||
}
|
||||
}))
|
||||
/**
|
||||
* Update a `mark` at `index` and `length` with `properties`.
|
||||
*
|
||||
* @param {Number} index
|
||||
* @param {Number} length
|
||||
* @param {Mark} mark
|
||||
* @param {Object} properties
|
||||
* @return {Text}
|
||||
*/
|
||||
|
||||
characters = characters.slice(0, index)
|
||||
.concat(chars)
|
||||
.concat(characters.slice(index))
|
||||
updateMark(index, length, mark, properties) {
|
||||
const characters = this.characters.map((char, i) => {
|
||||
if (i < index) return char
|
||||
if (i > index + length) return char
|
||||
let { marks } = char
|
||||
const j = marks.indexOf(mark)
|
||||
let m = marks.get(j)
|
||||
m = m.merge(properties)
|
||||
marks = marks.set(j, m)
|
||||
char = char.merge({ marks })
|
||||
return char
|
||||
})
|
||||
|
||||
return this.merge({ characters })
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ export function deleteAtRange(transform, range) {
|
||||
// If the start and end nodes are the same, just remove characters.
|
||||
if (startKey == endKey) {
|
||||
let text = document.getDescendant(startKey)
|
||||
text = text.removeCharacters(startOffset, endOffset)
|
||||
text = text.removeText(startOffset, endOffset - startOffset)
|
||||
document = document.updateDescendant(text)
|
||||
document = document.normalize()
|
||||
state = state.merge({ document })
|
||||
|
Loading…
x
Reference in New Issue
Block a user