Skip to content

Instantly share code, notes, and snippets.

@mdboom
Created May 2, 2018 16:04
Show Gist options
  • Save mdboom/33ba964e67a9e8a621fcfac4f478f567 to your computer and use it in GitHub Desktop.
Save mdboom/33ba964e67a9e8a621fcfac4f478f567 to your computer and use it in GitHub Desktop.
Demo Iodide notebook with a probably terrible idea for "synchronous" DOM updating
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>untitled - iodide</title>
<link rel="stylesheet" type="text/css" href="iodide.dev.css">
</head>
<body>
<script id="jsmd" type="text/jsmd">
%% meta
{
"lastExport": "2018-05-02T16:03:36.714Z"
}
%% md
## Experiment for problem of updating DOM from main thread
This is just a hare-brained idea to solve the problem outlined [here](https://github.com/iodide-project/iodide/issues/587#issue-319431892).
%% md
The idea is to transform the cell code into a generator function, and then call each line of that generator function asynchronously so that any updates to the DOM have a chance to happen. I couldn't find anything to do this transformation, but tools such as Babel or Acorn exist on which such a tool could be built. The transformation would essentially be inserting a yield statement between each statement.
This approach is similar to adding a main compiler loop hook in something like Python to process GUI events, except I don't think we have such a hook in Javascript.
So the following cell...
%% js
var div = document.getElementById("foo");
for (let i = 0; i < 10; ++i) {
div.appendChild(document.createTextNode(i));
}
div.appendChild(document.createTextNode("DONE"));
42;
%% md
...would be transformed to...
%% js
function* runCell() {
var div = document.getElementById("foo");
yield;
for (let i = 0; i < 10; ++i) {
div.appendChild(document.createTextNode(i));
yield;
}
yield;
div.appendChild(document.createTextNode("DONE"));
yield;
return 42;
}
%% md
This cell just makes a `<div>` that we can write pseudo-synchronously to.
<div id="foo"></div>
%% md
And then the following code would run in Iodide itself in order to run the cell.
%% js
let x = runCell();
var result;
var timer = setInterval(() => {
let response = x.next();
if (response.done) {
clearInterval(timer);
result = response.value;
}
}, 250); // <-- this value is large to show that the DOM updates "as we go"
// but it could also be 0 to run "as fast as possible"
result
</script>
<div id='page'></div>
<script src='iodide.dev.js'></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment