File tree Expand file tree Collapse file tree 4 files changed +86
-4
lines changed Expand file tree Collapse file tree 4 files changed +86
-4
lines changed Original file line number Diff line number Diff line change 1+ ---
2+ " react-mentions " : patch
3+ ---
4+
5+ Fixed substring matching bug when typeing korean.
Original file line number Diff line number Diff line change 1+ import escapeRegex from './escapeRegex'
2+
3+ function ch2pattern ( ch ) {
4+ const offset = 44032 /* '가'의 코드 */
5+ // 한국어 음절 (Korean syllables)
6+ if ( / [ 가 - 힣 ] / . test ( ch ) ) {
7+ const chCode = ch . charCodeAt ( 0 ) - offset
8+ // 종성이 있으면 문자 그대로를 찾는다.
9+ if ( chCode % 28 > 0 ) {
10+ return ch
11+ }
12+
13+ const begin = Math . floor ( chCode / 28 ) * 28 + offset
14+ const end = begin + 27
15+ return `[\\u${ begin . toString ( 16 ) } -\\u${ end . toString ( 16 ) } ]`
16+ }
17+
18+ // 한글 자음 (Korean consonants)
19+ if ( / [ ㄱ - ㅎ ] / . test ( ch ) ) {
20+ const con2syl = {
21+ ㄱ : '가' . charCodeAt ( 0 ) ,
22+ ㄲ : '까' . charCodeAt ( 0 ) ,
23+ ㄴ : '나' . charCodeAt ( 0 ) ,
24+ ㄷ : '다' . charCodeAt ( 0 ) ,
25+ ㄸ : '따' . charCodeAt ( 0 ) ,
26+ ㄹ : '라' . charCodeAt ( 0 ) ,
27+ ㅁ : '마' . charCodeAt ( 0 ) ,
28+ ㅂ : '바' . charCodeAt ( 0 ) ,
29+ ㅃ : '빠' . charCodeAt ( 0 ) ,
30+ ㅅ : '사' . charCodeAt ( 0 ) ,
31+ }
32+ const begin =
33+ con2syl [ ch ] ||
34+ ( ch . charCodeAt ( 0 ) - 12613 ) /* 'ㅅ'의 코드 */ * 588 + con2syl [ 'ㅅ' ]
35+ const end = begin + 587
36+ return `[${ ch } \\u${ begin . toString ( 16 ) } -\\u${ end . toString ( 16 ) } ]`
37+ }
38+
39+ // 그 외엔 그대로 내보냄 (other than korean)
40+ return escapeRegex ( ch )
41+ }
42+
43+ export default function createMatcher ( input ) {
44+ const pattern = input
45+ . split ( '' )
46+ . map ( ch2pattern )
47+ . map ( pattern => '(' + pattern + ')' )
48+ . join ( '' )
49+
50+ return new RegExp ( pattern + '.*' , 'i' )
51+ }
Original file line number Diff line number Diff line change 1+ import createMatcher from './createMatcher'
2+
3+ describe ( '#createMatcher' , ( ) => {
4+ it ( 'should match substring including input value' , ( ) => {
5+ const enRegex = createMatcher ( 'je' )
6+ expect ( enRegex . test ( 'Jesse Pinkman' ) ) . toEqual ( true )
7+ expect ( enRegex . test ( 'Pinkman' ) ) . toEqual ( false )
8+
9+ const enRegex2 = createMatcher ( 'pi' )
10+ expect ( 'Jesse Pinkman' . match ( enRegex2 ) . index ) . toEqual ( 6 )
11+ expect ( 'Pinkman' . match ( enRegex2 ) . index ) . toEqual ( 0 )
12+ } )
13+
14+ it ( 'should match substring including Korean consonants' , ( ) => {
15+ const koRegex = createMatcher ( 'ㅅㄷ' )
16+ expect ( koRegex . test ( '성덕선' ) ) . toEqual ( true )
17+ expect ( koRegex . test ( '덕선' ) ) . toEqual ( false )
18+
19+ const enRegex2 = createMatcher ( 'ㄷㅅ' )
20+ expect ( '성덕선' . match ( enRegex2 ) . index ) . toEqual ( 1 )
21+ expect ( '덕선' . match ( enRegex2 ) . index ) . toEqual ( 0 )
22+ } )
23+ } )
Original file line number Diff line number Diff line change 1+ import createMatcher from './createMatcher'
12import lettersDiacritics from './diacritics'
23
34const removeAccents = str => {
@@ -16,11 +17,13 @@ const removeAccents = str => {
1617export const normalizeString = str => removeAccents ( str ) . toLowerCase ( )
1718
1819const getSubstringIndex = ( str , substr , ignoreAccents ) => {
19- if ( ! ignoreAccents ) {
20- return str . toLowerCase ( ) . indexOf ( substr . toLowerCase ( ) )
21- }
20+ const display = ignoreAccents ? normalizeString ( str ) : str
21+ const query = ignoreAccents ? normalizeString ( substr ) : substr
2222
23- return normalizeString ( str ) . indexOf ( normalizeString ( substr ) )
23+ const regex = createMatcher ( query )
24+ const match = display . match ( regex )
25+
26+ return match ? match . index : - 1
2427}
2528
2629export default getSubstringIndex
You can’t perform that action at this time.
0 commit comments