Home | History | Annotate | Download | only in assets
      1 
      2 /* API LEVEL TOGGLE */
      3 addLoadEvent(changeApiLevel);
      4 
      5 var API_LEVEL_ENABLED_COOKIE = "api_level_enabled";
      6 var API_LEVEL_COOKIE = "api_level";
      7 var minLevel = 1;
      8 var maxLevel = 1;
      9 
     10 function 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 
     26 function buildApiLevelSelector() {
     27   maxLevel = SINCE_DATA.length;
     28   var userApiLevelEnabled = readCookie(API_LEVEL_ENABLED_COOKIE);
     29   var userApiLevel = parseInt(readCookie(API_LEVEL_COOKIE));
     30   userApiLevel = userApiLevel == 0 ? maxLevel : userApiLevel; // If there's no cookie (zero), use the max by default
     31 
     32   if (userApiLevelEnabled == 0) {
     33     $("#apiLevelSelector").attr("disabled","disabled");
     34   } else {
     35     $("#apiLevelCheckbox").attr("checked","checked");
     36     $("#api-level-toggle label").removeClass("disabled");
     37   }
     38 
     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   }
     46   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)
     50     select.append(option);
     51   }
     52 
     53   // get the DOM element and use setAttribute cuz IE6 fails when using jquery .attr('selected',true)
     54   var selectedLevelItem = $("#apiLevelSelector option[value='"+userApiLevel+"']").get(0);
     55   selectedLevelItem.setAttribute('selected',true);
     56 }
     57 
     58 function changeApiLevel() {
     59   maxLevel = SINCE_DATA.length;
     60   var userApiLevelEnabled = readCookie(API_LEVEL_ENABLED_COOKIE);
     61   var selectedLevel = maxLevel;
     62 
     63   if (userApiLevelEnabled == 0) {
     64     toggleVisisbleApis(selectedLevel, "body");
     65   } else {
     66     selectedLevel = parseInt($("#apiLevelSelector option:selected").val());
     67     toggleVisisbleApis(selectedLevel, "body");
     68 
     69     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   }
     74 
     75   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>"
     78                               + "<p>To use this " + thing + ", your application must specify API Level \"" + $("body").attr("class") + "\" or higher in its manifest "
     79                               + "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>");
     82   } else {
     83     $("#naMessage").hide();
     84   }
     85 }
     86 
     87 function toggleVisisbleApis(selectedLevel, context) {
     88   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);
     96     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");
    111     else obj.removeClass("absent").removeAttr("title");
    112   });
    113 }
    114 
    115 /* NAVTREE */
    116 
    117 function new_node(me, mom, text, link, children_data, api_level)
    118 {
    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");
    128   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   }
    133   node.li.appendChild(node.label_div);
    134   node.label_div.style.paddingLeft = 10*node.depth + "px";
    135 
    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 (a] 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 
    196 function 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);
    203       if ($(node.label_div).hasClass("absent")) $(node.get_children_ul()).addClass("absent");
    204       $(node.get_children_ul()).slideDown("fast");
    205     }
    206     node.plus_img.src = me.toroot + "assets/images/triangle-opened-small.png";
    207     node.expanded = true;
    208 
    209     // perform api level toggling because new nodes are new to the DOM
    210     var selectedLevel = $("#apiLevelSelector option:selected").val();
    211     toggleVisisbleApis(selectedLevel, "#side-nav");
    212   }
    213 }
    214 
    215 function 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],
    221         node_data[2], node_data[3]);
    222   }
    223 }
    224 
    225 function 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) {
    231       return full.substr(toroot.length);
    232     } 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 
    252 function 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 
    271 function 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));
    276 }
    277 
    278 function init_default_navtree(toroot) {
    279   init_navtree("nav-tree", toroot, NAVTREE_DATA);
    280   
    281   // perform api level toggling because because the whole tree is new to the DOM
    282   var selectedLevel = $("#apiLevelSelector option:selected").val();
    283   toggleVisisbleApis(selectedLevel, "#side-nav");
    284 }
    285 
    286 function init_navtree(navtree_id, toroot, root_nodes)
    287 {
    288   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 }
    318 
    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  */
    326 function 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  */
    353 function 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  */
    373 function 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 */
    391 function 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  */
    403 var agent = navigator['userAgent'].toLowerCase();
    404 var mac = agent.indexOf("macintosh") != -1;
    405 
    406 $(document).keydown( function(e) {
    407 var control = mac ? e.metaKey && !e.ctrlKey : e.ctrlKey; // get ctrl key
    408   if (control && e.which == 70) {  // 70 is "F"
    409     ensureAllInheritedExpanded();
    410   }
    411 });