Tumblr on Google Reader

By ucnv Last update Apr 2, 2009 — Installed 7,399 times.

There are 5 previous versions of this script.

// ==UserScript==
// @name           Tumblr on Google Reader
// @namespace      http://userscripts.org/users/40991
// @description    Share and reblog to your tumblr from your google reader.
// @include        http://www.google.com/reader/view/*
// @include        https://www.google.com/reader/view/*
// ==/UserScript==

var GoogleReader = {
    expanded: false,
    register: function() {
        $('chrome').addEventListener('DOMNodeInserted', function(e) {
            var box, content;
            if(e.target.id == 'scroll-filler') {
                if(!/http%3A%2F%2F/.test(location.href)) return;
                var link = 'http://' + decodeURIComponent(location.href.split(/http%3A%2F%2F/)[1]);
                Tumblr.checkUrl(link);
                return;
            } else if(/entry-actions/.test(e.target.className)) {
                content = getElementsByXPath('.//div[contains(@class,"entry-container")]', e.target.parentNode)[0];
                box = e.target, GoogleReader.expanded = false;
            } else if(/entry/.test(e.target.className)){
                var x = getElementsByXPath('.//div[contains(@class,"entry-actions")]', e.target);
                if(x) box = x[0], content = e.target, GoogleReader.expanded = true;
            }
            if(!box) return;
            window.setTimeout(function() {
                var a = (Tumblr.owns(getElementsByXPath('.//a[contains(@class,"entry-title-link")]', content)[0].href))? 
                    'reblog' : 
                    'share';
                GoogleReader.makeTumblrButton(a, box, content);
            }, ((GoogleReader.expanded)? 500 : 0));
        }, false);
        window.addEventListener('keypress', function(e) {
            if(e.target.tagName == 'INPUT' || e.target.tagName == 'TEXTAREA') return;
            if(e.which == 27 && Tumblr.bezel) Tumblr.bezel.erase();
            var k = String.fromCharCode(e.which);
            if(!k) return;
            var forceReblog = (k == Tumblr.keyForAction)? false : (k == Tumblr.keyForForceReblog)? true : null;
            var c = $('current-entry');
            if(typeof(forceReblog) != 'boolean' || !c) return;
            var x = getElementsByXPath('.//span[contains(@class,"tumblr-button")]', c);
            if(!x) return;
            var a = (/tumblr-button-reblog/.test(x[0].className))? 'reblog' : 'share';
            Tumblr[a](c, forceReblog);
            
        }, false);
    },
    makeTumblrButton: function(action, target, content) {
        var t = document.createElement('span');
        t.className = 'tumblr-button-' + action + ' link';
        t.style.cssText = 'padding:1px 8px 1px 16px;'
            + 'background-image:url("' + Tumblr[action + 'ButtonImage'] + '");'
            + 'background-color:transparent; background-position:0pt 50%; background-repeat:no-repeat;';
        t.appendChild(document.createTextNode((action == 'share')? 'Share on Tumblr' : 'Reblog'));
        t.addEventListener('mousedown', function() { Tumblr[action](content) }, false);
        target.appendChild(t);
    }
};

