blob: 5ebf5fe54699fa3080443b1d9bdc48a2dc147fc0 [file] [log] [blame]
The Android Open Source Project88b60792009-03-03 19:28:42 -08001
Scott Maine4d8f1b2012-06-21 18:03:05 -07002/* Initialize some droiddoc stuff */
3$(document).ready(function() {
4
5 // init available apis based on user pref
6 changeApiLevel();
7 initSidenavHeightResize()
8});
Scott Main9b5fdb92009-10-27 15:09:15 -07009
Scott Main25fda192009-08-04 11:26:30 -070010var API_LEVEL_COOKIE = "api_level";
11var minLevel = 1;
Scott Main70e60662011-07-27 18:20:34 -070012var maxLevel = 1;
Scott Main25fda192009-08-04 11:26:30 -070013
Scott Maine4d8f1b2012-06-21 18:03:05 -070014/******* SIDENAV DIMENSIONS ************/
15
16
17 function initSidenavHeightResize() {
18 // Change the drag bar size to nicely fit the scrollbar positions
19 var $dragBar = $(".ui-resizable-s");
20 $dragBar.css({'width': $dragBar.parent().width() - 5 + "px"});
21
22 $( "#resize-packages-nav" ).resizable({
23 containment: "#nav-panels",
24 handles: "s",
25 alsoResize: "#packages-nav",
26 resize: function(event, ui) { resizeNav(); }, /* resize the nav while dragging */
27 stop: function(event, ui) { saveNavPanels(); } /* once stopped, save the sizes to cookie */
28 });
29
Scott Main9b5fdb92009-10-27 15:09:15 -070030 }
Scott Maine4d8f1b2012-06-21 18:03:05 -070031
32function updateSidenavFixedWidth() {
33 if (!navBarIsFixed) return;
34 $('#devdoc-nav').css({
35 'width' : $('#side-nav').css('width'),
36 'margin' : $('#side-nav').css('margin')
37 });
38 $('#devdoc-nav a.totop').css({'display':'block','width':$("#nav").innerWidth()+'px'});
39
40 initSidenavHeightResize();
41}
42
43function updateSidenavFullscreenWidth() {
44 if (!navBarIsFixed) return;
45 $('#devdoc-nav').css({
46 'width' : $('#side-nav').css('width'),
47 'margin' : $('#side-nav').css('margin')
48 });
49 $('#devdoc-nav .totop').css({'left': 'inherit'});
50
51 initSidenavHeightResize();
Scott Main9b5fdb92009-10-27 15:09:15 -070052}
53
54function buildApiLevelSelector() {
Scott Main70e60662011-07-27 18:20:34 -070055 maxLevel = SINCE_DATA.length;
Scott Main70e60662011-07-27 18:20:34 -070056 var userApiLevel = parseInt(readCookie(API_LEVEL_COOKIE));
Scott Main64b879a2009-11-02 18:05:41 -080057 userApiLevel = userApiLevel == 0 ? maxLevel : userApiLevel; // If there's no cookie (zero), use the max by default
Scott Main9b5fdb92009-10-27 15:09:15 -070058
Scott Maine4d8f1b2012-06-21 18:03:05 -070059 minLevel = parseInt($("#doc-api-level").attr("class"));
Scott Main70e60662011-07-27 18:20:34 -070060 // Handle provisional api levels; the provisional level will always be the highest possible level
Scott Main219a2672011-09-21 18:38:44 -070061 // Provisional api levels will also have a length; other stuff that's just missing a level won't,
62 // so leave those kinds of entities at the default level of 1 (for example, the R.styleable class)
63 if (isNaN(minLevel) && minLevel.length) {
Scott Main70e60662011-07-27 18:20:34 -070064 minLevel = maxLevel;
65 }
Scott Main9b5fdb92009-10-27 15:09:15 -070066 var select = $("#apiLevelSelector").html("").change(changeApiLevel);
67 for (var i = maxLevel-1; i >= 0; i--) {
68 var option = $("<option />").attr("value",""+SINCE_DATA[i]).append(""+SINCE_DATA[i]);
69 // if (SINCE_DATA[i] < minLevel) option.addClass("absent"); // always false for strings (codenames)
Scott Main7a0090b2010-04-16 09:00:29 -070070 select.append(option);
Scott Main9b5fdb92009-10-27 15:09:15 -070071 }
Scott Main70e60662011-07-27 18:20:34 -070072
Scott Main25fda192009-08-04 11:26:30 -070073 // get the DOM element and use setAttribute cuz IE6 fails when using jquery .attr('selected',true)
Scott Main7a0090b2010-04-16 09:00:29 -070074 var selectedLevelItem = $("#apiLevelSelector option[value='"+userApiLevel+"']").get(0);
75 selectedLevelItem.setAttribute('selected',true);
Scott Main25fda192009-08-04 11:26:30 -070076}
77
78function changeApiLevel() {
Scott Main70e60662011-07-27 18:20:34 -070079 maxLevel = SINCE_DATA.length;
Scott Main7a0090b2010-04-16 09:00:29 -070080 var selectedLevel = maxLevel;
Scott Main70e60662011-07-27 18:20:34 -070081
Scott Maine4d8f1b2012-06-21 18:03:05 -070082 selectedLevel = parseInt($("#apiLevelSelector option:selected").val());
83 toggleVisisbleApis(selectedLevel, "body");
Scott Main70e60662011-07-27 18:20:34 -070084
Scott Maine4d8f1b2012-06-21 18:03:05 -070085 var date = new Date();
86 date.setTime(date.getTime()+(10*365*24*60*60*1000)); // keep this for 10 years
87 var expiration = date.toGMTString();
88 writeCookie(API_LEVEL_COOKIE, selectedLevel, null, expiration);
Scott Main70e60662011-07-27 18:20:34 -070089
Scott Main9b5fdb92009-10-27 15:09:15 -070090 if (selectedLevel < minLevel) {
91 var thing = ($("#jd-header").html().indexOf("package") != -1) ? "package" : "class";
Scott Maine4d8f1b2012-06-21 18:03:05 -070092 $("#naMessage").show().html("<div><p><strong>This " + thing + " is not available with API level " + selectedLevel + ".</strong></p>"
93 + "<p>To use this " + thing + ", you must develop your app using a build target "
94 + "that supports API level " + $("#doc-api-level").attr("class") + " or higher. To read these "
95 + "APIs, change the value of the API level filter above.</p>"
96 + "<p><a href='" +toRoot+ "guide/appendix/api-levels.html'>What is the API level?</a></p></div>");
Scott Main9b5fdb92009-10-27 15:09:15 -070097 } else {
Scott Main25fda192009-08-04 11:26:30 -070098 $("#naMessage").hide();
99 }
100}
101
Scott Main69497272009-08-24 17:33:06 -0700102function toggleVisisbleApis(selectedLevel, context) {
Scott Main7a0090b2010-04-16 09:00:29 -0700103 var apis = $(".api",context);
104 apis.each(function(i) {
105 var obj = $(this);
106 var className = obj.attr("class");
107 var apiLevelIndex = className.lastIndexOf("-")+1;
108 var apiLevelEndIndex = className.indexOf(" ", apiLevelIndex);
109 apiLevelEndIndex = apiLevelEndIndex != -1 ? apiLevelEndIndex : className.length;
110 var apiLevel = className.substring(apiLevelIndex, apiLevelEndIndex);
Scott Main70e60662011-07-27 18:20:34 -0700111 if (apiLevel.length == 0) { // for odd cases when the since data is actually missing, just bail
112 return;
113 }
114 apiLevel = parseInt(apiLevel);
115
116 // Handle provisional api levels; if this item's level is the provisional one, set it to the max
117 var selectedLevelNum = parseInt(selectedLevel)
118 var apiLevelNum = parseInt(apiLevel);
119 if (isNaN(apiLevelNum)) {
120 apiLevelNum = maxLevel;
121 }
122
123 // Grey things out that aren't available and give a tooltip title
Scott Maine4d8f1b2012-06-21 18:03:05 -0700124 if (apiLevelNum > selectedLevelNum) {
125 obj.addClass("absent").attr("title","Requires API Level \""
Scott Main70e60662011-07-27 18:20:34 -0700126 + apiLevel + "\" or higher");
Scott Maine4d8f1b2012-06-21 18:03:05 -0700127 }
Scott Main7a0090b2010-04-16 09:00:29 -0700128 else obj.removeClass("absent").removeAttr("title");
129 });
Scott Main69497272009-08-24 17:33:06 -0700130}
131
Scott Maine4d8f1b2012-06-21 18:03:05 -0700132
133
134
135
136
137
138
139
140
Scott Main25fda192009-08-04 11:26:30 -0700141/* NAVTREE */
142
143function new_node(me, mom, text, link, children_data, api_level)
The Android Open Source Project88b60792009-03-03 19:28:42 -0800144{
145 var node = new Object();
146 node.children = Array();
147 node.children_data = children_data;
148 node.depth = mom.depth + 1;
149
150 node.li = document.createElement("li");
151 mom.get_children_ul().appendChild(node.li);
152
153 node.label_div = document.createElement("div");
Scott Main25fda192009-08-04 11:26:30 -0700154 node.label_div.className = "label";
155 if (api_level != null) {
156 $(node.label_div).addClass("api");
157 $(node.label_div).addClass("api-level-"+api_level);
158 }
The Android Open Source Project88b60792009-03-03 19:28:42 -0800159 node.li.appendChild(node.label_div);
The Android Open Source Project88b60792009-03-03 19:28:42 -0800160
Scott Maine4d8f1b2012-06-21 18:03:05 -0700161 if (children_data != null) {
The Android Open Source Project88b60792009-03-03 19:28:42 -0800162 node.expand_toggle = document.createElement("a");
163 node.expand_toggle.href = "javascript:void(0)";
164 node.expand_toggle.onclick = function() {
165 if (node.expanded) {
166 $(node.get_children_ul()).slideUp("fast");
167 node.plus_img.src = me.toroot + "assets/images/triangle-closed-small.png";
168 node.expanded = false;
169 } else {
170 expand_node(me, node);
171 }
172 };
173 node.label_div.appendChild(node.expand_toggle);
174
175 node.plus_img = document.createElement("img");
176 node.plus_img.src = me.toroot + "assets/images/triangle-closed-small.png";
177 node.plus_img.className = "plus";
Scott Maine4d8f1b2012-06-21 18:03:05 -0700178 node.plus_img.width = "8";
The Android Open Source Project88b60792009-03-03 19:28:42 -0800179 node.plus_img.border = "0";
180 node.expand_toggle.appendChild(node.plus_img);
181
182 node.expanded = false;
183 }
184
185 var a = document.createElement("a");
186 node.label_div.appendChild(a);
187 node.label = document.createTextNode(text);
188 a.appendChild(node.label);
189 if (link) {
190 a.href = me.toroot + link;
191 } else {
192 if (children_data != null) {
193 a.className = "nolink";
194 a.href = "javascript:void(0)";
195 a.onclick = node.expand_toggle.onclick;
196 // This next line shouldn't be necessary. I'll buy a beer for the first
197 // person who figures out how to remove this line and have the link
198 // toggle shut on the first try. --joeo@android.com
199 node.expanded = false;
200 }
201 }
202
203
204 node.children_ul = null;
205 node.get_children_ul = function() {
206 if (!node.children_ul) {
207 node.children_ul = document.createElement("ul");
208 node.children_ul.className = "children_ul";
209 node.children_ul.style.display = "none";
210 node.li.appendChild(node.children_ul);
211 }
212 return node.children_ul;
213 };
214
215 return node;
216}
217
218function expand_node(me, node)
219{
220 if (node.children_data && !node.expanded) {
221 if (node.children_visited) {
222 $(node.get_children_ul()).slideDown("fast");
223 } else {
224 get_node(me, node);
Scott Maine4d8f1b2012-06-21 18:03:05 -0700225 if ($(node.label_div).hasClass("absent")) {
226 $(node.get_children_ul()).addClass("absent");
227 }
The Android Open Source Project88b60792009-03-03 19:28:42 -0800228 $(node.get_children_ul()).slideDown("fast");
229 }
230 node.plus_img.src = me.toroot + "assets/images/triangle-opened-small.png";
231 node.expanded = true;
Scott Main70e60662011-07-27 18:20:34 -0700232
Scott Main7a0090b2010-04-16 09:00:29 -0700233 // perform api level toggling because new nodes are new to the DOM
234 var selectedLevel = $("#apiLevelSelector option:selected").val();
Scott Main69497272009-08-24 17:33:06 -0700235 toggleVisisbleApis(selectedLevel, "#side-nav");
The Android Open Source Project88b60792009-03-03 19:28:42 -0800236 }
237}
238
239function get_node(me, mom)
240{
241 mom.children_visited = true;
242 for (var i in mom.children_data) {
243 var node_data = mom.children_data[i];
244 mom.children[i] = new_node(me, mom, node_data[0], node_data[1],
Scott Main25fda192009-08-04 11:26:30 -0700245 node_data[2], node_data[3]);
The Android Open Source Project88b60792009-03-03 19:28:42 -0800246 }
247}
248
249function this_page_relative(toroot)
250{
251 var full = document.location.pathname;
252 var file = "";
253 if (toroot.substr(0, 1) == "/") {
254 if (full.substr(0, toroot.length) == toroot) {
Scott Main25fda192009-08-04 11:26:30 -0700255 return full.substr(toroot.length);
The Android Open Source Project88b60792009-03-03 19:28:42 -0800256 } else {
257 // the file isn't under toroot. Fail.
258 return null;
259 }
260 } else {
261 if (toroot != "./") {
262 toroot = "./" + toroot;
263 }
264 do {
265 if (toroot.substr(toroot.length-3, 3) == "../" || toroot == "./") {
266 var pos = full.lastIndexOf("/");
267 file = full.substr(pos) + file;
268 full = full.substr(0, pos);
269 toroot = toroot.substr(0, toroot.length-3);
270 }
271 } while (toroot != "" && toroot != "/");
272 return file.substr(1);
273 }
274}
275
276function find_page(url, data)
277{
278 var nodes = data;
279 var result = null;
280 for (var i in nodes) {
281 var d = nodes[i];
282 if (d[1] == url) {
283 return new Array(i);
284 }
285 else if (d[2] != null) {
286 result = find_page(url, d[2]);
287 if (result != null) {
288 return (new Array(i).concat(result));
289 }
290 }
291 }
292 return null;
293}
294
Scott Main5b53cd72009-06-04 11:10:17 -0700295function load_navtree_data(toroot) {
296 var navtreeData = document.createElement("script");
297 navtreeData.setAttribute("type","text/javascript");
298 navtreeData.setAttribute("src", toroot+"navtree_data.js");
299 $("head").append($(navtreeData));
Scott Main25fda192009-08-04 11:26:30 -0700300}
Scott Main5b53cd72009-06-04 11:10:17 -0700301
302function init_default_navtree(toroot) {
Scott Maine4d8f1b2012-06-21 18:03:05 -0700303 init_navtree("tree-list", toroot, NAVTREE_DATA);
Scott Main69497272009-08-24 17:33:06 -0700304
Scott Main7a0090b2010-04-16 09:00:29 -0700305 // perform api level toggling because because the whole tree is new to the DOM
306 var selectedLevel = $("#apiLevelSelector option:selected").val();
Scott Main69497272009-08-24 17:33:06 -0700307 toggleVisisbleApis(selectedLevel, "#side-nav");
Scott Main5b53cd72009-06-04 11:10:17 -0700308}
309
The Android Open Source Project88b60792009-03-03 19:28:42 -0800310function init_navtree(navtree_id, toroot, root_nodes)
Scott Main25fda192009-08-04 11:26:30 -0700311{
The Android Open Source Project88b60792009-03-03 19:28:42 -0800312 var me = new Object();
313 me.toroot = toroot;
314 me.node = new Object();
315
316 me.node.li = document.getElementById(navtree_id);
317 me.node.children_data = root_nodes;
318 me.node.children = new Array();
319 me.node.children_ul = document.createElement("ul");
320 me.node.get_children_ul = function() { return me.node.children_ul; };
321 //me.node.children_ul.className = "children_ul";
322 me.node.li.appendChild(me.node.children_ul);
323 me.node.depth = 0;
324
325 get_node(me, me.node);
326
327 me.this_page = this_page_relative(toroot);
328 me.breadcrumbs = find_page(me.this_page, root_nodes);
329 if (me.breadcrumbs != null && me.breadcrumbs.length != 0) {
330 var mom = me.node;
331 for (var i in me.breadcrumbs) {
332 var j = me.breadcrumbs[i];
333 mom = mom.children[j];
334 expand_node(me, mom);
335 }
336 mom.label_div.className = mom.label_div.className + " selected";
337 addLoadEvent(function() {
338 scrollIntoView("nav-tree");
339 });
340 }
341}
Scott Main7a0090b2010-04-16 09:00:29 -0700342
343/* TOGGLE INHERITED MEMBERS */
344
345/* Toggle an inherited class (arrow toggle)
346 * @param linkObj The link that was clicked.
347 * @param expand 'true' to ensure it's expanded. 'false' to ensure it's closed.
348 * 'null' to simply toggle.
349 */
350function toggleInherited(linkObj, expand) {
351 var base = linkObj.getAttribute("id");
352 var list = document.getElementById(base + "-list");
353 var summary = document.getElementById(base + "-summary");
354 var trigger = document.getElementById(base + "-trigger");
355 var a = $(linkObj);
356 if ( (expand == null && a.hasClass("closed")) || expand ) {
357 list.style.display = "none";
358 summary.style.display = "block";
359 trigger.src = toRoot + "assets/images/triangle-opened.png";
360 a.removeClass("closed");
361 a.addClass("opened");
362 } else if ( (expand == null && a.hasClass("opened")) || (expand == false) ) {
363 list.style.display = "block";
364 summary.style.display = "none";
365 trigger.src = toRoot + "assets/images/triangle-closed.png";
366 a.removeClass("opened");
367 a.addClass("closed");
368 }
369 return false;
370}
371
372/* Toggle all inherited classes in a single table (e.g. all inherited methods)
373 * @param linkObj The link that was clicked.
374 * @param expand 'true' to ensure it's expanded. 'false' to ensure it's closed.
375 * 'null' to simply toggle.
376 */
377function toggleAllInherited(linkObj, expand) {
378 var a = $(linkObj);
379 var table = $(a.parent().parent().parent()); // ugly way to get table/tbody
380 var expandos = $(".jd-expando-trigger", table);
381 if ( (expand == null && a.text() == "[Expand]") || expand ) {
382 expandos.each(function(i) {
383 toggleInherited(this, true);
384 });
385 a.text("[Collapse]");
386 } else if ( (expand == null && a.text() == "[Collapse]") || (expand == false) ) {
387 expandos.each(function(i) {
388 toggleInherited(this, false);
389 });
390 a.text("[Expand]");
391 }
392 return false;
393}
394
395/* Toggle all inherited members in the class (link in the class title)
396 */
397function toggleAllClassInherited() {
398 var a = $("#toggleAllClassInherited"); // get toggle link from class title
Scott Maine4d8f1b2012-06-21 18:03:05 -0700399 var toggles = $(".toggle-all", $("#body-content"));
Scott Main7a0090b2010-04-16 09:00:29 -0700400 if (a.text() == "[Expand All]") {
401 toggles.each(function(i) {
402 toggleAllInherited(this, true);
403 });
404 a.text("[Collapse All]");
405 } else {
406 toggles.each(function(i) {
407 toggleAllInherited(this, false);
408 });
409 a.text("[Expand All]");
410 }
411 return false;
412}
413
414/* Expand all inherited members in the class. Used when initiating page search */
415function ensureAllInheritedExpanded() {
Scott Maine4d8f1b2012-06-21 18:03:05 -0700416 var toggles = $(".toggle-all", $("#body-content"));
Scott Main7a0090b2010-04-16 09:00:29 -0700417 toggles.each(function(i) {
418 toggleAllInherited(this, true);
419 });
420 $("#toggleAllClassInherited").text("[Collapse All]");
421}
422
423
424/* HANDLE KEY EVENTS
425 * - Listen for Ctrl+F (Cmd on Mac) and expand all inherited members (to aid page search)
426 */
427var agent = navigator['userAgent'].toLowerCase();
428var mac = agent.indexOf("macintosh") != -1;
429
430$(document).keydown( function(e) {
431var control = mac ? e.metaKey && !e.ctrlKey : e.ctrlKey; // get ctrl key
432 if (control && e.which == 70) { // 70 is "F"
433 ensureAllInheritedExpanded();
434 }
435});