mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-13 18:53:59 +02:00
add char, word, line delete transforms
This commit is contained in:
@@ -23,11 +23,10 @@ class Transform {
|
|||||||
*
|
*
|
||||||
* @param {Object} properties
|
* @param {Object} properties
|
||||||
* @property {State} properties.state
|
* @property {State} properties.state
|
||||||
* @property {Boolean} properties.normalized
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
constructor(properties) {
|
constructor(properties) {
|
||||||
const { state, normalized = true } = properties
|
const { state } = properties
|
||||||
this.state = state
|
this.state = state
|
||||||
this.operations = []
|
this.operations = []
|
||||||
}
|
}
|
||||||
|
@@ -369,8 +369,6 @@ function Plugin(options = {}) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function onKeyDownEnter(e, data, state) {
|
function onKeyDownEnter(e, data, state) {
|
||||||
debug('onKeyDownEnter', { data })
|
|
||||||
|
|
||||||
const { document, startKey } = state
|
const { document, startKey } = state
|
||||||
const hasVoidParent = document.hasVoidParent(startKey)
|
const hasVoidParent = document.hasVoidParent(startKey)
|
||||||
|
|
||||||
@@ -401,36 +399,13 @@ function Plugin(options = {}) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function onKeyDownBackspace(e, data, state) {
|
function onKeyDownBackspace(e, data, state) {
|
||||||
debug('onKeyDownBackspace', { data })
|
let boundary = 'Char'
|
||||||
|
if (data.isWord) boundary = 'Word'
|
||||||
// If expanded, delete regularly.
|
if (data.isLine) boundary = 'Line'
|
||||||
if (state.isExpanded) {
|
|
||||||
return state
|
|
||||||
.transform()
|
|
||||||
.delete()
|
|
||||||
.apply()
|
|
||||||
}
|
|
||||||
|
|
||||||
const { startOffset, startBlock } = state
|
|
||||||
const text = startBlock.text
|
|
||||||
let n
|
|
||||||
|
|
||||||
// Determine how far backwards to delete.
|
|
||||||
if (data.isWord) {
|
|
||||||
n = String.getWordOffsetBackward(text, startOffset)
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (data.isLine) {
|
|
||||||
n = startOffset
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
n = String.getCharOffsetBackward(text, startOffset)
|
|
||||||
}
|
|
||||||
|
|
||||||
return state
|
return state
|
||||||
.transform()
|
.transform()
|
||||||
.deleteBackward(n)
|
[`delete${boundary}Backward`]()
|
||||||
.apply()
|
.apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,36 +419,13 @@ function Plugin(options = {}) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function onKeyDownDelete(e, data, state) {
|
function onKeyDownDelete(e, data, state) {
|
||||||
debug('onKeyDownDelete', { data })
|
let boundary = 'Char'
|
||||||
|
if (data.isWord) boundary = 'Word'
|
||||||
// If expanded, delete regularly.
|
if (data.isLine) boundary = 'Line'
|
||||||
if (state.isExpanded) {
|
|
||||||
return state
|
|
||||||
.transform()
|
|
||||||
.delete()
|
|
||||||
.apply()
|
|
||||||
}
|
|
||||||
|
|
||||||
const { startOffset, startBlock } = state
|
|
||||||
const text = startBlock.text
|
|
||||||
let n
|
|
||||||
|
|
||||||
// Determine how far forwards to delete.
|
|
||||||
if (data.isWord) {
|
|
||||||
n = String.getWordOffsetForward(text, startOffset)
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (data.isLine) {
|
|
||||||
n = text.length - startOffset
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
n = String.getCharOffsetForward(text, startOffset)
|
|
||||||
}
|
|
||||||
|
|
||||||
return state
|
return state
|
||||||
.transform()
|
.transform()
|
||||||
.deleteForward(n)
|
[`delete${boundary}Forward`]()
|
||||||
.apply()
|
.apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,8 +457,6 @@ function Plugin(options = {}) {
|
|||||||
const previousText = document.getPreviousText(startKey)
|
const previousText = document.getPreviousText(startKey)
|
||||||
if (!previousText) return
|
if (!previousText) return
|
||||||
|
|
||||||
debug('onKeyDownLeft', { data })
|
|
||||||
|
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
return state
|
return state
|
||||||
.transform()
|
.transform()
|
||||||
@@ -543,8 +493,6 @@ function Plugin(options = {}) {
|
|||||||
const nextText = document.getNextText(startKey)
|
const nextText = document.getNextText(startKey)
|
||||||
if (!nextText) return state
|
if (!nextText) return state
|
||||||
|
|
||||||
debug('onKeyDownRight', { data })
|
|
||||||
|
|
||||||
// COMPAT: In Chrome & Safari, selections that are at the zero offset of
|
// COMPAT: In Chrome & Safari, selections that are at the zero offset of
|
||||||
// an inline node will be automatically replaced to be at the last offset
|
// an inline node will be automatically replaced to be at the last offset
|
||||||
// of a previous inline node, which screws us up, so we always want to set
|
// of a previous inline node, which screws us up, so we always want to set
|
||||||
@@ -560,6 +508,26 @@ function Plugin(options = {}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On `k` key down, delete untill the end of the line (mac only)
|
||||||
|
*
|
||||||
|
* @param {Event} e
|
||||||
|
* @param {Object} data
|
||||||
|
* @param {State} state
|
||||||
|
* @return {State}
|
||||||
|
*/
|
||||||
|
|
||||||
|
function onKeyDownK(e, data, state) {
|
||||||
|
if (!IS_MAC || !data.isCtrl) return
|
||||||
|
|
||||||
|
const { startOffset, startBlock } = state
|
||||||
|
|
||||||
|
return state
|
||||||
|
.transform()
|
||||||
|
.deleteForward(startBlock.length - startOffset)
|
||||||
|
.apply()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On `y` key down, redo.
|
* On `y` key down, redo.
|
||||||
*
|
*
|
||||||
@@ -572,8 +540,6 @@ function Plugin(options = {}) {
|
|||||||
function onKeyDownY(e, data, state) {
|
function onKeyDownY(e, data, state) {
|
||||||
if (!data.isMod) return
|
if (!data.isMod) return
|
||||||
|
|
||||||
debug('onKeyDownY', { data })
|
|
||||||
|
|
||||||
return state
|
return state
|
||||||
.transform()
|
.transform()
|
||||||
.redo()
|
.redo()
|
||||||
@@ -592,36 +558,12 @@ function Plugin(options = {}) {
|
|||||||
function onKeyDownZ(e, data, state) {
|
function onKeyDownZ(e, data, state) {
|
||||||
if (!data.isMod) return
|
if (!data.isMod) return
|
||||||
|
|
||||||
debug('onKeyDownZ', { data })
|
|
||||||
|
|
||||||
return state
|
return state
|
||||||
.transform()
|
.transform()
|
||||||
[data.isShift ? 'redo' : 'undo']()
|
[data.isShift ? 'redo' : 'undo']()
|
||||||
.apply({ save: false })
|
.apply({ save: false })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* On `k` key down, delete untill the end of the line (mac only)
|
|
||||||
*
|
|
||||||
* @param {Event} e
|
|
||||||
* @param {Object} data
|
|
||||||
* @param {State} state
|
|
||||||
* @return {State}
|
|
||||||
*/
|
|
||||||
|
|
||||||
function onKeyDownK(e, data, state) {
|
|
||||||
if (!IS_MAC || !data.isCtrl) return
|
|
||||||
|
|
||||||
debug('onKeyDownK', { data })
|
|
||||||
|
|
||||||
const { startOffset, startBlock } = state
|
|
||||||
|
|
||||||
return state
|
|
||||||
.transform()
|
|
||||||
.deleteForward(startBlock.text.length - startOffset)
|
|
||||||
.apply()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On paste.
|
* On paste.
|
||||||
*
|
*
|
||||||
|
@@ -63,6 +63,42 @@ export function deleteBackward(transform, n = 1) {
|
|||||||
transform.deleteBackwardAtRange(selection, n)
|
transform.deleteBackwardAtRange(selection, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete backward until the character boundary at the current selection.
|
||||||
|
*
|
||||||
|
* @param {Transform} transform
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function deleteCharBackward(transform) {
|
||||||
|
const { state } = transform
|
||||||
|
const { selection } = state
|
||||||
|
transform.deleteCharBackwardAtRange(selection)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete backward until the line boundary at the current selection.
|
||||||
|
*
|
||||||
|
* @param {Transform} transform
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function deleteLineBackward(transform) {
|
||||||
|
const { state } = transform
|
||||||
|
const { selection } = state
|
||||||
|
transform.deleteLineBackwardAtRange(selection)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete backward until the word boundary at the current selection.
|
||||||
|
*
|
||||||
|
* @param {Transform} transform
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function deleteWordBackward(transform) {
|
||||||
|
const { state } = transform
|
||||||
|
const { selection } = state
|
||||||
|
transform.deleteWordBackwardAtRange(selection)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete forward `n` characters at the current selection.
|
* Delete forward `n` characters at the current selection.
|
||||||
*
|
*
|
||||||
@@ -76,6 +112,42 @@ export function deleteForward(transform, n = 1) {
|
|||||||
transform.deleteForwardAtRange(selection, n)
|
transform.deleteForwardAtRange(selection, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete forward until the character boundary at the current selection.
|
||||||
|
*
|
||||||
|
* @param {Transform} transform
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function deleteCharForward(transform) {
|
||||||
|
const { state } = transform
|
||||||
|
const { selection } = state
|
||||||
|
transform.deleteCharForwardAtRange(selection)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete forward until the line boundary at the current selection.
|
||||||
|
*
|
||||||
|
* @param {Transform} transform
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function deleteLineForward(transform) {
|
||||||
|
const { state } = transform
|
||||||
|
const { selection } = state
|
||||||
|
transform.deleteLineForwardAtRange(selection)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete forward until the word boundary at the current selection.
|
||||||
|
*
|
||||||
|
* @param {Transform} transform
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function deleteWordForward(transform) {
|
||||||
|
const { state } = transform
|
||||||
|
const { selection } = state
|
||||||
|
transform.deleteWordForwardAtRange(selection)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert a `block` at the current selection.
|
* Insert a `block` at the current selection.
|
||||||
*
|
*
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
/* eslint no-console: 0 */
|
/* eslint no-console: 0 */
|
||||||
|
|
||||||
import Normalize from '../utils/normalize'
|
import Normalize from '../utils/normalize'
|
||||||
|
import String from '../utils/string'
|
||||||
import SCHEMA from '../schemas/core'
|
import SCHEMA from '../schemas/core'
|
||||||
import { List } from 'immutable'
|
import { List } from 'immutable'
|
||||||
|
|
||||||
@@ -119,6 +120,55 @@ export function deleteAtRange(transform, range, options = {}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete backward until the character boundary at a `range`.
|
||||||
|
*
|
||||||
|
* @param {Transform} transform
|
||||||
|
* @param {Selection} range
|
||||||
|
* @param {Object} options
|
||||||
|
* @property {Boolean} normalize
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function deleteCharBackwardAtRange(transform, range, options) {
|
||||||
|
const { state } = transform
|
||||||
|
const { startOffset, startBlock } = state
|
||||||
|
const { text } = startBlock
|
||||||
|
const n = String.getCharOffsetBackward(text, startOffset)
|
||||||
|
transform.deleteBackwardAtRange(range, n, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete backward until the line boundary at a `range`.
|
||||||
|
*
|
||||||
|
* @param {Transform} transform
|
||||||
|
* @param {Selection} range
|
||||||
|
* @param {Object} options
|
||||||
|
* @property {Boolean} normalize
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function deleteLineBackwardAtRange(transform, range, options) {
|
||||||
|
const { state } = transform
|
||||||
|
const { startOffset } = state
|
||||||
|
transform.deleteBackwardAtRange(range, startOffset, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete backward until the word boundary at a `range`.
|
||||||
|
*
|
||||||
|
* @param {Transform} transform
|
||||||
|
* @param {Selection} range
|
||||||
|
* @param {Object} options
|
||||||
|
* @property {Boolean} normalize
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function deleteWordBackwardAtRange(transform, range, options) {
|
||||||
|
const { state } = transform
|
||||||
|
const { startOffset, startBlock } = state
|
||||||
|
const { text } = startBlock
|
||||||
|
const n = String.getWordOffsetBackward(text, startOffset)
|
||||||
|
transform.deleteBackwardAtRange(range, n, options)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete backward `n` characters at a `range`.
|
* Delete backward `n` characters at a `range`.
|
||||||
*
|
*
|
||||||
@@ -189,6 +239,55 @@ export function deleteBackwardAtRange(transform, range, n = 1, options = {}) {
|
|||||||
transform.deleteAtRange(range, { normalize })
|
transform.deleteAtRange(range, { normalize })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete forward until the character boundary at a `range`.
|
||||||
|
*
|
||||||
|
* @param {Transform} transform
|
||||||
|
* @param {Selection} range
|
||||||
|
* @param {Object} options
|
||||||
|
* @property {Boolean} normalize
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function deleteCharForwardAtRange(transform, range, options) {
|
||||||
|
const { state } = transform
|
||||||
|
const { startOffset, startBlock } = state
|
||||||
|
const { text } = startBlock
|
||||||
|
const n = String.getCharOffsetForward(text, startOffset)
|
||||||
|
transform.deleteForwardAtRange(range, n, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete forward until the line boundary at a `range`.
|
||||||
|
*
|
||||||
|
* @param {Transform} transform
|
||||||
|
* @param {Selection} range
|
||||||
|
* @param {Object} options
|
||||||
|
* @property {Boolean} normalize
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function deleteLineForwardAtRange(transform, range, options) {
|
||||||
|
const { state } = transform
|
||||||
|
const { startOffset, startBlock } = state
|
||||||
|
transform.deleteForwardAtRange(range, startBlock.length - startOffset, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete forward until the word boundary at a `range`.
|
||||||
|
*
|
||||||
|
* @param {Transform} transform
|
||||||
|
* @param {Selection} range
|
||||||
|
* @param {Object} options
|
||||||
|
* @property {Boolean} normalize
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function deleteWordForwardAtRange(transform, range, options) {
|
||||||
|
const { state } = transform
|
||||||
|
const { startOffset, startBlock } = state
|
||||||
|
const { text } = startBlock
|
||||||
|
const n = String.getWordOffsetForward(text, startOffset)
|
||||||
|
transform.deleteForwardAtRange(range, n, options)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete forward `n` characters at a `range`.
|
* Delete forward `n` characters at a `range`.
|
||||||
*
|
*
|
||||||
|
@@ -33,7 +33,13 @@ import {
|
|||||||
import {
|
import {
|
||||||
deleteAtRange,
|
deleteAtRange,
|
||||||
deleteBackwardAtRange,
|
deleteBackwardAtRange,
|
||||||
|
deleteCharBackwardAtRange,
|
||||||
|
deleteCharForwardAtRange,
|
||||||
deleteForwardAtRange,
|
deleteForwardAtRange,
|
||||||
|
deleteLineBackwardAtRange,
|
||||||
|
deleteLineForwardAtRange,
|
||||||
|
deleteWordBackwardAtRange,
|
||||||
|
deleteWordForwardAtRange,
|
||||||
insertBlockAtRange,
|
insertBlockAtRange,
|
||||||
insertFragmentAtRange,
|
insertFragmentAtRange,
|
||||||
insertInlineAtRange,
|
insertInlineAtRange,
|
||||||
@@ -59,7 +65,13 @@ import {
|
|||||||
import {
|
import {
|
||||||
_delete,
|
_delete,
|
||||||
deleteBackward,
|
deleteBackward,
|
||||||
|
deleteCharBackward,
|
||||||
|
deleteCharForward,
|
||||||
deleteForward,
|
deleteForward,
|
||||||
|
deleteLineBackward,
|
||||||
|
deleteLineForward,
|
||||||
|
deleteWordBackward,
|
||||||
|
deleteWordForward,
|
||||||
insertBlock,
|
insertBlock,
|
||||||
insertFragment,
|
insertFragment,
|
||||||
insertInline,
|
insertInline,
|
||||||
@@ -194,7 +206,13 @@ export default {
|
|||||||
|
|
||||||
deleteAtRange,
|
deleteAtRange,
|
||||||
deleteBackwardAtRange,
|
deleteBackwardAtRange,
|
||||||
|
deleteCharBackwardAtRange,
|
||||||
|
deleteCharForwardAtRange,
|
||||||
deleteForwardAtRange,
|
deleteForwardAtRange,
|
||||||
|
deleteLineBackwardAtRange,
|
||||||
|
deleteLineForwardAtRange,
|
||||||
|
deleteWordBackwardAtRange,
|
||||||
|
deleteWordForwardAtRange,
|
||||||
insertBlockAtRange,
|
insertBlockAtRange,
|
||||||
insertFragmentAtRange,
|
insertFragmentAtRange,
|
||||||
insertInlineAtRange,
|
insertInlineAtRange,
|
||||||
@@ -218,7 +236,13 @@ export default {
|
|||||||
|
|
||||||
delete: _delete,
|
delete: _delete,
|
||||||
deleteBackward,
|
deleteBackward,
|
||||||
|
deleteCharBackward,
|
||||||
|
deleteCharForward,
|
||||||
deleteForward,
|
deleteForward,
|
||||||
|
deleteLineBackward,
|
||||||
|
deleteLineForward,
|
||||||
|
deleteWordBackward,
|
||||||
|
deleteWordForward,
|
||||||
insertBlock,
|
insertBlock,
|
||||||
insertFragment,
|
insertFragment,
|
||||||
insertInline,
|
insertInline,
|
||||||
|
Reference in New Issue
Block a user