| /* 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(); |
| |
| // 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 |
| } |
| |
| }()); |