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'>&#xb6;</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, '&amp;').
   364               replace(/\"/g, '&quot;').
   365               replace(/\'/g, '&#39;').
   366               replace(/</g, '&lt;').
   367               replace(/>/g, '&gt;');
   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    "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<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 += "&nbsp;" + makeAnchor(cgn.Func);
   601     return li
   602  }
   603  
   604  })();