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 = 117;
      7 var cookie_namespace = 'android_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 init() {
    132   $("#side-nav").css({position:"absolute",left:0});
    133   content = $("#doc-content");
    134   resizePackagesNav = $("#resize-packages-nav");
    135   classesNav = $("#classes-nav");
    136   sidenav = $("#side-nav");
    137   devdocNav = $("#devdoc-nav");
    138 
    139   var cookiePath = "";
    140   if (location.href.indexOf("/reference/") != -1) {
    141     cookiePath = "reference_";
    142   } else if (location.href.indexOf("/guide/") != -1) {
    143     cookiePath = "guide_";
    144   } else if (location.href.indexOf("/resources/") != -1) {
    145     cookiePath = "resources_";
    146   }
    147 
    148   if (!isMobile) {
    149     $("#resize-packages-nav").resizable({handles: "s", resize: function(e, ui) { resizePackagesHeight(); } });
    150     $(".side-nav-resizable").resizable({handles: "e", resize: function(e, ui) { resizeWidth(); } });
    151     var cookieWidth = readCookie(cookiePath+'width');
    152     var cookieHeight = readCookie(cookiePath+'height');
    153     if (cookieWidth) {
    154       restoreWidth(cookieWidth);
    155     } else if ($(".side-nav-resizable").length) {
    156       resizeWidth();
    157     }
    158     if (cookieHeight) {
    159       restoreHeight(cookieHeight);
    160     } else {
    161       resizeHeight();
    162     }
    163   }
    164 
    165   if (devdocNav.length) { // only dev guide and sdk 
    166     highlightNav(location.href); 
    167   }
    168 }
    169 
    170 function highlightNav(fullPageName) {
    171   var lastSlashPos = fullPageName.lastIndexOf("/");
    172   var firstSlashPos;
    173   if (fullPageName.indexOf("/guide/") != -1) {
    174       firstSlashPos = fullPageName.indexOf("/guide/");
    175     } else if (fullPageName.indexOf("/sdk/") != -1) {
    176       firstSlashPos = fullPageName.indexOf("/sdk/");
    177     } else {
    178       firstSlashPos = fullPageName.indexOf("/resources/");
    179     }
    180   if (lastSlashPos == (fullPageName.length - 1)) { // if the url ends in slash (add 'index.html')
    181     fullPageName = fullPageName + "index.html";
    182   }
    183   var htmlPos = fullPageName.lastIndexOf(".html", fullPageName.length);
    184   var pathPageName = fullPageName.slice(firstSlashPos, htmlPos + 5);
    185   var link = $("#devdoc-nav a[href$='"+ pathPageName+"']");
    186   if ((link.length == 0) && ((fullPageName.indexOf("/guide/") != -1) || (fullPageName.indexOf("/resources/") != -1))) { 
    187 // if there's no match, then let's backstep through the directory until we find an index.html page that matches our ancestor directories (only for dev guide)
    188     lastBackstep = pathPageName.lastIndexOf("/");
    189     while (link.length == 0) {
    190       backstepDirectory = pathPageName.lastIndexOf("/", lastBackstep);
    191       link = $("#devdoc-nav a[href$='"+ pathPageName.slice(0, backstepDirectory + 1)+"index.html']");
    192       lastBackstep = pathPageName.lastIndexOf("/", lastBackstep - 1);
    193       if (lastBackstep == 0) break;
    194     }
    195   }
    196 
    197   // add 'selected' to the <li> or <div> that wraps this <a>
    198   link.parent().addClass('selected');
    199 
    200   // if we're in a toggleable root link (<li class=toggle-list><div><a>)
    201   if (link.parent().parent().hasClass('toggle-list')) {
    202     toggle(link.parent().parent(), false); // open our own list
    203     // then also check if we're in a third-level nested list that's toggleable
    204     if (link.parent().parent().parent().is(':hidden')) {
    205       toggle(link.parent().parent().parent().parent(), false); // open the super parent list
    206     }
    207   }
    208   // if we're in a normal nav link (<li><a>) and the parent <ul> is hidden
    209   else if (link.parent().parent().is(':hidden')) {
    210     toggle(link.parent().parent().parent(), false); // open the parent list
    211     // then also check if the parent list is also nested in a hidden list
    212     if (link.parent().parent().parent().parent().is(':hidden')) {
    213       toggle(link.parent().parent().parent().parent().parent(), false); // open the super parent list
    214     }
    215   }
    216 }
    217 
    218 /* Resize the height of the nav panels in the reference,
    219  * and save the new size to a cookie */
    220 function resizePackagesHeight() {
    221   var windowHeight = ($(window).height() - HEADER_HEIGHT);
    222   var swapperHeight = windowHeight - 13; // move 13px for swapper link at the bottom
    223   resizePackagesNav.css({maxHeight:swapperHeight + "px"});
    224   classesNav.css({height:swapperHeight - parseInt(resizePackagesNav.css("height")) + "px"});
    225 
    226   $("#swapper").css({height:swapperHeight + "px"});
    227   $("#packages-nav").css({height:parseInt(resizePackagesNav.css("height")) - 6 + "px"}); //move 6px for handle
    228 
    229   var basePath = getBaseUri(location.pathname);
    230   var section = basePath.substring(1,basePath.indexOf("/",1));
    231   writeCookie("height", resizePackagesNav.css("height"), section, null);
    232 }
    233 
    234 /* Resize the height of the side-nav and doc-content divs,
    235  * which creates the frame effect */
    236 function resizeHeight() {
    237   var docContent = $("#doc-content");
    238 
    239   // Get the window height and always resize the doc-content and side-nav divs
    240   var windowHeight = ($(window).height() - HEADER_HEIGHT);
    241   docContent.css({height:windowHeight + "px"});
    242   $("#side-nav").css({height:windowHeight + "px"});
    243 
    244   var href = location.href;
    245   // If in the reference docs, also resize the "swapper", "classes-nav", and "nav-tree"  divs
    246   if (href.indexOf("/reference/") != -1) {
    247     var swapperHeight = windowHeight - 13;
    248     $("#swapper").css({height:swapperHeight + "px"});
    249     $("#classes-nav").css({height:swapperHeight - parseInt(resizePackagesNav.css("height")) + "px"});
    250     $("#nav-tree").css({height:swapperHeight + "px"});
    251 
    252   // If in the dev guide docs, also resize the "devdoc-nav" div
    253   } else if (href.indexOf("/guide/") != -1) {
    254     $("#devdoc-nav").css({height:sidenav.css("height")});
    255   } else if (href.indexOf("/resources/") != -1) {
    256     $("#devdoc-nav").css({height:sidenav.css("height")});
    257   }
    258 
    259   // Hide the "Go to top" link if there's no vertical scroll
    260   if ( parseInt($("#jd-content").css("height")) <= parseInt(docContent.css("height")) ) {
    261     $("a[href='#top']").css({'display':'none'});
    262   } else {
    263     $("a[href='#top']").css({'display':'inline'});
    264   }
    265 }
    266 
    267 /* Resize the width of the "side-nav" and the left margin of the "doc-content" div,
    268  * which creates the resizable side bar */
    269 function resizeWidth() {
    270   var windowWidth = $(window).width() + "px";
    271   if (sidenav.length) {
    272     var sidenavWidth = sidenav.css("width");
    273   } else {
    274     var sidenavWidth = 0;
    275   }
    276   content.css({marginLeft:parseInt(sidenavWidth) + 6 + "px"}); //account for 6px-wide handle-bar
    277 
    278   if (isIE6) {
    279     content.css({width:parseInt(windowWidth) - parseInt(sidenavWidth) - 6 + "px"}); // necessary in order to for scrollbars to be visible
    280   }
    281 
    282   resizePackagesNav.css({width:sidenavWidth});
    283   classesNav.css({width:sidenavWidth});
    284   $("#packages-nav").css({width:sidenavWidth});
    285 
    286   if ($(".side-nav-resizable").length) { // Must check if the nav is resizable because IE6 calls resizeWidth() from resizeAll() for all pages
    287     var basePath = getBaseUri(location.pathname);
    288     var section = basePath.substring(1,basePath.indexOf("/",1));
    289     writeCookie("width", sidenavWidth, section, null);
    290   }
    291 }
    292 
    293 /* For IE6 only,
    294  * because it can't properly perform auto width for "doc-content" div,
    295  * avoiding this for all browsers provides better performance */
    296 function resizeAll() {
    297   resizeHeight();
    298   resizeWidth();
    299 }
    300 
    301 function getBaseUri(uri) {
    302   var intlUrl = (uri.substring(0,6) == "/intl/");
    303   if (intlUrl) {
    304     base = uri.substring(uri.indexOf('intl/')+5,uri.length);
    305     base = base.substring(base.indexOf('/')+1, base.length);
    306       //alert("intl, returning base url: /" + base);
    307     return ("/" + base);
    308   } else {
    309       //alert("not intl, returning uri as found.");
    310     return uri;
    311   }
    312 }
    313 
    314 function requestAppendHL(uri) {
    315 //append "?hl=<lang> to an outgoing request (such as to blog)
    316   var lang = getLangPref();
    317   if (lang) {
    318     var q = 'hl=' + lang;
    319     uri += '?' + q;
    320     window.location = uri;
    321     return false;
    322   } else {
    323     return true;
    324   }
    325 }
    326 
    327 function loadLast(cookiePath) {
    328   var location = window.location.href;
    329   if (location.indexOf("/"+cookiePath+"/") != -1) {
    330     return true;
    331   }
    332   var lastPage = readCookie(cookiePath + "_lastpage");
    333   if (lastPage) {
    334     window.location = lastPage;
    335     return false;
    336   }
    337   return true;
    338 }
    339 
    340 $(window).unload(function(){
    341   var path = getBaseUri(location.pathname);
    342   if (path.indexOf("/reference/") != -1) {
    343     writeCookie("lastpage", path, "reference", null);
    344   } else if (path.indexOf("/guide/") != -1) {
    345     writeCookie("lastpage", path, "guide", null);
    346   } else if (path.indexOf("/resources/") != -1) {
    347     writeCookie("lastpage", path, "resources", null);
    348   }
    349 });
    350 
    351 function toggle(obj, slide) {
    352   var ul = $("ul:first", obj);
    353   var li = ul.parent();
    354   if (li.hasClass("closed")) {
    355     if (slide) {
    356       ul.slideDown("fast");
    357     } else {
    358       ul.show();
    359     }
    360     li.removeClass("closed");
    361     li.addClass("open");
    362     $(".toggle-img", li).attr("title", "hide pages");
    363   } else {
    364     ul.slideUp("fast");
    365     li.removeClass("open");
    366     li.addClass("closed");
    367     $(".toggle-img", li).attr("title", "show pages");
    368   }
    369 }
    370 
    371 function buildToggleLists() {
    372   $(".toggle-list").each(
    373     function(i) {
    374       $("div:first", this).append("<a class='toggle-img' href='#' title='show pages' onClick='toggle(this.parentNode.parentNode, true); return false;'></a>");
    375       $(this).addClass("closed");
    376     });
    377 }
    378 
    379 function getNavPref() {
    380   var v = readCookie('reference_nav');
    381   if (v != NAV_PREF_TREE) {
    382     v = NAV_PREF_PANELS;
    383   }
    384   return v;
    385 }
    386 
    387 function chooseDefaultNav() {
    388   nav_pref = getNavPref();
    389   if (nav_pref == NAV_PREF_TREE) {
    390     $("#nav-panels").toggle();
    391     $("#panel-link").toggle();
    392     $("#nav-tree").toggle();
    393     $("#tree-link").toggle();
    394   }
    395 }
    396 
    397 function swapNav() {
    398   if (nav_pref == NAV_PREF_TREE) {
    399     nav_pref = NAV_PREF_PANELS;
    400   } else {
    401     nav_pref = NAV_PREF_TREE;
    402     init_default_navtree(toRoot);
    403   }
    404   var date = new Date();
    405   date.setTime(date.getTime()+(10*365*24*60*60*1000)); // keep this for 10 years
    406   writeCookie("nav", nav_pref, "reference", date.toGMTString());
    407 
    408   $("#nav-panels").toggle();
    409   $("#panel-link").toggle();
    410   $("#nav-tree").toggle();
    411   $("#tree-link").toggle();
    412 
    413   if ($("#nav-tree").is(':visible')) scrollIntoView("nav-tree");
    414   else {
    415     scrollIntoView("packages-nav");
    416     scrollIntoView("classes-nav");
    417   }
    418 }
    419 
    420 function scrollIntoView(nav) {
    421   var navObj = $("#"+nav);
    422   if (navObj.is(':visible')) {
    423     var selected = $(".selected", navObj);
    424     if (selected.length == 0) return;
    425     if (selected.is("div")) selected = selected.parent();
    426 
    427     var scrolling = document.getElementById(nav);
    428     var navHeight = navObj.height();
    429     var offsetTop = selected.position().top;
    430     if (selected.parent().parent().is(".toggle-list")) offsetTop += selected.parent().parent().position().top;
    431     if(offsetTop > navHeight - 92) {
    432       scrolling.scrollTop = offsetTop - navHeight + 92;
    433     }
    434   }
    435 }
    436 
    437 function changeTabLang(lang) {
    438   var nodes = $("#header-tabs").find("."+lang);
    439   for (i=0; i < nodes.length; i++) { // for each node in this language 
    440     var node = $(nodes[i]);
    441     node.siblings().css("display","none"); // hide all siblings 
    442     if (node.not(":empty").length != 0) { //if this languages node has a translation, show it 
    443       node.css("display","inline");
    444     } else { //otherwise, show English instead 
    445       node.css("display","none");
    446       node.siblings().filter(".en").css("display","inline");
    447     }
    448   }
    449 }
    450 
    451 function changeNavLang(lang) {
    452   var nodes = $("#side-nav").find("."+lang);
    453   for (i=0; i < nodes.length; i++) { // for each node in this language 
    454     var node = $(nodes[i]);
    455     node.siblings().css("display","none"); // hide all siblings 
    456     if (node.not(":empty").length != 0) { // if this languages node has a translation, show it 
    457       node.css("display","inline");
    458     } else { // otherwise, show English instead 
    459       node.css("display","none");
    460       node.siblings().filter(".en").css("display","inline");
    461     }
    462   }
    463 }
    464 
    465 function changeDocLang(lang) {
    466   changeTabLang(lang);
    467   changeNavLang(lang);
    468 }
    469 
    470 function changeLangPref(lang, refresh) {
    471   var date = new Date();
    472   expires = date.toGMTString(date.setTime(date.getTime()+(10*365*24*60*60*1000))); // keep this for 50 years
    473   //alert("expires: " + expires)
    474   writeCookie("pref_lang", lang, null, expires);
    475   //changeDocLang(lang);
    476   if (refresh) {
    477     l = getBaseUri(location.pathname);
    478     window.location = l;
    479   }
    480 }
    481 
    482 function loadLangPref() {
    483   var lang = readCookie("pref_lang");
    484   if (lang != 0) {
    485     $("#language").find("option[value='"+lang+"']").attr("selected",true);
    486   }
    487 }
    488 
    489 function getLangPref() {
    490   var lang = $("#language").find(":selected").attr("value");
    491   if (!lang) {
    492     lang = readCookie("pref_lang");
    493   }
    494   return (lang != 0) ? lang : 'en';
    495 }
    496 
    497 
    498 function toggleContent(obj) {
    499   var button = $(obj);
    500   var div = $(obj.parentNode);
    501   var toggleMe = $(".toggle-content-toggleme",div);
    502   if (button.hasClass("show")) {
    503     toggleMe.slideDown();
    504     button.removeClass("show").addClass("hide");
    505   } else {
    506     toggleMe.slideUp();
    507     button.removeClass("hide").addClass("show");
    508   }
    509   $("span", button).toggle();
    510 }
    511