mirror of
https://github.com/golang/go
synced 2024-11-24 22:57:57 -07:00
doc: add playground.js
R=golang-dev, dsymonds CC=golang-dev https://golang.org/cl/5649087
This commit is contained in:
parent
dd91d83d24
commit
3509687d6a
@ -1,6 +1,197 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// A dummy playground.js file to silence godoc errors
|
||||
// when accessing doc/root.html.
|
||||
// opts is an object with these keys
|
||||
// codeEl - code editor element
|
||||
// outputEl - program output element
|
||||
// runEl - run button element
|
||||
// shareEl - share button element (optional)
|
||||
// shareURLEl - share URL text input element (optional)
|
||||
// preCompile - callback to mutate request data before compiling
|
||||
// postCompile - callback to read response data after compiling
|
||||
// simple - use plain textarea instead of CodeMirror.
|
||||
function playground(opts) {
|
||||
var simple = opts['simple'];
|
||||
var code = $(opts['codeEl']);
|
||||
var editor;
|
||||
|
||||
// autoindent helpers for simple mode.
|
||||
function insertTabs(n) {
|
||||
// find the selection start and end
|
||||
var start = code[0].selectionStart;
|
||||
var end = code[0].selectionEnd;
|
||||
// split the textarea content into two, and insert n tabs
|
||||
var v = code[0].value;
|
||||
var u = v.substr(0, start);
|
||||
for (var i=0; i<n; i++) {
|
||||
u += "\t";
|
||||
}
|
||||
u += v.substr(end);
|
||||
// set revised content
|
||||
code[0].value = u;
|
||||
// reset caret position after inserted tabs
|
||||
code[0].selectionStart = start+n;
|
||||
code[0].selectionEnd = start+n;
|
||||
}
|
||||
function autoindent(el) {
|
||||
var curpos = el.selectionStart;
|
||||
var tabs = 0;
|
||||
while (curpos > 0) {
|
||||
curpos--;
|
||||
if (el.value[curpos] == "\t") {
|
||||
tabs++;
|
||||
} else if (tabs > 0 || el.value[curpos] == "\n") {
|
||||
break;
|
||||
}
|
||||
}
|
||||
setTimeout(function() {
|
||||
insertTabs(tabs, 1);
|
||||
}, 1);
|
||||
}
|
||||
|
||||
function keyHandler(e) {
|
||||
if (simple && e.keyCode == 9) { // tab
|
||||
insertTabs(1);
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
if (e.keyCode == 13) { // enter
|
||||
if (e.shiftKey) { // +shift
|
||||
run();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
} else if (simple) {
|
||||
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); }
|
||||
}
|
||||
);
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
var seq = 0;
|
||||
function run() {
|
||||
clearErrors();
|
||||
output.removeClass("error").html(
|
||||
'<div class="loading">Waiting for remote server...</div>'
|
||||
);
|
||||
seq++;
|
||||
var cur = seq;
|
||||
var data = {"body": body()};
|
||||
if (opts['preCompile']) {
|
||||
opts['preCompile'](data);
|
||||
}
|
||||
$.ajax("/compile", {
|
||||
data: data,
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
success: function(data) {
|
||||
if (seq != cur) {
|
||||
return;
|
||||
}
|
||||
pre = $("<pre/>");
|
||||
output.empty().append(pre);
|
||||
if (opts['postCompile']) {
|
||||
opts['postCompile'](data);
|
||||
}
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
if (data.compile_errors != "") {
|
||||
pre.text(data.compile_errors);
|
||||
output.addClass("error");
|
||||
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);
|
||||
return;
|
||||
}
|
||||
pre.text(out);
|
||||
},
|
||||
error: function() {
|
||||
output.addClass("error").text(
|
||||
"Error communicating with remote server."
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
$(opts['runEl']).click(run);
|
||||
|
||||
if (opts['shareEl'] == null || opts['shareURLEl'] == null) {
|
||||
return editor;
|
||||
}
|
||||
|
||||
function origin(href) {
|
||||
return (""+href).split("/").slice(0, 3).join("/");
|
||||
}
|
||||
|
||||
var shareURL = $(opts['shareURLEl']).hide();
|
||||
var sharing = false;
|
||||
$(opts['shareEl']).click(function() {
|
||||
if (sharing) return;
|
||||
sharing = true;
|
||||
$.ajax("/share", {
|
||||
processData: false,
|
||||
data: body(),
|
||||
type: "POST",
|
||||
complete: function(xhr) {
|
||||
sharing = false;
|
||||
if (xhr.status != 200) {
|
||||
alert("Server error; try again.");
|
||||
return
|
||||
}
|
||||
var url = origin(window.location) + "/p/" +
|
||||
xhr.responseText;
|
||||
shareURL.show().val(url).focus().select();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return editor;
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ Linux, Mac OS X, Windows, and more.
|
||||
<div id="learn">
|
||||
<div class="rootHeading">Try Go</div>
|
||||
<div class="input">
|
||||
<textarea spellcheck="false">// You can edit this code!
|
||||
<textarea spellcheck="false" id="code">// You can edit this code!
|
||||
// Click here and start typing.
|
||||
package main
|
||||
|
||||
@ -36,14 +36,14 @@ func main() {
|
||||
fmt.Println("Hello, 世界")
|
||||
}</textarea>
|
||||
</div>
|
||||
<div class="output">
|
||||
<div class="output" id="output">
|
||||
<pre>
|
||||
Hello, 世界
|
||||
</pre>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<a href="#">Run</a>
|
||||
<a href="#">Share</a>
|
||||
<a id="run" href="#">Run</a>
|
||||
<a id="share" href="#">Share</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -75,8 +75,10 @@ Hello, 世界
|
||||
<div id="plusoneRoot"><g:plusone annotation="none"></g:plusone></div>
|
||||
|
||||
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
|
||||
<script>
|
||||
<script type="text/javascript" src="/doc/play/playground.js"></script>
|
||||
<script type="text/javascript">
|
||||
google.load("feeds", "1");
|
||||
google.load("jquery", "1.7.1");
|
||||
|
||||
function feedLoaded(result) {
|
||||
if (result.error) {
|
||||
@ -104,10 +106,21 @@ function feedLoaded(result) {
|
||||
}
|
||||
}
|
||||
|
||||
function fetchFeeds() {
|
||||
function init() {
|
||||
// Load blog feed.
|
||||
var feed = new google.feeds.Feed("http://blog.golang.org/feeds/posts/default");
|
||||
feed.load(feedLoaded);
|
||||
|
||||
// Set up playground.
|
||||
playground({
|
||||
"simple": true,
|
||||
"codeEl": "#code",
|
||||
"outputEl": "#output",
|
||||
"runEl": "#run",
|
||||
"shareEl": "#share",
|
||||
"shareURLEl": "#shareURL"
|
||||
});
|
||||
}
|
||||
|
||||
google.setOnLoadCallback(fetchFeeds);
|
||||
google.setOnLoadCallback(init);
|
||||
</script>
|
||||
|
@ -227,6 +227,7 @@ body {
|
||||
}
|
||||
|
||||
#learn pre, #learn textarea {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-family: Menlo, monospace;
|
||||
font-size: 14px;
|
||||
|
Loading…
Reference in New Issue
Block a user