DATE : 2008/11/22 (Sat)
Firefox 拡張で、特定の URL が読み込まれた際に他のページへ飛ばすには、nsIWebProgressListener インタフェースを実装したオブジェクトを作ります。
function MyListener() {
}
MyListener.prototype = {
/*
* nsIWebProgressListener の実装
*/
QueryInterface : function(aIID) {
if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
aIID.equals(Components.interfaces.nsISupports)) {
return this;
}
throw Components.results.NS_NOINSTANCE;
},
onStateChange : function(aWebProgress, aRequest, aFlag, aStatus) {
},
onLocationChange : function(aProgress, aRequest, aURI) {
},
onProgressChange : function(aProgress, aRequest, aCurSelfProgress,
aMaxSelfProgress, aCurTotalProgress,
aMaxTotalProgress) {
},
onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage) {
},
onSecurityChange : function(aWebProgress, aRequest, aState) {
}
}
nsIWebProgressListener インタフェースを実装したオブジェクトは、ページへのリクエストを監視できます。ページへのリクエストが発生すると onStateChange メソッドが呼ばれるので、このメソッド内に、移動したいページの URL へのリクエストを監視するコードを書きます。
onStateChange : function(aWebProgress, aRequest, aFlag, aStatus) {
var url = aRequest.name;
if (aFlag & Components.interfaces.nsIWebProgressListener.STATE_START) {
// url のページへのリクエストが発生した際に到達する
}
},
リクエストされた URL を取得するには、引数 aRequest の型である nsIRequest の name プロパティを使用します。また、リクエストの開始かどうかは、引数 aFlag のビット列を見ることでわかります。
引数 aRequest の name プロパティの中身が予期していた URL と同じであれば、別のページへ飛ばすようなコードを書きます。ここで、SOURCE_URL は別ページへ飛ばす対象となる URL、DESTINATION_URL は、移動先の URL を表します。
onStateChange : function(aWebProgress, aRequest, aFlag, aStatus) {
var url = aRequest.name;
if (aFlag & Components.interfaces.nsIWebProgressListener.STATE_START) {
if (url == SOURCE_URL) {
aWebProgress.DOMWindow.location.replace(DESTINATION_URL);
}
}
},
nsIWebProgress 型である引数 aWebProgress から、現在のページを表示している nsIDOMWindow 型のオブジェクトを取得し、そのページの場所を表す Location オブジェクトを使用して、移動先のページに置き換えます。Location オブジェクトでは、assign メソッドを使用してページを置き換える方法もありますが、上記のコードでは replace メソッドを使用しました。assing メソッドでは置き換えた元のページが履歴に残りますが、replace では残りません。
現在のページの URL は、 nsIDOMWindow 型のオブジェクトから取得した Location オブジェクトを使用しても取得できますが、今回はその方法が使えません。Location オブジェクトの表す URL はすでに読み込みが完了した後のページのものなので、上記のコードで新しくリクエストされた URL を Location オブジェクトから取得しようとしても、現在表示されているページの URL が取得されてしまいます。replace メソッドを使用してページを置き換えると新しいリクエストが発生するので、無限ループになる場合もあります。そのため、リクエストされた URL を使用する際には、必ず引数 aRequest の name プロパティから取得するようにしてください。
(;^ω^)これで長時間つまりました。
あとは、このリスナーオブジェクトを Firefox に登録します。
var myListener = new MyListener();
function load() {
gBrowser.addProgressListener(
myListener,
Components.interfaces.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
}
function unload() {
gBrowser.removeProgressListener(myListener);
}
window.addEventListener("load", load, false);
window.addEventListener("unload", unload, false);
参考文献
- On page load - MDC
- Progress Listeners - MDC
- nsIWebProgressListener - MDC
- nsIWebProgress - MDC
- Interface Reference - nsIRequest
- nsIDOMWindow - MDC
- location - MDC
