Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(304)

Side by Side Diff: third_party/WebKit/Source/core/dom/WhitespaceLayoutObjects.md

Issue 2402653002: Document LayoutObject generation for whitespace nodes. (Closed)
Patch Set: Proof-reading Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Whitespace LayoutObjects
2
3 Text nodes which only contain whitespace sometimes have a layout object and
4 sometimes they don't. This document tries to explain why and how these layout
5 objects are created.
6
7 ## Why
8
9 For layout purposes, whitespace nodes are sometimes significant, but not
10 always. In Blink, we try to create as few of them as possible to save memory,
11 and save CPU by having fewer layout objects to traverse.
12
13 ### Inline flow
14
15 Whitespace typically matters in an inline flow context. Example:
16
17 <span>A</span> </span>B</span>
18
19 If we didn't create a LayoutObject for the whitespace node between the two
20 spans, we would have rendered the markup above as "AB" as the span layout
21 objects would have been siblings in the layout tree.
22
23 ### Block flow
24
25 Whitespace typically doesn't matter in a block flow context. Example:
26
27 <div>A</div> <div>B</div>
28
29 In the example above, the whitespace node between the divs would not contribute
30 to layout/rendering. Hence, we can skip creating a LayoutText for it.
31
32 ### Out-of-flow
33
34 Out-of-flow elements like absolutely positioned elements do not affect inline
35 or block in-flow layout. That means we can skip such elements when considering
36 the need whitespace layout objects.
37
38 Example:
39
40 <div><span style="position:absolute">A</span> </span>B</span></div>
41
42 In the example above, we don't need to create a whitespace layout object since
43 it will be the first in-flow child of the block, and will not contribute to the
44 layout/rendering.
45
46 Example:
47
48 <span>A</span> <span style="position:absolute">Z</span> <span>B</span>
49
50 In the example above, we need to create a whitespace layout object to separate
51 the A and B in the rendering. However, we only need to create a layout object
52 for one of the whitespace nodes as whitespaces collapse.
53
54 ### Preformatted text and editing
55
56 Some values of the CSS white-space property will cause whitespace not to
57 collapse and affect layout and rendering also in block layout. In those cases
58 we always create layout objects for whitespace nodes.
59
60 Whitespace nodes are also significant in editing mode.
61
62 ## How
63
64 ### Initial layout tree attachment
65
66 When attaching a layout tree, we walk the flat-tree in a depth-first order
67 walking the siblings from left to right. As we reach a text node, we check if
68 we need to create a layout object in textLayoutObjectIsNeeded(). In particular,
69 if we found that it only contains whitespace, we start traversing the
70 previously added layout object siblings, skipping out-of-flow elements, to
71 decide if we need to create a whitespace layout object.
72
73 Important methods:
74
75 Text::attachLayoutTree()
76 Text::textLayoutObjectIsNeeded()
77
78 ### Layout object re-attachment
79
80 During style recalculation, elements whose computed value for display change
81 will have its layout sub-tree re-attached. Attachment of the descendant layout
82 objects happens the same way as for inital layout tree attachment, but the
83 interesting part for whitespace layout objects is how they are affected by
84 re-attachment of sibling elements. Sibling nodes may or may not be re-attached
85 during the same style recalc traversal depending on whether they change their
86 computed display value or not.
87
88 #### Style recalc traversal
89
90 An important pre-requisite for how whitespace layout objects are re-attached
91 is the traversal order we use for style recalc. The current traversal order
92 makes it hard or costly to implement whitespace re-attachement without bugs in
93 the presence of shadow trees, but let's describe what we do here.
94
95 Style recalc happens in the shadow-including tree order with the exception that
96 siblings are traversed from right to left. The ::before and ::after pseudo
97 elements are recalculated in left-to-right (!?!) order, before and after
98 shadow-including descendants respectively.
99
100 Inheritance happens down the flat-tree. Since we are not traversing in
101 flat-tree order, we implement this propagation from slot/content elements down
102 to assigned/distributed nodes by marking these nodes with LocalStyleChange when
103 we need to do inheritance propagation (done in HTMLSlotElement::willRecalcStyle
104 for instance). This works since light-tree children are traversed after the
105 shadow tree(s).
106
107 #### Re-attaching whitespace layout objects
108
109 When the computed display value changes, the requirement for whitespace
110 siblings may change.
111
112 Example:
113
114 <span style="position:absolute">A</span> <span>B</span>
115
116 Initially, we don't need a layout object for the whitespace above. If we change
117 the position of the first span to static, we need a layout object for the
118 whitespace. During style recalc we keep track of the last text node sibling we
119 traversed. The text node is reset when we traverse an element with a layout
120 box. Remember that we traverse from right to left. That means we have stored
121 the whitespace node above when we re-attach the left-most span. After
122 re-attachment we re-attach the stored text node to see if the need for a
123 layout object changed. If the text node re-attach changed the need for a layout
124 object we continue to re-attach following layout object siblings until we
125 reach an element with a layout object, or the re-attach was a no-op.
126
127 The need for a whitespace layout object is dictated by the layout tree
128 structure which is based on the flat-tree. That means the tracked text node
129 solution we use does not work properly when (re-)attaching slotted and
130 distributed nodes.
131
132 Example:
133
134 <div id="host">
135 <:shadow-root>
136 <span style="position:absolute">A</span><slot></slot>
137 </:shadow-root>
138 <span>B</span>
139 </div>
140
141 Initially, the whitespace before the B span above does not get a layout object.
142 If we change the absolute positioned span in the shadow tree to static, we need
143 to have a layout object for that whitespace node. However, since we traverse
144 traverse the light-tree children of #host after the shadow tree, we do not see
145 the text node before re-attaching the absolute positioned span.
146
147 Likewise we currently have issues with ::before and ::after elements because we
148 do not keep track of text nodes and pass them to ::before/::after element
149 re-attachments. See the "Known issues" below.
150
151 Important methods:
152
153 Element::recalcStyle()
154 ContainerNode::recalcDescendantStyles()
155 Node::reattachWhitespaceSiblingsIfNeeded()
156 Text::textLayoutObjectIsNeeded()
157 Text::reattachLayoutTreeIfNeeded()
158 Text::recalcTextStyle()
159
160 Known issues:
161
162 https://crbug.com/648931
163 https://crbug.com/648951
164 https://crbug.com/650168
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698