Home | History | Annotate | Download | only in assets
      1 (function() { // anonymize
      2 
      3 var allTags = {};
      4 var loadedResults = [];
      5 
      6 /**
      7  * Initialization code run upon the DOM being ready.
      8  */
      9 $(document).ready(function() {
     10   // Parse page query parameters.
     11   var params = parseParams(document.location.search);
     12   params.tag = params.tag ? makeArray(params.tag) : null;
     13 
     14   // Load tag and resource dataset.
     15   loadTags();
     16   loadResources();
     17 
     18   showResults(params);
     19 
     20   // Watch for keypresses in the keyword filter textbox, and update
     21   // search results to reflect the keyword filter.
     22   $('#resource-browser-keyword-filter').keyup(function() {
     23     // Filter results on screen by keyword.
     24     var keywords = $(this).val().split(/\s+/g);
     25     for (var i = 0; i < loadedResults.length; i++) {
     26       var hide = false;
     27       for (var j = 0; j < keywords.length; j++) {
     28         if (!resultMatchesKeyword(loadedResults[i].result, keywords[j])) {
     29           hide = true;
     30           break;
     31         }
     32       }
     33 
     34       loadedResults[i].node[hide ? 'hide' : 'show']();
     35     }
     36   });
     37 });
     38 
     39 /**
     40  * Returns whether or not the given search result contains the given keyword.
     41  */
     42 function resultMatchesKeyword(result, keyword) {
     43   keyword = keyword.toLowerCase();
     44   if (result.title &&
     45       result.title.en.toLowerCase().indexOf(keyword) >= 0)
     46     return true;
     47   else if (result.description &&
     48            result.description.en.toLowerCase().indexOf(keyword) >= 0)
     49     return true;
     50   else if (result.topicsHtml &&
     51            result.topicsHtml.replace(/\<.*?\>/g,'').toLowerCase().indexOf(keyword) >= 0)
     52     return true;
     53   return false;
     54 }
     55 
     56 /**
     57  * Populates the allTags array with tag data from the ANDROID_TAGS
     58  * variable in the resource data JS file.
     59  */
     60 function loadTags() {
     61   for (var tagClass in ANDROID_TAGS) {
     62     for (var tag in ANDROID_TAGS[tagClass]) {
     63       allTags[tag] = {
     64         displayTag: ANDROID_TAGS[tagClass][tag],
     65         tagClass: tagClass
     66       };
     67     }
     68   }
     69 }
     70 
     71 /**
     72  * Massage the ANDROID_RESOURCES resource list in the resource data JS file.
     73  */
     74 function loadResources() {
     75   for (var i = 0; i < ANDROID_RESOURCES.length; i++) {
     76     var resource = ANDROID_RESOURCES[i];
     77 
     78     // Convert the tags array to a tags hash for easier querying.
     79     resource.tagsHash = {};
     80     for (var j = 0; j < resource.tags.length; j++)
     81       resource.tagsHash[resource.tags[j]] = true;
     82 
     83     // Determine the type and topics of the resource by inspecting its tags.
     84     resource.topics = [];
     85     for (tag in resource.tagsHash)
     86       if (tag in allTags) {
     87         if (allTags[tag].tagClass == 'type') {
     88           resource.type = tag;
     89         } else if (allTags[tag].tagClass == 'topic') {
     90           resource.topics.push(tag);
     91         }
     92       }
     93 
     94     // Add a humanized topics list string.
     95     resource.topicsHtml = humanizeList(resource.topics, function(item) {
     96       return '<strong>' + allTags[item].displayTag + '</strong>';
     97     });
     98   }
     99 }
    100 
    101 /**
    102  * Loads resources for the given query parameters.
    103  */
    104 function showResults(params) {
    105   loadedResults = [];
    106   $('#resource-browser-search-params').empty();
    107   $('#resource-browser-results').empty();
    108 
    109   var i, j;
    110   var searchTags = [];
    111   if (params.tag) {
    112     for (i = 0; i < params.tag.length; i++) {
    113       var tag = params.tag[i];
    114       if (tag.toLowerCase() in allTags) {
    115         searchTags.push(tag.toLowerCase());
    116       }
    117     }
    118   }
    119 
    120   if (searchTags.length) {
    121     // Show query params.
    122     var taggedWithHtml = ['Showing technical resources tagged with '];
    123     taggedWithHtml.push(humanizeList(searchTags, function(item) {
    124       return '<strong>' + allTags[item].displayTag + '</strong>';
    125     }));
    126     $('#resource-browser-search-params').html(taggedWithHtml.join('') + ':');
    127   } else {
    128     $('#resource-browser-search-params').html('Showing all technical resources:');
    129   }
    130 
    131   var results = [];
    132 
    133   // Create the list of resources to show.
    134   for (i = 0; i < ANDROID_RESOURCES.length; i++) {
    135     var resource = ANDROID_RESOURCES[i];
    136     var skip = false;
    137 
    138     if (searchTags.length) {
    139       for (j = 0; j < searchTags.length; j++)
    140         if (!(searchTags[j] in resource.tagsHash)) {
    141           skip = true;
    142           break;
    143         }
    144 
    145       if (skip)
    146         continue;
    147 
    148       results.push(resource);
    149       continue;
    150     }
    151 
    152     results.push(resource);
    153   }
    154 
    155   // Format and show the list of resource results.
    156   if (results.length) {
    157     $('#resource-browser-results .no-results').hide();
    158     for (i = 0; i < results.length; i++) {
    159       var result = results[i];
    160       var resultJqNode = $(tmpl('tmpl_resource_browser_result', result));
    161       for (tag in result.tagsHash)
    162         resultJqNode.addClass('tagged-' + tag);
    163       $('#resource-browser-results').append(resultJqNode);
    164 
    165       loadedResults.push({ node: resultJqNode, result: result });
    166     }
    167   } else {
    168     $('#resource-browser-results .no-results').show();
    169   }
    170 }
    171 
    172 /**
    173  * Formats the given array into a human readable, English string, ala
    174  * 'a, b and c', with an optional item formatter/wrapper function.
    175  */
    176 function humanizeList(arr, itemFormatter) {
    177   itemFormatter = itemFormatter || function(o){ return o; };
    178   arr = arr || [];
    179 
    180   var out = [];
    181   for (var i = 0; i < arr.length; i++) {
    182     out.push(itemFormatter(arr[i]) +
    183         ((i < arr.length - 2) ? ', ' : '') +
    184         ((i == arr.length - 2) ? ' and ' : ''));
    185   }
    186 
    187   return out.join('');
    188 }
    189 
    190 /**
    191  * Parses a parameter string, i.e. foo=1&bar=2 into
    192  * a dictionary object.
    193  */
    194 function parseParams(paramStr) {
    195   var params = {};
    196   paramStr = paramStr.replace(/^[?#]/, '');
    197 
    198   var pairs = paramStr.split('&');
    199   for (var i = 0; i < pairs.length; i++) {
    200     var p = pairs[i].split('=');
    201     var key = p[0] ? decodeURIComponent(p[0]) : p[0];
    202     var val = p[1] ? decodeURIComponent(p[1]) : p[1];
    203     if (val === '0')
    204       val = 0;
    205     if (val === '1')
    206       val = 1;
    207 
    208     if (key in params) {
    209       // Handle array values.
    210       params[key] = makeArray(params[key]);
    211       params[key].push(val);
    212     } else {
    213       params[key] = val;
    214     }
    215   }
    216 
    217   return params;
    218 }
    219 
    220 /**
    221  * Returns the argument as a single-element array, or the argument itself
    222  * if it's already an array.
    223  */
    224 function makeArray(o) {
    225   if (!o)
    226     return [];
    227 
    228   if (typeof o === 'object' && 'splice' in o) {
    229     return o;
    230   } else {
    231     return [o];
    232   }
    233 }
    234 
    235 })();
    236