blink渲染知识三- blocking and inlines

RenderBlock表明一个物体代表一个block,他内部的对象要被竖着排列。他内部的对象要么都是RenderBox,要么都是RenderLine.

RenderLine表明一个物体,这个物体从其外部来看,是要被放置到一个line内部的。他内部的物体必须全都是RenderLine.

为了满足上述原则,webkit会手动加入一些renderobject

css标准里讲,一个Objectin-flowchildren说的是一个object的除了fixedabsoluted定位孩子之外的普通孩子。

一个对象可以说成是inlineblock, 意思是这个对象内部的孩子需要竖着排列,但是这个对象自己从外部来看要放置到一个line里。

Posted by DaveHyatt onThursday, August 9th, 2007 at 2:59 pm

In the previous entry I talked about the basic structure of a CSSbox. In this article I’m going to talk about subclasses ofRenderBox and about the concepts of block andinline.

A block flow is a box designed either to contain lines(e.g., a paragraph) or to contain other blocks that it stacksvertically. Example block flow elements in HTML are p and div.

An inline flow is an object that is designed to be part ofa line. Example inline flow elements in HTML are a, b,i and span.

In WebCore, there are three renderer classes that cover block andinline flows. RenderBlock, RenderInline andtheir common superclass RenderFlow.

RenderFlow.h
RenderBlock.h
RenderInline.h

An inline flow can be changed to a block flow (and vice versa)using the CSS display property.

div { display: inline }
span { display: block }

In addition to block and inline flows, there is another kind ofelement that can act as a block or inline: the replaced element. Areplaced element is an element whose rendering is unspecifiedby CSS. How the contents of the object render is left up to theelement itself. Examples of replaced elements are images, formcontrols, iframes, plugins and applets.

A replaced element can also be either block-level or inline-level.When a replaced element acts as a block, it will get stackedvertically as though it represents its own paragraph. When a replacedelement acts as an inline, it will be part of a line inside aparagraph. Replaced elements are inline by default.

Form controls are actually a strange special case. They are stillreplaced elements, but because they are implemented by the engine,controls actually ultimately subclass from RenderBlock.As a result, the concept of being replaced can’t really be confinedto a single common subclass, and is therefore represented as a bit onRenderObject instead. The isReplaced methodcan be used to ask if an object is a replaced element.

bool isReplaced() const

Images, plugins, frames and applets all inherit from a commonsubclass that implements replaced element behavior. This class isRenderReplaced.

RenderReplaced.h

TheInline Block

One of the most confusingly named objects in CSS is theinline-block. Inline blocks are block flows that are designedto sit on a line. In effect they are like inline replaced elements onthe outside, but on the inside they are block flows. The displayproperty in CSS can be used to create inline blocks. Inline blockswill report true if asked if they are replaced.

div { display: inline-block }
Tables

Tables in HTML are block-level by default. However they can alsobe made into inlines using the CSS display property with a value ofinline-table.

table { display: inline-table }

Again, from the outside an inline-table is like an inline replacedelement (and will return true from isReplaced), but on the inside theobject is still just a table.

In WebCore the RenderTable class represents a table.It inherits from RenderBlock for reasons that will be covered in thepositioning section later.

RenderTable.h

Text

Raw text is represented using the RenderText class.Text is always considered inline by WebCore, since it is alwaysplaced on lines.

RenderText.h

GettingBlock and Inline Information

The most basic method for obtaining block vs. inline status is theisInline function. This method asks if an object isdesigned to be part of a line. It does not care what the interior ofthe element is (e.g., text, image, an inline flow, an inline-block oran inline-table).

bool isInline() const

One of the common mistakes people make when working with therender tree is assuming that isInline means an object isalways an inline flow, text or an inline replaced element. Howeverbecause of inline-blocks and inline-tables, this method can returntrue even for these objects.

To ask if an object is actually a block or inline flow, thefollowing methods should be used.

bool isInlineFlow() const
bool isBlockFlow() const

These methods are essentially asking questions about the interiorof the object. An inline-block for example is still a block flow andnot an inline flow. It is inline on the outside, but on the inside itis a block flow.

