1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-29 09:59:48 +02:00

Consistent insert* methods (#5415)

* feat: add reviewpad.yml file

* Update reviewpad.yml

*  options to `Editor.insert*`

* 📝 options to `Editor.insert*`

*  getDefaultInsertLocation

*  getDefaultInsertLocation

*  getDefaultInsertLocation

* 📝 consistent selection

* Create tasty-lizards-remain.md

* Update tasty-lizards-remain.md

---------

Co-authored-by: reviewpad[bot] <104832597+reviewpad[bot]@users.noreply.github.com>
Co-authored-by: Dylan Schiemann <dylan@dojotoolkit.org>
This commit is contained in:
Ziad Beyens
2023-05-07 00:41:42 +02:00
committed by GitHub
parent 48c18b5368
commit 01f0210bcc
12 changed files with 92 additions and 60 deletions

View File

@@ -1,6 +1,10 @@
import { Transforms } from '../interfaces/transforms'
import { EditorInterface } from '../interfaces/editor'
export const insertNode: EditorInterface['insertNode'] = (editor, node) => {
Transforms.insertNodes(editor, node)
export const insertNode: EditorInterface['insertNode'] = (
editor,
node,
options
) => {
Transforms.insertNodes(editor, node, options)
}

View File

@@ -11,7 +11,10 @@ export const insertText: EditorInterface['insertText'] = (
if (selection) {
if (marks) {
const node = { text, ...marks }
Transforms.insertNodes(editor, node)
Transforms.insertNodes(editor, node, {
at: options.at,
voids: options.voids,
})
} else {
Transforms.insertText(editor, text, options)
}

View File

@@ -28,7 +28,11 @@ import {
} from '../types/types'
import { OmitFirstArg } from '../utils/types'
import { isEditor } from '../editor/is-editor'
import { TextInsertTextOptions } from './transforms/text'
import {
TextInsertFragmentOptions,
TextInsertTextOptions,
} from './transforms/text'
import { NodeInsertNodesOptions } from './transforms/node'
/**
* The `Editor` interface stores all the state of a Slate editor. It is extended
@@ -412,18 +416,24 @@ export interface EditorInterface {
insertBreak: (editor: Editor) => void
/**
* Insert a fragment at the current selection.
*
* If the selection is currently expanded, it will be deleted first.
* Inserts a fragment
* at the specified location or (if not defined) the current selection or (if not defined) the end of the document.
*/
insertFragment: (editor: Editor, fragment: Node[]) => void
insertFragment: (
editor: Editor,
fragment: Node[],
options?: TextInsertFragmentOptions
) => void
/**
* Insert a node at the current selection.
*
* If the selection is currently expanded, it will be deleted first.
* Atomically inserts `nodes`
* at the specified location or (if not defined) the current selection or (if not defined) the end of the document.
*/
insertNode: (editor: Editor, node: Node) => void
insertNode: <T extends Node>(
editor: Editor,
node: Node,
options?: NodeInsertNodesOptions<T>
) => void
/**
* Insert a soft break at the current selection.
@@ -433,9 +443,8 @@ export interface EditorInterface {
insertSoftBreak: (editor: Editor) => void
/**
* Insert text at the current selection.
*
* If the selection is currently expanded, it will be deleted first.
* Insert a string of text
* at the specified location or (if not defined) the current selection or (if not defined) the end of the document.
*/
insertText: (
editor: Editor,
@@ -774,8 +783,8 @@ export const Editor: EditorInterface = {
editor.insertBreak()
},
insertFragment(editor, fragment) {
editor.insertFragment(fragment)
insertFragment(editor, fragment, options) {
editor.insertFragment(fragment, options)
},
insertNode(editor, node) {

View File

@@ -2,21 +2,24 @@ import { Editor, Element, Location, Node, Path } from '../../index'
import { NodeMatch, PropsCompare, PropsMerge } from '../editor'
import { MaximizeMode, RangeMode } from '../../types/types'
export interface NodeInsertNodesOptions<T extends Node> {
at?: Location
match?: NodeMatch<T>
mode?: RangeMode
hanging?: boolean
select?: boolean
voids?: boolean
}
export interface NodeTransforms {
/**
* Insert nodes at a specific location in the Editor.
* Insert nodes in the editor
* at the specified location or (if not defined) the current selection or (if not defined) the end of the document.
*/
insertNodes: <T extends Node>(
editor: Editor,
nodes: Node | Node[],
options?: {
at?: Location
match?: NodeMatch<T>
mode?: RangeMode
hanging?: boolean
select?: boolean
voids?: boolean
}
options?: NodeInsertNodesOptions<T>
) => void
/**

View File

@@ -1,5 +1,6 @@
import { Editor, Location, Node, Path, Range, Transforms } from '../../index'
import { TextUnit } from '../../types/types'
import { getDefaultInsertLocation } from '../../utils'
export interface TextDeleteOptions {
at?: Location
@@ -28,7 +29,8 @@ export interface TextTransforms {
delete: (editor: Editor, options?: TextDeleteOptions) => void
/**
* Insert a fragment at a specific location in the editor.
* Insert a fragment in the editor
* at the specified location or (if not defined) the current selection or (if not defined) the end of the document.
*/
insertFragment: (
editor: Editor,
@@ -37,7 +39,8 @@ export interface TextTransforms {
) => void
/**
* Insert a string of text in the Editor.
* Insert a string of text in the editor
* at the specified location or (if not defined) the current selection or (if not defined) the end of the document.
*/
insertText: (
editor: Editor,
@@ -61,11 +64,7 @@ export const TextTransforms: TextTransforms = {
): void {
Editor.withoutNormalizing(editor, () => {
const { voids = false } = options
let { at = editor.selection } = options
if (!at) {
return
}
let { at = getDefaultInsertLocation(editor) } = options
if (Path.isPath(at)) {
at = Editor.range(editor, at)

View File

@@ -7,6 +7,7 @@ import { Point } from '../interfaces/point'
import { Text } from '../interfaces/text'
import { Element } from '../interfaces/element'
import { Path } from '../interfaces/path'
import { getDefaultInsertLocation } from '../utils'
export const insertNodes: NodeTransforms['insertNodes'] = (
editor,
@@ -27,18 +28,8 @@ export const insertNodes: NodeTransforms['insertNodes'] = (
const [node] = nodes
// By default, use the selection as the target location. But if there is
// no selection, insert at the end of the document since that is such a
// common use case when inserting from a non-selected state.
if (!at) {
if (editor.selection) {
at = editor.selection
} else if (editor.children.length > 0) {
at = Editor.end(editor, [])
} else {
at = [0]
}
at = getDefaultInsertLocation(editor)
select = true
}

View File

@@ -6,6 +6,7 @@ import { Element } from '../interfaces/element'
import { Node, NodeEntry } from '../interfaces/node'
import { Text } from '../interfaces/text'
import { TextTransforms } from '../interfaces/transforms/text'
import { getDefaultInsertLocation } from '../utils'
export const insertFragment: TextTransforms['insertFragment'] = (
editor,
@@ -14,15 +15,13 @@ export const insertFragment: TextTransforms['insertFragment'] = (
) => {
Editor.withoutNormalizing(editor, () => {
const { hanging = false, voids = false } = options
let { at = editor.selection } = options
let { at = getDefaultInsertLocation(editor) } = options
if (!fragment.length) {
return
}
if (!at) {
return
} else if (Range.isRange(at)) {
if (Range.isRange(at)) {
if (!hanging) {
at = Editor.unhangRange(editor, at, { voids })
}

View File

@@ -0,0 +1,17 @@
import { Editor, Location } from '../interfaces'
/**
* Get the default location to insert content into the editor.
* By default, use the selection as the target location. But if there is
* no selection, insert at the end of the document since that is such a
* common use case when inserting from a non-selected state.
*/
export const getDefaultInsertLocation = (editor: Editor): Location => {
if (editor.selection) {
return editor.selection
} else if (editor.children.length > 0) {
return Editor.end(editor, [])
} else {
return [0]
}
}

View File

@@ -1,4 +1,5 @@
export * from './deep-equal'
export * from './get-default-insert-location'
export * from './match-path'
export * from './string'
export * from './types'