Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / godoc / static / godocs.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 /* A little code to ease navigation of these documents.
6  *
7  * On window load we:
8  *  + Generate a table of contents (generateTOC)
9  *  + Bind foldable sections (bindToggles)
10  *  + Bind links to foldable sections (bindToggleLinks)
11  */
12
13 (function() {
14   'use strict';
15
16   // Mobile-friendly topbar menu
17   $(function() {
18     var menu = $('#menu');
19     var menuButton = $('#menu-button');
20     var menuButtonArrow = $('#menu-button-arrow');
21     menuButton.click(function(event) {
22       menu.toggleClass('menu-visible');
23       menuButtonArrow.toggleClass('vertical-flip');
24       event.preventDefault();
25       return false;
26     });
27   });
28
29   /* Generates a table of contents: looks for h2 and h3 elements and generates
30    * links. "Decorates" the element with id=="nav" with this table of contents.
31    */
32   function generateTOC() {
33     if ($('#manual-nav').length > 0) {
34       return;
35     }
36
37     // For search, we send the toc precomputed from server-side.
38     // TODO: Ideally, this should always be precomputed for all pages, but then
39     // we need to do HTML parsing on the server-side.
40     if (location.pathname === '/search') {
41       return;
42     }
43
44     var nav = $('#nav');
45     if (nav.length === 0) {
46       return;
47     }
48
49     var toc_items = [];
50     $(nav)
51       .nextAll('h2, h3')
52       .each(function() {
53         var node = this;
54         if (node.id == '') node.id = 'tmp_' + toc_items.length;
55         var link = $('<a/>')
56           .attr('href', '#' + node.id)
57           .text($(node).text());
58         var item;
59         if ($(node).is('h2')) {
60           item = $('<dt/>');
61         } else {
62           // h3
63           item = $('<dd class="indent"/>');
64         }
65         item.append(link);
66         toc_items.push(item);
67       });
68     if (toc_items.length <= 1) {
69       return;
70     }
71     var dl1 = $('<dl/>');
72     var dl2 = $('<dl/>');
73
74     var split_index = toc_items.length / 2 + 1;
75     if (split_index < 8) {
76       split_index = toc_items.length;
77     }
78     for (var i = 0; i < split_index; i++) {
79       dl1.append(toc_items[i]);
80     }
81     for (; /* keep using i */ i < toc_items.length; i++) {
82       dl2.append(toc_items[i]);
83     }
84
85     var tocTable = $('<table class="unruled"/>').appendTo(nav);
86     var tocBody = $('<tbody/>').appendTo(tocTable);
87     var tocRow = $('<tr/>').appendTo(tocBody);
88
89     // 1st column
90     $('<td class="first"/>')
91       .appendTo(tocRow)
92       .append(dl1);
93     // 2nd column
94     $('<td/>')
95       .appendTo(tocRow)
96       .append(dl2);
97   }
98
99   function bindToggle(el) {
100     $('.toggleButton', el).click(function() {
101       if ($(this).closest('.toggle, .toggleVisible')[0] != el) {
102         // Only trigger the closest toggle header.
103         return;
104       }
105
106       if ($(el).is('.toggle')) {
107         $(el)
108           .addClass('toggleVisible')
109           .removeClass('toggle');
110       } else {
111         $(el)
112           .addClass('toggle')
113           .removeClass('toggleVisible');
114       }
115     });
116   }
117
118   function bindToggles(selector) {
119     $(selector).each(function(i, el) {
120       bindToggle(el);
121     });
122   }
123
124   function bindToggleLink(el, prefix) {
125     $(el).click(function() {
126       var href = $(el).attr('href');
127       var i = href.indexOf('#' + prefix);
128       if (i < 0) {
129         return;
130       }
131       var id = '#' + prefix + href.slice(i + 1 + prefix.length);
132       if ($(id).is('.toggle')) {
133         $(id)
134           .find('.toggleButton')
135           .first()
136           .click();
137       }
138     });
139   }
140   function bindToggleLinks(selector, prefix) {
141     $(selector).each(function(i, el) {
142       bindToggleLink(el, prefix);
143     });
144   }
145
146   function setupDropdownPlayground() {
147     if (!$('#page').is('.wide')) {
148       return; // don't show on front page
149     }
150     var button = $('#playgroundButton');
151     var div = $('#playground');
152     var setup = false;
153     button.toggle(
154       function() {
155         button.addClass('active');
156         div.show();
157         if (setup) {
158           return;
159         }
160         setup = true;
161         playground({
162           codeEl: $('.code', div),
163           outputEl: $('.output', div),
164           runEl: $('.run', div),
165           fmtEl: $('.fmt', div),
166           shareEl: $('.share', div),
167           shareRedirect: '//play.golang.org/p/',
168         });
169       },
170       function() {
171         button.removeClass('active');
172         div.hide();
173       }
174     );
175     $('#menu').css('min-width', '+=60');
176
177     // Hide inline playground if we click somewhere on the page.
178     // This is needed in mobile devices, where the "Play" button
179     // is not clickable once the playground opens up.
180     $('#page').click(function() {
181       if (button.hasClass('active')) {
182         button.click();
183       }
184     });
185   }
186
187   function setupInlinePlayground() {
188     'use strict';
189     // Set up playground when each element is toggled.
190     $('div.play').each(function(i, el) {
191       // Set up playground for this example.
192       var setup = function() {
193         var code = $('.code', el);
194         playground({
195           codeEl: code,
196           outputEl: $('.output', el),
197           runEl: $('.run', el),
198           fmtEl: $('.fmt', el),
199           shareEl: $('.share', el),
200           shareRedirect: '//play.golang.org/p/',
201         });
202
203         // Make the code textarea resize to fit content.
204         var resize = function() {
205           code.height(0);
206           var h = code[0].scrollHeight;
207           code.height(h + 20); // minimize bouncing.
208           code.closest('.input').height(h);
209         };
210         code.on('keydown', resize);
211         code.on('keyup', resize);
212         code.keyup(); // resize now.
213       };
214
215       // If example already visible, set up playground now.
216       if ($(el).is(':visible')) {
217         setup();
218         return;
219       }
220
221       // Otherwise, set up playground when example is expanded.
222       var built = false;
223       $(el)
224         .closest('.toggle')
225         .click(function() {
226           // Only set up once.
227           if (!built) {
228             setup();
229             built = true;
230           }
231         });
232     });
233   }
234
235   // fixFocus tries to put focus to div#page so that keyboard navigation works.
236   function fixFocus() {
237     var page = $('div#page');
238     var topbar = $('div#topbar');
239     page.css('outline', 0); // disable outline when focused
240     page.attr('tabindex', -1); // and set tabindex so that it is focusable
241     $(window)
242       .resize(function(evt) {
243         // only focus page when the topbar is at fixed position (that is, it's in
244         // front of page, and keyboard event will go to the former by default.)
245         // by focusing page, keyboard event will go to page so that up/down arrow,
246         // space, etc. will work as expected.
247         if (topbar.css('position') == 'fixed') page.focus();
248       })
249       .resize();
250   }
251
252   function toggleHash() {
253     var id = window.location.hash.substring(1);
254     // Open all of the toggles for a particular hash.
255     var els = $(
256       document.getElementById(id),
257       $('a[name]').filter(function() {
258         return $(this).attr('name') == id;
259       })
260     );
261
262     while (els.length) {
263       for (var i = 0; i < els.length; i++) {
264         var el = $(els[i]);
265         if (el.is('.toggle')) {
266           el.find('.toggleButton')
267             .first()
268             .click();
269         }
270       }
271       els = el.parent();
272     }
273   }
274
275   function personalizeInstallInstructions() {
276     var prefix = '?download=';
277     var s = window.location.search;
278     if (s.indexOf(prefix) != 0) {
279       // No 'download' query string; detect "test" instructions from User Agent.
280       if (navigator.platform.indexOf('Win') != -1) {
281         $('.testUnix').hide();
282         $('.testWindows').show();
283       } else {
284         $('.testUnix').show();
285         $('.testWindows').hide();
286       }
287       return;
288     }
289
290     var filename = s.substr(prefix.length);
291     var filenameRE = /^go1\.\d+(\.\d+)?([a-z0-9]+)?\.([a-z0-9]+)(-[a-z0-9]+)?(-osx10\.[68])?\.([a-z.]+)$/;
292     var m = filenameRE.exec(filename);
293     if (!m) {
294       // Can't interpret file name; bail.
295       return;
296     }
297     $('.downloadFilename').text(filename);
298     $('.hideFromDownload').hide();
299
300     var os = m[3];
301     var ext = m[6];
302     if (ext != 'tar.gz') {
303       $('#tarballInstructions').hide();
304     }
305     if (os != 'darwin' || ext != 'pkg') {
306       $('#darwinPackageInstructions').hide();
307     }
308     if (os != 'windows') {
309       $('#windowsInstructions').hide();
310       $('.testUnix').show();
311       $('.testWindows').hide();
312     } else {
313       if (ext != 'msi') {
314         $('#windowsInstallerInstructions').hide();
315       }
316       if (ext != 'zip') {
317         $('#windowsZipInstructions').hide();
318       }
319       $('.testUnix').hide();
320       $('.testWindows').show();
321     }
322
323     var download = 'https://dl.google.com/go/' + filename;
324
325     var message = $(
326       '<p class="downloading">' +
327         'Your download should begin shortly. ' +
328         'If it does not, click <a>this link</a>.</p>'
329     );
330     message.find('a').attr('href', download);
331     message.insertAfter('#nav');
332
333     window.location = download;
334   }
335
336   function updateVersionTags() {
337     var v = window.goVersion;
338     if (/^go[0-9.]+$/.test(v)) {
339       $('.versionTag')
340         .empty()
341         .text(v);
342       $('.whereTag').hide();
343     }
344   }
345
346   function addPermalinks() {
347     function addPermalink(source, parent) {
348       var id = source.attr('id');
349       if (id == '' || id.indexOf('tmp_') === 0) {
350         // Auto-generated permalink.
351         return;
352       }
353       if (parent.find('> .permalink').length) {
354         // Already attached.
355         return;
356       }
357       parent
358         .append(' ')
359         .append($("<a class='permalink'>&#xb6;</a>").attr('href', '#' + id));
360     }
361
362     $('#page .container')
363       .find('h2[id], h3[id]')
364       .each(function() {
365         var el = $(this);
366         addPermalink(el, el);
367       });
368
369     $('#page .container')
370       .find('dl[id]')
371       .each(function() {
372         var el = $(this);
373         // Add the anchor to the "dt" element.
374         addPermalink(el, el.find('> dt').first());
375       });
376   }
377
378   $('.js-expandAll').click(function() {
379     if ($(this).hasClass('collapsed')) {
380       toggleExamples('toggle');
381       $(this).text('(Collapse All)');
382     } else {
383       toggleExamples('toggleVisible');
384       $(this).text('(Expand All)');
385     }
386     $(this).toggleClass('collapsed');
387   });
388
389   function toggleExamples(className) {
390     // We need to explicitly iterate through divs starting with "example_"
391     // to avoid toggling Overview and Index collapsibles.
392     $("[id^='example_']").each(function() {
393       // Check for state and click it only if required.
394       if ($(this).hasClass(className)) {
395         $(this)
396           .find('.toggleButton')
397           .first()
398           .click();
399       }
400     });
401   }
402
403   $(document).ready(function() {
404     generateTOC();
405     addPermalinks();
406     bindToggles('.toggle');
407     bindToggles('.toggleVisible');
408     bindToggleLinks('.exampleLink', 'example_');
409     bindToggleLinks('.overviewLink', '');
410     bindToggleLinks('.examplesLink', '');
411     bindToggleLinks('.indexLink', '');
412     setupDropdownPlayground();
413     setupInlinePlayground();
414     fixFocus();
415     setupTypeInfo();
416     setupCallgraphs();
417     toggleHash();
418     personalizeInstallInstructions();
419     updateVersionTags();
420
421     // godoc.html defines window.initFuncs in the <head> tag, and root.html and
422     // codewalk.js push their on-page-ready functions to the list.
423     // We execute those functions here, to avoid loading jQuery until the page
424     // content is loaded.
425     for (var i = 0; i < window.initFuncs.length; i++) window.initFuncs[i]();
426   });
427
428   // -- analysis ---------------------------------------------------------
429
430   // escapeHTML returns HTML for s, with metacharacters quoted.
431   // It is safe for use in both elements and attributes
432   // (unlike the "set innerText, read innerHTML" trick).
433   function escapeHTML(s) {
434     return s
435       .replace(/&/g, '&amp;')
436       .replace(/\"/g, '&quot;')
437       .replace(/\'/g, '&#39;')
438       .replace(/</g, '&lt;')
439       .replace(/>/g, '&gt;');
440   }
441
442   // makeAnchor returns HTML for an <a> element, given an anchorJSON object.
443   function makeAnchor(json) {
444     var html = escapeHTML(json.Text);
445     if (json.Href != '') {
446       html = "<a href='" + escapeHTML(json.Href) + "'>" + html + '</a>';
447     }
448     return html;
449   }
450
451   function showLowFrame(html) {
452     var lowframe = document.getElementById('lowframe');
453     lowframe.style.height = '200px';
454     lowframe.innerHTML =
455       "<p style='text-align: left;'>" +
456       html +
457       '</p>\n' +
458       "<div onclick='hideLowFrame()' style='position: absolute; top: 0; right: 0; cursor: pointer;'>✘</div>";
459   }
460
461   document.hideLowFrame = function() {
462     var lowframe = document.getElementById('lowframe');
463     lowframe.style.height = '0px';
464   };
465
466   // onClickCallers is the onclick action for the 'func' tokens of a
467   // function declaration.
468   document.onClickCallers = function(index) {
469     var data = document.ANALYSIS_DATA[index];
470     if (data.Callers.length == 1 && data.Callers[0].Sites.length == 1) {
471       document.location = data.Callers[0].Sites[0].Href; // jump to sole caller
472       return;
473     }
474
475     var html =
476       'Callers of <code>' + escapeHTML(data.Callee) + '</code>:<br/>\n';
477     for (var i = 0; i < data.Callers.length; i++) {
478       var caller = data.Callers[i];
479       html += '<code>' + escapeHTML(caller.Func) + '</code>';
480       var sites = caller.Sites;
481       if (sites != null && sites.length > 0) {
482         html += ' at line ';
483         for (var j = 0; j < sites.length; j++) {
484           if (j > 0) {
485             html += ', ';
486           }
487           html += '<code>' + makeAnchor(sites[j]) + '</code>';
488         }
489       }
490       html += '<br/>\n';
491     }
492     showLowFrame(html);
493   };
494
495   // onClickCallees is the onclick action for the '(' token of a function call.
496   document.onClickCallees = function(index) {
497     var data = document.ANALYSIS_DATA[index];
498     if (data.Callees.length == 1) {
499       document.location = data.Callees[0].Href; // jump to sole callee
500       return;
501     }
502
503     var html = 'Callees of this ' + escapeHTML(data.Descr) + ':<br/>\n';
504     for (var i = 0; i < data.Callees.length; i++) {
505       html += '<code>' + makeAnchor(data.Callees[i]) + '</code><br/>\n';
506     }
507     showLowFrame(html);
508   };
509
510   // onClickTypeInfo is the onclick action for identifiers declaring a named type.
511   document.onClickTypeInfo = function(index) {
512     var data = document.ANALYSIS_DATA[index];
513     var html =
514       'Type <code>' +
515       data.Name +
516       '</code>: ' +
517       '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<small>(size=' +
518       data.Size +
519       ', align=' +
520       data.Align +
521       ')</small><br/>\n';
522     html += implementsHTML(data);
523     html += methodsetHTML(data);
524     showLowFrame(html);
525   };
526
527   // implementsHTML returns HTML for the implements relation of the
528   // specified TypeInfoJSON value.
529   function implementsHTML(info) {
530     var html = '';
531     if (info.ImplGroups != null) {
532       for (var i = 0; i < info.ImplGroups.length; i++) {
533         var group = info.ImplGroups[i];
534         var x = '<code>' + escapeHTML(group.Descr) + '</code> ';
535         for (var j = 0; j < group.Facts.length; j++) {
536           var fact = group.Facts[j];
537           var y = '<code>' + makeAnchor(fact.Other) + '</code>';
538           if (fact.ByKind != null) {
539             html += escapeHTML(fact.ByKind) + ' type ' + y + ' implements ' + x;
540           } else {
541             html += x + ' implements ' + y;
542           }
543           html += '<br/>\n';
544         }
545       }
546     }
547     return html;
548   }
549
550   // methodsetHTML returns HTML for the methodset of the specified
551   // TypeInfoJSON value.
552   function methodsetHTML(info) {
553     var html = '';
554     if (info.Methods != null) {
555       for (var i = 0; i < info.Methods.length; i++) {
556         html += '<code>' + makeAnchor(info.Methods[i]) + '</code><br/>\n';
557       }
558     }
559     return html;
560   }
561
562   // onClickComm is the onclick action for channel "make" and "<-"
563   // send/receive tokens.
564   document.onClickComm = function(index) {
565     var ops = document.ANALYSIS_DATA[index].Ops;
566     if (ops.length == 1) {
567       document.location = ops[0].Op.Href; // jump to sole element
568       return;
569     }
570
571     var html = 'Operations on this channel:<br/>\n';
572     for (var i = 0; i < ops.length; i++) {
573       html +=
574         makeAnchor(ops[i].Op) +
575         ' by <code>' +
576         escapeHTML(ops[i].Fn) +
577         '</code><br/>\n';
578     }
579     if (ops.length == 0) {
580       html += '(none)<br/>\n';
581     }
582     showLowFrame(html);
583   };
584
585   $(window).load(function() {
586     // Scroll window so that first selection is visible.
587     // (This means we don't need to emit id='L%d' spans for each line.)
588     // TODO(adonovan): ideally, scroll it so that it's under the pointer,
589     // but I don't know how to get the pointer y coordinate.
590     var elts = document.getElementsByClassName('selection');
591     if (elts.length > 0) {
592       elts[0].scrollIntoView();
593     }
594   });
595
596   // setupTypeInfo populates the "Implements" and "Method set" toggle for
597   // each type in the package doc.
598   function setupTypeInfo() {
599     for (var i in document.ANALYSIS_DATA) {
600       var data = document.ANALYSIS_DATA[i];
601
602       var el = document.getElementById('implements-' + i);
603       if (el != null) {
604         // el != null => data is TypeInfoJSON.
605         if (data.ImplGroups != null) {
606           el.innerHTML = implementsHTML(data);
607           el.parentNode.parentNode.style.display = 'block';
608         }
609       }
610
611       var el = document.getElementById('methodset-' + i);
612       if (el != null) {
613         // el != null => data is TypeInfoJSON.
614         if (data.Methods != null) {
615           el.innerHTML = methodsetHTML(data);
616           el.parentNode.parentNode.style.display = 'block';
617         }
618       }
619     }
620   }
621
622   function setupCallgraphs() {
623     if (document.CALLGRAPH == null) {
624       return;
625     }
626     document.getElementById('pkg-callgraph').style.display = 'block';
627
628     var treeviews = document.getElementsByClassName('treeview');
629     for (var i = 0; i < treeviews.length; i++) {
630       var tree = treeviews[i];
631       if (tree.id == null || tree.id.indexOf('callgraph-') != 0) {
632         continue;
633       }
634       var id = tree.id.substring('callgraph-'.length);
635       $(tree).treeview({ collapsed: true, animated: 'fast' });
636       document.cgAddChildren(tree, tree, [id]);
637       tree.parentNode.parentNode.style.display = 'block';
638     }
639   }
640
641   document.cgAddChildren = function(tree, ul, indices) {
642     if (indices != null) {
643       for (var i = 0; i < indices.length; i++) {
644         var li = cgAddChild(tree, ul, document.CALLGRAPH[indices[i]]);
645         if (i == indices.length - 1) {
646           $(li).addClass('last');
647         }
648       }
649     }
650     $(tree).treeview({ animated: 'fast', add: ul });
651   };
652
653   // cgAddChild adds an <li> element for document.CALLGRAPH node cgn to
654   // the parent <ul> element ul. tree is the tree's root <ul> element.
655   function cgAddChild(tree, ul, cgn) {
656     var li = document.createElement('li');
657     ul.appendChild(li);
658     li.className = 'closed';
659
660     var code = document.createElement('code');
661
662     if (cgn.Callees != null) {
663       $(li).addClass('expandable');
664
665       // Event handlers and innerHTML updates don't play nicely together,
666       // hence all this explicit DOM manipulation.
667       var hitarea = document.createElement('div');
668       hitarea.className = 'hitarea expandable-hitarea';
669       li.appendChild(hitarea);
670
671       li.appendChild(code);
672
673       var childUL = document.createElement('ul');
674       li.appendChild(childUL);
675       childUL.setAttribute('style', 'display: none;');
676
677       var onClick = function() {
678         document.cgAddChildren(tree, childUL, cgn.Callees);
679         hitarea.removeEventListener('click', onClick);
680       };
681       hitarea.addEventListener('click', onClick);
682     } else {
683       li.appendChild(code);
684     }
685     code.innerHTML += '&nbsp;' + makeAnchor(cgn.Func);
686     return li;
687   }
688 })();