読者です 読者をやめる 読者になる 読者になる

GreasemonkeyをBookmarklet的に実行してみる

Greasemonkey

Firefox3 の Greasemonkey, unsafeWindow 内の prototype がとれない - 冬通りに消え行く制服ガールは✖夢物語にリアルを求めない。 - subtechの件。
そろそろGreasemonkeyをFirefox3対応にしていきたいところだけど、この問題がすごく厄介。

例えば、はてなスターの星をプロフィールアイコンに置き換えるGreasemonkey Scriptメンテナンス更新 - 0xFFはFirefox2では動くけどFirefox3では動かない。
とりあえず、無理やり動かしてみる。

// ==UserScript==
// @name           replace star by profile icon
// @namespace      http://ss-o.net/
// @include        http://*.hatena.ne.jp/*
// @checkurl       http://ss-o.net/userjs/replaceStarByProfileIcon.user.js
// @version        1.1
// ==/UserScript==

location.href = 'javascript:(' + function(){
(function(unsafeWindow){
  if (unsafeWindow && unsafeWindow.Hatena && unsafeWindow.Hatena.Star){
    var bindStarEntry = unsafeWindow.Hatena.Star.Entry.prototype.bindStarEntry;
    unsafeWindow.Hatena.Star.Entry.prototype.bindStarEntry = function(se){
      var self = this, stars = [];
      for (var i = 0,len = se.stars.length; i < len; i++) {
        var star = se.stars[i];
        if (star.name) {
          var img = unsafeWindow.Hatena.User.getProfileIcon(star.name);
          //img.src = img.src.replace(/\/profile_s/,'/profile');img.width = img.height = 64;
          img.alt = star.name;
          if (!star.img) star.img = img;
        }
        stars.push(star);
      }
      se.stars = stars;
      bindStarEntry.call(self, se);
    }
    var showName = unsafeWindow.Hatena.Star.Star.prototype.showName;
    unsafeWindow.Hatena.Star.Star.prototype.showName = function(e){
      this.screen_name = this.name;
      showName.call(this,e);
    };
  }
})(this.unsafeWindow||window);
}.toString() + ')()';

あえて本体には手を入れずに、関数で囲ってそれをtoStringしてコード部分を取得、そのコードをlocation.hrefに入れてBookmarklet的に実行してあげると。
元々Bookmarkletとしても動くタイプのScript(例えばOperaにも対応してるScriptとか!)はこれで一応動くみたいです。

ちなみに、この方法はそのページに読み込まれているライブラリとかを(おそらく)安全に利用できるメリットがあります。逆に言えばGM関数は使えないというデメリットがあるわけです。そのあたりをうまく使い分ければGreasemonkeyを書くのが少し楽になりそうですね。