2013-07-02
■ The NPA (Not Perfectly Accurate) diagram
Chapter One: Fundamental Concepts
The NPA (Not Perfectly Accurate) diagram at the start of this chapter is a structural diagram of the Mozilla platform. Each rectangular box is a complex subsystem that represents a chunk of technology. Each chunk is about equal in size to one or more software standards. These rectangular boxes are embedded inside the program that makes up the Mozilla platform; they are not particularly separate. The small stacked rectangles represent files that sit in a computer's file system. The platform reads and writes to these files as necessary.
■ XPCOMシェル
Latest topics > Firefoxで独自プロトコルを定義する方法 - outsider reflex
図1(以下を参照)は、新しいプロトコルを実装するのに必要なJavaScriptによるXPCOMシェルの基本的な構造を示しています。
- NSGetModule() は TestModule オブジェクトを返却するもので、XPCOMが私たちのコンポーネントを検索するときに呼び出されます。
- TestModule は、新しいコンポーネントを登録するためのものや、ProtocolFactoryオブジェクトを取得するための、XPCOMが呼び出すいくつかのメソッドを実装しています。
- ProtocolFactoryはMozillaの要求に応じて、Protocolオブジェクトを生成することを許可します。
- Protocolは最終的にはプロトコルの実装となる物で、XPCOMが呼び出すためのいくつかのメソッドを持ちます。newChannelと呼ばれるメソッドは、Mozillaがそのプロトコルを解決する必要が生じた際に実行されるコードを含んでいます。
新しいプロトコルを作るためにコードが変更されなければならない時を除いて、XPCOMシェルのコードの変更はすぐに適用されます。
- 図1:XPCOMシェルの基本的な構造
// XPCOMの定数の定義 // Protocolの定義 // ProtocolFactoryの定義 // TestModuleの定義 function NSGetModule(){ return TestModule; }
■ NSGetFactory() / NSGetModule()
https://developer.mozilla.org/en-US/docs/XPCOM/XPCOM_changes_in_Gecko_2.0
The JavaScript code no longer exports a NSGetModule() function. It now must export a NSGetFactory() function, which accepts a class ID (CID) as a parameter.
CID コンポーネンツ ID ?
■ tombloo.js
https://tombloocodereading.jottit.com/xpi/components/tombloo.js
//XPCOMの定数の定義 const EXTENSION_ID = 'tombloo@brasil.to'; const Cc = Components.classes; const Ci = Components.interfaces; const Cr = Components.results; var ILocalFile = Ci.nsILocalFile; // ... //いろいろ関数の定義 // ----[Application]---- // ----[Utility]---- // Module の定義 Module = { //いろいろプロパティやメソッドの定義 CID: Components.ID('{aec75109-b143-4e49-a708-4904cfe85ea0}'), NAME: 'TomblooService', PID: '@brasil.to/tombloo-service;1', initialized: false, onRegister: function () { //... }, instance: { shouldLoad: function (contentType, contentLocation, requestOrigin, context, mimeTypeGuess, extra) { //... }, shouldProcess: function (aContentType, aContentLocation, aRequestOrigin, aContext, aMimeTypeGuess, aExtra) { //... }, QueryInterface: function (iid) { //... }, }, createInstance: function (outer, iid) { // ここが重要なところ }, } // Module の組み込み var ModuleImpl = { registerSelf: function (compMgr, fileSpec, location, type) { compMgr.QueryInterface(Ci.nsIComponentRegistrar).registerFactoryLocation( Module.CID, Module.NAME, Module.PID, fileSpec, location, type); Module.onRegister && Module.onRegister(compMgr, fileSpec, location, type); }, canUnload: function (compMgr) { return true; }, getClassObject: function (compMgr, cid, iid) { if (!cid.equals(Module.CID)) throw Cr.NS_ERROR_NO_INTERFACE; if (!iid.equals(Ci.nsIFactory)) throw Cr.NS_ERROR_NOT_IMPLEMENTED; Module.onInit && Module.onInit(compMgr, cid, iid); return this.factory; }, // factory factory: { createInstance: function (outer, iid) { if (outer != null) throw Cr.NS_ERROR_NO_AGGREGATION; var obj = Module.createInstance(outer, iid); obj.Module = Module; obj.wrappedJSObject = obj; return obj; } } }; // for Gecko 1.9.x function NSGetModule(compMgr, fileSpec) { return ModuleImpl; } // for Gecko 2.0+ function NSGetFactory(cid) { return ModuleImpl.factory; }