1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-09-01 03:11:44 +02:00

add wrapTextAtRange tests, cleanup wrapText style and backwards handling

This commit is contained in:
Ian Storm Taylor
2016-08-09 09:32:46 -07:00
parent 17f703cecb
commit 90d4eced95
33 changed files with 395 additions and 27 deletions

View File

@@ -188,9 +188,9 @@ Wrap the [`Block`](./block.md) nodes in the current selection with a new [`Block
Wrap the [`Inline`](./inline.md) nodes in the current selection with a new [`Inline`](./inline.md) node of `type`, with optional `data`.
### `wrapText`
`wrapText(before: String, after: String) => Transform`
`wrapText(prefix: String, [suffix: String]) => Transform`
Surround the text in the current selection.
Surround the text in the current selection with `prefix` and `suffix` strings. If the `suffix` is ommitted, the `prefix` will be used instead.
## Selection Transforms
@@ -378,9 +378,9 @@ Wrap the [`Block`](./block.md) nodes in a `range` with a new [`Block`](./block.m
Wrap the [`Inline`](./inline.md) nodes in a `range` with a new [`Inline`](./inline.md) node with `properties`. For convenience, you can pass a `type` string or `properties` object.
### `wrapTextAtRange`
`wrapTextAtRange(range: Selection, prefix: String, suffix: String) => Transform`
`wrapTextAtRange(range: Selection, prefix: String, [suffix: String]) => Transform`
Surround the text in a `range`.
Surround the text in a `range` with `prefix` and `suffix` strings. If the `suffix` is ommitted, the `prefix` will be used instead.
## History Transforms

View File

@@ -1146,21 +1146,28 @@ class State extends new Record(DEFAULTS) {
*/
wrapText(prefix, suffix = prefix) {
let { document, selection } = this
let { startKey, endKey, startOffset, endOffset } = selection
let acrossBlocks = (startKey !== endKey)
let state = this
let { document, selection } = state
let { anchorOffset, anchorKey, focusOffset, focusKey, isBackward } = selection
let after
// Determine what the selection should be after wrapping.
if (anchorKey == focusKey) {
after = selection.moveForward(prefix.length)
}
else {
after = selection.merge({
anchorOffset: isBackward ? anchorOffset : anchorOffset + prefix.length,
focusOffset: isBackward ? focusOffset + prefix.length : focusOffset
})
}
// Wrap the text and update the state.
document = document.wrapTextAtRange(selection, prefix, suffix)
selection = selection
.merge({
anchorKey: startKey,
anchorOffset: startOffset + prefix.length,
focusKey: endKey,
focusOffset: acrossBlocks ? endOffset : endOffset + prefix.length
})
return this.merge({ document, selection })
selection = after
state = state.merge({ document, selection })
return state
}
/**

View File

@@ -1017,7 +1017,7 @@ const Transforms = {
})
return node.normalize()
},
},
/**
* Wrap the text in a `range` in a prefix/suffix.
@@ -1029,16 +1029,19 @@ const Transforms = {
*/
wrapTextAtRange(range, prefix, suffix = prefix) {
let withPrefix = this.insertTextAtRange(range.collapseToAnchor(), prefix)
let acrossBlocks = (range.startKey !== range.endKey)
let withSuffix = withPrefix.insertTextAtRange(
range
.collapseToFocus()
.moveForward(acrossBlocks ? 0 : prefix.length),
suffix
)
let node = this
return withSuffix
// Insert text at the starting edge.
const { startKey, endKey } = range
const start = range.collapseToStart()
node = node.insertTextAtRange(start, prefix)
// Determine the new ending edge, and insert text there.
let end = range.collapseToEnd()
if (startKey == endKey) end = end.moveForward(prefix.length)
node = node.insertTextAtRange(end, suffix)
return node
}
}

View File

@@ -0,0 +1,18 @@
export default function (state) {
const { document, selection } = state
const texts = document.getTexts()
const first = texts.first()
const last = texts.last()
const range = selection.merge({
anchorKey: first.key,
anchorOffset: 2,
focusKey: last.key,
focusOffset: 2
})
return state
.transform()
.wrapTextAtRange(range, '[[', ']]')
.apply()
}

View File

@@ -0,0 +1,12 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: word
- kind: block
type: paragraph
nodes:
- kind: text
text: another

View File

@@ -0,0 +1,12 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: wo[[rd
- kind: block
type: paragraph
nodes:
- kind: text
text: an]]other

View File

@@ -0,0 +1,18 @@
export default function (state) {
const { document, selection } = state
const texts = document.getTexts()
const first = texts.first()
const last = texts.last()
const range = selection.merge({
anchorKey: first.key,
anchorOffset: 2,
focusKey: last.key,
focusOffset: 2
})
return state
.transform()
.wrapTextAtRange(range, '[[', ']]')
.apply()
}

View File

@@ -0,0 +1,15 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: inline
type: link
nodes:
- kind: text
text: word
- kind: inline
type: link
nodes:
- kind: text
text: another

View File

@@ -0,0 +1,15 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: inline
type: link
nodes:
- kind: text
text: wo[[rd
- kind: inline
type: link
nodes:
- kind: text
text: an]]other

View File

@@ -0,0 +1,18 @@
export default function (state) {
const { document, selection } = state
const texts = document.getTexts()
const first = texts.first()
const range = selection.merge({
anchorKey: first.key,
anchorOffset: 3,
focusKey: first.key,
focusOffset: 1,
isBackward: true
})
return state
.transform()
.wrapTextAtRange(range, '[[', ']]')
.apply()
}

View File

@@ -0,0 +1,7 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: word

View File

@@ -0,0 +1,7 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: w[[or]]d

View File

@@ -0,0 +1,17 @@
export default function (state) {
const { document, selection } = state
const texts = document.getTexts()
const first = texts.first()
const range = selection.merge({
anchorKey: first.key,
anchorOffset: 0,
focusKey: first.key,
focusOffset: 0
})
return state
.transform()
.wrapTextAtRange(range, '[[', ']]')
.apply()
}

View File

@@ -0,0 +1,7 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: ""

View File

@@ -0,0 +1,7 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: "[[]]"

View File

@@ -0,0 +1,17 @@
export default function (state) {
const { document, selection } = state
const texts = document.getTexts()
const first = texts.first()
const range = selection.merge({
anchorKey: first.key,
anchorOffset: 2,
focusKey: first.key,
focusOffset: 4
})
return state
.transform()
.wrapTextAtRange(range, '[[', ']]')
.apply()
}

View File

@@ -0,0 +1,7 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: word

View File

@@ -0,0 +1,7 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: wo[[rd]]

View File

@@ -0,0 +1,17 @@
export default function (state) {
const { document, selection } = state
const texts = document.getTexts()
const first = texts.first()
const range = selection.merge({
anchorKey: first.key,
anchorOffset: 1,
focusKey: first.key,
focusOffset: 3
})
return state
.transform()
.wrapTextAtRange(range, '[[', ']]')
.apply()
}

View File

@@ -0,0 +1,7 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: word

View File

@@ -0,0 +1,7 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: w[[or]]d

View File

@@ -0,0 +1,17 @@
export default function (state) {
const { document, selection } = state
const texts = document.getTexts()
const first = texts.first()
const range = selection.merge({
anchorKey: first.key,
anchorOffset: 0,
focusKey: first.key,
focusOffset: 2
})
return state
.transform()
.wrapTextAtRange(range, '[[', ']]')
.apply()
}

View File

@@ -0,0 +1,7 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: word

View File

@@ -0,0 +1,7 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: "[[wo]]rd"

View File

@@ -0,0 +1,17 @@
export default function (state) {
const { document, selection } = state
const texts = document.getTexts()
const first = texts.first()
const range = selection.merge({
anchorKey: first.key,
anchorOffset: 0,
focusKey: first.key,
focusOffset: 4
})
return state
.transform()
.wrapTextAtRange(range, '[[', ']]')
.apply()
}

View File

@@ -0,0 +1,7 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: word

View File

@@ -0,0 +1,7 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: "[[word]]"

View File

@@ -0,0 +1,17 @@
export default function (state) {
const { document, selection } = state
const texts = document.getTexts()
const first = texts.first()
const range = selection.merge({
anchorKey: first.key,
anchorOffset: 1,
focusKey: first.key,
focusOffset: 3
})
return state
.transform()
.wrapTextAtRange(range, '**')
.apply()
}

View File

@@ -0,0 +1,7 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: word

View File

@@ -0,0 +1,7 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: w**or**d

View File

@@ -0,0 +1,36 @@
import assert from 'assert'
export default function (state) {
const { document, selection } = state
const texts = document.getTexts()
const first = texts.first()
const range = selection.merge({
anchorKey: first.key,
anchorOffset: 3,
focusKey: first.key,
focusOffset: 1,
isBackward: true
})
const next = state
.transform()
.moveTo(range)
.wrapText('[[', ']]')
.apply()
const updated = next.document.getTexts().get(0)
assert.deepEqual(
next.selection.toJS(),
range.merge({
anchorKey: updated.key,
anchorOffset: 5,
focusKey: updated.key,
focusOffset: 3
}).toJS()
)
return next
}

View File

@@ -0,0 +1,7 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: word

View File

@@ -0,0 +1,7 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: w[[or]]d