[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kfm-devel
Subject:    design changes in khtml (long mail...)
From:       Lars Knoll <knoll () mpi-hd ! mpg ! de>
Date:       1999-11-28 14:59:17
[Download RAW message or body]

Hi,

I thought a bit about the changes in the design of khtml, we will need to
support CSS(2). It got a bit long, since I wanted/had to explain, how
layouting/rendering in khtml is done at the moment, why I'd like to change
that, and what we would gain from changing. All of this is (of course) planned
for the time after crash.

I'd appreciate any comments on it.

Cheers,
Lars

This document gives a short description of how I think, we should
change our rendering code in khtml, to make it CSS(2) compatible, and
easy extendable.

Fot this I have to first describe a bit the current approach we use in khtml.

khtml makes use of the document object model (DOM) for storing the document
in a tree like structure. Imagine a some html like

<html>
<body>
<H1>some text</h1>
<p>a paragraph</p>
</body>
</html>


In the DOM, this would get parsed into a tree looking like:

HTMLDocumentElement
  \--> HTMLBodyElement
         |--> HTMLHeadingElement
         |      \--> Text
         \--> HTMLParagraphElement
                \--> Text

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:

HTMLDocumentElementImpl*
  \--> HTMLBodyElementImpl*
         |--> HTMLHeadingElementImpl*
         |      \--> TextImpl*
         \--> HTMLParagraphElementImpl*
                \--> TextImpl*

We use a refcounting scheme to assure, that all the objects get deleted, in 
case the root element get deleted (as long as there's no interface class 
holding a pointer to the Implementation).

Now, the point is, that up to now, all elements had functions to paint 
themselves (using a QPainter). Block level elements had the ability, to
layout themselves and they inline child element. Inline elements are elements
like <b>, <img> and also text. One does need to make this distinction, because
inline elements are rendered left to right into the box defined by the surrounding \
block level element, and we have to take care of aligned objects  (<img align=left \
...>), and (later on) bidirectional layouting.

So for every (well not every...) HTML element, there exists a corresponding 
class in the DOM, and code for rendering and layouting of it.

Now this model has proven to be very fast, and easy to handle, but 
unfortunately it isn't useable, if we want support for CSS2 (which we want :).

Let me explain why:

In CSS2, you can define properties for elements occuring in the HTML.
You can for example do a definition block like:

H1 { color: red; }

to get the contents of all <h1> elements rendered in red.

Now, if all the properties one can use were that simple, we could deal with
it the way we do now, even though it would be a bit a mess checking for all
properties in all child elements.

But on the other hand (I'm showing the most extreme example), one could do:

H1 { display: inline; }

to get the heading rendered inline, instead of defining a separate block, or

H1 { display: table; }

to have the H1 element behave like a table element.

Like this you can use the display, to redefine the display properties of
all elements. This is not particularily useful for HTML (one shouldn't even do
it, because it would make the html source unreadable.

But this can be very useful in the case of XML, since one can define how
certain XML elements should be displayed by simply using a small stylesheet.

Think of some XML code like:

<headline>This is a headline</headline>
<subtitle>A subtitle for the article</subtitle>
<par>This is where the main <bold>text</bold> of the article goes</par>

Now khtml at the moment would just ignore all the XML elements, and render 
the whole thing into one paragraph without any formatting.

With the help of a small stylesheet looking like:

headline { display: block; font-size: 20pt; }
subtitle { display: block; font-size: 14pt; }
par      { display: block; }
bold     { display: inline; font-weight: bold }

one could get this piece of XML rendered correctly.

There are more arguments, why the current approach is bad, and I don't want
to number them all.

So I propose a new approach to rendering html, which would

* give us the ability to render XML for free
* be much more flexible and extensible
* one only needs to define a default style sheet for html, to get
  html rendering correct
* easier to maintain in the end, since we separate DOM from rendering,
  and the nuumber of different elements we render will go down to a handful.
* should be as fast for rendering, a bit slower for parsing/layouting, 
  since we have the overhead for the Style Sheets (a thing we would get
  anyway, since we want some CSS support).
* It'll make the memory consumed by a DOM tree much smaller, so we could even
  think about holding documents in the parsed form in a memoery cache (which
  would make accessing them (by forward/back for example) extremely fast.

The approach works as follows:

* Every element in the DOM gets a pointer to a CSS element, which defines the
  rendering of the HTML element. 
* The CSS elements form a tree parallel to the DOM tree of the document.
* The DOM elements only define the document structure, change all
  attributes related to rendering into CSS properties, and pass them to the
  CSS element.
* We define a basic CSSObject, which provides all access/rendering/layouting
  functions needed as virtual functions (that's what we do for the DOM 
  elements at the moment).
* We derive from that objects like CSSInline, CSSBlock, CSSTable, etc...
  which provide rendering functionality for inline, block, etc... elements.
* Special care has to be taken with so called "replaced" elements (elements,
  which get their contents from outside the DOM/CSS model. <img>, <applet>
  and form elements are examples for that. For each of these elements, we need
  to provide a special CSS class doing the rendering and possible interaction
  (like submitting for forms).


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic