Make Linkで goo.gl を使えるようにするパッチ

Firefox のアドオンのMake Link で、短縮URLの goo.gl を使えるようにするパッチ。
設定に %goo.gl% とすると、goo.gl で短縮されたURLに置換されます。
何故か %tinyurl% が効かないのもついでに修正。

diff -urN makelink.orig/content/makelink/link_maker.js makelink/content/makelink/link_maker.js
--- makelink.orig/content/makelink/link_maker.js	Tue Aug 17 20:28:18 2010
+++ makelink/content/makelink/link_maker.js	Fri Dec 17 22:27:40 2010
@@ -129,7 +129,15 @@
           copyText += info['title'];
           break;
         case 'tinyurl':
-          var shortenedUrl = this.urlShortener_.getShortenedUrl(info['url']);
+          var shortenedUrl = this.urlShortener_.getTinyUrlShortenedUrl(info['url']);
+          if (!shortenedUrl) { 
+            this.logger_.warning('Failed to fetch shortened URL');
+            return false;
+          }
+          copyText += shortenedUrl;
+          break;
+        case 'goo.gl':
+          var shortenedUrl = this.urlShortener_.getGooglShortenedUrl(info['url']);
           if (!shortenedUrl) { 
             this.logger_.warning('Failed to fetch shortened URL');
             return false;
diff -urN makelink.orig/content/makelink/url_shortener.js makelink/content/makelink/url_shortener.js
--- makelink.orig/content/makelink/url_shortener.js	Sat Jun 20 22:48:24 2009
+++ makelink/content/makelink/url_shortener.js	Fri Dec 17 22:15:16 2010
@@ -82,3 +82,88 @@
     return null;
   }
 };
+
+net.soylentred.makelink.UrlShortener.prototype.getGooglShortenedUrl =
+    function(url) {
+  this.logger_.logCall('getGooglShortenedUrl', arguments);
+
+  function c() {
+    for (var l = 0, m = 0; m < arguments.length; m++)
+      l = l + arguments[m] & 4294967295;
+    return l;
+  }
+  function d(l) {
+    l = String(0 < l ? l : l + 4294967296);
+    var m = l;
+    for (var o = 0, n = false, p = m.length - 1; p >= 0; --p) {
+      var q = Number(m.charAt(p));
+      if (n) {
+        q *= 2;
+        o += Math.floor(q / 10) + q % 10;
+      } else {
+        o += q;
+      }
+      n = !n;
+    }
+    m = m = o % 10;
+    o = 0;
+    if (m != 0) {
+      o = 10 - m;
+      if (l.length % 2 == 1) {
+        if (o % 2 == 1)
+          o += 9;
+        o /= 2;
+      }
+    }
+    m = String(o);
+    m += l;
+    return l = m;
+  }
+  function e(l) {
+    for (var m = 5381, o = 0; o < l.length; o++)
+      m = c(m << 5, m, l.charCodeAt(o));
+    return m;
+  }
+  function f(l) {
+    for (var m = 0, o = 0; o < l.length; o++)
+      m = c(l.charCodeAt(o), m << 6, m << 16, -m);
+    return m;
+  }
+
+  var i = e(url);
+  i = i >> 2 & 1073741823;
+  i = i >> 4 & 67108800 | i & 63;
+  i = i >> 4 & 4193280 | i & 1023;
+  i = i >> 4 & 245760 | i & 16383;
+
+  var h = f(url);
+  var k = (i >> 2 & 15) << 4 | h & 15;
+  k |= (i >> 6 & 15) << 12 | (h >> 8 & 15) << 8;
+  k |= (i >> 10 & 15) << 20 | (h >> 16 & 15) << 16;
+  k |= (i >> 14 & 15) << 28 | (h >> 24 & 15) << 24;
+  j = "7" + d(k);
+
+  i = "user=toolbar@google.com&url=";
+  i += encodeURIComponent(url);
+  i += "&auth_token=";
+  i += j;
+
+  request = new XMLHttpRequest();
+  request.open('POST', 'http://goo.gl/api/url',false);
+  request.setRequestHeader('Content-Type' , 'application/x-www-form-urlencoded');
+  request.send(i);
+  if (request.status != 201 || !request.responseText) {
+    this.logger_.warning('Failed to fetch goo.gl shortened URL.' +
+        ' Response code ' + request.status);
+    return null;
+  }
+  try {
+    var json = request.responseText;
+    var data = eval("("+json+")")
+    return data.short_url;
+  } catch (e) {
+    this.logger_.warning('Can\'t get goo.gl URL.\n' +
+        request.responseText);
+    return null;
+  }
+};