var Tumblr = {
    reblogWithConfirm: true,
    keyForAction: 'T',
    keyForForceReblog: 'R',
    reblogUrlBase: 'http://www.tumblr.com/reblog/',
    shareUrlBase: 'http://www.tumblr.com/share',
    reblogButtonImage: ["data:image/png,",
        "%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%10%00%00%00%10%08%0",
        "2%00%00%00%90%91h6%00%00%00%06tRNS%00%FF%00%FF%00%FF7X%1B%7D%00",
        "%00%00%09pHYs%00%00%0E%C4%00%00%0E%C4%01%95%2B%0E%1B%00%00%01%2",
        "0IDATx%9C%95Q%B1%AA%83%40%10%DC%93%83h!%89%87%D8%5BXXI0%C4%C6O%",
        "C8%E7Z%F9%09%82(%A2%16%16%16B%02%A68%12%2C%8C%84%BB%7B%C5I%0A%C",
        "93%C9v%B3%3B%C30%B3H%08%01%BF%8C%F2%91q%BD%5E%7F%13%E4y~%3E%9F%",
        "BF%15PJ)%A5I%924M%237H%08Q%14E%5D%D7%1F%ADl%DB%0E%82%40%A1%94~%",
        "C3%06%00UU%01%00%23%84%24%3E%9DNoyQ%14i%9A%E6%FB%BE%AE%EB%00%80",
        "_%07%C6%18%E7%7C%C1V%14%C54%CD%FD~%8F1%BE%5C.%DB%EDv%168%8E%C39",
        "%7F%3E%9F%96e-B%1F%0E%07%00%A8%AA%AA%EB%3A%D7u%15%008%1E%8F%8E%",
        "E3%3C%1E%8F%3C%CF%17%0E%84%90%DDn'%84%E8%BANn%B0a%18%08%A1%BE%E",
        "F%CB%B2%9C%A6%89RJ%08Y%89%8E%01%A0i%9A%B6m%25%8E%E3x%85%0D%F2q%",
        "9B%CDf%9D%24%C7%F3%3C%90%8F%BB%DF%EF%C30%A4i%3A%8E%E3%7F%E5%0A!",
        "8%E7sK%8C1%5D%D7%C30%CC%B2%ECm%B9%2F%CD%EC%20%F1%EDv%03%00%CE%F",
        "9z%E8%3F%B4%19%8D%FE%40%00%9D%86%00%00%00%00IEND%AEB%60%82"
    ].join(''),
    shareButtonImage: ["data:image/png,",
        "%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%10%00%00%00%10%08%0",
        "2%00%00%00%90%91h6%00%00%00%06tRNS%00%EE%00%F0%00%EE%0B4%C2%80%",
        "00%00%00%09pHYs%00%00%0E%C4%00%00%0E%C4%01%95%2B%0E%1B%00%00%01",
        "%06IDATx%9C%9DR%3DO%C30%10%7D%C1%89rCE%D4%A1%B2%CA%C0%90%C1%03C",
        "7%8F%91%18%B23%F4%EFV%FC%81%8A%8D%01eBH%20%AC%8AB%22%3E.r-%18%0",
        "C%25q%0B(x%3A%9F%DF%BB%F7%EE%7C%D1%FAi%8D!%E7%60%10%FA%3F%84%B8",
        "%7B%B9%AE%AA%E6%99%0FG%14%C5)%80%F7M%0B%A0aV%B9%A2%11%85%84%FA%",
        "B1%BE%BC%AA%CC%CA%10%113%03%F0%01%11%A9%5C%B9%96EJ%3DK%FC%CAfeT",
        "%AE%E6gs%9F)OK%AD53%DF%DF%DD%EC%B1%F4%F6R%CB%89%D4Z'%09%B6%22%B",
        "3%93Y%FDP7%CCB%ECX%1AOdyt%9C%24%B0%16%1E%0D%C09.%8A%A2%0B%FC%26",
        "d%E3%CC%07%D6~6%00%40%08%EA%CF%E5%E7%B1z%11%E78%C8%FF%F1%0F~2%B",
        "F%11%5C%CB%8B%F3%85%B7%B4%BCX%9A%5B%83M%0F%10%07%04k!%A7RN%25%8",
        "0T%A4Y%16*D%7B%96o%5B2%FE%8A%3BeC%850%B7%F3%3Ex%F9%3E%00k%7Ca%0",
        "8%B1%9C%DF%ED%00%00%00%00IEND%AEB%60%82"
    ].join(''),
    loginUrl: 'http://www.tumblr.com/login?redirect_to=%2Fdashboard', 
    bezel: null,
    knownHosts: [/tumblr\.com/],
    unknownHosts: [],
    owns: function(link) {
        for(var x in Tumblr.unknownHosts) if(Tumblr.unknownHosts[x].test(link)) return false;
        for(var x in Tumblr.knownHosts) if(Tumblr.knownHosts[x].test(link)) return true;
        return false;
    },
    checkUrl: function(link) {
        for(var x in Tumblr.unknownHosts) if(Tumblr.unknownHosts[x].test(link)) return;
        for(var x in Tumblr.knownHosts) if(Tumblr.knownHosts[x].test(link)) return;
        var host = (/^.*:\/\/([^\/]*)/.test(link))? RegExp.$1 : '';
        setTimeout(function() {
            GM_xmlhttpRequest({
                method: 'GET',
                url: 'http://www.tumblr.com/check_domain?url=' + encodeURIComponent(host),
                onload: function(r) {
                    var e = new RegExp('^http://' + host);
                    var k = /This domain is configured correctly/.test(r.responseText); // Is it accurate?
                    if(k) Tumblr.knownHosts.push(e);
                    else Tumblr.unknownHosts.push(e);
                }
            });
        }, 0);
    },
    reblog: function(content, force) {
        force = force || !Tumblr.reblogWithConfirm;
        var link = getElementsByXPath('.//a[contains(@class,"entry-title-link")]', content)[0];
        var id = (/\/post\/(\d+)/.test(link.href))? RegExp.$1 : '';
        var url = link.href;
        GM_xmlhttpRequest({method:'GET', url:url, onload: function(r) {
            new RegExp('rk=([0-9a-zA-Z]*)').test(r.responseText);
            var token = RegExp.$1;
            var url = Tumblr.reblogUrlBase + id + '/' + token + '?redirect_to=%2F%20%2F';
            if(!force) Tumblr.prepare();
            else Tumblr.prepare().hide();
            GM_xmlhttpRequest({
                method: 'GET',
                url: url,
                onload: function(r) {
                    var h = Tumblr.modifyReblogHTML(r.responseText, force)
                    if(!force) Tumblr.show(h);
                    else Tumblr.bezel.src = 'data:text/html;,' + encodeURIComponent(h);
                }
            });
        }});
    },
    share: function(content) {
        var link = getElementsByXPath('.//a[contains(@class,"entry-title-link")]', content)[0];
        var s = window.getSelection().toString();
        var url = Tumblr.shareUrlBase + 
                '?v=3&u=' + encodeURIComponent(link.href) +
                '&t=' + encodeURIComponent(link.innerHTML.replace(/<[^>]*>/g, '')) +
                '&s=' + encodeURIComponent(s);
        Tumblr.prepare();
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            onload: function(r) {
                Tumblr.show(Tumblr.modifyShareHTML(r.responseText));
            }
        });
    },
    prepare: function() {
        if(!Tumblr.bezel) {
            var f = Tumblr.bezel = document.createElement('iframe');
            f.id = 'tumblr-bezel';
            var b = document.createElement('div');
            b.id = 'tumblr-bezel-box';
            var x = document.createElement('div');
            x.id = 'tumblr-bezel-container';
            b.appendChild(f);
            document.body.appendChild(b);
            document.body.appendChild(x);
            
            var css = <><![CDATA[
              #tumblr-bezel-container {
                display: none;
                width: 100%;
                height: 100%;
                margin: 0;
                padding: 0;
                text-align: center;
                position: fixed;
                top: 0;
                left: 0;
                z-index: 1050;
                opacity: 0.8;
                background-color: #1c1428;
              }
              #tumblr-bezel-box {
                padding: 20px;
                display: none;
                margin: auto
                overflow: hidden;
                background-color: #f3f3f3;
                position: absolute;
                top: 8%;
                -moz-border-radius: 20px;
                opacity: 1;
                z-index: 1060;
                width: 450px;
                height: 430px;
              }
              #tumblr-bezel {
                border: 0;
                width:450px;
                height: 430px;
                overflow: hidden;
              }
            ]]></>;
            GM_addStyle(css.toString());
            f.show = function() {
                b.style.left = '';
                x.style.display = b.style.display = 'block';
            }
            f.hide = function() {
                b.style.left = '-9000px';
                x.style.display = 'none';
            }
            f.erase = unsafeWindow.eraseTumblrFrame = function() {
                b.style.left = '';
                x.style.display = b.style.display = 'none';
                f.src = 'about:blank';
                window.focus();
            }
            x.addEventListener('click', f.erase, false);
        }
        Tumblr.bezel.parentNode.style.marginLeft = ((document.body.clientWidth - 450) / 2) + 'px';
        Tumblr.show(Tumblr.loadingMessage());
        return Tumblr.bezel;
    },
    show: function(html) {
        Tumblr.bezel.src = 'data:text/html;,' + encodeURIComponent(html);
        Tumblr.bezel.show();
    },
    modifyShareHTML: function(s) {
        if(/<h1>[\s\n]*Log\s*in/.test(s)) return Tumblr.loginPrompt();
        s = s.replace(/<head>/, '<head><base href="' + Tumblr.shareUrlBase + '" />');
        s += 
        <script type="text/javascript">
        <![CDATA[
            var r = window.parent.eraseTumblrFrame;
            window.onunload = function() { if(saving) r() };
            window.addEventListener('keydown', function(e) { if(e.which == 27) r() }, false);
            window.focus();
        ]]>
        </script>.toXMLString();
        s = s.replace(/href="#"/g, 'href="javascript:;"');
        return s;
    },
    modifyReblogHTML: function(s, force) {
        if(/<h1>[\s\n]*Log\s*in/.test(s)) return Tumblr.loginPrompt();
        s = s.replace(/<head>/, '<head><base href="' + Tumblr.reblogUrlBase + '" />');
        s = s.replace(/\/javascript\/application\.js/, '');
        s = s.replace(/'_top'/, "''");
        s = s.replace(/urchinTracker\(\);/, '');
        if(!force) {
            s = s.replace(/global\.css/, '');
            s = s.replace(/background:.+center;/g, '');
            s = s.replace(/_500\.(\w+)"/g, '_100.$1"');  
            s += <>
            <style type="text/css">
            <![CDATA[
              #header, #footer, h1, 
              #header_container, #content_top, #content_bottom, #site_notice {
                display: none;
              }
              body {
                background-color: #f3f3f3;
                margin: 0px;
                padding: 0px;
                font: Normal 13px 'Lucida Grande', Verdana, Helvetica, sans-serif;
                width: 400px;
              }
              a {
                color: #007BFF;
                outline-width: 0px;
                -moz-outline-width: 0px;
              }
              div#container {
                background-color: #fff;
                border-right: solid 1px #ddd;
                border-bottom: solid 1px #ddd;
                position: absolute;
                top: 5px;
                left: 10px;
                right: 15px;
                padding: 0px 15px 0px 15px;
                overflow: auto;
                width: 400px;
                height: 420px;
              }
              div#container h2 {
                margin: 15px 0px 0px 0px;
                font-size: 15px;
              }
              div#container h2 span.optional {
                font-size: 10px;
                color: #bbb;
                font-style: italic;
                font-weight: normal;
              }
              div#container form {
                margin: 0px;
                padding: 0px;
              }
              textarea, input.text, input.text_field {
                width: 370px !important;
                font: Normal 12px 'Lucida Grande', Verdana, Helvetica, sans-serif;
                border: solid 1px #ccc;
                background-color: #f4f4f4;
              }
              .mceToolbarContainer {
                width: 380px !important;
              }
              div#left_column, div#right_column {
                width: 390px !important;
                margin: 5px;
              }
              div#right_column * {
                font-size: 100% !important;
                line-height: 1em;
              }
              div#right_column {
                display: none;
              }
            ]]>
            </style>
            <script type="text/javascript">
            <![CDATA[
                var saving = false;
                var r = window.parent.eraseTumblrFrame;
                window.onunload = function() { if(saving) r() };
                window.addEventListener('keydown', function(e) { if(e.which == 27) r() }, false);
                if($('save_button')) $('save_button').onclick = function() { saving = true; }
                if($('cancel_button')) $('cancel_button').onclick = function() {
                    saving = true;
                    location.href='about:blank';
                    return false;
                };
                window.focus();
            ]]>
            </script>
            </>.toXMLString();
        } else {
            s += 
            <script type="text/javascript">
            <![CDATA[
                window.onunload = window.parent.eraseTumblrFrame;
                document.getElementById('edit_post').submit();
            ]]>
            </script>.toXMLString();
        }
        return s;
    },
    loadingMessage: function() {
        var html = 
        <html>
        <head><title>Loading</title></head>
        <body style="background-color: #d5d5d5;">
          <p style="text-align:center;margin-top:200px;">
            <img src="http://assets.tumblr.com/images/loading.gif" /> loading...
          </p>
        </body>
        <script type="text/javascript">
        <![CDATA[
            var r = window.parent.eraseTumblrFrame;
            window.addEventListener('keydown', function(e) { if(e.which == 27) r() }, false);
            window.focus();
        ]]>
        </script>
        </html>;
        return html.toXMLString();
    },
    loginPrompt: function() {
        var html = 
        <html>
        <head><title>Log in</title></head>
        <body style="background-color: #d5d5d5;">
          <p style="text-align:center;margin-top:200px;">
            Please <a href={Tumblr.loginUrl} target="_blank">log in</a> first.
          </p>
        </body>
        <script type="text/javascript">
        <![CDATA[
            var r = window.parent.eraseTumblrFrame;
            window.addEventListener('keydown', function(e) { if(e.which == 27) r() }, false);
            window.focus();
        ]]>
        </script>
        </html>;
        return html.toXMLString();
    }
};

GoogleReader.register();


function $(e) {
    return document.getElementById(e);
}

function getElementsByXPath(xpath, context) {
    var nodes = [], context = context || document;
    try {
        var r = document.evaluate(xpath, context, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
        for(var i = 0; i < r.snapshotLength; nodes.push(r.snapshotItem(i++)));
    } catch(e) { log(e) }
    return nodes;
}

function log(s) { (console)? console.log(s) : GM_log(s) }