+++ /dev/null
-// 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 little code to ease navigation of these documents.
- *
- * On window load we:
- * + Bind search box hint placeholder show/hide events (bindSearchEvents)
- * + Generate a table of contents (generateTOC)
- * + Bind foldable sections (bindToggles)
- * + Bind links to foldable sections (bindToggleLinks)
- */
-
-(function() {
-'use strict';
-
-function bindSearchEvents() {
-
- var search = $('#search');
- if (search.length === 0) {
- return; // no search box
- }
-
- function clearInactive() {
- if (search.is('.inactive')) {
- search.val('');
- search.removeClass('inactive');
- }
- }
-
- function restoreInactive() {
- if (search.val() !== '') {
- return;
- }
- search.val(search.attr('placeholder'));
- search.addClass('inactive');
- }
-
- search.on('focus', clearInactive);
- search.on('blur', restoreInactive);
-
- restoreInactive();
-}
-
-/* Generates a table of contents: looks for h2 and h3 elements and generates
- * links. "Decorates" the element with id=="nav" with this table of contents.
- */
-function generateTOC() {
- if ($('#manual-nav').length > 0) {
- return;
- }
-
- var nav = $('#nav');
- if (nav.length === 0) {
- return;
- }
-
- var toc_items = [];
- $(nav).nextAll('h2, h3').each(function() {
- var node = this;
- if (node.id == '')
- node.id = 'tmp_' + toc_items.length;
- var link = $('<a/>').attr('href', '#' + node.id).text($(node).text());
- var item;
- if ($(node).is('h2')) {
- item = $('<dt/>');
- } else { // h3
- item = $('<dd/>');
- }
- item.append(link);
- toc_items.push(item);
- });
- if (toc_items.length <= 1) {
- return;
- }
-
- var dl1 = $('<dl/>');
- var dl2 = $('<dl/>');
-
- var split_index = (toc_items.length / 2) + 1;
- if (split_index < 8) {
- split_index = toc_items.length;
- }
- for (var i = 0; i < split_index; i++) {
- dl1.append(toc_items[i]);
- }
- for (/* keep using i */; i < toc_items.length; i++) {
- dl2.append(toc_items[i]);
- }
-
- var tocTable = $('<table class="unruled"/>').appendTo(nav);
- var tocBody = $('<tbody/>').appendTo(tocTable);
- var tocRow = $('<tr/>').appendTo(tocBody);
-
- // 1st column
- $('<td class="first"/>').appendTo(tocRow).append(dl1);
- // 2nd column
- $('<td/>').appendTo(tocRow).append(dl2);
-}
-
-function bindToggle(el) {
- $('.toggleButton', el).click(function() {
- if ($(el).is('.toggle')) {
- $(el).addClass('toggleVisible').removeClass('toggle');
- } else {
- $(el).addClass('toggle').removeClass('toggleVisible');
- }
- });
-}
-function bindToggles(selector) {
- $(selector).each(function(i, el) {
- bindToggle(el);
- });
-}
-
-function bindToggleLink(el, prefix) {
- $(el).click(function() {
- var href = $(el).attr('href');
- var i = href.indexOf('#'+prefix);
- if (i < 0) {
- return;
- }
- var id = '#' + prefix + href.slice(i+1+prefix.length);
- if ($(id).is('.toggle')) {
- $(id).find('.toggleButton').first().click();
- }
- });
-}
-function bindToggleLinks(selector, prefix) {
- $(selector).each(function(i, el) {
- bindToggleLink(el, prefix);
- });
-}
-
-function setupDropdownPlayground() {
- if (!$('#page').is('.wide')) {
- return; // don't show on front page
- }
- var button = $('#playgroundButton');
- var div = $('#playground');
- var setup = false;
- button.toggle(function() {
- button.addClass('active');
- div.show();
- if (setup) {
- return;
- }
- setup = true;
- playground({
- 'codeEl': $('.code', div),
- 'outputEl': $('.output', div),
- 'runEl': $('.run', div),
- 'fmtEl': $('.fmt', div),
- 'shareEl': $('.share', div),
- 'shareRedirect': 'http://play.golang.org/p/'
- });
- },
- function() {
- button.removeClass('active');
- div.hide();
- });
- button.show();
- $('#menu').css('min-width', '+=60');
-}
-
-function setupInlinePlayground() {
- 'use strict';
- // Set up playground when each element is toggled.
- $('div.play').each(function (i, el) {
- // Set up playground for this example.
- var setup = function() {
- var code = $('.code', el);
- playground({
- 'codeEl': code,
- 'outputEl': $('.output', el),
- 'runEl': $('.run', el),
- 'fmtEl': $('.fmt', el),
- 'shareEl': $('.share', el),
- 'shareRedirect': 'http://play.golang.org/p/'
- });
-
- // Make the code textarea resize to fit content.
- var resize = function() {
- code.height(0);
- var h = code[0].scrollHeight;
- code.height(h+20); // minimize bouncing.
- code.closest('.input').height(h);
- };
- code.on('keydown', resize);
- code.on('keyup', resize);
- code.keyup(); // resize now.
- };
-
- // If example already visible, set up playground now.
- if ($(el).is(':visible')) {
- setup();
- return;
- }
-
- // Otherwise, set up playground when example is expanded.
- var built = false;
- $(el).closest('.toggle').click(function() {
- // Only set up once.
- if (!built) {
- setup();
- built = true;
- }
- });
- });
-}
-
-// fixFocus tries to put focus to div#page so that keyboard navigation works.
-function fixFocus() {
- var page = $('div#page');
- var topbar = $('div#topbar');
- page.css('outline', 0); // disable outline when focused
- page.attr('tabindex', -1); // and set tabindex so that it is focusable
- $(window).resize(function (evt) {
- // only focus page when the topbar is at fixed position (that is, it's in
- // front of page, and keyboard event will go to the former by default.)
- // by focusing page, keyboard event will go to page so that up/down arrow,
- // space, etc. will work as expected.
- if (topbar.css('position') == "fixed")
- page.focus();
- }).resize();
-}
-
-function toggleHash() {
- var hash = $(window.location.hash);
- if (hash.is('.toggle')) {
- hash.find('.toggleButton').first().click();
- }
-}
-
-function addPlusButtons() {
- var po = document.createElement('script');
- po.type = 'text/javascript';
- po.async = true;
- po.src = 'https://apis.google.com/js/plusone.js';
- var s = document.getElementsByTagName('script')[0];
- s.parentNode.insertBefore(po, s);
-}
-
-$(document).ready(function() {
- bindSearchEvents();
- generateTOC();
- bindToggles(".toggle");
- bindToggles(".toggleVisible");
- bindToggleLinks(".exampleLink", "example_");
- bindToggleLinks(".overviewLink", "");
- bindToggleLinks(".examplesLink", "");
- bindToggleLinks(".indexLink", "");
- setupDropdownPlayground();
- setupInlinePlayground();
- fixFocus();
- toggleHash();
- addPlusButtons();
-
- // godoc.html defines window.initFuncs in the <head> tag, and root.html and
- // codewalk.js push their on-page-ready functions to the list.
- // We execute those functions here, to avoid loading jQuery until the page
- // content is loaded.
- for (var i = 0; i < window.initFuncs.length; i++) window.initFuncs[i]();
-});
-
-})();
+++ /dev/null
-// 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/playground.js from the repository at
-// https://code.google.com/p/go.talks
-// Please make changes to that repository.
-
-/*
-In the absence of any formal way to specify interfaces in JavaScript,
-here's a skeleton implementation of a playground transport.
-
- function Transport() {
- // Set up any transport state (eg, make a websocket connnection).
- return {
- Run: function(body, output, options) {
- // Compile and run the program 'body' with 'options'.
- // Call the 'output' callback to display program output.
- return {
- Kill: function() {
- // Kill the running program.
- }
- };
- }
- };
- }
-
- // The output callback is called multiple times, and each time it is
- // passed an object of this form.
- var write = {
- Kind: 'string', // 'start', 'stdout', 'stderr', 'end'
- Body: 'string' // content of write or end status message
- }
-
- // The first call must be of Kind 'start' with no body.
- // Subsequent calls may be of Kind 'stdout' or 'stderr'
- // and must have a non-null Body string.
- // The final call should be of Kind 'end' with an optional
- // Body string, signifying a failure ("killed", for example).
-
- // The output callback must be of this form.
- // See PlaygroundOutput (below) for an implementation.
- function outputCallback(write) {
- }
-*/
-
-function HTTPTransport() {
- 'use strict';
-
- // TODO(adg): support stderr
-
- function playback(output, events) {
- var timeout;
- output({Kind: 'start'});
- function next() {
- if (events.length === 0) {
- output({Kind: 'end'});
- return;
- }
- var e = events.shift();
- if (e.Delay === 0) {
- output({Kind: 'stdout', Body: e.Message});
- next();
- return;
- }
- timeout = setTimeout(function() {
- output({Kind: 'stdout', Body: e.Message});
- next();
- }, e.Delay / 1000000);
- }
- next();
- return {
- Stop: function() {
- clearTimeout(timeout);
- }
- }
- }
-
- function error(output, msg) {
- output({Kind: 'start'});
- output({Kind: 'stderr', Body: msg});
- output({Kind: 'end'});
- }
-
- var seq = 0;
- return {
- Run: function(body, output, options) {
- seq++;
- var cur = seq;
- var playing;
- $.ajax('/compile', {
- type: 'POST',
- data: {'version': 2, 'body': body},
- dataType: 'json',
- success: function(data) {
- if (seq != cur) return;
- if (!data) return;
- if (playing != null) playing.Stop();
- if (data.Errors) {
- error(output, data.Errors);
- return;
- }
- playing = playback(output, data.Events);
- },
- error: function() {
- error(output, 'Error communicating with remote server.');
- }
- });
- return {
- Kill: function() {
- if (playing != null) playing.Stop();
- output({Kind: 'end', Body: 'killed'});
- }
- };
- }
- };
-}
-
-function SocketTransport() {
- 'use strict';
-
- var id = 0;
- var outputs = {};
- var started = {};
- var websocket = new WebSocket('ws://' + window.location.host + '/socket');
-
- websocket.onclose = function() {
- console.log('websocket connection closed');
- }
-
- websocket.onmessage = function(e) {
- var m = JSON.parse(e.data);
- var output = outputs[m.Id];
- if (output === null)
- return;
- if (!started[m.Id]) {
- output({Kind: 'start'});
- started[m.Id] = true;
- }
- output({Kind: m.Kind, Body: m.Body});
- }
-
- function send(m) {
- websocket.send(JSON.stringify(m));
- }
-
- return {
- Run: function(body, output, options) {
- var thisID = id+'';
- id++;
- outputs[thisID] = output;
- send({Id: thisID, Kind: 'run', Body: body, Options: options});
- return {
- Kill: function() {
- send({Id: thisID, Kind: 'kill'});
- }
- };
- }
- };
-}
-
-function PlaygroundOutput(el) {
- 'use strict';
-
- return function(write) {
- if (write.Kind == 'start') {
- el.innerHTML = '';
- return;
- }
-
- var cl = 'system';
- if (write.Kind == 'stdout' || write.Kind == 'stderr')
- cl = write.Kind;
-
- var m = write.Body;
- if (write.Kind == 'end')
- m = '\nProgram exited' + (m?(': '+m):'.');
-
- if (m.indexOf('IMAGE:') === 0) {
- // TODO(adg): buffer all writes before creating image
- var url = 'data:image/png;base64,' + m.substr(6);
- var img = document.createElement('img');
- img.src = url;
- el.appendChild(img);
- return;
- }
-
- // ^L clears the screen.
- var s = m.split('\x0c');
- if (s.length > 1) {
- el.innerHTML = '';
- m = s.pop();
- }
-
- m = m.replace(/&/g, '&');
- m = m.replace(/</g, '<');
- m = m.replace(/>/g, '>');
-
- var needScroll = (el.scrollTop + el.offsetHeight) == el.scrollHeight;
-
- var span = document.createElement('span');
- span.className = cl;
- span.innerHTML = m;
- el.appendChild(span);
-
- if (needScroll)
- el.scrollTop = el.scrollHeight - el.offsetHeight;
- }
-}
-
-(function() {
- function lineHighlight(error) {
- var regex = /prog.go:([0-9]+)/g;
- var r = regex.exec(error);
- while (r) {
- $(".lines div").eq(r[1]-1).addClass("lineerror");
- r = regex.exec(error);
- }
- }
- function highlightOutput(wrappedOutput) {
- return function(write) {
- if (write.Body) lineHighlight(write.Body);
- wrappedOutput(write);
- }
- }
- function lineClear() {
- $(".lineerror").removeClass("lineerror");
- }
-
- // 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)
- // toysEl - toys select element (optional)
- // enableHistory - enable using HTML5 history API (optional)
- // transport - playground transport to use (default is HTTPTransport)
- function playground(opts) {
- var code = $(opts.codeEl);
- var transport = opts['transport'] || new HTTPTransport();
- var running;
-
- // autoindent helpers.
- 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);
- }
-
- function keyHandler(e) {
- if (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 {
- autoindent(e.target);
- }
- }
- return true;
- }
- code.unbind('keydown').bind('keydown', keyHandler);
- var outdiv = $(opts.outputEl).empty();
- var output = $('<pre/>').appendTo(outdiv);
-
- function body() {
- return $(opts.codeEl).val();
- }
- function setBody(text) {
- $(opts.codeEl).val(text);
- }
- function origin(href) {
- return (""+href).split("/").slice(0, 3).join("/");
- }
-
- 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);
- }
-
- function setError(error) {
- if (running) running.Kill();
- lineClear();
- lineHighlight(error);
- output.empty().addClass("error").text(error);
- }
- function loading() {
- lineClear();
- if (running) running.Kill();
- output.removeClass("error").text('Waiting for remote server...');
- }
- function run() {
- loading();
- running = transport.Run(body(), highlightOutput(PlaygroundOutput(output[0])));
- }
- function fmt() {
- loading();
- $.ajax("/fmt", {
- data: {"body": body()},
- type: "POST",
- dataType: "json",
- success: function(data) {
- if (data.Error) {
- setError(data.Error);
- } else {
- setBody(data.Body);
- setError("");
- }
- }
- });
- }
-
- $(opts.runEl).click(run);
- $(opts.fmtEl).click(fmt);
-
- if (opts.shareEl !== null && (opts.shareURLEl !== null || opts.shareRedirect !== null)) {
- var shareURL;
- if (opts.shareURLEl) {
- shareURL = $(opts.shareURLEl).hide();
- }
- var sharing = false;
- $(opts.shareEl).click(function() {
- if (sharing) return;
- sharing = true;
- var sharingData = body();
- $.ajax("/share", {
- processData: false,
- data: sharingData,
- type: "POST",
- complete: function(xhr) {
- sharing = false;
- if (xhr.status != 200) {
- alert("Server error; try again.");
- return;
- }
- if (opts.shareRedirect) {
- window.location = opts.shareRedirect + xhr.responseText;
- }
- if (shareURL) {
- 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;
- }
- }
- }
- });
- });
- }
-
- 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);
- }
- });
- });
- }
- }
-
- window.playground = playground;
-})();