|
これは kdelibs/khtmlにあるものです。 この文書では、手短かにhtmlライブラリの内部デザインの概観を説明します。私がこれを書いたのは、khtmlライブラリがかなり膨大なものになってしまって最初にソースコードを読む際に途方に暮れてしまうからです。このドキュメントを読んだからといってkhtmlを理解したことにはなりませんが、ソースコードをより楽に読んでもらう助けになったらなと思います。 ライブラリはいくつかの異なるパーツから成り立っています。基本的にライブラリを使用する際にはKHTMLPartのインスタンスを作成し、データを与えればよいです。 (注)実際のコード : http://devel-home.kde.org/~larrosa/tutorial/p4.html 多かれ少なかれkhtmlを他のアプリケーションで用いようと思ったならば、知らなければならない事はこれだけです。 以下では、現在web technolobyの分野で使われている専門用語について貴方がすでに知っているものとします。もし知らないならば、いくつかの参照すべきリストを示します。
Tokenizer and parser 新しいドキュメントをパースし始めるときはまず、Part(in khtml_part.cpp::begin())によってDocumentImpl?* (for XML documents)やHTMLDocumentImpl?*オブジェクトが生成されます。 XMLTokenizerはQtのQXMLクラスを用いてドキュメントをパースし、そのSAX interfaceを用いてkhtmls DOMへとパースします。 HTMLのtokenizerはkhtmltokenizer.cppにあります。 tokenizerは文字毎に完全に状態が変ります。 HTMLTokenizerはHTMLParserを生成します。 HTMLとXMLにおける大きな違いの一つは、HTMLのParserとTokernizerはデータが運ばれると供に徐々にパースできるのに対して、XMLTokenizer(QtのXMLParserの制限が原因なのですが)は完全に文書がロードされた後しかその文書をパースできません。 The DOM in khtml 文書をパースすると、以下の様なDOMツリーが作成されます。
HTMLDocumentElement
|--> HTMLHeadElement
| \--> HTMLStyleElement
| \--> CSSStyleSheet
\--> HTMLBodyElement
|--> HTMLHeadingElement
| \--> Text
|--> Text
\--> HTMLParagraphElement
|--> Text
|--> HTMLImageElement
\--> Text
実際には上記のクラスはDOMにアクセスするためのインターフェースです。
HTMLDocumentElementImpl*
|--> HTMLHeadElementImpl*
| \--> HTMLStyleElementImpl*
| \--> CSSStyleSheetImpl*
\--> HTMLBodyElementImpl*
|--> HTMLHeadingElementImpl*
| \--> TextImpl*
|--> TextImpl*
\--> HTMLParagraphElementImpl*
|--> TextImpl*
|--> HTMLImageElementImpl*
\--> TextImpl*
refcounting schemeを用いて、rootエレメントが削除された時に全てのオブジェクトが削除されることが保証されています。(Implementationを指すポインタを持っているインターフェースクラスが無い場合のみに限ります) インターフェースクラス(Implという名前でないもの)は、dom/ディレクトリで規定されており、khtml自体では全く使うことがありません。 ほとんどの場合インターフェースとインプレメンテ‐ションの間には1対1対応があることが分かるでしょう。 C++においては、インターフェースクラスを用いてKHTMLの外からDOMツリー全体にアクセス出来るでしょう。 CSS エレメント<style>の中身(この場合は h1: { color: red; })はHTMLStyleElementImpl?オブジェクトになります。 後で説明するように、実際には"後程"というのは相対的なものです。 ''外部オブジェクトのロード" いくつかのタグ(<img>, <link>, <object>等)は、ロードしなければならない外部オブジェクトの参照を含んでいます。 ローダは準備が完了すると、このCachedObjectClient?に通知し、クライアントはデータを受信します。 表示する
ここまででDOMツリーを構築し、それに関連するスタイルシートと外部オブジェクトを準備しました。 CSSに完全対応したレンダリングエンジンを使うのです。 このリストを作ると、CSSStyleSelector?の"styleForElement?(DOM::ElementImpl? *)"関数を呼び出すことによってそれぞれのDOMエレメントからRenderStyle?オブジェクトを得られるようになります。 そのあと、レンダーツリーが構築されます。 上記の例では次のようなレンダリングツリーが構築されます。
RenderRoot*
\--> RenderBody*
|--> RenderFlow* (<H1>)
| \--> RenderText* ("some red text")
|--> RenderFlow* (anonymous box)
| \--> RenderText* ("more text")
\--> RenderFlow* (<P>)
|--> RenderText* ("a paragraph with an")
|--> RenderImage*
\--> RenderText* ("embedded image.")
RenderRoot?オブジェクトがlayout()を実行することによって、KHTMLViewによって与えられた有効な領域にレンダリングツリーが自らをレイアウトします。 ディレクトリ構造 ディレクトリ構造の簡単な説明をします。
例外処理 ライブラリサイズを抑えるため、C++の例外は dom/サブディレクトリのみ有効になっています。 最後に 完全で100%正しいとは言えませんが、HTML/XMLファイルを画面に表示するまでの道程を簡単に紹介しました。
以下では、現在web technolobyの分野で使われている専門用語について貴方が |