blob: 1c1424a6e2ec0383b961d17081d21e9c5308697b [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;
// manage translations
function L(k) {
if (tr[k]) {
return tr[k];
} else {
console.log("translation missing for: "+k);
return "(no translation for "+k+")";
}
}
function init() {
var $tocdiv = $('<div id="toc" />').insertBefore('#slides').hide();
$tocdiv.append($('<h2>'+L('toc')+'</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", L('prev')));
} 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", L('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: "default",
matchBrackets: true,
indentUnit: 4,
tabSize: 4,
indentWithTabs: false,
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(L('syntax')+': '+L('off'));
} else {
editor.setOption('theme', 'default');
$('#togglesyntax').text(L('syntax')+': '+L('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(L('lineno')+': '+L('off'));
} else {
editor.setOption('lineNumbers', true);
$('#togglelineno').text(L('lineno')+': '+L('on'));
}
setcookie('lineno', editor.getOption('lineNumbers'), 14);
$('.controls').removeClass('expanded');
return false;
});
if (getcookie('lineno') != ""+editor.getOption('lineNumbers')) {
$('#togglelineno').trigger('click');
} else {
$('#togglelineno').text(L('lineno')+': '+L('on'));
}
if (getcookie('theme') != ""+editor.getOption('theme')) {
$('#togglesyntax').trigger('click');
} else {
$('#togglesyntax').text(L('syntax')+': '+L('on'));
}
// set these according to lang.js
$('#run').text(L('run'));
$('#reset').text(L('reset'));
$('#format').text(L('format'));
$('#kill').text(L('kill'));
$('#tocbtn').attr('title', L('toc'));
$('#run').attr('title', L('compile'));
$('#more').attr('title', L('more'));
}
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();
// notify the change of slides if analytics is available.
if (window.trackPageview) window.trackPageview();
// load stored code, or hide code box
if ($s.hasClass("nocode")) {
$('#workspace').hide();
$('#wrap').addClass('full-width');
} else {
$('#wrap').removeClass('full-width');
$('#workspace').show();
$output.empty();
// Load stored code from HTML source or from the pageData cache.
// Highlight "HL" lines if the cached data hasn't been changed.
var $src = $s.find('div.source');
var orig = $src.text().trim();
var loaded = load(i);
if (loaded && loaded != orig) {
editor.setValue(loaded);
} else {
editor.setValue(orig);
$src.find('b').closest('span').each(function() {
var n = $(this).attr('num')*1 - 1;
editor.setLineClass(n, null, 'highlightLine');
});
clearHighlightOnChange();
}
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('div.source').text().trim());
save(slidenum);
}
var pageData = {};
function save(page) {
pageData[page] = editor.getValue();
return true;
}
function load(page) {
var data = pageData[page];
if (data) {
return data;
}
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;
});
var transport; // set by initTour
var running;
function body() {
return editor.getValue();
}
function loading() {
$output.html('<pre><span class="loading">'+L('waiting')+'</span></pre>');
}
function run() {
kill();
loading();
var output = highlightOutput(PlaygroundOutput($output.find("pre")[0]));
running = transport.Run(body(), output);
}
function highlightOutput(wrappedOutput) {
return function(write) {
if (write.Body) highlightErrors(write.Body);
wrappedOutput(write);
}
}
function kill() {
if (running) running.Kill();
}
var seq = 0;
function format() {
seq++;
var cur = seq;
loading();
$.ajax("/fmt", {
data: {"body": body()},
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(L('errcomm')).appendTo($output);
}
});
}
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');
}
clearHighlightOnChange();
}
function clearHighlightOnChange() {
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());
}
window.initTour = function(t) {
transport = t
}
}());