1
0
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:
Ian Storm Taylor
2016-11-29 16:58:12 -08:00
parent 4854d11ba4
commit 1fd27578fa
5 changed files with 224 additions and 88 deletions

View File

@@ -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 = []
} }

View File

@@ -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.
* *

View File

@@ -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.
* *

View File

@@ -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`.
* *

View File

@@ -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,