diff --git a/page/client.ts b/page/client.ts index f23a17b..c19820e 100644 --- a/page/client.ts +++ b/page/client.ts @@ -209,3 +209,45 @@ export function redrawPreeditUnderline() { export function hasPreedit() { return !!preedit } + +export function deleteSurroundingText(offset: number, size: number) { + const input = getInputElement() + if (!input) { + return + } + + const text = input.value + const jsCursor = input.selectionStart! + const chars = [...text] + + let charCursor = 0 + let currentJsIndex = 0 + for (const char of chars) { + if (currentJsIndex >= jsCursor) { + break + } + currentJsIndex += char.length + charCursor++ + } + + const startCharIndex = charCursor + offset + const endCharIndex = startCharIndex + size + + if (startCharIndex < 0 || endCharIndex > chars.length || startCharIndex >= endCharIndex) { + return + } + + let startJsIndex = 0 + for (let i = 0; i < startCharIndex; i++) { + startJsIndex += chars[i].length + } + let endJsIndex = startJsIndex + for (let i = startCharIndex; i < endCharIndex; i++) { + endJsIndex += chars[i].length + } + + input.setRangeText('', startJsIndex, endJsIndex, 'end') + input.dispatchEvent(new Event('change')) + input.dispatchEvent(new Event('input')) + onTextChange(input.value) +} diff --git a/page/index.ts b/page/index.ts index 81fc6f9..76a462a 100644 --- a/page/index.ts +++ b/page/index.ts @@ -2,7 +2,7 @@ import type { Input } from './focus' import UZIP from 'uzip' import { activateMenuAction, getMenuActions } from './action' import { cli } from './cli' -import { commit, placePanel, setPreedit } from './client' +import { commit, deleteSurroundingText, placePanel, setPreedit } from './client' import { getAddons, getConfig, setConfig } from './config' import { OPTIONS, SERVICE_WORKER, WEB, WEB_WORKER } from './constant' import { hasTouch, isFirefox } from './context' @@ -72,6 +72,7 @@ globalThis.fcitx = Object.assign((...args: any[]) => { invoke: (name: string, args: string) => fcitx[name](...JSON.parse(args)), setPreedit, commit, + deleteSurroundingText, sendEventToKeyboard, getLanguageName, setCurrentInputMethod, diff --git a/wasmfrontend/wasmfrontend.cpp b/wasmfrontend/wasmfrontend.cpp index 4749d3a..2436be0 100644 --- a/wasmfrontend/wasmfrontend.cpp +++ b/wasmfrontend/wasmfrontend.cpp @@ -60,6 +60,11 @@ WasmInputContext::WasmInputContext(WasmFrontend *frontend, WasmInputContext::~WasmInputContext() { destroy(); } +void WasmInputContext::deleteSurroundingTextImpl(int offset, + unsigned int size) { + EM_ASM(fcitx.deleteSurroundingText($0, $1), offset, size); +} + void WasmInputContext::commitStringImpl(const std::string &text) { EM_ASM(fcitx.commit(UTF8ToString($0)), text.c_str()); } diff --git a/wasmfrontend/wasmfrontend.h b/wasmfrontend/wasmfrontend.h index e9d2752..5559cb4 100644 --- a/wasmfrontend/wasmfrontend.h +++ b/wasmfrontend/wasmfrontend.h @@ -51,7 +51,7 @@ class WasmInputContext : public InputContext { const char *frontend() const override { return "wasm"; } void commitStringImpl(const std::string &text) override; - void deleteSurroundingTextImpl(int offset, unsigned int size) override {} + void deleteSurroundingTextImpl(int offset, unsigned int size) override; void forwardKeyImpl(const ForwardKeyEvent &key) override {} void updatePreeditImpl() override;