ページ内で発行されたイベントをcontentscriptで取得したい

368 views
Skip to first unread message

shuwatto

unread,
Dec 12, 2009, 10:49:39 PM12/12/09
to Chromium-Extensions-Japan
こんにちはshuwattoといいます。

ページとcontentscriptでともにjQuery1.3を使っています。

ページ内のjavascriptで、$('foo').trigger('bar')として発行されたイベントに対して、
contentscript内で$('foo').bind('bar', hoge)のようにしてリスナを登録したいと思っています。

isolated worldになっているので、contentscript内から直接ページ内のjavascriptイベントを拾えないようです。
この場合background.html経由で何とか出来るかもと思ったのですが、
backgroundからページ内javascriptにアクセスする方法がわかりませんでした。

何か良い手があれば教えてください。
よろしくお願いします。

smilkobuta

unread,
Dec 12, 2009, 11:38:41 PM12/12/09
to Chromium-Extensions-Japan

executeScriptでうまく行くのではないでしょうか。

* chrome.tabs.executeScript
http://code.google.com/chrome/extensions/tabs.html#method-executeScript

Ohta Shogo

unread,
Dec 13, 2009, 8:55:48 PM12/13/09
to Chromium-Extensions-Japan
こんにちは、太田です。

ページ内のjavascriptというのは、表示しているサイトのJavaScriptのことで、つまり自分では直接編集することはできない部分という
ことで良いでしょうか?

以下、ページ内のJavaScriptをサイトスクリプト、Content Scriptはコンテントスクリプト、backgroundはバックグラウ
ンドスクリプトと呼び分けます。

まず、サイトスクリプトにはコンテントスクリプトからもバックグラウンドスクリプトからもアクセスすることはできません。
ただ、コンテントスクリプトから任意のスクリプトをサイトスクリプトとして実行させることは可能です。
# バックグラウンドからも、chrome.tabs.updateでブックマークレットとしてサイト側のコンテキストでスクリプトを実行することは可
能です。この場合、manifest.jsonでpermissionsにtabsを指定する必要があります。

その方法とは、1つはscript要素を作って挿入する方法、もう1つはlocation.hrefにjavascriptスキームを渡す方法(ブック
マークレット方式)です。
script要素を作る方法は少し手間ですが、動的にスクリプト作って実行することもできますし、予め用意しておいたJavaScriptファイルを挿
入することもできます。
ブックマークレット方式は手軽ですが、文字列でスクリプトを書くのでややコードが読みにくくなります。

で、サイトスクリプトとして実行は可能ですが、当然そのスクリプトからはサイト側のグローバル変数にアクセス可能できる代償に、コンテントスクリプト側
の変数にはアクセスできなくなります。なので、実行したきりで結果を受け取ることができません。

そこで、カスタムイベントを使う方法があります。この辺りは、
http://nanto.asablo.jp/blog/2008/06/26/3596261 Greasemonkey スクリプトとイベントで
通信
が参考になります。

さて、ここまでをスクリプトにしてみるとこんな感じです。

まず、結果を受け取る必要がなければイベントを使う必要がないので、下記のようにするだけでOKです。
location.href = '(' + String(function($){
/*サイトスクリプトとして実行したいコード*/
}) + ')(jQuery);';

結果を受け取りたい場合、下記のようになります。

document.addEventListener("SiteScriptMessage", function (response) {
JSON.parse(response.data); // => SOMEDATA
}, false);

location.href = '(' + String(function(){
var SOMEDATA/*サイト側のデータ*/;
var event = document.createEvent('MessageEvent');
event.initMessageEvent("SiteScriptMessage", true, false,
JSON.stringify(SOMEDATA),
location.protocol + "//" + location.host,
"", window);
document.dispatchEvent(event);
}) + ')();';


以上ですが、ちょっとわかり難いですかね…。
また、質問頂ければと…。

shuwatto

unread,
Dec 14, 2009, 12:16:25 AM12/14/09
to chromium-ext...@googlegroups.com
こんにちは、shuwattoです。
smilkobutaさん、太田さんお返事ありがとうございます。

二つの方法を試してみたのでご報告です。

まずexecuteScriptを使ってみたのですが、
ページ内で発行されるカスタムイベントは取得できませんでした。
executeScriptは拡張側からサイトスクリプトにコードを注入するというものではないようです。
いまいち使いどころが良くわかりません。
私のコードが間違っているという可能性もありますが。

ブックマークレット方式の、
location.href = '(' を location.href = 'javascript:(' に変えてやるとうまくいきました。

今回は結果を受け取る必要が無かったのでイベントリスナを登録するコードは試していませんが、こちらも便利に使えそうです。

どうもありがとうございました。
Reply all
Reply to author
Forward
0 new messages