OLD | NEW |
1 # Whitespace LayoutObjects | 1 # Whitespace LayoutObjects |
2 | 2 |
3 Text nodes which only contain whitespace sometimes have a layout object and | 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 | 4 sometimes they don't. This document tries to explain why and how these layout |
5 objects are created. | 5 objects are created. |
6 | 6 |
7 ## Why | 7 ## Why |
8 | 8 |
9 For layout purposes, whitespace nodes are sometimes significant, but not | 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, | 10 always. In Blink, we try to create as few of them as possible to save memory, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 In the example above, we don't need to create a whitespace layout object since | 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 | 43 it will be the first in-flow child of the block, and will not contribute to the |
44 layout/rendering. | 44 layout/rendering. |
45 | 45 |
46 Example: | 46 Example: |
47 | 47 |
48 <span>A</span> <span style="position:absolute">Z</span> <span>B</span> | 48 <span>A</span> <span style="position:absolute">Z</span> <span>B</span> |
49 | 49 |
50 In the example above, we need to create a whitespace layout object to separate | 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 | 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. | 52 for one of the whitespace nodes as whitespace collapse. |
53 | 53 |
54 ### Preformatted text and editing | 54 ### Preformatted text and editing |
55 | 55 |
56 Some values of the CSS white-space property will cause whitespace not to | 56 Some values of the CSS white-space property will cause whitespace to not |
57 collapse and affect layout and rendering also in block layout. In those cases | 57 collapse and affect layout and rendering also in block layout. In those cases |
58 we always create layout objects for whitespace nodes. | 58 we always create layout objects for whitespace nodes. |
59 | 59 |
60 Whitespace nodes are also significant in editing mode. | 60 Whitespace nodes are also significant in editing mode. |
61 | 61 |
62 ## How | 62 ## How |
63 | 63 |
64 ### Initial layout tree attachment | 64 ### Initial layout tree attachment |
65 | 65 |
66 When attaching a layout tree, we walk the flat-tree in a depth-first order | 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 | 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, | 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 | 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 | 70 previously added layout object siblings, skipping out-of-flow elements, to |
71 decide if we need to create a whitespace layout object. | 71 decide if we need to create a whitespace layout object. |
72 | 72 |
73 Important methods: | 73 Important methods: |
74 | 74 |
75 Text::attachLayoutTree() | 75 Text::attachLayoutTree() |
76 Text::textLayoutObjectIsNeeded() | 76 Text::textLayoutObjectIsNeeded() |
77 | 77 |
78 ### Layout object re-attachment | 78 ### Layout object re-attachment |
79 | 79 |
80 During style recalculation, elements whose computed value for display change | 80 During style recalculation, elements whose computed value for display changes |
81 will have its layout sub-tree re-attached. Attachment of the descendant layout | 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 | 82 objects happens the same way as for initial layout tree attachment, but the |
83 interesting part for whitespace layout objects is how they are affected by | 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 | 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 | 85 during the same style recalc traversal depending on whether they change their |
86 computed display value or not. | 86 computed display values or not. |
87 | 87 |
88 #### Style recalc traversal | 88 #### Style recalc traversal |
89 | 89 |
90 An important pre-requisite for how whitespace layout objects are re-attached | 90 An important prerequisite for how whitespace layout objects are re-attached |
91 is the traversal order we use for style recalc. The current traversal order | 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 | 92 makes it hard or costly to implement whitespace re-attachment without bugs in |
93 the presence of shadow trees, but let's describe what we do here. | 93 the presence of shadow trees, but let's describe what we do here. |
94 | 94 |
95 Style recalc happens in the shadow-including tree order with the exception that | 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 | 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 | 97 elements are recalculated in left-to-right (!?!) order, before and after |
98 shadow-including descendants respectively. | 98 shadow-including descendants respectively. |
99 | 99 |
100 Inheritance happens down the flat-tree. Since we are not traversing in | 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 | 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 | 102 to assigned/distributed nodes by marking these nodes with LocalStyleChange when |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 <div id="host"> | 134 <div id="host"> |
135 <:shadow-root> | 135 <:shadow-root> |
136 <span style="position:absolute">A</span><slot></slot> | 136 <span style="position:absolute">A</span><slot></slot> |
137 </:shadow-root> | 137 </:shadow-root> |
138 <span>B</span> | 138 <span>B</span> |
139 </div> | 139 </div> |
140 | 140 |
141 Initially, the whitespace before the B span above does not get a layout object. | 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 | 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 | 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 | 144 the light-tree children of #host after the shadow tree, we do not see the text |
145 the text node before re-attaching the absolute positioned span. | 145 node before re-attaching the absolute positioned span. |
146 | 146 |
147 Likewise we currently have issues with ::before and ::after elements because we | 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 | 148 do not keep track of text nodes and pass them to ::before/::after element |
149 re-attachments. See the "Known issues" below. | 149 re-attachments. See the "Known issues" below. |
150 | 150 |
151 Important methods: | 151 Important methods: |
152 | 152 |
153 Element::recalcStyle() | 153 Element::recalcStyle() |
154 ContainerNode::recalcDescendantStyles() | 154 ContainerNode::recalcDescendantStyles() |
155 Node::reattachWhitespaceSiblingsIfNeeded() | 155 Node::reattachWhitespaceSiblingsIfNeeded() |
156 Text::textLayoutObjectIsNeeded() | 156 Text::textLayoutObjectIsNeeded() |
157 Text::reattachLayoutTreeIfNeeded() | 157 Text::reattachLayoutTreeIfNeeded() |
158 Text::recalcTextStyle() | 158 Text::recalcTextStyle() |
159 | 159 |
160 Known issues: | 160 Known issues: |
161 | 161 |
162 https://crbug.com/648931 | 162 https://crbug.com/648931 |
163 https://crbug.com/648951 | 163 https://crbug.com/648951 |
164 https://crbug.com/650168 | 164 https://crbug.com/650168 |
OLD | NEW |