kotlin-playground
kotlin-playground copied to clipboard
feat/PR request: onOutputReady event
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!
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);
Hello, thanks for the feedback! We will have a look. 😊
@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?
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:
When output is added to the DOM, the editor expands appropriately, but my iframe doesn't:
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?