411 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			411 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
| 
 | |
| /* API LEVEL TOGGLE */
 | |
| addLoadEvent(changeApiLevel);
 | |
| 
 | |
| var API_LEVEL_ENABLED_COOKIE = "api_level_enabled";
 | |
| var API_LEVEL_COOKIE = "api_level";
 | |
| var minLevel = 1;
 | |
| var maxLevel = 1;
 | |
| 
 | |
| function toggleApiLevelSelector(checkbox) {
 | |
|   var date = new Date();
 | |
|   date.setTime(date.getTime()+(10*365*24*60*60*1000)); // keep this for 10 years
 | |
|   var expiration = date.toGMTString();
 | |
|   if (checkbox.checked) {
 | |
|     $("#apiLevelSelector").removeAttr("disabled");
 | |
|     $("#api-level-toggle label").removeClass("disabled");
 | |
|     writeCookie(API_LEVEL_ENABLED_COOKIE, 1, null, expiration);
 | |
|   } else {
 | |
|     $("#apiLevelSelector").attr("disabled","disabled");
 | |
|     $("#api-level-toggle label").addClass("disabled");
 | |
|     writeCookie(API_LEVEL_ENABLED_COOKIE, 0, null, expiration);
 | |
|   }
 | |
|   changeApiLevel();
 | |
| }
 | |
| 
 | |
| function buildApiLevelSelector() {
 | |
|   maxLevel = SINCE_DATA.length;
 | |
|   var userApiLevelEnabled = readCookie(API_LEVEL_ENABLED_COOKIE);
 | |
|   var userApiLevel = parseInt(readCookie(API_LEVEL_COOKIE));
 | |
|   userApiLevel = userApiLevel == 0 ? maxLevel : userApiLevel; // If there's no cookie (zero), use the max by default
 | |
| 
 | |
|   if (userApiLevelEnabled == 0) {
 | |
|     $("#apiLevelSelector").attr("disabled","disabled");
 | |
|   } else {
 | |
|     $("#apiLevelCheckbox").attr("checked","checked");
 | |
|     $("#api-level-toggle label").removeClass("disabled");
 | |
|   }
 | |
| 
 | |
|   minLevel = parseInt($("body").attr("class"));
 | |
|   // Handle provisional api levels; the provisional level will always be the highest possible level
 | |
|   // Provisional api levels will also have a length; other stuff that's just missing a level won't,
 | |
|   // so leave those kinds of entities at the default level of 1 (for example, the R.styleable class)
 | |
|   if (isNaN(minLevel) && minLevel.length) {
 | |
|     minLevel = maxLevel;
 | |
|   }
 | |
|   var select = $("#apiLevelSelector").html("").change(changeApiLevel);
 | |
|   for (var i = maxLevel-1; i >= 0; i--) {
 | |
|     var option = $("<option />").attr("value",""+SINCE_DATA[i]).append(""+SINCE_DATA[i]);
 | |
|   //  if (SINCE_DATA[i] < minLevel) option.addClass("absent"); // always false for strings (codenames)
 | |
|     select.append(option);
 | |
|   }
 | |
| 
 | |
|   // get the DOM element and use setAttribute cuz IE6 fails when using jquery .attr('selected',true)
 | |
|   var selectedLevelItem = $("#apiLevelSelector option[value='"+userApiLevel+"']").get(0);
 | |
|   selectedLevelItem.setAttribute('selected',true);
 | |
| }
 | |
| 
 | |
