1var resizePackagesNav; 2var classesNav; 3var devdocNav; 4var sidenav; 5var content; 6var HEADER_HEIGHT = -1; 7var cookie_namespace = 'doclava_developer'; 8var NAV_PREF_TREE = "tree"; 9var NAV_PREF_PANELS = "panels"; 10var nav_pref; 11var toRoot; 12var isMobile = false; // true if mobile, so we can adjust some layout 13var isIE6 = false; // true if IE6 14 15// TODO: use $(document).ready instead 16function 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 28var agent = navigator['userAgent'].toLowerCase(); 29// If a mobile phone, set flag and do mobile setup 30if ((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 48function 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. 58Loading this in the head was slowing page load time */ 59addLoadEvent( 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 66addLoadEvent( function() { 67 $("pre:not(.no-pretty-print)").addClass("prettyprint"); 68 prettyPrint(); 69} ); 70 71function setToRoot(root) { 72 toRoot = root; 73 // note: toRoot also used by carousel.js 74} 75 76function 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 90function 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 103function 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 120function 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 131function 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 143function 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 177function 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 */ 233function 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 */ 248function 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 */ 281function 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 */ 307function resizeAll() { 308 resizeHeight(); 309 resizeWidth(); 310} 311 312function 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 325function 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 338function 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 362function 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 382function 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 390function getNavPref() { 391 var v = readCookie('reference_nav'); 392 if (v != NAV_PREF_TREE) { 393 v = NAV_PREF_PANELS; 394 } 395 return v; 396} 397 398function 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 408function 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 431function 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 448function 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 462function 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 476function changeDocLang(lang) { 477 changeTabLang(lang); 478 changeNavLang(lang); 479} 480 481function 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 493function loadLangPref() { 494 var lang = readCookie("pref_lang"); 495 if (lang != 0) { 496 $("#language").find("option[value='"+lang+"']").attr("selected",true); 497 } 498} 499 500function 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 509function 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}