• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /* API LEVEL TOGGLE */
3 <?cs if:reference.apilevels ?>
4 addLoadEvent(changeApiLevel);
5 <?cs /if ?>
6 
7 var API_LEVEL_ENABLED_COOKIE = "api_level_enabled";
8 var API_LEVEL_COOKIE = "api_level";
9 var minLevel = 1;
10 
11 function 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 
27 function 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 
53 function 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 
82 function 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 
98 function 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 
177 function 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 
196 function 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 
206 function 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 
233 function 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 
252 function 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 
259 function 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 
267 function 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  */
307 function 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  */
334 function 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  */
354 function 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 */
372 function 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  */
384 var agent = navigator['userAgent'].toLowerCase();
385 var mac = agent.indexOf("macintosh") != -1;
386 
387 $(document).keydown( function(e) {
388 var control = mac ? e.metaKey && !e.ctrlKey : e.ctrlKey; // get ctrl key
389   if (control && e.which == 70) {  // 70 is "F"
390     ensureAllInheritedExpanded();
391   }
392 });