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

Trigger mimerender extension from another extension #7982

Open
aliasmrchips opened this issue Mar 4, 2020 · 11 comments
Open

Trigger mimerender extension from another extension #7982

aliasmrchips opened this issue Mar 4, 2020 · 11 comments

Comments

@aliasmrchips
Copy link

I made a mimerender extension and I am able to trigger the extension by opening a file from the file browser. I can also trigger the extension in the output cell of a notebook by using IPython.display({my_mimetype: data}, raw=True). I would like to do "the same thing" but using javascript (i.e., from within another extension). So, I would make the data object locally and then call something, trigger an event, generate a message or send a signal that would do the equivalent of IPython.display.

In other words, let's say I have two extensions; foo and bar. The "foo" extension will render objects of type "foo" and the "bar" extension will render objects of type "bar".

example.foo.json

{
    "key": "value",
    "index": 0
}

example.bar.json

{
    "index": 0
}

Note that the "bar" mimetype is actually a subset of the "foo" mimetype. So, I can open .foo.json and .bar.json files and they will be rendered (in separate tabs) by their respective extensions. So far, so good.

However, since all the data required to render a "bar" type document is included in a "foo" type document, I would like to include that capability in the "foo" extension. So, the sequence of events would be: 1) Open the "foo" document with the "foo" extension. 2) Do something within the "foo" extension (click on a link or a button or something) that will result in 3) the "bar" extension rendering the "bar" portion of the original "foo" document (again in a separate jlab tab).

I am not sure what the correct mechanism to do this is. My inclination is to have the "foo" extension generate a message or emit a signal (similar to what the filebrowser must be doing), but have been so far unsuccessful.

@jasongrout
Copy link
Contributor

For reference: this question started in a conversation on Gitter [1, 2].

@jasongrout
Copy link
Contributor

  1. Open the "foo" document with the "foo" extension. 2) Do something within the "foo" extension (click on a link or a button or something) that will result in 3) the "bar" extension rendering the "bar" portion of the original "foo" document (again in a separate jlab tab).

So in the end, you want two tabs, one with the foo rendering, and one with the bar rendering? Or do you want the bar rendering inside the foo tab?

@aliasmrchips
Copy link
Author

Separate tabs. As if, I had opened two files with the file browser.

@jasongrout
Copy link
Contributor

So it sounds like the suggestions on gitter are appropriate:

Look at how the rendermime registry is used in JupyterLab:

const mimeType = this._rendermime.preferredMimeType(options.bundle, 'any');
if (!mimeType) {
return;
}
this._content = this._rendermime.createRenderer(mimeType);
void this._content.renderModel(model);
this._content.addClass(CONTENT_CLASS);
layout.addWidget(this._content);

const mimeType = this._rendermime.preferredMimeType(data);
if (mimeType) {
const widget = this._rendermime.createRenderer(mimeType);
const model = new MimeModel({ data });
void widget.renderModel(model);
update.content = widget;
}

let mimeType = this.rendermime.preferredMimeType(

Take one of those as an example for:

  1. Create a bundle of data
  2. Ask the registry for a renderer for that mimetype
  3. Create a new MainAreaWidget with that renderer as the content
  4. Add that MainAreaWidget to the dock panel.

@aliasmrchips
Copy link
Author

Ok, I think I get it now. For steps 3) and 4), I assume I would do something like in the tutorial?https://github.com/jupyterlab/jupyterlab/blob/master/docs/source/developer/extension_tutorial.rst

Is there an "app" instance I can access from within a mimerender extension?

@jasongrout
Copy link
Contributor

You are going to have to make a normal extension for this.

@aliasmrchips
Copy link
Author

What handles this (creating a new MainAreaWidget) normally? For example, when you open a file in the file browser? The FileBrowser extension or something else?

@jasongrout
Copy link
Contributor

Whoever wants to create a widget. See the astronomy picture of the day tutorial in the docs, for example.

@aliasmrchips
Copy link
Author

Ok, two more questions:

  1. Is there an example of making a mimerender extension from a normal extension?
  2. Is there an example of lumino signals/messaging?

@saulshanabrook
Copy link
Member

@aliasmrchips

Is there an example of making a mimerender extension from a normal extension?

Here is an example of adding a rendermime widget but that won't add the file handling part.

Is there an example of lumino signals/messaging?

Tons!

Here is one I just made up

import { Signal, ISignal } from '@lumino/signaling';


type SENDER = string;
type VALUE = number;
const s = new Signal<SENDER, VALUE>("sender");


const si: ISignal<SENDER, VALUE> = s;
// I can't emit on the ISignal only on the concrete
// this lets us protect emission and only provide the ability to connect

function slot(sender: SENDER, args: VALUE) {
  console.assert(sender === "sender")
  console.assert(args === 123)
}
// Connect a function to be called on each emmission
si.connect(slot);

// Emit some value. all connected "slots" (callbacks) will be called
s.emit(123)

// disconnect your slot when you are done.
si.disconnect(slot)

@aliasmrchips
Copy link
Author

Trying the signaling example, I get this error:

Screen Shot 2020-03-04 at 11 05 31 AM

I have split the code between two extensions with the "emit" in one and the "slot" connect in the other. Any ideas?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants