~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/layout/doc/obsolete/block.html

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
 
2
<html>
 
3
<head>
 
4
   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 
5
   <meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; Linux 2.2.5-22 i686) [Netscape]">
 
6
</head>
 
7
<body>
 
8
 
 
9
<h1>
 
10
<u>Block Layout</u></h1>
 
11
This document attempts to describe how "block" layout works in the mozilla
 
12
layout engine.
 
13
<p><tt>nsBlockFrame</tt> implements layout behavior that conforms to the
 
14
CSS "display:block" and "display: list-item" layout. It has several responsibilities:
 
15
<ol>
 
16
<li>
 
17
&nbsp;Line layout. The block is responsible for flowing inline elements
 
18
into "lines" and applying all of the css behavior as one might expect,
 
19
including line-height, vertical-align, relative positioning, etc.</li>
 
20
 
 
21
<li>
 
22
Float management. The block is responsible for the reflow and placement
 
23
of floating elements.</li>
 
24
 
 
25
<li>
 
26
Child block management. Blocks can contain inline elements and block elements.
 
27
Hence, blocks are responsible for reflowing child blocks. The majority
 
28
of that logic has been split out into nsBlockReflowContext, but a fair
 
29
amount remains here.</li>
 
30
 
 
31
<li>
 
32
Supporting table reflow. The block has to carefully compute the "max-element-size"
 
33
information needed by tables. Hence, any time changes are made here one
 
34
should always run the table regression tests because the odds are you broke
 
35
one of them!</li>
 
36
</ol>
 
37
 
 
38
<h3>
 
39
<u>The Big Picture for Block Reflow</u></h3>
 
40
The block frame uses a list of nsLineBox's to keep track of each "line"
 
41
of frames it manages. There are two types of lines:
 
42
<blockquote>"inline" lines which contain only inline elements
 
43
<br>"block" lines which contain exactly one block element</blockquote>
 
44
Each line has a "dirty" bit which indicates that it needs reflow. Reflow
 
45
consists of identifying which lines need to be marked dirty and then reflowing
 
46
all lines. For lines which are "clean" the reflow logic will endeavor to
 
47
recover the state of reflow <i>as if the line had been reflowed</i>. This
 
48
saves time and allows for a faster incremental reflow. For lines which
 
49
are dirty, the line is reflowed appropriately.
 
50
<p>The only special thing about incremental reflow command handling is
 
51
that it marks lines dirty before proceeding, and keeps track of the child
 
52
frame that is the next frame on the reflow command path.
 
53
<p>Here is a list of the various classes involved in block layout:
 
54
<p><b>nsBlockFrame</b>
 
55
<blockquote>The primary culprit.</blockquote>
 
56
<b>nsBlockReflowState</b>
 
57
<blockquote>This helper class is used to augment the nsHTMLReflowState
 
58
with other information needed by the block reflow logic during reflow.
 
59
It is a temporary object that is designed to live on the processor stack
 
60
and contains "running" state used by the blocks reflow logic.</blockquote>
 
61
<b>nsBlockBandData</b>
 
62
<blockquote>Another helper class that wraps up management of a space manager
 
63
(nsISpaceManager, nsSpaceManager) and nsBandData. It also assists in management
 
64
of floating elements. While nsSpaceManager is policy free, nsBlockBandData
 
65
provides specific HTML and CSS policy.</blockquote>
 
66
<b>nsBlockReflowContext</b>
 
67
<blockquote>A helper class that encapsulates the logic needed to reflow
 
68
a child block frame. This is used by the block code reflow a child block
 
69
and to reflow floating elements (which are to be treated as blocks according
 
70
to the CSS2 spec).</blockquote>
 
71
<b>nsLineBox</b>
 
72
<blockquote>A data class used to store line information for the block frame
 
73
code. Each line has a list of children (though the frames are linked together
 
74
across lines to maintain the sibling list for nsIFrame::FirstChild) and
 
