1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-22 15:02:51 +02:00

fix mark operation range creation

This commit is contained in:
Ian Storm Taylor
2017-09-05 18:24:21 -07:00
parent 6f3f8ee685
commit 367a22c39a
22 changed files with 157 additions and 32 deletions

View File

@@ -28,15 +28,41 @@ Changes.addMarkByKey = (change, key, offset, length, mark, options = {}) => {
const { state } = change
const { document } = state
const path = document.getPath(key)
const node = document.getNode(key)
const ranges = node.getRanges()
change.applyOperation({
type: 'add_mark',
path,
offset,
length,
mark,
const operations = []
const bx = offset
const by = offset + length
let o = 0
ranges.forEach((range) => {
const ax = o
const ay = ax + range.text.length
o += range.text.length
// If the range doesn't overlap with the operation, continue on.
if (ay < bx || by < ax) return
// If the range already has the mark, continue on.
if (range.marks.has(mark)) return
// Otherwise, determine which offset and characters overlap.
const start = Math.max(ax, bx)
const end = Math.min(ay, by)
operations.push({
type: 'add_mark',
path,
offset: start,
length: end - start,
mark,
})
})
change.applyOperations(operations)
if (normalize) {
const parent = document.getParent(key)
change.normalizeNodeByKey(parent.key, SCHEMA)
@@ -211,15 +237,41 @@ Changes.removeMarkByKey = (change, key, offset, length, mark, options = {}) => {
const { state } = change
const { document } = state
const path = document.getPath(key)
const node = document.getNode(key)
const ranges = node.getRanges()
change.applyOperation({
type: 'remove_mark',
path,
offset,
length,
mark,
const operations = []
const bx = offset
const by = offset + length
let o = 0
ranges.forEach((range) => {
const ax = o
const ay = ax + range.text.length
o += range.text.length
// If the range doesn't overlap with the operation, continue on.
if (ay < bx || by < ax) return
// If the range already has the mark, continue on.
if (!range.marks.has(mark)) return
// Otherwise, determine which offset and characters overlap.
const start = Math.max(ax, bx)
const end = Math.min(ay, by)
operations.push({
type: 'remove_mark',
path,
offset: start,
length: end - start,
mark,
})
})
change.applyOperations(operations)
if (normalize) {
const parent = document.getParent(key)
change.normalizeNodeByKey(parent.key, SCHEMA)
@@ -280,7 +332,6 @@ Changes.removeTextByKey = (change, key, offset, length, options = {}) => {
let o = 0
ranges.forEach((range) => {
const { marks } = range
const ax = o
const ay = ax + range.text.length
@@ -299,15 +350,12 @@ Changes.removeTextByKey = (change, key, offset, length, options = {}) => {
path,
offset: start,
text: string,
marks,
marks: range.marks,
})
})
// Apply the removals in reverse order, so that subsequent removals aren't
// impacted by previous ones.
removals.reverse().forEach((op) => {
change.applyOperation(op)
})
// Apply in reverse order, so subsequent removals don't impact previous ones.
change.applyOperations(removals.reverse())
if (normalize) {
const block = document.getClosestBlock(key)

View File

@@ -13,11 +13,11 @@ export default function (state) {
})
const next = state
.transform()
.change()
.select(range)
.toggleMark('bold')
.insertText('a')
.apply()
.state
assert.deepEqual(next.selection.toJS(), range.move(1).toJS())

View File

@@ -13,10 +13,10 @@ export default function (state) {
})
const next = state
.transform()
.change()
.select(range)
.toggleMark('bold')
.apply()
.state
assert.deepEqual(next.selection.toJS(), range.toJS())

View File

@@ -12,10 +12,10 @@ export default function (state) {
})
const next = state
.transform()
.change()
.select(range)
.toggleMark('bold')
.apply()
.state
assert.deepEqual(next.selection.toJS(), range.toJS())

View File

@@ -13,12 +13,12 @@ export default function (state) {
})
const next = state
.transform()
.change()
.select(range)
.toggleMark('bold')
.toggleMark('bold')
.insertText('a')
.apply()
.state
assert.deepEqual(next.selection.toJS(), range.move(1).toJS())

View File

@@ -0,0 +1,18 @@
import assert from 'assert'
export default function (state) {
const { selection } = state
const next = state
.change()
.removeMarkByKey('a', 0, 4, 'bold')
.state
.change()
.undo()
.state
assert.deepEqual(next.selection.toJS(), selection.toJS())
return next
}

View File

@@ -0,0 +1,8 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
key: a
text: text

View File

@@ -0,0 +1,8 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
key: a
text: text

View File

@@ -6,7 +6,7 @@ export default function (state) {
const next = state
.change()
.addMarkByKey('key1', 0, 8, 'marktype')
.addMarkByKey('a', 0, 8, 'marktype')
.state
.change()

View File

@@ -4,5 +4,10 @@ nodes:
type: paragraph
nodes:
- kind: text
key: 'key1'
text: The text
key: a
ranges:
- text: te
marks: []
- text: xt
marks:
- type: bold

View File

@@ -4,5 +4,9 @@ nodes:
type: paragraph
nodes:
- kind: text
key: 'key1'
text: The text
key: a
ranges:
- text: te
- text: xt
marks:
- type: bold

View File

@@ -0,0 +1,18 @@
import assert from 'assert'
export default function (state) {
const { selection } = state
const next = state
.change()
.addMarkByKey('a', 0, 4, 'bold')
.state
.change()
.undo()
.state
assert.deepEqual(next.selection.toJS(), selection.toJS())
return next
}

View File

@@ -0,0 +1,8 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
key: a
text: text

View File

@@ -0,0 +1,8 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
key: a
text: text