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