blob: e3f9484fa5121dbcd3d34f3412804fec5f65aa9e [file] [log] [blame]
/* 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.
*/
(function() {
"use strict";
var slides, editor, $editor, $output;
var slide = null;
var slidenum = 0;
function init() {
if (tourMode === 'local') {
$('.appengineMode').remove();
} else {
$('.localMode').remove();
}
var $tocdiv = $('<div id="toc" />').insertBefore('#slides').hide();
$tocdiv.append($('<h2>Table of Contents</h2>'));
var $toc = $('<ol />').appendTo($tocdiv);
$("#tocbtn").click(toggleToc);
slides = $("div.slide");
slides.each(function(i, slide) {
var $s = $(slide).hide();
var $h2 = $s.find("h2").first();
var $nav;
if ($h2.length > 0) {
$("<div/>").addClass("clear").insertAfter($h2);
$nav = $("<div/>").addClass("nav");
if (i > 0) {
$nav.append($("<a>◀</a>").click(function() {
show(i-1);
return false;
}).attr("href", "#"+(i)).attr("title", "Previous"));
} else {
$nav.append($("<span>◀</span>"));
}
if (i+1 < slides.length) {
$nav.append($("<a>▶</a>").click(function() {
show(i+1);
return false;
}).attr("href", "#"+(i+2)).attr("title", "Next"));
} else {
$nav.append($("<span>▶</span>"));
}
$nav.insertBefore($h2);
var thisI = i;
var $entry = $("<a />").text($h2.text()).click(function() {
show(thisI);
}).attr('href', '#'+(i+1));
$toc.append($entry);
$entry.wrap('<li />');
}
});
// set up playground editor
editor = CodeMirror.fromTextArea(document.getElementById('editor'), {
theme: "plain",
matchBrackets: true,
indentUnit: 8,
tabSize: 8,
indentWithTabs: true,
mode: "text/x-go",
lineNumbers: true,
extraKeys: {
"Shift-Enter": function() {
run();
}
}
});
$editor = $(editor.getWrapperElement()).attr('id', 'code');
$output = $('#output');
$('#more').click(function() {
$('.controls').toggleClass('expanded');
return false;
});
$('html').click(function() {
$('.controls').removeClass('expanded');
});
$('#run').click(function() {
run();
$('.controls').removeClass('expanded');
return false;
});
$('#reset').click(function() {
reset();
$('.controls').removeClass('expanded');
return false;
});
$('#kill').click(function() {
kill();
$('.controls').removeClass('expanded');
return false;
});
$('#format').click(function() {
format();
$('.controls').removeClass('expanded');
return false;
});
$('#togglesyntax').click(function() {
if (editor.getOption('theme') === 'default') {
editor.setOption('theme', 'plain');
$('#togglesyntax').text('Syntax-Highlighting: off');
} else {
editor.setOption('theme', 'default');
$('#togglesyntax').text('Syntax-Highlighting: on');
}
setcookie('theme', editor.getOption('theme'), 14);
$('.controls').removeClass('expanded');
return false;
});
$('#togglelineno').click(function() {
if (editor.getOption('lineNumbers')) {
editor.setOption('lineNumbers', false);
$('#togglelineno').text('Line-Numbers: off');
} else {
editor.setOption('lineNumbers', true);
$('#togglelineno').text('Line-Numbers: on');
}
setcookie('lineno', editor.getOption('lineNumbers'), 14);
$('.controls').removeClass('expanded');
return false;
});
if (getcookie('lineno') != ""+editor.getOption('lineNumbers')) {
$('#togglelineno').trigger('click');
}
if (getcookie('theme') != ""+editor.getOption('theme')) {
$('#togglesyntax').trigger('click');
}
}
function toggleToc() {
if ($('#toc').is(':visible')) {
show(slidenum);
} else {
$('#slides, #workspace, #slidenum').hide();
$('#toc').show();
}
return false;
}
function show(i) {
if(i < 0 || i >= slides.length) {
return;
}
// if a slide is already onscreen, hide it and store its code
if(slide !== null) {
var $oldSlide = $(slide).hide();
if (!$oldSlide.hasClass("nocode")) {
save(slidenum);
}
}
$('#toc').hide();
$('#slidenum, #slides').show();
// switch to new slide
slidenum = i;
$("#slidenum").text(i+1);
slide = slides[i];
var $s = $(slide).show();
// load stored code, or hide code box
if ($s.hasClass("nocode")) {
$('#workspace').hide();
} else {
$('#workspace').show();
$output.empty();
editor.setValue(load(i) || $s.find('pre.source').text());
editor.focus();
}
// update url fragment
var url = location.href;
var j = url.indexOf("#");
if(j >= 0) {
url = url.substr(0, j);
}
url += "#" + (slidenum+1).toString();
location.href = url;
}
function reset() {
editor.setValue($(slide).find('pre.source').text());
save(slidenum);
}
function save(page) {
// TODO: store editor.getValue() using localStorage or something similar
return false;
}
function load(page) {
// TODO: retrieve a previously stored code snippet from localStorage
return false;
}
function urlSlideNumber(url) {
var i = url.indexOf("#");
if(i < 0) {
return 0;
}
var frag = decodeURIComponent(url.substr(i+1));
if(/^\d+$/.test(frag)) {
i = parseInt(frag, 10);
if(i-1 < 0 || i-1 >= slides.length) {
return 0;
}
return i-1;
}
return 0;
}
function pageUpDown(event) {
var e = window.event || event;
if (e.keyCode === 33) { // page up
e.preventDefault();
show(slidenum-1);
return false;
}
if (e.keyCode === 34) { // page down
e.preventDefault();
show(slidenum+1);
return false;
}
return true;
}
$(document).ready(function() {
init();
if (location.href.indexOf('#') < 0) {
show(0);
} else {
show(urlSlideNumber(location.href));
}
document.onkeydown = pageUpDown;
});
$(window).unload(function() {
save(slidenum);
});
var seq = 0;
function run() {
seq++;
var cur = seq;
$output.html('<div class="loading">Waiting for remote server...</div>');
$.ajax("/compile", {
data: {"body": editor.getValue()},
type: "POST",
dataType: "json",
success: function(data) {
if (seq !== cur) {
return;
}
$output.empty();
if (data.compile_errors) {
$('<pre class="error" />').text(data.compile_errors).appendTo($output);
highlightErrors(data.compile_errors);
}
if (/^IMAGE:/.exec(data.output)) {
var img = $('<img />').attr('src',
'data:image/png;base64,' + data.output.substr(6));
$output.empty().append(img);
return;
}
$('<pre />').text(data.output).appendTo($output);
},
error: function() {
$output.empty();
$('<pre class="error" />').text("Error communicating with remote server.").appendTo($output);
}
});
}
function format() {
seq++;
var cur = seq;
$output.html('<div class="loading">Waiting for remote server...</div>');
$.ajax("/fmt", {
data: {"body": editor.getValue()},
type: "POST",
dataType: "json",
success: function(data) {
if (seq !== cur) {
return;
}
$output.empty();
if (data.Error) {
$('<pre class="error" />').text(data.Error).appendTo($output);
highlightErrors(data.Error);
} else {
editor.setValue(data.Body);
}
},
error: function() {
$('<pre class="error" />').text("Error communicating with remote server.").appendTo($output);
}
});
}
function kill() {
$.ajax("/kill");
}
function highlightErrors(text) {
if (!editor || !text) {
return;
}
var errorRe = /[a-z0-9]+\.go:([0-9]+):/g;
var result;
while ((result = errorRe.exec(text)) !== null) {
var line = result[1]*1-1;
editor.setLineClass(line, null, 'errLine');
}
editor.setOption('onChange', function() {
for (var i = 0; i < editor.lineCount(); i++) {
editor.setLineClass(i, null, null);
}
editor.setOption('onChange', null);
});
}
function getcookie(name) {
if (document.cookie.length > 0) {
var start = document.cookie.indexOf(name + '=');
if (start >= 0) {
start += name.length + 1;
var end = document.cookie.indexOf(';', start);
if (end < 0) {
end = document.cookie.length;
}
return decodeURIComponent(document.cookie.substring(start, end));
}
}
return null;
}
function setcookie(name, value, expire) {
var expdate = new Date();
expdate.setDate(expdate.getDate() + expire);
document.cookie = name + '=' + encodeURIComponent(value) +
((expire === undefined) ? '' : ';expires=' + expdate.toGMTString());
}
}());