情報、エンターテイメント、そして個人に関連したことの源としてウェブの重要性がますます高まるにつれて、HTML 形式で蓄えられたデータにアクセスし閲覧できることは、幅広い他の高度に分岐したソフトウェアアプリケーションにとってますます重要になってきています。それが単純な HTML ページビューワの問題であろうと成熟したウェブブラウザの問題であろうと、HTML ベースの文書を解釈、表示できることは本当に多くの状況においてますます重要な機能です。アプリケーション開発者にとって問題となっているのは、開発期間を最小限にしながらも機敏でがっしりとした製品を仕上げるには、どのようにしてこの決定的に重要な機能性を実装するかです。Gecko、Netscape と Mozilla の心臓部であるレンダリングエンジン "Gecko"を組み込むことは、この問題に対する傑出した解決策です。
Gecko を組み込むことは賢い選択です。Gecko は機敏で、がっしりしていて、高度に標準に準拠しています。Mozilla と Netscape のソフトウェアの中で、それは広く配付され、非常に良くレビューされています。
Gecko はオープンソースです。他の組み込み選択肢とは違って、Gecko のソースコードの全ては自由に入手でき、完全にカスタマイズできます。必要なだけいじくりまわしたり微調整したりできるのです。そして、選択されるライセンスに影響されるにもかかわらず、他の完全な私有商業製品にも、コンポーネントとして Gecko を使用することができます。
そして、Gecko は Mozilla プロジェクトと関連しているので、Gecko を組み込むための努力を援助するための多くの資源が利用できます。Mozilla のウェブサイト、mozilla.org(日本語版)、には組み込みプロジェクトのエリア mozilla.org/projects/embedding/(日本語版)があります。Gecko を組み込んでいる人たちに関連したたくさんのニュースグループだけでなく、彼らの間の情報交換に焦点を当てたニュースグループ、 netscape.public.mozilla.embedding、もあります。コードベースのための完全な相互参照は lxr.mozilla.org/seamonkey/(日本語版)で利用できます。そして、あらゆるバグを整理したり、その過程を追跡したり、修正を支援することは、Bugzilla バグデータベースである bugzilla.mozilla.org/(日本語版)を通じて簡単に行うことができます。
Gecko はまた、頭のてっぺんからしっぽの先まで完全に OS に依存しないように作られています。mozilla.org から直接に、それは Wintel、Mac OS 9.0 と OS X、そして Linux で動きます。そして、たくさんの他の OS 環境へのサードパーティーポートがあります。
最後に、Gecko の使用を許可することは無料です。たとえ最終的なアプリケーションが他の私有の商業的なアプリケーションであっても。非常に一般的に、Mozilla 提供のソースコード(組み込まれたコードではなくて)のどんな修正も私たちのコミュニティーに還元しなければなりません。その同じ元のコードをアプリケーションユーザーの方にも利用できるようにしなければなりません(しばしば mozilla.org ウェブサイトへのリンクによって)。そして、そのアプリケーションは Gecko を組み込んだものであるということを、いくつかの明らかな方法(例えば、ボックス上のロゴや About: ページ上に)で示さなければなりません。利用可能なライセンス形態の厳密な記述は www.mozilla.org/MPL/(日本語版)に示されています。これはライセンス情報に関する法的効力を持つ唯一の完全な情報です。
ひとたび組み込もうと決心したならば、たどらなければならない、3つの主なステップがあります。第1に、コードを手に入れなければなりません。その後に、Gecko コードベースを上手に扱うのに使われている具体的な技術のいくつかを理解しなければなりません。最後に、どの追加の機能を加えたいのか決めなければなりません。このセクションは、あなたをこれらのステップへと案内するでしょう。
現時点で Gecko を組み込むために必要となるファイルを入手する最も良い方法は、全ての Mozilla のソースツリーをダウンロードしてビルドすることです。これは実際、かなり単純な過程です。完全なガイドと関連するリンクは Mozilla のソースコードをダウンロードするで入手できます。次善の、コンポーネントごとに処理する方法は、発展途上で、依然としてβ版の段階です。このプロジェクトについての情報は www.mozilla.org/projects/embedding/GRE.html(日本語版)に見つけられます。さらに、Gecko ランタイム環境(Gecko Runtime Environment, GRE)の開発についても作業が行われています。GRE は、単一のコアライブラリのセットを利用して、Mozilla コンポーネント上にビルドされた多彩なアプリケーションをサポートするでしょう。このプロジェクトは www.mozilla.org/projects/embedding/GRE.html(日本語版)にあります。(もしコンポーネントごとに作業に取りかかりたいなら、バージョンとバイナリの互換性の問題に特に気をつけなければなりません。この領域のヘルプは mozilla.org/projects/xpcom/glue/Component_Reuse.html(日本語版)を見て下さい。)
まず第一に、あなたはいくつかのツールを手に入れなければなりません(基本的には、サポートされたコンパイラ、Perl 配布パッケージ(ディストリビューション)、そして、いくつかの一般的な目的のユーティリティー)。その後、あなたのコンピュータ環境を設定しなければなりません。その次に、ソースをダウンロードしなければなりません。全ツリーをダウンロードしようと思っているなら、2つの方法があります:完全なツリーの tarball を FTP で入手できます。(これは、最も単純な方法です。そして、コンパイルする保証がされています。しかし、それはコードへの最新の追加を含んでいないかもしれません。)または、完全に最新のコードを入手したり、追加更新するために CVS を使うことができます。ひとたびツリーとツールを手に入れ、環境を適切に準備したら、あなたは提供された適切な makefile を走らせさえすれば良いのです。サポートされた OS 環境ごとに詳細な説明があります。
ビルドが完了した時、mozilla/embedding/ config ディレクトリへ、ナビゲートして下さい。そこでは、異なった OS 環境でそれぞれ組み込むための manifest ファイルのサンプルが見つかるでしょう。(全ての名前は "basebrowser" で始まります。)これらはただのサンプルであり、あなたの必要性に完全には合わないかもしれません。しかし、始めるには良い場所です。見本として使うことのできるそれぞれの OS 環境のための組み込みプロジェクトのサンプルもあります。mozilla.org/projects/embedding/examples/index.html(日本語版)を見て下さい。
Mozilla は始めから様々なプラットフォーム間とプログラム言語間を横断して設計と開発をサポートする準備をしていました。この目的のために、数多くの組織内でプログラミング技術が開発されました。そして、それら全てがオブジェクトのカプセル化(情報隠ぺい)という理想に基づいていました。Gecko を組み込む作業をする際には、必然的にこれらの技術の実践的な知識を身に付けることが伴います。そしてそれには、XPCOM、XPIDL、 XPConnect、特別な文字列クラス、場合によっては XUL、を含んでいます。以下の章では、それらへの端的な導入を提供します。更なる情報は mozilla.org サイトで見つけることができます。
Mozilla の技術の最も重要なのは XPCOM、the Cross-Platform Component Object Model(プラットフォームに依存しないコンポーネントオブジェクトモデル)、です。XPCOM は Mozilla 全体を通じてオブジェクトと他のデータの生成、所有、削除を管理する枠組みを提供します。もしあなたが MSCOM を使っているならば、ある基礎的な類似に気がつくでしょう。しかし、重大な違いもあります - XPCOM はプラットフォームに依存せず単一のスレッドの中で幅広く動くよう意図されていて - そしてその2つは今のところ互換性はありません。
XPCOM の核となる部分にこそ、インターフェースの構想があります。インターフェースは、全て特定の機能に関連した、一連のメソッド、属性、関連した定数の単純な記述です:それらのものを実装するクラスとは完全に違います。インターフェースは一種の契約(コントラクト)として供給します:特定のインターフェースをサポートするあらゆるオブジェクトは、それに記述されたサービスをそれが演じることを保証します。インターフェースを可能な限り言語間で平等に保つために、それは特別な言語、インターフェース定義言語 (Interface Difinition Language、IDL)、で書かれています。インターフェースのファイルはしばしば .idl ファイルとして参照されます。これらのファイルは、インターフェースの機能を明細に述べているのに加えて、インターフェースの IID、すなわち、そのグローバルに唯一な識別番号(ID 番号)を運びます。
Gecko 内でのコミュニケーションの多くは、これらの抽象的な構造の点で起きます(慣習から、それらの名前は nsISomething という形式に従います)。
//こう
void ProcessSample(nsISample* aSample) {
aSample->Poke("Hello");
//こうではない
void ProcessSample(nsSampleImpl* aSample) {
aSample->Poke("hello");
XPCOM の抽象のレベルはシステム内での大きな柔軟性を生みます。実装は必要な時に自由に変化します。しかし、はたらくためにはインターフェース自体は固定したままでなければなりません。Mozilla の初期の設計と開発期間全体を通じて、インターフェースはいくらか流動的であってきました。しかしプロジェクトが成熟してくるにつれて、ますます多くのインターフェースが FROZEN(凍結)と印を付けられました。印付けされたどんなインターフェースも将来変化しないと保証されています。
組み込み努力のカギとなる主要なインターフェースのほとんどは、現在凍結されています。しかし、あらゆるインターフェースを使う前に確かめるのは常に良い考えです。インターフェースの状態は .idl ファイルのコメントに一覧表にされています。凍結されたインターフェースは @status FROZEN と印が付けられています。あなたは mozilla 相互参照ツールを使って、lxr.mozilla.org/seamonkey/search?string=%40status+FROZEN に凍結されたインターフェースを探すことができます。凍結されるまでインターフェースはいつ何時変わるかもしれません。凍結過程について詳しい情報は、 組み込みプロジェクトのページ を見て下さい。
ひとたびインターフェースが凍結されたら、Gecko 組み込み API リファレンス に加えられます。
1つのオブジェクトが1つよりも多くのインターフェースをサポートできます。実際、基本的には全てのオブジェクトは、少なくとも2つのインターフェースをサポートします - 特別に役立つ何かをする最小限のインターフェースと、より一般的な目的を供給するインターフェース、nsISupports です。ある意味、nsIsupports は全ての XPCOM インターフェースの原型です。全てのインターフェースはそれから継承します。ほとんどは直接的に継承しています。 それは2つの主要機能を供給します - ランタイムタイプの発見とオブジェクトの寿命管理です。これは MSCOM の IUnknown と機能的には同一のものです。
オブジェクトは多様なインターフェースをサポートできるので、 1つのインターフェースへポインタをもつことや、異なったインターフェース - あなたがひょっとしたらそのインターフェースの機能を必要とするかもしれない - もまたサポートするかどうか知りたい、といったことは完全に可能です。 nsISupports の最初のメソッドである QueryInterface はまさにこれを行うものです。これは実際、「私はこのオブジェクトがタイプ A(インタフェース A に対応)のものであることを知ってるけど、タイプ B(インタフェース B に対応)でもあるかい?」といった質問ができます。
もしそれがそうである(または知っている)ならば、QueryInterface() は新たに要求されたインターフェースに縛りつけられたポインタを呼び出し元に返します。
void ProcessSample(nsISample* aSample) {
nsIExample *example;
nsresult rv;
rv = aSample->QueryInterface(NS_GET_IID(nsIExample),(void **)&example);
if (NS_SUCCEEDED(rv)) {
example->DoSomeOperation();
NS_RELEASE(example); //Release を呼び出すためにマクロを使用します
}
}
XPCOM は実際にオブジェクトを生成するための間接的なメソッド、コンポーネントマネージャー(Conponent Manager)を使用しているから、そして同じオブジェクトへの - しばしば異なったインターフェースに縛りつけられた - 多様なポインタが存在できるから、呼び出し元がそれらのポインタがポイントする全てのオブジェクトを現在見失わないことは、急速に難しくなってきているかもしれません。オブジェクトはそれらが必要とするのよりもより長く、メモリー内のまわりに保たれている可能性があります、それがリークの原因となっているのですが。または、オブジェクトが早まって削除される可能性があります、それがポインタのダングリングの原因となっているのですが。nsISupports における残り2つのメソッド AddRef() と Release() は、この問題を処理するよう設計されています。ポインタが出てくるたびに、そのオブジェクトに対して AddRef() が呼び出され、内部カウンタを増やします。 ポインタがリリースされるたびに Release() が呼び出され、同じ内部カウンタを減らします。 カウンタが 0 に到達するとき、残っているオブジェクトへのポインタはなくなり、オブジェクトは安全に自身を削除します。オブジェクトの寿命の制御はオブジェクト自身の中で留まります。XPCOM の "賢い" ポインタ、nsCOMPtr、すなわちこの過程を自動でするのを助けるユーティリティーについての情報はここを見て下さい。
オブジェクトを生成することもまた、XPCOM では間接的な過程です。ちょうどインターフェースがグローバルな唯一の ID 番号 (IID) をもっているのと同じように、XPCOM のクラスはそれら自身の GUID (グローバルな唯一の ID 番号)すなわち CID が割り当てられます。加えて、XPCOM のクラスはまたテキストベースの ID、契約 ID(Contract ID)、と呼ばれるのもしばしば与えられます。これらの ID の一方またはもう一方は、実際にオブジェクトを作っている永続的な XPCOM コンポーネント、コンポーネントマネージャー、についてのメソッドへと通されます。(XPCOM ではモジュールと呼ばれている)クラスの新しいライブラリがシステムへと初めて導入されるとき、それは自身をコンポーネントマネージャーに登録しなければなりません。コンポーネントマネージャーはそれらが存在しているライブラリへ、それらの ID とともにクラスの地図を作っているレジストリを維持しています。
シングルトンオブジェクトによって供給された限られた数の永続的なサービスは、コンポーネントマネージャーの仲間、サービスマネージャーによって作られて、制御されています。コンポーネントマネージャーはそれ自体、そのような永続的なサービスの例です。
XPCOM 内の機能は抽象的なインターフェースによって記述されています。そして、システムの部分間のほとんどのコミュニケーションは、それらのインターフェースの点で起こります。一方で、インターフェースを実装する基礎的なオブジェクトは、それが維持している相互参照レジストリに基づいたコンポーネントマネージャーによって、間接的に作られます。
全てのインターフェースによって共有された1つの機能とは、実行時(ランタイム)に基盤となるオブジェクトに対して他のインタフェースも実装しているかどうかを聞くことができるというものです。理論上では、ある1つのインターフェースは固定されて変更できません。しかし、Mozilla コードベース内でのこのステージでは、FROZEN と宣言されたインターフェースのみがはっきりと変化しないと保証されます。オブジェクトの寿命管理は加えられた、またはリリースされたオブジェクトへポインタの数を見失わない内部カウンタを通じて、オブジェクト自身の中で起こります。クライアントの唯一の責任はカウンタを増減することです。内部カウンタが 0 に達したとき、オブジェクトは自身を削除します。
しかし、正しいタイミングで AddRef() と Release() を忘れずに呼び出すのが難しいこともあるかもしれません。 この過程をより簡単に、そしてより信頼できるようにするために、XPCOM は内蔵の "賢い" ポインタ、すなわち nsCOMPtr をもっています。このポインタはあなたのために AddRef() と Release() を呼び出すことの面倒をみます。可能な限り nsCOMPtr を使うことはあなたのコードをよりきれいに、そしてより効率よくするでしょう。その賢いポインタについて更なる情報は "完全な nsCOMPtr ユーザーマニュアル" を見て下さい。
Mozilla は実際に非常に多くの内蔵マクロ(慣習から、コード内に全て大文字で書かれています)とか、XPCOM でのコーディングの全過程をより簡単にすることができる nsCOMPtr のようなユーティリティーを提供します。これらの多くは下記のファイルに見つけられます:nsCom.h、nsDebug.h、nsError.h、nsIServiceManager.h、nsISupportsUtils.h。Mozilla はまたメモリの使用をたどるための他の開発ツールなどのものを提供します。これらについての更なる情報は http://www.mozilla-japan.org/performance/ に見つけられます。
XPCOM 全般についての更なる情報は XPCOM に見つけることができます。XPCOM コンポーネント群を作ることを一通り目を通すには、O'Reilly の Creating Applications with Mozilla の第8章を見て下さい。このトピックに完全に専念した新しい本、 Creating XPCOM Components もあります。COM システムへの基礎にある論理のいくつかのより完全な説明は、Don Box による Essential COM の最初の方の章で見つけることができます。それが特に MSCOM に焦点を置いている一方で、その本はそのようなオブジェクトモデルを使うために核となっている合理性のいくつかについての素晴らしい背景を提供します。
ンターフェースは XPIDL、Cross Platform Interface Definition Language(プラットフォームに依存しないインターフェース定義言語)で書かれた抽象的なクラスです。そして、役立つようにするために、それらのインターフェース内で約束された機能は、ある恒常的なプログラミング言語で実装されなければなりません。これを容易にするのは XPIDL コンパイラの仕事です。ひとたびインターフェースが .idl ファイルに定義されたら、XPIDL コンパイラがそれを処理することができます。
コンパイラは多くの物事を出力することができます。しかし、一般的には出力は2つの重要な部分をもっています:完全な C++ インターフェース実装のためのコメントアウトされたテンプレートを含んだ C++ .h ファイルと、インターフェースを Javascript に利用できるようにさせるための XPConnect とともにはたらくタイプライブラリ情報を含んだ XPT ファイルです。XPIDL(単純な C のような言語)の文法・構文についてと、コンパイラの使用についての更なる情報は XPIDL に見つけることができます。
XPConnect は、 Javascript で書かれたコードが、C++ で書かれた XPCOM コンポーネントにアクセスして扱うことを可能にし、またその逆のこともできるようにする XPCOM モジュールです。XPConnect によって、XPCOM インターフェースのどちらの側のコンポーネントも、もう一方の側のオブジェクトがこれらの言語のうちどちらで実装されているかということについて、知ることも気にすることも普通は必要ありません。
あるインターフェースが XPIDL コンパイラを通じて実行されるとき、それは XPT、すなわちタイプライブラリファイルを1つ作ります。XPConnect は、XPCOM インターフェースを横断して C++ のオブジェクトと Javascript のオブジェクトの間に透過的なコミュニケーションを実装するためにこのファイル内の情報を使用するので、たとえあなたがもっぱら C++ で開発しているとしても、それらがあなたのコードとともに生成され、含まれることを確かめるのは重要です。実際には、JS(Javascript)に実装されたブラウザの重要な部分だけではなく、将来的にはあなたが作ったどんなコンポーネントとも互いに影響しあうための JS ベースのコードを誰かが使いたいかもしれません。
Mozilla の出身である XPConnet は C++ と JS の間の相互命令ができることを現在容易にしています。(Python を含んだ)他の言語からのアクセスを可能にするためにそれを広げるためのモジュールは、独立開発の途上です。
ウェブブラウジングには、概して大量の文字列を扱うことが伴います。Mozilla はそのような扱いを容易にし、それを効率的に素早く描画するための C++ クラス階層を開発してきました。オブジェクト間のやりとり(メッセージ)をより単純でエラーのないようにするために、Mozilla はインターフェース、つまり抽象クラスを使用しています。文字列階層もまた、同様の理由により、一連の抽象的なクラス、 nsAString 、 nsASingleFragmentString 、nsAFlatString によって保証されています。(これらは、ダブルバイト文字列を参照しています。 nsACString などが最上層である、シングルバイト文字列を参照する同様な(クラス)階層もあります。) nsAString は文字の連なりであることだけが保証されます。 nsASingleFragmentString は、文字が単一のバッファに蓄えられているということが保証されます。 nsAFlatString は、文字が、単一で終端が null で示されるバッファに蓄えられているだろうことが保証されます。下層には具体的なクラスがある一方で、一般には、ある特定の状況下において、可能な限り最も抽象的な型を使うことが一番です。例えば、ポインタ(の使用)を介して、連結操作を仮想的に行うことができます。そしてその連結操作は、他の文字列同様に使うことのできる nsAString という結果になります。これにより、別のやり方でなされなければならないであろう、メモリの割り当て及びコピーをせずに済むわけです。更なる情報は "XPCOM string guide Mozilla 文字列クラスガイド" を見て下さい。
この最後の Mozilla 技術は、使用するかどうか選択できます。あなたのアプリケーションに、UI(ユーザーインターフェース)をどのように作ると決めるか次第です。 XUL は Mozilla の高度な、柔軟性のある XML UI 言語です。XUL は UI を構築するために、大部分のプラットフォームから独立したウィジェットを、数多く提供します。Netscape と Mozilla は両方ともインターフェースに XUL を使用しています。しかし、全ての組み込み開発者が、XUL を選択しているわけではありません。XBL(eXtensible Binding Language、拡張可能な結びつけの言語)によって、 XUL の XML 要素への挙動を貼付けることができます。XUL についての更なる情報は XUL Reference に、XBL についての更なる情報は XBL - Extensible Binding Language 1.0 に見つけることができます。また、XUL の役立つ良い情報も、XulPlanet(日本語版)にたくさんあります。
これを書いている時点では(02/8/19)、Gecko は部分的にモジュール化された描画エンジンです。基本的なブラウジングよりも高度ないくつかの機能は、いつも Gecko とともに組み込まれます。そして、ある構造上の決定の結果、いくつかの機能についてはいつも Gecko と共に組み込まれるでしょう;現在もいくつかはいつも Gecko とともに組み込まれています。しかし、将来のある時点で、分離可能になるかもしれません;そして、いくつかは現在、完全に選択可能なものとして利用できます。下記の表は、これら追加の機能の現在の状況が書いてあります。
| 機能 | 現在の状況 | 将来の状況 |
|---|---|---|
| FTP サポート | 選択可能 | |
| HTTPS サポート | 選択可能 | |
| 国際文字サポート | 選択可能 | |
| XUL サポート | 必須 | おそらく選択可能 |
| ネットワークサポート | 必須 | もしかしたら選択可能 |
| JavaScript サポート | 必須 | もしかしたら選択可能 |
| CSS サポート | 必須 | 常に必須 |
| DOM サポート | 必須 | ほぼ必須 |
| XML サポート | 必須 | ほぼ必須 |
現時点では、状況は改善しているけれども、レンダリングエンジン Gecko とともに、Mozilla エディタを組み込むことは不確かな問題です。組み込み可能なエディタの状況についての更なる情報は、http://www.mozilla-japan.org/editor/...ing_Guide.html を見て下さい。
以下にあげるのは、Gecko を組み込む際に最も一般的に使われるインターフェースのいくつかについての記述です。これは決して利用できるインターフェースを網羅しているリストではありません。このセクションでのインターフェースは、Mozilla によって提供されたクラスにあるものです。Gecko は、組み込み作業者がインターフェースに実装を提供することを期待しているような、そういった一連のインターフェースもあります。それらの例は次のセクションでカバーされています。
Gecko の初期化と、終了を提供するための、2つの C++ だけの関数があります。初期化関数(NS_InitEmbedding)は Gecko を使おうとする前に呼び出されなければなりません。それは XPCOM が動き出し、必要ならコンポーネントレジストリを作り、グローバルサービスを開始している、ということを確約します。シャットダウン関数(NS_TermEmbedding)は Gecko 組み込みレイヤーを終了させて、グローバルサービスが解放され、ファイルが閉じられ、XPCOM がシャットダウンしたことを確約します。
初期化の間にこのインターフェースを使うことで、組み込み作業者が新しい nsWebBrowser インスタンス(典型的なブラウザウィンドウの「クライアントエリア」を表現しているオブジェクト)と、組み込み作業者の chrome を関連させることができ、あらゆるリスナを登録することができます。このインターフェースはまた、コンテント DOM ウィンドウを得るために、そして、そこから DOM の残りのファイルを得るためにランタイムに使われるかもしれません。
XULPlanet nsWebBrowser reference にも同様にこのクラスについての多くの有益な情報があります。
nsIWebNavigation インターフェースは、URI をウェブブラウザインスタンスに読み込み、セッション履歴機能 - 「戻る」とか「進む」といったような - へのアクセスを提供するのに使われます。このインターフェースはこれを書いている時点では(06/6/06)、凍結(frozen)されていません。
nsIWebBrowserPersist インターフェースは、URI をファイルに保存するのを許可します。このインターフェースはこれを書いている時点では(06/6/06)、凍結されていません。
nsIBaseWindow インターフェースは、一般的なウィンドウと、そのウィンドウ上で実行されるかもしれない基本的な命令(大きさ、位置、ウィンドウタイトルの検索など)を記述します。このインターフェースはこれを書いている時点では(06/6/06)、凍結されていません。