Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 修复选中展开状态下的文字撤回和光标问题 #5782

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 19 additions & 17 deletions packages/core/src/text-area/event-handlers/composition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,17 @@
* @author wangfupeng
*/

import { Editor, Range, Element } from 'slate'
import { Editor, Range, Element, Transforms, Path } from 'slate'
import { IDomEditor } from '../../editor/interface'
import { DomEditor } from '../../editor/dom-editor'
import TextArea from '../TextArea'
import { hasEditableTarget } from '../helpers'
import { IS_SAFARI, IS_CHROME, IS_FIREFOX } from '../../utils/ua'
import { DOMNode } from '../../utils/dom'
import { hidePlaceholder } from '../place-holder'
import { editorSelectionToDOM } from '../syncSelection'

const EDITOR_TO_TEXT: WeakMap<IDomEditor, string> = new WeakMap()
const EDITOR_TO_START_CONTAINER: WeakMap<IDomEditor, DOMNode> = new WeakMap()
const EDITOR_TO_START_CONTAINER: WeakMap<IDomEditor, DOMNode | undefined> = new WeakMap()

/**
* composition start 事件
Expand All @@ -27,30 +26,30 @@ export function handleCompositionStart(e: Event, textarea: TextArea, editor: IDo

if (!hasEditableTarget(editor, event.target)) return

const { selection } = editor
const { selection } = editor;

if (selection && Range.isExpanded(selection)) {
Editor.deleteFragment(editor)

Promise.resolve().then(() => {
// deleteFragment 会在一个 Promise 后更新 dom,导致浏览器选区不正确
// 因此这里延迟一下再设置选区,使选区在正确位置
// 这里 model 选区没有发生变化,不能使用 editor.restoreSelection
// restoreSelection 会对比前后 model 选区是否相同,相同就不更新了
editorSelectionToDOM(textarea, editor, true)
})
Editor.deleteFragment(editor);
}

if (selection && Range.isCollapsed(selection)) {
EDITOR_TO_START_CONTAINER.set(editor, undefined);
// 跨dom的editor selection是无法计算出domNode的,为了防止报错加上边界
if (editor.selection && selection && Path.equals(selection.anchor.path, selection.focus.path)) {
// 记录下 dom text ,以便触发 maxLength 时使用
const domRange = DomEditor.toDOMRange(editor, selection)
const domRange = DomEditor.toDOMRange(editor, editor.selection)
const startContainer = domRange.startContainer
const curText = startContainer.textContent || ''
EDITOR_TO_TEXT.set(editor, curText)

// 记录下 dom range startContainer
EDITOR_TO_START_CONTAINER.set(editor, startContainer)
}
textarea.isComposing = true

// 折叠光标形式下,每次刷新是不用重新计算浏览器的selection的
if (selection && Range.isCollapsed(selection)) {
textarea.isComposing = true
}


// 隐藏 placeholder
hidePlaceholder(textarea, editor)
Expand Down Expand Up @@ -141,7 +140,10 @@ export function handleCompositionEnd(e: Event, textarea: TextArea, editor: IDomE
return
}
// 否则,拼音输入的开始和结束,不是同一个 text node ,则将第一个 text node 重新设置 text
oldStartContainer.textContent = EDITOR_TO_TEXT.get(editor) || ''
if (DomEditor.hasDOMNode(editor, oldStartContainer)) {
oldStartContainer.textContent = EDITOR_TO_TEXT.get(editor) || ''
}

})
}
}