$shibayu36->blog;

株式会社はてなでエンジニアをしています。プログラミングや読書のことなどについて書いています。

はてなダイアリーの編集時に、見出しが自動的にtwitter投稿の欄にコピーされるgrease monkey作った

 最近のはてなダイアリーのアップデートで、エントリーをtwitterに自動通知する機能が付け加わりました。非常に便利です。ただ、今の仕様ではツイートの内容を入力しないと、「見出し+URL」という形で、ツイートの内容を入力すると「入力内容+URL」という形で投稿されます。僕はいつも、「一言+見出し+URL」という形でtwitterで投稿したいため、いつも見出し部分をコピペしていました。非常にめんどくさくなってきたので、見出し部分をツイートの内容に自動的にコピーするgrease monkeyスクリプトを作りました。

fillin_hatena_diary_twi_content_with_title.user.js

その場編集、詳細編集の両方ともで使えます。http://gist.github.com/431043に置いておきました。rawという所をクリックするとインストールできます。

その場編集

タイトル部分のテキストに入力すると、自動的にツイートの内容にコピーされます。
f:id:shiba_yu36:20100610112926p:image

詳細編集

見出し記法(*)を使っている、最初の見出しを自動的にツイートの内容にコピーします。
f:id:shiba_yu36:20100610112927p:image

技術的な事

初めてgrease monkeyスクリプトを書いたので、いろいろはまりました。技術的な事をメモしていきたいと思います。

addEventListenerの引数

addEventListenerには3つの引数を渡します。一つ目がeventのtype, 二つ目が実行する関数、三つ目がバブリングをキャプチャするかどうかです。次のように使います。

document.addEventListener('change', function(){...}, false);
XPathから要素を取得

javascriptXPathを取得するにはdocument.evaluateを使います。
引数は

  1. XPathの文字列。
  2. どのノードに対して行なうか。よく使われるのはdocument。
  3. 名前空間変換関数。HTML文書ではnullを渡す。
  4. 結果の型を指定。https://developer.mozilla.org/ja/Introduction_to_using_XPath_in_JavaScript#XPathResult_Defined_Constantsが参考になる
  5. 結果に利用するオブジェクト。既存のオブジェクトを指定すると、それが再利用される。null指定で問題なし。
var res_snap;
res_snap = document.evaluate('//*[@id="twitter_notification_prefix"]',
     document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
バブリング

その場編集の場合、JavaScriptで動的に入力欄を作っていたため、EventListenerを入力欄に割り当てる事ができませんでした。そこで、バブリングをつかって、documentオブジェクト自身にイベントリスナーを設定し、バブリングしてきたら、もともとイベントが発生してきた元に対してアクションする事で対処しました。

        var fillInTwitterEditInPlace = function(e) {
            if (e.target.name == 'title') {
                var title = e.target;
                var twitter_prefix = title.form.elements.namedItem('twitter_notification_prefix');
                twitter_prefix.value = title.value;
                twitter_prefix.style.color = "";
            }
        };

        document.addEventListener('change', fillInTwitterEditInPlace, true);

関数の中で、e.targetを使うと、もともとイベントが起こった要素が取得できます。e.currentTargetを使うと、イベントを受け取った要素が取得できます(今回の場合はdocument)。便利ですね。