Home | History | Annotate | Download | only in assets
      1 var resizePackagesNav;
      2 var classesNav;
      3 var devdocNav;
      4 var sidenav;
      5 var content;
      6 var HEADER_HEIGHT = -1;
      7 var cookie_namespace = 'doclava_developer';
      8 var NAV_PREF_TREE = "tree";
      9 var NAV_PREF_PANELS = "panels";
     10 var nav_pref;
     11 var toRoot;
     12 var isMobile = false; // true if mobile, so we can adjust some layout
     13 var isIE6 = false; // true if IE6
     14 
     15 // TODO: use $(document).ready instead
     16 function addLoadEvent(newfun) {
     17   var current = window.onload;
     18   if (typeof window.onload != 'function') {
     19     window.onload = newfun;
     20   } else {
     21     window.onload = function() {
     22       current();
     23       newfun();
     24     }
     25   }
     26 }
     27 
     28 var agent = navigator['userAgent'].toLowerCase();
     29 // If a mobile phone, set flag and do mobile setup
     30 if ((agent.indexOf("mobile") != -1) ||      // android, iphone, ipod
     31     (agent.indexOf("blackberry") != -1) ||
     32     (agent.indexOf("webos") != -1) ||
     33     (agent.indexOf("mini") != -1)) {        // opera mini browsers
     34   isMobile = true;
     35   addLoadEvent(mobileSetup);
     36 // If not a mobile browser, set the onresize event for IE6, and others
     37 } else if (agent.indexOf("msie 6") != -1) {
     38   isIE6 = true;
     39   addLoadEvent(function() {
     40     window.onresize = resizeAll;
     41   });
     42 } else {
     43   addLoadEvent(function() {
     44     window.onresize = resizeHeight;
     45   });
     46 }
     47 
     48 function mobileSetup() {
     49   $("body").css({'overflow':'auto'});
     50   $("html").css({'overflow':'auto'});
     51   $("#body-content").css({'position':'relative', 'top':'0'});
     52   $("#doc-content").css({'overflow':'visible', 'border-left':'3px solid #DDD'});
     53   $("#side-nav").css({'padding':'0'});
     54   $("#nav-tree").css({'overflow-y': 'auto'});
     55 }
     56 
     57 /* loads the lists.js file to the page.
     58 Loading this in the head was slowing page load time */
     59 addLoadEvent( function() {
     60   var lists = document.createElement("script");
     61   lists.setAttribute("type","text/javascript");
     62   lists.setAttribute("src", toRoot+"reference/lists.js");
     63   document.getElementsByTagName("head")[0].appendChild(lists);
     64 } );
     65 
     66 addLoadEvent( function() {
     67   $("pre:not(.no-pretty-print)").addClass("prettyprint");
     68   prettyPrint();
     69 } );
     70 
     71 function setToRoot(root) {
     72   toRoot = root;
     73   // note: toRoot also used by carousel.js
     74 }
     75 
     76 function restoreWidth(navWidth) {
     77   var windowWidth = $(window).width() + "px";
     78   content.css({marginLeft:parseInt(navWidth) + 6 + "px"}); //account for 6px-wide handle-bar
     79 
     80   if (isIE6) {
     81     content.css({width:parseInt(windowWidth) - parseInt(navWidth) - 6 + "px"}); // necessary in order for scrollbars to be visible
     82   }
     83 
     84   sidenav.css({width:navWidth});
     85   resizePackagesNav.css({width:navWidth});
     86   classesNav.css({width:navWidth});
     87   $("#packages-nav").css({width:navWidth});
     88 }
     89 
     90 function restoreHeight(packageHeight) {
     91   var windowHeight = ($(window).height() - HEADER_HEIGHT);
     92   var swapperHeight = windowHeight - 13;
     93   $("#swapper").css({height:swapperHeight + "px"});
     94   sidenav.css({height:windowHeight + "px"});
     95   content.css({height:windowHeight + "px"});
     96   resizePackagesNav.css({maxHeight:swapperHeight + "px", height:packageHeight});
     97   classesNav.css({height:swapperHeight - parseInt(packageHeight) + "px"});
     98   $("#packages-nav").css({height:parseInt(packageHeight) - 6 + "px"}); //move 6px to give space for the resize handle
     99   devdocNav.css({height:sidenav.css("height")});
    100   $("#nav-tree").css({height:swapperHeight + "px"});
    101 }
    102 
    103 function readCookie(cookie) {
    104   var myCookie = cookie_namespace+"_"+cookie+"=";
    105   if (document.cookie) {
    106     var index = document.cookie.indexOf(myCookie);
    107     if (index != -1) {
    108       var valStart = index + myCookie.length;
    109       var valEnd = document.cookie.indexOf(";", valStart);
    110       if (valEnd == -1) {
    111         valEnd = document.cookie.length;
    112       }
    113       var val = document.cookie.substring(valStart, valEnd);
    114       return val;
    115     }
    116   }
    117   return 0;
    118 }
    119 
    120 function writeCookie(cookie, val, section, expiration) {
    121   if (val==undefined) return;
    122   section = section == null ? "_" : "_"+section+"_";
    123   if (expiration == null) {
    124     var date = new Date();
    125     date.setTime(date.getTime()+(10*365*24*60*60*1000)); // default expiration is one week
    126     expiration = date.toGMTString();
    127   }
    128   document.cookie = cookie_namespace + section + cookie + "=" + val + "; expires=" + expiration+"; path=/";
    129 }
    130 
    131 function getSection() {
    132   if (location.href.indexOf("/reference/") != -1) {
    133     return "reference";
    134   } else if (location.href.indexOf("/guide/") != -1) {
    135     return "guide";
    136   } else if (location.href.indexOf("/resources/") != -1) {
    137     return "resources";
    138   }
    139   var basePath = getBaseUri(location.pathname);
    140   return basePath.substring(1,basePath.indexOf("/",1));
    141 }
    142 
    143 function init() {
    144   HEADER_HEIGHT = $("#header").height()+3;
    145   $("#side-nav").css({position:"absolute",left:0});
    146   content = $("#doc-content");
    147   resizePackagesNav = $("#resize-packages-nav");
    148   classesNav = $("#classes-nav");
    149   sidenav = $("#side-nav");
    150   devdocNav = $("#devdoc-nav");
    151 
    152   var cookiePath = getSection() + "_";
    153 
    154   if (!isMobile) {
    155     $("#resize-packages-nav").resizable({handles: "s", resize: function(e, ui) { resizePackagesHeight(); } });
    156     $(".side-nav-resizable").resizable({handles: "e", resize: function(e, ui) { resizeWidth(); } });
    157     var cookieWidth = readCookie(cookiePath+'width');
    158     var cookieHeight = readCookie(cookiePath+'height');
    159     if (cookieWidth) {
    160       restoreWidth(cookieWidth);
    161     } else if ($(".side-nav-resizable").length) {
    162       resizeWidth();
    163     }
    164     if (cookieHeight) {
    165       restoreHeight(cookieHeight);
    166     } else {
    167       resizeHeight();
    168     }
    169   }
    170 
    171   if (devdocNav.length) { // only dev guide, resources, and sdk
    172     tryPopulateResourcesNav();
    173     highlightNav(location.href);
    174   }
    175 }
    176 
    177 function highlightNav(fullPageName) {
    178   var lastSlashPos = fullPageName.lastIndexOf("/");
    179   var firstSlashPos;
    180   if (fullPageName.indexOf("/guide/") != -1) {
    181       firstSlashPos = fullPageName.indexOf("/guide/");
    182     } else if (fullPageName.indexOf("/sdk/") != -1) {
    183       firstSlashPos = fullPageName.indexOf("/sdk/");
    184     } else {
    185       firstSlashPos = fullPageName.indexOf("/resources/");
    186     }
    187   if (lastSlashPos == (fullPageName.length - 1)) { // if the url ends in slash (add 'index.html')
    188     fullPageName = fullPageName + "index.html";
    189   }
    190   // First check if the exact URL, with query string and all, is in the navigation menu
    191   var pathPageName = fullPageName.substr(firstSlashPos);
    192   var link = $("#devdoc-nav a[href$='"+ pathPageName+"']");
    193   if (link.length == 0) {
    194     var htmlPos = fullPageName.lastIndexOf(".html", fullPageName.length);
    195     pathPageName = fullPageName.slice(firstSlashPos, htmlPos + 5); // +5 advances past ".html"
    196     link = $("#devdoc-nav a[href$='"+ pathPageName+"']");
    197     if ((link.length == 0) && ((fullPageName.indexOf("/guide/") != -1) || (fullPageName.indexOf("/resources/") != -1))) {
    198       // if there's no match, then let's backstep through the directory until we find an index.html page
    199       // that matches our ancestor directories (only for dev guide and resources)
    200       lastBackstep = pathPageName.lastIndexOf("/");
    201       while (link.length == 0) {
    202         backstepDirectory = pathPageName.lastIndexOf("/", lastBackstep);
    203         link = $("#devdoc-nav a[href$='"+ pathPageName.slice(0, backstepDirectory + 1)+"index.html']");
    204         lastBackstep = pathPageName.lastIndexOf("/", lastBackstep - 1);
    205         if (lastBackstep == 0) break;
    206       }
    207     }
    208   }
    209 
    210   // add 'selected' to the <li> or <div> that wraps this <a>
    211   link.parent().addClass('selected');
    212 
    213   // if we're in a toggleable root link (<li class=toggle-list><div><a>)
    214   if (link.parent().parent().hasClass('toggle-list')) {
    215     toggle(link.parent().parent(), false); // open our own list
    216     // then also check if we're in a third-level nested list that's toggleable
    217     if (link.parent().parent().parent().is(':hidden')) {
    218       toggle(link.parent().parent().parent().parent(), false); // open the super parent list
    219     }
    220   }
    221   // if we're in a normal nav link (<li><a>) and the parent <ul> is hidden
    222   else if (link.parent().parent().is(':hidden')) {
    223     toggle(link.parent().parent().parent(), false); // open the parent list
    224     // then also check if the parent list is also nested in a hidden list
    225     if (link.parent().parent().parent().parent().is(':hidden')) {
    226       toggle(link.parent().parent().parent().parent().parent(), false); // open the super parent list
    227     }
    228   }
    229 }
    230 
    231 /* Resize the height of the nav panels in the reference,
    232  * and save the new size to a cookie */
    233 function resizePackagesHeight() {
    234   var windowHeight = ($(window).height() - HEADER_HEIGHT);
    235   var swapperHeight = windowHeight - 13; // move 13px for swapper link at the bottom
    236   resizePackagesNav.css({maxHeight:swapperHeight + "px"});
    237   classesNav.css({height:swapperHeight - parseInt(resizePackagesNav.css("height")) + "px"});
    238 
    239   $("#swapper").css({height:swapperHeight + "px"});
    240   $("#packages-nav").css({height:parseInt(resizePackagesNav.css("height")) - 6 + "px"}); //move 6px for handle
    241 
    242   var section = getSection();
    243   writeCookie("height", resizePackagesNav.css("height"), section, null);
    244 }
    245 
    246 /* Resize the height of the side-nav and doc-content divs,
    247  * which creates the frame effect */
    248 function resizeHeight() {
    249   var docContent = $("#doc-content");
    250 
    251   // Get the window height and always resize the doc-content and side-nav divs
    252   var windowHeight = ($(window).height() - HEADER_HEIGHT);
    253   docContent.css({height:windowHeight + "px"});
    254   $("#side-nav").css({height:windowHeight + "px"});
    255 
    256   var href = location.href;
    257   // If in the reference docs, also resize the "swapper", "classes-nav", and "nav-tree"  divs
    258   if (href.indexOf("/reference/") != -1) {
    259     var swapperHeight = windowHeight - 13;
    260     $("#swapper").css({height:swapperHeight + "px"});
    261     $("#classes-nav").css({height:swapperHeight - parseInt(resizePackagesNav.css("height")) + "px"});
    262     $("#nav-tree").css({height:swapperHeight + "px"});
    263 
    264   // If in the dev guide docs, also resize the "devdoc-nav" div
    265   } else if (href.indexOf("/guide/") != -1) {
    266     $("#devdoc-nav").css({height:sidenav.css("height")});
    267   } else if (href.indexOf("/resources/") != -1) {
    268     $("#devdoc-nav").css({height:sidenav.css("height")});
    269   }
    270 
    271   // Hide the "Go to top" link if there's no vertical scroll
    272   if ( parseInt($("#jd-content").css("height")) <= parseInt(docContent.css("height")) ) {
    273     $("a[href='#top']").css({'display':'none'});
    274   } else {
    275     $("a[href='#top']").css({'display':'inline'});
    276   }
    277 }
    278 
    279 /* Resize the width of the "side-nav" and the left margin of the "doc-content" div,
    280  * which creates the resizable side bar */
    281 function resizeWidth() {
    282   var windowWidth = $(window).width() + "px";
    283   if (sidenav.length) {
    284     var sidenavWidth = sidenav.css("width");
    285   } else {
    286     var sidenavWidth = 0;
    287   }
    288   content.css({marginLeft:parseInt(sidenavWidth) + 6 + "px"}); //account for 6px-wide handle-bar
    289 
    290   if (isIE6) {
    291     content.css({width:parseInt(windowWidth) - parseInt(sidenavWidth) - 6 + "px"}); // necessary in order to for scrollbars to be visible
    292   }
    293 
    294   resizePackagesNav.css({width:sidenavWidth});
    295   classesNav.css({width:sidenavWidth});
    296   $("#packages-nav").css({width:sidenavWidth});
    297 
    298   if ($(".side-nav-resizable").length) { // Must check if the nav is resizable because IE6 calls resizeWidth() from resizeAll() for all pages
    299     var section = getSection();
    300     writeCookie("width", sidenavWidth, section, null);
    301   }
    302 }
    303 
    304 /* For IE6 only,
    305  * because it can't properly perform auto width for "doc-content" div,
    306  * avoiding this for all browsers provides better performance */
    307 function resizeAll() {
    308   resizeHeight();
    309   resizeWidth();
    310 }
    311 
    312 function getBaseUri(uri) {
    313   var intlUrl = (uri.substring(0,6) == "/intl/");
    314   if (intlUrl) {
    315     base = uri.substring(uri.indexOf('intl/')+5,uri.length);
    316     base = base.substring(base.indexOf('/')+1, base.length);
    317       //alert("intl, returning base url: /" + base);
    318     return ("/" + base);
    319   } else {
    320       //alert("not intl, returning uri as found.");
    321     return uri;
    322   }
    323 }
    324 
    325 function requestAppendHL(uri) {
    326 //append "?hl=<lang> to an outgoing request (such as to blog)
    327   var lang = getLangPref();
    328   if (lang) {
    329     var q = 'hl=' + lang;
    330     uri += '?' + q;
    331     window.location = uri;
    332     return false;
    333   } else {
    334     return true;
    335   }
    336 }
    337 
    338 function loadLast(cookiePath) {
    339   var location = window.location.href;
    340   if (location.indexOf("/"+cookiePath+"/") != -1) {
    341     return true;
    342   }
    343   var lastPage = readCookie(cookiePath + "_lastpage");
    344   if (lastPage) {
    345     window.location = lastPage;
    346     return false;
    347   }
    348   return true;
    349 }
    350 
    351 $(window).unload(function(){
    352   var path = getBaseUri(location.pathname);
    353   if (path.indexOf("/reference/") != -1) {
    354     writeCookie("lastpage", path, "reference", null);
    355   } else if (path.indexOf("/guide/") != -1) {
    356     writeCookie("lastpage", path, "guide", null);
    357   } else if (path.indexOf("/resources/") != -1) {
    358     writeCookie("lastpage", path, "resources", null);
    359   }
    360 });
    361 
    362 function toggle(obj, slide) {
    363   var ul = $("ul:first", obj);
    364   var li = ul.parent();
    365   if (li.hasClass("closed")) {
    366     if (slide) {
    367       ul.slideDown("fast");
    368     } else {
    369       ul.show();
    370     }
    371     li.removeClass("closed");
    372     li.addClass("open");
    373     $(".toggle-img", li).attr("title", "hide pages");
    374   } else {
    375     ul.slideUp("fast");
    376     li.removeClass("open");
    377     li.addClass("closed");
    378     $(".toggle-img", li).attr("title", "show pages");
    379   }
    380 }
    381 
    382 function buildToggleLists() {
    383   $(".toggle-list").each(
    384     function(i) {
    385       $("div:first", this).append("<a class='toggle-img' href='#' title='show pages' onClick='toggle(this.parentNode.parentNode, true); return false;'></a>");
    386       $(this).addClass("closed");
    387     });
    388 }
    389 
    390 function getNavPref() {
    391   var v = readCookie('reference_nav');
    392   if (v != NAV_PREF_TREE) {
    393     v = NAV_PREF_PANELS;
    394   }
    395   return v;
    396 }
    397 
    398 function chooseDefaultNav() {
    399   nav_pref = getNavPref();
    400   if (nav_pref == NAV_PREF_TREE) {
    401     $("#nav-panels").toggle();
    402     $("#panel-link").toggle();
    403     $("#nav-tree").toggle();
    404     $("#tree-link").toggle();
    405   }
    406 }
    407 
    408 function swapNav() {
    409   if (nav_pref == NAV_PREF_TREE) {
    410     nav_pref = NAV_PREF_PANELS;
    411   } else {
    412     nav_pref = NAV_PREF_TREE;
    413     init_default_navtree(toRoot);
    414   }
    415   var date = new Date();
    416   date.setTime(date.getTime()+(10*365*24*60*60*1000)); // keep this for 10 years
    417   writeCookie("nav", nav_pref, "reference", date.toGMTString());
    418 
    419   $("#nav-panels").toggle();
    420   $("#panel-link").toggle();
    421   $("#nav-tree").toggle();
    422   $("#tree-link").toggle();
    423 
    424   if ($("#nav-tree").is(':visible')) scrollIntoView("nav-tree");
    425   else {
    426     scrollIntoView("packages-nav");
    427     scrollIntoView("classes-nav");
    428   }
    429 }
    430 
    431 function scrollIntoView(nav) {
    432   var navObj = $("#"+nav);
    433   if (navObj.is(':visible')) {
    434     var selected = $(".selected", navObj);
    435     if (selected.length == 0) return;
    436     if (selected.is("div")) selected = selected.parent();
    437 
    438     var scrolling = document.getElementById(nav);
    439     var navHeight = navObj.height();
    440     var offsetTop = selected.position().top;
    441     if (selected.parent().parent().is(".toggle-list")) offsetTop += selected.parent().parent().position().top;
    442     if(offsetTop > navHeight - 92) {
    443       scrolling.scrollTop = offsetTop - navHeight + 92;
    444     }
    445   }
    446 }
    447 
    448 function changeTabLang(lang) {
    449   var nodes = $("#header-tabs").find("."+lang);
    450   for (i=0; i < nodes.length; i++) { // for each node in this language
    451     var node = $(nodes[i]);
    452     node.siblings().css("display","none"); // hide all siblings
    453     if (node.not(":empty").length != 0) { //if this languages node has a translation, show it
    454       node.css("display","inline");
    455     } else { //otherwise, show English instead
    456       node.css("display","none");
    457       node.siblings().filter(".en").css("display","inline");
    458     }
    459   }
    460 }
    461 
    462 function changeNavLang(lang) {
    463   var nodes = $("#side-nav").find("."+lang);
    464   for (i=0; i < nodes.length; i++) { // for each node in this language
    465     var node = $(nodes[i]);
    466     node.siblings().css("display","none"); // hide all siblings
    467     if (node.not(":empty").length != 0) { // if this languages node has a translation, show it
    468       node.css("display","inline");
    469     } else { // otherwise, show English instead
    470       node.css("display","none");
    471       node.siblings().filter(".en").css("display","inline");
    472     }
    473   }
    474 }
    475 
    476 function changeDocLang(lang) {
    477   changeTabLang(lang);
    478   changeNavLang(lang);
    479 }
    480 
    481 function changeLangPref(lang, refresh) {
    482   var date = new Date();
    483   expires = date.toGMTString(date.setTime(date.getTime()+(10*365*24*60*60*1000))); // keep this for 50 years
    484   //alert("expires: " + expires)
    485   writeCookie("pref_lang", lang, null, expires);
    486   //changeDocLang(lang);
    487   if (refresh) {
    488     l = getBaseUri(location.pathname);
    489     window.location = l;
    490   }
    491 }
    492 
    493 function loadLangPref() {
    494   var lang = readCookie("pref_lang");
    495   if (lang != 0) {
    496     $("#language").find("option[value='"+lang+"']").attr("selected",true);
    497   }
    498 }
    499 
    500 function getLangPref() {
    501   var lang = $("#language").find(":selected").attr("value");
    502   if (!lang) {
    503     lang = readCookie("pref_lang");
    504   }
    505   return (lang != 0) ? lang : 'en';
    506 }
    507 
    508 
    509 function toggleContent(obj) {
    510   var button = $(obj);
    511   var div = $(obj.parentNode);
    512   var toggleMe = $(".toggle-content-toggleme",div);
    513   if (button.hasClass("show")) {
    514     toggleMe.slideDown();
    515     button.removeClass("show").addClass("hide");
    516   } else {
    517     toggleMe.slideUp();
    518     button.removeClass("hide").addClass("show");
    519   }
    520   $("span", button).toggle();
    521 }