Firefox拡張入門第7回(独自プロトコルの定義 - ttp)
2ちゃんねるなどでリンク避けとして"ttp://..."を使うことがあります。
今回の拡張では、ttpプロトコルを定義して、"http://..."と同様に扱えるようにしましょう。
- ttpプロトコルを扱うXPCOMコンポーネントのクラスを登録します。
- そのクラスのnewURI関数で、URIの部品を受け取って、nsIURIのインスタンスを返します。(注)
- そのクラスのnewChannel関数で、↑で作ったnsIURIのインスタンスを受け取って、ttpプロトコルのためのnsIChannelのインスタンスを返します。ここではhttpプロトコルのnewChannel関数に処理を丸投げするので簡単です。
(注)"ここではhttpプロトコルのnewURI関数に処理を丸投げするので簡単です"・・・だと芸がないですもんね。
拡張のcomponentsディレクトリ以下に、jsファイルを置けば自動で認識してくれます。
//XPCOMコンポーネントを作るための便利ライブラリを使います。 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); //プロトコルを扱うクラス function TTProtocol() {} TTProtocol.prototype = { //クラスの説明 classDescription: "TTP Protocol", //XPCOMコンポーネントのID。 末尾の"...=ttp"に注目。 contractID : "@mozilla.org/network/protocol;1?name=ttp", //XPCOMコンポーネントのUUID。UUIDは各自で生成します。 classID : Components.ID("0bc360c0-a913-11de-8a39-0800200c9a66"), QueryInterface : XPCOMUtils.generateQI([Components.interfaces.nsIProtocolHandler]), //プロコトルのスキーム。 scheme: "ttp", //ポート番号は任意。HTTPと同様。 defaultPort: -1, //プロトコルの設定。HTTPと同様。 protocolFlags: Components.interfaces.nsIProtocolHandler.URI_STD | Components.interfaces.nsIProtocolHandler.URI_LOADABLE_BY_ANYONE, //ポート番号は任意。 allowPort: function TTProtocolAllowPort(aPort, aScheme) { return false; }, //URIを処理する関数。 //部品を受け取ってnsIURIのインスタンスを返します。 newURI: function TTProtocolNewURI(aSpec, aCharset, aBaseURI) { var uri = Components.classes["@mozilla.org/network/standard-url;1"] .createInstance(Components.interfaces.nsIStandardURL); uri.init(Components.interfaces.nsIStandardURL.URLTYPE_STANDARD, -1, aSpec, aCharset, aBaseURI); uri.QueryInterface(Components.interfaces.nsIURI); return uri; }, //通信チャンネルを作る関数。 //↑で作ったnsIURIのインスタンスを受け取ってnsIChannelのインスタンスを返します。 newChannel: function TTProtocolNewChannel(aURI) { var IOService = Components.classes["@mozilla.org/network/io-service;1"]. getService(Components.interfaces.nsIIOService); return IOService.newChannel("h" + aURI.spec, null, null); } }; //コンポーネントの生成。 function NSGetModule(compMgr, fileSpec){ return XPCOMUtils.generateModule([TTProtocol]); }
特にclassIDには、各コンポーネント固有のUUIDが必要なのでUUID (GUID) Generator on the WEBで生成してください。
newURI関数
この関数は、絶対アドレスと相対アドレスの両方を扱う役目があります。
絶対アドレスのときは、aSpecに文字列"http://.../main.html"、aBaseURIにnullが入っています。
相対アドレスのときは、aSpecに文字列"../images/01.jpg", aBaseURIにnsIURIのインスタンスで、specが"http://.../main.html"なものが入っています。
newURI関数は、これらの部品をもとに、nsIURIのインスタンスを作って返します。
newURI関数のnsIStandardURL
この部品をイチから料理するのは面倒です。
特に"http://..."の処理は複雑で、":80"があったり、"user@domain"があったり・・・。
似たり寄ったりの処理を"ftp://..."や"file://..."でも使うので、このnsIStandardURLがあります。
今回の"ttp://..."はhttpと同じなので、コイツに任せればおしまいです。
さらに柔軟にURIを作りたいときは、nsISimpleURIを使うこともあるようです。
独自プロトコルの使いどころ
ブラウザの窓の中に、"CSSとJavascriptを駆使したブラウザ的なページ"を作りはじめたら、
このテクニックが必要なサインです。ブラウザの中にブラウザを作っていませんか?
例えばGMailの画面は、gmailto:があるとスッキリする気がします。
Webブラウザの未来Web-based protocol handlersに期待しましょう。