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