| function changeApiLevel() {
 | |
|   maxLevel = SINCE_DATA.length;
 | |
|   var userApiLevelEnabled = readCookie(API_LEVEL_ENABLED_COOKIE);
 | |
|   var selectedLevel = maxLevel;
 | |
| 
 | |
|   if (userApiLevelEnabled == 0) {
 | |
|     toggleVisisbleApis(selectedLevel, "body");
 | |
|   } else {
 | |
|     selectedLevel = parseInt($("#apiLevelSelector option:selected").val());
 | |
|     toggleVisisbleApis(selectedLevel, "body");
 | |
| 
 | |
|     var date = new Date();
 | |
|     date.setTime(date.getTime()+(10*365*24*60*60*1000)); // keep this for 10 years
 | |
|     var expiration = date.toGMTString();
 | |
|     writeCookie(API_LEVEL_COOKIE, selectedLevel, null, expiration);
 | |
|   }
 | |
| 
 | |
|   if (selectedLevel < minLevel) {
 | |
|     var thing = ($("#jd-header").html().indexOf("package") != -1) ? "package" : "class";
 | |
|     $("#naMessage").show().html("<div><p><strong>This " + thing + " is not available with API Level " + selectedLevel + ".</strong></p>"
 | |
|                               + "<p>To use this " + thing + ", your application must specify API Level \"" + $("body").attr("class") + "\" or higher in its manifest "
 | |
|                               + "and be compiled against a version of the Android library that supports an equal or higher API Level. To reveal this "
 | |
|                               + "document, change the value of the API Level filter above.</p>"
 | |
|                               + "<p><a href='" +toRoot+ "guide/appendix/api-levels.html'>What is the API Level?</a></p></div>");
 | |
|   } else {
 | |
|     $("#naMessage").hide();
 | |
|   }
 | |
| }
 | |
| 
 | |
| function toggleVisisbleApis(selectedLevel, context) {
 | |
|   var apis = $(".api",context);
 | |
|   apis.each(function(i) {
 | |
|     var obj = $(this);
 | |
|     var className = obj.attr("class");
 | |
|     var apiLevelIndex = className.lastIndexOf("-")+1;
 | |
|     var apiLevelEndIndex = className.indexOf(" ", apiLevelIndex);
 | |
|     apiLevelEndIndex = apiLevelEndIndex != -1 ? apiLevelEndIndex : className.length;
 | |
|     var apiLevel = className.substring(apiLevelIndex, apiLevelEndIndex);
 | |
|     if (apiLevel.length == 0) { // for odd cases when the since data is actually missing, just bail
 | |
|       return;
 | |
|     }
 | |
|     apiLevel = parseInt(apiLevel);
 | |
| 
 | |
|     // Handle provisional api levels; if this item's level is the provisional one, set it to the max
 | |
|     var selectedLevelNum = parseInt(selectedLevel)
 | |
|     var apiLevelNum = parseInt(apiLevel);
 | |
|     if (isNaN(apiLevelNum)) {
 | |
|         apiLevelNum = maxLevel;
 | |
|     }
 | |
| 
 | |
|     // Grey things out that aren't available and give a tooltip title
 | |
|     if (apiLevelNum > selectedLevelNum) obj.addClass("absent").attr("title","Requires API Level \""
 | |
|             + apiLevel + "\" or higher");
 | |
|     else obj.removeClass("absent").removeAttr("title");
 | |
|   });
 | |
| }
 | |
| 
 | |
| /* NAVTREE */
 | |
| 
 | |
| function new_node(me, mom, text, link, children_data, api_level)
 | |
