github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/misc/tour/js/tour.js (about) 1 /* Copyright 2012 The Go Authors. All rights reserved. 2 * Use of this source code is governed by a BSD-style 3 * license that can be found in the LICENSE file. 4 */ 5 (function() { 6 "use strict"; 7 8 var slides, editor, $editor, $output; 9 var slide = null; 10 var slidenum = 0; 11 12 // manage translations 13 function L(k) { 14 if (tr[k]) { 15 return tr[k]; 16 } else { 17 console.log("translation missing for: "+k); 18 return "(no translation for "+k+")"; 19 } 20 } 21 22 function init() { 23 var $tocdiv = $('<div id="toc" />').insertBefore('#slides').hide(); 24 $tocdiv.append($('<h2>'+L('toc')+'</h2>')); 25 var $toc = $('<ol />').appendTo($tocdiv); 26 $("#tocbtn").click(toggleToc); 27 28 slides = $("div.slide"); 29 slides.each(function(i, slide) { 30 var $s = $(slide).hide(); 31 32 var $h2 = $s.find("h2").first(); 33 var $nav; 34 if ($h2.length > 0) { 35 $("<div/>").addClass("clear").insertAfter($h2); 36 $nav = $("<div/>").addClass("nav"); 37 if (i > 0) { 38 $nav.append($("<a>◀</a>").click(function() { 39 show(i-1); 40 return false; 41 }).attr("href", "#"+(i)).attr("title", L('prev'))); 42 } else { 43 $nav.append($("<span>◀</span>")); 44 } 45 if (i+1 < slides.length) { 46 $nav.append($("<a>▶</a>").click(function() { 47 show(i+1); 48 return false; 49 }).attr("href", "#"+(i+2)).attr("title", L('next'))); 50 } else { 51 $nav.append($("<span>▶</span>")); 52 } 53 $nav.insertBefore($h2); 54 55 var thisI = i; 56 var $entry = $("<a />").text($h2.text()).click(function() { 57 show(thisI); 58 }).attr('href', '#'+(i+1)); 59 $toc.append($entry); 60 $entry.wrap('<li />'); 61 62 } 63 }); 64 65 // set up playground editor 66 editor = CodeMirror.fromTextArea(document.getElementById('editor'), { 67 theme: "default", 68 matchBrackets: true, 69 indentUnit: 4, 70 tabSize: 4, 71 indentWithTabs: false, 72 mode: "text/x-go", 73 lineNumbers: true, 74 extraKeys: { 75 "Shift-Enter": function() { 76 run(); 77 } 78 } 79 }); 80 $editor = $(editor.getWrapperElement()).attr('id', 'code'); 81 $output = $('#output'); 82 83 $('#more').click(function() { 84 $('.controls').toggleClass('expanded'); 85 return false; 86 }); 87 $('html').click(function() { 88 $('.controls').removeClass('expanded'); 89 }); 90 91 $('#run').click(function() { 92 run(); 93 $('.controls').removeClass('expanded'); 94 return false; 95 }); 96 97 $('#reset').click(function() { 98 reset(); 99 $('.controls').removeClass('expanded'); 100 return false; 101 }); 102 103 $('#kill').click(function() { 104 kill(); 105 $('.controls').removeClass('expanded'); 106 return false; 107 }); 108 109 $('#format').click(function() { 110 format(); 111 $('.controls').removeClass('expanded'); 112 return false; 113 }); 114 115 $('#togglesyntax').click(function() { 116 if (editor.getOption('theme') === 'default') { 117 editor.setOption('theme', 'plain'); 118 $('#togglesyntax').text(L('syntax')+': '+L('off')); 119 } else { 120 editor.setOption('theme', 'default'); 121 $('#togglesyntax').text(L('syntax')+': '+L('on')); 122 } 123 setcookie('theme', editor.getOption('theme'), 14); 124 $('.controls').removeClass('expanded'); 125 return false; 126 }); 127 128 $('#togglelineno').click(function() { 129 if (editor.getOption('lineNumbers')) { 130 editor.setOption('lineNumbers', false); 131 $('#togglelineno').text(L('lineno')+': '+L('off')); 132 } else { 133 editor.setOption('lineNumbers', true); 134 $('#togglelineno').text(L('lineno')+': '+L('on')); 135 } 136 setcookie('lineno', editor.getOption('lineNumbers'), 14); 137 $('.controls').removeClass('expanded'); 138 return false; 139 }); 140 141 if (getcookie('lineno') != ""+editor.getOption('lineNumbers')) { 142 $('#togglelineno').trigger('click'); 143 } else { 144 $('#togglelineno').text(L('lineno')+': '+L('on')); 145 } 146 147 if (getcookie('theme') != ""+editor.getOption('theme')) { 148 $('#togglesyntax').trigger('click'); 149 } else { 150 $('#togglesyntax').text(L('syntax')+': '+L('on')); 151 } 152 153 // set these according to lang.js 154 $('#run').text(L('run')); 155 $('#reset').text(L('reset')); 156 $('#format').text(L('format')); 157 $('#kill').text(L('kill')); 158 $('#tocbtn').attr('title', L('toc')); 159 $('#run').attr('title', L('compile')); 160 $('#more').attr('title', L('more')); 161 } 162 163 function toggleToc() { 164 if ($('#toc').is(':visible')) { 165 show(slidenum); 166 } else { 167 $('#slides, #workspace, #slidenum').hide(); 168 $('#toc').show(); 169 } 170 return false; 171 } 172 173 function show(i) { 174 if(i < 0 || i >= slides.length) { 175 return; 176 } 177 178 // if a slide is already onscreen, hide it and store its code 179 if(slide !== null) { 180 var $oldSlide = $(slide).hide(); 181 if (!$oldSlide.hasClass("nocode")) { 182 save(slidenum); 183 } 184 } 185 186 $('#toc').hide(); 187 $('#slidenum, #slides').show(); 188 189 // switch to new slide 190 slidenum = i; 191 $("#slidenum").text(i+1); 192 slide = slides[i]; 193 var $s = $(slide).show(); 194 195 // load stored code, or hide code box 196 if ($s.hasClass("nocode")) { 197 $('#workspace').hide(); 198 $('#wrap').addClass('full-width'); 199 } else { 200 $('#wrap').removeClass('full-width'); 201 $('#workspace').show(); 202 $output.empty(); 203 204 // Load stored code from HTML source or from the pageData cache. 205 // Highlight "HL" lines if the cached data hasn't been changed. 206 var $src = $s.find('div.source'); 207 var orig = $src.text().trim(); 208 var loaded = load(i); 209 if (loaded && loaded != orig) { 210 editor.setValue(loaded); 211 } else { 212 editor.setValue(orig); 213 $src.find('b').closest('span').each(function() { 214 var n = $(this).attr('num')*1 - 1; 215 editor.setLineClass(n, null, 'highlightLine'); 216 }); 217 clearHighlightOnChange(); 218 } 219 220 editor.focus(); 221 } 222 223 // update url fragment 224 var url = location.href; 225 var j = url.indexOf("#"); 226 if(j >= 0) { 227 url = url.substr(0, j); 228 } 229 url += "#" + (slidenum+1).toString(); 230 location.href = url; 231 } 232 233 function reset() { 234 editor.setValue($(slide).find('div.source').text().trim()); 235 save(slidenum); 236 } 237 238 var pageData = {}; 239 240 function save(page) { 241 pageData[page] = editor.getValue(); 242 return true; 243 } 244 245 function load(page) { 246 var data = pageData[page]; 247 if (data) { 248 return data; 249 } 250 return false; 251 } 252 253 function urlSlideNumber(url) { 254 var i = url.indexOf("#"); 255 if(i < 0) { 256 return 0; 257 } 258 var frag = decodeURIComponent(url.substr(i+1)); 259 if(/^\d+$/.test(frag)) { 260 i = parseInt(frag, 10); 261 if(i-1 < 0 || i-1 >= slides.length) { 262 return 0; 263 } 264 return i-1; 265 } 266 return 0; 267 } 268 269 function pageUpDown(event) { 270 var e = window.event || event; 271 if (e.keyCode === 33) { // page up 272 e.preventDefault(); 273 show(slidenum-1); 274 return false; 275 } 276 if (e.keyCode === 34) { // page down 277 e.preventDefault(); 278 show(slidenum+1); 279 return false; 280 } 281 return true; 282 } 283 284 $(document).ready(function() { 285 init(); 286 if (location.href.indexOf('#') < 0) { 287 show(0); 288 } else { 289 show(urlSlideNumber(location.href)); 290 } 291 document.onkeydown = pageUpDown; 292 }); 293 294 var transport; // set by initTour 295 var running; 296 297 function body() { 298 return editor.getValue(); 299 } 300 301 function loading() { 302 $output.html('<pre><span class="loading">'+L('waiting')+'</span></pre>'); 303 } 304 305 function run() { 306 kill(); 307 loading(); 308 var output = highlightOutput(PlaygroundOutput($output.find("pre")[0])); 309 running = transport.Run(body(), output); 310 } 311 312 function highlightOutput(wrappedOutput) { 313 return function(write) { 314 if (write.Body) highlightErrors(write.Body); 315 wrappedOutput(write); 316 } 317 } 318 319 function kill() { 320 if (running) running.Kill(); 321 } 322 323 var seq = 0; 324 325 function format() { 326 seq++; 327 var cur = seq; 328 loading(); 329 $.ajax("/fmt", { 330 data: {"body": body()}, 331 type: "POST", 332 dataType: "json", 333 success: function(data) { 334 if (seq !== cur) { 335 return; 336 } 337 $output.empty(); 338 if (data.Error) { 339 $('<pre class="error" />').text(data.Error).appendTo($output); 340 highlightErrors(data.Error); 341 } else { 342 editor.setValue(data.Body); 343 } 344 }, 345 error: function() { 346 $('<pre class="error" />').text(L('errcomm')).appendTo($output); 347 } 348 }); 349 } 350 351 function highlightErrors(text) { 352 if (!editor || !text) { 353 return; 354 } 355 var errorRe = /[a-z0-9]+\.go:([0-9]+):/g; 356 var result; 357 while ((result = errorRe.exec(text)) !== null) { 358 var line = result[1]*1-1; 359 editor.setLineClass(line, null, 'errLine'); 360 } 361 clearHighlightOnChange(); 362 } 363 364 function clearHighlightOnChange() { 365 editor.setOption('onChange', function() { 366 for (var i = 0; i < editor.lineCount(); i++) { 367 editor.setLineClass(i, null, null); 368 } 369 editor.setOption('onChange', null); 370 }); 371 } 372 373 function getcookie(name) { 374 if (document.cookie.length > 0) { 375 var start = document.cookie.indexOf(name + '='); 376 if (start >= 0) { 377 start += name.length + 1; 378 var end = document.cookie.indexOf(';', start); 379 if (end < 0) { 380 end = document.cookie.length; 381 } 382 return decodeURIComponent(document.cookie.substring(start, end)); 383 } 384 } 385 return null; 386 } 387 388 function setcookie(name, value, expire) { 389 var expdate = new Date(); 390 expdate.setDate(expdate.getDate() + expire); 391 document.cookie = name + '=' + encodeURIComponent(value) + 392 ((expire === undefined) ? '' : ';expires=' + expdate.toGMTString()); 393 } 394 395 window.initTour = function(t) { 396 transport = t 397 } 398 399 }());