mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-21 06:31:28 +02:00
refactor for operations
This commit is contained in:
@@ -42,6 +42,20 @@ class Character extends CharacterRecord {
|
|||||||
return new List(array.map(Character.create))
|
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.
|
* Get the kind.
|
||||||
*
|
*
|
||||||
|
@@ -60,6 +60,23 @@ const Node = {
|
|||||||
return descendant
|
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.
|
* Concat children `nodes` on to the end of the node.
|
||||||
*
|
*
|
||||||
@@ -405,6 +422,24 @@ const Node = {
|
|||||||
return child
|
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`.
|
* Get the depth of a child node by `key`, with optional `startAt`.
|
||||||
*
|
*
|
||||||
@@ -721,6 +756,27 @@ const Node = {
|
|||||||
return 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`.
|
* Get the node before a descendant node by `key`.
|
||||||
*
|
*
|
||||||
@@ -911,6 +967,19 @@ const Node = {
|
|||||||
return this.merge({ nodes })
|
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`.
|
* Check if the inline nodes are split at a `range`.
|
||||||
*
|
*
|
||||||
@@ -1106,6 +1175,18 @@ const Node = {
|
|||||||
return 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`.
|
* Set a new value for a child node by `key`.
|
||||||
*
|
*
|
||||||
|
@@ -98,6 +98,28 @@ class Text extends new Record(DEFAULTS) {
|
|||||||
.join('')
|
.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`.
|
* Derive a set of decorated characters with `decorators`.
|
||||||
*
|
*
|
||||||
@@ -129,6 +151,21 @@ class Text extends new Record(DEFAULTS) {
|
|||||||
return schema.__getDecorators(this)
|
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`.
|
* 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 {Numbder} index
|
||||||
* @param {Number} end
|
* @param {String} text
|
||||||
|
* @param {String} marks (optional)
|
||||||
* @return {Text} text
|
* @return {Text} text
|
||||||
*/
|
*/
|
||||||
|
|
||||||
removeCharacters(start, end) {
|
insertText(index, text, marks) {
|
||||||
|
marks = marks || this.getMarksAtIndex(index)
|
||||||
let { characters } = this
|
let { characters } = this
|
||||||
|
const chars = Character.createListFromText(text, marks)
|
||||||
|
|
||||||
characters = characters.filterNot((char, i) => {
|
characters = characters.slice(0, index)
|
||||||
return start <= i && i < end
|
.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 })
|
return this.merge({ characters })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert text `string` at `index`.
|
* Remove text from the text node at `index` for `length`.
|
||||||
*
|
*
|
||||||
* @param {Numbder} index
|
* @param {Number} index
|
||||||
* @param {String} string
|
* @param {Number} length
|
||||||
* @param {String} marks (optional)
|
|
||||||
* @return {Text} text
|
* @return {Text} text
|
||||||
*/
|
*/
|
||||||
|
|
||||||
insertText(index, string, marks) {
|
removeText(index, length) {
|
||||||
let { characters } = this
|
let { characters } = this
|
||||||
|
let start = index
|
||||||
|
let end = index + length
|
||||||
|
characters = characters.filterNot((char, i) => start <= i && i < end)
|
||||||
|
return this.merge({ characters })
|
||||||
|
}
|
||||||
|
|
||||||
if (!marks) {
|
/**
|
||||||
const prev = index ? characters.get(index - 1) : null
|
* Update a `mark` at `index` and `length` with `properties`.
|
||||||
marks = prev ? prev.marks : Mark.createSet()
|
*
|
||||||
}
|
* @param {Number} index
|
||||||
|
* @param {Number} length
|
||||||
|
* @param {Mark} mark
|
||||||
|
* @param {Object} properties
|
||||||
|
* @return {Text}
|
||||||
|
*/
|
||||||
|
|
||||||
const chars = Character.createList(string.split('').map((char) => {
|
updateMark(index, length, mark, properties) {
|
||||||
return {
|
const characters = this.characters.map((char, i) => {
|
||||||
text: char,
|
if (i < index) return char
|
||||||
marks
|
if (i > index + length) return char
|
||||||
}
|
let { marks } = char
|
||||||
}))
|
const j = marks.indexOf(mark)
|
||||||
|
let m = marks.get(j)
|
||||||
characters = characters.slice(0, index)
|
m = m.merge(properties)
|
||||||
.concat(chars)
|
marks = marks.set(j, m)
|
||||||
.concat(characters.slice(index))
|
char = char.merge({ marks })
|
||||||
|
return char
|
||||||
|
})
|
||||||
|
|
||||||
return this.merge({ characters })
|
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 the start and end nodes are the same, just remove characters.
|
||||||
if (startKey == endKey) {
|
if (startKey == endKey) {
|
||||||
let text = document.getDescendant(startKey)
|
let text = document.getDescendant(startKey)
|
||||||
text = text.removeCharacters(startOffset, endOffset)
|
text = text.removeText(startOffset, endOffset - startOffset)
|
||||||
document = document.updateDescendant(text)
|
document = document.updateDescendant(text)
|
||||||
document = document.normalize()
|
document = document.normalize()
|
||||||
state = state.merge({ document })
|
state = state.merge({ document })
|
||||||
|
Reference in New Issue
Block a user