diff --git a/shell/platform/ohos/flutter_embedding/application/src/ohosTest/ets/test/plugin/editing/ListenableEditingState.test.ets b/shell/platform/ohos/flutter_embedding/application/src/ohosTest/ets/test/plugin/editing/ListenableEditingState.test.ets index fa1d6a164172b22ecafba7ed7ecb68f06dde5aaf..1a0c51c5b003f097dced18372731c043e59369c8 100644 --- a/shell/platform/ohos/flutter_embedding/application/src/ohosTest/ets/test/plugin/editing/ListenableEditingState.test.ets +++ b/shell/platform/ohos/flutter_embedding/application/src/ohosTest/ets/test/plugin/editing/ListenableEditingState.test.ets @@ -18,6 +18,13 @@ export default function ListenableEditingStateTest() { expect(editingState.getSelectionStart()).assertEqual(5); expect(editingState.getSelectionEnd()).assertEqual(5); }) + + it('should handle delete event correctly (right)', 0, () => { + editingState.handleDeleteEvent(true, 1); + expect(editingState.getStringCache()).assertEqual('hello'); + expect(editingState.getSelectionStart()).assertEqual(5); + expect(editingState.getSelectionEnd()).assertEqual(5); + }) it('should handle newline event correctly', 0, () => { editingState.handleNewlineEvent(); expect(editingState.getStringCache()).assertEqual('hello\n'); diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/ListenableEditingState.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/ListenableEditingState.ets index 690fdff3a427a874969e75bfc252697f57714405..1d4e82adce38586009dc2668736ec87ff60eec9a 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/ListenableEditingState.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/ListenableEditingState.ets @@ -247,6 +247,58 @@ export class ListenableEditingState { } } + handleDeleteEvent(leftOrRight: boolean, length: number): void { + if (length === 0) { + return; + } + + let start = + this.mSelectionStartCache < this.mSelectionEndCache ? this.mSelectionStartCache : this.mSelectionEndCache; + let end = this.mSelectionStartCache > this.mSelectionEndCache ? this.mSelectionStartCache : this.mSelectionEndCache; + + if (leftOrRight == false) { + //delete left + if (start == 0 && end == 0) { + return; + } + + let unicodeStart = start; + if (start == end) { + for (let i = 0; i < length; i++) { + unicodeStart = FlutterTextUtils.getOffsetBefore(this.mStringCache, unicodeStart); + if (unicodeStart === 0) { + break; + } + } + } + this.replace(unicodeStart, end, "", 0, 0); + this.mSelectionStartCache = unicodeStart; + let tempStr: string = this.mStringCache.slice(0, unicodeStart) + this.mStringCache.slice(end); + this.mStringCache = tempStr; + this.mSelectionEndCache = this.mSelectionStartCache; + } else if (leftOrRight == true) { + //delete right + if (start == this.mStringCache.length) { + return; + } + let unicodeEnd = end; + if (start == end) { + for (let i = 0; i < length; i++) { + unicodeEnd = FlutterTextUtils.getOffsetAfter(this.mStringCache, unicodeEnd); + if (unicodeEnd === this.mStringCache.length) { + break; + } + } + } + this.replace(start, unicodeEnd, "", 0, 0); + this.mSelectionEndCache = start; + let tempStr: string = this.mStringCache.slice(0, start) + (unicodeEnd >= this.mStringCache.length ? "" : this.mStringCache.slice(unicodeEnd)); + this.mStringCache = tempStr; + this.mSelectionStartCache = this.mSelectionEndCache; + } + this.notifyListenersIfNeeded(true, true, false); + } + handleNewlineEvent(): void { // 获取光标所在位置; // 当光标移动前位置小于移动后的位置时,获取光标移动前位置;反之获取移动后位置 diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/TextInputPlugin.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/TextInputPlugin.ets index 4509d270ba24c4356310a177f5ab4b30bf24b81e..8692e4ee2ab2b441609faf8b52b224b7b90178e5 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/TextInputPlugin.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/TextInputPlugin.ets @@ -253,6 +253,22 @@ class TextInputMethodHandlerImpl implements TextInputMethodHandler { return; } + try { + this.inputMethodController.on('deleteLeft', this.deleteLeftCallback) + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe deleteLeft:" + JSON.stringify(err)); + this.cancelListenKeyBoardEvent(); + return; + } + + try { + this.inputMethodController.on('deleteRight', this.deleteRightCallback) + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe deleteRight:" + JSON.stringify(err)); + this.cancelListenKeyBoardEvent(); + return; + } + try { this.inputMethodController.on('sendFunctionKey', this.sendFunctionKeyCallback) } catch (err) { @@ -285,6 +301,14 @@ class TextInputMethodHandlerImpl implements TextInputMethodHandler { this.mEditable.handleInsertTextEvent(text); } + private deleteLeftCallback = (length: number) => { + this.mEditable.handleDeleteEvent(false, length); + } + + private deleteRightCallback = (length: number) => { + this.mEditable.handleDeleteEvent(true, length); + } + private sendFunctionKeyCallback = (functionKey: inputMethod.FunctionKey) => { /// 临时规避缺少newline对应枚举类型问题 if (functionKey.enterKeyType == NEWLINE_KEY_TYPE) { @@ -303,6 +327,8 @@ class TextInputMethodHandlerImpl implements TextInputMethodHandler { cancelListenKeyBoardEvent(): void { this.inputMethodController?.off('insertText', this.insertTextCallback); + this.inputMethodController?.off('deleteLeft', this.deleteLeftCallback); + this.inputMethodController?.off('deleteRight', this.deleteRightCallback); this.inputMethodController?.off('sendFunctionKey', this.sendFunctionKeyCallback); this.inputMethodController?.off('sendKeyboardStatus', this.sendKeyboardStatusCallback); this.inputMethodController?.off('selectByRange', this.selectByRangeCallback);