Googleの検索結果にFacebookの「いいね!」を追加表示してあらあらうふふ

最近、facebookの「いいね!」の数を表示しているページが増えてきたなぁと感じます。
ただ、facebookの良いところは「自分の知っている近くの誰か」なので、数だけ出しているよりも「あなたの知り合いの〜さんが」的なことまで表示してるページの方がfacebookっぽいなぁと思ったりします。(それが良いか悪いかは別として。)



で、昔googleの検索結果にはてブとかのブックマーク数を追加してくれるgreasemonkeyとかあったなぁと思い出し、
「ってことは、誰かfacebookのいいねをgoogleの検索結果に表示してくれる機能作ってるんじゃないかな」
と推測。
ということで試しにググってみたんですけど、『自分のサイトに「いいね!」ボタンを追加する』みたいな記事ばっかり出てきて引っかからず。
google chromeの拡張機能ページに行って「facebook」ってキーワードで検索したりしても数が多過ぎて面倒になりました。



結果、探す時間よりも試しにサクッと作ってしまった方が早そうなので作りました。
必要なことは、

  1. googleの検索結果からページのリンク一覧を取ってくる
  2. そのページに「いいね!」している自分のユーザを表示する

ということだけです。



まず、「いいね!」している自分のユーザの表示方法ですが、「いいね!」ボタンを作るページがfacebookに用意されているのでそれをそのまま利用します。
デフォルトの状態で「Get Code」を押せばわかる通り、iframeに対象のページのURLを追加して表示していますね。
ということで、このiframeをgoogleの検索結果に追加すればいいだけですね。


ソースはこんな感じ。
ブックマークレットで動かしたかったので、jQueryをわざわざ使うのイマイチだなと思い、使ったことのないevaluateの使い方をググりながらXPath利用することにしました。

(function(doc) {
    var myClass = 'facebook-like-button',
        liSS =  doc.evaluate(
                    "id('ires')/ol/li[contains(@class, 'w0')]",
                    doc,
                    null,
                    XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
                    null
                ),
        li,
        aSS,
        iframe,
        i,
        l;


    for (i=0, l=liSS.snapshotLength; i<l; ++i) {
        li = liSS.snapshotItem(i);

        if (li.lastChild.className === myClass) {
            continue;
        }

        aSS = doc.evaluate(
                "div/span/h3/a",
                li,
                null,
                XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
                null
        );
    
        iframe = doc.createElement('iframe');
        iframe.className = myClass;
        iframe.src = [
            'http://www.facebook.com/plugins/like.php?href=%%URL%%'
                .replace('%%URL%%', encodeURIComponent(aSS.snapshotItem(0).href)),
            'layout=standard',
            'show_faces=true',
            'width=450',
            'action=like',
            'colorscheme=light',
            'height=80'
        ].join('&amp;');
        iframe.scrolling = 'no';
        iframe.frameBorder = 0;
        iframeStyle = iframe.style;
        iframeStyle.border = 'none';
        iframeStyle.overflow = 'hidden';
        iframeStyle.width = '450px';
        iframeStyle.height = '80px';
        
        li.appendChild(iframe);
    }

})(document);

やってることは、

  1. id='ires'が付いているdivが結果を入れているブロックなので、その中から検索結果一つずつのliを取り出す
  2. liから更に深く辿って行き、aタグのhref(「いいね!」を確認したいページのURL)を取得し、facebookのiframeに付加する
  3. また、同じiframeが何度も追加されないようにチェック用のclassもiframeに付けておく
  4. それぞれのiframeをliの最後に付け足していく

という流れだけです。簡単ですね。



これをブックマークレットにすると下のものになります。

javascript:(function(g){var e="facebook-like-button",h=g.evaluate("id('ires')/ol/li[contains(@class, 'w0')]",g,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null),a,c,f,d,b;for(d=0,b=h.snapshotLength;d<b;++d){a=h.snapshotItem(d);if(a.lastChild.className===e){continue}c=g.evaluate("div/span/h3/a",a,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);f=g.createElement("iframe");f.className=e;f.src=["http://www.facebook.com/plugins/like.php?href=%%URL%%".replace("%%URL%%",encodeURIComponent(c.snapshotItem(0).href)),"layout=standard","show_faces=true","width=450","action=like","colorscheme=light","height=80"].join("&amp;");f.scrolling="no";f.frameBorder=0;iframeStyle=f.style;iframeStyle.border="none";iframeStyle.overflow="hidden";iframeStyle.width="450px";iframeStyle.height="80px";a.appendChild(f)}})(document);

これをgoogleの検索結果のアドレスバーに入れて、カチャカチャカチャ・・・ッターン! とやればほらこんな感じ。