| {
 | |
|   var node = new Object();
 | |
|   node.children = Array();
 | |
|   node.children_data = children_data;
 | |
|   node.depth = mom.depth + 1;
 | |
| 
 | |
|   node.li = document.createElement("li");
 | |
|   mom.get_children_ul().appendChild(node.li);
 | |
| 
 | |
|   node.label_div = document.createElement("div");
 | |
|   node.label_div.className = "label";
 | |
|   if (api_level != null) {
 | |
|     $(node.label_div).addClass("api");
 | |
|     $(node.label_div).addClass("api-level-"+api_level);
 | |
|   }
 | |
|   node.li.appendChild(node.label_div);
 | |
|   node.label_div.style.paddingLeft = 10*node.depth + "px";
 | |
| 
 | |
|   if (children_data == null) {
 | |
|     // 12 is the width of the triangle and padding extra space
 | |
|     node.label_div.style.paddingLeft = ((10*node.depth)+12) + "px";
 | |
|   } else {
 | |
|     node.label_div.style.paddingLeft = 10*node.depth + "px";
 | |
|     node.expand_toggle = document.createElement("a");
 | |
|     node.expand_toggle.href = "javascript:void(0)";
 | |
|     node.expand_toggle.onclick = function() {
 | |
|           if (node.expanded) {
 | |
|             $(node.get_children_ul()).slideUp("fast");
 | |
|             node.plus_img.src = me.toroot + "assets/images/triangle-closed-small.png";
 | |
|             node.expanded = false;
 | |
|           } else {
 | |
|             expand_node(me, node);
 | |
|           }
 | |
|        };
 | |
|     node.label_div.appendChild(node.expand_toggle);
 | |
| 
 | |
|     node.plus_img = document.createElement("img");
 | |
|     node.plus_img.src = me.toroot + "assets/images/triangle-closed-small.png";
 | |
|     node.plus_img.className = "plus";
 | |
|     node.plus_img.border = "0";
 | |
|     node.expand_toggle.appendChild(node.plus_img);
 | |
| 
 | |
|     node.expanded = false;
 | |
|   }
 | |
| 
 | |
|   var a = document.createElement("a");
 | |
|   node.label_div.appendChild(a);
 | |
|   node.label = document.createTextNode(text);
 | |
|   a.appendChild(node.label);
 | |
|   if (link) {
 | |
|     a.href = me.toroot + link;
 | |
|   } else {
 | |
|     if (children_data != null) {
 | |
|       a.className = "nolink";
 | |
|       a.href = "javascript:void(0)";
 | |
|       a.onclick = node.expand_toggle.onclick;
 | |
|       // This next line shouldn't be necessary.  I'll buy a beer for the first
 | |
|       // person who figures out how to remove this line and have the link
 | |
|       // toggle shut on the first try. --joeo@android.com
 | |
|       node.expanded = false;
 | |
|     }
 | |
|   }
 | |
|   
 | |
| 
 | |
|   node.children_ul = null;
 | |
|   node.get_children_ul = function() {
 | |
|       if (!node.children_ul) {
 | |
|         node.children_ul = document.createElement("ul");
 | |
|         node.children_ul.className = "children_ul";
 | |
|         node.children_ul.style.display = "none";
 | |
|         node.li.appendChild(node.children_ul);
 | |
|       }
 | |
|       return node.children_ul;
 | |
|     };
 | |
| 
 | |
|   return node;
 | |
| }
 | |
| 
 | |
| function expand_node(me, node)
 | |
| {
 | |
|   if (node.children_data && !node.expanded) {
 | |
|     if (node.children_visited) {
 | |
|       $(node.get_children_ul()).slideDown("fast");
 | |
|     } else {
 | |
|       get_node(me, node);
 | |
|       if ($(node.label_div).hasClass("absent")) $(node.get_children_ul()).addClass("absent");
 | |
|       $(node.get_children_ul()).slideDown("fast");
 | |
|     }
 | |
|     node.plus_img.src = me.toroot + "assets/images/triangle-opened-small.png";
 | |
|     node.expanded = true;
 | |
| 
 | |
|     // perform api level toggling because new nodes are new to the DOM
 | |
|     var selectedLevel = $("#apiLevelSelector option:selected").val();
 | |
|     toggleVisisbleApis(selectedLevel, "#side-nav");
 | |
|   }
 | |
| }
 | |
| 
 | |
| function get_node(me, mom)
 | |
| {
 | |
|   mom.children_visited = true;
 | |
|   for (var i in mom.children_data) {
 | |
|     var node_data = mom.children_data[i];
 | |
|     mom.children[i] = new_node(me, mom, node_data[0], node_data[1],
 | |
|         node_data[2], node_data[3]);
 | |
|   }
 | |
| }
 | |
| 
 | |
| function this_page_relative(toroot)
 | |
