diff --git a/docs/reference/slate/change.md b/docs/reference/slate/change.md index f9e91d6ec..e82e0d7bf 100644 --- a/docs/reference/slate/change.md +++ b/docs/reference/slate/change.md @@ -192,6 +192,14 @@ Split the [`Inline`](./inline.md) node in the current selection by `depth` level Remove a [`mark`](./mark.md) from the characters in the current selection. For convenience, you can pass a `type` string or `properties` object to implicitly create a [`Mark`](./mark.md) of that type. +### `replaceMark` + +`replaceMark(oldMark: Mark, newMark: Mark) => Change`
+`replaceMark(oldProperties: Object, newProperties: Object) => Change`
+`replaceMark(oldType: String, newType: String) => Change` + +Replace a [`mark`](./mark.md) in the characters in the current selection. For convenience, you can pass a `type` string or `properties` object to implicitly create a [`Mark`](./mark.md) of that type. + ### `toggleMark` `toggleMark(mark: Mark) => Change`
diff --git a/packages/slate/src/changes/at-current-range.js b/packages/slate/src/changes/at-current-range.js index bee3fc7f8..f898a46a3 100644 --- a/packages/slate/src/changes/at-current-range.js +++ b/packages/slate/src/changes/at-current-range.js @@ -264,6 +264,19 @@ Changes.removeMark = (change, mark) => { } } +/** + * Replace an `oldMark` with a `newMark` in the characters in the current selection. + * + * @param {Change} change + * @param {Mark} oldMark + * @param {Mark} newMark + */ + +Changes.replaceMark = (change, oldMark, newMark) => { + change.removeMark(oldMark) + change.addMark(newMark) +} + /** * Add or remove a `mark` from the characters in the current selection, * depending on whether it's already there. diff --git a/packages/slate/test/changes/at-current-range/replace-mark/across-blocks.js b/packages/slate/test/changes/at-current-range/replace-mark/across-blocks.js new file mode 100644 index 000000000..3252075c4 --- /dev/null +++ b/packages/slate/test/changes/at-current-range/replace-mark/across-blocks.js @@ -0,0 +1,37 @@ +/** @jsx h */ + +import h from '../../../helpers/h' + +export default function(change) { + change.replaceMark('italic', 'bold') +} + +export const input = ( + + + + wo + rd + + + an + other + + + +) + +export const output = ( + + + + wo + rd + + + an + other + + + +) diff --git a/packages/slate/test/changes/at-current-range/replace-mark/across-inlines.js b/packages/slate/test/changes/at-current-range/replace-mark/across-inlines.js new file mode 100644 index 000000000..8ea3f0dd7 --- /dev/null +++ b/packages/slate/test/changes/at-current-range/replace-mark/across-inlines.js @@ -0,0 +1,49 @@ +/** @jsx h */ + +import h from '../../../helpers/h' + +export default function(change) { + change.replaceMark('italic', 'bold') +} + +export const input = ( + + + + + wo + rd + + + + + + + an + other + + + + +) + +export const output = ( + + + + + wo + rd + + + + + + + an + other + + + + +) diff --git a/packages/slate/test/changes/at-current-range/replace-mark/collapsed-selection.js b/packages/slate/test/changes/at-current-range/replace-mark/collapsed-selection.js new file mode 100644 index 000000000..e34a739aa --- /dev/null +++ b/packages/slate/test/changes/at-current-range/replace-mark/collapsed-selection.js @@ -0,0 +1,29 @@ +/** @jsx h */ + +import h from '../../../helpers/h' + +export default function(change) { + change.replaceMark('italic', 'bold').insertText('a') +} + +export const input = ( + + + + + word + + + +) + +export const output = ( + + + + a + word + + + +) diff --git a/packages/slate/test/changes/at-current-range/replace-mark/existing-marks.js b/packages/slate/test/changes/at-current-range/replace-mark/existing-marks.js new file mode 100644 index 000000000..867641f3e --- /dev/null +++ b/packages/slate/test/changes/at-current-range/replace-mark/existing-marks.js @@ -0,0 +1,33 @@ +/** @jsx h */ + +import h from '../../../helpers/h' + +export default function(change) { + change.replaceMark('italic', 'bold') +} + +export const input = ( + + + + + + word + + + + +) + +export const output = ( + + + + + wo + + rd + + + +) diff --git a/packages/slate/test/changes/at-current-range/replace-mark/first-character.js b/packages/slate/test/changes/at-current-range/replace-mark/first-character.js new file mode 100644 index 000000000..c005a36fd --- /dev/null +++ b/packages/slate/test/changes/at-current-range/replace-mark/first-character.js @@ -0,0 +1,31 @@ +/** @jsx h */ + +import h from '../../../helpers/h' + +export default function(change) { + change.replaceMark('italic', 'bold') +} + +export const input = ( + + + + + w + ord + + + +) + +export const output = ( + + + + + w + ord + + + +) diff --git a/packages/slate/test/changes/at-current-range/replace-mark/last-character.js b/packages/slate/test/changes/at-current-range/replace-mark/last-character.js new file mode 100644 index 000000000..884f0f3bf --- /dev/null +++ b/packages/slate/test/changes/at-current-range/replace-mark/last-character.js @@ -0,0 +1,31 @@ +/** @jsx h */ + +import h from '../../../helpers/h' + +export default function(change) { + change.replaceMark('italic', 'bold') +} + +export const input = ( + + + + wor + d + + + + +) + +export const output = ( + + + + wor + d + + + + +) diff --git a/packages/slate/test/changes/at-current-range/replace-mark/middle-character.js b/packages/slate/test/changes/at-current-range/replace-mark/middle-character.js new file mode 100644 index 000000000..eb191a9c4 --- /dev/null +++ b/packages/slate/test/changes/at-current-range/replace-mark/middle-character.js @@ -0,0 +1,31 @@ +/** @jsx h */ + +import h from '../../../helpers/h' + +export default function(change) { + change.replaceMark('italic', 'bold') +} + +export const input = ( + + + + w + o + rd + + + +) + +export const output = ( + + + + w + o + rd + + + +) diff --git a/packages/slate/test/changes/at-current-range/replace-mark/whole-word.js b/packages/slate/test/changes/at-current-range/replace-mark/whole-word.js new file mode 100644 index 000000000..41bbda069 --- /dev/null +++ b/packages/slate/test/changes/at-current-range/replace-mark/whole-word.js @@ -0,0 +1,31 @@ +/** @jsx h */ + +import h from '../../../helpers/h' + +export default function(change) { + change.replaceMark('italic', 'bold') +} + +export const input = ( + + + + + word + + + + +) + +export const output = ( + + + + + word + + + + +) diff --git a/packages/slate/test/changes/at-current-range/replace-mark/with-mark-object.js b/packages/slate/test/changes/at-current-range/replace-mark/with-mark-object.js new file mode 100644 index 000000000..7a528c18f --- /dev/null +++ b/packages/slate/test/changes/at-current-range/replace-mark/with-mark-object.js @@ -0,0 +1,39 @@ +/** @jsx h */ + +import h from '../../../helpers/h' + +import { Mark } from '../../../..' + +export default function(change) { + change.replaceMark( + 'italic', + Mark.create({ + type: 'bold', + data: { thing: 'value' }, + }) + ) +} + +export const input = ( + + + + + w + ord + + + +) + +export const output = ( + + + + + w + ord + + + +) diff --git a/packages/slate/test/changes/at-current-range/replace-mark/with-plain-object.js b/packages/slate/test/changes/at-current-range/replace-mark/with-plain-object.js new file mode 100644 index 000000000..65d5d4910 --- /dev/null +++ b/packages/slate/test/changes/at-current-range/replace-mark/with-plain-object.js @@ -0,0 +1,34 @@ +/** @jsx h */ + +import h from '../../../helpers/h' + +export default function(change) { + change.replaceMark('italic', { + type: 'bold', + data: { thing: 'value' }, + }) +} + +export const input = ( + + + + + w + ord + + + +) + +export const output = ( + + + + + w + ord + + + +)