WebCore Rendering I --- the basic

原文:http://www.webkit.org/blog/114/webcore-rendering-i-the-basics/

一下是翻译版本,后面还有对照版本。

 这是一系列文章中的第一篇,目的是帮助那些对WebCore rendering有兴趣的人们。 当完成这些文章,你可以在博客和WebKit网站的document部分看到这些文章。

The DOM Tree

一个网页被分析成包含很多node的一棵树,叫做文档对象模型(Document Object Model 简称DOM)。树上所有节点的基类是class Node,定义在下面的文件中:

Node.h

Nodes被分为很多种类,节点的种类与rendering的代码有关,这些种类包括:

  • 文档 - 树的根节点总是文档节点,总共有3种文档类:Document、HTMLDocument和SVGDocument。 Document可以应用于除SVG document以往的所有XML文档, HTMLDocument继承与Document,仅应用于HTML文档。SVGDocument也继承与Document应用于SVG document。

    Document.h
    HTMLDocument.h

  •  元素(Elements) - 所有出现在HTML或XML中的tags都是元素(element),从rendering角度来说,一个元素(element)就是一个具有tag名称的节点,他可以被转型为某个特定的子类,能够提供render需要的数据 

    Element.h

  • 文本(Text) -  出现在元素之间的raw text被指定为文本节点,文本节点保存raw text,render tree能够从中得到字符数据。

    Text.h

The Render Tree

rendering过程的一个核心就是render tree。 render tree也是一个由对象(objects)构成的树,这一点与DOM树非常相似,其中每一个对象与文档(document)、元素(element)、文本(text)节点对应。render tree中还包含一些额外的对象不能与DOM 节点对应。

render tree中所有节点的基类都是RenderObject,定义在下面的文件中。

RenderObject.h

一个DOM节点的RenderObject能够通过调用该节点的renderer()方法来得到。

RenderObject* renderer() const

下面这些render tree 遍历当中是最常用的方法:

RenderObject* firstChild() const;
RenderObject* lastChild() const;
RenderObject* previousSibling() const;
RenderObject* nextSibling() const;


 下面的例子演示通过一个循环遍历所有直接儿子的过程,这是render tree遍历中最常用的代码:

for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
    ...
}


 

创建 Render Tree

renderer被创建是通过DOM调用attach方法。当一个文档被解析,DOM节点被添加到DOM树中,节点的attach方法被调用来创建renderer。

void attach()

attach方法为DOM节点计算样式信息(style information)。如果一个元素的CSS属性的display被设置为none或者一个节点是被设置了display: none 节点的子孙,那么renderer将不会被创建。节点的子类和CSS显示属性值被联合起来决定创建什么样类型的renderer。

销毁 Render Tree

当DOM节点被从文档中删除或者文档被销毁(例如:tab/window被关闭),renderer将被销毁。detach方法将被调用用于断开及销毁renderers。

void detach()

销毁过程是一个自底向上的递归过程,子孙节点总是在其父节点销毁前进行销毁。

访问样式信息

在attachement的过程中,DOM为元素想CSS查询其样式信息,由此产生的信息存储在一个叫做RenderStyle的对象中。

RenderStyle.h

每一个WebKit支持的CSS属性都能够通过一个对象来进行查询,RenderStyles是引用计数对象(reference counted objects)。一旦DOM节点创建了一个renderer,他通过调用setStyle方法来将样式信息设置到这个randerer上。

void setStyle(RenderStyle*)

renderer将添加一个引用指向这个样式,并将保持直到设置一个新的样式或者被销毁。

RenderStyle* style() const

CSS Box 模型

RenderObject类的一个主力子类就是RenderBox,这个子类表示那些遵循CSS Box模型的对象。其中包括所有具有border、padding、margin、width、hight等属性的对象。现在一些不遵循CSS box模型的对象(如:SVG对象)也继承自RenderBox。这实际上是个错误,未来再render tree的重构过程中将被纠正。 

