XPCOMとは、プラットフォームに依存しないコンポーネントを作成するための仕組みです。これによりJavaScriptでは実現できない処理を、C++やJavaなどで記述できます。
Firefox 53以降、XPCOMを利用したアドオンはAMOに登録できません。Firefox 53 - Add-ons/2017 - MozillaWiki
現在ではXPCOMの利用は非推奨とされています。The Future of Developing Firefox Add-ons | Mozilla Add-ons Blog (2015/08/21)
XPConnectによって、JavaScriptオブジェクトからXPCOMオブジェクトにアクセスできるようになります。それはコンポーネント クラスのIDであるContractIDを指定して、
Components.classes[ 'ContractID' ]Components.classes | MDN
のようにすることで、それに関連付けられたXPCOMコンポーネントのオブジェクトを取得できます。
ContractIDは、
@ドメイン名/モジュール名/コンポーネント名;バージョン番号
の形式で表され、おもに次のようなものがあります。
XPCOMコンポーネントのインスタンスを取得する方法には、次の3つがあります。
var sound = Components.classes[ '@mozilla.org/sound;1' ] .createInstance( Components.interfaces.nsISound );
var sound= Components.classes[ '@mozilla.org/sound;1' ] .createInstance() .QueryInterface( Components.interfaces.nsISound );
var Cc = Components.classes[ '@mozilla.org/sound;1' ]; var sound = new Cc( Components.interfaces.nsISound );
XPCOM コンポーネントのインスタンスを作成する - Components.classes | MDN
XPCOMオブジェクトによっては、新規に作成されたオブジェクトではなく、XPCOMオブジェクト自体から使用できるものがあります。そのようなXPCOMのオブジェクトをサービスと呼び、XPCOMオブジェクトからgetService()によって取得できます。
var localFile = Components.classes[ '@mozilla.org/file/local;1' ] .createInstance( Components.interfaces.nsILocalFile );
これは、それぞれのオブジェクトの参照を取得することで、
var Cc = Components.classes; var Ci = Components.interfaces; var file = Cc[ '@mozilla.org/file/local;1' ]; var localFile = file.createInstance( Ci.nsILocalFile );
のように記述することもできます。実際に既存のアドオンでは、このような用例を多く見受けます。Using components - Mozilla | MDN
この参照を定数で保持することもできます。
const Cc = Components.classes; const Ci = Components.interfaces;
しかしこの定数名は他で宣言されることがあるため、これをグローバルなスコープで行うと「TypeError: redeclaration of var Cc」として例外が発生することがあります。よってVarで変数として宣言するのが安全です。Redeclaration of a constant - what the..? • mozillaZine Forums
nsISupportsはすべてのインターフェイスで継承されていて、QueryInterface()メソッドのみを実装しています。
コンポーネントから、指定のインターフェイスを取得できます。
void QueryInterface( in nsIIDRef uuid, // インターフェイスのUUID [iid_is(uuid),retval] out nsQIResult result // );QueryInterface() - nsISupports - XPCOM Interface Reference | MDN
nsIPrefBranchオブジェクトは、ユーザー設定のルートとして生成されます。
var prefBranch = Components.classes[ '@mozilla.org/preferences-service;1' ] .getService( Components.interfaces.nsIPrefBranch );
nsILocalFileオブジェクトは、ファイル操作のためのインスタンスとして生成されます。
var localFile = Components.classes[ '@mozilla.org/file/local;1' ] .createInstance( Components.interfaces.nsILocalFile );
インターフェイスの配列を与えるだけで、簡単にQueryInterface()関数を実装できます。
function generateQI(
interfaces // インターフェイスの配列
);
generateQI() - XPCOMUtils.jsm - Mozilla | MDN
戻り値で、QueryInterface()関数が返されます。