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