这个从CSS2.1 spec中来的流程图演示了CSS box部分的内容,下面这些方法可以被调用去获得border/margin/padding widths。因为实际计算的RenderObject将会有很大的变化(特别是对于表格,表格能够覆盖cell padding并且可以使cell间具有collapsed borders),所以RenderStyle不应该被调用,除非目的是查看原始的演示信息。

 

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;


width()和height()方法给出包含了border的box的宽度和高度

int width() const;
int height() const;


client box不包括border和scrollbar,但包含padding

int clientLeft() const { return borderLeft(); }
int clientTop() const { return borderTop(); }
int clientWidth() const;
int clientHeight() const;


context box是指CSS box中去掉border和padding

IntRect contentBox() const;
int contentWidth() const { return clientWidth() - paddingLeft() - paddingRight(); }
int contentHeight() const { return clientHeight() - paddingTop() - paddingBottom(); }


当一个box具有水平和垂直滚动条时,他被放置在border和padding之间。scrollbar size包括client width 和client height。但scrollbar 不是content box的部分。scrollable area和当前scroll位置的大小都可以通过RenderObject得到,我将在一个单独的部分介绍这些。

int scrollLeft() const;
int scrollTop() const;
int scrollWidth() const;
int scrollHeight() const;

Boxes还具有x和y位置。这些位置是相对于他们的祖先来说的,这个规则有很多的例外,这是render tree中最让人困惑的一部分。

int xPos() const;
int yPos() const;

 

----------------------------------------------------------------对照版-----------------------------------------------------

This is the first of a series of posts designed to help people interested in hacking on WebCore’s rendering system. I’ll be posting these articles as I finish them on this blog, and they will also be available in the documentation section of the Web site.

这是一系列文章中的第一篇,目的是帮助那些对WebCore rendering有兴趣的人们。 当完成这些文章,你可以在博客和WebKit网站的document部分看到这些文章。

The DOM Tree

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 isNode.

一个网页被分析成包含很多node的一棵树,叫做文档对象模型(Document Object Model 简称DOM)。树上所有节点的基类是class Node,定义在下面的文件中:

Node.h

Nodes break down into several categories. The node types that are relevant to the rendering code are:

Nodes被分为很多种类,节点的种类与rendering的代码有关,这些种类包括:

  • Document – The root of the tree is always the document. There are three document classes,Document,HTMLDocument andSVGDocument. The first is used for all XML documents other than SVG documents. The second applies only to HTML documents and inherits fromDocument.
    The third applies to SVG documents and also inherits from Document.

    文档 - 树的根节点总是文档节点,总共有3种文档类:Document、HTMLDocument和SVGDocument。 Document可以应用于除SVG document以往的所有XML文档, HTMLDocument继承与Document,仅应用于HTML文档。SVGDocument也继承与Document应用于SVG document。

    Document.h
    HTMLDocument.h

  • Elements – All of the tags that occur in HTML or XML source turn into elements. From a rendering perspective, an element is a node with a tag name that can be used to cast to a specific subclass that can be queried for data that the renderer needs.

     元素(Elements) - 所有出现在HTML或XML中的tags都是元素(element),从rendering角度来说,一个元素(element)就是一个具有tag名称的节点,他可以被转型为某个特定的子类,能够提供render需要的数据 

    Element.h

  • Text – Raw text that occurs in between elements gets turned into text nodes. Text nodes store this raw text, and the render tree can query the node for its character data. .

    文本(Text) -  出现在元素之间的raw text被指定为文本节点,文本节点保存raw text,render tree能够从中得到字符数据。

    Text.h

The Render Tree

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.

rendering过程的一个核心就是render tree。 render tree也是一个由对象(objects)构成的树,这一点与DOM树非常相似,其中每一个对象与文档(document)、元素(element)、文本(text)节点对应。render tree中还包含一些额外的对象不能与DOM 节点对应。

The base class of all render tree nodes is RenderObject.

render tree中所有节点的基类都是RenderObject,定义在下面的文件中。

RenderObject.h

The RenderObject for a DOM node can be obtained using the renderer() method onNode.

一个DOM节点的RenderObject能够通过调用该节点的renderer()方法来得到。