これで何かググった時に「そうだよねそうだよね。やっぱりこのページいいねしてるよね。…あらあら、こっちのページもいいねしてるのね。うふふ。」的なあらあらうふふ感で検索結果を眺められますね。


Google Chrome拡張化する

ネタものなのでここで終わりなんですが、ブックマークレットのままだとやっぱり面倒だなぁと思い、せっかくだからgoogle chrome拡張にしました。
拡張機能のページへアップするわけではないので必要最低限で作りました。



まず適当にディレクトリ作ります。
その中にさっきのJavaScriptfacebook-like-button.jsという名前で保存。
さらにmanifest.jsonというファイルを作り、以下のように書きます。

{
  "name": "Facebook like button for Google search",
  "version": "0.0.1",

  "description": "This extension displays Facebook like buttons in google search results.",

  "content_scripts": [{
     "js": ["facebook-like-button.js"],
     "matches": ["http://www.google.co.jp/search*"],
     "run_at": "document_end"
  }],
  "permissions": ["http://www.google.co.jp/*"]
}

contentとpermissionsだけちゃんとしてれば他はどうでもいいです。
contentで「http://www.google.co.jp/search*というページで、レンダリング終了後に、さっき作ったfacebook-like-button.jsを実行する」という指定をして終了。



ファイル2つだけのシンプルなディレクトリができました。
あとはGoogle Chrome拡張機能を開き(chrome://extensions/)、デベロッパー モードでこのディレクトリを読みこめばOK。
これでgoogle chromeを使ってgoogleの検索結果のページにアクセスすると、さっきと同じ表示になり、あらあらうふふができるようになりましたね。


AutoPagerizeに対応する

さて、ここで終わりにして検索ページを開いてあらあらうふふとやっていたのですが、僕のchromeにはAutoPagerizeが入っていて、ヌルヌルとページが追加された後の結果には「いいね!」が出てこずイマイチです。



ということで、AutoPagerizeに対応させることにしました。
変更後のソースは下のようになります。

(function(doc) {
    var myClass = 'facebook-like-button';
    function addLikeButton($ires) {
        var liSS =  doc.evaluate(
                    ($ires ? "" : "id('ires')/")
                        + "ol/li[contains(@class, 'w0')]",
                    $ires || doc,
                    null,
                    XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
                    null
                ),
        $li,
        aSS,
        $iframe,
        i,
        l;


        for (i=0, l=liSS.snapshotLength; i<l; ++i) {
            $li = liSS.snapshotItem(i);

            if ($li.lastChild.className === myClass) {
                continue;
            }

            aSS = doc.evaluate(
                    "div/span/h3/a",
                    $li,
                    null,
                    XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
                    null
            );
        
            $iframe = doc.createElement('iframe');
            $iframe.className = myClass;
            $iframe.src = [
                'http://www.facebook.com/plugins/like.php?href=%%URL%%'
                    .replace('%%URL%%', encodeURIComponent(aSS.snapshotItem(0).href)),
                'layout=standard',
                'show_faces=true',
                'width=450',
                'action=like',
                'colorscheme=light',
                'height=80'
            ].join('&amp;');
            $iframe.scrolling = 'no';
            $iframe.frameBorder = 0;
            iframeStyle = $iframe.style;
            iframeStyle.border = 'none';
            iframeStyle.overflow = 'hidden';
            iframeStyle.width = '450px';
            iframeStyle.height = '80px';
            
            $li.appendChild($iframe);
        }
    }

    doc.body.addEventListener('AutoPagerize_DOMNodeInserted', function(evt){
        var $ires = evt.target;

        if ($ires.id === 'ires') {
            addLikeButton($ires);
        }
    }, false);

    addLikeButton()

})(document);

対応方法はAutoPagerizeで継ぎ足された部分に自分のスクリプトを適用する方法あれこれ - os0x.blogを参考にさせていただきました。
addEventListenerでAutoPagerize_DOMNodeInsertedを拾ってあげれば良いみたいです。



変更後に再度Google Chrome拡張機能を開き(chrome://extensions/)、「再読み込み」してあげれば完成。
今度はヌルヌルとページ追加されながら「いいね!」が出てきてあらあらうふふな感じになりました。


まとめ

ここまでやって何なんですが、ググるキーワードを変えて検索してたら去年の10月にbingに同じ機能が実装されているんですね…。
まぁ、でもbingを普段使ってないからいいです。
友達承認メールの時しかログインしていないfacebookですが、あらあらうふふがやりたいためにログインしておいてもいいかなぁなんて思う今日この頃です。