kotlin-playground icon indicating copy to clipboard operation
kotlin-playground copied to clipboard

feat/PR request: onOutputReady event

Open DavidScales opened this issue 4 years ago • 4 comments

I'm using Kotlin Playground in an iframe, and I need to expand the iframe size based on the height of the playground.

Right now I can update the iframe size with postMessage. I use the onChange event to check if the playground height has changed (from user's editing code) and update the iframe height accordingly.

When the code is compiled and output or exceptions are displayed in the output window, the output window expands to an arbitrary size. Right now I have no way of knowing when that's happened.

I can use the onConsoleOpen event to check when the console has been opened, but when an onConsoleOpen callback is defined, it's fired during the "waitingForOutput" stage:

this.update({
      waitingForOutput: true,
      openConsole: false
});
if (onOpenConsole) onOpenConsole(); //open when waitingForOutput=true

Which is before the actual output/exceptions have been returned, and thus before the final height of the console/output window have been set.

I'm willing to make a PR to create some kind of "onOutputReady" event, if you're open to the idea?

Or of you have a better approach, I'm open to that too. Thanks!

DavidScales avatar May 07 '20 23:05 DavidScales

For example in executable-fragment.js, when calling execute, adding something like

if (onOutputReady) onOutputReady();

Once output is returned from the compiling server seems to work:

WebDemoApi.executeKotlinCode(
        this.getCode(),
        compilerVersion,
        targetPlatform, args,
        theme,
        hiddenDependencies,
        onTestPassed,
        onTestFailed).then(
        state => {
          state.waitingForOutput = false;
          if (onOutputReady) onOutputReady(); // <---------------------
          if (state.output || state.exception) {
            state.openConsole = true;
          } else {
            if (onCloseConsole) onCloseConsole();
          }
          if ((state.errors.length > 0 || state.exception) && onError) onError();
          this.update(state);
        },
        () => this.update({waitingForOutput: false})
      )

Then I can just pass in an onOutputReady callback when instantiating the playground:

const options = {
    onChange: updateHeight,
    callback: updateHeight,
    onCloseConsole: updateHeight,
    onOpenConsole: updateHeight,
    onOutputReady: updateHeight
}
KotlinPlayground('code', options);

DavidScales avatar May 08 '20 22:05 DavidScales

Hello, thanks for the feedback! We will have a look. 😊

AlexanderPrendota avatar May 09 '20 09:05 AlexanderPrendota

@DavidScales We have PR#84 with stream output. Output will be received by chunks. Do you need update by any chunks or with one event like onOutputReady in this case?

zoobestik avatar May 10 '20 17:05 zoobestik

Hmm, I don't know that I necessarily need output in chunks (although that sounds like a good idea).

What I really need is to know when the output (chunk or final) has been added to the DOM.

Here is my situation visualized, right now I have the editor in an iframe:

initial_iframe

When output is added to the DOM, the editor expands appropriately, but my iframe doesn't:

output_hidden

So I need some event that signals that the DOM has been updated, so that in the child page I can grab the new height and send it to the parent page:

const newHeight = document.body.offsetHeight;
window.parent.postMessage({data: newHeight, type: 'resize'}, '*');

And my parent can listen and adjust the iframe accordingly:

window.addEventListener('message', (e) => {
    iframe.style.height = e.data.data + 'px';
});

So actually, the onOutputRead examples I gave aren't even sufficient, because I am firing onOutputReady when the output returns from the compiling server, but has not yet been added to the DOM, so there is still a delay.

I actually need something more like onOutputAddedToDom.

Any ideas for a problem like this?

DavidScales avatar May 12 '20 19:05 DavidScales