🐛 Resolved a selection conflict issue during IME input method combination input
This commit is contained in:
@@ -6,6 +6,9 @@ import i18n from './i18n';
|
||||
import router from './router';
|
||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
|
||||
import { registerDirectives } from './directives';
|
||||
import {EditorView} from "@codemirror/view";
|
||||
|
||||
(EditorView as any).EDIT_CONTEXT = false;
|
||||
|
||||
const pinia = createPinia();
|
||||
pinia.use(piniaPluginPersistedstate);
|
||||
|
||||
@@ -15,7 +15,7 @@ export function createCursorPositionExtension(documentId: number) {
|
||||
constructor(private view: EditorView) {
|
||||
const {debouncedFn, flush} = createDebounce(
|
||||
() => this.saveCursorPosition(),
|
||||
{delay: 400}
|
||||
{delay: 1000}
|
||||
);
|
||||
this.debouncedSave = {fn: debouncedFn, flush};
|
||||
|
||||
|
||||
@@ -7,6 +7,14 @@ import { StateField, RangeSetBuilder, EditorState, Transaction } from "@codemirr
|
||||
import { blockState } from "./state";
|
||||
import { codeBlockEvent, USER_EVENTS } from "./annotation";
|
||||
|
||||
/**
|
||||
* IME 输入状态追踪
|
||||
*
|
||||
* 注意:CodeMirror 有 view.composing 和 view.compositionStarted 内置状态,
|
||||
* 但 transactionFilter 中访问不到 view,所以需要用全局变量追踪
|
||||
*/
|
||||
let isComposing = false;
|
||||
|
||||
/**
|
||||
* 块开始装饰组件
|
||||
*/
|
||||
@@ -223,8 +231,16 @@ const preventFirstBlockFromBeingDeleted = EditorState.changeFilter.of((tr: any)
|
||||
/**
|
||||
* 防止选择在第一个块之前
|
||||
* 使用 transactionFilter 来确保选择不会在第一个块之前
|
||||
*
|
||||
* IME:在输入法组合输入期间(compositionstart ~ compositionend),
|
||||
* 暂时禁用选区矫正,避免与 IME 选区管理冲突导致光标跳转
|
||||
*/
|
||||
const preventSelectionBeforeFirstBlock = EditorState.transactionFilter.of((tr: any) => {
|
||||
// IME 组合输入期间不矫正选区
|
||||
if (isComposing) {
|
||||
return tr;
|
||||
}
|
||||
|
||||
if (tr.annotation(codeBlockEvent)) {
|
||||
return tr;
|
||||
}
|
||||
@@ -256,6 +272,34 @@ const preventSelectionBeforeFirstBlock = EditorState.transactionFilter.of((tr: a
|
||||
return tr;
|
||||
});
|
||||
|
||||
/**
|
||||
* IME 输入监听器
|
||||
* 监听 composition 事件更新 isComposing 状态,供 transactionFilter 使用
|
||||
*/
|
||||
const imeListener = ViewPlugin.fromClass(
|
||||
class {
|
||||
constructor(view: EditorView) {
|
||||
view.dom.addEventListener('compositionstart', this.handleCompositionStart);
|
||||
view.dom.addEventListener('compositionend', this.handleCompositionEnd);
|
||||
}
|
||||
|
||||
handleCompositionStart = () => {
|
||||
isComposing = true;
|
||||
};
|
||||
|
||||
handleCompositionEnd = () => {
|
||||
// 延迟重置状态,确保所有相关事务都已处理完毕
|
||||
setTimeout(() => {
|
||||
isComposing = false;
|
||||
}, 0);
|
||||
};
|
||||
|
||||
destroy() {
|
||||
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* 获取块装饰扩展 - 简化选项
|
||||
*/
|
||||
@@ -271,6 +315,7 @@ export function getBlockDecorationExtensions(options: {
|
||||
atomicNoteBlock,
|
||||
preventFirstBlockFromBeingDeleted,
|
||||
preventSelectionBeforeFirstBlock,
|
||||
imeListener, // IME 状态监听器
|
||||
];
|
||||
|
||||
if (showBackground) {
|
||||
|
||||
Reference in New Issue
Block a user