github.com/jgarto/itcv@v0.0.0-20180826224514-4eea09c1aa0d/examples/sites/present/templates/slides.tmpl (about) 1 {/* This is the slide template. It defines how presentations are formatted. */} 2 3 {{define "root"}} 4 <!DOCTYPE html> 5 <html> 6 <head> 7 <title>{{.Title}}</title> 8 <meta charset='utf-8'> 9 <script> 10 var notesEnabled = {{.NotesEnabled}}; 11 </script> 12 <!-- This is a test --> 13 <style> 14 @media screen { 15 /* Framework */ 16 html { 17 height: 100%; 18 } 19 20 body { 21 margin: 0; 22 padding: 0; 23 24 display: block !important; 25 26 height: 100%; 27 min-height: 740px; 28 29 overflow-x: hidden; 30 overflow-y: auto; 31 32 background: rgb(215, 215, 215); 33 background: -o-radial-gradient(rgb(240, 240, 240), rgb(190, 190, 190)); 34 background: -moz-radial-gradient(rgb(240, 240, 240), rgb(190, 190, 190)); 35 background: -webkit-radial-gradient(rgb(240, 240, 240), rgb(190, 190, 190)); 36 background: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 500, from(rgb(240, 240, 240)), to(rgb(190, 190, 190))); 37 38 -webkit-font-smoothing: antialiased; 39 } 40 41 .slides { 42 width: 100%; 43 height: 100%; 44 left: 0; 45 top: 0; 46 47 position: absolute; 48 49 -webkit-transform: translate3d(0, 0, 0); 50 } 51 52 .slides > article { 53 display: block; 54 55 position: absolute; 56 overflow: hidden; 57 58 width: 900px; 59 height: 700px; 60 61 left: 50%; 62 top: 50%; 63 64 margin-left: -450px; 65 margin-top: -350px; 66 67 padding: 40px 60px; 68 69 box-sizing: border-box; 70 -o-box-sizing: border-box; 71 -moz-box-sizing: border-box; 72 -webkit-box-sizing: border-box; 73 74 border-radius: 10px; 75 -o-border-radius: 10px; 76 -moz-border-radius: 10px; 77 -webkit-border-radius: 10px; 78 79 background-color: white; 80 81 border: 1px solid rgba(0, 0, 0, .3); 82 83 transition: transform .3s ease-out; 84 -o-transition: -o-transform .3s ease-out; 85 -moz-transition: -moz-transform .3s ease-out; 86 -webkit-transition: -webkit-transform .3s ease-out; 87 } 88 .slides.layout-widescreen > article { 89 margin-left: -550px; 90 width: 1100px; 91 } 92 .slides.layout-faux-widescreen > article { 93 margin-left: -550px; 94 width: 1100px; 95 96 padding: 40px 160px; 97 } 98 99 .slides.layout-widescreen > article:not(.nobackground):not(.biglogo), 100 .slides.layout-faux-widescreen > article:not(.nobackground):not(.biglogo) { 101 background-position-x: 0, 840px; 102 } 103 104 /* Clickable/tappable areas */ 105 106 .slide-area { 107 z-index: 1000; 108 109 position: absolute; 110 left: 0; 111 top: 0; 112 width: 150px; 113 height: 700px; 114 115 left: 50%; 116 top: 50%; 117 118 cursor: pointer; 119 margin-top: -350px; 120 121 tap-highlight-color: transparent; 122 -o-tap-highlight-color: transparent; 123 -moz-tap-highlight-color: transparent; 124 -webkit-tap-highlight-color: transparent; 125 } 126 #prev-slide-area { 127 margin-left: -550px; 128 } 129 #next-slide-area { 130 margin-left: 400px; 131 } 132 .slides.layout-widescreen #prev-slide-area, 133 .slides.layout-faux-widescreen #prev-slide-area { 134 margin-left: -650px; 135 } 136 .slides.layout-widescreen #next-slide-area, 137 .slides.layout-faux-widescreen #next-slide-area { 138 margin-left: 500px; 139 } 140 141 /* Slides */ 142 143 .slides > article { 144 display: none; 145 } 146 .slides > article.far-past { 147 display: block; 148 transform: translate(-2040px); 149 -o-transform: translate(-2040px); 150 -moz-transform: translate(-2040px); 151 -webkit-transform: translate3d(-2040px, 0, 0); 152 } 153 .slides > article.past { 154 display: block; 155 transform: translate(-1020px); 156 -o-transform: translate(-1020px); 157 -moz-transform: translate(-1020px); 158 -webkit-transform: translate3d(-1020px, 0, 0); 159 } 160 .slides > article.current { 161 display: block; 162 transform: translate(0); 163 -o-transform: translate(0); 164 -moz-transform: translate(0); 165 -webkit-transform: translate3d(0, 0, 0); 166 } 167 .slides > article.next { 168 display: block; 169 transform: translate(1020px); 170 -o-transform: translate(1020px); 171 -moz-transform: translate(1020px); 172 -webkit-transform: translate3d(1020px, 0, 0); 173 } 174 .slides > article.far-next { 175 display: block; 176 transform: translate(2040px); 177 -o-transform: translate(2040px); 178 -moz-transform: translate(2040px); 179 -webkit-transform: translate3d(2040px, 0, 0); 180 } 181 182 .slides.layout-widescreen > article.far-past, 183 .slides.layout-faux-widescreen > article.far-past { 184 display: block; 185 transform: translate(-2260px); 186 -o-transform: translate(-2260px); 187 -moz-transform: translate(-2260px); 188 -webkit-transform: translate3d(-2260px, 0, 0); 189 } 190 .slides.layout-widescreen > article.past, 191 .slides.layout-faux-widescreen > article.past { 192 display: block; 193 transform: translate(-1130px); 194 -o-transform: translate(-1130px); 195 -moz-transform: translate(-1130px); 196 -webkit-transform: translate3d(-1130px, 0, 0); 197 } 198 .slides.layout-widescreen > article.current, 199 .slides.layout-faux-widescreen > article.current { 200 display: block; 201 transform: translate(0); 202 -o-transform: translate(0); 203 -moz-transform: translate(0); 204 -webkit-transform: translate3d(0, 0, 0); 205 } 206 .slides.layout-widescreen > article.next, 207 .slides.layout-faux-widescreen > article.next { 208 display: block; 209 transform: translate(1130px); 210 -o-transform: translate(1130px); 211 -moz-transform: translate(1130px); 212 -webkit-transform: translate3d(1130px, 0, 0); 213 } 214 .slides.layout-widescreen > article.far-next, 215 .slides.layout-faux-widescreen > article.far-next { 216 display: block; 217 transform: translate(2260px); 218 -o-transform: translate(2260px); 219 -moz-transform: translate(2260px); 220 -webkit-transform: translate3d(2260px, 0, 0); 221 } 222 } 223 224 @media print { 225 /* Set page layout */ 226 @page { 227 size: A4 landscape; 228 } 229 230 body { 231 display: block !important; 232 } 233 234 .slides > article { 235 display: block; 236 237 position: relative; 238 239 page-break-inside: never; 240 page-break-after: always; 241 242 overflow: hidden; 243 } 244 245 h2 { 246 position: static !important; 247 margin-top: 400px !important; 248 margin-bottom: 100px !important; 249 } 250 251 div.code { 252 background: rgb(240, 240, 240); 253 } 254 255 /* Add explicit links */ 256 a:link:after, a:visited:after { 257 content: " (" attr(href) ") "; 258 font-size: 50%; 259 } 260 261 #help { 262 display: none; 263 visibility: hidden; 264 } 265 } 266 267 /* Styles for slides */ 268 269 .slides > article { 270 font-family: 'Open Sans', Arial, sans-serif; 271 272 color: black; 273 text-shadow: 0 1px 1px rgba(0, 0, 0, .1); 274 275 font-size: 26px; 276 line-height: 36px; 277 278 letter-spacing: -1px; 279 } 280 281 b { 282 font-weight: 600; 283 } 284 285 a { 286 color: rgb(0, 102, 204); 287 text-decoration: none; 288 } 289 a:visited { 290 color: rgba(0, 102, 204, .75); 291 } 292 a:hover { 293 color: black; 294 } 295 296 p { 297 margin: 0; 298 padding: 0; 299 300 margin-top: 20px; 301 } 302 p:first-child { 303 margin-top: 0; 304 } 305 306 h1 { 307 font-size: 60px; 308 line-height: 60px; 309 310 padding: 0; 311 margin: 0; 312 margin-top: 200px; 313 margin-bottom: 5px; 314 padding-right: 40px; 315 316 font-weight: 600; 317 318 letter-spacing: -3px; 319 320 color: rgb(51, 51, 51); 321 } 322 323 h2 { 324 font-size: 45px; 325 line-height: 45px; 326 327 position: absolute; 328 bottom: 150px; 329 330 padding: 0; 331 margin: 0; 332 padding-right: 40px; 333 334 font-weight: 600; 335 336 letter-spacing: -2px; 337 338 color: rgb(51, 51, 51); 339 } 340 341 h3 { 342 font-size: 30px; 343 line-height: 36px; 344 345 padding: 0; 346 margin: 0; 347 padding-right: 40px; 348 349 font-weight: 600; 350 351 letter-spacing: -1px; 352 353 color: rgb(51, 51, 51); 354 } 355 356 ul { 357 margin: 0; 358 padding: 0; 359 margin-top: 20px; 360 margin-left: 1.5em; 361 } 362 li { 363 padding: 0; 364 margin: 0 0 .5em 0; 365 } 366 367 div.code { 368 padding: 5px 10px; 369 margin-top: 20px; 370 margin-bottom: 20px; 371 overflow: hidden; 372 373 background: rgb(240, 240, 240); 374 border: 1px solid rgb(224, 224, 224); 375 } 376 pre { 377 margin: 0; 378 padding: 0; 379 380 font-family: 'Droid Sans Mono', 'Courier New', monospace; 381 font-size: 18px; 382 line-height: 24px; 383 letter-spacing: -1px; 384 385 color: black; 386 } 387 388 pre.numbers span:before { 389 content: attr(num); 390 margin-right: 1em; 391 display: inline-block; 392 } 393 394 code { 395 font-size: 95%; 396 font-family: 'Droid Sans Mono', 'Courier New', monospace; 397 398 color: black; 399 } 400 401 article > .image, 402 article > .video { 403 text-align: center; 404 margin-top: 40px; 405 } 406 407 article > .background { 408 position: absolute; 409 top: 0; 410 left: 0; 411 right: 0; 412 bottom: 0; 413 z-index: -1; 414 } 415 416 article > .background > img { 417 max-height: 100%; 418 max-width: 100%; 419 } 420 421 table { 422 width: 100%; 423 border-collapse: collapse; 424 margin-top: 40px; 425 } 426 th { 427 font-weight: 600; 428 text-align: left; 429 } 430 td, 431 th { 432 border: 1px solid rgb(224, 224, 224); 433 padding: 5px 10px; 434 vertical-align: top; 435 } 436 437 p.link { 438 margin-left: 20px; 439 } 440 441 /* Code */ 442 div.code { 443 outline: 0px solid transparent; 444 } 445 div.playground { 446 position: relative; 447 } 448 div.output { 449 position: absolute; 450 left: 50%; 451 top: 50%; 452 right: 40px; 453 bottom: 40px; 454 background: #202020; 455 padding: 5px 10px; 456 z-index: 2; 457 458 border-radius: 10px; 459 -o-border-radius: 10px; 460 -moz-border-radius: 10px; 461 -webkit-border-radius: 10px; 462 463 } 464 div.output pre { 465 margin: 0; 466 padding: 0; 467 background: none; 468 border: none; 469 width: 100%; 470 height: 100%; 471 overflow: auto; 472 } 473 div.output .stdout, div.output pre { 474 color: #e6e6e6; 475 } 476 div.output .stderr, div.output .error { 477 color: rgb(255, 200, 200); 478 } 479 div.output .system, div.output .exit { 480 color: rgb(255, 230, 120) 481 } 482 .buttons { 483 position: relative; 484 float: right; 485 top: -60px; 486 right: 10px; 487 } 488 div.output .buttons { 489 position: absolute; 490 float: none; 491 top: auto; 492 right: 5px; 493 bottom: 5px; 494 } 495 496 /* Presenter details */ 497 .presenter { 498 margin-top: 20px; 499 } 500 .presenter p, 501 .presenter .link { 502 margin: 0; 503 font-size: 28px; 504 line-height: 1.2em; 505 } 506 507 /* Output resize details */ 508 .ui-resizable-handle { 509 position: absolute; 510 } 511 .ui-resizable-n { 512 cursor: n-resize; 513 height: 7px; 514 width: 100%; 515 top: -5px; 516 left: 0; 517 } 518 .ui-resizable-w { 519 cursor: w-resize; 520 width: 7px; 521 left: -5px; 522 top: 0; 523 height: 100%; 524 } 525 .ui-resizable-nw { 526 cursor: nw-resize; 527 width: 9px; 528 height: 9px; 529 left: -5px; 530 top: -5px; 531 } 532 iframe { 533 border: none; 534 } 535 figcaption { 536 color: #666; 537 text-align: center; 538 font-size: 0.75em; 539 } 540 541 #help { 542 font-family: 'Open Sans', Arial, sans-serif; 543 text-align: center; 544 color: white; 545 background: #000; 546 opacity: 0.5; 547 position: fixed; 548 bottom: 25px; 549 left: 50px; 550 right: 50px; 551 padding: 20px; 552 553 border-radius: 10px; 554 -o-border-radius: 10px; 555 -moz-border-radius: 10px; 556 -webkit-border-radius: 10px; 557 } 558 </style> 559 <script> 560 // Copyright 2012 The Go Authors. All rights reserved. 561 // Use of this source code is governed by a BSD-style 562 // license that can be found in the LICENSE file. 563 564 var PERMANENT_URL_PREFIX = '/static/'; 565 566 var SLIDE_CLASSES = ['far-past', 'past', 'current', 'next', 'far-next']; 567 568 var PM_TOUCH_SENSITIVITY = 15; 569 570 var curSlide; 571 572 /* ---------------------------------------------------------------------- */ 573 /* classList polyfill by Eli Grey 574 * (http://purl.eligrey.com/github/classList.js/blob/master/classList.js) */ 575 576 if (typeof document !== 'undefined' && !('classList' in document.createElement('a'))) { 577 578 (function (view) { 579 580 var 581 classListProp = 'classList' 582 , protoProp = 'prototype' 583 , elemCtrProto = (view.HTMLElement || view.Element)[protoProp] 584 , objCtr = Object 585 strTrim = String[protoProp].trim || function () { 586 return this.replace(/^\s+|\s+$/g, ''); 587 } 588 , arrIndexOf = Array[protoProp].indexOf || function (item) { 589 for (var i = 0, len = this.length; i < len; i++) { 590 if (i in this && this[i] === item) { 591 return i; 592 } 593 } 594 return -1; 595 } 596 // Vendors: please allow content code to instantiate DOMExceptions 597 , DOMEx = function (type, message) { 598 this.name = type; 599 this.code = DOMException[type]; 600 this.message = message; 601 } 602 , checkTokenAndGetIndex = function (classList, token) { 603 if (token === '') { 604 throw new DOMEx( 605 'SYNTAX_ERR' 606 , 'An invalid or illegal string was specified' 607 ); 608 } 609 if (/\s/.test(token)) { 610 throw new DOMEx( 611 'INVALID_CHARACTER_ERR' 612 , 'String contains an invalid character' 613 ); 614 } 615 return arrIndexOf.call(classList, token); 616 } 617 , ClassList = function (elem) { 618 var 619 trimmedClasses = strTrim.call(elem.className) 620 , classes = trimmedClasses ? trimmedClasses.split(/\s+/) : [] 621 ; 622 for (var i = 0, len = classes.length; i < len; i++) { 623 this.push(classes[i]); 624 } 625 this._updateClassName = function () { 626 elem.className = this.toString(); 627 }; 628 } 629 , classListProto = ClassList[protoProp] = [] 630 , classListGetter = function () { 631 return new ClassList(this); 632 } 633 ; 634 // Most DOMException implementations don't allow calling DOMException's toString() 635 // on non-DOMExceptions. Error's toString() is sufficient here. 636 DOMEx[protoProp] = Error[protoProp]; 637 classListProto.item = function (i) { 638 return this[i] || null; 639 }; 640 classListProto.contains = function (token) { 641 token += ''; 642 return checkTokenAndGetIndex(this, token) !== -1; 643 }; 644 classListProto.add = function (token) { 645 token += ''; 646 if (checkTokenAndGetIndex(this, token) === -1) { 647 this.push(token); 648 this._updateClassName(); 649 } 650 }; 651 classListProto.remove = function (token) { 652 token += ''; 653 var index = checkTokenAndGetIndex(this, token); 654 if (index !== -1) { 655 this.splice(index, 1); 656 this._updateClassName(); 657 } 658 }; 659 classListProto.toggle = function (token) { 660 token += ''; 661 if (checkTokenAndGetIndex(this, token) === -1) { 662 this.add(token); 663 } else { 664 this.remove(token); 665 } 666 }; 667 classListProto.toString = function () { 668 return this.join(' '); 669 }; 670 671 if (objCtr.defineProperty) { 672 var classListPropDesc = { 673 get: classListGetter 674 , enumerable: true 675 , configurable: true 676 }; 677 try { 678 objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); 679 } catch (ex) { // IE 8 doesn't support enumerable:true 680 if (ex.number === -0x7FF5EC54) { 681 classListPropDesc.enumerable = false; 682 objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); 683 } 684 } 685 } else if (objCtr[protoProp].__defineGetter__) { 686 elemCtrProto.__defineGetter__(classListProp, classListGetter); 687 } 688 689 }(self)); 690 691 } 692 /* ---------------------------------------------------------------------- */ 693 694 /* Slide movement */ 695 696 function hideHelpText() { 697 document.getElementById('help').style.display = 'none'; 698 }; 699 700 function getSlideEl(no) { 701 if ((no < 0) || (no >= slideEls.length)) { 702 return null; 703 } else { 704 return slideEls[no]; 705 } 706 }; 707 708 function updateSlideClass(slideNo, className) { 709 var el = getSlideEl(slideNo); 710 711 if (!el) { 712 return; 713 } 714 715 if (className) { 716 el.classList.add(className); 717 } 718 719 for (var i in SLIDE_CLASSES) { 720 if (className != SLIDE_CLASSES[i]) { 721 el.classList.remove(SLIDE_CLASSES[i]); 722 } 723 } 724 }; 725 726 function updateSlides() { 727 if (window.trackPageview) window.trackPageview(); 728 729 for (var i = 0; i < slideEls.length; i++) { 730 switch (i) { 731 case curSlide - 2: 732 updateSlideClass(i, 'far-past'); 733 break; 734 case curSlide - 1: 735 updateSlideClass(i, 'past'); 736 break; 737 case curSlide: 738 updateSlideClass(i, 'current'); 739 break; 740 case curSlide + 1: 741 updateSlideClass(i, 'next'); 742 break; 743 case curSlide + 2: 744 updateSlideClass(i, 'far-next'); 745 break; 746 default: 747 updateSlideClass(i); 748 break; 749 } 750 } 751 752 triggerLeaveEvent(curSlide - 1); 753 triggerEnterEvent(curSlide); 754 755 window.setTimeout(function() { 756 // Hide after the slide 757 disableSlideFrames(curSlide - 2); 758 }, 301); 759 760 enableSlideFrames(curSlide - 1); 761 enableSlideFrames(curSlide + 2); 762 763 updateHash(); 764 }; 765 766 function prevSlide() { 767 hideHelpText(); 768 if (curSlide > 0) { 769 curSlide--; 770 771 updateSlides(); 772 } 773 774 if (notesEnabled) localStorage.setItem('destSlide', curSlide); 775 }; 776 777 function nextSlide() { 778 hideHelpText(); 779 if (curSlide < slideEls.length - 1) { 780 curSlide++; 781 782 updateSlides(); 783 } 784 785 if (notesEnabled) localStorage.setItem('destSlide', curSlide); 786 }; 787 788 /* Slide events */ 789 790 function triggerEnterEvent(no) { 791 var el = getSlideEl(no); 792 if (!el) { 793 return; 794 } 795 796 var onEnter = el.getAttribute('onslideenter'); 797 if (onEnter) { 798 new Function(onEnter).call(el); 799 } 800 801 var evt = document.createEvent('Event'); 802 evt.initEvent('slideenter', true, true); 803 evt.slideNumber = no + 1; // Make it readable 804 805 el.dispatchEvent(evt); 806 }; 807 808 function triggerLeaveEvent(no) { 809 var el = getSlideEl(no); 810 if (!el) { 811 return; 812 } 813 814 var onLeave = el.getAttribute('onslideleave'); 815 if (onLeave) { 816 new Function(onLeave).call(el); 817 } 818 819 var evt = document.createEvent('Event'); 820 evt.initEvent('slideleave', true, true); 821 evt.slideNumber = no + 1; // Make it readable 822 823 el.dispatchEvent(evt); 824 }; 825 826 /* Touch events */ 827 828 function handleTouchStart(event) { 829 if (event.touches.length == 1) { 830 touchDX = 0; 831 touchDY = 0; 832 833 touchStartX = event.touches[0].pageX; 834 touchStartY = event.touches[0].pageY; 835 836 document.body.addEventListener('touchmove', handleTouchMove, true); 837 document.body.addEventListener('touchend', handleTouchEnd, true); 838 } 839 }; 840 841 function handleTouchMove(event) { 842 if (event.touches.length > 1) { 843 cancelTouch(); 844 } else { 845 touchDX = event.touches[0].pageX - touchStartX; 846 touchDY = event.touches[0].pageY - touchStartY; 847 event.preventDefault(); 848 } 849 }; 850 851 function handleTouchEnd(event) { 852 var dx = Math.abs(touchDX); 853 var dy = Math.abs(touchDY); 854 855 if ((dx > PM_TOUCH_SENSITIVITY) && (dy < (dx * 2 / 3))) { 856 if (touchDX > 0) { 857 prevSlide(); 858 } else { 859 nextSlide(); 860 } 861 } 862 863 cancelTouch(); 864 }; 865 866 function cancelTouch() { 867 document.body.removeEventListener('touchmove', handleTouchMove, true); 868 document.body.removeEventListener('touchend', handleTouchEnd, true); 869 }; 870 871 /* Preloading frames */ 872 873 function disableSlideFrames(no) { 874 var el = getSlideEl(no); 875 if (!el) { 876 return; 877 } 878 879 var frames = el.getElementsByTagName('iframe'); 880 for (var i = 0, frame; frame = frames[i]; i++) { 881 disableFrame(frame); 882 } 883 }; 884 885 function enableSlideFrames(no) { 886 var el = getSlideEl(no); 887 if (!el) { 888 return; 889 } 890 891 var frames = el.getElementsByTagName('iframe'); 892 for (var i = 0, frame; frame = frames[i]; i++) { 893 enableFrame(frame); 894 } 895 }; 896 897 function disableFrame(frame) { 898 frame.src = 'about:blank'; 899 }; 900 901 function enableFrame(frame) { 902 var src = frame._src; 903 904 if (frame.src != src && src != 'about:blank') { 905 frame.src = src; 906 } 907 }; 908 909 function setupFrames() { 910 var frames = document.querySelectorAll('iframe'); 911 for (var i = 0, frame; frame = frames[i]; i++) { 912 frame._src = frame.src; 913 disableFrame(frame); 914 } 915 916 enableSlideFrames(curSlide); 917 enableSlideFrames(curSlide + 1); 918 enableSlideFrames(curSlide + 2); 919 }; 920 921 function setupInteraction() { 922 /* Clicking and tapping */ 923 924 var el = document.createElement('div'); 925 el.className = 'slide-area'; 926 el.id = 'prev-slide-area'; 927 el.addEventListener('click', prevSlide, false); 928 document.querySelector('section.slides').appendChild(el); 929 930 var el = document.createElement('div'); 931 el.className = 'slide-area'; 932 el.id = 'next-slide-area'; 933 el.addEventListener('click', nextSlide, false); 934 document.querySelector('section.slides').appendChild(el); 935 936 /* Swiping */ 937 938 document.body.addEventListener('touchstart', handleTouchStart, false); 939 } 940 941 /* Hash functions */ 942 943 function getCurSlideFromHash() { 944 var slideNo = parseInt(location.hash.substr(1)); 945 946 if (slideNo) { 947 curSlide = slideNo - 1; 948 } else { 949 curSlide = 0; 950 } 951 }; 952 953 function updateHash() { 954 // TODO 955 // location.replace('#' + (curSlide + 1)); 956 }; 957 958 /* Event listeners */ 959 960 function handleBodyKeyDown(event) { 961 // If we're in a code element, only handle pgup/down. 962 var inCode = event.target.classList.contains('code'); 963 964 switch (event.keyCode) { 965 case 78: // 'N' opens presenter notes window 966 if (!inCode && notesEnabled) toggleNotesWindow(); 967 break; 968 case 72: // 'H' hides the help text 969 case 27: // escape key 970 if (!inCode) hideHelpText(); 971 break; 972 973 case 39: // right arrow 974 case 13: // Enter 975 case 32: // space 976 if (inCode) break; 977 case 34: // PgDn 978 nextSlide(); 979 event.preventDefault(); 980 break; 981 982 case 37: // left arrow 983 case 8: // Backspace 984 if (inCode) break; 985 case 33: // PgUp 986 prevSlide(); 987 event.preventDefault(); 988 break; 989 990 case 40: // down arrow 991 if (inCode) break; 992 nextSlide(); 993 event.preventDefault(); 994 break; 995 996 case 38: // up arrow 997 if (inCode) break; 998 prevSlide(); 999 event.preventDefault(); 1000 break; 1001 } 1002 }; 1003 1004 function addEventListeners() { 1005 document.addEventListener('keydown', handleBodyKeyDown, false); 1006 }; 1007 1008 /* Initialization */ 1009 1010 function addFontStyle() { 1011 var el = document.createElement('link'); 1012 el.rel = 'stylesheet'; 1013 el.type = 'text/css'; 1014 el.href = '//fonts.googleapis.com/css?family=' + 1015 'Open+Sans:regular,semibold,italic,italicsemibold|Droid+Sans+Mono'; 1016 1017 document.body.appendChild(el); 1018 }; 1019 1020 function addGeneralStyle() { 1021 var el = document.createElement('link'); 1022 el.rel = 'stylesheet'; 1023 el.type = 'text/css'; 1024 el.href = PERMANENT_URL_PREFIX + 'styles.css'; 1025 document.body.appendChild(el); 1026 1027 var el = document.createElement('meta'); 1028 el.name = 'viewport'; 1029 el.content = 'width=1100,height=750'; 1030 document.querySelector('head').appendChild(el); 1031 1032 var el = document.createElement('meta'); 1033 el.name = 'apple-mobile-web-app-capable'; 1034 el.content = 'yes'; 1035 document.querySelector('head').appendChild(el); 1036 }; 1037 1038 function handleDomLoaded() { 1039 slideEls = document.querySelectorAll('section.slides > article'); 1040 1041 setupFrames(); 1042 1043 addFontStyle(); 1044 // addGeneralStyle(); 1045 addEventListeners(); 1046 1047 updateSlides(); 1048 1049 setupInteraction(); 1050 1051 if (window.location.hostname == 'localhost' || window.location.hostname == '127.0.0.1' || window.location.hostname == '::1') { 1052 hideHelpText(); 1053 } 1054 1055 document.body.classList.add('loaded'); 1056 1057 setupNotesSync(); 1058 }; 1059 1060 function initialize() { 1061 getCurSlideFromHash(); 1062 1063 if (window['_DEBUG']) { 1064 PERMANENT_URL_PREFIX = '../'; 1065 } 1066 1067 if (window['_DCL']) { 1068 handleDomLoaded(); 1069 } else { 1070 document.addEventListener('DOMContentLoaded', handleDomLoaded, false); 1071 } 1072 } 1073 1074 // If ?debug exists then load the script relative instead of absolute 1075 if (!window['_DEBUG'] && document.location.href.indexOf('?debug') !== -1) { 1076 document.addEventListener('DOMContentLoaded', function() { 1077 // Avoid missing the DomContentLoaded event 1078 window['_DCL'] = true 1079 }, false); 1080 1081 window['_DEBUG'] = true; 1082 var script = document.createElement('script'); 1083 script.type = 'text/javascript'; 1084 script.src = '../slides.js'; 1085 var s = document.getElementsByTagName('script')[0]; 1086 s.parentNode.insertBefore(script, s); 1087 1088 // Remove this script 1089 s.parentNode.removeChild(s); 1090 } else { 1091 initialize(); 1092 } 1093 1094 /* Synchronize windows when notes are enabled */ 1095 1096 function setupNotesSync() { 1097 if (!notesEnabled) return; 1098 1099 function setupPlayResizeSync() { 1100 var out = document.getElementsByClassName('output'); 1101 for (var i = 0; i < out.length; i++) { 1102 $(out[i]).bind('resize', function(event) { 1103 if ($(event.target).hasClass('ui-resizable')) { 1104 localStorage.setItem('play-index', i); 1105 localStorage.setItem('output-style', out[i].style.cssText); 1106 } 1107 }) 1108 } 1109 }; 1110 function setupPlayCodeSync() { 1111 var play = document.querySelectorAll('div.playground'); 1112 for (var i = 0; i < play.length; i++) { 1113 play[i].addEventListener('input', inputHandler, false); 1114 1115 function inputHandler(e) { 1116 localStorage.setItem('play-index', i); 1117 localStorage.setItem('play-code', e.target.innerHTML); 1118 } 1119 } 1120 }; 1121 1122 setupPlayCodeSync(); 1123 setupPlayResizeSync(); 1124 localStorage.setItem('destSlide', curSlide); 1125 window.addEventListener('storage', updateOtherWindow, false); 1126 } 1127 1128 // An update to local storage is caught only by the other window 1129 // The triggering window does not handle any sync actions 1130 function updateOtherWindow(e) { 1131 // Ignore remove storage events which are not meant to update the other window 1132 var isRemoveStorageEvent = !e.newValue; 1133 if (isRemoveStorageEvent) return; 1134 1135 var destSlide = localStorage.getItem('destSlide'); 1136 while (destSlide > curSlide) { 1137 nextSlide(); 1138 } 1139 while (destSlide < curSlide) { 1140 prevSlide(); 1141 } 1142 1143 updatePlay(e); 1144 updateNotes(); 1145 } 1146 </script> 1147 1148 {{if .NotesEnabled}} 1149 <script> 1150 var sections = {{.Sections}}; 1151 var titleNotes = {{.TitleNotes}} 1152 </script> 1153 <script src='/static/notes.js'></script> 1154 {{end}} 1155 1156 <script> 1157 // Initialize Google Analytics tracking code on production site only. 1158 if (window["location"] && window["location"]["hostname"] == "talks.golang.org") { 1159 var _gaq = _gaq || []; 1160 _gaq.push(["_setAccount", "UA-11222381-6"]); 1161 _gaq.push(["b._setAccount", "UA-49880327-6"]); 1162 window.trackPageview = function() { 1163 _gaq.push(["_trackPageview", location.pathname+location.hash]); 1164 _gaq.push(["b._trackPageview", location.pathname+location.hash]); 1165 }; 1166 window.trackPageview(); 1167 window.trackEvent = function(category, action, opt_label, opt_value, opt_noninteraction) { 1168 _gaq.push(["_trackEvent", category, action, opt_label, opt_value, opt_noninteraction]); 1169 _gaq.push(["b._trackEvent", category, action, opt_label, opt_value, opt_noninteraction]); 1170 }; 1171 } 1172 </script> 1173 </head> 1174 1175 <body style='display: none'> 1176 1177 <section class='slides layout-widescreen'> 1178 1179 <article> 1180 <h1>{{.Title}}</h1> 1181 {{with .Subtitle}}<h3>{{.}}</h3>{{end}} 1182 {{if not .Time.IsZero}}<h3>{{.Time.Format "2 January 2006"}}</h3>{{end}} 1183 {{range .Authors}} 1184 <div class="presenter"> 1185 {{range .TextElem}}{{elem $.Template .}}{{end}} 1186 </div> 1187 {{end}} 1188 </article> 1189 1190 {{range $i, $s := .Sections}} 1191 <!-- start of slide {{$s.Number}} --> 1192 <article> 1193 {{if $s.Elem}} 1194 <h3>{{$s.Title}}</h3> 1195 {{range $s.Elem}}{{elem $.Template .}}{{end}} 1196 {{else}} 1197 <h2>{{$s.Title}}</h2> 1198 {{end}} 1199 </article> 1200 <!-- end of slide {{$i}} --> 1201 {{end}}{{/* of Slide block */}} 1202 1203 <article> 1204 <h3>Thank you</h3> 1205 {{range .Authors}} 1206 <div class="presenter"> 1207 {{range .Elem}}{{elem $.Template .}}{{end}} 1208 </div> 1209 {{end}} 1210 </article> 1211 1212 </section> 1213 1214 <div id="help"> 1215 Use the left and right arrow keys or click the left and right 1216 edges of the page to navigate between slides.<br> 1217 (Press 'H' or navigate to hide this message.) 1218 </div> 1219 1220 {{if .PlayEnabled}} 1221 <script src='/play.js'></script> 1222 {{end}} 1223 1224 <script> 1225 (function() { 1226 // Load Google Analytics tracking code on production site only. 1227 if (window["location"] && window["location"]["hostname"] == "talks.golang.org") { 1228 var ga = document.createElement("script"); ga.type = "text/javascript"; ga.async = true; 1229 ga.src = ("https:" == document.location.protocol ? "https://ssl" : "http://www") + ".google-analytics.com/ga.js"; 1230 var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(ga, s); 1231 } 1232 })(); 1233 </script> 1234 </body> 1235 </html> 1236 {{end}} 1237 1238 {{define "newline"}} 1239 <br> 1240 {{end}}