blob: daddde08cfa2101de2da9556f2a98a4a76ea3046 [file] [log] [blame]
The Android Open Source Project88b60792009-03-03 19:28:42 -08001
Scott Main25fda192009-08-04 11:26:30 -07002/* API LEVEL TOGGLE */
3addLoadEvent(changeApiLevel);
Scott Main9b5fdb92009-10-27 15:09:15 -07004
5var API_LEVEL_ENABLED_COOKIE = "api_level_enabled";
Scott Main25fda192009-08-04 11:26:30 -07006var API_LEVEL_COOKIE = "api_level";
7var minLevel = 1;
8
Scott Main9b5fdb92009-10-27 15:09:15 -07009function 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);
Scott Main64b879a2009-11-02 18:05:41 -080029 userApiLevel = userApiLevel == 0 ? maxLevel : userApiLevel; // If there's no cookie (zero), use the max by default
Scott Main9b5fdb92009-10-27 15:09:15 -070030
31 if (userApiLevelEnabled == 0) {
32 $("#apiLevelSelector").attr("disabled","disabled");
33 } else {
34 $("#apiLevelCheckbox").attr("checked","checked");
35 $("#api-level-toggle label").removeClass("disabled");
36 }
Scott Main7a0090b2010-04-16 09:00:29 -070037
Scott Main25fda192009-08-04 11:26:30 -070038 minLevel = $("body").attr("class");
Scott Main9b5fdb92009-10-27 15:09:15 -070039 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)
Scott Main7a0090b2010-04-16 09:00:29 -070043 select.append(option);
Scott Main9b5fdb92009-10-27 15:09:15 -070044 }
Scott Main7a0090b2010-04-16 09:00:29 -070045
Scott Main25fda192009-08-04 11:26:30 -070046 // get the DOM element and use setAttribute cuz IE6 fails when using jquery .attr('selected',true)
Scott Main7a0090b2010-04-16 09:00:29 -070047 var selectedLevelItem = $("#apiLevelSelector option[value='"+userApiLevel+"']").get(0);
48 selectedLevelItem.setAttribute('selected',true);
Scott Main25fda192009-08-04 11:26:30 -070049}
50
51function changeApiLevel() {
Scott Main9b5fdb92009-10-27 15:09:15 -070052 var maxLevel = SINCE_DATA.length;
53 var userApiLevelEnabled = readCookie(API_LEVEL_ENABLED_COOKIE);
Scott Main7a0090b2010-04-16 09:00:29 -070054 var selectedLevel = maxLevel;
55
Scott Main9b5fdb92009-10-27 15:09:15 -070056 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 }
Scott Main69497272009-08-24 17:33:06 -070067
Scott Main9b5fdb92009-10-27 15:09:15 -070068 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>"
Scott Main25fda192009-08-04 11:26:30 -070071 + "<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>");
Scott Main9b5fdb92009-10-27 15:09:15 -070075 } else {
Scott Main25fda192009-08-04 11:26:30 -070076 $("#naMessage").hide();
77 }
78}
79
Scott Main69497272009-08-24 17:33:06 -070080function toggleVisisbleApis(selectedLevel, context) {
Scott Main7a0090b2010-04-16 09:00:29 -070081 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 });
Scott Main69497272009-08-24 17:33:06 -070092}
93
Scott Main25fda192009-08-04 11:26:30 -070094/* NAVTREE */
95
96function new_node(me, mom, text, link, children_data, api_level)
The Android Open Source Project88b60792009-03-03 19:28:42 -080097{
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");
Scott Main25fda192009-08-04 11:26:30 -0700107 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 }
The Android Open Source Project88b60792009-03-03 19:28:42 -0800112 node.li.appendChild(node.label_div);
113 node.label_div.style.paddingLeft = 10*node.depth + "px";
The Android Open Source Project88b60792009-03-03 19:28:42 -0800114
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);
Scott Main25fda192009-08-04 11:26:30 -0700182 if ($(node.label_div).hasClass("absent")) $(node.get_children_ul()).addClass("absent");
The Android Open Source Project88b60792009-03-03 19:28:42 -0800183 $(node.get_children_ul()).slideDown("fast");
184 }
185 node.plus_img.src = me.toroot + "assets/images/triangle-opened-small.png";
186 node.expanded = true;
Scott Main69497272009-08-24 17:33:06 -0700187
Scott Main7a0090b2010-04-16 09:00:29 -0700188 // perform api level toggling because new nodes are new to the DOM
189 var selectedLevel = $("#apiLevelSelector option:selected").val();
Scott Main69497272009-08-24 17:33:06 -0700190 toggleVisisbleApis(selectedLevel, "#side-nav");
The Android Open Source Project88b60792009-03-03 19:28:42 -0800191 }
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],
Scott Main25fda192009-08-04 11:26:30 -0700200 node_data[2], node_data[3]);
The Android Open Source Project88b60792009-03-03 19:28:42 -0800201 }
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) {
Scott Main25fda192009-08-04 11:26:30 -0700210 return full.substr(toroot.length);
The Android Open Source Project88b60792009-03-03 19:28:42 -0800211 } 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
Scott Main5b53cd72009-06-04 11:10:17 -0700250function 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));
Scott Main25fda192009-08-04 11:26:30 -0700255}
Scott Main5b53cd72009-06-04 11:10:17 -0700256
257function init_default_navtree(toroot) {
Scott Main5b53cd72009-06-04 11:10:17 -0700258 init_navtree("nav-tree", toroot, NAVTREE_DATA);
Scott Main69497272009-08-24 17:33:06 -0700259
Scott Main7a0090b2010-04-16 09:00:29 -0700260 // perform api level toggling because because the whole tree is new to the DOM
261 var selectedLevel = $("#apiLevelSelector option:selected").val();
Scott Main69497272009-08-24 17:33:06 -0700262 toggleVisisbleApis(selectedLevel, "#side-nav");
Scott Main5b53cd72009-06-04 11:10:17 -0700263}
264
The Android Open Source Project88b60792009-03-03 19:28:42 -0800265function init_navtree(navtree_id, toroot, root_nodes)
Scott Main25fda192009-08-04 11:26:30 -0700266{
The Android Open Source Project88b60792009-03-03 19:28:42 -0800267 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}
Scott Main7a0090b2010-04-16 09:00:29 -0700297
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});