fix(ios): input, Japanese IME ascii

Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
fufesou 2026-06-09 19:39:45 +08:00
commit f05d622342
2 changed files with 52 additions and 77 deletions

View file

@ -484,10 +484,8 @@ String? _continuedComposingValue(
if (kind != _CompositionKind.ascii) {
return null;
}
if (!_shouldHoldCollapsedAsciiComposingText(
previousTail: previousTail,
composingText: continuedValue,
)) {
if (_containsJapaneseKana(previousTail) ||
!_isLikelyPinyinComposingText(continuedValue)) {
return null;
}
@ -497,14 +495,6 @@ String? _continuedComposingValue(
return continuedValue;
}
bool _shouldHoldCollapsedAsciiComposingText({
required String previousTail,
required String composingText,
}) {
if (_containsJapaneseKana(previousTail)) return false;
return _isLikelyPinyinComposingText(composingText);
}
bool _isHeldPinyinComposingText(String? value) {
if (value == null || value.isEmpty) return false;
if (_compositionKind(value) != _CompositionKind.ascii) return false;
@ -561,7 +551,6 @@ bool _isLikelyPinyinComposingText(String value) {
bool _isLikelyPinyinToken(String token) {
return _isPinyinSyllablePrefix(token) ||
_isPinyinSyllableSequencePrefix(token) ||
_isPinyinSyllableWithTrailingInitial(token) ||
_isShortPinyinInitialSequence(token);
}
@ -570,7 +559,7 @@ bool _isPinyinSyllableSequencePrefix(String token) {
if (!_isCompletePinyinSyllable(token.substring(0, index))) continue;
final remaining = token.substring(index);
if (_isPinyinSyllablePrefix(remaining) ||
if (_isPinyinSyllablePrefixWithFinal(remaining) ||
_isPinyinSyllableSequencePrefix(remaining)) {
return true;
}
@ -591,16 +580,16 @@ bool _isPinyinSyllablePrefix(String token) {
return _pinyinFinals.any((finalValue) => finalValue.startsWith(token));
}
bool _isPinyinSyllableWithTrailingInitial(String token) {
for (var index = 1; index < token.length; index++) {
if (!_isCompletePinyinSyllable(token.substring(0, index))) continue;
bool _isPinyinSyllablePrefixWithFinal(String token) {
for (final initial in _pinyinInitials) {
if (!token.startsWith(initial)) continue;
final trailing = token.substring(index);
if (_pinyinInitials.any((initial) => initial.startsWith(trailing))) {
return true;
}
final finalPrefix = token.substring(initial.length);
if (finalPrefix.isEmpty) return false;
return _pinyinFinals
.any((finalValue) => finalValue.startsWith(finalPrefix));
}
return false;
return _pinyinFinals.any((finalValue) => finalValue.startsWith(token));
}
bool _isCompletePinyinSyllable(String token) {

View file

@ -325,6 +325,44 @@ void main() {
]);
});
test('sends Japanese IME ascii candidate when composing clears', () {
final session = _IOSSoftKeyboardInputSession('111');
expect(session.diff('111c', const TextRange(start: 3, end: 4)).actions,
isEmpty);
expect(session.diff('111ca', const TextRange(start: 3, end: 5)).actions,
isEmpty);
expect(session.diff('111cat', const TextRange(start: 3, end: 6)).actions,
isEmpty);
var result = session.diff('111cat');
expect(result.nextValue, '111cat');
expect(result.nextComposingValue, isNull);
expect(result.actions, [
const IOSSoftKeyboardInputAction.inputText('cat'),
]);
expect(session.diff('111catd', const TextRange(start: 6, end: 7)).actions,
isEmpty);
expect(
session.diff('111catdo', const TextRange(start: 6, end: 8)).actions,
isEmpty);
expect(
session.diff('111catdog', const TextRange(start: 6, end: 9)).actions,
isEmpty);
expect(
session.diff('111cat dog', const TextRange(start: 6, end: 10))
.actions,
isEmpty);
result = session.diff('111cat dog');
expect(result.nextValue, '111cat dog');
expect(result.nextComposingValue, isNull);
expect(result.actions, [
const IOSSoftKeyboardInputAction.inputText(' dog'),
]);
});
test('sends Korean jamo composition immediately', () {
final result = diffIOSSoftKeyboardInput(
previousValue: '111',
@ -339,21 +377,6 @@ void main() {
]);
});
test('sends Korean jamo without composing range immediately', () {
final result = diffIOSSoftKeyboardInput(
previousValue: '111',
currentValue: '111ㅎ',
composingRange: TextRange.empty,
sentinelPrefixLength: 3,
);
expect(result.nextValue, '111ㅎ');
expect(result.nextComposingValue, isNull);
expect(result.actions, [
const IOSSoftKeyboardInputAction.inputText(''),
]);
});
test('sends composing Korean hangul syllable immediately', () {
final result = diffIOSSoftKeyboardInput(
previousValue: '111',
@ -466,29 +489,8 @@ void main() {
const IOSSoftKeyboardInputAction.inputText(''),
]);
result = session.diff('111ㄹㅇㅎ');
expect(result.nextValue, '111ㄹㅇㅎ');
expect(result.nextComposingValue, isNull);
expect(result.actions, [
const IOSSoftKeyboardInputAction.inputText(''),
]);
result = session.diff('111ㄹㅇㅎㅎ');
expect(result.nextValue, '111ㄹㅇㅎㅎ');
expect(result.nextComposingValue, isNull);
expect(result.actions, [
const IOSSoftKeyboardInputAction.inputText(''),
]);
result = session.diff('111ㄹㅇㅎㅎㅇ');
expect(result.nextValue, '111ㄹㅇㅎㅎㅇ');
expect(result.nextComposingValue, isNull);
expect(result.actions, [
const IOSSoftKeyboardInputAction.inputText(''),
]);
result = session.diff('111ㄹㅇㅎㅎㅇ\n');
expect(result.nextValue, '111ㄹㅇㅎㅎㅇ\n');
result = session.diff('111ㄹㅇ\n');
expect(result.nextValue, '111ㄹㅇ\n');
expect(result.nextComposingValue, isNull);
expect(result.actions, [
const IOSSoftKeyboardInputAction.inputKey('\n'),
@ -523,18 +525,9 @@ void main() {
});
test('replaces Korean jamo with hangul after sent hangul', () {
final session = _IOSSoftKeyboardInputSession('111한');
session.previousComposingValue = '';
session.previousControllerText = '111한';
final session = _IOSSoftKeyboardInputSession('111한ㄴ');
var result = session.diff('111한ㄴ');
expect(result.nextValue, '111한ㄴ');
expect(result.nextComposingValue, isNull);
expect(result.actions, [
const IOSSoftKeyboardInputAction.inputText(''),
]);
result = session.diff('111한나');
final result = session.diff('111한나');
expect(result.nextValue, '111한나');
expect(result.nextComposingValue, isNull);
expect(result.actions, [
@ -912,13 +905,6 @@ void main() {
expect(result.actions, [
const IOSSoftKeyboardInputAction.inputText('什么'),
]);
result = session.diff('111什么清苦ang');
expect(result.nextValue, '111什么清苦');
expect(result.nextComposingValue, 'ang');
expect(result.actions, [
const IOSSoftKeyboardInputAction.inputText('清苦'),
]);
});
test('sends partial pinyin commit when remaining spelling is composing',