layout/doc/obsolete/block.html

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

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

mercurial