个人主页https://xugaoxiang.com,微信公众号: Dev_Club 或者搜索 程序员Club
全部博文(229)
分类: LINUX
2011-02-24 22:33:23
A Web page is parsed into a tree of nodes called the Document Object
Model (DOM for short). The base class for all nodes in the tree is Node
.
Nodes break down into several categories. The node types that are relevant to the rendering code are:
Document
, HTMLDocument
and SVGDocument
.
The first is used for all XML documents other than SVG documents. The
second applies only to HTML documents and inherits from Document
.Document
.
At the heart of rendering is the render tree. The render tree is very similar to the DOM in that it is a tree of objects, where each object can correspond to the document, elements or text nodes. The render tree can also contain additional objects that have no corresponding DOM node.
The base class of all render tree nodes is RenderObject
.
The RenderObject
for a DOM node can be obtained using the renderer()
method on Node
.
RenderObject* renderer() const
The following methods are most commonly used to walk the render tree.
RenderObject* firstChild() const;
RenderObject* lastChild() const;
RenderObject* previousSibling() const;
RenderObject* nextSibling() const;
Here is an example of a loop that walks a renderer’s immediate children. This is the most common walk that occurs in the render tree code.
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
...
}
Renderers are created through a process on the DOM called attachment. As a document is parsed and DOM nodes are added, a method called attach gets called on the DOM nodes to create the renderers.
void attach()
The attach method computes style information for the DOM node. If the display CSS property for the element is set to none or if the node is a descendant of an element with display: none set, then no renderer will be created. The subclass of the node and the CSS display property value are used together to determine what kind of renderer to make for the node.
Attach is a top down recursive operation. A parent node will always have its renderer created before any of its descendants will have their renderers created.
Renderers are destroyed when DOM nodes are removed from the document or when the document gets torn down (e.g., because the tab/window it was in got closed). A method called detach gets called on the DOM nodes to disconnect and destroy the renderers.
void detach()
Detachment is a bottom up recursive operation. Descendant nodes will always have their renderers destroyed before a parent destroys its renderer.
During attachment the DOM queries CSS to obtain style information for an element. The resultant information is stored in an object called a RenderStyle.
Every single CSS property that WebKit supports can be queried via this object. RenderStyles are reference counted objects. If a DOM node creates a renderer, then it connects the style information to that renderer using the setStyle method on the renderer.
void setStyle(RenderStyle*)
The renderer adds a reference to the style that it will maintain until it either gets a new style or gets destroyed.
The RenderStyle
can be accessed from a RenderObject
using the style()
method.
RenderStyle* style() const
One of the principal workhorse subclasses of RenderObject
is RenderBox
.
This subclass represents objects that obey the CSS box model. These
include any objects that have borders, padding, margins, width and
height. Right now some objects that do not follow the CSS box model
(e.g., SVG objects) still subclass from RenderBox
. This is actually a mistake that will be fixed in the future through refactoring of the render tree.
from the CSS2.1 spec illustrates the parts of a CSS box. The following
methods can be used to obtain the border/margin/padding widths. The RenderStyle
should not be used unless the intent is to look at the original raw style information, since what is actually computed for the RenderObject
could be very different (especially for tables, which can override cell padding and have collapsed borders between cells).
int marginTop() const;
int marginBottom() const;
int marginLeft() const;
int marginRight() const;
int paddingTop() const;
int paddingBottom() const;
int paddingLeft() const;
int paddingRight() const;
int borderTop() const;
int borderBottom() const;
int borderLeft() const;
int borderRight() const;
The width()
and height()
methods give the width and height of the box including its borders.
int width() const;
int height() const;
The client box is the area of the box excluding borders and scrollbars. Padding is included.
int clientLeft() const { return borderLeft(); }
int clientTop() const { return borderTop(); }
int clientWidth() const;
int clientHeight() const;
The term content box is used to describe the area of the CSS box that excludes the borders and padding.
IntRect contentBox() const;
int contentWidth() const { return clientWidth() - paddingLeft() - paddingRight(); }
int contentHeight() const { return clientHeight() - paddingTop() - paddingBottom(); }
When a box has a horizontal or vertical scrollbar, it is placed in
between the border and the padding. A scrollbar’s size is included in
the client width and client height. Scrollbars are not part of the
content box. The size of the scrollable area and the current scroll
position can both be obtained from the RenderObject
. I will cover this in more detail in a separate section on scrolling.
int scrollLeft() const;
int scrollTop() const;
int scrollWidth() const;
int scrollHeight() const;
Boxes also have x and y positions. These positions are relative to the ancestor that is responsible for deciding where this box should be placed. There are numerous exceptions to this rule, however, and this is one of the most confusing areas of the render tree.
int xPos() const;
int yPos() const;
From:
http://www.webkit.org/blog/114/webcore-rendering-i-the-basics/