75
some other state used to assist in incremental reflow.</blockquote>
 
76
<b>nsLineLayout</b>
 
77
<blockquote>This class is the line layout engine. Its a passive entity
 
78
in the sense that its the responsibility of the block/inline code to use
 
79
the class (this is done so that the line layout engine doesn't have to
 
80
manage child frame lists so that both nsBlockFrame and nsInlineFrame can
 
81
use the class).</blockquote>
 
82
<b>nsTextRun</b>
 
83
<blockquote>This is a data class used to store text run information. Text
 
84
runs are <i>logically</i> contiguous runs of text (they may or may not
 
85
be structurally contiguous). The block frame stores a pointer to a list
 
86
of nsTextRun's and during line layout provides the list to the nsLineLayout
 
87
engine so that when text is reflowed the text layout code (nsTextFrame)
 
88
can find related text to properly handle word breaking.</blockquote>
 
89
 
 
90
<h3>
 
91
<u>Frame construction methods</u></h3>
 
92
When the blocks child list is modified (AppendFrames, InsertFrames, RemoveFrame)
 
93
the block code updates its nsLineBox list. Since each nsLineBox is typed
 
94
(some are marked "inline" and some are marked "block"), the update logic
 
95
maintains the invariant of "one block frame per block line".
 
96
<p>When structural changes are made to the blocks children (append/insert/remove)
 
97
the block code updates the line's and then marks the affected lines "dirty"
 
98
(each nsLineBox has a dirty bit). After the structural changes are finished
 
99
then the block will generate an incremental reflow command of type "ReflowDirty".
 
100
<h3>
 
101
<u>Line Layout</u></h3>
 
102
Line layout consists of the placement of inline elements on a line until
 
103
there is no more room on the line. At that point the line is "broken" and
 
104
continued on the next line. This process continues until all inline elements
 
105
have been exhausted. The block code maintains a list of "nsLineBox"'s to
 
106
facilitate this. These are used instead of frames because they use less
 
107
memory and because it allows the block to directly control their behavior.
 
108
<p>The helper class nsLineLayout provides the majority of the line layout
 
109
behavior needed by the block.
 
110
<p>The block does keep "text-run" information around for the nsLineLayout
 
111
logic to use during reflow. Text runs keep track of logically adjacent
 
112
pieces of text within a block. This information is essential for properly
 
113
computing line and word breaking. Why? Well, because in html you can write
 
114
something like this:
 
115
<p>&nbsp; &lt;p>I &lt;b>W&lt;/b>as thinking one day&lt;/p>
 
116
<p>Notice that the word "Was" is composed of two pieces of text, and that
 
117
they do <i>not</i> have the same parent (content or frame). To properly
 
118
reflow this and not break the word prematurely after the "W", the text-run
 
119
information is used by the text frame code to "look ahead" and prevent
 
120
premature breaking.
 
121
<p>Lines also keep track of the type of "break" that occurred on the line.
 
122
This is used, for example, to support html's "&lt;br clear=left>" behavior.
 
123
<h3>
 
124
<u>Float Management</u></h3>
 
125
Since child block elements are containing blocks for floats, the only
 
126
place where a block frame will see a float is as part of an inline line.
 
127
Consequently, the nsLineBox will only keep track of floats on inline
 
128
lines (saving storage for block lines).
 
129
<p>The nsLineLayout class and the block frame cooperate in the management
 
130
of floats. Since the frame construction code leaves a "placeholder" frame
 
131
in-flow where the float was found, when nsLineLayout reflows a placeholder
 
132
frame it knows to inform the block about it. That triggers the blocks "AddFloat"
 
133
logic which then determines where the float should be placed (on the
 
134
current line or below the current line).
 
135
<p>The block frame uses the space manager to manage the effects of floats,
 
136
namely the consumption of available space. For example, for a left aligned
 
137
floating element, the inline elements must be placed to the right of the
 
138
float. To simplify this process, the spacemanager is used to keep track
 
139
of available and busy space. Floats when placed mark space as busy and
 
140
the spacemanager will them compute the available space. Most of this logic
 
141
is handled by the nsBlockReflowState which uses a helper class, nsBlockBandData,
 
142
in concert with the space manager, to do the available space computations.
 
143
<h3>
 
144
<u>Child Block Placement</u></h3>
 
145
Child block reflow is done primarily by using the nsBlockReflowContext
 
146
code. However, a key detail worth mentioning here is how margins are handled.
 
147
When the nsHTMLReflowState was created, we placed into it the logic for
 
148
computing margins, border and padding (among other things). Unfortunately,
 
149
given the css rules for sibling and generational margin collapsing, the
 
150
nsHTMLReflowState is unable to properly compute top and bottom margins.
 
151
Hence, the block frame and the nsBlockReflowContext code perform that function.
 
152
At the time that the nsBlockReflowContext was designed and implemented
 
153
we thought that it could compute the top-margin itself and then proceed
 
154
to place the child block element. However, that turned out to be wrong
 
155
(oh well) because the correct available space isn't known until <i>after</i>
 
156
the top margin is computed. Hence, there is some unfortunate duplication
 
157
of reflow state calculations present in the block frame code.
 
158
<h3>
 
159
<u>Bullets</u></h3>
 
160
Another type of block frame is the "display: list-item". List-items use
 
161
nsBulletFrame's to manage bullet reflow. However, the block is responsible
 
162
for bullet placement. In most situations, the nsLineLayout class is used
 
163
to do the placement. However, if the first effective child of the block
 
164
is another block, then the block has to do the placement itself.
 
165
<h3>
 
166
<u>Blank lines</u></h3>
 
167
Because our content model contains as much of the original source documents
 
168
content as possible, we end up with a lot of white space that ends up being
 
169
compressed into nothingness. This white space ends up impacting this logic
 
170
in several ways. For example:
 
171
<p>&nbsp; &lt;div>
 
172
<br>&nbsp;&nbsp; &lt;p>abc&lt;/p>
 
173
<br>&nbsp;&nbsp; &lt;p>def&lt;/p>
 
174
<br>&nbsp; &lt;/div>
 
175
<p>In the content model for the above html, there is white space between
 
176
the various block elements (some after the &lt;div>, some after the first
 
177
&lt;/p>, again after the second &lt;/p>).
 
178
<p>For css margin collapsing to work properly, each of those instances
 
179
of white space has to behave as if they didn't exist. Consequently, there
 
180
is special logic in the inline line reflow code, and in the nsBlockReflowContext
 
181
code and in the GetTopBlockChild method, to basically ignore such lines.
 
182
<h3>
 
183
<u>First-letter style</u></h3>
 
184
The block contributes, in a small way, to first-letter style reflow. The
 
185
frame construction code is responsible for creating the list of child frames
 
186
for all frames, including the block. It manages the creation of letter-frames,
 
187
where appropriate, so that all the block has to do is reflow them almost
 
188
normally like other inline frames.
 
189
<p>There are two things different that the block does:
 
190
<p>It is responsible for calling nsLineLayout::SetFirstLetterStyleOK
 
191
<br>It is responsible for continuing to place frames on a line, even after
 
192
a frame has said "it can't fit". Normally during inline reflow, if a frame
 
193
comes back and says it can't fit, the block will end the line, push all
 
194
remaining frames to the next line and pick up the reflow from there after
 
195
making sure the frame that didn't fit is continued. For letter-frames,
 
196
this would result in the first-letter being on one line with the remaining
 
197
text on subsequent lines. Hence, the block code handles this special case.
 
198
<br>&nbsp;
 
199
<h3>
 
200
<u>First-line style</u></h3>
 
201
First-line is handled entirely by the frame construction code.
 
202
<br>&nbsp;
 
203
<br>&nbsp;
 
204
</body>
 
205
</html>