(function() { // anonymize var allTags = {}; var loadedResults = []; /** * Initialization code run upon the DOM being ready. */ $(document).ready(function() { // Parse page query parameters. var params = parseParams(document.location.search); params.tag = params.tag ? makeArray(params.tag) : null; // Load tag and resource dataset. loadTags(); loadResources(); showResults(params); // Watch for keypresses in the keyword filter textbox, and update // search results to reflect the keyword filter. $('#resource-browser-keyword-filter').keyup(function() { // Filter results on screen by keyword. var keywords = $(this).val().split(/\s+/g); for (var i = 0; i < loadedResults.length; i++) { var hide = false; for (var j = 0; j < keywords.length; j++) { if (!resultMatchesKeyword(loadedResults[i].result, keywords[j])) { hide = true; break; } } loadedResults[i].node[hide ? 'hide' : 'show'](); } }); }); /** * Returns whether or not the given search result contains the given keyword. */ function resultMatchesKeyword(result, keyword) { keyword = keyword.toLowerCase(); if (result.title && result.title.en.toLowerCase().indexOf(keyword) >= 0) return true; else if (result.description && result.description.en.toLowerCase().indexOf(keyword) >= 0) return true; else if (result.topicsHtml && result.topicsHtml.replace(/\<.*?\>/g,'').toLowerCase().indexOf(keyword) >= 0) return true; return false; } /** * Populates the allTags array with tag data from the ANDROID_TAGS * variable in the resource data JS file. */ function loadTags() { for (var tagClass in ANDROID_TAGS) { for (var tag in ANDROID_TAGS[tagClass]) { allTags[tag] = { displayTag: ANDROID_TAGS[tagClass][tag], tagClass: tagClass }; } } } /** * Massage the ANDROID_RESOURCES resource list in the resource data JS file. */ function loadResources() { for (var i = 0; i < ANDROID_RESOURCES.length; i++) { var resource = ANDROID_RESOURCES[i]; // Convert the tags array to a tags hash for easier querying. resource.tagsHash = {}; for (var j = 0; j < resource.tags.length; j++) resource.tagsHash[resource.tags[j]] = true; // Determine the type and topics of the resource by inspecting its tags. resource.topics = []; for (tag in resource.tagsHash) if (tag in allTags) { if (allTags[tag].tagClass == 'type') { resource.type = tag; } else if (allTags[tag].tagClass == 'topic') { resource.topics.push(tag); } } // Add a humanized topics list string. resource.topicsHtml = humanizeList(resource.topics, function(item) { return '<strong>' + allTags[item].displayTag + '</strong>'; }); } } /** * Loads resources for the given query parameters. */ function showResults(params) { loadedResults = []; $('#resource-browser-search-params').empty(); $('#resource-browser-results').empty(); var i, j; var searchTags = []; if (params.tag) { for (i = 0; i < params.tag.length; i++) { var tag = params.tag[i]; if (tag.toLowerCase() in allTags) { searchTags.push(tag.toLowerCase()); } } } if (searchTags.length) { // Show query params. var taggedWithHtml = ['Showing technical resources tagged with ']; taggedWithHtml.push(humanizeList(searchTags, function(item) { return '<strong>' + allTags[item].displayTag + '</strong>'; })); $('#resource-browser-search-params').html(taggedWithHtml.join('') + ':'); } else { $('#resource-browser-search-params').html('Showing all technical resources:'); } var results = []; // Create the list of resources to show. for (i = 0; i < ANDROID_RESOURCES.length; i++) { var resource = ANDROID_RESOURCES[i]; var skip = false; if (searchTags.length) { for (j = 0; j < searchTags.length; j++) if (!(searchTags[j] in resource.tagsHash)) { skip = true; break; } if (skip) continue; results.push(resource); continue; } results.push(resource); } // Format and show the list of resource results. if (results.length) { $('#resource-browser-results .no-results').hide(); for (i = 0; i < results.length; i++) { var result = results[i]; var resultJqNode = $(tmpl('tmpl_resource_browser_result', result)); for (tag in result.tagsHash) resultJqNode.addClass('tagged-' + tag); $('#resource-browser-results').append(resultJqNode); loadedResults.push({ node: resultJqNode, result: result }); } } else { $('#resource-browser-results .no-results').show(); } } /** * Formats the given array into a human readable, English string, ala * 'a, b and c', with an optional item formatter/wrapper function. */ function humanizeList(arr, itemFormatter) { itemFormatter = itemFormatter || function(o){ return o; }; arr = arr || []; var out = []; for (var i = 0; i < arr.length; i++) { out.push(itemFormatter(arr[i]) + ((i < arr.length - 2) ? ', ' : '') + ((i == arr.length - 2) ? ' and ' : '')); } return out.join(''); } /** * Parses a parameter string, i.e. foo=1&bar=2 into * a dictionary object. */ function parseParams(paramStr) { var params = {}; paramStr = paramStr.replace(/^[?#]/, ''); var pairs = paramStr.split('&'); for (var i = 0; i < pairs.length; i++) { var p = pairs[i].split('='); var key = p[0] ? decodeURIComponent(p[0]) : p[0]; var val = p[1] ? decodeURIComponent(p[1]) : p[1]; if (val === '0') val = 0; if (val === '1') val = 1; if (key in params) { // Handle array values. params[key] = makeArray(params[key]); params[key].push(val); } else { params[key] = val; } } return params; } /** * Returns the argument as a single-element array, or the argument itself * if it's already an array. */ function makeArray(o) { if (!o) return []; if (typeof o === 'object' && 'splice' in o) { return o; } else { return [o]; } } })();