Skip to content

Commit

Permalink
insertTextByPath should replace marks on the inserted text with the o…
Browse files Browse the repository at this point in the history
…nce that are provided (ianstormtaylor#2936)

It were trying to add those marks that are passed to the function to the existing once,
but it should replace them instead.

Example error behavior was:
* put cursor at the end of the marked text
* toggle marks
* enter text

expected:
text is being added without toggled marks

actual:
text is added with those marks applied
  • Loading branch information
sgurenkov authored and ianstormtaylor committed Aug 19, 2019
1 parent 9d9d606 commit 65796c8
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 11 deletions.
62 changes: 59 additions & 3 deletions packages/slate/src/commands/by-path.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,62 @@ Commands.addMarksByPath = (editor, path, offset, length, marks) => {
})
}

/**
* Sets specific set of marks on the path
* @param {Editor} editor
* @param {Array} path
* @param {Number} offset
* @param {Number} length
* @param {Array<Object|Mark>} marks
*/

Commands.replaceMarksByPath = (editor, path, offset, length, marks) => {
const marksSet = Mark.createSet(marks)

const { value } = editor
const { document } = value
const node = document.assertNode(path)

if (node.marks.equals(marksSet)) {
return
}

editor.withoutNormalizing(() => {
// If it ends before the end of the node, we'll need to split to create a new
// text with different marks.
if (offset + length < node.text.length) {
editor.splitNodeByPath(path, offset + length)
}

// Same thing if it starts after the start. But in that case, we need to
// update our path and offset to point to the new start.
if (offset > 0) {
editor.splitNodeByPath(path, offset)
path = PathUtils.increment(path)
offset = 0
}

const marksToApply = marksSet.subtract(node.marks)
const marksToRemove = node.marks.subtract(marksSet)

marksToRemove.forEach(mark => {
editor.applyOperation({
type: 'remove_mark',
path,
mark: Mark.create(mark),
})
})

marksToApply.forEach(mark => {
editor.applyOperation({
type: 'add_mark',
path,
mark: Mark.create(mark),
})
})
})
}

/**
* Insert a `fragment` at `index` in a node by `path`.
*
Expand Down Expand Up @@ -107,7 +163,6 @@ Commands.insertNodeByPath = (editor, path, index, node) => {
*/

Commands.insertTextByPath = (editor, path, offset, text, marks) => {
marks = Mark.createSet(marks)
const { value } = editor
const { annotations, document } = value
document.assertNode(path)
Expand Down Expand Up @@ -140,8 +195,8 @@ Commands.insertTextByPath = (editor, path, offset, text, marks) => {
text,
})

if (marks.size) {
editor.addMarksByPath(path, offset, text.length, marks)
if (marks) {
editor.replaceMarksByPath(path, offset, text.length, marks)
}
})
}
Expand Down Expand Up @@ -726,6 +781,7 @@ const COMMANDS = [
'removeMark',
'removeNode',
'removeText',
'replaceMarks',
'replaceNode',
'replaceText',
'setMark',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/** @jsx h */

import h from '../../../helpers/h'

export default function(editor) {
editor.replaceMarksByKey('a', 0, 2, [{ type: 'italic' }])
}

export const input = (
<value>
<document>
<paragraph>
<b key="a" thing="value">
word
</b>
</paragraph>
</document>
</value>
)

export const output = (
<value>
<document>
<paragraph>
<i>wo</i>
<b thing="value">rd</b>
</paragraph>
</document>
</value>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/** @jsx h */

import h from '../../../helpers/h'

export default function(editor) {
editor.replaceMarksByKey('a', 0, 2, [])
}

export const input = (
<value>
<document>
<paragraph>
<b key="a" thing="value">
word
</b>
</paragraph>
</document>
</value>
)

export const output = (
<value>
<document>
<paragraph>
wo
<b thing="value">rd</b>
</paragraph>
</document>
</value>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/** @jsx h */

import h from '../../../helpers/h'

export default function(editor) {
editor.replaceMarksByKey('a', 0, 2, [
{ type: 'bold', data: { thing: 'new value' } },
])
}

export const input = (
<value>
<document>
<paragraph>
<b key="a" thing="value">
word
</b>
</paragraph>
</document>
</value>
)

export const output = (
<value>
<document>
<paragraph>
<b thing="new value">wo</b>
<b thing="value">rd</b>
</paragraph>
</document>
</value>
)
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,7 @@ export const output = (
<value>
<document>
<paragraph>
Meow,{' '}
<fontSize size={16}>
<fontSize size={12}>cat is cute</fontSize>
</fontSize>
Meow, <fontSize size={16}>cat is cute</fontSize>
<fontSize size={12}>
<cursor />d.
</fontSize>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,7 @@ export const output = (
<value>
<document>
<paragraph>
Meow,{' '}
<i>
<b>cat is cute</b>
</i>
Meow, <i>cat is cute</i>
<b>
<cursor />d.
</b>
Expand Down

0 comments on commit 65796c8

Please sign in to comment.