diff --git a/doc/play/playground.js b/doc/play/playground.js
index 0f56fc05646..709136627ba 100644
--- a/doc/play/playground.js
+++ b/doc/play/playground.js
@@ -83,18 +83,73 @@ function playground(opts) {
'
Waiting for remote server...
'
);
}
- function setOutput(text, error) {
+ var playbackTimeout;
+ function playback(pre, events) {
+ function show(msg) {
+ // ^L clears the screen.
+ var msgs = msg.split("\x0c");
+ if (msgs.length == 1) {
+ pre.text(pre.text() + msg);
+ return;
+ }
+ pre.text(msgs.pop());
+ }
+ function next() {
+ if (events.length == 0) {
+ var exit = $('');
+ exit.text("\nProgram exited.");
+ exit.appendTo(pre);
+ return;
+ }
+ var e = events.shift();
+ if (e.Delay == 0) {
+ show(e.Message);
+ next();
+ } else {
+ playbackTimeout = setTimeout(function() {
+ show(e.Message);
+ next();
+ }, e.Delay / 1000000);
+ }
+ }
+ next();
+ }
+ function stopPlayback() {
+ clearTimeout(playbackTimeout);
+ }
+ function setOutput(events, error) {
+ stopPlayback();
output.empty();
$(".lineerror").removeClass("lineerror");
+
+ // Display errors.
if (error) {
output.addClass("error");
var regex = /prog.go:([0-9]+)/g;
var r;
- while (r = regex.exec(text)) {
+ while (r = regex.exec(error)) {
$(".lines div").eq(r[1]-1).addClass("lineerror");
}
+ $("").text(error).appendTo(output);
+ return;
+ }
+
+ // Display image output.
+ if (events.length > 0 && events[0].Message.indexOf("IMAGE:") == 0) {
+ var out = "";
+ for (var i = 0; i < events.length; i++) {
+ out += events[i].Message;
+ }
+ var url = "data:image/png;base64," + out.substr(6);
+ $("").attr("src", url).appendTo(output);
+ return;
+ }
+
+ // Play back events.
+ if (events !== null) {
+ var pre = $("").appendTo(output);
+ playback(pre, events);
}
- $("").text(text).appendTo(output);
}
var pushedEmpty = (window.location.pathname == "/");
@@ -134,7 +189,10 @@ function playground(opts) {
loading();
seq++;
var cur = seq;
- var data = {"body": body()};
+ var data = {
+ "version": 2,
+ "body": body()
+ };
$.ajax("/compile", {
data: data,
type: "POST",
@@ -146,20 +204,11 @@ function playground(opts) {
if (!data) {
return;
}
- if (data.compile_errors != "") {
- setOutput(data.compile_errors, true);
+ if (data.Errors) {
+ setOutput(null, data.Errors);
return;
}
- var out = ""+data.output;
- if (out.indexOf("IMAGE:") == 0) {
- var img = $("");
- var url = "data:image/png;base64,";
- url += out.substr(6)
- img.attr("src", url);
- output.empty().append(img);
- return;
- }
- setOutput(out, false);
+ setOutput(data.Events, false);
},
error: function() {
output.addClass("error").text(
@@ -178,11 +227,11 @@ function playground(opts) {
dataType: "json",
success: function(data) {
if (data.Error) {
- setOutput(data.Error, true);
+ setOutput(null, data.Error);
return;
}
setBody(data.Body);
- setOutput("", false);
+ setOutput(null);
}
});
});
diff --git a/doc/style.css b/doc/style.css
index 4dae3fd6413..a93aa2827cf 100644
--- a/doc/style.css
+++ b/doc/style.css
@@ -486,6 +486,9 @@ div.play .buttons a {
padding: 10px;
cursor: pointer;
}
+div.play .output .exit {
+ color: #999;
+}
/* drop-down playground */
#playgroundButton,