케이스 ce-0558-insertparagraph-preventdefault-composition-broken-safari-japanese-ko · 시나리오 scenario-insertparagraph-preventdefault-composition-broken

insertParagraph preventDefault가 Safari에서 일본어 IME 조합을 깨뜨림

OS: macOS 14.0+ 기기: Desktop or Laptop Any 브라우저: Safari 17.0+ 키보드: Japanese (IME) 초안
safarimacosinsertparagraphpreventdefaultjapaneseimecompositionkeydownbeforeinputinput-event

현상

macOS의 Safari 데스크톱에서 insertParagraph(Enter 키)에 대해 keydown 또는 beforeinput 이벤트에서 preventDefault()를 호출하면 일본어 IME 조합 상태가 손상됩니다. 이 문제가 발생한 후, 후속 일본어 텍스트 입력이 제대로 작동하지 않습니다. input 이벤트가 제대로 발생하지 않거나, 일본어 문자가 삽입되지 않거나, 조합 상태가 일관되지 않은 상태로 남을 수 있습니다.

재현 예제

  1. contenteditable div를 생성하고 포커스를 설정합니다.
  2. Enter가 눌리거나 inputType === "insertParagraph"일 때 e.preventDefault()를 호출하는 keydown 및/또는 beforeinput 이벤트 리스너를 추가합니다.
  3. IME를 사용하여 일본어 텍스트를 입력합니다(예: “こんにちは”).
  4. Enter 키를 누릅니다.
  5. preventDefault()가 단락 삽입을 성공적으로 막는 것을 확인합니다.
  6. 더 많은 일본어 텍스트를 입력하려고 시도합니다(예: “ありがとう”).
  7. 일본어 문자가 삽입되지 않거나 input 이벤트가 제대로 발생하지 않는 것을 확인합니다.

관찰된 동작

  • insertParagraph에서 preventDefault(): keydown 또는 beforeinput에서 호출되면 단락 삽입을 성공적으로 막습니다.
  • 후속 IME 입력 실패: insertParagraph를 막은 후 일본어 IME 입력이 작동하지 않습니다.
  • input 이벤트 누락: 후속 일본어 텍스트 입력에 대해 input 이벤트가 발생하지 않을 수 있습니다.
  • 조합 이벤트: compositionstart, compositionupdate, compositionend가 제대로 발생하지 않을 수 있습니다.
  • 문자 삽입 실패: 입력한 일본어 문자가 contenteditable 요소에 나타나지 않습니다.
  • IME 상태 손상: IME 조합 상태가 일관되지 않게 되며 요소를 blur하고 refocus하지 않고는 복구할 수 없습니다.

예상 동작

  • preventDefault()는 IME 조합 상태에 영향을 주지 않고 단락 삽입을 막아야 합니다.
  • insertParagraph를 막은 후 후속 일본어 IME 입력이 정상적으로 계속 작동해야 합니다.
  • 이전에 insertParagraph가 막혔는지 여부와 관계없이 모든 IME 입력에 대해 input 이벤트가 올바르게 발생해야 합니다.
  • IME 조합 상태가 일관되고 기능적으로 유지되어야 합니다.

분석

이 문제는 insertParagraph를 막을 때 Safari의 내부 IME 조합 상태 관리가 손상되기 때문에 발생합니다. 포맷팅 래퍼나 빈 노드가 있을 때 특히 Enter를 누르면 단락 삽입과 조합 상태 전환 간의 브라우저 조정이 방해받아 IME가 일관되지 않은 상태로 남게 됩니다.

Input Events Level 2 사양에 따르면 조합 관련 입력 이벤트는 취소할 수 없지만, insertParagraph를 취소하면 조합 생명주기에 간섭할 수 있으며, 특히 IME 조합 중 또는 조합 후 Enter를 누를 때 그렇습니다.

해결 방법

막기 전에 isComposing 확인

조합 중이 아닐 때만 insertParagraph를 막기:

editor.addEventListener('beforeinput', (e) => {
  if (e.inputType === 'insertParagraph' && !e.isComposing) {
    e.preventDefault();
    // 사용자 정의 단락 삽입 로직
  }
});

조합 확인과 함께 keydown에서 Enter 처리

editor.addEventListener('keydown', (e) => {
  if (e.key === 'Enter' && !e.isComposing) {
    e.preventDefault();
    // 사용자 정의 단락 삽입
  }
});

손상된 경우 IME 상태 리셋

조합 상태가 이미 손상된 경우 요소를 blur하고 refocus:

function resetIMEState(editor) {
  editor.blur();
  setTimeout(() => {
    editor.focus();
  }, 0);
}

브라우저 비교

  • Safari (데스크톱 macOS): 이 문제가 발생합니다. insertParagraph를 막으면 후속 일본어 IME 입력이 깨집니다.
  • Chrome: 확인 필요
  • Firefox: 확인 필요
  • Edge: 확인 필요

이 시나리오의 변형

Playground for this case

Use the reported environment as a reference and record what happens in your environment while interacting with the editable area.

Reported environment
OS: macOS 14.0+
Device: Desktop or Laptop Any
Browser: Safari 17.0+
Keyboard: Japanese (IME)
Your environment
Sample HTML:
Event log
Use this log together with the case description when filing or updating an issue.
0 events
Interact with the editable area to see events here.