@kyanny's blog

My thoughts, my life. Views/opinions are my own.

pjax を利用したサイト向けの Chrome Extension の書き方

Chrome Extension の Content Scripts を使うと Greasemonkey のようにウェブサイトを加工できて便利だが、 Content Scripts はページのロード後に一度だけ実行されるので、 github.com のように pjax を利用しているサイトではページ遷移後に期待通り実行されないことがある。

pjax は pjax:success などの独自イベントを発火するが、 Content Scripts はサンドボックス環境で実行されるので pjax が発火するイベントを Listen することができない。しかし DOM の変更時に発生するイベントを Listen することはできる。

DOM の変更を検知するためには DOMSubtreeModified が利用できるが、このイベントは DOM Level 3 で deprecated になってしまった。 Mutation events も同様なので、 MutationObserver を使うのがよい。 WIP Pull Request Unhighlignter for GitHub では MutationObserver を利用した。

https://github.com/kyanny/chrome-ext-wip-pull-request-unhighlighter-for-github/blob/134fea5c17ba261c5354ec86c50108261a77ca7c/app.js#L29-L47

MutationObserver はどの要素からのイベントを受け取るかをオプションで細かく制御できるが、設定を誤ると期待するイベントが発火されないので注意。先のスクリプトでは childList: true, subtree: true というオプションを指定して body 以下の全ての子要素(孫要素も含む)からのイベントを受け取り、イベントハンドラ内で mutation.type をチェックして childList のときのみ DOM を変更するスクリプトを実行している。