Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow native context menu to be shown for notebook cell in Chrome. #4720

Merged
merged 2 commits into from Jun 28, 2018

Conversation

@ian-r-rose
Copy link
Member

@ian-r-rose ian-r-rose commented Jun 13, 2018

Fixes #4718.

This is a consequence of the saga of #3554. To refresh people's memory: CodeMirror has some special context menu logic that differs depending on whether Firefox or Chrome is being used. That logic was causing some extremely subtle focusing problems for notebook cells that ate up several developer-days.

We ultimately fixed it with a somewhat-hackish solution of calling preventDefault on context menu events for notebook cells. This lets CodeMirror know that is should not handle the event itself. However, we inadvertently prevented native context menus for notebook cells (and only in Chrome).

This fix continues in the somewhat-hackish code path by allowing the context menu to continue un-cancelled if the shift key is pressed.

@jasongrout
Copy link
Contributor

@jasongrout jasongrout commented Jun 13, 2018

The code looks good to me.

@afshin
Copy link
Member

@afshin afshin commented Jun 20, 2018

I am not sure I understand all the edge cases, but does this achieve the same effect?

/**
 * Handle `contextmenu` event.
 */
private _evtContextMenuCapture(event: PointerEvent): void {
  if (event.shiftKey) {
    return;
  }

  // `event.target` sometimes gives an orphaned node in Firefox 57, which
  // can have `null` anywhere in its parent tree. If we fail to find a
  // cell using `event.target`, try again using a target reconstructed from
  // the position of the click event.
  let target = event.target as HTMLElement;
  let index = this._findCell(target);
  if (index === -1) {
    target = document.elementFromPoint(event.clientX, event.clientY) as HTMLElement;
    index = this._findCell(target);
  }
  let widget = this.widgets[index];

  if (widget && widget.editorWidget.node.contains(target)) {
    // Prevent CodeMirror from focusing the editor.
    // TODO: find an editor-agnostic solution.
    event.preventDefault();
  }
}

@afshin
Copy link
Member

@afshin afshin commented Jun 20, 2018

Because if we can save on doing some DOM traversal and bail early, it seems both clearer and more performant.

@ian-r-rose
Copy link
Member Author

@ian-r-rose ian-r-rose commented Jun 20, 2018

Yes, that would work as well, and I almost did that. I went for the version that I submitted because I wanted to do have as tight of a box around preventDefault as possible, but I don't have a strong opinion either way, and the result is the same.

@jasongrout jasongrout requested a review from afshin Jun 28, 2018
@jasongrout
Copy link
Contributor

@jasongrout jasongrout commented Jun 28, 2018

@afshin, can you review and merge when you're happy?

afshin
afshin approved these changes Jun 28, 2018
Copy link
Member

@afshin afshin left a comment

Cheers!
👍

@afshin afshin merged commit 4420b14 into jupyterlab:master Jun 28, 2018
2 checks passed
@ian-r-rose ian-r-rose mentioned this pull request Jul 20, 2018
@lock lock bot locked as resolved and limited conversation to collaborators Aug 8, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

3 participants