🐛 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 router from './router';
|
||||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
|
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
|
||||||
import { registerDirectives } from './directives';
|
import { registerDirectives } from './directives';
|
||||||
|
import {EditorView} from "@codemirror/view";
|
||||||
|
|
||||||
|
(EditorView as any).EDIT_CONTEXT = false;
|
||||||
|
|
||||||
const pinia = createPinia();
|
const pinia = createPinia();
|
||||||
pinia.use(piniaPluginPersistedstate);
|
pinia.use(piniaPluginPersistedstate);
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export function createCursorPositionExtension(documentId: number) {
|
|||||||
constructor(private view: EditorView) {
|
constructor(private view: EditorView) {
|
||||||
const {debouncedFn, flush} = createDebounce(
|
const {debouncedFn, flush} = createDebounce(
|
||||||
() => this.saveCursorPosition(),
|
() => this.saveCursorPosition(),
|
||||||
{delay: 400}
|
{delay: 1000}
|
||||||
);
|
);
|
||||||
this.debouncedSave = {fn: debouncedFn, flush};
|
this.debouncedSave = {fn: debouncedFn, flush};
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,14 @@ import { StateField, RangeSetBuilder, EditorState, Transaction } from "@codemirr
|
|||||||
import { blockState } from "./state";
|
import { blockState } from "./state";
|
||||||
import { codeBlockEvent, USER_EVENTS } from "./annotation";
|
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 来确保选择不会在第一个块之前
|
* 使用 transactionFilter 来确保选择不会在第一个块之前
|
||||||
|
*
|
||||||
|
* IME:在输入法组合输入期间(compositionstart ~ compositionend),
|
||||||
|
* 暂时禁用选区矫正,避免与 IME 选区管理冲突导致光标跳转
|
||||||
*/
|
*/
|
||||||
const preventSelectionBeforeFirstBlock = EditorState.transactionFilter.of((tr: any) => {
|
const preventSelectionBeforeFirstBlock = EditorState.transactionFilter.of((tr: any) => {
|
||||||
|
// IME 组合输入期间不矫正选区
|
||||||
|
if (isComposing) {
|
||||||
|
return tr;
|
||||||
|
}
|
||||||
|
|
||||||
if (tr.annotation(codeBlockEvent)) {
|
if (tr.annotation(codeBlockEvent)) {
|
||||||
return tr;
|
return tr;
|
||||||
}
|
}
|
||||||
@@ -256,6 +272,34 @@ const preventSelectionBeforeFirstBlock = EditorState.transactionFilter.of((tr: a
|
|||||||
return tr;
|
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,
|
atomicNoteBlock,
|
||||||
preventFirstBlockFromBeingDeleted,
|
preventFirstBlockFromBeingDeleted,
|
||||||
preventSelectionBeforeFirstBlock,
|
preventSelectionBeforeFirstBlock,
|
||||||
|
imeListener, // IME 状态监听器
|
||||||
];
|
];
|
||||||
|
|
||||||
if (showBackground) {
|
if (showBackground) {
|
||||||
|
|||||||
Reference in New Issue
Block a user