Case ce-0214-ime-insertfromcomposition-targetranges-desktop-safari-korean · Scenario scenario-ime-insertfromcomposition-targetranges

insertFromComposition targetRanges should be trusted even when collapsed in Desktop Safari

OS: macOS 14.0+ Device: Desktop or Laptop Any Browser: Safari 17.0+ Keyboard: Korean (IME) Status: draft
composition ime beforeinput insertFromComposition targetRanges desktop safari korean

Phenomenon

In Desktop Safari with Korean IME, insertFromComposition fires with targetRanges that may be collapsed but accurately represent the insertion point. Recalculating ranges based on current selection causes incorrect positioning. The targetRanges should be trusted as-is, even when collapsed.

Reproduction example

  1. Focus a contenteditable element in Desktop Safari (macOS).
  2. Activate Korean IME.
  3. Start composing Korean text (e.g., type “ㅎ” then “ㅏ” then “ㄴ” to compose “한”).
  4. Continue typing to update composition (e.g., type “ㄱ” then “ㅡ” then “ㄹ” to update to “한글”).
  5. Observe beforeinput events with inputType: 'insertFromComposition'.
  6. Check getTargetRanges() - they may be collapsed but represent the correct insertion point.
  7. If handlers recalculate ranges based on current selection, text will be inserted at wrong position.

Observed behavior

When updating Korean composition text:

  1. beforeinput event:

    • inputType: 'insertFromComposition'
    • isComposing: true
    • data: '한글' (the new composition text)
    • getTargetRanges() returns ranges that may be collapsed (startOffset === endOffset)
    • The collapsed ranges accurately represent where the composition text should be inserted
  2. If ranges are recalculated:

    • Handlers that recalculate based on window.getSelection() get incorrect position
    • Text may be inserted at wrong location (e.g., duplicated or misplaced)
    • Composition text may appear in unexpected positions
  3. If ranges are trusted as-is:

    • Text is inserted at correct position
    • Composition updates work correctly
    • No positioning issues occur

Expected behavior

  • targetRanges from insertFromComposition should be trusted as-is, even when collapsed
  • Recalculating ranges based on current selection should NOT be necessary
  • The collapsed targetRanges accurately represent the insertion point
  • Handlers should use targetRanges directly without modification

Impact

  • Incorrect positioning: Handlers that recalculate collapsed targetRanges will insert text at wrong positions
  • Duplicated text: Text may be inserted multiple times or in wrong locations
  • Composition breakage: Composition updates may fail or produce incorrect results
  • Platform-specific bugs: Code that works on other browsers may fail on Desktop Safari

Browser Comparison

  • Desktop Safari: insertFromComposition fires with accurate collapsed targetRanges (trust as-is)
  • iOS Safari (Japanese/Kanji): insertFromComposition fires with collapsed targetRanges that need recalculation
  • iOS Safari (Korean): insertFromComposition does NOT fire
  • Chrome/Edge: Generally uses insertCompositionText instead of insertFromComposition
  • Firefox: Behavior varies but generally more consistent with Chrome

Notes and possible direction for workarounds

  • Trust targetRanges as-is: Do not recalculate collapsed targetRanges in Desktop Safari:

    element.addEventListener('beforeinput', (e) => {
      if (e.inputType === 'insertFromComposition') {
        const targetRanges = e.getTargetRanges?.() || [];
        if (targetRanges.length > 0) {
          // Trust targetRanges even if collapsed
          // Do NOT recalculate based on current selection
          const range = targetRanges[0];
          // Use range.startContainer and range.startOffset directly
          handleCompositionInsertion(range);
        }
      }
    });
  • Platform detection: Detect Desktop Safari vs iOS Safari to apply correct strategy:

    const isDesktopSafari = /Macintosh/.test(navigator.userAgent) && /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent);
    
    if (isDesktopSafari && e.inputType === 'insertFromComposition') {
      // Trust targetRanges as-is
    }
  • Avoid selection-based recalculation: Do not use window.getSelection() to recalculate ranges in Desktop Safari

Before

Hello

Korean composition in progress
After (Bug - recalculated)

Hello 한글

If ranges are recalculated, text is inserted at wrong position
vs
✅ Expected (trust targetRanges)

Hello 한글

Trusting targetRanges as-is produces correct positioning

Browser compatibility matrix

This matrix shows which browser and OS combinations have documented cases for this scenario. The current case is highlighted. Click on a cell to view other cases.

Current case
Confirmed
Draft
No case documented

All variants (detailed table)

Complete list of all cases for this scenario with full environment details.

Case OS Device Browser Keyboard Status
ce-0214-ime-insertfromcomposition-targetranges-desktop-safari-korean macOS 14.0+ Desktop or Laptop Any Safari 17.0+ Korean (IME) draft
ce-0215-ime-insertfromcomposition-targetranges-ios-safari-japanese iOS 17.0+ iPhone or iPad Any Safari 17.0+ Japanese (IME) draft
ce-0216-ime-insertfromcomposition-missing-ios-safari-korean iOS 17.0+ iPhone or iPad Any Safari 17.0+ Korean (IME) draft

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: Korean (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.

Comments & Discussion

Have questions, suggestions, or want to share your experience? Join the discussion below.