Commit 3509687d authored by Andrew Gerrand's avatar Andrew Gerrand

doc: add playground.js

R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/5649087
parent dd91d83d
// 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,39 +75,52 @@ 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) {
console.log(result.error);
return;
}
var blog = document.getElementById("blog");
var read = blog.getElementsByClassName("read")[0];
for (var i = 0; i < result.feed.entries.length && i < 2; i++) {
var entry = result.feed.entries[i];
var title = document.createElement("a");
title.className = "title";
title.href = entry.link;
title.innerHTML = entry.title;
blog.insertBefore(title, read);
var extract = document.createElement("div");
extract.className = "extract";
extract.innerHTML = entry.contentSnippet;
blog.insertBefore(extract, read);
var when = document.createElement("div");
when.className = "when";
var pub = entry.publishedDate.split(" ").slice(1,3).join(" ");
when.innerHTML = "Published " + pub
blog.insertBefore(when, read);
}
if (result.error) {
console.log(result.error);
return;
}
var blog = document.getElementById("blog");
var read = blog.getElementsByClassName("read")[0];
for (var i = 0; i < result.feed.entries.length && i < 2; i++) {
var entry = result.feed.entries[i];
var title = document.createElement("a");
title.className = "title";
title.href = entry.link;
title.innerHTML = entry.title;
blog.insertBefore(title, read);
var extract = document.createElement("div");
extract.className = "extract";
extract.innerHTML = entry.contentSnippet;
blog.insertBefore(extract, read);
var when = document.createElement("div");
when.className = "when";
var pub = entry.publishedDate.split(" ").slice(1,3).join(" ");
when.innerHTML = "Published " + pub
blog.insertBefore(when, read);
}
}
function fetchFeeds() {
var feed = new google.feeds.Feed("http://blog.golang.org/feeds/posts/default");
feed.load(feedLoaded);
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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment