Calling JavaScript commands that depend on the context

Hello,
I’m working on a port of jupyterlab that runs on iPhones and iPads.

One of the issues is extending the on-screen keyboard so that users have access to most useful commands (cut, copy, paste, run cell…) (see picture: from left to right: undo, redo, tab, shift-tab, cut, copy, paste, up, down, execute cell).

The way I can do it easily is by calling JavaScript commands that get executed (I used --expose-app-in-browser). For example, the up button corresponds to:

            webView.evaluateJavaScript("window.jupyterapp.commands.execute('notebook:move-cursor-up');")

I’ve been able to do most of the commands I wanted to do using commands.execute. Now I’m left with commands where the action to be taken depends on the status of the notebook: the “tab” button can either indent code or call autocomplete, depending on whether there is some text to the left of it (same for shift-tab). “Cut” should either cut a cell (if we’re in command mode) or cut the text inside a cell (if we’re in edit mode). I know there is an internal variable that tells whether the notebook is in edit mode, but I cannot find a way to access it.

I have tried with window.jupyterapp.commands.processKeydownEvent(event); for tab, but it did not work.

I can’t really recommend relying on expose-app-in-browser. You’ll likely want to consider a custom postMessage API which you can reason about, and hopefully extend.

We’ve started thinking about this over on jupyterlite as well. This is likely not a feature that would land in full (retro)lab, as these kinds of integration can be rather fiddly, and vary depending on how secure you want them to be.

Thanks for the suggestion. I’ll keep in mind what you said about the postMessage API. In my case (admittedly very specific) javascript commands are a very easy route for communication between the App side and the Jupyterlab side.

To answer my own question (in case someone else has the same issue), the solution is to send the event to the activeElement:

document.activeElement.dispatchEvent(event);