Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201028153306-37f0764111ff / cmd / present / static / slides.js
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 var PERMANENT_URL_PREFIX = '/static/';
6
7 var SLIDE_CLASSES = ['far-past', 'past', 'current', 'next', 'far-next'];
8
9 var PM_TOUCH_SENSITIVITY = 15;
10
11 var curSlide;
12
13 /* ---------------------------------------------------------------------- */
14 /* classList polyfill by Eli Grey
15  * (http://purl.eligrey.com/github/classList.js/blob/master/classList.js) */
16
17 if (
18   typeof document !== 'undefined' &&
19   !('classList' in document.createElement('a'))
20 ) {
21   (function(view) {
22     var classListProp = 'classList',
23       protoProp = 'prototype',
24       elemCtrProto = (view.HTMLElement || view.Element)[protoProp],
25       objCtr = Object;
26     (strTrim =
27       String[protoProp].trim ||
28       function() {
29         return this.replace(/^\s+|\s+$/g, '');
30       }),
31       (arrIndexOf =
32         Array[protoProp].indexOf ||
33         function(item) {
34           for (var i = 0, len = this.length; i < len; i++) {
35             if (i in this && this[i] === item) {
36               return i;
37             }
38           }
39           return -1;
40         }),
41       // Vendors: please allow content code to instantiate DOMExceptions
42       (DOMEx = function(type, message) {
43         this.name = type;
44         this.code = DOMException[type];
45         this.message = message;
46       }),
47       (checkTokenAndGetIndex = function(classList, token) {
48         if (token === '') {
49           throw new DOMEx(
50             'SYNTAX_ERR',
51             'An invalid or illegal string was specified'
52           );
53         }
54         if (/\s/.test(token)) {
55           throw new DOMEx(
56             'INVALID_CHARACTER_ERR',
57             'String contains an invalid character'
58           );
59         }
60         return arrIndexOf.call(classList, token);
61       }),
62       (ClassList = function(elem) {
63         var trimmedClasses = strTrim.call(elem.className),
64           classes = trimmedClasses ? trimmedClasses.split(/\s+/) : [];
65         for (var i = 0, len = classes.length; i < len; i++) {
66           this.push(classes[i]);
67         }
68         this._updateClassName = function() {
69           elem.className = this.toString();
70         };
71       }),
72       (classListProto = ClassList[protoProp] = []),
73       (classListGetter = function() {
74         return new ClassList(this);
75       });
76     // Most DOMException implementations don't allow calling DOMException's toString()
77     // on non-DOMExceptions. Error's toString() is sufficient here.
78     DOMEx[protoProp] = Error[protoProp];
79     classListProto.item = function(i) {
80       return this[i] || null;
81     };
82     classListProto.contains = function(token) {
83       token += '';
84       return checkTokenAndGetIndex(this, token) !== -1;
85     };
86     classListProto.add = function(token) {
87       token += '';
88       if (checkTokenAndGetIndex(this, token) === -1) {
89         this.push(token);
90         this._updateClassName();
91       }
92     };
93     classListProto.remove = function(token) {
94       token += '';
95       var index = checkTokenAndGetIndex(this, token);
96       if (index !== -1) {
97         this.splice(index, 1);
98         this._updateClassName();
99       }
100     };
101     classListProto.toggle = function(token) {
102       token += '';
103       if (checkTokenAndGetIndex(this, token) === -1) {
104         this.add(token);
105       } else {
106         this.remove(token);
107       }
108     };
109     classListProto.toString = function() {
110       return this.join(' ');
111     };
112
113     if (objCtr.defineProperty) {
114       var classListPropDesc = {
115         get: classListGetter,
116         enumerable: true,
117         configurable: true,
118       };
119       try {
120         objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
121       } catch (ex) {
122         // IE 8 doesn't support enumerable:true
123         if (ex.number === -0x7ff5ec54) {
124           classListPropDesc.enumerable = false;
125           objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
126         }
127       }
128     } else if (objCtr[protoProp].__defineGetter__) {
129       elemCtrProto.__defineGetter__(classListProp, classListGetter);
130     }
131   })(self);
132 }
133 /* ---------------------------------------------------------------------- */
134
135 /* Slide movement */
136
137 function hideHelpText() {
138   document.getElementById('help').style.display = 'none';
139 }
140
141 function getSlideEl(no) {
142   if (no < 0 || no >= slideEls.length) {
143     return null;
144   } else {
145     return slideEls[no];
146   }
147 }
148
149 function updateSlideClass(slideNo, className) {
150   var el = getSlideEl(slideNo);
151
152   if (!el) {
153     return;
154   }
155
156   if (className) {
157     el.classList.add(className);
158   }
159
160   for (var i in SLIDE_CLASSES) {
161     if (className != SLIDE_CLASSES[i]) {
162       el.classList.remove(SLIDE_CLASSES[i]);
163     }
164   }
165 }
166
167 function updateSlides() {
168   if (window.trackPageview) window.trackPageview();
169
170   for (var i = 0; i < slideEls.length; i++) {
171     switch (i) {
172       case curSlide - 2:
173         updateSlideClass(i, 'far-past');
174         break;
175       case curSlide - 1:
176         updateSlideClass(i, 'past');
177         break;
178       case curSlide:
179         updateSlideClass(i, 'current');
180         break;
181       case curSlide + 1:
182         updateSlideClass(i, 'next');
183         break;
184       case curSlide + 2:
185         updateSlideClass(i, 'far-next');
186         break;
187       default:
188         updateSlideClass(i);
189         break;
190     }
191   }
192
193   triggerLeaveEvent(curSlide - 1);
194   triggerEnterEvent(curSlide);
195
196   window.setTimeout(function() {
197     // Hide after the slide
198     disableSlideFrames(curSlide - 2);
199   }, 301);
200
201   enableSlideFrames(curSlide - 1);
202   enableSlideFrames(curSlide + 2);
203
204   updateHash();
205 }
206
207 function prevSlide() {
208   hideHelpText();
209   if (curSlide > 0) {
210     curSlide--;
211
212     updateSlides();
213   }
214
215   if (notesEnabled) localStorage.setItem(destSlideKey(), curSlide);
216 }
217
218 function nextSlide() {
219   hideHelpText();
220   if (curSlide < slideEls.length - 1) {
221     curSlide++;
222
223     updateSlides();
224   }
225
226   if (notesEnabled) localStorage.setItem(destSlideKey(), curSlide);
227 }
228
229 /* Slide events */
230
231 function triggerEnterEvent(no) {
232   var el = getSlideEl(no);
233   if (!el) {
234     return;
235   }
236
237   var onEnter = el.getAttribute('onslideenter');
238   if (onEnter) {
239     new Function(onEnter).call(el);
240   }
241
242   var evt = document.createEvent('Event');
243   evt.initEvent('slideenter', true, true);
244   evt.slideNumber = no + 1; // Make it readable
245
246   el.dispatchEvent(evt);
247 }
248
249 function triggerLeaveEvent(no) {
250   var el = getSlideEl(no);
251   if (!el) {
252     return;
253   }
254
255   var onLeave = el.getAttribute('onslideleave');
256   if (onLeave) {
257     new Function(onLeave).call(el);
258   }
259
260   var evt = document.createEvent('Event');
261   evt.initEvent('slideleave', true, true);
262   evt.slideNumber = no + 1; // Make it readable
263
264   el.dispatchEvent(evt);
265 }
266
267 /* Touch events */
268
269 function handleTouchStart(event) {
270   if (event.touches.length == 1) {
271     touchDX = 0;
272     touchDY = 0;
273
274     touchStartX = event.touches[0].pageX;
275     touchStartY = event.touches[0].pageY;
276
277     document.body.addEventListener('touchmove', handleTouchMove, true);
278     document.body.addEventListener('touchend', handleTouchEnd, true);
279   }
280 }
281
282 function handleTouchMove(event) {
283   if (event.touches.length > 1) {
284     cancelTouch();
285   } else {
286     touchDX = event.touches[0].pageX - touchStartX;
287     touchDY = event.touches[0].pageY - touchStartY;
288     event.preventDefault();
289   }
290 }
291
292 function handleTouchEnd(event) {
293   var dx = Math.abs(touchDX);
294   var dy = Math.abs(touchDY);
295
296   if (dx > PM_TOUCH_SENSITIVITY && dy < (dx * 2) / 3) {
297     if (touchDX > 0) {
298       prevSlide();
299     } else {
300       nextSlide();
301     }
302   }
303
304   cancelTouch();
305 }
306
307 function cancelTouch() {
308   document.body.removeEventListener('touchmove', handleTouchMove, true);
309   document.body.removeEventListener('touchend', handleTouchEnd, true);
310 }
311
312 /* Preloading frames */
313
314 function disableSlideFrames(no) {
315   var el = getSlideEl(no);
316   if (!el) {
317     return;
318   }
319
320   var frames = el.getElementsByTagName('iframe');
321   for (var i = 0, frame; (frame = frames[i]); i++) {
322     disableFrame(frame);
323   }
324 }
325
326 function enableSlideFrames(no) {
327   var el = getSlideEl(no);
328   if (!el) {
329     return;
330   }
331
332   var frames = el.getElementsByTagName('iframe');
333   for (var i = 0, frame; (frame = frames[i]); i++) {
334     enableFrame(frame);
335   }
336 }
337
338 function disableFrame(frame) {
339   frame.src = 'about:blank';
340 }
341
342 function enableFrame(frame) {
343   var src = frame._src;
344
345   if (frame.src != src && src != 'about:blank') {
346     frame.src = src;
347   }
348 }
349
350 function setupFrames() {
351   var frames = document.querySelectorAll('iframe');
352   for (var i = 0, frame; (frame = frames[i]); i++) {
353     frame._src = frame.src;
354     disableFrame(frame);
355   }
356
357   enableSlideFrames(curSlide);
358   enableSlideFrames(curSlide + 1);
359   enableSlideFrames(curSlide + 2);
360 }
361
362 function setupInteraction() {
363   /* Clicking and tapping */
364
365   var el = document.createElement('div');
366   el.className = 'slide-area';
367   el.id = 'prev-slide-area';
368   el.addEventListener('click', prevSlide, false);
369   document.querySelector('section.slides').appendChild(el);
370
371   var el = document.createElement('div');
372   el.className = 'slide-area';
373   el.id = 'next-slide-area';
374   el.addEventListener('click', nextSlide, false);
375   document.querySelector('section.slides').appendChild(el);
376
377   /* Swiping */
378
379   document.body.addEventListener('touchstart', handleTouchStart, false);
380 }
381
382 /* Hash functions */
383
384 function getCurSlideFromHash() {
385   var slideNo = parseInt(location.hash.substr(1));
386
387   if (slideNo) {
388     curSlide = slideNo - 1;
389   } else {
390     curSlide = 0;
391   }
392 }
393
394 function updateHash() {
395   location.replace('#' + (curSlide + 1));
396 }
397
398 /* Event listeners */
399
400 function handleBodyKeyDown(event) {
401   // If we're in a code element, only handle pgup/down.
402   var inCode = event.target.classList.contains('code');
403
404   switch (event.keyCode) {
405     case 78: // 'N' opens presenter notes window
406       if (!inCode && notesEnabled) toggleNotesWindow();
407       break;
408     case 72: // 'H' hides the help text
409     case 27: // escape key
410       if (!inCode) hideHelpText();
411       break;
412
413     case 39: // right arrow
414     case 13: // Enter
415     case 32: // space
416       if (inCode) break;
417     case 34: // PgDn
418       nextSlide();
419       event.preventDefault();
420       break;
421
422     case 37: // left arrow
423     case 8: // Backspace
424       if (inCode) break;
425     case 33: // PgUp
426       prevSlide();
427       event.preventDefault();
428       break;
429
430     case 40: // down arrow
431       if (inCode) break;
432       nextSlide();
433       event.preventDefault();
434       break;
435
436     case 38: // up arrow
437       if (inCode) break;
438       prevSlide();
439       event.preventDefault();
440       break;
441   }
442 }
443
444 function scaleSmallViewports() {
445   var el = document.querySelector('section.slides');
446   var transform = '';
447   var sWidthPx = 1250;
448   var sHeightPx = 750;
449   var sAspectRatio = sWidthPx / sHeightPx;
450   var wAspectRatio = window.innerWidth / window.innerHeight;
451
452   if (wAspectRatio <= sAspectRatio && window.innerWidth < sWidthPx) {
453     transform = 'scale(' + window.innerWidth / sWidthPx + ')';
454   } else if (window.innerHeight < sHeightPx) {
455     transform = 'scale(' + window.innerHeight / sHeightPx + ')';
456   }
457   el.style.transform = transform;
458 }
459
460 function addEventListeners() {
461   document.addEventListener('keydown', handleBodyKeyDown, false);
462   var resizeTimeout;
463   window.addEventListener('resize', function() {
464     // throttle resize events
465     window.clearTimeout(resizeTimeout);
466     resizeTimeout = window.setTimeout(function() {
467       resizeTimeout = null;
468       scaleSmallViewports();
469     }, 50);
470   });
471
472   // Force reset transform property of section.slides when printing page.
473   // Use both onbeforeprint and matchMedia for compatibility with different browsers.
474   var beforePrint = function() {
475     var el = document.querySelector('section.slides');
476     el.style.transform = '';
477   };
478   window.onbeforeprint = beforePrint;
479   if (window.matchMedia) {
480     var mediaQueryList = window.matchMedia('print');
481     mediaQueryList.addListener(function(mql) {
482       if (mql.matches) beforePrint();
483     });
484   }
485 }
486
487 /* Initialization */
488
489 function addFontStyle() {
490   var el = document.createElement('link');
491   el.rel = 'stylesheet';
492   el.type = 'text/css';
493   el.href =
494     '//fonts.googleapis.com/css?family=' +
495     'Open+Sans:regular,semibold,italic,italicsemibold|Droid+Sans+Mono';
496
497   document.body.appendChild(el);
498 }
499
500 function addGeneralStyle() {
501   var el = document.createElement('link');
502   el.rel = 'stylesheet';
503   el.type = 'text/css';
504   el.href = PERMANENT_URL_PREFIX + 'styles.css';
505   document.body.appendChild(el);
506
507   var el = document.createElement('meta');
508   el.name = 'viewport';
509   el.content = 'width=device-width,height=device-height,initial-scale=1';
510   document.querySelector('head').appendChild(el);
511
512   var el = document.createElement('meta');
513   el.name = 'apple-mobile-web-app-capable';
514   el.content = 'yes';
515   document.querySelector('head').appendChild(el);
516
517   scaleSmallViewports();
518 }
519
520 function handleDomLoaded() {
521   slideEls = document.querySelectorAll('section.slides > article');
522
523   setupFrames();
524
525   addFontStyle();
526   addGeneralStyle();
527   addEventListeners();
528
529   updateSlides();
530
531   setupInteraction();
532
533   if (
534     window.location.hostname == 'localhost' ||
535     window.location.hostname == '127.0.0.1' ||
536     window.location.hostname == '::1'
537   ) {
538     hideHelpText();
539   }
540
541   document.body.classList.add('loaded');
542
543   setupNotesSync();
544 }
545
546 function initialize() {
547   getCurSlideFromHash();
548
549   if (window['_DEBUG']) {
550     PERMANENT_URL_PREFIX = '../';
551   }
552
553   if (window['_DCL']) {
554     handleDomLoaded();
555   } else {
556     document.addEventListener('DOMContentLoaded', handleDomLoaded, false);
557   }
558 }
559
560 // If ?debug exists then load the script relative instead of absolute
561 if (!window['_DEBUG'] && document.location.href.indexOf('?debug') !== -1) {
562   document.addEventListener(
563     'DOMContentLoaded',
564     function() {
565       // Avoid missing the DomContentLoaded event
566       window['_DCL'] = true;
567     },
568     false
569   );
570
571   window['_DEBUG'] = true;
572   var script = document.createElement('script');
573   script.type = 'text/javascript';
574   script.src = '../slides.js';
575   var s = document.getElementsByTagName('script')[0];
576   s.parentNode.insertBefore(script, s);
577
578   // Remove this script
579   s.parentNode.removeChild(s);
580 } else {
581   initialize();
582 }
583
584 /* Synchronize windows when notes are enabled */
585
586 function setupNotesSync() {
587   if (!notesEnabled) return;
588
589   function setupPlayResizeSync() {
590     var out = document.getElementsByClassName('output');
591     for (var i = 0; i < out.length; i++) {
592       $(out[i]).bind('resize', function(event) {
593         if ($(event.target).hasClass('ui-resizable')) {
594           localStorage.setItem('play-index', i);
595           localStorage.setItem('output-style', out[i].style.cssText);
596         }
597       });
598     }
599   }
600   function setupPlayCodeSync() {
601     var play = document.querySelectorAll('div.playground');
602     for (var i = 0; i < play.length; i++) {
603       play[i].addEventListener('input', inputHandler, false);
604
605       function inputHandler(e) {
606         localStorage.setItem('play-index', i);
607         localStorage.setItem('play-code', e.target.innerHTML);
608       }
609     }
610   }
611
612   setupPlayCodeSync();
613   setupPlayResizeSync();
614   localStorage.setItem(destSlideKey(), curSlide);
615   window.addEventListener('storage', updateOtherWindow, false);
616 }
617
618 // An update to local storage is caught only by the other window
619 // The triggering window does not handle any sync actions
620 function updateOtherWindow(e) {
621   // Ignore remove storage events which are not meant to update the other window
622   var isRemoveStorageEvent = !e.newValue;
623   if (isRemoveStorageEvent) return;
624
625   var destSlide = localStorage.getItem(destSlideKey());
626   while (destSlide > curSlide) {
627     nextSlide();
628   }
629   while (destSlide < curSlide) {
630     prevSlide();
631   }
632
633   updatePlay(e);
634   updateNotes();
635 }