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:
5
.changeset/giant-comics-walk.md
Normal file
5
.changeset/giant-comics-walk.md
Normal 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
@@ -1,14 +1,17 @@
|
|||||||
import assert from 'assert'
|
import assert from 'assert'
|
||||||
import {
|
import {
|
||||||
|
codepointsIteratorRTL,
|
||||||
getCharacterDistance,
|
getCharacterDistance,
|
||||||
getWordDistance,
|
getWordDistance,
|
||||||
codepointsIteratorRTL,
|
|
||||||
} from '../../src/utils/string'
|
} from '../../src/utils/string'
|
||||||
|
|
||||||
const codepoints = [
|
const codepoints = [
|
||||||
['a', 1],
|
['a', 1],
|
||||||
['0', 1],
|
['0', 1],
|
||||||
[' ', 1],
|
[' ', 1],
|
||||||
|
['# ', 1],
|
||||||
|
['* ', 1],
|
||||||
|
['2 ', 1],
|
||||||
['🙂', 2],
|
['🙂', 2],
|
||||||
['☺️', 2],
|
['☺️', 2],
|
||||||
['☺️', 2],
|
['☺️', 2],
|
||||||
@@ -67,6 +70,35 @@ const tagSequences = [
|
|||||||
['🏴', 14],
|
['🏴', 14],
|
||||||
] as const
|
] 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']
|
const dirs = ['ltr', 'rtl']
|
||||||
|
|
||||||
dirs.forEach(dir => {
|
dirs.forEach(dir => {
|
||||||
@@ -104,6 +136,20 @@ dirs.forEach(dir => {
|
|||||||
assert.strictEqual(getCharacterDistance(str + str, isRTL), dist)
|
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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user