Yodlee Time = Money

Converts money spent into time spent

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// vim: tw=80 ts=4 sw=4 et nu ai si
//
// ==UserScript==
// @name           Yodlee Time = Money
// @namespace      http://www.arthaey.com/
// @description    Converts money spent into time spent
// @include        https://moneycenter.yodlee.com/moneycenter/chart.moneycenter.do?*chartId=6*
// @version        1.0
//
// Backed up from http://userscripts.org/scripts/review/12875
// Last updated on 2007-10-09
// ==/UserScript==

/* HOW TO USE:
 *
 *  To set the "minutes-per-dollars" ratio:
 *
 *   1. right-click on the Greasemonkey monkey face in the status bar
 *   2. select the "Select User Script Commands" menu
 *   3. select the "Set Minutes Per Dollars" menu item
 *   4. enter in the numbers of minutes it takes you to earn $1
 *       - if it takes you more than an hour, multiply by 60 to get minutes
 *       - fractional minutes ARE allowed (15.5, for example)
 *
 * Now, go to the "Expenses Analysis" chart for your Yodlee Moneycenter account.
 * The table column titled "$ Amount" will now include the amount of time it
 * "cost" you to earn that money.
 *
 * Any time you want to update your minutes-per-dollars ratio, just select the
 * User Script Command from the Greasemonkey menu. The page will reload to
 * display the new calculations.
 *
 * CHANGELOG:
 *  v1.0 - initial release (inspired by the book "Your Money or Your Life")
 *
 */

window.addEventListener("load", function(){

    var DEBUG = true; // FIXME

    /* UTILITY FUNCTIONS *****************************************************/

    function debug(msg) {
        if (DEBUG) console.log("DEBUG: " + msg);
    }

    /* Finds elements whose id matches the given regexp. */
    function getElementsByIdRegExp(regex, restrict) {
        var matchingElements = [];

        if (!regex) return matchingElements;
        //if (restrict != "id" && restrict != "class") restrict = null;

        var elements = document.getElementsByTagName("*");
        var element;

        for (var i = 0; i < elements.length; i++) {
            element = elements[i];
            if (element.id.match(regex)) {
                matchingElements.push(element);
            }
        }

        return matchingElements;
    }

    /*
     * Written by Jonathan Snook, http://www.snook.ca/jonathan
     * Add-ons by Robert Nyman, http://www.robertnyman.com
     */
    function getElementsByClassName(className, tag, elm){
        var testClass = new RegExp("(^|\\s)" + className + "(\\s|$)");
        var tag = tag || "*";
        var elm = elm || document;
        var elements = (tag == "*" && elm.all)? elm.all : elm.getElementsByTagName(tag);
        var returnElements = [];
        var current;
        var length = elements.length;
        for(var i=0; i<length; i++){
            current = elements[i];
            if(testClass.test(current.className)){
                returnElements.push(current);
            }
        }
        return returnElements;
    }

    // returns cents
    function stringToMoney(moneyStr) {
        if (!moneyStr) return null;

        // convert to string, if necessary
        if (!moneyStr.replace) {
            moneyStr = moneyStr.toString();
        }

        // remove any non-digit characters, excepting "."
        moneyStr = moneyStr.replace(/[^0-9.]/g, '');

        // add cents to even dollar amounts
        if (!moneyStr.match(/[.]/)) {
            moneyStr += ".00";
        }

        // convert to an integer amount of cents
        return Math.round(parseFloat(moneyStr) * 100);
    }

    function moneyToString(money) {
        var cents = Math.round(money);
        var even = (cents % 100 == 0);
        var moneyStr = new Number(Math.round(cents) / 100).toLocaleString();
        return "$" + moneyStr + (even ? ".00" : "");
    }

    const MIN_PER_HR  = 60;
    const MIN_PER_DAY = 60 * 24;
    const MIN_PER_YR  = 60 * 24 * 365;

    function timeToString(time) {
        if (!time) return;

        var years   = Math.floor(time / MIN_PER_YR);
        var days    = Math.floor((time - years * MIN_PER_YR) / MIN_PER_DAY);
        var hours   = Math.floor((time - days * MIN_PER_DAY) / MIN_PER_HR);
        var minutes = Math.floor(time % 60);

        var check = minutes +
                    hours * MIN_PER_HR +
                    days * MIN_PER_DAY +
                    years * MIN_PER_YR;

        if (check != Math.floor(time)) {
            debug("ERROR in time conversion: " + check + " vs " + time + " (" +
                minutes + "m, " +
                hours   + "h, " + 
                days    + "d, " + 
                years   + "y)");
        }

        var timeStr = minutes + "m";
        if (hours > 0) timeStr = hours + "h, " + timeStr;
        if (days  > 0) timeStr = days  + "d, " + timeStr;
        if (years > 0) timeStr = years + "y, " + timeStr;

        return timeStr;
    }

    String.prototype.trim = function() { return this.replace(/^\s+|\s+$/, ''); };

    /* MAIN FUNCTIONS ********************************************************/

    function promptMinutesPerDollar(oldValue) {
        return prompt("Minutes Per Dollar", oldValue);
    }

    function setMinutesPerDollar() {
        var oldValue = GM_getValue("MinutesPerDollar", null);
        GM_setValue("MinutesPerDollar", promptMinutesPerDollar(oldValue));
        if (oldValue) window.location.reload();
    }

    function getMinutesPerDollar() {
        var minutesPerDollar = GM_getValue("MinutesPerDollar", null);
        if (!minutesPerDollar) {
            minutesPerDollar = promptMinutesPerDollar("");
        }
        GM_setValue("MinutesPerDollar", minutesPerDollar);
        return minutesPerDollar;
    }

    function doConvertMoneyToTime() {
        minutesPerDollar = getMinutesPerDollar();
        if (!minutesPerDollar) return;

        var table = document.getElementById("expenseAnalysis");
        if (!table) return;

        var cells = getElementsByClassName("rcell", "td", table);
        var cell, money, moneyStr, time, timeStr;

        // both percent and money columns are "rcell", so skip every other cell
        for (var i = 1; i < cells.length; i += 2) {
            cell = cells[i];
            moneyStr = cell.textContent.trim();
            money = stringToMoney(moneyStr); // in cents, NOT dollars
            if (!money) continue;

            time = minutesPerDollar * (money / 100);
            timeStr = timeToString(time);
            debug("Row " + (i+1)/2 + ": " + moneyStr + " == " + timeStr);
            cell.innerHTML =
                "<span style='float:left'>(" + timeStr + ")</span>&nbsp;" +
                moneyStr;
        }
    }

    GM_registerMenuCommand("Set Minutes Per Dollar", setMinutesPerDollar);
    doConvertMoneyToTime();

}, true);