1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-01-19 14:27:07 +01:00

fix delete forward/backward to be unicode aware, closes #87

This commit is contained in:
Ian Storm Taylor 2016-07-14 13:42:10 -07:00
parent 54fe325c80
commit bf1ea4f975
2 changed files with 87 additions and 42 deletions

View File

@ -2,9 +2,9 @@
import Key from '../utils/key'
import Placeholder from '../components/placeholder'
import React from 'react'
import String from '../utils/string'
import keycode from 'keycode'
import { IS_WINDOWS, IS_MAC } from '../utils/environment'
import { getWordOffsetBackward, getWordOffsetForward } from '../utils/string'
/**
* The default plugin.
@ -156,14 +156,16 @@ function Plugin(options = {}) {
case 'backspace': {
if (state.isExpanded) return transform.delete().apply()
const { startOffset, startBlock } = state
const text = startBlock.text
let n
if (Key.isWord(e)) {
n = getWordOffsetBackward(state.startBlock.text, state.startOffset)
n = String.getWordOffsetBackward(text, startOffset)
} else if (Key.isLine(e)) {
n = state.startOffset
n = startOffset
} else {
n = 1
n = String.getCharOffsetBackward(text, startOffset)
}
return transform.deleteBackward(n).apply()
@ -171,14 +173,16 @@ function Plugin(options = {}) {
case 'delete': {
if (state.isExpanded) return transform.delete().apply()
const { startOffset, startBlock } = state
const text = startBlock.text
let n
if (Key.isWord(e)) {
n = getWordOffsetForward(state.startBlock.text, state.startOffset)
n = String.getWordOffsetForward(text, startOffset)
} else if (Key.isLine(e)) {
n = state.startBlock.text.length - state.startOffset
n = text.length - startOffset
} else {
n = 1
n = String.getCharOffsetForward(text, startOffset)
}
return transform.deleteForward(n).apply()

View File

@ -60,7 +60,7 @@ function isWord(char, remaining) {
// If it's a chameleon character, recurse to see if the next one is or not.
if (CHAMELEON.test(char)) {
const next = remaining.charAt(0)
const length = getCharacterLength(next)
const length = getCharLength(next)
const rest = remaining.slice(length)
if (isWord(next, rest)) return true
}
@ -76,12 +76,51 @@ function isWord(char, remaining) {
* @return {Number}
*/
function getCharacterLength(char) {
function getCharLength(char) {
return isSurrogate(char.charCodeAt(0))
? 2
: 1
}
/**
* Get the offset to the end of the first character in `text`.
*
* @param {String} text
* @return {Number}
*/
function getCharOffset(text) {
const char = text.charAt(0)
return getCharLength(char)
}
/**
* Get the offset to the end of the character before an `offset` in `text`.
*
* @param {String} text
* @param {Number} offset
* @return {Number}
*/
function getCharOffsetBackward(text, offset) {
text = text.slice(0, offset)
text = reverse(text)
return getCharOffset(text)
}
/**
* Get the offset to the end of the character after an `offset` in `text`.
*
* @param {String} text
* @param {Number} offset
* @return {Number}
*/
function getCharOffsetForward(text, offset) {
text = text.slice(offset)
return getCharOffset(text)
}
/**
* Get the length of a `string`.
*
@ -95,7 +134,7 @@ function getLength(string) {
for (
let i = 0, char = string.charAt(i);
i < string.length;
i += getCharacterLength(char)
i += getCharLength(char)
) {
length++
}
@ -104,34 +143,7 @@ function getLength(string) {
}
/**
* Get the offset at the end of the word before an `offset` in `text`.
*
* @param {String} text
* @param {Number} offset
* @return {Number}
*/
function getWordOffsetBackward(text, offset) {
text = text.slice(0, offset)
text = reverse(text)
return getWordOffset(text)
}
/**
* Get the offset at the end of the word after an `offset` in `text`.
*
* @param {String} text
* @param {Number} offset
* @return {Number}
*/
function getWordOffsetForward(text, offset) {
text = text.slice(offset)
return getWordOffset(text)
}
/**
* Get the offset at the end of the first word in `text`.
* Get the offset to the end of the first word in `text`.
*
* @param {String} text
* @return {Number}
@ -144,7 +156,7 @@ function getWordOffset(text) {
let char
while (char = text.charAt(i)) {
const l = getCharacterLength(char)
const l = getCharLength(char)
const rest = text.slice(i + l)
if (isWord(char, rest)) {
@ -162,11 +174,40 @@ function getWordOffset(text) {
return length
}
/**
* Get the offset to the end of the word before an `offset` in `text`.
*
* @param {String} text
* @param {Number} offset
* @return {Number}
*/
function getWordOffsetBackward(text, offset) {
text = text.slice(0, offset)
text = reverse(text)
return getWordOffset(text)
}
/**
* Get the offset to the end of the word after an `offset` in `text`.
*
* @param {String} text
* @param {Number} offset
* @return {Number}
*/
function getWordOffsetForward(text, offset) {
text = text.slice(offset)
return getWordOffset(text)
}
/**
* Export.
*/
export {
export default {
getCharOffsetForward,
getCharOffsetBackward,
getWordOffsetBackward,
getWordOffsetForward
}