summaryrefslogtreecommitdiff
path: root/doc/play
diff options
context:
space:
mode:
authorMichael Stapelberg <stapelberg@debian.org>2013-03-04 21:27:36 +0100
committerMichael Stapelberg <michael@stapelberg.de>2013-03-04 21:27:36 +0100
commit04b08da9af0c450d645ab7389d1467308cfc2db8 (patch)
treedb247935fa4f2f94408edc3acd5d0d4f997aa0d8 /doc/play
parent917c5fb8ec48e22459d77e3849e6d388f93d3260 (diff)
downloadgolang-upstream/1.1_hg20130304.tar.gz
Imported Upstream version 1.1~hg20130304upstream/1.1_hg20130304
Diffstat (limited to 'doc/play')
-rw-r--r--doc/play/fib.go4
-rw-r--r--doc/play/playground.js263
-rw-r--r--doc/play/sieve.go4
-rw-r--r--doc/play/solitaire.go14
-rw-r--r--doc/play/tree.go4
5 files changed, 165 insertions, 124 deletions
diff --git a/doc/play/fib.go b/doc/play/fib.go
index 42da9ce82..19e472102 100644
--- a/doc/play/fib.go
+++ b/doc/play/fib.go
@@ -1,5 +1,7 @@
package main
+import "fmt"
+
// fib returns a function that returns
// successive Fibonacci numbers.
func fib() func() int {
@@ -13,5 +15,5 @@ func fib() func() int {
func main() {
f := fib()
// Function calls are evaluated left-to-right.
- println(f(), f(), f(), f(), f())
+ fmt.Println(f(), f(), f(), f(), f())
}
diff --git a/doc/play/playground.js b/doc/play/playground.js
index d7cc58d6e..709136627 100644
--- a/doc/play/playground.js
+++ b/doc/play/playground.js
@@ -3,23 +3,19 @@
// license that can be found in the LICENSE file.
// opts is an object with these keys
-// codeEl - code editor element
-// outputEl - program output element
-// runEl - run button element
-// fmtEl - fmt button element (optional)
-// shareEl - share button element (optional)
-// shareURLEl - share URL text input element (optional)
-// shareRedirect - base URL to redirect to on share (optional)
-// preCompile - callback to mutate request data before compiling (optional)
-// postCompile - callback to read response data after compiling (optional)
-// simple - use plain textarea instead of CodeMirror. (optional)
-// toysEl - select element with a list of toys. (optional)
+// codeEl - code editor element
+// outputEl - program output element
+// runEl - run button element
+// fmtEl - fmt button element (optional)
+// shareEl - share button element (optional)
+// shareURLEl - share URL text input element (optional)
+// shareRedirect - base URL to redirect to on share (optional)
+// toysEl - toys select element (optional)
+// enableHistory - enable using HTML5 history API (optional)
function playground(opts) {
- var simple = opts['simple'];
var code = $(opts['codeEl']);
- var editor;
- // autoindent helpers for simple mode.
+ // autoindent helpers.
function insertTabs(n) {
// find the selection start and end
var start = code[0].selectionStart;
@@ -49,12 +45,12 @@ function playground(opts) {
}
}
setTimeout(function() {
- insertTabs(tabs, 1);
+ insertTabs(tabs);
}, 1);
}
function keyHandler(e) {
- if (simple && e.keyCode == 9) { // tab
+ if (e.keyCode == 9) { // tab
insertTabs(1);
e.preventDefault();
return false;
@@ -64,58 +60,19 @@ function playground(opts) {
run();
e.preventDefault();
return false;
- } else if (simple) {
+ } else {
autoindent(e.target);
}
}
return true;
}
- if (simple) {
- code.unbind('keydown').bind('keydown', keyHandler);
- } else {
- editor = CodeMirror.fromTextArea(
- code[0],
- {
- lineNumbers: true,
- indentUnit: 8,
- indentWithTabs: true,
- onKeyEvent: function(editor, e) { keyHandler(e); }
- }
- );
- }
+ code.unbind('keydown').bind('keydown', keyHandler);
var output = $(opts['outputEl']);
- function clearErrors() {
- if (!editor) {
- return;
- }
- var lines = editor.lineCount();
- for (var i = 0; i < lines; i++) {
- editor.setLineClass(i, null);
- }
- }
- function highlightErrors(text) {
- if (!editor) {
- return;
- }
- var errorRe = /[a-z]+\.go:([0-9]+):/g;
- var result;
- while ((result = errorRe.exec(text)) != null) {
- var line = result[1]*1-1;
- editor.setLineClass(line, "errLine")
- }
- }
function body() {
- if (editor) {
- return editor.getValue();
- }
return $(opts['codeEl']).val();
}
function setBody(text) {
- if (editor) {
- editor.setValue(text);
- return;
- }
$(opts['codeEl']).val(text);
}
function origin(href) {
@@ -126,24 +83,116 @@ function playground(opts) {
'<div class="loading">Waiting for remote server...</div>'
);
}
- 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 = $('<span class="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(error)) {
+ $(".lines div").eq(r[1]-1).addClass("lineerror");
+ }
+ $("<pre/>").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);
+ $("<img/>").attr("src", url).appendTo(output);
+ return;
+ }
+
+ // Play back events.
+ if (events !== null) {
+ var pre = $("<pre/>").appendTo(output);
+ playback(pre, events);
+ }
+ }
+
+ var pushedEmpty = (window.location.pathname == "/");
+ function inputChanged() {
+ if (pushedEmpty) {
+ return;
}
- $("<pre/>").text(text).appendTo(output);
+ pushedEmpty = true;
+
+ $(opts['shareURLEl']).hide();
+ window.history.pushState(null, "", "/");
+ }
+
+ function popState(e) {
+ if (e == null) {
+ return;
+ }
+
+ if (e && e.state && e.state.code) {
+ setBody(e.state.code);
+ }
+ }
+
+ var rewriteHistory = false;
+
+ if (window.history &&
+ window.history.pushState &&
+ window.addEventListener &&
+ opts['enableHistory']) {
+ rewriteHistory = true;
+ code[0].addEventListener('input', inputChanged);
+ window.addEventListener('popstate', popState)
}
var seq = 0;
function run() {
- clearErrors();
loading();
seq++;
var cur = seq;
- var data = {"body": body()};
- if (opts['preCompile']) {
- opts['preCompile'](data);
- }
+ var data = {
+ "version": 2,
+ "body": body()
+ };
$.ajax("/compile", {
data: data,
type: "POST",
@@ -152,34 +201,19 @@ function playground(opts) {
if (seq != cur) {
return;
}
- if (opts['postCompile']) {
- opts['postCompile'](data);
- }
if (!data) {
return;
}
- if (data.compile_errors != "") {
- setOutput(data.compile_errors, true);
- highlightErrors(data.compile_errors);
- return;
- }
- var out = ""+data.output;
- if (out.indexOf("IMAGE:") == 0) {
- var img = $("<img/>");
- var url = "data:image/png;base64,";
- url += out.substr(6)
- img.attr("src", url);
- output.empty().append(img);
+ if (data.Errors) {
+ setOutput(null, data.Errors);
return;
}
- setOutput(out, false);
+ setOutput(data.Events, false);
},
- error: function(xhr) {
- var text = "Error communicating with remote server.";
- if (xhr.status == 501) {
- text = xhr.responseText;
- }
- output.addClass("error").text(text);
+ error: function() {
+ output.addClass("error").text(
+ "Error communicating with remote server."
+ );
}
});
}
@@ -193,29 +227,11 @@ function playground(opts) {
dataType: "json",
success: function(data) {
if (data.Error) {
- setOutput(data.Error, true);
- highlightErrors(data.Error);
+ setOutput(null, data.Error);
return;
}
setBody(data.Body);
- setOutput("", false);
- }
- });
- });
-
- $(opts['toysEl']).bind('change', function() {
- var toy = $(this).val();
- loading();
- $.ajax("/doc/play/"+toy, {
- processData: false,
- type: "GET",
- complete: function(xhr) {
- if (xhr.status != 200) {
- setOutput("Server error; try again.", true);
- return;
- }
- setBody(xhr.responseText);
- setOutput("", false);
+ setOutput(null);
}
});
});
@@ -229,16 +245,13 @@ function playground(opts) {
$(opts['shareEl']).click(function() {
if (sharing) return;
sharing = true;
+ var sharingData = body();
$.ajax("/share", {
processData: false,
- data: body(),
+ data: sharingData,
type: "POST",
complete: function(xhr) {
sharing = false;
- if (xhr.status == 501) {
- alert(xhr.responseText);
- return;
- }
if (xhr.status != 200) {
alert("Server error; try again.");
return;
@@ -247,13 +260,37 @@ function playground(opts) {
window.location = opts['shareRedirect'] + xhr.responseText;
}
if (shareURL) {
- var url = origin(window.location) + "/p/" + xhr.responseText;
+ var path = "/p/" + xhr.responseText
+ var url = origin(window.location) + path;
shareURL.show().val(url).focus().select();
+
+ if (rewriteHistory) {
+ var historyData = {
+ "code": sharingData,
+ };
+ window.history.pushState(historyData, "", path);
+ pushedEmpty = false;
+ }
}
}
});
});
}
- return editor;
+ if (opts['toysEl'] != null) {
+ $(opts['toysEl']).bind('change', function() {
+ var toy = $(this).val();
+ $.ajax("/doc/play/"+toy, {
+ processData: false,
+ type: "GET",
+ complete: function(xhr) {
+ if (xhr.status != 200) {
+ alert("Server error; try again.")
+ return;
+ }
+ setBody(xhr.responseText);
+ }
+ });
+ });
+ }
}
diff --git a/doc/play/sieve.go b/doc/play/sieve.go
index 585507ac4..519093453 100644
--- a/doc/play/sieve.go
+++ b/doc/play/sieve.go
@@ -2,6 +2,8 @@
package main
+import "fmt"
+
// Send the sequence 2, 3, 4, ... to channel 'ch'.
func Generate(ch chan<- int) {
for i := 2; ; i++ {
@@ -26,7 +28,7 @@ func main() {
go Generate(ch) // Launch Generate goroutine.
for i := 0; i < 10; i++ {
prime := <-ch
- print(prime, "\n")
+ fmt.Println(prime)
ch1 := make(chan int)
go Filter(ch, ch1, prime)
ch = ch1
diff --git a/doc/play/solitaire.go b/doc/play/solitaire.go
index 759d54281..15022aa19 100644
--- a/doc/play/solitaire.go
+++ b/doc/play/solitaire.go
@@ -28,7 +28,7 @@ var board = []rune(
...........
`)
-// center is the position of the center hole if
+// center is the position of the center hole if
// there is a single one; otherwise it is -1.
var center int
@@ -47,7 +47,7 @@ func init() {
var moves int // number of times move is called
-// move tests if there is a peg at position pos that
+// move tests if there is a peg at position pos that
// can jump over another peg in direction dir. If the
// move is valid, it is executed and move returns true.
// Otherwise, move returns false.
@@ -69,11 +69,11 @@ func unmove(pos, dir int) {
board[pos+2*dir] = '○'
}
-// solve tries to find a sequence of moves such that
-// there is only one peg left at the end; if center is
+// solve tries to find a sequence of moves such that
+// there is only one peg left at the end; if center is
// >= 0, that last peg must be in the center position.
// If a solution is found, solve prints the board after
-// each move in a backward fashion (i.e., the last
+// each move in a backward fashion (i.e., the last
// board position is printed first, all the way back to
// the starting board position).
func solve() bool {
@@ -89,7 +89,7 @@ func solve() bool {
// see if this new board has a solution
if solve() {
unmove(pos, dir)
- println(string(board))
+ fmt.Println(string(board))
return true
}
unmove(pos, dir)
@@ -102,7 +102,7 @@ func solve() bool {
// tried each possible move
if n == 1 && (center < 0 || last == center) {
// there's only one peg left
- println(string(board))
+ fmt.Println(string(board))
return true
}
// no solution found for this board
diff --git a/doc/play/tree.go b/doc/play/tree.go
index 5bcbf05a8..3790e6cda 100644
--- a/doc/play/tree.go
+++ b/doc/play/tree.go
@@ -2,7 +2,7 @@
// express concurrent concepts, such as
// this binary tree comparison.
//
-// Trees may be of different shapes,
+// Trees may be of different shapes,
// but have the same contents. For example:
//
// 4 6
@@ -29,7 +29,7 @@ type Tree struct {
Right *Tree
}
-// Walk traverses a tree depth-first,
+// Walk traverses a tree depth-first,
// sending each Value on a channel.
func Walk(t *Tree, ch chan int) {
if t == nil {