jupyter / notebook

Jupyter Interactive Notebook
https://jupyter-notebook.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
11.75k stars 4.99k forks source link

Cell cursor position on iOS #2679

Open alexstaravoitau opened 7 years ago

alexstaravoitau commented 7 years ago

Issue

Currently cells in Jupyter Notebook have the following behaviour when running in iOS Safari or WKWebView:

  1. User taps on a code cell, say, on line 5.
  2. Cell becomes selected, cursor is set to line 5 and is blinking as expected.
  3. When user starts typing, cursor jumps to the end of the cell and any new characters get appended to the end of cell contents (not at the initial cursor position on line 5).

What's causing it

Please mind that I have little to no experience in web development, so only investigated far enough to come up with a workaround injection for a native iOS app I'm working on. After some experimenting turned out that what causes such behaviour is a call to CodeMirror's refresh() function in CodeCell.prototype.select callback in codecell.js (same for TextCell). This is what this callback looks like at the time of writing:

CodeCell.prototype.select = function () {
    var cont = Cell.prototype.select.apply(this, arguments);
    if (cont) {
        this.code_mirror.refresh(); // This line is causing the issue on iOS
        this.auto_highlight();
    }
    return cont;
};

In case it's going to help, this is the order of CodeMirror events being sent after user taps inside a code cell to start editing it:

[Log] touchstart
[Log] beforeSelectionChange // Reports that cursor position is about to change from (0, 0) 
                            // to where the user tapped.
[Log] cursorActivity        // Cursor position changed, `cm.getCursor()` returns correct 
                            // cursor position now.
[Log] refresh
[Log] update
[Log] focus
[Log] beforeSelectionChange // Reports that cursor position is about to change again.
[Log] cursorActivity        // Cursor position changed, `cm.getCursor()` returns end-of-cell 
                            // cursor position with `bad: true` flag set. Yet in the UI input 
                            // cursor is located at the old position.

Expected behaviour

Essentially this cursor position update should not happen. The text should appear exactly where the user tapped. This issue does not happen in CodeMirror inputs on other web pages, so there must be something in a way Jupyter Notebook is handling it.

viaregio commented 7 years ago

Probably this is also prohibiting a successful copy to the clipboard on iOS devices.