diff options
Diffstat (limited to 'khtml/DESIGN.html')
-rw-r--r-- | khtml/DESIGN.html | 346 |
1 files changed, 0 insertions, 346 deletions
diff --git a/khtml/DESIGN.html b/khtml/DESIGN.html deleted file mode 100644 index 16484d4f1..000000000 --- a/khtml/DESIGN.html +++ /dev/null @@ -1,346 +0,0 @@ -<html> -<head> -<title>Internal design of khtml</title> -<style> -dt { font-weight: bold; } -</style> -<body bgcolor=white> -<h1>Internal design of khtml</h1> - -<p> -This document tries to give a short overview about the internal design of the khtml -library. I've written this, because the lib has gotten quite big, and it is hard at first to find your -way in the source code. This doesn't mean that you'll understand khtml after reading this -document, but it'll hopefully make it easier for you to read the source code. -</p> -<p> -The library is build up out of several different parts. Basically, when you use the lib, you -create an instance of a KHTMLPart, and feed data to it. That's more or less all you need to -know if you want to use khtml for another application. If you want to start hacking khtml, -here's a sketch of the objects that will get constructed, when eg. running testkhtml with -a url argument. -</p> -<p> -In the following I'll assume that you're familiar with all the buzzwords used in current web -techology. In case you aren't here's a more or less complete list of references: -</p> -<blockquote> -<p> -<b>Document Object model (DOM):</b><br> -<a href="http://www.w3.org/DOM/">DOM Level1 and 2</a><br> -We support DOM Level2 except for the events model at the moment. -</p> -<p> -<b>HTML:</b><br> -<a href="http://www.w3.org/TR/html4/">HTML4 specs</a><br> -<a href="http://www.w3.org/TR/xhtml1/">xhtml specs</a><br> -We support almost all of HTML4 and xhtml. -</p> -<p> -<b>Cascading style sheets (CSS):</b><br> -<a href="http://www.w3.org/TR/REC-CSS2/">CSS2 specs</a><br> -We support almost all of CSS1, and most parts of CSS2. -</p> -<p> -<b>Javascript:</b><br> -<a href="http://msdn.microsoft.com/workshop/author/dhtml/reference/objects.asp">Microsoft javascript bindings</a><br> -<a href="http://docs.sun.com/source/816-6408-10/index.html">Netscape javascript reference</a><br> -Netscapes javascript bindings are outdated. We shouldn't follow them. Let's focus on getting the bindings -compatible to IE. -<a href="http://mozilla.org/docs/dom/domref/">Mozilla JS/DOM reference</a> -</p> -</blockquote> - -<p> -<a href="khtml_part.h">KHTMLPart</a> creates one instance of a -<a href="khtmlview.h">KHTMLView</a> (derived from TQScrollView), -the widget showing the whole thing. At the same time a DOM tree -is built up from the HTML or XML found in the specified file. -<p> -Let me describe this with an example. -<p> -khtml makes use of the document object model (DOM) for storing the document -in a tree like structure. Imagine some html like -<pre> -<html> - <head> - <style> - h1: { color: red; } - </style> - </head> - <body> - <H1> - some red text - </h1> - more text - <p> - a paragraph with an - <img src="foo.png"> - embedded image. - </p> - </body> -</html> -</pre> -In the following I'll show how this input will be processed step by step to generate the visible output -you will finally see on your screen. I'm describing the things as if they happen one after the other, -to make the principle more clear. In reality, to get visible output on the screen as soon as possible, -all these things (from tokenization to the build up and layouting of the rendering tree) happen -more or less in parallel. - -<h2>Tokenizer and parser</h2> -<p> -The first thing that happens when you start parsing a new document is that a -DocumentImpl* (for XML documents) or an HTMLDocumentImpl* object will get -created by the Part (in khtml_part.cpp::begin()). A Tokenizer* -object is created as soon as DocumentImpl::open() is called by the part, also -in begin() (can be either an XMLTokenizer or an HTMLTokenizer). -<p> -The XMLTokenizer uses the QXML classes in Qt to parse the document, and it's SAX interface -to parse the stuff into khtmls DOM. -<p> -For HTML, the tokenizer is located in khtmltokenizer.cpp. The tokenizer uses the contents -of a HTML-file as input and breaks this contents up in a linked list of -tokens. The tokenizer recognizes HTML-entities and HTML-tags. Text between -begin- and end-tags is handled distinctly for several tags. The distinctions -are in the way how spaces, linefeeds, HTML-entities and other tags are -handled. -<p> -The tokenizer is completely state-driven on a character by character basis. -All text passed over to the tokenizer is directly tokenized. A complete -HTML-file can be passed to the tokenizer as a whole, character by character -(not very efficient) or in blocks of any (variable) size. -<p> -The HTMLTokenizer creates an HTMLParser which -interprets the stream of tokens provided by the tokenizer -and constructs the tree of Nodes representing the document according -to the Document Object Model. -<p> - -<h2>The DOM in khtml</h2> -<p> -Parsing the document given above gives the following DOM tree: - -<pre> -HTMLDocumentElement - |--> HTMLHeadElement - | \--> HTMLStyleElement - | \--> CSSStyleSheet - \--> HTMLBodyElement - |--> HTMLHeadingElement - | \--> Text - |--> Text - \--> HTMLParagraphElement - |--> Text - |--> HTMLImageElement - \--> Text -</pre> -<p> -Actually, the classes mentioned above are the interfaces for accessing the -DOM. The actual data is stored in *Impl classes, providing the implementation -for all of the above mentioned elements. So internally we have a tree -looking like: -<pre> -HTMLDocumentElementImpl* - |--> HTMLHeadElementImpl* - | \--> HTMLStyleElementImpl* - | \--> CSSStyleSheetImpl* - \--> HTMLBodyElementImpl* - |--> HTMLHeadingElementImpl* - | \--> TextImpl* - |--> TextImpl* - \--> HTMLParagraphElementImpl* - |--> TextImpl* - |--> HTMLImageElementImpl* - \--> TextImpl* -</pre> -<p> -We use a refcounting scheme to assure that all the objects get deleted, in -case the root element gets deleted (as long as there's no interface class -holding a pointer to the Implementation). -<p> -The interface classes (the ones without the Impl) are defined in the <code>dom/</code> -subdirectory, and are not used by khtml itself at all. The only place they are used are in the -javascript bindings, which uses them to access the DOM tree. The big advantage of having this -separation between interface classes and imlementation classes, is that we can have several -interface objects pointing to the same implementation. This implements the requirement of -explicit sharing of the DOM specs. -<p> -Another advantage is, that (as the implementation classes are not exported) it gives us a lot -more freedom to make changes in the implementation without breaking binary compatibility. -<p> -You will find almost a one to one correspondence between the interface classes and the implementation -classes. In the implementation classes we have added a few more intermediate classes, that can -not be seen from the outside for various reasons (make implementation of shared features easier -or to reduce memory consumption). -<p> -In C++, you can access the whole DOM tree from outside KHTML by using the interface classes. -For a description see the <a href="http://developer.kde.org/documentation/library/kdeqt/trinityarch/khtml/index.html">introduction to khtml</a> on <a href="http://developer.kde.org/">developer.kde.org</a>. - -One thing that has been omitted in the discussion above is the style sheet defined inside the -<code><style></code> element (as an example of a style sheet) and the image element -(as an example of an external resource that needs to be loaded). This will be done in the following -two sections. - -<h2>CSS</h2> The contents of the <code><style></code> element (in this -case the <code>h1 { color: red; }</code> rule) will get passed to the -<a href="html/html_headimpl.h">HTMLStyleElementImpl object</a>. This object creates an -<a href="css/cssstylesheetimpl.h">CSSStyleSheetImpl object</a> and passes the -data to it. The <a href="css/cssparser.h">CSS parser</a> will take -the data, and parse it into a DOM structure for CSS (similar to the one for -HTML, see also the DOM level 2 specs). This will be later on used to define the -look of the HTML elements in the DOM tree. -<p> -Actually "later on" is relative, as we will see later, that this happens partly in parallel to -the build up of the DOM tree. - -<h2>Loading external objects</h2> -<p> -Some HTML elements (as <code><img>, <link>, <object>, etc.</code>) contain -references to external objects, that have to be loaded. This is done by the -Loader and related classes (misc/loader.*). Objects that might need to load external objects -inherit from <a href="misc/loader_client.h">CachedObjectClient</a>, and can ask -the <a href="misc/loader.h">loader</a> (that also acts as a memory cache) to -download the object they need for them from the web. -<p> -Once the <a href="misc/loader.h">loader</a> has the requested object ready, it will notify the -<a href="misc/loader_client.h">CachedObjectClient</a> of this, and the client can -then process the received data. - -<h2>Making it visible</h2> - -Now once we have the DOM tree, and the associated style sheets and external objects, how -do we get the stuff actually displayed on the screen? -<p> -For this we have a rendering engine, that is completely based on CSS. The first -thing that is done is to collect all style sheets that apply to the document -and create a nice list of style rules that need to be applied to the -elements. This is done in the <a href="css/cssstyleselector.h">CSSStyleSelector</a> class. -It takes the <a href="css/html4.css">default HTML style sheet</a> (defined in css/html4.css), -an optional user defined style sheet, and all style sheets from the document, -and combines them to a nice list of parsed style rules (optimised for fast -lookup). The exact rules of how these style sheets should get applied to HTML -or XML documents can be found in the CSS2 specs. -<p> -Once we have this list, we can get a <a -href="rendering/render_style.h">RenderStyle object</a> -for every DOM element from the <a -href="css/cssstyleselector.h">CSSStyleSelector</a> by calling -"styleForElement(DOM::ElementImpl *)". -The style object describes in a compact form all the -<a href="css/css_properties.in">CSS properties</a> -that should get applied to the Node. -<p> -After that, a rendering tree gets built up. Using the style object, the -<a href="xml/dom_nodeimpl.h">DOM Node</a> creates an appropriate render object -(all these are defined in the rendering subdirectory) and adds it to the -rendering tree. This will give another tree like structure, that resembles in -it's general structure the DOM tree, but might have some significant -differences too. First of all, so called - <a href="http://www.w3.org/TR/REC-CSS2/visuren.html#anonymous-block-level">anonymous boxes</a> - (see - <a href="http://www.w3.org/TR/REC-CSS2/">CSS specs</a>) that -have no DOM counterpart might get inserted into the rendering tree to satisfy -DOM requirements. Second, the display property of the style affects which type -of rendering object is chosen to represent the current DOM object. - -<p> -In the above example we would get the following rendering tree: -<pre> -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.") -</pre> - -<p> -A call to of <a href="rendering/render_root.cpp">layout()</a> on the -<a href="rendering/render_root.h">RenderRoot </a> (the root of the rendering tree) -object causes the rendering tree to layout itself into the available space -(width) given by the the KHTMLView. After that, the drawContents() method of -KHTMLView can call RenderRoot->print() with appropriate parameters to actually -paint the document. This is not 100% correct, when parsing incrementally, but -is exactly what happens when you resize the document. - - -As you can see, the conversion to the rendering tree removed the head part of -the HTML code, and inserted an anonymous render object around the string "more -text". For an explanation why this is done, see the CSS specs. -<p> - -<h2>Directory structure</h2> - -A short explanation of the subdirectories in khtml. -<dl> -<dt><a href="css/">css:</a> -<dd>Contains all the stuff relevant to the CSS part of DOM Level2 (implementation classes only), -the <a href="css/cssparser.h">CSS parser</a>, and the stuff to create -RenderStyle object out of Nodes and the CSS style sheets. -<dt><a href="dom/">dom: </a> -<dd>Contains the external DOM API (the DOM interface classes) for all of the DOM -<dt><a href="ecma/">ecma:</a> -<dd>The javascript bindings to the DOM and khtml. -<dt><a href="html/">html:</a> -<dd>The html subpart of the DOM (implementation only), the HTML tokenizer and parser and a class -that defines the DTD to use for HTML (used mainly in the parser). -<dt><a href="java/">java:</a> -<dd>Java related stuff. -<dt><a href="misc/">misc:</a> -<dd>Some misc stuff needed in khtml. Contains the image loader, some misc definitions and the -decoder class that converts the incoming stream to unicode. -<dt><a href="rendering">rendering:</a> -<dd>Everything thats related to bringing a DOM tree with CSS declarations to the screen. Contains -the definition of the objects used in the rendering tree, the layouting code, and the RenderStyle objects. -<dt><a href="xml/">xml:</a> -<dd>The XML part of the DOM implementation, the xml tokenizer. -</dl> - -<h2>Exception handling</h2> -To save on library size, C++-exceptions are only enabled in the dom/ subdirectory, -since exceptions are mandated by the DOM API. In the rest of KHTML's code, -we pass an error flag (usually called "exceptionCode"), and the class that -is part of dom/* checks for this flag and throws the exception. - -<h2>Final words...</h2> -<p> -All the above is to give you a quick introduction into the way khtml brings an HTML/XML file to the screen. -It is by no way complete or even 100% correct. I left out many problems, I will perhaps add either on request -or when I find some time to do so. Let me name some of the missing things: -<ul> -<li>The decoder to convert the incoming stream to Unicode -<li>interaction with konqueror/applications -<li>javascript -<li>dynamic reflow and how to use the DOM to manipulate khtmls visual output -<li>mouse/event handling -<li>real interactions when parsing incrementally -<li>java -</ul> - -Still I hope that this short introduction will make it easier for you to get a first hold of khtml and the way it works. -<p> -Now before I finish let me add a small <b>warning</b> and <b>advice</b> to all of you who plan hacking khtml themselves: -<p> -khtml is by now a quite big library and it takes some time to understand how it works. Don't let yourself get frustrated -if you don't immediately understand how it works. On the other hand, it is by now one of the libraries that -get used a lot, that probably has the biggest number of remaining bugs (even though it's sometimes hard to -know if some behavior is really a bug). -<blockquote> -Some parts of it's code are however <b>extremely touchy</b> (especially the layouting algorithms), -and making changes there (that might fix a bug on one web page) might introduce severe bugs. -All the people developing khtml have already spend huge amounts of time searching for such bugs, -that only showed up on some web pages, and thus were found only a week after the change that -introduced the bug was made. This can be very frustrating for us, and we'd appreciate if people -that are not completely familiar with khtml post changes touching these critical regions to kfm-devel -for review before applying them. -</blockquote> - -<div style="margin-top: 2em; font-size: large;"> -And now have fun hacking khtml. -<div style="margin-left: 10em; margin-bottom: 1em;">Lars</div> -</div> -</body> -</html> |