WebCore rendering II-blocks and inlines

Source: Internet
Author: User
WebCore rendering II-blocks and inlines

PostedDave HyattOn Thursday, August 9th, 2007

In the previous entry I talked about the basic structure of a CSS box. In this article I'm going to talk about subclassesRenderBoxAnd about the conceptsBlockAndInline.

ABlock FlowIs a box designed either to contain lines (e.g., a paragraph) or to contain other blocks that it stacks vertically. example block flow elements in HTML arePAndDiv.

AnInline FlowIs an object that is designed to be part of a line. Example inline flow elements in HTML areA,B,IAndSpan.

In WebCore, there are three Renderer classes that cover block and inline flows.RenderBlock,RenderInlineAnd their common superclassRenderFlow.

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 of element that can act as a block or Inline: The replaced element.ReplacedElement is an element whose rendering is unspecified by CSS. how the contents of the object render is left up to the element itself. examples of replaced elements are images, Form Controls, 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 stacked vertically as though it represents its own paragraph. when a replaced element acts as an inline, it will be part of a line inside a paragraph. replaced elements are inline by default.

Form Controls are actually a strange special case. They are still replaced elements, but because they are implemented by the engine, controls actually ultimately subclass fromRenderBlock. As a result, the concept of being replaced can't really be confined to a single common subclass, and is therefore represented as a bit onRenderObjectInstead.isReplacedMethod can be used to ask if an object is a replaced element.

bool isReplaced() const

Images, plugins, frames and applets all inherit from a common subclass that implements replaced Element Behavior. This class isRenderReplaced.

RenderReplaced.h

The Inline Block

One of the most confusingly named objects in CSS isInline-block. Inline blocks are block flows that are designed to sit on a line. in effect they are like inline replaced elements on the outside, but on the inside they are block flows. the display property in CSS can be used to create inline blocks. inline blocks will report true if asked if they are replaced.

div { display: inline-block }
Tables

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

table { display: inline-table }

Again, from the outside an inline-table is like an inline replaced element (and will return true from isreplaced), but on the inside the object is still just a table.

In WebCoreRenderTableClass represents a table. It inherits from renderblock for reasons that will be covered in the positioning section later.

RenderTable.h

Text

Raw text is represented usingRenderTextClass. Text is always considered inline by WebCore, since it is always placed on lines.

RenderText.h

Getting block and inline Information

The most basic method for obtaining block vs. inline status isisInlineFunction. this method asks if an object is designed to be part of a line. it does not care what the interior of the element is (e.g ., text, image, an inline flow, an inline-block or an inline-table ).

bool isInline() const

One of the common mistakes people make when working with the render tree is assuming thatisInlineMeans an object is always an inline flow, text or an inline replaced element. However because of inline-blocks and inline-tables, this method can return true even for these objects.

To ask if an object is actually a block or Inline flow, the following methods shocould be used.

bool isInlineFlow() constbool isBlockFlow() const

These methods are essential asking questions about the interior of the object. an inline-block for example is still a block flow and not an inline flow. it is inline on the outside, but on the inside it is a block flow.

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

bool isRenderBlock() constbool isRenderInline() const

TheisRenderBlockMethod is useful in the context of positioning, since both block flows and tables act as positioned object containers.

To ask if an object is specifically an inline block or Inline table,isInlineBlockOrInlineTableMethod can be used.

bool isInlineBlockOrInlineTable() const

Children of block flows

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

All in-flow children of a block flow must be blocks, or all in-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 return true fromisInlineOr they must all return false fromisInline. The render tree will change its structure as needed to preserve this invariant.

ThechildrenInlineMethod is used to ask whether the children of a block flow are inlines or blocks.

bool childrenInline() const

Children of inline flows

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

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

Anonymous Blocks

In order to preserve the block flow child invariant (only inline children or only block children), the render tree will construct objects calledAnonymous Blocks. Consider the following example:

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

In the above example, the outer Div has two children: some text and another Div. the first child is an inline, but the second child is a block. because this combination of children violates the all-inline or all-block child rule, the render tree will construct an anonymous block flow to wrap the text. the render tree therefore becomes:

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

TheisAnonymousBlockMethod can be used to ask if a Renderer is an anonymous block flow.

bool isAnonymousBlock() const

Whenever a block flow has inline children and a block object suddenly tries to insert itself as a child, anonymous blocks will be created as needed to wrap all of the inlines. contiguous inlines will share a single common anonymous block, so the number of anonymous blocks can be kept to a minimum. themakeChildrenNonInlineMethod inRenderBlockIs the function that performs this adjustment.

void makeChildrenNonInline(RenderObject *insertionPoint)

Blocks inside inline flows

One of the nastiest constructs you will see in HTML is when a block 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 the bold element must be inlines. the render tree has to perform a rather complicated series of steps in order to fix up the tree. three anonymous blocks are constructed. the first block holds all of the inlines that come before the Divs. the second anonymous block holds the Divs. the third anonymous block holds all of the inlines that come 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 two render objects, since they are in both the anonymous pre block and the anonymous post block. in the case of the bold Dom element, its children are in the PRE block, but then continue into the middle block and then finally continue into the post block. the render tree connects these objects viaContinuation chain.

RenderFlow* continuation() constbool isInlineContinuation() const

The first bold Renderer in the pre block is the one that can be obtained frombDom element using the element'srenderer()Method. This Renderer has as itscontinuation()The middle anonymous block. The middle anonymous block has as itscontinuation()The second bold Renderer. In this way code that needs to examine the renderers that represent the children of the DOM element can still do so relatively easily.

In the above exampleiDom element also split. Its children are all in the pre and post blocks, and therefore only one connection is needed. The ITALIC Renderer in the pre block sets itscontinuation()To the Italic Renderer in The Post block.

The function that performs the recursive splitting of inline flows and that creates the continuation chain connections is calledsplitFlowAnd is inRenderInline.cpp.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.