1 2 /* Initialize some droiddoc stuff */ 3 $(document).ready(function() { 4 5 // init available apis based on user pref 6 changeApiLevel(); 7 initSidenavHeightResize() 8 }); 9 10 var API_LEVEL_COOKIE = "api_level"; 11 var minLevel = 1; 12 var maxLevel = 1; 13 14 /******* SIDENAV DIMENSIONS ************/ 15 16 17 function initSidenavHeightResize() { 18 // Change the drag bar size to nicely fit the scrollbar positions 19 var $dragBar = $(".ui-resizable-s"); 20 $dragBar.css({'width': $dragBar.parent().width() - 5 + "px"}); 21 22 $( "#resize-packages-nav" ).resizable({ 23 containment: "#nav-panels", 24 handles: "s", 25 alsoResize: "#packages-nav", 26 resize: function(event, ui) { resizeNav(); }, /* resize the nav while dragging */ 27 stop: function(event, ui) { saveNavPanels(); } /* once stopped, save the sizes to cookie */ 28 }); 29 30 } 31 32 function updateSidenavFixedWidth() { 33 if (!navBarIsFixed) return; 34 $('#devdoc-nav').css({ 35 'width' : $('#side-nav').css('width'), 36 'margin' : $('#side-nav').css('margin') 37 }); 38 $('#devdoc-nav a.totop').css({'display':'block','width':$("#nav").innerWidth()+'px'}); 39 40 initSidenavHeightResize(); 41 } 42 43 function updateSidenavFullscreenWidth() { 44 if (!navBarIsFixed) return; 45 $('#devdoc-nav').css({ 46 'width' : $('#side-nav').css('width'), 47 'margin' : $('#side-nav').css('margin') 48 }); 49 $('#devdoc-nav .totop').css({'left': 'inherit'}); 50 51 initSidenavHeightResize(); 52 } 53 54 function buildApiLevelSelector() { 55 maxLevel = SINCE_DATA.length; 56 var userApiLevel = parseInt(readCookie(API_LEVEL_COOKIE)); 57 userApiLevel = userApiLevel == 0 ? maxLevel : userApiLevel; // If there's no cookie (zero), use the max by default 58 59 minLevel = parseInt($("#doc-api-level").attr("class")); 60 // Handle provisional api levels; the provisional level will always be the highest possible level 61 // Provisional api levels will also have a length; other stuff that's just missing a level won't, 62 // so leave those kinds of entities at the default level of 1 (for example, the R.styleable class) 63 if (isNaN(minLevel) && minLevel.length) { 64 minLevel = maxLevel; 65 } 66 var select = $("#apiLevelSelector").html("").change(changeApiLevel); 67 for (var i = maxLevel-1; i >= 0; i--) { 68 var option = $("<option />").attr("value",""+SINCE_DATA[i]).append(""+SINCE_DATA[i]); 69 // if (SINCE_DATA[i] < minLevel) option.addClass("absent"); // always false for strings (codenames) 70 select.append(option); 71 } 72 73 // get the DOM element and use setAttribute cuz IE6 fails when using jquery .attr('selected',true) 74 var selectedLevelItem = $("#apiLevelSelector option[value='"+userApiLevel+"']").get(0); 75 selectedLevelItem.setAttribute('selected',true); 76 } 77 78 function changeApiLevel() { 79 maxLevel = SINCE_DATA.length; 80 var selectedLevel = maxLevel; 81 82 selectedLevel = parseInt($("#apiLevelSelector option:selected").val()); 83 toggleVisisbleApis(selectedLevel, "body"); 84 85 var date = new Date(); 86 date.setTime(date.getTime()+(10*365*24*60*60*1000)); // keep this for 10 years 87 var expiration = date.toGMTString(); 88 writeCookie(API_LEVEL_COOKIE, selectedLevel, null, expiration); 89 90 if (selectedLevel < minLevel) { 91 var thing = ($("#jd-header").html().indexOf("package") != -1) ? "package" : "class"; 92 $("#naMessage").show().html("<div><p><strong>This " + thing + " is not available with API level " + selectedLevel + ".</strong></p>" 93 + "<p>To use this " + thing + ", you must develop your app using a build target " 94 + "that supports API level " + $("#doc-api-level").attr("class") + " or higher. To read these " 95 + "APIs, change the value of the API level filter above.</p>" 96 + "<p><a href='" +toRoot+ "guide/appendix/api-levels.html'>What is the API level?</a></p></div>"); 97 } else { 98 $("#naMessage").hide(); 99 } 100 } 101 102 function toggleVisisbleApis(selectedLevel, context) { 103 var apis = $(".api",context); 104 apis.each(function(i) { 105 var obj = $(this); 106 var className = obj.attr("class"); 107 var apiLevelIndex = className.lastIndexOf("-")+1; 108 var apiLevelEndIndex = className.indexOf(" ", apiLevelIndex); 109 apiLevelEndIndex = apiLevelEndIndex != -1 ? apiLevelEndIndex : className.length; 110 var apiLevel = className.substring(apiLevelIndex, apiLevelEndIndex); 111 if (apiLevel.length == 0) { // for odd cases when the since data is actually missing, just bail 112 return; 113 } 114 apiLevel = parseInt(apiLevel); 115 116 // Handle provisional api levels; if this item's level is the provisional one, set it to the max 117 var selectedLevelNum = parseInt(selectedLevel) 118 var apiLevelNum = parseInt(apiLevel); 119 if (isNaN(apiLevelNum)) { 120 apiLevelNum = maxLevel; 121 } 122 123 // Grey things out that aren't available and give a tooltip title 124 if (apiLevelNum > selectedLevelNum) { 125 obj.addClass("absent").attr("title","Requires API Level \"" 126 + apiLevel + "\" or higher"); 127 } 128 else obj.removeClass("absent").removeAttr("title"); 129 }); 130 } 131 132 133 134 135 136 137 138 139 140 141 /* NAVTREE */ 142 143 function new_node(me, mom, text, link, children_data, api_level) 144 { 145 var node = new Object(); 146 node.children = Array(); 147 node.children_data = children_data; 148 node.depth = mom.depth + 1; 149 150 node.li = document.createElement("li"); 151 mom.get_children_ul().appendChild(node.li); 152 153 node.label_div = document.createElement("div"); 154 node.label_div.className = "label"; 155 if (api_level != null) { 156 $(node.label_div).addClass("api"); 157 $(node.label_div).addClass("api-level-"+api_level); 158 } 159 node.li.appendChild(node.label_div); 160 161 if (children_data != null) { 162 node.expand_toggle = document.createElement("a"); 163 node.expand_toggle.href = "javascript:void(0)"; 164 node.expand_toggle.onclick = function() { 165 if (node.expanded) { 166 $(node.get_children_ul()).slideUp("fast"); 167 node.plus_img.src = me.toroot + "assets/images/triangle-closed-small.png"; 168 node.expanded = false; 169 } else { 170 expand_node(me, node); 171 } 172 }; 173 node.label_div.appendChild(node.expand_toggle); 174 175 node.plus_img = document.createElement("img"); 176 node.plus_img.src = me.toroot + "assets/images/triangle-closed-small.png"; 177 node.plus_img.className = "plus"; 178 node.plus_img.width = "8"; 179 node.plus_img.border = "0"; 180 node.expand_toggle.appendChild(node.plus_img); 181 182 node.expanded = false; 183 } 184 185 var a = document.createElement("a"); 186 node.label_div.appendChild(a); 187 node.label = document.createTextNode(text); 188 a.appendChild(node.label); 189 if (link) { 190 a.href = me.toroot + link; 191 } else { 192 if (children_data != null) { 193 a.className = "nolink"; 194 a.href = "javascript:void(0)"; 195 a.onclick = node.expand_toggle.onclick; 196 // This next line shouldn't be necessary. I'll buy a beer for the first 197 // person who figures out how to remove this line and have the link 198 // toggle shut on the first try. --joeo (a] android.com 199 node.expanded = false; 200 } 201 } 202 203 204 node.children_ul = null; 205 node.get_children_ul = function() { 206 if (!node.children_ul) { 207 node.children_ul = document.createElement("ul"); 208 node.children_ul.className = "children_ul"; 209 node.children_ul.style.display = "none"; 210 node.li.appendChild(node.children_ul); 211 } 212 return node.children_ul; 213 }; 214 215 return node; 216 } 217 218 function expand_node(me, node) 219 { 220 if (node.children_data && !node.expanded) { 221 if (node.children_visited) { 222 $(node.get_children_ul()).slideDown("fast"); 223 } else { 224 get_node(me, node); 225 if ($(node.label_div).hasClass("absent")) { 226 $(node.get_children_ul()).addClass("absent"); 227 } 228 $(node.get_children_ul()).slideDown("fast"); 229 } 230 node.plus_img.src = me.toroot + "assets/images/triangle-opened-small.png"; 231 node.expanded = true; 232 233 // perform api level toggling because new nodes are new to the DOM 234 var selectedLevel = $("#apiLevelSelector option:selected").val(); 235 toggleVisisbleApis(selectedLevel, "#side-nav"); 236 } 237 } 238 239 function get_node(me, mom) 240 { 241 mom.children_visited = true; 242 for (var i in mom.children_data) { 243 var node_data = mom.children_data[i]; 244 mom.children[i] = new_node(me, mom, node_data[0], node_data[1], 245 node_data[2], node_data[3]); 246 } 247 } 248 249 function this_page_relative(toroot) 250 { 251 var full = document.location.pathname; 252 var file = ""; 253 if (toroot.substr(0, 1) == "/") { 254 if (full.substr(0, toroot.length) == toroot) { 255 return full.substr(toroot.length); 256 } else { 257 // the file isn't under toroot. Fail. 258 return null; 259 } 260 } else { 261 if (toroot != "./") { 262 toroot = "./" + toroot; 263 } 264 do { 265 if (toroot.substr(toroot.length-3, 3) == "../" || toroot == "./") { 266 var pos = full.lastIndexOf("/"); 267 file = full.substr(pos) + file; 268 full = full.substr(0, pos); 269 toroot = toroot.substr(0, toroot.length-3); 270 } 271 } while (toroot != "" && toroot != "/"); 272 return file.substr(1); 273 } 274 } 275 276 function find_page(url, data) 277 { 278 var nodes = data; 279 var result = null; 280 for (var i in nodes) { 281 var d = nodes[i]; 282 if (d[1] == url) { 283 return new Array(i); 284 } 285 else if (d[2] != null) { 286 result = find_page(url, d[2]); 287 if (result != null) { 288 return (new Array(i).concat(result)); 289 } 290 } 291 } 292 return null; 293 } 294 295 function load_navtree_data(toroot) { 296 var navtreeData = document.createElement("script"); 297 navtreeData.setAttribute("type","text/javascript"); 298 navtreeData.setAttribute("src", toroot+"navtree_data.js"); 299 $("head").append($(navtreeData)); 300 } 301 302 function init_default_navtree(toroot) { 303 init_navtree("tree-list", toroot, NAVTREE_DATA); 304 305 // perform api level toggling because because the whole tree is new to the DOM 306 var selectedLevel = $("#apiLevelSelector option:selected").val(); 307 toggleVisisbleApis(selectedLevel, "#side-nav"); 308 } 309 310 function init_navtree(navtree_id, toroot, root_nodes) 311 { 312 var me = new Object(); 313 me.toroot = toroot; 314 me.node = new Object(); 315 316 me.node.li = document.getElementById(navtree_id); 317 me.node.children_data = root_nodes; 318 me.node.children = new Array(); 319 me.node.children_ul = document.createElement("ul"); 320 me.node.get_children_ul = function() { return me.node.children_ul; }; 321 //me.node.children_ul.className = "children_ul"; 322 me.node.li.appendChild(me.node.children_ul); 323 me.node.depth = 0; 324 325 get_node(me, me.node); 326 327 me.this_page = this_page_relative(toroot); 328 me.breadcrumbs = find_page(me.this_page, root_nodes); 329 if (me.breadcrumbs != null && me.breadcrumbs.length != 0) { 330 var mom = me.node; 331 for (var i in me.breadcrumbs) { 332 var j = me.breadcrumbs[i]; 333 mom = mom.children[j]; 334 expand_node(me, mom); 335 } 336 mom.label_div.className = mom.label_div.className + " selected"; 337 addLoadEvent(function() { 338 scrollIntoView("nav-tree"); 339 }); 340 } 341 } 342 343 /* TOGGLE INHERITED MEMBERS */ 344 345 /* Toggle an inherited class (arrow toggle) 346 * @param linkObj The link that was clicked. 347 * @param expand 'true' to ensure it's expanded. 'false' to ensure it's closed. 348 * 'null' to simply toggle. 349 */ 350 function toggleInherited(linkObj, expand) { 351 var base = linkObj.getAttribute("id"); 352 var list = document.getElementById(base + "-list"); 353 var summary = document.getElementById(base + "-summary"); 354 var trigger = document.getElementById(base + "-trigger"); 355 var a = $(linkObj); 356 if ( (expand == null && a.hasClass("closed")) || expand ) { 357 list.style.display = "none"; 358 summary.style.display = "block"; 359 trigger.src = toRoot + "assets/images/triangle-opened.png"; 360 a.removeClass("closed"); 361 a.addClass("opened"); 362 } else if ( (expand == null && a.hasClass("opened")) || (expand == false) ) { 363 list.style.display = "block"; 364 summary.style.display = "none"; 365 trigger.src = toRoot + "assets/images/triangle-closed.png"; 366 a.removeClass("opened"); 367 a.addClass("closed"); 368 } 369 return false; 370 } 371 372 /* Toggle all inherited classes in a single table (e.g. all inherited methods) 373 * @param linkObj The link that was clicked. 374 * @param expand 'true' to ensure it's expanded. 'false' to ensure it's closed. 375 * 'null' to simply toggle. 376 */ 377 function toggleAllInherited(linkObj, expand) { 378 var a = $(linkObj); 379 var table = $(a.parent().parent().parent()); // ugly way to get table/tbody 380 var expandos = $(".jd-expando-trigger", table); 381 if ( (expand == null && a.text() == "[Expand]") || expand ) { 382 expandos.each(function(i) { 383 toggleInherited(this, true); 384 }); 385 a.text("[Collapse]"); 386 } else if ( (expand == null && a.text() == "[Collapse]") || (expand == false) ) { 387 expandos.each(function(i) { 388 toggleInherited(this, false); 389 }); 390 a.text("[Expand]"); 391 } 392 return false; 393 } 394 395 /* Toggle all inherited members in the class (link in the class title) 396 */ 397 function toggleAllClassInherited() { 398 var a = $("#toggleAllClassInherited"); // get toggle link from class title 399 var toggles = $(".toggle-all", $("#body-content")); 400 if (a.text() == "[Expand All]") { 401 toggles.each(function(i) { 402 toggleAllInherited(this, true); 403 }); 404 a.text("[Collapse All]"); 405 } else { 406 toggles.each(function(i) { 407 toggleAllInherited(this, false); 408 }); 409 a.text("[Expand All]"); 410 } 411 return false; 412 } 413 414 /* Expand all inherited members in the class. Used when initiating page search */ 415 function ensureAllInheritedExpanded() { 416 var toggles = $(".toggle-all", $("#body-content")); 417 toggles.each(function(i) { 418 toggleAllInherited(this, true); 419 }); 420 $("#toggleAllClassInherited").text("[Collapse All]"); 421 } 422 423 424 /* HANDLE KEY EVENTS 425 * - Listen for Ctrl+F (Cmd on Mac) and expand all inherited members (to aid page search) 426 */ 427 var agent = navigator['userAgent'].toLowerCase(); 428 var mac = agent.indexOf("macintosh") != -1; 429 430 $(document).keydown( function(e) { 431 var control = mac ? e.metaKey && !e.ctrlKey : e.ctrlKey; // get ctrl key 432 if (control && e.which == 70) { // 70 is "F" 433 ensureAllInheritedExpanded(); 434 } 435 });