Skip to content

iOS Safari tap jumps to wrong place when tap lands on a line padding #1639

@lishid

Description

@lishid

Describe the issue

So I have a 2-in-1 combo here:

  1. When a cm-line has top padding, tapping on the top padding causes Safari to set the selection to be at the the first text character in the line, rather than the character closest to the tap. Chrome is smart enough to do the right thing. Unfortunately I think this may need a kludge since I can't seem to get Safari to behave more like Chrome.
  2. When the editor loses focus, and a tap triggers the bug above, if the first character of the line happens to be on a widget (even if the widget is explicitly contenteditable=false!!), the editor completely ignores the selection and resumes the last selection. This happens because the tap triggers focus and selectionchange; focus sets a 10ms timer, and selectionchange catches the selection to be within the widget, which has ignoreEvent returning true, causing the selection to be ignored; subsequently the focus timeout fires and resets the selection to the editor's last know position.

The repro link below sets up a widget at the beginning of the first line, and a CSS style for an exaggerated top padding for cm-view for ease of reproduction. (In our production app, the padding is 1-2px, so the reproduction is seemingly random depending on whether the fat finger hit the 2-4px zone or not)

As demonstrated in the video below from the repro link:
0-5s: Put the cursor at the end of the document (initial setup).
6-9s: Tap on the top padding of line 1 (with the widget at the beginning of line). Notice the cursor is still at the end of the document (bug 2).
10-12s: Tap on the top padding of line 2 (without the widget at the beginning of line). Notice the cursor has been moved to the beginning of line 2 (bug 1).
12s-15s: Repeat with line 1, notice cursor is still at line 2 (bug 2).

ScreenRecording_11-14-2025_22-44-00_1.mov

Browser and platform

iOS 18/26 Safari

Reproduction link

https://codemirror.net/try/#c=aW1wb3J0IHtXaWRnZXRUeXBlLCBEZWNvcmF0aW9uLCBFZGl0b3JWaWV3fSBmcm9tICJAY29kZW1pcnJvci92aWV3IgppbXBvcnQge1N0YXRlRmllbGR9IGZyb20gIkBjb2RlbWlycm9yL3N0YXRlIgpjbGFzcyBUZXN0V2lkZ2V0IGV4dGVuZHMgV2lkZ2V0VHlwZSB7CiAgdG9ET00oKSB7CiAgICBsZXQgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7CiAgICBlbC5pbm5lclRleHQgPSAnXHUyMDBCJzsKICAgIHJldHVybiBlbDsKICB9Cn0KbmV3IEVkaXRvclZpZXcoewogIGRvYzogImNvbnNvbGUubG9nKCdoZWxsbycpXG4iLnJlcGVhdCg1KSwKICBleHRlbnNpb25zOiBbU3RhdGVGaWVsZC5kZWZpbmUoewogICAgY3JlYXRlKCkgeyAKICAgICAgcmV0dXJuIERlY29yYXRpb24uc2V0KFsKICAgICAgICBEZWNvcmF0aW9uLndpZGdldCh7d2lkZ2V0OiBuZXcgVGVzdFdpZGdldCgpLCBibG9jazogZmFsc2V9KS5yYW5nZSgwLCAwKQogICAgICBdKTsKICAgIH0sCiAgICB1cGRhdGUoZGVjb3MsIHRyKSB7CiAgICAgIHJldHVybiBkZWNvczsKICAgIH0sCiAgICBwcm92aWRlOiBmID0+IEVkaXRvclZpZXcuZGVjb3JhdGlvbnMuZnJvbShmKQogIH0pLCBFZGl0b3JWaWV3LnRoZW1lKHsgIi5jbS1saW5lIjogeyBwYWRkaW5nVG9wOiAiMzBweCIgfX0pXSwKICBwYXJlbnQ6IGRvY3VtZW50LmJvZHkKfSkK

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions