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