| {
 | |
|   var full = document.location.pathname;
 | |
|   var file = "";
 | |
|   if (toroot.substr(0, 1) == "/") {
 | |
|     if (full.substr(0, toroot.length) == toroot) {
 | |
|       return full.substr(toroot.length);
 | |
|     } else {
 | |
|       // the file isn't under toroot.  Fail.
 | |
|       return null;
 | |
|     }
 | |
|   } else {
 | |
|     if (toroot != "./") {
 | |
|       toroot = "./" + toroot;
 | |
|     }
 | |
|     do {
 | |
|       if (toroot.substr(toroot.length-3, 3) == "../" || toroot == "./") {
 | |
|         var pos = full.lastIndexOf("/");
 | |
|         file = full.substr(pos) + file;
 | |
|         full = full.substr(0, pos);
 | |
|         toroot = toroot.substr(0, toroot.length-3);
 | |
|       }
 | |
|     } while (toroot != "" && toroot != "/");
 | |
|     return file.substr(1);
 | |
|   }
 | |
| }
 | |
| 
 | |
| function find_page(url, data)
 | |
| {
 | |
|   var nodes = data;
 | |
|   var result = null;
 | |
|   for (var i in nodes) {
 | |
|     var d = nodes[i];
 | |
|     if (d[1] == url) {
 | |
|       return new Array(i);
 | |
|     }
 | |
|     else if (d[2] != null) {
 | |
|       result = find_page(url, d[2]);
 | |
|       if (result != null) {
 | |
|         return (new Array(i).concat(result));
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   return null;
 | |
| }
 | |
| 
 | |
| function load_navtree_data(toroot) {
 | |
|   var navtreeData = document.createElement("script");
 | |
|   navtreeData.setAttribute("type","text/javascript");
 | |
|   navtreeData.setAttribute("src", toroot+"navtree_data.js");
 | |
|   $("head").append($(navtreeData));
 | |
| }
 | |
| 
 | |
| function init_default_navtree(toroot) {
 | |
|   init_navtree("nav-tree", toroot, NAVTREE_DATA);
 | |
|   
 | |
|   // perform api level toggling because because the whole tree is new to the DOM
 | |
|   var selectedLevel = $("#apiLevelSelector option:selected").val();
 | |
|   toggleVisisbleApis(selectedLevel, "#side-nav");
 | |
| }
 | |
| 
 | |
| function init_navtree(navtree_id, toroot, root_nodes)
 | |
| {
 | |
|   var me = new Object();
 | |
|   me.toroot = toroot;
 | |
|   me.node = new Object();
 | |
| 
 | |
|   me.node.li = document.getElementById(navtree_id);
 | |
|   me.node.children_data = root_nodes;
 | |
|   me.node.children = new Array();
 | |
|   me.node.children_ul = document.createElement("ul");
 | |
|   me.node.get_children_ul = function() { return me.node.children_ul; };
 | |
|   //me.node.children_ul.className = "children_ul";
 | |
|   me.node.li.appendChild(me.node.children_ul);
 | |
|   me.node.depth = 0;
 | |
| 
 | |
|   get_node(me, me.node);
 | |
| 
 | |
|   me.this_page = this_page_relative(toroot);
 | |
|   me.breadcrumbs = find_page(me.this_page, root_nodes);
 | |
|   if (me.breadcrumbs != null && me.breadcrumbs.length != 0) {
 | |
|     var mom = me.node;
 | |
|     for (var i in me.breadcrumbs) {
 | |
|       var j = me.breadcrumbs[i];
 | |
|       mom = mom.children[j];
 | |
|       expand_node(me, mom);
 | |
|     }
 | |
|     mom.label_div.className = mom.label_div.className + " selected";
 | |
|     addLoadEvent(function() {
 | |
|       scrollIntoView("nav-tree");
 | |
|       });
 | |
|   }
 | |
| }
 | |
| 
 | |
| /* TOGGLE INHERITED MEMBERS */
 | |
| 
 | |
| /* Toggle an inherited class (arrow toggle)
 | |
|  * @param linkObj  The link that was clicked.
 | |
|  * @param expand  'true' to ensure it's expanded. 'false' to ensure it's closed.
 | |
|  *                'null' to simply toggle.
 | |
|  */
 | |
| function toggleInherited(linkObj, expand) {
 | |
|     var base = linkObj.getAttribute("id");
 | |
|     var list = document.getElementById(base + "-list");
 | |
|     var summary = document.getElementById(base + "-summary");
 | |
|     var trigger = document.getElementById(base + "-trigger");
 | |
|     var a = $(linkObj);
 | |
|     if ( (expand == null && a.hasClass("closed")) || expand ) {
 | |
|         list.style.display = "none";
 | |
|         summary.style.display = "block";
 | |
|         trigger.src = toRoot + "assets/images/triangle-opened.png";
 | |
|         a.removeClass("closed");
 | |
|         a.addClass("opened");
 | |
|     } else if ( (expand == null && a.hasClass("opened")) || (expand == false) ) {
 | |
|         list.style.display = "block";
 | |
|         summary.style.display = "none";
 | |
|         trigger.src = toRoot + "assets/images/triangle-closed.png";
 | |
|         a.removeClass("opened");
 | |
|         a.addClass("closed");
 | |
|     }
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| /* Toggle all inherited classes in a single table (e.g. all inherited methods)
 | |
|  * @param linkObj  The link that was clicked.
 | |
|  * @param expand  'true' to ensure it's expanded. 'false' to ensure it's closed.
 | |
|  *                'null' to simply toggle.
 | |
|  */
 | |
| function toggleAllInherited(linkObj, expand) {
 | |
|   var a = $(linkObj);
 | |
|   var table = $(a.parent().parent().parent()); // ugly way to get table/tbody
 | |
|   var expandos = $(".jd-expando-trigger", table);
 | |
|   if ( (expand == null && a.text() == "[Expand]") || expand ) {
 | |
|     expandos.each(function(i) {
 | |
|       toggleInherited(this, true);
 | |
|     });
 | |
|     a.text("[Collapse]");
 | |
|   } else if ( (expand == null && a.text() == "[Collapse]") || (expand == false) ) {
 | |
|     expandos.each(function(i) {
 | |
|       toggleInherited(this, false);
 | |
|     });
 | |
|     a.text("[Expand]");
 | |
|   }
 | |
|   return false;
 | |
| }
 | |
| 
 | |
| /* Toggle all inherited members in the class (link in the class title)
 | |
|  */
 | |
| function toggleAllClassInherited() {
 | |
|   var a = $("#toggleAllClassInherited"); // get toggle link from class title
 | |
|   var toggles = $(".toggle-all", $("#doc-content"));
 | |
|   if (a.text() == "[Expand All]") {
 | |
|     toggles.each(function(i) {
 | |
|       toggleAllInherited(this, true);
 | |
|     });
 | |
|     a.text("[Collapse All]");
 | |
|   } else {
 | |
|     toggles.each(function(i) {
 | |
|       toggleAllInherited(this, false);
 | |
|     });
 | |
|     a.text("[Expand All]");
 | |
|   }
 | |
|   return false;
 | |
| }
 | |
| 
 | |
| /* Expand all inherited members in the class. Used when initiating page search */
 | |
| function ensureAllInheritedExpanded() {
 | |
|   var toggles = $(".toggle-all", $("#doc-content"));
 | |
|   toggles.each(function(i) {
 | |
|     toggleAllInherited(this, true);
 | |
|   });
 | |
|   $("#toggleAllClassInherited").text("[Collapse All]");
 | |
| }
 | |
| 
 | |
| 
 | |
| /* HANDLE KEY EVENTS
 | |
|  * - Listen for Ctrl+F (Cmd on Mac) and expand all inherited members (to aid page search)
 | |
|  */
 | |
| var agent = navigator['userAgent'].toLowerCase();
 | |
| var mac = agent.indexOf("macintosh") != -1;
 | |
| 
 | |
| $(document).keydown( function(e) {
 | |
| var control = mac ? e.metaKey && !e.ctrlKey : e.ctrlKey; // get ctrl key
 | |
|   if (control && e.which == 70) {  // 70 is "F"
 | |
|     ensureAllInheritedExpanded();
 | |
|   }
 | |
| }); |