nire0510 / Ember API Meta Data

// ==UserScript==
// @name         Ember API Meta Data
// @namespace    http://nirelbaz.com/
// @version      0.3
// @description  Adds extra meta data to Ember's API page side bar items
// @author       Nir Elbaz
// @match        http://emberjs.com/api/*
// @grant        none
// @require http://code.jquery.com/jquery-latest.js
// ==/UserScript==
/* jshint -W097 */
'use strict';

(function ($, undefined) {
    var cache;
    
    // initialization:
    (function () {
        var arrDeferred;
        
        cache = getCache();
        arrDeferred = scanMenu();
        
        $.when.apply($, arrDeferred).done(
            function () {
                updateCache();
            }
        );
    })();
    
    /**
     * Gets cached items statues in order to minimize http requests
     */
    function getCache() {
        var strCachedItems = localStorage.getItem('ember-api-meta-data'),
            dtmNow = new Date();
        
        return (strCachedItems && (dtmNow.getDate().toString() + dtmNow.getMonth().toString() === getLastUpdated()) ? JSON.parse(strCachedItems) : {});
    }
    
    /**
     * Updates cache with latest results
     */
    function updateCache() {
        localStorage.setItem('ember-api-meta-data', JSON.stringify(cache));
        setLastUpdated();
    }
    
    /**
     * Sets last updated date to today
     */
    function setLastUpdated() {
        var dtmNow = new Date();
        
        return localStorage.setItem('ember-api-meta-lastupdated', dtmNow.getDate().toString() + dtmNow.getMonth().toString());
    }
    
    /**
     * Gets the date stamp cache was last updated
     */
    function getLastUpdated() {
        return localStorage.getItem('ember-api-meta-lastupdated');
    }
    
    /**
     * Scans Ember API side menu items
     */
    function scanMenu() {
        var arrDeferred = [];
        
        $('a:contains("Classes")').next().find('li a').each(
            function (index, elem) {
                if (cache.hasOwnProperty(elem.getAttribute('href'))) {
                    markItem(elem, cache[elem.getAttribute('href')]);
                }
                else {
                    var promise = $.get(elem.getAttribute('href'));
                    
                    promise.then(
                        function (data) {
                            var arrStatuses = $.makeArray($(data).find('.api-header + hr ~ p').map(function (index, elem) { return elem.innerText }));

                            markItem(elem, arrStatuses);
                            cache[elem.getAttribute('href')] = arrStatuses;
                        }
                    );
                    
                    arrDeferred.push(promise);
                }
            }
        );
        
        return arrDeferred;
    }
    
    /**
     * Marks menu item according to its status
     */
    function markItem(elem, arrStatuses) {
        arrStatuses.forEach(
            function (strStatus) {
                // set style:
                switch (strStatus) {
                    case 'DEPRECATED':
                        elem.style.textDecoration = 'line-through';
                        break;
                    case 'PRIVATE':
                        elem.style.color = 'gray';
                        break;
                }
                // set tooltip:
                elem.setAttribute('title', elem.hasAttribute('title') ? elem.getAttribute('title') + ' ' + strStatus : strStatus);
            }
        );
    }
})(window.jQuery);