diff --git a/godoc/static/bake.sh b/godoc/static/bake.sh
index c1491cac..0466682e 100755
--- a/godoc/static/bake.sh
+++ b/godoc/static/bake.sh
@@ -17,6 +17,7 @@ STATIC="
opensearch.xml
package.html
package.txt
+ play.js
playground.js
search.html
search.txt
diff --git a/godoc/static/godoc.html b/godoc/static/godoc.html
index 11766986..0872211a 100644
--- a/godoc/static/godoc.html
+++ b/godoc/static/godoc.html
@@ -23,6 +23,7 @@
Packages
The Project
Help
+Blog
{{if .Playground}}
Play
{{end}}
diff --git a/godoc/static/play.js b/godoc/static/play.js
new file mode 100644
index 00000000..350b368a
--- /dev/null
+++ b/godoc/static/play.js
@@ -0,0 +1,103 @@
+// 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.
+
+// This is a copy of present/js/play.js from the repository at
+// https://code.google.com/p/go.talks
+// Please make changes to that repository.
+
+function initPlayground(transport) {
+ "use strict";
+
+ function text(node) {
+ var s = "";
+ for (var i = 0; i < node.childNodes.length; i++) {
+ var n = node.childNodes[i];
+ if (n.nodeType === 1 && n.tagName === "SPAN" && n.className != "number") {
+ var innerText = n.innerText === undefined ? "textContent" : "innerText";
+ s += n[innerText] + "\n";
+ continue;
+ }
+ if (n.nodeType === 1 && n.tagName !== "BUTTON") {
+ s += text(n);
+ }
+ }
+ return s;
+ }
+
+ function init(code) {
+ var output = document.createElement('div');
+ var outpre = document.createElement('pre');
+ var running;
+
+ if ($ && $(output).resizable) {
+ $(output).resizable({
+ handles: "n,w,nw",
+ minHeight: 27,
+ minWidth: 135,
+ maxHeight: 608,
+ maxWidth: 990
+ });
+ }
+
+ function onKill() {
+ if (running) running.Kill();
+ }
+
+ function onRun(e) {
+ onKill();
+ output.style.display = "block";
+ outpre.innerHTML = "";
+ run1.style.display = "none";
+ var options = {Race: e.shiftKey};
+ running = transport.Run(text(code), PlaygroundOutput(outpre), options);
+ }
+
+ function onClose() {
+ onKill();
+ output.style.display = "none";
+ run1.style.display = "inline-block";
+ }
+
+ var run1 = document.createElement('button');
+ run1.innerHTML = 'Run';
+ run1.className = 'run';
+ run1.addEventListener("click", onRun, false);
+ var run2 = document.createElement('button');
+ run2.className = 'run';
+ run2.innerHTML = 'Run';
+ run2.addEventListener("click", onRun, false);
+ var kill = document.createElement('button');
+ kill.className = 'kill';
+ kill.innerHTML = 'Kill';
+ kill.addEventListener("click", onKill, false);
+ var close = document.createElement('button');
+ close.className = 'close';
+ close.innerHTML = 'Close';
+ close.addEventListener("click", onClose, false);
+
+ var button = document.createElement('div');
+ button.classList.add('buttons');
+ button.appendChild(run1);
+ // Hack to simulate insertAfter
+ code.parentNode.insertBefore(button, code.nextSibling);
+
+ var buttons = document.createElement('div');
+ buttons.classList.add('buttons');
+ buttons.appendChild(run2);
+ buttons.appendChild(kill);
+ buttons.appendChild(close);
+
+ output.classList.add('output');
+ output.appendChild(buttons);
+ output.appendChild(outpre);
+ output.style.display = "none";
+ code.parentNode.insertBefore(output, button.nextSibling);
+ }
+
+ var play = document.querySelectorAll('div.playground');
+ for (var i = 0; i < play.length; i++) {
+ init(play[i]);
+ }
+}
+
diff --git a/godoc/static/static.go b/godoc/static/static.go
index b953be5f..f8c29bcc 100644
--- a/godoc/static/static.go
+++ b/godoc/static/static.go
@@ -173,6 +173,7 @@ var Files = map[string]string{
Packages
The Project
Help
+Blog
{{if .Playground}}
Play
{{end}}
@@ -830,6 +831,110 @@ SUBDIRECTORIES
{{else}}{{range .List}}
{{repeat ` + "`" + `. ` + "`" + ` .Depth}}{{.Name}}{{end}}
{{end}}{{end}}
+`,
+ "play.js": `// 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.
+
+// This is a copy of present/js/play.js from the repository at
+// https://code.google.com/p/go.talks
+// Please make changes to that repository.
+
+function initPlayground(transport) {
+ "use strict";
+
+ function text(node) {
+ var s = "";
+ for (var i = 0; i < node.childNodes.length; i++) {
+ var n = node.childNodes[i];
+ if (n.nodeType === 1 && n.tagName === "SPAN" && n.className != "number") {
+ var innerText = n.innerText === undefined ? "textContent" : "innerText";
+ s += n[innerText] + "\n";
+ continue;
+ }
+ if (n.nodeType === 1 && n.tagName !== "BUTTON") {
+ s += text(n);
+ }
+ }
+ return s;
+ }
+
+ function init(code) {
+ var output = document.createElement('div');
+ var outpre = document.createElement('pre');
+ var running;
+
+ if ($ && $(output).resizable) {
+ $(output).resizable({
+ handles: "n,w,nw",
+ minHeight: 27,
+ minWidth: 135,
+ maxHeight: 608,
+ maxWidth: 990
+ });
+ }
+
+ function onKill() {
+ if (running) running.Kill();
+ }
+
+ function onRun(e) {
+ onKill();
+ output.style.display = "block";
+ outpre.innerHTML = "";
+ run1.style.display = "none";
+ var options = {Race: e.shiftKey};
+ running = transport.Run(text(code), PlaygroundOutput(outpre), options);
+ }
+
+ function onClose() {
+ onKill();
+ output.style.display = "none";
+ run1.style.display = "inline-block";
+ }
+
+ var run1 = document.createElement('button');
+ run1.innerHTML = 'Run';
+ run1.className = 'run';
+ run1.addEventListener("click", onRun, false);
+ var run2 = document.createElement('button');
+ run2.className = 'run';
+ run2.innerHTML = 'Run';
+ run2.addEventListener("click", onRun, false);
+ var kill = document.createElement('button');
+ kill.className = 'kill';
+ kill.innerHTML = 'Kill';
+ kill.addEventListener("click", onKill, false);
+ var close = document.createElement('button');
+ close.className = 'close';
+ close.innerHTML = 'Close';
+ close.addEventListener("click", onClose, false);
+
+ var button = document.createElement('div');
+ button.classList.add('buttons');
+ button.appendChild(run1);
+ // Hack to simulate insertAfter
+ code.parentNode.insertBefore(button, code.nextSibling);
+
+ var buttons = document.createElement('div');
+ buttons.classList.add('buttons');
+ buttons.appendChild(run2);
+ buttons.appendChild(kill);
+ buttons.appendChild(close);
+
+ output.classList.add('output');
+ output.appendChild(buttons);
+ output.appendChild(outpre);
+ output.style.display = "none";
+ code.parentNode.insertBefore(output, button.nextSibling);
+ }
+
+ var play = document.querySelectorAll('div.playground');
+ for (var i = 0; i < play.length; i++) {
+ init(play[i]);
+ }
+}
+
`,
"playground.js": `// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
@@ -1961,5 +2066,55 @@ div#playground .code {
div#playground .output {
height: 100px;
}
+
+/* Inline runnable snippets (play.js/initPlayground) */
+#content .code pre, #content .playground pre, #content .output pre {
+ margin: 0;
+ padding: 0;
+ background: none;
+ border: none;
+ overflow: auto;
+}
+#content .playground .number {
+ color: #999;
+}
+#content .code, #content .playground, #content .output {
+ width: auto;
+ margin: 20px;
+ padding: 10px;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+}
+#content .code, #content .playground {
+ background: #e9e9e9;
+}
+#content .output {
+ background: #202020;
+}
+#content .output .stdout, #content .output pre {
+ color: #e6e6e6;
+}
+#content .output .stderr, #content .output .error {
+ color: rgb(244, 74, 63);
+}
+#content .output .system, #content .output .exit {
+ color: rgb(255, 209, 77)
+}
+#content .buttons {
+ position: relative;
+ float: right;
+ top: -50px;
+ right: 30px;
+}
+#content .output .buttons {
+ top: -60px;
+ right: 0;
+ height: 0;
+}
+#content .buttons .kill {
+ display: none;
+ visibility: hidden;
+}
`,
}
diff --git a/godoc/static/style.css b/godoc/static/style.css
index 11dbce52..66d233c7 100644
--- a/godoc/static/style.css
+++ b/godoc/static/style.css
@@ -541,3 +541,53 @@ div#playground .code {
div#playground .output {
height: 100px;
}
+
+/* Inline runnable snippets (play.js/initPlayground) */
+#content .code pre, #content .playground pre, #content .output pre {
+ margin: 0;
+ padding: 0;
+ background: none;
+ border: none;
+ overflow: auto;
+}
+#content .playground .number {
+ color: #999;
+}
+#content .code, #content .playground, #content .output {
+ width: auto;
+ margin: 20px;
+ padding: 10px;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+}
+#content .code, #content .playground {
+ background: #e9e9e9;
+}
+#content .output {
+ background: #202020;
+}
+#content .output .stdout, #content .output pre {
+ color: #e6e6e6;
+}
+#content .output .stderr, #content .output .error {
+ color: rgb(244, 74, 63);
+}
+#content .output .system, #content .output .exit {
+ color: rgb(255, 209, 77)
+}
+#content .buttons {
+ position: relative;
+ float: right;
+ top: -50px;
+ right: 30px;
+}
+#content .output .buttons {
+ top: -60px;
+ right: 0;
+ height: 0;
+}
+#content .buttons .kill {
+ display: none;
+ visibility: hidden;
+}