1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-09-09 06:30:40 +02:00

split format_text into two commands (#3340)

* split format_text into two commands

* fix lint
This commit is contained in:
Ian Storm Taylor
2019-12-17 22:17:33 -05:00
committed by GitHub
parent 235a578967
commit 28b5217370
3 changed files with 103 additions and 79 deletions

View File

@@ -95,6 +95,30 @@ export const createEditor = (): Editor => {
const { selection } = editor
switch (command.type) {
case 'add_mark': {
if (selection) {
const { key, value } = command
if (Range.isExpanded(selection)) {
Editor.setNodes(
editor,
{ [key]: value },
{ match: Text.isText, split: true }
)
} else {
const marks = {
...(Editor.marks(editor) || {}),
[key]: value,
}
editor.marks = marks
editor.onChange()
}
}
break
}
case 'delete_backward': {
if (selection && Range.isCollapsed(selection)) {
Editor.delete(editor, { unit: command.unit, reverse: true })
@@ -119,55 +143,6 @@ export const createEditor = (): Editor => {
break
}
case 'format_text': {
if (selection) {
const { properties } = command
if (Range.isExpanded(selection)) {
const [match] = Editor.nodes(editor, {
match: n => Text.isText(n) && Text.matches(n, properties),
universal: true,
})
if (match) {
const keys = Object.keys(properties)
Editor.unsetNodes(editor, keys, {
match: Text.isText,
split: true,
})
} else {
Editor.setNodes(editor, properties, {
match: Text.isText,
split: true,
})
}
} else {
const marks = { ...(Editor.marks(editor) || {}) }
let match = true
for (const key in properties) {
if (marks[key] !== properties[key]) {
match = false
break
}
}
if (match) {
for (const key in properties) {
delete marks[key]
}
} else {
Object.assign(marks, properties)
}
editor.marks = marks
editor.onChange()
}
}
break
}
case 'insert_break': {
Editor.splitNodes(editor, { always: true })
break
@@ -217,6 +192,26 @@ export const createEditor = (): Editor => {
}
break
}
case 'remove_mark': {
if (selection) {
const { key } = command
if (Range.isExpanded(selection)) {
Editor.unsetNodes(editor, key, {
match: Text.isText,
split: true,
})
} else {
const marks = { ...(Editor.marks(editor) || {}) }
delete marks[key]
editor.marks = marks
editor.onChange()
}
}
break
}
}
}
},

View File

@@ -21,6 +21,16 @@ export const Command = {
},
}
/**
* The `AddMarkCommand` adds properties to the text nodes in the selection.
*/
export interface AddMarkCommand {
type: 'add_mark'
key: string
value: any
}
/**
* The `DeleteBackwardCommand` delete's content backward, meaning before the
* current selection, by a specific `unit` of distance.
@@ -49,15 +59,6 @@ export interface DeleteFragmentCommand {
type: 'delete_fragment'
}
/**
* The `FormatTextCommand` adds properties to the text nodes in the selection.
*/
export interface FormatTextCommand {
type: 'format_text'
properties: Record<string, any>
}
/**
* The `InsertBreakCommand` breaks a block in two at the current selection.
*/
@@ -93,20 +94,30 @@ export interface InsertTextCommand {
text: string
}
/**
* The `RemoveMarkCommand` removes properties from text nodes in the selection.
*/
export interface RemoveMarkCommand {
type: 'remove_mark'
key: string
}
/**
* The `CoreCommand` union is a set of all of the commands that are recognized
* by Slate's "core" out of the box.
*/
export type CoreCommand =
| AddMarkCommand
| DeleteBackwardCommand
| DeleteForwardCommand
| DeleteFragmentCommand
| FormatTextCommand
| InsertBreakCommand
| InsertFragmentCommand
| InsertNodeCommand
| InsertTextCommand
| RemoveMarkCommand
export const CoreCommand = {
/**
@@ -116,14 +127,14 @@ export const CoreCommand = {
isCoreCommand(value: any): value is CoreCommand {
if (Command.isCommand(value)) {
switch (value.type) {
case 'add_mark':
return typeof value.key === 'string' && value.value != null
case 'delete_backward':
return typeof value.unit === 'string'
case 'delete_forward':
return typeof value.unit === 'string'
case 'delete_fragment':
return true
case 'format_text':
return isPlainObject(value.properties)
case 'insert_break':
return true
case 'insert_fragment':
@@ -132,6 +143,8 @@ export const CoreCommand = {
return Node.isNode(value.node)
case 'insert_text':
return typeof value.text === 'string'
case 'remove_mark':
return typeof value.key === 'string'
}
}