diff options
author | Andrew Gerrand <adg@golang.org> | 2012-10-04 16:53:05 +1000 |
---|---|---|
committer | Andrew Gerrand <adg@golang.org> | 2012-10-04 16:53:05 +1000 |
commit | de94d9a48eb26fe987b5780b022fa330ccf2a82a (patch) | |
tree | 64a4b1856303768e9998ada80d61bd54758f92a6 /doc/play | |
parent | b9ded78f37da699f8c12fe47ed05d9753519bdf8 (diff) | |
download | go-de94d9a48eb26fe987b5780b022fa330ccf2a82a.tar.gz |
godoc: make examples editable and runnable in playground
R=dsymonds
CC=golang-dev
http://codereview.appspot.com/6523045
Diffstat (limited to 'doc/play')
-rw-r--r-- | doc/play/playground.js | 154 |
1 files changed, 62 insertions, 92 deletions
diff --git a/doc/play/playground.js b/doc/play/playground.js index d7cc58d6e..3f766a9bf 100644 --- a/doc/play/playground.js +++ b/doc/play/playground.js @@ -3,23 +3,18 @@ // license that can be found in the LICENSE file. // opts is an object with these keys -// codeEl - code editor element +// codeEl - code editor element // outputEl - program output element -// runEl - run button 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) +// 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 +44,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 +59,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) { @@ -128,22 +84,56 @@ function playground(opts) { } function setOutput(text, error) { output.empty(); + $(".lineerror").removeClass("lineerror"); if (error) { output.addClass("error"); + var regex = /prog.go:([0-9]+)/g; + var r; + while (r = regex.exec(text)) { + $(".lines div").eq(r[1]-1).addClass("lineerror"); + } } $("<pre/>").text(text).appendTo(output); } + var pushedEmpty = (window.location.pathname == "/"); + function inputChanged() { + if (pushedEmpty) { + return; + } + 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); - } $.ajax("/compile", { data: data, type: "POST", @@ -152,15 +142,11 @@ 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; @@ -174,12 +160,10 @@ function playground(opts) { } setOutput(out, 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." + ); } }); } @@ -194,7 +178,6 @@ function playground(opts) { success: function(data) { if (data.Error) { setOutput(data.Error, true); - highlightErrors(data.Error); return; } setBody(data.Body); @@ -203,23 +186,6 @@ function playground(opts) { }); }); - $(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); - } - }); - }); - if (opts['shareEl'] != null && (opts['shareURLEl'] != null || opts['shareRedirect'] != null)) { var shareURL; if (opts['shareURLEl']) { @@ -229,16 +195,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 +210,20 @@ 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; } |