android-developer-reference.js revision d77248ac7e1c05d7e5c16dd6df7e2067a2791e7b
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 = $("#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});