Changeset 230484 in webkit
- Timestamp:
- Apr 10, 2018 10:21:50 AM (6 years ago)
- Location:
- trunk/Tools
- Files:
-
- 1 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Tools/ChangeLog
r230473 r230484 1 2018-04-10 Zalan Bujtas <zalan@apple.com> 2 3 [LayoutReloaded] Add support for out-of-flow descendants in inline formatting context. 4 https://bugs.webkit.org/show_bug.cgi?id=184454 5 6 Reviewed by Antti Koivisto. 7 8 When the containing block of an out-of-flow positioned element establishes an inline formatting context. 9 This is mostly about moving out-of-flow logic from BlockFormattingContext to the base class. 10 11 * LayoutReloaded/FormattingContext/BlockFormatting/BlockFormattingContext.js: 12 (BlockFormattingContext.prototype._adjustBottomWithFIXME): 13 (BlockFormattingContext): 14 (BlockFormattingContext.prototype._layoutOutOfFlowDescendants): Deleted. 15 (BlockFormattingContext.prototype._computeOutOfFlowWidth): Deleted. 16 (BlockFormattingContext.prototype._computeInFlowWidth): Deleted. 17 (BlockFormattingContext.prototype._computeOutOfFlowHeight): Deleted. 18 (BlockFormattingContext.prototype._computeOutOfFlowPosition): Deleted. 19 (BlockFormattingContext.prototype._shrinkToFitWidth): Deleted. 20 * LayoutReloaded/FormattingContext/FormattingContext.js: 21 (FormattingContext.prototype._placeInFlowPositionedChildren): 22 (FormattingContext.prototype._computeInFlowWidth): 23 (FormattingContext.prototype._layoutOutOfFlowDescendants): 24 (FormattingContext.prototype._computeOutOfFlowWidth): 25 (FormattingContext.prototype._computeOutOfFlowHeight): 26 (FormattingContext.prototype._computeOutOfFlowPosition): 27 (FormattingContext.prototype._shrinkToFitWidth): 28 * LayoutReloaded/FormattingContext/InlineFormatting/InlineFormattingContext.js: 29 (InlineFormattingContext.prototype.layout): 30 (InlineFormattingContext.prototype._handleInlineContainer): 31 (InlineFormattingContext.prototype._handleInlineBlockContainer): 32 (InlineFormattingContext.prototype._placeOutOfFlowDescendants): Deleted. 33 * LayoutReloaded/test/index.html: 34 * LayoutReloaded/test/inline-with-out-of-flow-descendant.html: Added. 35 1 36 2018-04-09 Zan Dobersek <zdobersek@igalia.com> 2 37 -
trunk/Tools/LayoutReloaded/FormattingContext/BlockFormatting/BlockFormattingContext.js
r230469 r230484 119 119 } 120 120 121 _layoutOutOfFlowDescendants() {122 // This lays out all the out-of-flow boxes that belong to this formatting context even if123 // the root container is not the containing block.124 let outOfFlowDescendants = this._outOfFlowDescendants();125 for (let outOfFlowBox of outOfFlowDescendants) {126 this._addToLayoutQueue(outOfFlowBox);127 this.computeWidth(outOfFlowBox);128 this.layoutState().layout(outOfFlowBox);129 this.computeHeight(outOfFlowBox);130 this._computeOutOfFlowPosition(outOfFlowBox);131 this._removeFromLayoutQueue(outOfFlowBox);132 }133 }134 135 _computeOutOfFlowWidth(layoutBox) {136 // 10.3.7 Absolutely positioned, non-replaced elements137 138 // 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left'139 // 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if the 'direction' property of the element establishing140 // the static-position containing block is 'ltr' set 'left' to the static position, otherwise set 'right' to the static position.141 // Then solve for 'left' (if 'direction is 'rtl') or 'right' (if 'direction' is 'ltr').142 // 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right'143 // 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve for 'left'144 // 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve for 'width'145 // 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve for 'right'146 let width = Number.NaN;147 if (Utils.isWidthAuto(layoutBox) && Utils.isLeftAuto(layoutBox) && Utils.isRightAuto(layoutBox))148 width = this._shrinkToFitWidth(layoutBox);149 else if (Utils.isLeftAuto(layoutBox) && Utils.isWidthAuto(layoutBox) && !Utils.isRightAuto(layoutBox))150 width = this._shrinkToFitWidth(layoutBox); // 1151 else if (Utils.isLeftAuto(layoutBox) && Utils.isRightAuto(layoutBox) && !Utils.isWidthAuto(layoutBox))152 width = Utils.width(layoutBox); // 2153 else if (Utils.isWidthAuto(layoutBox) && Utils.isRightAuto(layoutBox) && !Utils.isLeftAuto(layoutBox))154 width = this._shrinkToFitWidth(layoutBox); // 3155 else if (Utils.isLeftAuto(layoutBox) && !Utils.isWidthAuto(layoutBox) && !Utils.isRightAuto(layoutBox))156 width = Utils.width(layoutBox); // 4157 else if (Utils.isWidthAuto(layoutBox) && !Utils.isLeftAuto(layoutBox) && !Utils.isRightAuto(layoutBox))158 width = Math.max(0, this.displayBox(layoutBox.containingBlock()).contentBox().width() - Utils.right(layoutBox) - Utils.left(layoutBox)); // 5159 else if (Utils.isRightAuto(layoutBox) && !Utils.isLeftAuto(layoutBox) && !Utils.isWidthAuto(layoutBox))160 width = Utils.width(layoutBox); // 6161 else162 ASSERT_NOT_REACHED();163 width += Utils.computedHorizontalBorderAndPadding(layoutBox.node());164 this.displayBox(layoutBox).setWidth(width);165 }166 167 _computeInFlowWidth(layoutBox) {168 if (Utils.isWidthAuto(layoutBox))169 return this.displayBox(layoutBox).setWidth(this._horizontalConstraint(layoutBox));170 return this.displayBox(layoutBox).setWidth(Utils.width(layoutBox) + Utils.computedHorizontalBorderAndPadding(layoutBox.node()));171 }172 173 _computeOutOfFlowHeight(layoutBox) {174 // 1. If all three of 'top', 'height', and 'bottom' are auto, set 'top' to the static position and apply rule number three below.175 // 2. If none of the three are 'auto': If both 'margin-top' and 'margin-bottom' are 'auto', solve the equation under176 // the extra constraint that the two margins get equal values. If one of 'margin-top' or 'margin-bottom' is 'auto',177 // solve the equation for that value. If the values are over-constrained, ignore the value for 'bottom' and solve for that value.178 // Otherwise, pick the one of the following six rules that applies.179 180 // 3. 'top' and 'height' are 'auto' and 'bottom' is not 'auto', then the height is based on the content per 10.6.7,181 // set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'top'182 // 4. 'top' and 'bottom' are 'auto' and 'height' is not 'auto', then set 'top' to the static position, set 'auto' values183 // for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'184 // 5. 'height' and 'bottom' are 'auto' and 'top' is not 'auto', then the height is based on the content per 10.6.7,185 // set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'186 // 6. 'top' is 'auto', 'height' and 'bottom' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'top'187 // 7. 'height' is 'auto', 'top' and 'bottom' are not 'auto', then 'auto' values for 'margin-top' and 'margin-bottom' are set to 0 and solve for 'height'188 // 8. 'bottom' is 'auto', 'top' and 'height' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0 and solve for 'bottom'189 let height = Number.NaN;190 if (Utils.isHeightAuto(layoutBox) && Utils.isBottomAuto(layoutBox) && Utils.isTopAuto(layoutBox))191 height = this._contentHeight(layoutBox); // 1192 else if (Utils.isTopAuto((layoutBox)) && Utils.isHeightAuto((layoutBox)) && !Utils.isBottomAuto((layoutBox)))193 height = this._contentHeight(layoutBox); // 3194 else if (Utils.isTopAuto((layoutBox)) && Utils.isBottomAuto((layoutBox)) && !Utils.isHeightAuto((layoutBox)))195 height = Utils.height(layoutBox); // 4196 else if (Utils.isHeightAuto((layoutBox)) && Utils.isBottomAuto((layoutBox)) && !Utils.isTopAuto((layoutBox)))197 height = this._contentHeight(layoutBox); // 5198 else if (Utils.isTopAuto((layoutBox)) && !Utils.isHeightAuto((layoutBox)) && !Utils.isBottomAuto((layoutBox)))199 height = Utils.height(layoutBox); // 6200 else if (Utils.isHeightAuto((layoutBox)) && !Utils.isTopAuto((layoutBox)) && !Utils.isBottomAuto((layoutBox)))201 height = Math.max(0, this.displayBox(layoutBox.containingBlock()).contentBox().height() - Utils.bottom(layoutBox) - Utils.top(layoutBox)); // 7202 else if (Utils.isBottomAuto((layoutBox)) && !Utils.isTopAuto((layoutBox)) && !Utils.isHeightAuto((layoutBox)))203 height = Utils.height(layoutBox); // 8204 else205 ASSERT_NOT_REACHED();206 height += Utils.computedVerticalBorderAndPadding(layoutBox.node());207 this.displayBox(layoutBox).setHeight(height);208 }209 210 121 _computeInFlowHeight(layoutBox) { 211 122 if (Utils.isHeightAuto(layoutBox)) { … … 265 176 return bottom; 266 177 } 267 268 _computeOutOfFlowPosition(layoutBox) {269 let displayBox = this.displayBox(layoutBox);270 let top = Number.NaN;271 let containerSize = this.displayBox(layoutBox.containingBlock()).contentBox().size();272 // Top/bottom273 if (Utils.isTopAuto(layoutBox) && Utils.isBottomAuto(layoutBox)) {274 ASSERT(Utils.isStaticallyPositioned(layoutBox));275 // Vertically statically positioned.276 // FIXME: Figure out if it is actually valid that we use the parent box as the container (which is not even in this formatting context).277 let parent = layoutBox.parent();278 let parentDisplayBox = this.displayBox(parent);279 let previousInFlowSibling = layoutBox.previousInFlowSibling();280 let contentBottom = previousInFlowSibling ? this.displayBox(previousInFlowSibling).bottom() : parentDisplayBox.contentBox().top();281 top = contentBottom + this.marginTop(layoutBox);282 // Convert static position (in parent coordinate system) to absolute (in containing block coordindate system).283 if (parent != layoutBox.containingBlock()) {284 ASSERT(displayBox.parent() == this.displayBox(layoutBox.containingBlock()));285 top += Utils.mapPosition(parentDisplayBox.topLeft(), parentDisplayBox, displayBox.parent()).top();286 }287 } else if (!Utils.isTopAuto(layoutBox))288 top = Utils.top(layoutBox) + this.marginTop(layoutBox);289 else if (!Utils.isBottomAuto(layoutBox))290 top = containerSize.height() - Utils.bottom(layoutBox) - displayBox.height() - this.marginBottom(layoutBox);291 else292 ASSERT_NOT_REACHED();293 // Left/right294 let left = Number.NaN;295 if (Utils.isLeftAuto(layoutBox) && Utils.isRightAuto(layoutBox)) {296 ASSERT(Utils.isStaticallyPositioned(layoutBox));297 // Horizontally statically positioned.298 // FIXME: Figure out if it is actually valid that we use the parent box as the container (which is not even in this formatting context).299 let parent = layoutBox.parent();300 let parentDisplayBox = this.displayBox(parent);301 left = parentDisplayBox.contentBox().left() + this.marginLeft(layoutBox);302 // Convert static position (in parent coordinate system) to absolute (in containing block coordindate system).303 if (parent != layoutBox.containingBlock()) {304 ASSERT(displayBox.parent() == this.displayBox(layoutBox.containingBlock()));305 left += Utils.mapPosition(parentDisplayBox.topLeft(), parentDisplayBox, displayBox.parent()).left();306 }307 } else if (!Utils.isLeftAuto(layoutBox))308 left = Utils.left(layoutBox) + this.marginLeft(layoutBox);309 else if (!Utils.isRightAuto(layoutBox))310 left = containerSize.width() - Utils.right(layoutBox) - displayBox.width() - this.marginRight(layoutBox);311 else312 ASSERT_NOT_REACHED();313 displayBox.setTopLeft(new LayoutPoint(top, left));314 }315 316 _shrinkToFitWidth(layoutBox) {317 // FIXME: this is naive.318 ASSERT(Utils.isWidthAuto(layoutBox));319 if (!layoutBox.isContainer() || !layoutBox.hasChild())320 return 0;321 let width = 0;322 for (let inFlowChild = layoutBox.firstInFlowChild(); inFlowChild; inFlowChild = inFlowChild.nextInFlowSibling()) {323 let widthCandidate = Utils.isWidthAuto(inFlowChild) ? this._shrinkToFitWidth(inFlowChild) : Utils.width(inFlowChild);324 width = Math.max(width, widthCandidate + Utils.computedHorizontalBorderAndPadding(inFlowChild.node()));325 }326 return width;327 }328 178 } -
trunk/Tools/LayoutReloaded/FormattingContext/FormattingContext.js
r230469 r230484 118 118 } 119 119 120 _placeInFlowPositionedChildren(container) { 121 if (!container.isContainer()) 122 return; 123 // If this layoutBox also establishes a formatting context, then positioning already has happend at the formatting context. 124 if (container.establishesFormattingContext() && container != this.formattingRoot()) 125 return; 126 ASSERT(container.isContainer()); 127 for (let inFlowChild = container.firstInFlowChild(); inFlowChild; inFlowChild = inFlowChild.nextInFlowSibling()) { 128 if (!inFlowChild.isInFlowPositioned()) 129 continue; 130 this._computeInFlowPositionedPosition(inFlowChild); 131 } 132 } 133 120 134 _computeInFlowPositionedPosition(layoutBox) { 121 135 // Start with the original, static position. … … 135 149 } 136 150 137 _placeInFlowPositionedChildren(container) { 138 if (!container.isContainer()) 139 return; 140 // If this layoutBox also establishes a formatting context, then positioning already has happend at the formatting context. 141 if (container.establishesFormattingContext() && container != this.formattingRoot()) 142 return; 143 ASSERT(container.isContainer()); 144 for (let inFlowChild = container.firstInFlowChild(); inFlowChild; inFlowChild = inFlowChild.nextInFlowSibling()) { 145 if (!inFlowChild.isInFlowPositioned()) 146 continue; 147 this._computeInFlowPositionedPosition(inFlowChild); 148 } 151 _computeInFlowWidth(layoutBox) { 152 if (Utils.isWidthAuto(layoutBox)) 153 return this.displayBox(layoutBox).setWidth(this._horizontalConstraint(layoutBox)); 154 return this.displayBox(layoutBox).setWidth(Utils.width(layoutBox) + Utils.computedHorizontalBorderAndPadding(layoutBox.node())); 155 } 156 157 _layoutOutOfFlowDescendants() { 158 // This lays out all the out-of-flow boxes that belong to this formatting context even if 159 // the root container is not the containing block. 160 let outOfFlowDescendants = this._outOfFlowDescendants(); 161 for (let outOfFlowBox of outOfFlowDescendants) { 162 this._addToLayoutQueue(outOfFlowBox); 163 this._computeOutOfFlowWidth(outOfFlowBox); 164 this.layoutState().layout(outOfFlowBox); 165 this._computeOutOfFlowHeight(outOfFlowBox); 166 this._computeOutOfFlowPosition(outOfFlowBox); 167 this._removeFromLayoutQueue(outOfFlowBox); 168 } 169 } 170 171 _computeOutOfFlowWidth(layoutBox) { 172 // 10.3.7 Absolutely positioned, non-replaced elements 173 174 // 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left' 175 // 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if the 'direction' property of the element establishing 176 // the static-position containing block is 'ltr' set 'left' to the static position, otherwise set 'right' to the static position. 177 // Then solve for 'left' (if 'direction is 'rtl') or 'right' (if 'direction' is 'ltr'). 178 // 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' 179 // 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve for 'left' 180 // 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve for 'width' 181 // 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve for 'right' 182 let width = Number.NaN; 183 if (Utils.isWidthAuto(layoutBox) && Utils.isLeftAuto(layoutBox) && Utils.isRightAuto(layoutBox)) 184 width = this._shrinkToFitWidth(layoutBox); 185 else if (Utils.isLeftAuto(layoutBox) && Utils.isWidthAuto(layoutBox) && !Utils.isRightAuto(layoutBox)) 186 width = this._shrinkToFitWidth(layoutBox); // 1 187 else if (Utils.isLeftAuto(layoutBox) && Utils.isRightAuto(layoutBox) && !Utils.isWidthAuto(layoutBox)) 188 width = Utils.width(layoutBox); // 2 189 else if (Utils.isWidthAuto(layoutBox) && Utils.isRightAuto(layoutBox) && !Utils.isLeftAuto(layoutBox)) 190 width = this._shrinkToFitWidth(layoutBox); // 3 191 else if (Utils.isLeftAuto(layoutBox) && !Utils.isWidthAuto(layoutBox) && !Utils.isRightAuto(layoutBox)) 192 width = Utils.width(layoutBox); // 4 193 else if (Utils.isWidthAuto(layoutBox) && !Utils.isLeftAuto(layoutBox) && !Utils.isRightAuto(layoutBox)) 194 width = Math.max(0, this.displayBox(layoutBox.containingBlock()).contentBox().width() - Utils.right(layoutBox) - Utils.left(layoutBox)); // 5 195 else if (Utils.isRightAuto(layoutBox) && !Utils.isLeftAuto(layoutBox) && !Utils.isWidthAuto(layoutBox)) 196 width = Utils.width(layoutBox); // 6 197 else 198 ASSERT_NOT_REACHED(); 199 width += Utils.computedHorizontalBorderAndPadding(layoutBox.node()); 200 this.displayBox(layoutBox).setWidth(width); 201 } 202 203 _computeOutOfFlowHeight(layoutBox) { 204 // 1. If all three of 'top', 'height', and 'bottom' are auto, set 'top' to the static position and apply rule number three below. 205 // 2. If none of the three are 'auto': If both 'margin-top' and 'margin-bottom' are 'auto', solve the equation under 206 // the extra constraint that the two margins get equal values. If one of 'margin-top' or 'margin-bottom' is 'auto', 207 // solve the equation for that value. If the values are over-constrained, ignore the value for 'bottom' and solve for that value. 208 // Otherwise, pick the one of the following six rules that applies. 209 210 // 3. 'top' and 'height' are 'auto' and 'bottom' is not 'auto', then the height is based on the content per 10.6.7, 211 // set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'top' 212 // 4. 'top' and 'bottom' are 'auto' and 'height' is not 'auto', then set 'top' to the static position, set 'auto' values 213 // for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom' 214 // 5. 'height' and 'bottom' are 'auto' and 'top' is not 'auto', then the height is based on the content per 10.6.7, 215 // set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom' 216 // 6. 'top' is 'auto', 'height' and 'bottom' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'top' 217 // 7. 'height' is 'auto', 'top' and 'bottom' are not 'auto', then 'auto' values for 'margin-top' and 'margin-bottom' are set to 0 and solve for 'height' 218 // 8. 'bottom' is 'auto', 'top' and 'height' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0 and solve for 'bottom' 219 let height = Number.NaN; 220 if (Utils.isHeightAuto(layoutBox) && Utils.isBottomAuto(layoutBox) && Utils.isTopAuto(layoutBox)) 221 height = this._contentHeight(layoutBox); // 1 222 else if (Utils.isTopAuto((layoutBox)) && Utils.isHeightAuto((layoutBox)) && !Utils.isBottomAuto((layoutBox))) 223 height = this._contentHeight(layoutBox); // 3 224 else if (Utils.isTopAuto((layoutBox)) && Utils.isBottomAuto((layoutBox)) && !Utils.isHeightAuto((layoutBox))) 225 height = Utils.height(layoutBox); // 4 226 else if (Utils.isHeightAuto((layoutBox)) && Utils.isBottomAuto((layoutBox)) && !Utils.isTopAuto((layoutBox))) 227 height = this._contentHeight(layoutBox); // 5 228 else if (Utils.isTopAuto((layoutBox)) && !Utils.isHeightAuto((layoutBox)) && !Utils.isBottomAuto((layoutBox))) 229 height = Utils.height(layoutBox); // 6 230 else if (Utils.isHeightAuto((layoutBox)) && !Utils.isTopAuto((layoutBox)) && !Utils.isBottomAuto((layoutBox))) 231 height = Math.max(0, this.displayBox(layoutBox.containingBlock()).contentBox().height() - Utils.bottom(layoutBox) - Utils.top(layoutBox)); // 7 232 else if (Utils.isBottomAuto((layoutBox)) && !Utils.isTopAuto((layoutBox)) && !Utils.isHeightAuto((layoutBox))) 233 height = Utils.height(layoutBox); // 8 234 else 235 ASSERT_NOT_REACHED(); 236 height += Utils.computedVerticalBorderAndPadding(layoutBox.node()); 237 this.displayBox(layoutBox).setHeight(height); 238 } 239 240 _computeOutOfFlowPosition(layoutBox) { 241 let displayBox = this.displayBox(layoutBox); 242 let top = Number.NaN; 243 let containerSize = this.displayBox(layoutBox.containingBlock()).contentBox().size(); 244 // Top/bottom 245 if (Utils.isTopAuto(layoutBox) && Utils.isBottomAuto(layoutBox)) { 246 ASSERT(Utils.isStaticallyPositioned(layoutBox)); 247 // Vertically statically positioned. 248 // FIXME: Figure out if it is actually valid that we use the parent box as the container (which is not even in this formatting context). 249 let parent = layoutBox.parent(); 250 let parentDisplayBox = this.displayBox(parent); 251 let previousInFlowSibling = layoutBox.previousInFlowSibling(); 252 let contentBottom = previousInFlowSibling ? this.displayBox(previousInFlowSibling).bottom() : parentDisplayBox.contentBox().top(); 253 top = contentBottom + this.marginTop(layoutBox); 254 // Convert static position (in parent coordinate system) to absolute (in containing block coordindate system). 255 if (parent != layoutBox.containingBlock()) { 256 ASSERT(displayBox.parent() == this.displayBox(layoutBox.containingBlock())); 257 top += Utils.mapPosition(parentDisplayBox.topLeft(), parentDisplayBox, displayBox.parent()).top(); 258 } 259 } else if (!Utils.isTopAuto(layoutBox)) 260 top = Utils.top(layoutBox) + this.marginTop(layoutBox); 261 else if (!Utils.isBottomAuto(layoutBox)) 262 top = containerSize.height() - Utils.bottom(layoutBox) - displayBox.height() - this.marginBottom(layoutBox); 263 else 264 ASSERT_NOT_REACHED(); 265 // Left/right 266 let left = Number.NaN; 267 if (Utils.isLeftAuto(layoutBox) && Utils.isRightAuto(layoutBox)) { 268 ASSERT(Utils.isStaticallyPositioned(layoutBox)); 269 // Horizontally statically positioned. 270 // FIXME: Figure out if it is actually valid that we use the parent box as the container (which is not even in this formatting context). 271 let parent = layoutBox.parent(); 272 let parentDisplayBox = this.displayBox(parent); 273 left = parentDisplayBox.contentBox().left() + this.marginLeft(layoutBox); 274 // Convert static position (in parent coordinate system) to absolute (in containing block coordindate system). 275 if (parent != layoutBox.containingBlock()) { 276 ASSERT(displayBox.parent() == this.displayBox(layoutBox.containingBlock())); 277 left += Utils.mapPosition(parentDisplayBox.topLeft(), parentDisplayBox, displayBox.parent()).left(); 278 } 279 } else if (!Utils.isLeftAuto(layoutBox)) 280 left = Utils.left(layoutBox) + this.marginLeft(layoutBox); 281 else if (!Utils.isRightAuto(layoutBox)) 282 left = containerSize.width() - Utils.right(layoutBox) - displayBox.width() - this.marginRight(layoutBox); 283 else 284 ASSERT_NOT_REACHED(); 285 displayBox.setTopLeft(new LayoutPoint(top, left)); 286 } 287 288 _shrinkToFitWidth(layoutBox) { 289 // FIXME: this is naive and missing the actual preferred width computation. 290 ASSERT(Utils.isWidthAuto(layoutBox)); 291 if (!layoutBox.isContainer() || !layoutBox.hasChild()) 292 return 0; 293 let width = 0; 294 for (let inFlowChild = layoutBox.firstInFlowChild(); inFlowChild; inFlowChild = inFlowChild.nextInFlowSibling()) { 295 let widthCandidate = Utils.isWidthAuto(inFlowChild) ? this._shrinkToFitWidth(inFlowChild) : Utils.width(inFlowChild); 296 width = Math.max(width, widthCandidate + Utils.computedHorizontalBorderAndPadding(inFlowChild.node())); 297 } 298 return width; 149 299 } 150 300 -
trunk/Tools/LayoutReloaded/FormattingContext/InlineFormatting/InlineFormattingContext.js
r230469 r230484 51 51 this._placeInFlowPositionedChildren(this.formattingRoot()); 52 52 // And take care of out-of-flow boxes as the final step. 53 this._ placeOutOfFlowDescendants(this.formattingRoot());53 this._layoutOutOfFlowDescendants(this.formattingRoot()); 54 54 this._commitLine(); 55 55 ASSERT(!this.m_inlineContainerStack.length); … … 70 70 this._removeFromLayoutQueue(inlineContainer); 71 71 this._addToLayoutQueue(inlineContainer.nextInFlowOrFloatSibling()); 72 // Place the in- and out-of-flow positioned children.72 // Place inflow positioned children. 73 73 this._placeInFlowPositionedChildren(inlineContainer); 74 this._placeOutOfFlowDescendants(inlineContainer);75 74 } 76 75 … … 78 77 _handleInlineBlockContainer(inlineBlockContainer) { 79 78 ASSERT(inlineBlockContainer.establishesFormattingContext()); 79 let displayBox = this.displayBox(inlineBlockContainer); 80 81 // TODO: auto width/height 80 82 this._adjustLineForInlineContainerStart(inlineBlockContainer); 81 // TODO: auto width/height82 let displayBox = this.displayBox(inlineBlockContainer);83 83 displayBox.setWidth(Utils.width(inlineBlockContainer) + Utils.computedHorizontalBorderAndPadding(inlineBlockContainer.node())); 84 this.layoutState().layout(inlineBlockContainer); 84 85 displayBox.setHeight(Utils.height(inlineBlockContainer) + Utils.computedVerticalBorderAndPadding(inlineBlockContainer.node())); 85 this.layoutState().layout(inlineBlockContainer); 86 this._adjustLineForInlineContainerEnd(inlineBlockContainer); 87 86 88 this._line().addInlineContainerBox(displayBox.size()); 87 this._adjustLineForInlineContainerEnd(inlineBlockContainer);88 89 this._removeFromLayoutQueue(inlineBlockContainer); 89 90 this._addToLayoutQueue(inlineBlockContainer.nextInFlowOrFloatSibling()); … … 151 152 let offset = this.marginRight(inlineContainer) + Utils.computedBorderAndPaddingRight(inlineContainer.node()); 152 153 this._line().adjustWithOffset(offset); 153 }154 155 _placeOutOfFlowDescendants(container) {156 157 154 } 158 155 -
trunk/Tools/LayoutReloaded/test/index.html
r230469 r230484 81 81 "inline-with-padding-border-margin-offsets.html", 82 82 "inline-block-with-fixed-width-height.html", 83 "inline-with-relative-positioning.html" 83 "inline-with-relative-positioning.html", 84 "inline-with-out-of-flow-descendant.html" 84 85 ]; 85 86
Note: See TracChangeset
for help on using the changeset viewer.