RenderObject* renderer() const

The following methods are most commonly used to walk the render tree.

下面这些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.

下面的例子演示通过一个循环遍历所有直接儿子的过程,这是render tree遍历中最常用的代码:

for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
    ...
}
Creating the Render Tree
创建 Render Tree

Renderers are created through a process on the DOM called attachment. As a document is parsed and DOM nodes are added, a method calledattach gets called on the DOM nodes to create the renderers.

renderer被创建是通过DOM调用attach方法。当一个文档被解析,DOM节点被添加到DOM树中,节点的attach方法被调用来创建renderer。

void attach()

The attach method computes style information for the DOM node. If the display CSS property for the element is set tonone or if the node is a descendant of an element withdisplay: 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.

attach方法为DOM节点计算样式信息(style information)。如果一个元素的CSS属性的display被设置为none或者一个节点是被设置了display: none 节点的子孙,那么renderer将不会被创建。节点的子类和CSS显示属性值被联合起来决定创建什么样类型的renderer。

Destroying the Render Tree
销毁 Render Tree

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 calleddetach gets called on the DOM nodes to disconnect and destroy the renderers.

当DOM节点被从文档中删除或者文档被销毁(例如:tab/window被关闭),renderer将被销毁。detach方法将被调用用于断开及销毁renderers。

void detach()

Detachment is a bottom up recursive operation. Descendant nodes will always have their renderers destroyed before a parent destroys its renderer.

销毁过程是一个自底向上的递归过程,子孙节点总是在其父节点销毁前进行销毁。

Accessing Style Information
访问样式信息

During attachment the DOM queries CSS to obtain style information for an element. The resultant information is stored in an object called aRenderStyle.

在attachement的过程中,DOM为元素想CSS查询其样式信息,由此产生的信息存储在一个叫做RenderStyle的对象中。

RenderStyle.h

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 thesetStyle method on the renderer.

每一个WebKit支持的CSS属性都能够通过一个对象来进行查询,RenderStyles是引用计数对象(reference counted objects)。一旦DOM节点创建了一个renderer,他通过调用setStyle方法来将样式信息设置到这个randerer上。

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 thestyle() method.

renderer将添加一个引用指向这个样式,并将保持直到设置一个新的样式或者被销毁。

RenderStyle* style() const

The CSS Box Model
CSS Box 模型

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 fromRenderBox. This is actually a mistake that will be fixed in the future through refactoring of the render tree.

RenderObject类的一个主力子类就是RenderBox,这个子类表示那些遵循CSS Box模型的对象。其中包括所有具有border、padding、margin、width、hight等属性的对象。现在一些不遵循CSS box模型的对象(如:SVG对象)也继承自RenderBox。这实际上是个错误,未来再render tree的重构过程中将被纠正。 

This diagram 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. TheRenderStyle should not be used unless the intent is to look at the original raw style information, since what is actually computed for theRenderObject could be very different (especially for tables, which can override cell padding and have collapsed borders between cells).

这个从CSS2.1 spec中来的流程图演示了CSS box部分的内容,下面这些方法可以被调用去获得border/margin/padding widths。因为实际计算的RenderObject将会有很大的变化(特别是对于表格,表格能够覆盖cell padding并且可以使cell间具有collapsed borders),所以RenderStyle不应该被调用,除非目的是查看原始的演示信息。

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.

width()和height()方法给出包含了border的box的宽度和高度

int width() const;
int height() const;

The client box is the area of the box excluding borders and scrollbars. Padding is included.

client box不包括border和scrollbar,但包含padding

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.

context box是指CSS box中去掉border和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.

当一个box具有水平和垂直滚动条时,他被放置在border和padding之间。scrollbar size包括client width 和client height。但scrollbar 不是content box的部分。scrollable area和当前scroll位置的大小都可以通过RenderObject得到,我将在一个单独的部分介绍这些。

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.

Boxes还具有x和y位置。这些位置是相对于他们的祖先来说的,这个规则有很多的例外,这是render tree中最让人困惑的一部分。

int xPos() const;
int yPos() const;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值