The exact class type can be queried for blocks and inlines usingthe following methods.

bool isRenderBlock() const
bool isRenderInline() const

The isRenderBlock method is useful in the context ofpositioning, since both block flows and tables act as positionedobject containers.

To ask if an object is specifically an inline block or inlinetable, the isInlineBlockOrInlineTable method can beused.

bool isInlineBlockOrInlineTable() const

Childrenof Block Flows

Block flows have a simple invariant regarding their children thatthe render tree always obeys. That rule can be summarized as follows:

All in-flow children of a block flow must be blocks, or allin-flow children of a block flow must be inlines.

In other words, once you exclude floating and positioned elements,all of the children of a block flow in the render tree must returntrue from isInline or they must all return false fromisInline. The render tree will change its structure asneeded to preserve this invariant.

The childrenInline method is used to ask whether thechildren of a block flow are inlines or blocks.

bool childrenInline() const

Childrenof Inline Flows

Children of inline flows have an even simpler invariant that mustbe maintained.

All in-flow children of an inline flow must be inlines.

AnonymousBlocks

In order to preserve the block flow child invariant (only inlinechildren or only block children), the render tree will constructobjects called anonymous blocks. Consider the followingexample:

<div>
Some text
<div>
Some more text
</div>
</div>

In the above example, the outer div has two children: some textand another div. The first child is an inline, but the second childis a block. Because this combination of children violates theall-inline or all-block child rule, the render tree will construct ananonymous block flow to wrap the text. The render tree thereforebecomes:

<div>
<anonymous block>
Some text
</anonymous block>
<div>
Some more text
</div>
</div>

The isAnonymousBlock method can be used to ask if arenderer is an anonymous block flow.

bool isAnonymousBlock() const

Whenever a block flow has inline children and a block objectsuddenly tries to insert itself as a child, anonymous blocks will becreated as needed to wrap all of the inlines. Contiguous inlines willshare a single common anonymous block, so the number of anonymousblocks can be kept to a minimum. The makeChildrenNonInlinemethod in RenderBlock is the function that performs thisadjustment.

void makeChildrenNonInline(RenderObject *insertionPoint)

Blocksinside Inline Flows

One of the nastiest constructs you will see in HTML is when ablock is placed inside an inline flow. Here is an example:

<i>Italic only <b>italic and bold
<div>
Wow, a block!
</div>
<div>
Wow, another block!
</div>
More italic and bold text</b>
More italic text</i>

The two divs violate the invariant that all of the children of thebold element must be inlines. The render tree has to perform a rathercomplicated series of steps in order to fix up the tree. Threeanonymous blocks are constructed. The first block holds all of theinlines that come before the divs. The second anonymous block holdsthe divs. The third anonymous block holds all of the inlines thatcome after the divs.

<anonymous pre block>
<i>Italic only <b>italic and bold</b></i>
</anonymous pre block>
<anonymous middle block>
<div>
Wow, a block!
</div>
<div>
Wow, another block!
</div>
</anonymous middle block>
<anonymous post block>
<i><b>More italic and bold text</b> More
italic text</i>
</anonymous post block>

Notice that the bold and italic renderers had to split into tworender objects, since they are in both the anonymous pre block andthe anonymous post block. In the case of the bold DOM element, itschildren are in the pre block, but then continue into the middleblock and then finally continue into the post block. The render treeconnects these objects via a continuation chain.

RenderFlow* continuation() const
bool isInlineContinuation() const

The first bold renderer in the pre block is the one that can beobtained from the b DOM element using the element’srenderer() method. This renderer has as itscontinuation() the middle anonymous block. The middleanonymous block has as its continuation() the secondbold renderer. In this way code that needs to examine the renderersthat represent the children of the DOM element can still do sorelatively easily.

In the above example the i DOM element also split.Its children are all in the pre and post blocks, and therefore onlyone connection is needed. The italic renderer in the pre block setsits continuation() to the italic renderer in the postblock.

The function that performs the recursive splitting of inline flowsand that creates the continuation chain connections is calledsplitFlow and is in RenderInline.cpp.

You can follow any responses to this entry through the RSS2.0 feed. Both comments and pings are currently closed.







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值