fix(desktop): keep the hint off the text during IME composition
Input events are deliberately skipped for the duration of an IME composition (they carry uncommitted preedit text), so nothing clears the empty marker until compositionend — the hint kept painting behind the hiragana the user was composing. Drop the marker as composition starts; the normalizer restores it if composition ends with nothing committed. Taking the hint out of the text flow fixed the displacement half of #75960 on its own — preedit now starts at the field's left edge either way — but the overlap needed this too. Co-authored-by: Ryuichi Natori <to-na@users.noreply.github.com>
This commit is contained in:
parent
414e5af114
commit
93ec02bf79
|
|
@ -1,6 +1,7 @@
|
|||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import {
|
||||
beginComposerComposition,
|
||||
composerPlainText,
|
||||
deleteChipBeforeCaret,
|
||||
normalizeComposerEditorDom,
|
||||
|
|
@ -159,6 +160,26 @@ describe('an emptied composer shows its placeholder again', () => {
|
|||
|
||||
expect(el.matches(PLACEHOLDER_SHOWS)).toBe(false)
|
||||
})
|
||||
|
||||
// Input events are skipped for the duration of an IME composition, so nothing
|
||||
// else clears the marker until it ends — the hint would sit behind the
|
||||
// hiragana the user is composing (#75960).
|
||||
it('hides the placeholder before IME preedit text starts', () => {
|
||||
const el = emptied()
|
||||
|
||||
beginComposerComposition(el)
|
||||
|
||||
expect(el.matches(PLACEHOLDER_SHOWS)).toBe(false)
|
||||
})
|
||||
|
||||
it('brings the placeholder back when composition ends with nothing committed', () => {
|
||||
const el = emptied()
|
||||
|
||||
beginComposerComposition(el)
|
||||
normalizeComposerEditorDom(el)
|
||||
|
||||
expect(el.matches(PLACEHOLDER_SHOWS)).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
/** A directive chip, as `refChipElement` builds it. */
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ import { ActionBadges } from './micro-actions'
|
|||
import { chipTypedPathOnSpace, pathifyRefs } from './path-refs'
|
||||
import { QueuePanel } from './queue-panel'
|
||||
import {
|
||||
beginComposerComposition,
|
||||
composerPlainText,
|
||||
deleteChipBeforeCaret,
|
||||
deleteSelectionInEditor,
|
||||
|
|
@ -967,8 +968,13 @@ export function ChatBar({
|
|||
// until an unrelated edit forces a sync (#39614).
|
||||
flushEditorToDraft(event.currentTarget)
|
||||
}}
|
||||
onCompositionStart={() => {
|
||||
onCompositionStart={event => {
|
||||
composingRef.current = true
|
||||
|
||||
// Input events are skipped for the rest of the composition, so
|
||||
// nothing else would clear the empty marker until it ends — and the
|
||||
// hint would sit behind the preedit text the whole time (#75960).
|
||||
beginComposerComposition(event.currentTarget)
|
||||
}}
|
||||
onDragOver={handleInputDragOver}
|
||||
onDrop={handleInputDrop}
|
||||
|
|
|
|||
|
|
@ -71,6 +71,17 @@ export function markEditorEmptiness(editor: HTMLElement) {
|
|||
}
|
||||
}
|
||||
|
||||
/** Drop the marker as IME composition starts, before any preedit text lands.
|
||||
*
|
||||
* Input events during composition are deliberately skipped (they carry
|
||||
* uncommitted preedit text), so nothing else clears the marker until
|
||||
* `compositionend` — and the hint would otherwise sit behind the hiragana the
|
||||
* user is composing. `normalizeComposerEditorDom` restores it if composition
|
||||
* ends with nothing committed. */
|
||||
export function beginComposerComposition(editor: HTMLElement) {
|
||||
delete editor.dataset.empty
|
||||
}
|
||||
|
||||
/** @see referenceRe — the shared pattern every surface recognises a reference
|
||||
* with. Module-level `/g` regexes carry `lastIndex`, so call sites reset it. */
|
||||
export const REF_RE = referenceRe()
|
||||
|
|
|
|||
Loading…
Reference in New Issue