blob: ba47d4d55529e0d44e2584d21d1eb96c29b7ecca [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;
Robert Lyfd1eb132012-06-08 12:21:15 -07008var maxLevel = 1;
Scott Main25fda192009-08-04 11:26:30 -07009
Scott Main9b5fdb92009-10-27 15:09:15 -070010function toggleApiLevelSelector(checkbox) {
11 var date = new Date();
12 date.setTime(date.getTime()+(10*365*24*60*60*1000)); // keep this for 10 years
13 var expiration = date.toGMTString();
14 if (checkbox.checked) {
15 $("#apiLevelSelector").removeAttr("disabled");
16 $("#api-level-toggle label").removeClass("disabled");
17 writeCookie(API_LEVEL_ENABLED_COOKIE, 1, null, expiration);
18 } else {
19 $("#apiLevelSelector").attr("disabled","disabled");
20 $("#api-level-toggle label").addClass("disabled");
21 writeCookie(API_LEVEL_ENABLED_COOKIE, 0, null, expiration);
22 }
23 changeApiLevel();
24}
25
26function buildApiLevelSelector() {
Robert Lyfd1eb132012-06-08 12:21:15 -070027 maxLevel = SINCE_DATA.length;
Scott Main9b5fdb92009-10-27 15:09:15 -070028 var userApiLevelEnabled = readCookie(API_LEVEL_ENABLED_COOKIE);
Robert Lyfd1eb132012-06-08 12:21:15 -070029 var userApiLevel = parseInt(readCookie(API_LEVEL_COOKIE));
Scott Main64b879a2009-11-02 18:05:41 -080030 userApiLevel = userApiLevel == 0 ? maxLevel : userApiLevel; // If there's no cookie (zero), use the max by default
Scott Main9b5fdb92009-10-27 15:09:15 -070031
32 if (userApiLevelEnabled == 0) {
33 $("#apiLevelSelector").attr("disabled","disabled");
34 } else {
35 $("#apiLevelCheckbox").attr("checked","checked");
36 $("#api-level-toggle label").removeClass("disabled");
37 }
Robert Lyfd1eb132012-06-08 12:21:15 -070038
39 minLevel = parseInt($("body").attr("class"));
40 // Handle provisional api levels; the provisional level will always be the highest possible level
41 // Provisional api levels will also have a length; other stuff that's just missing a level won't,
42 // so leave those kinds of entities at the default level of 1 (for example, the R.styleable class)
43 if (isNaN(minLevel) && minLevel.length) {
44 minLevel = maxLevel;
45 }
Scott Main9b5fdb92009-10-27 15:09:15 -070046 var select = $("#apiLevelSelector").html("").change(changeApiLevel);
47 for (var i = maxLevel-1; i >= 0; i--) {
48 var option = $("<option />").attr("value",""+SINCE_DATA[i]).append(""+SINCE_DATA[i]);
49 // if (SINCE_DATA[i] < minLevel) option.addClass("absent"); // always false for strings (codenames)
Scott Main7a0090b2010-04-16 09:00:29 -070050 select.append(option);
Scott Main9b5fdb92009-10-27 15:09:15 -070051 }
Robert Lyfd1eb132012-06-08 12:21:15 -070052
Scott Main25fda192009-08-04 11:26:30 -070053 // get the DOM element and use setAttribute cuz IE6 fails when using jquery .attr('selected',true)
Scott Main7a0090b2010-04-16 09:00:29 -070054 var selectedLevelItem = $("#apiLevelSelector option[value='"+userApiLevel+"']").get(0);
55 selectedLevelItem.setAttribute('selected',true);
Scott Main25fda192009-08-04 11:26:30 -070056}
57
58function changeApiLevel() {
Robert Lyfd1eb132012-06-08 12:21:15 -070059 maxLevel = SINCE_DATA.length;
Scott Main9b5fdb92009-10-27 15:09:15 -070060 var userApiLevelEnabled = readCookie(API_LEVEL_ENABLED_COOKIE);
Scott Main7a0090b2010-04-16 09:00:29 -070061 var selectedLevel = maxLevel;
Robert Lyfd1eb132012-06-08 12:21:15 -070062
Scott Main9b5fdb92009-10-27 15:09:15 -070063 if (userApiLevelEnabled == 0) {
64 toggleVisisbleApis(selectedLevel, "body");
65 } else {
Robert Lyfd1eb132012-06-08 12:21:15 -070066 selectedLevel = parseInt($("#apiLevelSelector option:selected").val());
Scott Main9b5fdb92009-10-27 15:09:15 -070067 toggleVisisbleApis(selectedLevel, "body");
Robert Lyfd1eb132012-06-08 12:21:15 -070068
Scott Main9b5fdb92009-10-27 15:09:15 -070069 var date = new Date();
70 date.setTime(date.getTime()+(10*365*24*60*60*1000)); // keep this for 10 years
71 var expiration = date.toGMTString();
72 writeCookie(API_LEVEL_COOKIE, selectedLevel, null, expiration);
73 }
Robert Lyfd1eb132012-06-08 12:21:15 -070074
Scott Main9b5fdb92009-10-27 15:09:15 -070075 if (selectedLevel < minLevel) {
76 var thing = ($("#jd-header").html().indexOf("package") != -1) ? "package" : "class";
77 $("#naMessage").show().html("<div><p><strong>This " + thing + " is not available with API Level " + selectedLevel + ".</strong></p>"
Robert Lyfd1eb132012-06-08 12:21:15 -070078 + "<p>To use this " + thing + ", your application must specify API Level \"" + $("body").attr("class") + "\" or higher in its manifest "
Scott Main25fda192009-08-04 11:26:30 -070079 + "and be compiled against a version of the Android library that supports an equal or higher API Level. To reveal this "
80 + "document, change the value of the API Level filter above.</p>"
81 + "<p><a href='" +toRoot+ "guide/appendix/api-levels.html'>What is the API Level?</a></p></div>");
Scott Main9b5fdb92009-10-27 15:09:15 -070082 } else {
Scott Main25fda192009-08-04 11:26:30 -070083 $("#naMessage").hide();
84 }
85}
86
Scott Main69497272009-08-24 17:33:06 -070087function toggleVisisbleApis(selectedLevel, context) {
Scott Main7a0090b2010-04-16 09:00:29 -070088 var apis = $(".api",context);
89 apis.each(function(i) {
90 var obj = $(this);
91 var className = obj.attr("class");
92 var apiLevelIndex = className.lastIndexOf("-")+1;
93 var apiLevelEndIndex = className.indexOf(" ", apiLevelIndex);
94 apiLevelEndIndex = apiLevelEndIndex != -1 ? apiLevelEndIndex : className.length;
95 var apiLevel = className.substring(apiLevelIndex, apiLevelEndIndex);
Robert Lyfd1eb132012-06-08 12:21:15 -070096 if (apiLevel.length == 0) { // for odd cases when the since data is actually missing, just bail
97 return;
98 }
99 apiLevel = parseInt(apiLevel);
100
101 // Handle provisional api levels; if this item's level is the provisional one, set it to the max
102 var selectedLevelNum = parseInt(selectedLevel)
103 var apiLevelNum = parseInt(apiLevel);
104 if (isNaN(apiLevelNum)) {
105 apiLevelNum = maxLevel;
106 }
107
108 // Grey things out that aren't available and give a tooltip title
109 if (apiLevelNum > selectedLevelNum) obj.addClass("absent").attr("title","Requires API Level \""
110 + apiLevel + "\" or higher");
Scott Main7a0090b2010-04-16 09:00:29 -0700111 else obj.removeClass("absent").removeAttr("title");
112 });
Scott Main69497272009-08-24 17:33:06 -0700113}
114
Scott Main25fda192009-08-04 11:26:30 -0700115/* NAVTREE */
116
117function new_node(me, mom, text, link, children_data, api_level)
The Android Open Source Project88b60792009-03-03 19:28:42 -0800118{
119 var node = new Object();
120 node.children = Array();
121 node.children_data = children_data;
122 node.depth = mom.depth + 1;
123
124 node.li = document.createElement("li");
125 mom.get_children_ul().appendChild(node.li);
126
127 node.label_div = document.createElement("div");
Scott Main25fda192009-08-04 11:26:30 -0700128 node.label_div.className = "label";
129 if (api_level != null) {
130 $(node.label_div).addClass("api");
131 $(node.label_div).addClass("api-level-"+api_level);
132 }
The Android Open Source Project88b60792009-03-03 19:28:42 -0800133 node.li.appendChild(node.label_div);
134 node.label_div.style.paddingLeft = 10*node.depth + "px";
The Android Open Source Project88b60792009-03-03 19:28:42 -0800135
136 if (children_data == null) {
137 // 12 is the width of the triangle and padding extra space
138 node.label_div.style.paddingLeft = ((10*node.depth)+12) + "px";
139 } else {
140 node.label_div.style.paddingLeft = 10*node.depth + "px";
141 node.expand_toggle = document.createElement("a");
142 node.expand_toggle.href = "javascript:void(0)";
143 node.expand_toggle.onclick = function() {
144 if (node.expanded) {
145 $(node.get_children_ul()).slideUp("fast");
146 node.plus_img.src = me.toroot + "assets/images/triangle-closed-small.png";
147 node.expanded = false;
148 } else {
149 expand_node(me, node);
150 }
151 };
152 node.label_div.appendChild(node.expand_toggle);
153
154 node.plus_img = document.createElement("img");
155 node.plus_img.src = me.toroot + "assets/images/triangle-closed-small.png";
156 node.plus_img.className = "plus";
157 node.plus_img.border = "0";
158 node.expand_toggle.appendChild(node.plus_img);
159
160 node.expanded = false;
161 }
162
163 var a = document.createElement("a");
164 node.label_div.appendChild(a);
165 node.label = document.createTextNode(text);
166 a.appendChild(node.label);
167 if (link) {
168 a.href = me.toroot + link;
169 } else {
170 if (children_data != null) {
171 a.className = "nolink";
172 a.href = "javascript:void(0)";
173 a.onclick = node.expand_toggle.onclick;
174 // This next line shouldn't be necessary. I'll buy a beer for the first
175 // person who figures out how to remove this line and have the link
176 // toggle shut on the first try. --joeo@android.com
177 node.expanded = false;
178 }
179 }
180
181
182 node.children_ul = null;
183 node.get_children_ul = function() {
184 if (!node.children_ul) {
185 node.children_ul = document.createElement("ul");
186 node.children_ul.className = "children_ul";
187 node.children_ul.style.display = "none";
188 node.li.appendChild(node.children_ul);
189 }
190 return node.children_ul;
191 };
192
193 return node;
194}
195
196function expand_node(me, node)
197{
198 if (node.children_data && !node.expanded) {
199 if (node.children_visited) {
200 $(node.get_children_ul()).slideDown("fast");
201 } else {
202 get_node(me, node);
Scott Main25fda192009-08-04 11:26:30 -0700203 if ($(node.label_div).hasClass("absent")) $(node.get_children_ul()).addClass("absent");
The Android Open Source Project88b60792009-03-03 19:28:42 -0800204 $(node.get_children_ul()).slideDown("fast");
205 }
206 node.plus_img.src = me.toroot + "assets/images/triangle-opened-small.png";
207 node.expanded = true;
Robert Lyfd1eb132012-06-08 12:21:15 -0700208
Scott Main7a0090b2010-04-16 09:00:29 -0700209 // perform api level toggling because new nodes are new to the DOM
210 var selectedLevel = $("#apiLevelSelector option:selected").val();
Scott Main69497272009-08-24 17:33:06 -0700211 toggleVisisbleApis(selectedLevel, "#side-nav");
The Android Open Source Project88b60792009-03-03 19:28:42 -0800212 }
213}
214
215function get_node(me, mom)
216{
217 mom.children_visited = true;
218 for (var i in mom.children_data) {
219 var node_data = mom.children_data[i];
220 mom.children[i] = new_node(me, mom, node_data[0], node_data[1],
Scott Main25fda192009-08-04 11:26:30 -0700221 node_data[2], node_data[3]);
The Android Open Source Project88b60792009-03-03 19:28:42 -0800222 }
223}
224
225function this_page_relative(toroot)
226{
227 var full = document.location.pathname;
228 var file = "";
229 if (toroot.substr(0, 1) == "/") {
230 if (full.substr(0, toroot.length) == toroot) {
Scott Main25fda192009-08-04 11:26:30 -0700231 return full.substr(toroot.length);
The Android Open Source Project88b60792009-03-03 19:28:42 -0800232 } else {
233 // the file isn't under toroot. Fail.
234 return null;
235 }
236 } else {
237 if (toroot != "./") {
238 toroot = "./" + toroot;
239 }
240 do {
241 if (toroot.substr(toroot.length-3, 3) == "../" || toroot == "./") {
242 var pos = full.lastIndexOf("/");
243 file = full.substr(pos) + file;
244 full = full.substr(0, pos);
245 toroot = toroot.substr(0, toroot.length-3);
246 }
247 } while (toroot != "" && toroot != "/");
248 return file.substr(1);
249 }
250}
251
252function find_page(url, data)
253{
254 var nodes = data;
255 var result = null;
256 for (var i in nodes) {
257 var d = nodes[i];
258 if (d[1] == url) {
259 return new Array(i);
260 }
261 else if (d[2] != null) {
262 result = find_page(url, d[2]);
263 if (result != null) {
264 return (new Array(i).concat(result));
265 }
266 }
267 }
268 return null;
269}
270
Scott Main5b53cd72009-06-04 11:10:17 -0700271function load_navtree_data(toroot) {
272 var navtreeData = document.createElement("script");
273 navtreeData.setAttribute("type","text/javascript");
274 navtreeData.setAttribute("src", toroot+"navtree_data.js");
275 $("head").append($(navtreeData));
Scott Main25fda192009-08-04 11:26:30 -0700276}
Scott Main5b53cd72009-06-04 11:10:17 -0700277
278function init_default_navtree(toroot) {
Scott Main5b53cd72009-06-04 11:10:17 -0700279 init_navtree("nav-tree", toroot, NAVTREE_DATA);
Scott Main69497272009-08-24 17:33:06 -0700280
Scott Main7a0090b2010-04-16 09:00:29 -0700281 // perform api level toggling because because the whole tree is new to the DOM
282 var selectedLevel = $("#apiLevelSelector option:selected").val();
Scott Main69497272009-08-24 17:33:06 -0700283 toggleVisisbleApis(selectedLevel, "#side-nav");
Scott Main5b53cd72009-06-04 11:10:17 -0700284}
285
The Android Open Source Project88b60792009-03-03 19:28:42 -0800286function init_navtree(navtree_id, toroot, root_nodes)
Scott Main25fda192009-08-04 11:26:30 -0700287{
The Android Open Source Project88b60792009-03-03 19:28:42 -0800288 var me = new Object();
289 me.toroot = toroot;
290 me.node = new Object();
291
292 me.node.li = document.getElementById(navtree_id);
293 me.node.children_data = root_nodes;
294 me.node.children = new Array();
295 me.node.children_ul = document.createElement("ul");
296 me.node.get_children_ul = function() { return me.node.children_ul; };
297 //me.node.children_ul.className = "children_ul";
298 me.node.li.appendChild(me.node.children_ul);
299 me.node.depth = 0;
300
301 get_node(me, me.node);
302
303 me.this_page = this_page_relative(toroot);
304 me.breadcrumbs = find_page(me.this_page, root_nodes);
305 if (me.breadcrumbs != null && me.breadcrumbs.length != 0) {
306 var mom = me.node;
307 for (var i in me.breadcrumbs) {
308 var j = me.breadcrumbs[i];
309 mom = mom.children[j];
310 expand_node(me, mom);
311 }
312 mom.label_div.className = mom.label_div.className + " selected";
313 addLoadEvent(function() {
314 scrollIntoView("nav-tree");
315 });
316 }
317}
Scott Main7a0090b2010-04-16 09:00:29 -0700318
319/* TOGGLE INHERITED MEMBERS */
320
321/* Toggle an inherited class (arrow toggle)
322 * @param linkObj The link that was clicked.
323 * @param expand 'true' to ensure it's expanded. 'false' to ensure it's closed.
324 * 'null' to simply toggle.
325 */
326function toggleInherited(linkObj, expand) {
327 var base = linkObj.getAttribute("id");
328 var list = document.getElementById(base + "-list");
329 var summary = document.getElementById(base + "-summary");
330 var trigger = document.getElementById(base + "-trigger");
331 var a = $(linkObj);
332 if ( (expand == null && a.hasClass("closed")) || expand ) {
333 list.style.display = "none";
334 summary.style.display = "block";
335 trigger.src = toRoot + "assets/images/triangle-opened.png";
336 a.removeClass("closed");
337 a.addClass("opened");
338 } else if ( (expand == null && a.hasClass("opened")) || (expand == false) ) {
339 list.style.display = "block";
340 summary.style.display = "none";
341 trigger.src = toRoot + "assets/images/triangle-closed.png";
342 a.removeClass("opened");
343 a.addClass("closed");
344 }
345 return false;
346}
347
348/* Toggle all inherited classes in a single table (e.g. all inherited methods)
349 * @param linkObj The link that was clicked.
350 * @param expand 'true' to ensure it's expanded. 'false' to ensure it's closed.
351 * 'null' to simply toggle.
352 */
353function toggleAllInherited(linkObj, expand) {
354 var a = $(linkObj);
355 var table = $(a.parent().parent().parent()); // ugly way to get table/tbody
356 var expandos = $(".jd-expando-trigger", table);
357 if ( (expand == null && a.text() == "[Expand]") || expand ) {
358 expandos.each(function(i) {
359 toggleInherited(this, true);
360 });
361 a.text("[Collapse]");
362 } else if ( (expand == null && a.text() == "[Collapse]") || (expand == false) ) {
363 expandos.each(function(i) {
364 toggleInherited(this, false);
365 });
366 a.text("[Expand]");
367 }
368 return false;
369}
370
371/* Toggle all inherited members in the class (link in the class title)
372 */
373function toggleAllClassInherited() {
374 var a = $("#toggleAllClassInherited"); // get toggle link from class title
375 var toggles = $(".toggle-all", $("#doc-content"));
376 if (a.text() == "[Expand All]") {
377 toggles.each(function(i) {
378 toggleAllInherited(this, true);
379 });
380 a.text("[Collapse All]");
381 } else {
382 toggles.each(function(i) {
383 toggleAllInherited(this, false);
384 });
385 a.text("[Expand All]");
386 }
387 return false;
388}
389
390/* Expand all inherited members in the class. Used when initiating page search */
391function ensureAllInheritedExpanded() {
392 var toggles = $(".toggle-all", $("#doc-content"));
393 toggles.each(function(i) {
394 toggleAllInherited(this, true);
395 });
396 $("#toggleAllClassInherited").text("[Collapse All]");
397}
398
399
400/* HANDLE KEY EVENTS
401 * - Listen for Ctrl+F (Cmd on Mac) and expand all inherited members (to aid page search)
402 */
403var agent = navigator['userAgent'].toLowerCase();
404var mac = agent.indexOf("macintosh") != -1;
405
406$(document).keydown( function(e) {
407var control = mac ? e.metaKey && !e.ctrlKey : e.ctrlKey; // get ctrl key
408 if (control && e.which == 70) { // 70 is "F"
409 ensureAllInheritedExpanded();
410 }
411});