diff options
author | Michael Stapelberg <stapelberg@debian.org> | 2013-03-04 21:27:36 +0100 |
---|---|---|
committer | Michael Stapelberg <michael@stapelberg.de> | 2013-03-04 21:27:36 +0100 |
commit | 04b08da9af0c450d645ab7389d1467308cfc2db8 (patch) | |
tree | db247935fa4f2f94408edc3acd5d0d4f997aa0d8 /doc/play | |
parent | 917c5fb8ec48e22459d77e3849e6d388f93d3260 (diff) | |
download | golang-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.go | 4 | ||||
-rw-r--r-- | doc/play/playground.js | 263 | ||||
-rw-r--r-- | doc/play/sieve.go | 4 | ||||
-rw-r--r-- | doc/play/solitaire.go | 14 | ||||
-rw-r--r-- | doc/play/tree.go | 4 |
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 { |