1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-20 06:01:24 +02:00

fix: cursor jumps more than one character unexpectedly (#4671)

* Add test cases suggested in https://github.com/ianstormtaylor/slate/issues/4649#issuecomment-974015248

* fix: cursor jumping more than one character

* Optimization

* Make ZWJs in test strings visible
This commit is contained in:
unageek
2021-11-23 17:45:08 +09:00
committed by GitHub
parent e538065572
commit e3afda9466
3 changed files with 226 additions and 218 deletions

View File

@@ -0,0 +1,5 @@
---
'slate': patch
---
Fixed the issue where the cursor jumps more than one character unexpectedly

File diff suppressed because one or more lines are too long

View File

@@ -1,14 +1,17 @@
import assert from 'assert'
import {
codepointsIteratorRTL,
getCharacterDistance,
getWordDistance,
codepointsIteratorRTL,
} from '../../src/utils/string'
const codepoints = [
['a', 1],
['0', 1],
[' ', 1],
['# ', 1],
['* ', 1],
['2 ', 1],
['🙂', 2],
['☺️', 2],
['☺️', 2],
@@ -67,6 +70,35 @@ const tagSequences = [
['🏴󠁧󠁢󠁷󠁬󠁳󠁿', 14],
] as const
// Sample strings from https://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakTest.html#samples
// In some strings, explicit Unicode code points are used to prevent accidental normalization.
// Zero-width joiners (U+200D), which are hard to tell, are also made explicit.
const sampleStrings = {
'2': ['a\u0308'],
'3': [' \u200d', 'ن'],
'4': ['ن\u200d', ' '],
'5': ['ᄀᄀ'],
'6': ['가\u11a8', 'ᄀ'],
'7': ['각ᆨ', 'ᄀ'],
'8': ['🇦🇧', '🇨', 'b'],
'9': ['a', '🇦🇧', '🇨', 'b'],
'10': ['a', '🇦🇧\u200d', '🇨', 'b'],
'11': ['a', '🇦\u200d', '🇧🇨', 'b'],
'12': ['a', '🇦🇧', '🇨🇩', 'b'],
'13': ['a\u200d'],
'14': ['a\u0308', 'b'],
'15': ['a', 'b'],
'16': ['a', '؀b'],
'17': ['👶🏿', '👶'],
'18': ['a🏿', '👶'],
'19': ['a🏿', '👶\u200d🛑'],
'20': ['👶🏿̈\u200d👶🏿'],
'21': ['🛑\u200d🛑'],
'22': ['a\u200d', '🛑'],
'23': ['✁\u200d✁'],
'24': ['a\u200d', '✁'],
}
const dirs = ['ltr', 'rtl']
dirs.forEach(dir => {
@@ -104,6 +136,20 @@ dirs.forEach(dir => {
assert.strictEqual(getCharacterDistance(str + str, isRTL), dist)
})
})
Object.entries(sampleStrings).forEach(([label, strs]) => {
for (let i = 0; i < strs.length; i++) {
let str = ''
if (isRTL) {
str = strs.slice(0, i + 1).join('')
} else {
str = strs.slice(i).join('')
}
it(`Sample string ${label}, boundary ${isRTL ? i : i + 1}`, () => {
assert.strictEqual(getCharacterDistance(str, isRTL), strs[i].length)
})
}
})
})
})