Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) | 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) |
| 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) | 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) |
| 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv ed. | 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. |
| 7 * All rights reserved. | |
| 7 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. | 8 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. |
| 8 * | 9 * |
| 9 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
| 10 * modify it under the terms of the GNU Library General Public | 11 * modify it under the terms of the GNU Library General Public |
| 11 * License as published by the Free Software Foundation; either | 12 * License as published by the Free Software Foundation; either |
| 12 * version 2 of the License, or (at your option) any later version. | 13 * version 2 of the License, or (at your option) any later version. |
| 13 * | 14 * |
| 14 * This library is distributed in the hope that it will be useful, | 15 * This library is distributed in the hope that it will be useful, |
| 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 95 LayoutBox::LayoutBox(ContainerNode* node) | 96 LayoutBox::LayoutBox(ContainerNode* node) |
| 96 : LayoutBoxModelObject(node), | 97 : LayoutBoxModelObject(node), |
| 97 m_intrinsicContentLogicalHeight(-1), | 98 m_intrinsicContentLogicalHeight(-1), |
| 98 m_minPreferredLogicalWidth(-1), | 99 m_minPreferredLogicalWidth(-1), |
| 99 m_maxPreferredLogicalWidth(-1), | 100 m_maxPreferredLogicalWidth(-1), |
| 100 m_inlineBoxWrapper(nullptr) { | 101 m_inlineBoxWrapper(nullptr) { |
| 101 setIsBox(); | 102 setIsBox(); |
| 102 } | 103 } |
| 103 | 104 |
| 104 PaintLayerType LayoutBox::layerTypeRequired() const { | 105 PaintLayerType LayoutBox::layerTypeRequired() const { |
| 105 // hasAutoZIndex only returns true if the element is positioned or a flex-item since | 106 // hasAutoZIndex only returns true if the element is positioned or a flex-item |
| 106 // position:static elements that are not flex-items get their z-index coerced to auto. | 107 // since position:static elements that are not flex-items get their z-index |
| 108 // coerced to auto. | |
| 107 if (isPositioned() || createsGroup() || hasClipPath() || | 109 if (isPositioned() || createsGroup() || hasClipPath() || |
| 108 hasTransformRelatedProperty() || style()->hasCompositorProxy() || | 110 hasTransformRelatedProperty() || style()->hasCompositorProxy() || |
| 109 hasHiddenBackface() || hasReflection() || style()->specifiesColumns() || | 111 hasHiddenBackface() || hasReflection() || style()->specifiesColumns() || |
| 110 style()->isStackingContext() || | 112 style()->isStackingContext() || |
| 111 style()->shouldCompositeForCurrentAnimations()) | 113 style()->shouldCompositeForCurrentAnimations()) |
| 112 return NormalPaintLayer; | 114 return NormalPaintLayer; |
| 113 | 115 |
| 114 if (hasOverflowClip()) | 116 if (hasOverflowClip()) |
| 115 return OverflowClipPaintLayer; | 117 return OverflowClipPaintLayer; |
| 116 | 118 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 178 } | 180 } |
| 179 | 181 |
| 180 void LayoutBox::styleWillChange(StyleDifference diff, | 182 void LayoutBox::styleWillChange(StyleDifference diff, |
| 181 const ComputedStyle& newStyle) { | 183 const ComputedStyle& newStyle) { |
| 182 const ComputedStyle* oldStyle = style(); | 184 const ComputedStyle* oldStyle = style(); |
| 183 if (oldStyle) { | 185 if (oldStyle) { |
| 184 LayoutFlowThread* flowThread = flowThreadContainingBlock(); | 186 LayoutFlowThread* flowThread = flowThreadContainingBlock(); |
| 185 if (flowThread && flowThread != this) | 187 if (flowThread && flowThread != this) |
| 186 flowThread->flowThreadDescendantStyleWillChange(this, diff, newStyle); | 188 flowThread->flowThreadDescendantStyleWillChange(this, diff, newStyle); |
| 187 | 189 |
| 188 // The background of the root element or the body element could propagate up to | 190 // The background of the root element or the body element could propagate up |
| 189 // the canvas. Just dirty the entire canvas when our style changes substanti ally. | 191 // to the canvas. Just dirty the entire canvas when our style changes |
| 192 // substantially. | |
| 190 if ((diff.needsPaintInvalidation() || diff.needsLayout()) && node() && | 193 if ((diff.needsPaintInvalidation() || diff.needsLayout()) && node() && |
| 191 (isHTMLHtmlElement(*node()) || isHTMLBodyElement(*node()))) { | 194 (isHTMLHtmlElement(*node()) || isHTMLBodyElement(*node()))) { |
| 192 view()->setShouldDoFullPaintInvalidation(); | 195 view()->setShouldDoFullPaintInvalidation(); |
| 193 | 196 |
| 194 if (oldStyle->hasEntirelyFixedBackground() != | 197 if (oldStyle->hasEntirelyFixedBackground() != |
| 195 newStyle.hasEntirelyFixedBackground()) | 198 newStyle.hasEntirelyFixedBackground()) |
| 196 view()->compositor()->setNeedsUpdateFixedBackground(); | 199 view()->compositor()->setNeedsUpdateFixedBackground(); |
| 197 } | 200 } |
| 198 | 201 |
| 199 // When a layout hint happens and an object's position style changes, we hav e to do a layout | 202 // When a layout hint happens and an object's position style changes, we |
| 200 // to dirty the layout tree using the old position value now. | 203 // have to do a layout to dirty the layout tree using the old position |
| 204 // value now. | |
| 201 if (diff.needsFullLayout() && parent() && | 205 if (diff.needsFullLayout() && parent() && |
| 202 oldStyle->position() != newStyle.position()) { | 206 oldStyle->position() != newStyle.position()) { |
| 203 if (!oldStyle->hasOutOfFlowPosition() && | 207 if (!oldStyle->hasOutOfFlowPosition() && |
| 204 newStyle.hasOutOfFlowPosition()) { | 208 newStyle.hasOutOfFlowPosition()) { |
| 205 // We're about to go out of flow. Before that takes place, we need to ma rk the | 209 // We're about to go out of flow. Before that takes place, we need to |
| 206 // current containing block chain for preferred widths recalculation. | 210 // mark the current containing block chain for preferred widths |
| 211 // recalculation. | |
| 207 setNeedsLayoutAndPrefWidthsRecalc( | 212 setNeedsLayoutAndPrefWidthsRecalc( |
| 208 LayoutInvalidationReason::StyleChange); | 213 LayoutInvalidationReason::StyleChange); |
| 209 } else { | 214 } else { |
| 210 markContainerChainForLayout(); | 215 markContainerChainForLayout(); |
| 211 } | 216 } |
| 212 if (oldStyle->position() == StaticPosition) | 217 if (oldStyle->position() == StaticPosition) |
| 213 setShouldDoFullPaintInvalidation(); | 218 setShouldDoFullPaintInvalidation(); |
| 214 else if (newStyle.hasOutOfFlowPosition()) | 219 else if (newStyle.hasOutOfFlowPosition()) |
| 215 parent()->setChildNeedsLayout(); | 220 parent()->setChildNeedsLayout(); |
| 216 if (isFloating() && !isOutOfFlowPositioned() && | 221 if (isFloating() && !isOutOfFlowPositioned() && |
| 217 newStyle.hasOutOfFlowPosition()) | 222 newStyle.hasOutOfFlowPosition()) |
| 218 removeFloatingOrPositionedChildFromBlockLists(); | 223 removeFloatingOrPositionedChildFromBlockLists(); |
| 219 } | 224 } |
| 220 // FIXME: This branch runs when !oldStyle, which means that layout was never called | 225 // FIXME: This branch runs when !oldStyle, which means that layout was never |
| 221 // so what's the point in invalidating the whole view that we never painted? | 226 // called so what's the point in invalidating the whole view that we never |
| 227 // painted? | |
| 222 } else if (isBody()) { | 228 } else if (isBody()) { |
| 223 view()->setShouldDoFullPaintInvalidation(); | 229 view()->setShouldDoFullPaintInvalidation(); |
| 224 } | 230 } |
| 225 | 231 |
| 226 LayoutBoxModelObject::styleWillChange(diff, newStyle); | 232 LayoutBoxModelObject::styleWillChange(diff, newStyle); |
| 227 } | 233 } |
| 228 | 234 |
| 229 void LayoutBox::styleDidChange(StyleDifference diff, | 235 void LayoutBox::styleDidChange(StyleDifference diff, |
| 230 const ComputedStyle* oldStyle) { | 236 const ComputedStyle* oldStyle) { |
| 231 // Horizontal writing mode definition is updated in LayoutBoxModelObject::upda teFromStyle, | 237 // Horizontal writing mode definition is updated in LayoutBoxModelObject:: |
| 232 // (as part of the LayoutBoxModelObject::styleDidChange call below). So, we ca n safely cache the horizontal | 238 // updateFromStyle, (as part of the LayoutBoxModelObject::styleDidChange call |
| 233 // writing mode value before style change here. | 239 // below). So, we can safely cache the horizontal writing mode value before |
| 240 // style change here. | |
| 234 bool oldHorizontalWritingMode = isHorizontalWritingMode(); | 241 bool oldHorizontalWritingMode = isHorizontalWritingMode(); |
| 235 | 242 |
| 236 LayoutBoxModelObject::styleDidChange(diff, oldStyle); | 243 LayoutBoxModelObject::styleDidChange(diff, oldStyle); |
| 237 | 244 |
| 238 if (isFloatingOrOutOfFlowPositioned() && oldStyle && | 245 if (isFloatingOrOutOfFlowPositioned() && oldStyle && |
| 239 !oldStyle->isFloating() && !oldStyle->hasOutOfFlowPosition() && | 246 !oldStyle->isFloating() && !oldStyle->hasOutOfFlowPosition() && |
| 240 parent() && parent()->isLayoutBlockFlow()) | 247 parent() && parent()->isLayoutBlockFlow()) |
| 241 toLayoutBlockFlow(parent())->childBecameFloatingOrOutOfFlow(this); | 248 toLayoutBlockFlow(parent())->childBecameFloatingOrOutOfFlow(this); |
| 242 | 249 |
| 243 const ComputedStyle& newStyle = styleRef(); | 250 const ComputedStyle& newStyle = styleRef(); |
| 244 if (needsLayout() && oldStyle) | 251 if (needsLayout() && oldStyle) |
| 245 removeFromPercentHeightContainer(); | 252 removeFromPercentHeightContainer(); |
| 246 | 253 |
| 247 if (oldHorizontalWritingMode != isHorizontalWritingMode()) { | 254 if (oldHorizontalWritingMode != isHorizontalWritingMode()) { |
| 248 if (oldStyle) { | 255 if (oldStyle) { |
| 249 if (isOrthogonalWritingModeRoot()) | 256 if (isOrthogonalWritingModeRoot()) |
| 250 markOrthogonalWritingModeRoot(); | 257 markOrthogonalWritingModeRoot(); |
| 251 else | 258 else |
| 252 unmarkOrthogonalWritingModeRoot(); | 259 unmarkOrthogonalWritingModeRoot(); |
| 253 } | 260 } |
| 254 | 261 |
| 255 clearPercentHeightDescendants(); | 262 clearPercentHeightDescendants(); |
| 256 } | 263 } |
| 257 | 264 |
| 258 // If our zoom factor changes and we have a defined scrollLeft/Top, we need to adjust that value into the | 265 // If our zoom factor changes and we have a defined scrollLeft/Top, we need to |
| 259 // new zoomed coordinate space. | 266 // adjust that value into the new zoomed coordinate space. |
| 260 if (hasOverflowClip() && oldStyle && | 267 if (hasOverflowClip() && oldStyle && |
| 261 oldStyle->effectiveZoom() != newStyle.effectiveZoom()) { | 268 oldStyle->effectiveZoom() != newStyle.effectiveZoom()) { |
| 262 PaintLayerScrollableArea* scrollableArea = this->getScrollableArea(); | 269 PaintLayerScrollableArea* scrollableArea = this->getScrollableArea(); |
| 263 ASSERT(scrollableArea); | 270 ASSERT(scrollableArea); |
| 264 if (int left = scrollableArea->scrollXOffset()) { | 271 if (int left = scrollableArea->scrollXOffset()) { |
| 265 left = (left / oldStyle->effectiveZoom()) * newStyle.effectiveZoom(); | 272 left = (left / oldStyle->effectiveZoom()) * newStyle.effectiveZoom(); |
| 266 scrollableArea->scrollToXOffset(left); | 273 scrollableArea->scrollToXOffset(left); |
| 267 } | 274 } |
| 268 if (int top = scrollableArea->scrollYOffset()) { | 275 if (int top = scrollableArea->scrollYOffset()) { |
| 269 top = (top / oldStyle->effectiveZoom()) * newStyle.effectiveZoom(); | 276 top = (top / oldStyle->effectiveZoom()) * newStyle.effectiveZoom(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 307 updateBackgroundAttachmentFixedStatusAfterStyleChange(); | 314 updateBackgroundAttachmentFixedStatusAfterStyleChange(); |
| 308 | 315 |
| 309 if (oldStyle) { | 316 if (oldStyle) { |
| 310 LayoutFlowThread* flowThread = flowThreadContainingBlock(); | 317 LayoutFlowThread* flowThread = flowThreadContainingBlock(); |
| 311 if (flowThread && flowThread != this) | 318 if (flowThread && flowThread != this) |
| 312 flowThread->flowThreadDescendantStyleDidChange(this, diff, *oldStyle); | 319 flowThread->flowThreadDescendantStyleDidChange(this, diff, *oldStyle); |
| 313 | 320 |
| 314 updateScrollSnapMappingAfterStyleChange(&newStyle, oldStyle); | 321 updateScrollSnapMappingAfterStyleChange(&newStyle, oldStyle); |
| 315 } | 322 } |
| 316 | 323 |
| 317 ASSERT( | 324 // Non-atomic inlines should be LayoutInline or LayoutText, not LayoutBox. |
| 318 !isInline() || | 325 DCHECK(!isInline() || isAtomicInlineLevel()); |
| 319 isAtomicInlineLevel()); // Non-atomic inlines should be LayoutInline or L ayoutText, not LayoutBox. | |
| 320 } | 326 } |
| 321 | 327 |
| 322 void LayoutBox::updateBackgroundAttachmentFixedStatusAfterStyleChange() { | 328 void LayoutBox::updateBackgroundAttachmentFixedStatusAfterStyleChange() { |
| 323 if (!frameView()) | 329 if (!frameView()) |
| 324 return; | 330 return; |
| 325 | 331 |
| 326 // On low-powered/mobile devices, preventing blitting on a scroll can cause no ticeable delays | 332 // On low-powered/mobile devices, preventing blitting on a scroll can cause |
| 327 // when scrolling a page with a fixed background image. As an optimization, as suming there are | 333 // noticeable delays when scrolling a page with a fixed background image. As |
| 328 // no fixed positoned elements on the page, we can acclerate scrolling (via bl itting) if we | 334 // an optimization, assuming there are no fixed positoned elements on the |
| 329 // ignore the CSS property "background-attachment: fixed". | 335 // page, we can acclerate scrolling (via blitting) if we ignore the CSS |
| 336 // property "background-attachment: fixed". | |
| 330 bool ignoreFixedBackgroundAttachment = | 337 bool ignoreFixedBackgroundAttachment = |
| 331 RuntimeEnabledFeatures::fastMobileScrollingEnabled(); | 338 RuntimeEnabledFeatures::fastMobileScrollingEnabled(); |
| 332 if (ignoreFixedBackgroundAttachment) | 339 if (ignoreFixedBackgroundAttachment) |
| 333 return; | 340 return; |
| 334 | 341 |
| 335 // An object needs to be repainted on frame scroll when it has background-atta chment:fixed. | 342 // An object needs to be repainted on frame scroll when it has background- |
| 336 // LayoutView is responsible for painting root background, thus the root eleme nt (and the | 343 // attachment:fixed. LayoutView is responsible for painting root background, |
| 337 // body element if html element has no background) skips painting backgrounds. | 344 // thus the root element (and the body element if html element has no |
| 345 // background) skips painting backgrounds. | |
| 338 bool isBackgroundAttachmentFixedObject = !isDocumentElement() && | 346 bool isBackgroundAttachmentFixedObject = !isDocumentElement() && |
| 339 !backgroundStolenForBeingBody() && | 347 !backgroundStolenForBeingBody() && |
| 340 styleRef().hasFixedBackgroundImage(); | 348 styleRef().hasFixedBackgroundImage(); |
| 341 if (isLayoutView() && | 349 if (isLayoutView() && |
| 342 view()->compositor()->supportsFixedRootBackgroundCompositing()) { | 350 view()->compositor()->supportsFixedRootBackgroundCompositing()) { |
| 343 if (styleRef().hasEntirelyFixedBackground()) | 351 if (styleRef().hasEntirelyFixedBackground()) |
| 344 isBackgroundAttachmentFixedObject = false; | 352 isBackgroundAttachmentFixedObject = false; |
| 345 } | 353 } |
| 346 | 354 |
| 347 setIsBackgroundAttachmentFixedObject(isBackgroundAttachmentFixedObject); | 355 setIsBackgroundAttachmentFixedObject(isBackgroundAttachmentFixedObject); |
| 348 } | 356 } |
| 349 | 357 |
| 350 void LayoutBox::updateShapeOutsideInfoAfterStyleChange( | 358 void LayoutBox::updateShapeOutsideInfoAfterStyleChange( |
| 351 const ComputedStyle& style, | 359 const ComputedStyle& style, |
| 352 const ComputedStyle* oldStyle) { | 360 const ComputedStyle* oldStyle) { |
| 353 const ShapeValue* shapeOutside = style.shapeOutside(); | 361 const ShapeValue* shapeOutside = style.shapeOutside(); |
| 354 const ShapeValue* oldShapeOutside = | 362 const ShapeValue* oldShapeOutside = |
| 355 oldStyle ? oldStyle->shapeOutside() | 363 oldStyle ? oldStyle->shapeOutside() |
| 356 : ComputedStyle::initialShapeOutside(); | 364 : ComputedStyle::initialShapeOutside(); |
| 357 | 365 |
| 358 Length shapeMargin = style.shapeMargin(); | 366 Length shapeMargin = style.shapeMargin(); |
| 359 Length oldShapeMargin = | 367 Length oldShapeMargin = |
| 360 oldStyle ? oldStyle->shapeMargin() : ComputedStyle::initialShapeMargin(); | 368 oldStyle ? oldStyle->shapeMargin() : ComputedStyle::initialShapeMargin(); |
| 361 | 369 |
| 362 float shapeImageThreshold = style.shapeImageThreshold(); | 370 float shapeImageThreshold = style.shapeImageThreshold(); |
| 363 float oldShapeImageThreshold = | 371 float oldShapeImageThreshold = |
| 364 oldStyle ? oldStyle->shapeImageThreshold() | 372 oldStyle ? oldStyle->shapeImageThreshold() |
| 365 : ComputedStyle::initialShapeImageThreshold(); | 373 : ComputedStyle::initialShapeImageThreshold(); |
| 366 | 374 |
| 367 // FIXME: A future optimization would do a deep comparison for equality. (bug 100811) | 375 // FIXME: A future optimization would do a deep comparison for equality. (bug |
| 376 // 100811) | |
| 368 if (shapeOutside == oldShapeOutside && shapeMargin == oldShapeMargin && | 377 if (shapeOutside == oldShapeOutside && shapeMargin == oldShapeMargin && |
| 369 shapeImageThreshold == oldShapeImageThreshold) | 378 shapeImageThreshold == oldShapeImageThreshold) |
| 370 return; | 379 return; |
| 371 | 380 |
| 372 if (!shapeOutside) | 381 if (!shapeOutside) |
| 373 ShapeOutsideInfo::removeInfo(*this); | 382 ShapeOutsideInfo::removeInfo(*this); |
| 374 else | 383 else |
| 375 ShapeOutsideInfo::ensureInfo(*this).markShapeAsDirty(); | 384 ShapeOutsideInfo::ensureInfo(*this).markShapeAsDirty(); |
| 376 | 385 |
| 377 if (shapeOutside || shapeOutside != oldShapeOutside) | 386 if (shapeOutside || shapeOutside != oldShapeOutside) |
| 378 markShapeOutsideDependentsForLayout(); | 387 markShapeOutsideDependentsForLayout(); |
| 379 } | 388 } |
| 380 | 389 |
| 381 void LayoutBox::updateGridPositionAfterStyleChange( | 390 void LayoutBox::updateGridPositionAfterStyleChange( |
| 382 const ComputedStyle* oldStyle) { | 391 const ComputedStyle* oldStyle) { |
| 383 if (!oldStyle || !parent() || !parent()->isLayoutGrid()) | 392 if (!oldStyle || !parent() || !parent()->isLayoutGrid()) |
| 384 return; | 393 return; |
| 385 | 394 |
| 386 if (oldStyle->gridColumnStart() == style()->gridColumnStart() && | 395 if (oldStyle->gridColumnStart() == style()->gridColumnStart() && |
| 387 oldStyle->gridColumnEnd() == style()->gridColumnEnd() && | 396 oldStyle->gridColumnEnd() == style()->gridColumnEnd() && |
| 388 oldStyle->gridRowStart() == style()->gridRowStart() && | 397 oldStyle->gridRowStart() == style()->gridRowStart() && |
| 389 oldStyle->gridRowEnd() == style()->gridRowEnd() && | 398 oldStyle->gridRowEnd() == style()->gridRowEnd() && |
| 390 oldStyle->order() == style()->order() && | 399 oldStyle->order() == style()->order() && |
| 391 oldStyle->hasOutOfFlowPosition() == style()->hasOutOfFlowPosition()) | 400 oldStyle->hasOutOfFlowPosition() == style()->hasOutOfFlowPosition()) |
| 392 return; | 401 return; |
| 393 | 402 |
| 394 // It should be possible to not dirty the grid in some cases (like moving an e xplicitly placed grid item). | 403 // It should be possible to not dirty the grid in some cases (like moving an |
| 404 // explicitly placed grid item). | |
| 395 // For now, it's more simple to just always recompute the grid. | 405 // For now, it's more simple to just always recompute the grid. |
| 396 toLayoutGrid(parent())->dirtyGrid(); | 406 toLayoutGrid(parent())->dirtyGrid(); |
| 397 } | 407 } |
| 398 | 408 |
| 399 void LayoutBox::updateScrollSnapMappingAfterStyleChange( | 409 void LayoutBox::updateScrollSnapMappingAfterStyleChange( |
| 400 const ComputedStyle* newStyle, | 410 const ComputedStyle* newStyle, |
| 401 const ComputedStyle* oldStyle) { | 411 const ComputedStyle* oldStyle) { |
| 402 SnapCoordinator* snapCoordinator = document().snapCoordinator(); | 412 SnapCoordinator* snapCoordinator = document().snapCoordinator(); |
| 403 if (!snapCoordinator) | 413 if (!snapCoordinator) |
| 404 return; | 414 return; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 454 LayoutState state(*this, locationOffset()); | 464 LayoutState state(*this, locationOffset()); |
| 455 while (child) { | 465 while (child) { |
| 456 child->layoutIfNeeded(); | 466 child->layoutIfNeeded(); |
| 457 ASSERT(!child->needsLayout()); | 467 ASSERT(!child->needsLayout()); |
| 458 child = child->nextSibling(); | 468 child = child->nextSibling(); |
| 459 } | 469 } |
| 460 invalidateBackgroundObscurationStatus(); | 470 invalidateBackgroundObscurationStatus(); |
| 461 clearNeedsLayout(); | 471 clearNeedsLayout(); |
| 462 } | 472 } |
| 463 | 473 |
| 464 // More IE extensions. clientWidth and clientHeight represent the interior of a n object | 474 // More IE extensions. clientWidth and clientHeight represent the interior of |
| 465 // excluding border and scrollbar. | 475 // an object excluding border and scrollbar. |
| 466 DISABLE_CFI_PERF | 476 DISABLE_CFI_PERF |
| 467 LayoutUnit LayoutBox::clientWidth() const { | 477 LayoutUnit LayoutBox::clientWidth() const { |
| 468 return m_frameRect.width() - borderLeft() - borderRight() - | 478 return m_frameRect.width() - borderLeft() - borderRight() - |
| 469 verticalScrollbarWidth(); | 479 verticalScrollbarWidth(); |
| 470 } | 480 } |
| 471 | 481 |
| 472 DISABLE_CFI_PERF | 482 DISABLE_CFI_PERF |
| 473 LayoutUnit LayoutBox::clientHeight() const { | 483 LayoutUnit LayoutBox::clientHeight() const { |
| 474 return m_frameRect.height() - borderTop() - borderBottom() - | 484 return m_frameRect.height() - borderTop() - borderBottom() - |
| 475 horizontalScrollbarHeight(); | 485 horizontalScrollbarHeight(); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 528 int LayoutBox::pixelSnappedScrollHeight() const { | 538 int LayoutBox::pixelSnappedScrollHeight() const { |
| 529 if (hasOverflowClip()) | 539 if (hasOverflowClip()) |
| 530 return snapSizeToPixel(getScrollableArea()->scrollHeight(), | 540 return snapSizeToPixel(getScrollableArea()->scrollHeight(), |
| 531 location().y() + clientTop()); | 541 location().y() + clientTop()); |
| 532 // For objects with visible overflow, this matches IE. | 542 // For objects with visible overflow, this matches IE. |
| 533 // FIXME: Need to work right with writing modes. | 543 // FIXME: Need to work right with writing modes. |
| 534 return snapSizeToPixel(scrollHeight(), location().y() + clientTop()); | 544 return snapSizeToPixel(scrollHeight(), location().y() + clientTop()); |
| 535 } | 545 } |
| 536 | 546 |
| 537 void LayoutBox::setScrollLeft(LayoutUnit newLeft) { | 547 void LayoutBox::setScrollLeft(LayoutUnit newLeft) { |
| 538 // This doesn't hit in any tests, but since the equivalent code in setScrollTo p | 548 // This doesn't hit in any tests, but since the equivalent code in |
| 539 // does, presumably this code does as well. | 549 // setScrollTop does, presumably this code does as well. |
| 540 DisableCompositingQueryAsserts disabler; | 550 DisableCompositingQueryAsserts disabler; |
| 541 | 551 |
| 542 if (hasOverflowClip()) | 552 if (hasOverflowClip()) |
| 543 getScrollableArea()->scrollToXOffset(newLeft, ScrollOffsetClamped, | 553 getScrollableArea()->scrollToXOffset(newLeft, ScrollOffsetClamped, |
| 544 ScrollBehaviorAuto); | 554 ScrollBehaviorAuto); |
| 545 } | 555 } |
| 546 | 556 |
| 547 void LayoutBox::setScrollTop(LayoutUnit newTop) { | 557 void LayoutBox::setScrollTop(LayoutUnit newTop) { |
| 548 // Hits in compositing/overflow/do-not-assert-on-invisible-composited-layers.h tml | 558 // Hits in |
| 559 // compositing/overflow/do-not-assert-on-invisible-composited-layers.html | |
| 549 DisableCompositingQueryAsserts disabler; | 560 DisableCompositingQueryAsserts disabler; |
| 550 | 561 |
| 551 if (hasOverflowClip()) | 562 if (hasOverflowClip()) |
| 552 getScrollableArea()->scrollToYOffset(newTop, ScrollOffsetClamped, | 563 getScrollableArea()->scrollToYOffset(newTop, ScrollOffsetClamped, |
| 553 ScrollBehaviorAuto); | 564 ScrollBehaviorAuto); |
| 554 } | 565 } |
| 555 | 566 |
| 556 void LayoutBox::scrollToOffset(const DoubleSize& offset, | 567 void LayoutBox::scrollToOffset(const DoubleSize& offset, |
| 557 ScrollBehavior scrollBehavior) { | 568 ScrollBehavior scrollBehavior) { |
| 558 // This doesn't hit in any tests, but since the equivalent code in setScrollTo p | 569 // This doesn't hit in any tests, but since the equivalent code in |
| 559 // does, presumably this code does as well. | 570 // setScrollTop does, presumably this code does as well. |
| 560 DisableCompositingQueryAsserts disabler; | 571 DisableCompositingQueryAsserts disabler; |
| 561 | 572 |
| 562 if (hasOverflowClip()) | 573 if (hasOverflowClip()) |
| 563 getScrollableArea()->scrollToOffset(offset, ScrollOffsetClamped, | 574 getScrollableArea()->scrollToOffset(offset, ScrollOffsetClamped, |
| 564 scrollBehavior); | 575 scrollBehavior); |
| 565 } | 576 } |
| 566 | 577 |
| 567 // Returns true iff we are attempting an autoscroll inside an iframe with scroll ing="no". | 578 // Returns true iff we are attempting an autoscroll inside an iframe with |
| 579 // scrolling="no". | |
| 568 static bool isDisallowedAutoscroll(HTMLFrameOwnerElement* ownerElement, | 580 static bool isDisallowedAutoscroll(HTMLFrameOwnerElement* ownerElement, |
| 569 FrameView* frameView) { | 581 FrameView* frameView) { |
| 570 if (ownerElement && isHTMLFrameElementBase(*ownerElement)) { | 582 if (ownerElement && isHTMLFrameElementBase(*ownerElement)) { |
| 571 HTMLFrameElementBase* frameElementBase = | 583 HTMLFrameElementBase* frameElementBase = |
| 572 toHTMLFrameElementBase(ownerElement); | 584 toHTMLFrameElementBase(ownerElement); |
| 573 if (Page* page = frameView->frame().page()) { | 585 if (Page* page = frameView->frame().page()) { |
| 574 return page->autoscrollController().autoscrollInProgress() && | 586 return page->autoscrollController().autoscrollInProgress() && |
| 575 frameElementBase->scrollingMode() == ScrollbarAlwaysOff; | 587 frameElementBase->scrollingMode() == ScrollbarAlwaysOff; |
| 576 } | 588 } |
| 577 } | 589 } |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 596 LayoutBox* parentBox = nullptr; | 608 LayoutBox* parentBox = nullptr; |
| 597 LayoutRect newRect = rectToScroll; | 609 LayoutRect newRect = rectToScroll; |
| 598 | 610 |
| 599 bool restrictedByLineClamp = false; | 611 bool restrictedByLineClamp = false; |
| 600 if (containingBlock()) { | 612 if (containingBlock()) { |
| 601 parentBox = containingBlock(); | 613 parentBox = containingBlock(); |
| 602 restrictedByLineClamp = !containingBlock()->style()->lineClamp().isNone(); | 614 restrictedByLineClamp = !containingBlock()->style()->lineClamp().isNone(); |
| 603 } | 615 } |
| 604 | 616 |
| 605 if (hasOverflowClip() && !restrictedByLineClamp) { | 617 if (hasOverflowClip() && !restrictedByLineClamp) { |
| 606 // Don't scroll to reveal an overflow layer that is restricted by the -webki t-line-clamp property. | 618 // Don't scroll to reveal an overflow layer that is restricted by the |
| 607 // This will prevent us from revealing text hidden by the slider in Safari R SS. | 619 // -webkit-line-clamp property. This will prevent us from revealing text |
| 620 // hidden by the slider in Safari RSS. | |
| 621 // TODO(eae): We probably don't need this any more as we don't share any | |
| 622 // code with the Safari RSS reeder. | |
| 608 newRect = getScrollableArea()->scrollIntoView(rectToScroll, alignX, alignY, | 623 newRect = getScrollableArea()->scrollIntoView(rectToScroll, alignX, alignY, |
| 609 scrollType); | 624 scrollType); |
| 610 if (newRect.isEmpty()) | 625 if (newRect.isEmpty()) |
| 611 return; | 626 return; |
| 612 } else if (!parentBox && canBeProgramaticallyScrolled()) { | 627 } else if (!parentBox && canBeProgramaticallyScrolled()) { |
| 613 if (FrameView* frameView = this->frameView()) { | 628 if (FrameView* frameView = this->frameView()) { |
| 614 HTMLFrameOwnerElement* ownerElement = document().localOwner(); | 629 HTMLFrameOwnerElement* ownerElement = document().localOwner(); |
| 615 if (!isDisallowedAutoscroll(ownerElement, frameView)) { | 630 if (!isDisallowedAutoscroll(ownerElement, frameView)) { |
| 616 if (makeVisibleInVisualViewport) { | 631 if (makeVisibleInVisualViewport) { |
| 617 frameView->getScrollableArea()->scrollIntoView(rectToScroll, alignX, | 632 frameView->getScrollableArea()->scrollIntoView(rectToScroll, alignX, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 663 quads.append(localToAbsoluteQuad(FloatRect( | 678 quads.append(localToAbsoluteQuad(FloatRect( |
| 664 0, 0, m_frameRect.width().toFloat(), m_frameRect.height().toFloat()))); | 679 0, 0, m_frameRect.width().toFloat(), m_frameRect.height().toFloat()))); |
| 665 } | 680 } |
| 666 | 681 |
| 667 FloatRect LayoutBox::localBoundingBoxRectForAccessibility() const { | 682 FloatRect LayoutBox::localBoundingBoxRectForAccessibility() const { |
| 668 return FloatRect(0, 0, m_frameRect.width().toFloat(), | 683 return FloatRect(0, 0, m_frameRect.width().toFloat(), |
| 669 m_frameRect.height().toFloat()); | 684 m_frameRect.height().toFloat()); |
| 670 } | 685 } |
| 671 | 686 |
| 672 void LayoutBox::updateLayerTransformAfterLayout() { | 687 void LayoutBox::updateLayerTransformAfterLayout() { |
| 673 // Transform-origin depends on box size, so we need to update the layer transf orm after layout. | 688 // Transform-origin depends on box size, so we need to update the layer |
| 689 // transform after layout. | |
| 674 if (hasLayer()) | 690 if (hasLayer()) |
| 675 layer()->updateTransformationMatrix(); | 691 layer()->updateTransformationMatrix(); |
| 676 } | 692 } |
| 677 | 693 |
| 678 LayoutUnit LayoutBox::constrainLogicalWidthByMinMax(LayoutUnit logicalWidth, | 694 LayoutUnit LayoutBox::constrainLogicalWidthByMinMax(LayoutUnit logicalWidth, |
| 679 LayoutUnit availableWidth, | 695 LayoutUnit availableWidth, |
| 680 LayoutBlock* cb) const { | 696 LayoutBlock* cb) const { |
| 681 const ComputedStyle& styleToUse = styleRef(); | 697 const ComputedStyle& styleToUse = styleRef(); |
| 682 if (!styleToUse.logicalMaxWidth().isMaxSizeNone()) | 698 if (!styleToUse.logicalMaxWidth().isMaxSizeNone()) |
| 683 logicalWidth = | 699 logicalWidth = |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 700 logicalHeight = std::min(logicalHeight, maxH); | 716 logicalHeight = std::min(logicalHeight, maxH); |
| 701 } | 717 } |
| 702 return std::max(logicalHeight, computeLogicalHeightUsing( | 718 return std::max(logicalHeight, computeLogicalHeightUsing( |
| 703 MinSize, styleToUse.logicalMinHeight(), | 719 MinSize, styleToUse.logicalMinHeight(), |
| 704 intrinsicContentHeight)); | 720 intrinsicContentHeight)); |
| 705 } | 721 } |
| 706 | 722 |
| 707 LayoutUnit LayoutBox::constrainContentBoxLogicalHeightByMinMax( | 723 LayoutUnit LayoutBox::constrainContentBoxLogicalHeightByMinMax( |
| 708 LayoutUnit logicalHeight, | 724 LayoutUnit logicalHeight, |
| 709 LayoutUnit intrinsicContentHeight) const { | 725 LayoutUnit intrinsicContentHeight) const { |
| 710 // If the min/max height and logical height are both percentages we take advan tage of already knowing the current resolved percentage height | 726 // If the min/max height and logical height are both percentages we take |
| 727 // advantage of already knowing the current resolved percentage height | |
| 711 // to avoid recursing up through our containing blocks again to determine it. | 728 // to avoid recursing up through our containing blocks again to determine it. |
| 712 const ComputedStyle& styleToUse = styleRef(); | 729 const ComputedStyle& styleToUse = styleRef(); |
| 713 if (!styleToUse.logicalMaxHeight().isMaxSizeNone()) { | 730 if (!styleToUse.logicalMaxHeight().isMaxSizeNone()) { |
| 714 if (styleToUse.logicalMaxHeight().type() == Percent && | 731 if (styleToUse.logicalMaxHeight().type() == Percent && |
| 715 styleToUse.logicalHeight().type() == Percent) { | 732 styleToUse.logicalHeight().type() == Percent) { |
| 716 LayoutUnit availableLogicalHeight( | 733 LayoutUnit availableLogicalHeight( |
| 717 logicalHeight / styleToUse.logicalHeight().value() * 100); | 734 logicalHeight / styleToUse.logicalHeight().value() * 100); |
| 718 logicalHeight = | 735 logicalHeight = |
| 719 std::min(logicalHeight, valueForLength(styleToUse.logicalMaxHeight(), | 736 std::min(logicalHeight, valueForLength(styleToUse.logicalMaxHeight(), |
| 720 availableLogicalHeight)); | 737 availableLogicalHeight)); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 808 // If neither the image nor the color are opaque then skip this layer. | 825 // If neither the image nor the color are opaque then skip this layer. |
| 809 if (!layerKnownOpaque) | 826 if (!layerKnownOpaque) |
| 810 continue; | 827 continue; |
| 811 } | 828 } |
| 812 EFillBox currentClip = cur->clip(); | 829 EFillBox currentClip = cur->clip(); |
| 813 // Restrict clip if attachment is local. | 830 // Restrict clip if attachment is local. |
| 814 if (currentClip == BorderFillBox && | 831 if (currentClip == BorderFillBox && |
| 815 cur->attachment() == LocalBackgroundAttachment) | 832 cur->attachment() == LocalBackgroundAttachment) |
| 816 currentClip = PaddingFillBox; | 833 currentClip = PaddingFillBox; |
| 817 | 834 |
| 818 // If we're asking for the clip rect, a content-box clipped fill layer can be scrolled | 835 // If we're asking for the clip rect, a content-box clipped fill layer can |
| 819 // into the padding box of the overflow container. | 836 // be scrolled into the padding box of the overflow container. |
| 820 if (rectType == BackgroundClipRect && currentClip == ContentFillBox && | 837 if (rectType == BackgroundClipRect && currentClip == ContentFillBox && |
| 821 cur->attachment() == LocalBackgroundAttachment) { | 838 cur->attachment() == LocalBackgroundAttachment) { |
| 822 currentClip = PaddingFillBox; | 839 currentClip = PaddingFillBox; |
| 823 } | 840 } |
| 824 | 841 |
| 825 backgroundBox = enclosingFillBox(backgroundBox, currentClip); | 842 backgroundBox = enclosingFillBox(backgroundBox, currentClip); |
| 826 } while (current); | 843 } while (current); |
| 827 } | 844 } |
| 828 switch (backgroundBox) { | 845 switch (backgroundBox) { |
| 829 case BorderFillBox: | 846 case BorderFillBox: |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1050 } | 1067 } |
| 1051 | 1068 |
| 1052 void LayoutBox::middleClickAutoscroll(const IntPoint& sourcePoint) { | 1069 void LayoutBox::middleClickAutoscroll(const IntPoint& sourcePoint) { |
| 1053 LocalFrame* frame = this->frame(); | 1070 LocalFrame* frame = this->frame(); |
| 1054 if (!frame) | 1071 if (!frame) |
| 1055 return; | 1072 return; |
| 1056 | 1073 |
| 1057 IntPoint lastKnownMousePosition = | 1074 IntPoint lastKnownMousePosition = |
| 1058 frame->eventHandler().lastKnownMousePosition(); | 1075 frame->eventHandler().lastKnownMousePosition(); |
| 1059 | 1076 |
| 1060 // We need to check if the last known mouse position is out of the window. Whe n the mouse is out of the window, the position is incoherent | 1077 // We need to check if the last known mouse position is out of the window. |
| 1078 // When the mouse is out of the window, the position is incoherent | |
| 1061 static IntPoint previousMousePosition; | 1079 static IntPoint previousMousePosition; |
| 1062 if (lastKnownMousePosition.x() < 0 || lastKnownMousePosition.y() < 0) | 1080 if (lastKnownMousePosition.x() < 0 || lastKnownMousePosition.y() < 0) |
| 1063 lastKnownMousePosition = previousMousePosition; | 1081 lastKnownMousePosition = previousMousePosition; |
| 1064 else | 1082 else |
| 1065 previousMousePosition = lastKnownMousePosition; | 1083 previousMousePosition = lastKnownMousePosition; |
| 1066 | 1084 |
| 1067 IntSize delta = lastKnownMousePosition - sourcePoint; | 1085 IntSize delta = lastKnownMousePosition - sourcePoint; |
| 1068 | 1086 |
| 1069 if (abs(delta.width()) <= | 1087 if (abs(delta.width()) <= |
| 1070 AutoscrollController:: | 1088 AutoscrollController::noMiddleClickAutoscrollRadius) // at the center we |
|
ikilpatrick
2016/10/04 16:39:02
icky.
| |
| 1071 noMiddleClickAutoscrollRadius) // at the center we let the space for the icon | 1089 // let the space for |
| 1090 // the icon | |
| 1072 delta.setWidth(0); | 1091 delta.setWidth(0); |
| 1073 if (abs(delta.height()) <= | 1092 if (abs(delta.height()) <= |
| 1074 AutoscrollController::noMiddleClickAutoscrollRadius) | 1093 AutoscrollController::noMiddleClickAutoscrollRadius) |
| 1075 delta.setHeight(0); | 1094 delta.setHeight(0); |
| 1076 scroll(ScrollByPixel, FloatSize(adjustedScrollDelta(delta))); | 1095 scroll(ScrollByPixel, FloatSize(adjustedScrollDelta(delta))); |
| 1077 } | 1096 } |
| 1078 | 1097 |
| 1079 void LayoutBox::scrollByRecursively(const DoubleSize& delta, | 1098 void LayoutBox::scrollByRecursively(const DoubleSize& delta, |
| 1080 ScrollOffsetClamping clamp) { | 1099 ScrollOffsetClamping clamp) { |
| 1081 if (delta.isZero()) | 1100 if (delta.isZero()) |
| 1082 return; | 1101 return; |
| 1083 | 1102 |
| 1084 bool restrictedByLineClamp = false; | 1103 bool restrictedByLineClamp = false; |
| 1085 if (parent()) | 1104 if (parent()) |
| 1086 restrictedByLineClamp = !parent()->style()->lineClamp().isNone(); | 1105 restrictedByLineClamp = !parent()->style()->lineClamp().isNone(); |
| 1087 | 1106 |
| 1088 if (hasOverflowClip() && !restrictedByLineClamp) { | 1107 if (hasOverflowClip() && !restrictedByLineClamp) { |
| 1089 PaintLayerScrollableArea* scrollableArea = this->getScrollableArea(); | 1108 PaintLayerScrollableArea* scrollableArea = this->getScrollableArea(); |
| 1090 ASSERT(scrollableArea); | 1109 ASSERT(scrollableArea); |
| 1091 | 1110 |
| 1092 DoubleSize newScrollOffset = scrollableArea->adjustedScrollOffset() + delta; | 1111 DoubleSize newScrollOffset = scrollableArea->adjustedScrollOffset() + delta; |
| 1093 scrollableArea->scrollToOffset(newScrollOffset, clamp); | 1112 scrollableArea->scrollToOffset(newScrollOffset, clamp); |
| 1094 | 1113 |
| 1095 // If this layer can't do the scroll we ask the next layer up that can scrol l to try | 1114 // If this layer can't do the scroll we ask the next layer up that can |
| 1115 // scroll to try. | |
| 1096 DoubleSize remainingScrollOffset = | 1116 DoubleSize remainingScrollOffset = |
| 1097 newScrollOffset - scrollableArea->adjustedScrollOffset(); | 1117 newScrollOffset - scrollableArea->adjustedScrollOffset(); |
| 1098 if (!remainingScrollOffset.isZero() && parent()) { | 1118 if (!remainingScrollOffset.isZero() && parent()) { |
| 1099 if (LayoutBox* scrollableBox = enclosingScrollableBox()) | 1119 if (LayoutBox* scrollableBox = enclosingScrollableBox()) |
| 1100 scrollableBox->scrollByRecursively(remainingScrollOffset, clamp); | 1120 scrollableBox->scrollByRecursively(remainingScrollOffset, clamp); |
| 1101 | 1121 |
| 1102 LocalFrame* frame = this->frame(); | 1122 LocalFrame* frame = this->frame(); |
| 1103 if (frame && frame->page()) | 1123 if (frame && frame->page()) |
| 1104 frame->page()->autoscrollController().updateAutoscrollLayoutObject(); | 1124 frame->page()->autoscrollController().updateAutoscrollLayoutObject(); |
| 1105 } | 1125 } |
| 1106 } else if (view()->frameView()) { | 1126 } else if (view()->frameView()) { |
| 1107 // If we are here, we were called on a layoutObject that can be programmatic ally scrolled, but doesn't | 1127 // If we are here, we were called on a layoutObject that can be |
| 1108 // have an overflow clip. Which means that it is a document node that can be scrolled. | 1128 // programmatically scrolled, but doesn't have an overflow clip. Which means |
| 1129 // that it is a document node that can be scrolled. | |
| 1109 // FIXME: Pass in DoubleSize. crbug.com/414283. | 1130 // FIXME: Pass in DoubleSize. crbug.com/414283. |
| 1110 view()->frameView()->scrollBy(flooredIntSize(delta), UserScroll); | 1131 view()->frameView()->scrollBy(flooredIntSize(delta), UserScroll); |
| 1111 | 1132 |
| 1112 // FIXME: If we didn't scroll the whole way, do we want to try looking at th e frames ownerElement? | 1133 // FIXME: If we didn't scroll the whole way, do we want to try looking at |
| 1134 // the frames ownerElement? | |
| 1113 // https://bugs.webkit.org/show_bug.cgi?id=28237 | 1135 // https://bugs.webkit.org/show_bug.cgi?id=28237 |
| 1114 } | 1136 } |
| 1115 } | 1137 } |
| 1116 | 1138 |
| 1117 bool LayoutBox::needsPreferredWidthsRecalculation() const { | 1139 bool LayoutBox::needsPreferredWidthsRecalculation() const { |
| 1118 return style()->paddingStart().isPercentOrCalc() || | 1140 return style()->paddingStart().isPercentOrCalc() || |
| 1119 style()->paddingEnd().isPercentOrCalc(); | 1141 style()->paddingEnd().isPercentOrCalc(); |
| 1120 } | 1142 } |
| 1121 | 1143 |
| 1122 IntSize LayoutBox::originAdjustmentForScrollbars() const { | 1144 IntSize LayoutBox::originAdjustmentForScrollbars() const { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1162 return true; | 1184 return true; |
| 1163 | 1185 |
| 1164 if (applyOverflowClip == ApplyNonScrollOverflowClip) | 1186 if (applyOverflowClip == ApplyNonScrollOverflowClip) |
| 1165 return true; | 1187 return true; |
| 1166 | 1188 |
| 1167 if (hasOverflowClip()) { | 1189 if (hasOverflowClip()) { |
| 1168 LayoutSize offset = LayoutSize(-scrolledContentOffset()); | 1190 LayoutSize offset = LayoutSize(-scrolledContentOffset()); |
| 1169 rect.move(offset); | 1191 rect.move(offset); |
| 1170 } | 1192 } |
| 1171 | 1193 |
| 1172 // This won't work fully correctly for fixed-position elements, who should rec eive CSS clip but for whom the current object | 1194 // This won't work fully correctly for fixed-position elements, who should |
| 1173 // is not in the containing block chain. | 1195 // receive CSS clip but for whom the current object is not in the containing |
| 1196 // block chain. | |
| 1174 LayoutRect clipRect = clippingRect(); | 1197 LayoutRect clipRect = clippingRect(); |
| 1175 | 1198 |
| 1176 bool doesIntersect; | 1199 bool doesIntersect; |
| 1177 if (visualRectFlags & EdgeInclusive) { | 1200 if (visualRectFlags & EdgeInclusive) { |
| 1178 doesIntersect = rect.inclusiveIntersect(clipRect); | 1201 doesIntersect = rect.inclusiveIntersect(clipRect); |
| 1179 } else { | 1202 } else { |
| 1180 rect.intersect(clipRect); | 1203 rect.intersect(clipRect); |
| 1181 doesIntersect = !rect.isEmpty(); | 1204 doesIntersect = !rect.isEmpty(); |
| 1182 } | 1205 } |
| 1183 | 1206 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1254 LayoutUnit LayoutBox::overrideLogicalContentWidth() const { | 1277 LayoutUnit LayoutBox::overrideLogicalContentWidth() const { |
| 1255 ASSERT(hasOverrideLogicalContentWidth()); | 1278 ASSERT(hasOverrideLogicalContentWidth()); |
| 1256 return m_rareData->m_overrideLogicalContentWidth; | 1279 return m_rareData->m_overrideLogicalContentWidth; |
| 1257 } | 1280 } |
| 1258 | 1281 |
| 1259 LayoutUnit LayoutBox::overrideLogicalContentHeight() const { | 1282 LayoutUnit LayoutBox::overrideLogicalContentHeight() const { |
| 1260 ASSERT(hasOverrideLogicalContentHeight()); | 1283 ASSERT(hasOverrideLogicalContentHeight()); |
| 1261 return m_rareData->m_overrideLogicalContentHeight; | 1284 return m_rareData->m_overrideLogicalContentHeight; |
| 1262 } | 1285 } |
| 1263 | 1286 |
| 1264 // TODO (lajava) Now that we have implemented these functions based on physical direction, we'd rather remove the logical ones. | 1287 // TODO (lajava) Now that we have implemented these functions based on physical |
| 1288 // direction, we'd rather remove the logical ones. | |
| 1265 LayoutUnit LayoutBox::overrideContainingBlockContentLogicalWidth() const { | 1289 LayoutUnit LayoutBox::overrideContainingBlockContentLogicalWidth() const { |
| 1266 DCHECK(hasOverrideContainingBlockLogicalWidth()); | 1290 DCHECK(hasOverrideContainingBlockLogicalWidth()); |
| 1267 return m_rareData->m_overrideContainingBlockContentLogicalWidth; | 1291 return m_rareData->m_overrideContainingBlockContentLogicalWidth; |
| 1268 } | 1292 } |
| 1269 | 1293 |
| 1270 // TODO (lajava) Shouldn't we implement these functions based on physical direct ion ?. | 1294 // TODO (lajava) Shouldn't we implement these functions based on physical |
| 1295 // direction ?. | |
| 1271 LayoutUnit LayoutBox::overrideContainingBlockContentLogicalHeight() const { | 1296 LayoutUnit LayoutBox::overrideContainingBlockContentLogicalHeight() const { |
| 1272 DCHECK(hasOverrideContainingBlockLogicalHeight()); | 1297 DCHECK(hasOverrideContainingBlockLogicalHeight()); |
| 1273 return m_rareData->m_overrideContainingBlockContentLogicalHeight; | 1298 return m_rareData->m_overrideContainingBlockContentLogicalHeight; |
| 1274 } | 1299 } |
| 1275 | 1300 |
| 1276 // TODO (lajava) Shouldn't we implement these functions based on physical direct ion ?. | 1301 // TODO (lajava) Shouldn't we implement these functions based on physical |
| 1302 // direction ?. | |
| 1277 bool LayoutBox::hasOverrideContainingBlockLogicalWidth() const { | 1303 bool LayoutBox::hasOverrideContainingBlockLogicalWidth() const { |
| 1278 return m_rareData && | 1304 return m_rareData && |
| 1279 m_rareData->m_hasOverrideContainingBlockContentLogicalWidth; | 1305 m_rareData->m_hasOverrideContainingBlockContentLogicalWidth; |
| 1280 } | 1306 } |
| 1281 | 1307 |
| 1282 // TODO (lajava) Shouldn't we implement these functions based on physical direct ion ?. | 1308 // TODO (lajava) Shouldn't we implement these functions based on physical |
| 1309 // direction ?. | |
| 1283 bool LayoutBox::hasOverrideContainingBlockLogicalHeight() const { | 1310 bool LayoutBox::hasOverrideContainingBlockLogicalHeight() const { |
| 1284 return m_rareData && | 1311 return m_rareData && |
| 1285 m_rareData->m_hasOverrideContainingBlockContentLogicalHeight; | 1312 m_rareData->m_hasOverrideContainingBlockContentLogicalHeight; |
| 1286 } | 1313 } |
| 1287 | 1314 |
| 1288 // TODO (lajava) Shouldn't we implement these functions based on physical direct ion ?. | 1315 // TODO (lajava) Shouldn't we implement these functions based on physical |
| 1316 // direction ?. | |
| 1289 void LayoutBox::setOverrideContainingBlockContentLogicalWidth( | 1317 void LayoutBox::setOverrideContainingBlockContentLogicalWidth( |
| 1290 LayoutUnit logicalWidth) { | 1318 LayoutUnit logicalWidth) { |
| 1291 DCHECK_GE(logicalWidth, LayoutUnit(-1)); | 1319 DCHECK_GE(logicalWidth, LayoutUnit(-1)); |
| 1292 ensureRareData().m_overrideContainingBlockContentLogicalWidth = logicalWidth; | 1320 ensureRareData().m_overrideContainingBlockContentLogicalWidth = logicalWidth; |
| 1293 ensureRareData().m_hasOverrideContainingBlockContentLogicalWidth = true; | 1321 ensureRareData().m_hasOverrideContainingBlockContentLogicalWidth = true; |
| 1294 } | 1322 } |
| 1295 | 1323 |
| 1296 // TODO (lajava) Shouldn't we implement these functions based on physical direct ion ?. | 1324 // TODO (lajava) Shouldn't we implement these functions based on physical |
| 1325 // direction ?. | |
| 1297 void LayoutBox::setOverrideContainingBlockContentLogicalHeight( | 1326 void LayoutBox::setOverrideContainingBlockContentLogicalHeight( |
| 1298 LayoutUnit logicalHeight) { | 1327 LayoutUnit logicalHeight) { |
| 1299 DCHECK_GE(logicalHeight, LayoutUnit(-1)); | 1328 DCHECK_GE(logicalHeight, LayoutUnit(-1)); |
| 1300 ensureRareData().m_overrideContainingBlockContentLogicalHeight = | 1329 ensureRareData().m_overrideContainingBlockContentLogicalHeight = |
| 1301 logicalHeight; | 1330 logicalHeight; |
| 1302 ensureRareData().m_hasOverrideContainingBlockContentLogicalHeight = true; | 1331 ensureRareData().m_hasOverrideContainingBlockContentLogicalHeight = true; |
| 1303 } | 1332 } |
| 1304 | 1333 |
| 1305 // TODO (lajava) Shouldn't we implement these functions based on physical direct ion ?. | 1334 // TODO (lajava) Shouldn't we implement these functions based on physical |
| 1335 // direction ?. | |
| 1306 void LayoutBox::clearContainingBlockOverrideSize() { | 1336 void LayoutBox::clearContainingBlockOverrideSize() { |
| 1307 if (!m_rareData) | 1337 if (!m_rareData) |
| 1308 return; | 1338 return; |
| 1309 ensureRareData().m_hasOverrideContainingBlockContentLogicalWidth = false; | 1339 ensureRareData().m_hasOverrideContainingBlockContentLogicalWidth = false; |
| 1310 ensureRareData().m_hasOverrideContainingBlockContentLogicalHeight = false; | 1340 ensureRareData().m_hasOverrideContainingBlockContentLogicalHeight = false; |
| 1311 } | 1341 } |
| 1312 | 1342 |
| 1313 // TODO (lajava) Shouldn't we implement these functions based on physical direct ion ?. | 1343 // TODO (lajava) Shouldn't we implement these functions based on physical |
| 1344 // direction ?. | |
| 1314 void LayoutBox::clearOverrideContainingBlockContentLogicalHeight() { | 1345 void LayoutBox::clearOverrideContainingBlockContentLogicalHeight() { |
| 1315 if (!m_rareData) | 1346 if (!m_rareData) |
| 1316 return; | 1347 return; |
| 1317 ensureRareData().m_hasOverrideContainingBlockContentLogicalHeight = false; | 1348 ensureRareData().m_hasOverrideContainingBlockContentLogicalHeight = false; |
| 1318 } | 1349 } |
| 1319 | 1350 |
| 1320 LayoutUnit LayoutBox::extraInlineOffset() const { | 1351 LayoutUnit LayoutBox::extraInlineOffset() const { |
| 1321 return gExtraInlineOffsetMap ? gExtraInlineOffsetMap->get(this) | 1352 return gExtraInlineOffsetMap ? gExtraInlineOffsetMap->get(this) |
| 1322 : LayoutUnit(); | 1353 : LayoutUnit(); |
| 1323 } | 1354 } |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1503 return true; | 1534 return true; |
| 1504 } | 1535 } |
| 1505 | 1536 |
| 1506 if (!style()->backgroundLayers().image() || | 1537 if (!style()->backgroundLayers().image() || |
| 1507 style()->backgroundLayers().next()) { | 1538 style()->backgroundLayers().next()) { |
| 1508 paintedExtent = backgroundRect; | 1539 paintedExtent = backgroundRect; |
| 1509 return true; | 1540 return true; |
| 1510 } | 1541 } |
| 1511 | 1542 |
| 1512 BackgroundImageGeometry geometry; | 1543 BackgroundImageGeometry geometry; |
| 1513 // TODO(jchaffraix): This function should be rethought as it's called during a nd outside | 1544 // TODO(jchaffraix): This function should be rethought as it's called during |
| 1514 // of the paint phase. Potentially returning different results at different ph ases. | 1545 // and outside of the paint phase. Potentially returning different results at |
| 1546 // different phases. | |
| 1515 geometry.calculate(*this, nullptr, GlobalPaintNormalPhase, | 1547 geometry.calculate(*this, nullptr, GlobalPaintNormalPhase, |
| 1516 style()->backgroundLayers(), backgroundRect); | 1548 style()->backgroundLayers(), backgroundRect); |
| 1517 if (geometry.hasNonLocalGeometry()) | 1549 if (geometry.hasNonLocalGeometry()) |
| 1518 return false; | 1550 return false; |
| 1519 paintedExtent = LayoutRect(geometry.destRect()); | 1551 paintedExtent = LayoutRect(geometry.destRect()); |
| 1520 return true; | 1552 return true; |
| 1521 } | 1553 } |
| 1522 | 1554 |
| 1523 bool LayoutBox::backgroundIsKnownToBeOpaqueInRect( | 1555 bool LayoutBox::backgroundIsKnownToBeOpaqueInRect( |
| 1524 const LayoutRect& localRect) const { | 1556 const LayoutRect& localRect) const { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1580 continue; | 1612 continue; |
| 1581 LayoutBox* childBox = toLayoutBox(child); | 1613 LayoutBox* childBox = toLayoutBox(child); |
| 1582 if (!isCandidateForOpaquenessTest(*childBox)) | 1614 if (!isCandidateForOpaquenessTest(*childBox)) |
| 1583 continue; | 1615 continue; |
| 1584 LayoutPoint childLocation = childBox->location(); | 1616 LayoutPoint childLocation = childBox->location(); |
| 1585 if (childBox->isInFlowPositioned()) | 1617 if (childBox->isInFlowPositioned()) |
| 1586 childLocation.move(childBox->offsetForInFlowPosition()); | 1618 childLocation.move(childBox->offsetForInFlowPosition()); |
| 1587 LayoutRect childLocalRect = localRect; | 1619 LayoutRect childLocalRect = localRect; |
| 1588 childLocalRect.moveBy(-childLocation); | 1620 childLocalRect.moveBy(-childLocation); |
| 1589 if (childLocalRect.y() < 0 || childLocalRect.x() < 0) { | 1621 if (childLocalRect.y() < 0 || childLocalRect.x() < 0) { |
| 1590 // If there is unobscured area above/left of a static positioned box then the rect is probably not covered. | 1622 // If there is unobscured area above/left of a static positioned box then |
| 1623 // the rect is probably not covered. | |
| 1591 if (!childBox->isPositioned()) | 1624 if (!childBox->isPositioned()) |
| 1592 return false; | 1625 return false; |
| 1593 continue; | 1626 continue; |
| 1594 } | 1627 } |
| 1595 if (childLocalRect.maxY() > childBox->size().height() || | 1628 if (childLocalRect.maxY() > childBox->size().height() || |
| 1596 childLocalRect.maxX() > childBox->size().width()) | 1629 childLocalRect.maxX() > childBox->size().width()) |
| 1597 continue; | 1630 continue; |
| 1598 if (childBox->backgroundIsKnownToBeOpaqueInRect(childLocalRect)) | 1631 if (childBox->backgroundIsKnownToBeOpaqueInRect(childLocalRect)) |
| 1599 return true; | 1632 return true; |
| 1600 if (childBox->foregroundIsKnownToBeOpaqueInRect(childLocalRect, | 1633 if (childBox->foregroundIsKnownToBeOpaqueInRect(childLocalRect, |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 1623 return foregroundIsKnownToBeOpaqueInRect(backgroundRect, | 1656 return foregroundIsKnownToBeOpaqueInRect(backgroundRect, |
| 1624 backgroundObscurationTestMaxDepth); | 1657 backgroundObscurationTestMaxDepth); |
| 1625 } | 1658 } |
| 1626 | 1659 |
| 1627 void LayoutBox::paintMask(const PaintInfo& paintInfo, | 1660 void LayoutBox::paintMask(const PaintInfo& paintInfo, |
| 1628 const LayoutPoint& paintOffset) const { | 1661 const LayoutPoint& paintOffset) const { |
| 1629 BoxPainter(*this).paintMask(paintInfo, paintOffset); | 1662 BoxPainter(*this).paintMask(paintInfo, paintOffset); |
| 1630 } | 1663 } |
| 1631 | 1664 |
| 1632 void LayoutBox::imageChanged(WrappedImagePtr image, const IntRect*) { | 1665 void LayoutBox::imageChanged(WrappedImagePtr image, const IntRect*) { |
| 1633 // TODO(chrishtr): support PaintInvalidationDelayedFull for animated border im ages. | 1666 // TODO(chrishtr): support PaintInvalidationDelayedFull for animated border |
| 1667 // images. | |
| 1634 if ((styleRef().borderImage().image() && | 1668 if ((styleRef().borderImage().image() && |
| 1635 styleRef().borderImage().image()->data() == image) || | 1669 styleRef().borderImage().image()->data() == image) || |
| 1636 (styleRef().maskBoxImage().image() && | 1670 (styleRef().maskBoxImage().image() && |
| 1637 styleRef().maskBoxImage().image()->data() == image) || | 1671 styleRef().maskBoxImage().image()->data() == image) || |
| 1638 (styleRef().boxReflect() && styleRef().boxReflect()->mask().image() && | 1672 (styleRef().boxReflect() && styleRef().boxReflect()->mask().image() && |
| 1639 styleRef().boxReflect()->mask().image()->data() == image)) { | 1673 styleRef().boxReflect()->mask().image()->data() == image)) { |
| 1640 setShouldDoFullPaintInvalidation(); | 1674 setShouldDoFullPaintInvalidation(); |
| 1641 } else { | 1675 } else { |
| 1642 for (const FillLayer* layer = &styleRef().maskLayers(); layer; | 1676 for (const FillLayer* layer = &styleRef().maskLayers(); layer; |
| 1643 layer = layer->next()) { | 1677 layer = layer->next()) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1675 info.markShapeAsDirty(); | 1709 info.markShapeAsDirty(); |
| 1676 markShapeOutsideDependentsForLayout(); | 1710 markShapeOutsideDependentsForLayout(); |
| 1677 } | 1711 } |
| 1678 } | 1712 } |
| 1679 } | 1713 } |
| 1680 | 1714 |
| 1681 ResourcePriority LayoutBox::computeResourcePriority() const { | 1715 ResourcePriority LayoutBox::computeResourcePriority() const { |
| 1682 LayoutRect viewBounds = viewRect(); | 1716 LayoutRect viewBounds = viewRect(); |
| 1683 LayoutRect objectBounds = LayoutRect(absoluteContentBox()); | 1717 LayoutRect objectBounds = LayoutRect(absoluteContentBox()); |
| 1684 | 1718 |
| 1685 // The object bounds might be empty right now, so intersects will fail since i t doesn't deal | 1719 // The object bounds might be empty right now, so intersects will fail since |
| 1686 // with empty rects. Use LayoutRect::contains in that case. | 1720 // it doesn't deal with empty rects. Use LayoutRect::contains in that case. |
| 1687 bool isVisible; | 1721 bool isVisible; |
| 1688 if (!objectBounds.isEmpty()) | 1722 if (!objectBounds.isEmpty()) |
| 1689 isVisible = viewBounds.intersects(objectBounds); | 1723 isVisible = viewBounds.intersects(objectBounds); |
| 1690 else | 1724 else |
| 1691 isVisible = viewBounds.contains(objectBounds); | 1725 isVisible = viewBounds.contains(objectBounds); |
| 1692 | 1726 |
| 1693 LayoutRect screenRect; | 1727 LayoutRect screenRect; |
| 1694 if (!objectBounds.isEmpty()) { | 1728 if (!objectBounds.isEmpty()) { |
| 1695 screenRect = viewBounds; | 1729 screenRect = viewBounds; |
| 1696 screenRect.intersect(objectBounds); | 1730 screenRect.intersect(objectBounds); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1824 const LayoutBlockFlow* cb) const { | 1858 const LayoutBlockFlow* cb) const { |
| 1825 LayoutUnit logicalTopPosition = logicalTop(); | 1859 LayoutUnit logicalTopPosition = logicalTop(); |
| 1826 LayoutUnit startOffsetForContent = cb->startOffsetForContent(); | 1860 LayoutUnit startOffsetForContent = cb->startOffsetForContent(); |
| 1827 LayoutUnit endOffsetForContent = cb->endOffsetForContent(); | 1861 LayoutUnit endOffsetForContent = cb->endOffsetForContent(); |
| 1828 LayoutUnit logicalHeight = cb->logicalHeightForChild(*this); | 1862 LayoutUnit logicalHeight = cb->logicalHeightForChild(*this); |
| 1829 LayoutUnit startOffsetForLine = cb->startOffsetForLine( | 1863 LayoutUnit startOffsetForLine = cb->startOffsetForLine( |
| 1830 logicalTopPosition, DoNotIndentText, logicalHeight); | 1864 logicalTopPosition, DoNotIndentText, logicalHeight); |
| 1831 LayoutUnit endOffsetForLine = | 1865 LayoutUnit endOffsetForLine = |
| 1832 cb->endOffsetForLine(logicalTopPosition, DoNotIndentText, logicalHeight); | 1866 cb->endOffsetForLine(logicalTopPosition, DoNotIndentText, logicalHeight); |
| 1833 | 1867 |
| 1834 // If there aren't any floats constraining us then allow the margins to shrink /expand the width as much as they want. | 1868 // If there aren't any floats constraining us then allow the margins to |
| 1869 // shrink/expand the width as much as they want. | |
| 1835 if (startOffsetForContent == startOffsetForLine && | 1870 if (startOffsetForContent == startOffsetForLine && |
| 1836 endOffsetForContent == endOffsetForLine) | 1871 endOffsetForContent == endOffsetForLine) |
| 1837 return cb->availableLogicalWidthForLine(logicalTopPosition, DoNotIndentText, | 1872 return cb->availableLogicalWidthForLine(logicalTopPosition, DoNotIndentText, |
| 1838 logicalHeight) - | 1873 logicalHeight) - |
| 1839 childMarginStart - childMarginEnd; | 1874 childMarginStart - childMarginEnd; |
| 1840 | 1875 |
| 1841 LayoutUnit width = cb->availableLogicalWidthForLine( | 1876 LayoutUnit width = cb->availableLogicalWidthForLine( |
| 1842 logicalTopPosition, DoNotIndentText, logicalHeight) - | 1877 logicalTopPosition, DoNotIndentText, logicalHeight) - |
| 1843 std::max(LayoutUnit(), childMarginStart) - | 1878 std::max(LayoutUnit(), childMarginStart) - |
| 1844 std::max(LayoutUnit(), childMarginEnd); | 1879 std::max(LayoutUnit(), childMarginEnd); |
| 1845 // We need to see if margins on either the start side or the end side can cont ain the floats in question. If they can, | 1880 // We need to see if margins on either the start side or the end side can |
| 1846 // then just using the line width is inaccurate. In the case where a float com pletely fits, we don't need to use the line | 1881 // contain the floats in question. If they can, then just using the line width |
| 1847 // offset at all, but can instead push all the way to the content edge of the containing block. In the case where the float | 1882 // is inaccurate. In the case where a float completely fits, we don't need to |
| 1848 // doesn't fit, we can use the line offset, but we need to grow it by the marg in to reflect the fact that the margin was | 1883 // use the line offset at all, but can instead push all the way to the content |
| 1849 // "consumed" by the float. Negative margins aren't consumed by the float, and so we ignore them. | 1884 // edge of the containing block. In the case where the float doesn't fit, we |
| 1885 // can use the line offset, but we need to grow it by the margin to reflect | |
| 1886 // the fact that the margin was "consumed" by the float. Negative margins | |
| 1887 // aren't consumed by the float, and so we ignore them. | |
| 1850 width += portionOfMarginNotConsumedByFloat( | 1888 width += portionOfMarginNotConsumedByFloat( |
| 1851 childMarginStart, startOffsetForContent, startOffsetForLine); | 1889 childMarginStart, startOffsetForContent, startOffsetForLine); |
| 1852 width += portionOfMarginNotConsumedByFloat( | 1890 width += portionOfMarginNotConsumedByFloat( |
| 1853 childMarginEnd, endOffsetForContent, endOffsetForLine); | 1891 childMarginEnd, endOffsetForContent, endOffsetForLine); |
| 1854 return width; | 1892 return width; |
| 1855 } | 1893 } |
| 1856 | 1894 |
| 1857 LayoutUnit LayoutBox::containingBlockLogicalHeightForGetComputedStyle() const { | 1895 LayoutUnit LayoutBox::containingBlockLogicalHeightForGetComputedStyle() const { |
| 1858 if (hasOverrideContainingBlockLogicalHeight()) | 1896 if (hasOverrideContainingBlockLogicalHeight()) |
| 1859 return overrideContainingBlockContentLogicalHeight(); | 1897 return overrideContainingBlockContentLogicalHeight(); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1900 if (hasOverrideContainingBlockLogicalHeight()) | 1938 if (hasOverrideContainingBlockLogicalHeight()) |
| 1901 return overrideContainingBlockContentLogicalHeight(); | 1939 return overrideContainingBlockContentLogicalHeight(); |
| 1902 | 1940 |
| 1903 LayoutBlock* cb = containingBlock(); | 1941 LayoutBlock* cb = containingBlock(); |
| 1904 if (cb->hasOverrideLogicalContentHeight()) | 1942 if (cb->hasOverrideLogicalContentHeight()) |
| 1905 return cb->overrideLogicalContentHeight(); | 1943 return cb->overrideLogicalContentHeight(); |
| 1906 | 1944 |
| 1907 const ComputedStyle& containingBlockStyle = cb->styleRef(); | 1945 const ComputedStyle& containingBlockStyle = cb->styleRef(); |
| 1908 Length logicalHeightLength = containingBlockStyle.logicalHeight(); | 1946 Length logicalHeightLength = containingBlockStyle.logicalHeight(); |
| 1909 | 1947 |
| 1910 // FIXME: For now just support fixed heights. Eventually should support perce ntage heights as well. | 1948 // FIXME: For now just support fixed heights. Eventually should support |
| 1949 // percentage heights as well. | |
| 1911 if (!logicalHeightLength.isFixed()) { | 1950 if (!logicalHeightLength.isFixed()) { |
| 1912 LayoutUnit fillFallbackExtent = | 1951 LayoutUnit fillFallbackExtent = |
| 1913 LayoutUnit(containingBlockStyle.isHorizontalWritingMode() | 1952 LayoutUnit(containingBlockStyle.isHorizontalWritingMode() |
| 1914 ? view()->frameView()->visibleContentSize().height() | 1953 ? view()->frameView()->visibleContentSize().height() |
| 1915 : view()->frameView()->visibleContentSize().width()); | 1954 : view()->frameView()->visibleContentSize().width()); |
| 1916 LayoutUnit fillAvailableExtent = | 1955 LayoutUnit fillAvailableExtent = |
| 1917 containingBlock()->availableLogicalHeight(ExcludeMarginBorderPadding); | 1956 containingBlock()->availableLogicalHeight(ExcludeMarginBorderPadding); |
| 1918 if (fillAvailableExtent == -1) | 1957 if (fillAvailableExtent == -1) |
| 1919 return fillFallbackExtent; | 1958 return fillFallbackExtent; |
| 1920 return std::min(fillAvailableExtent, fillFallbackExtent); | 1959 return std::min(fillAvailableExtent, fillFallbackExtent); |
| 1921 } | 1960 } |
| 1922 | 1961 |
| 1923 // Use the content box logical height as specified by the style. | 1962 // Use the content box logical height as specified by the style. |
| 1924 return cb->adjustContentBoxLogicalHeightForBoxSizing( | 1963 return cb->adjustContentBoxLogicalHeightForBoxSizing( |
| 1925 LayoutUnit(logicalHeightLength.value())); | 1964 LayoutUnit(logicalHeightLength.value())); |
| 1926 } | 1965 } |
| 1927 | 1966 |
| 1928 void LayoutBox::mapLocalToAncestor(const LayoutBoxModelObject* ancestor, | 1967 void LayoutBox::mapLocalToAncestor(const LayoutBoxModelObject* ancestor, |
| 1929 TransformState& transformState, | 1968 TransformState& transformState, |
| 1930 MapCoordinatesFlags mode) const { | 1969 MapCoordinatesFlags mode) const { |
| 1931 bool isFixedPos = style()->position() == FixedPosition; | 1970 bool isFixedPos = style()->position() == FixedPosition; |
| 1932 | 1971 |
| 1933 // If this box has a transform or contains paint, it acts as a fixed position container for fixed descendants, | 1972 // If this box has a transform or contains paint, it acts as a fixed position |
| 1934 // and may itself also be fixed position. So propagate 'fixed' up only if this box is fixed position. | 1973 // container for fixed descendants, and may itself also be fixed position. So |
| 1974 // propagate 'fixed' up only if this box is fixed position. | |
| 1935 if (style()->canContainFixedPositionObjects() && !isFixedPos) | 1975 if (style()->canContainFixedPositionObjects() && !isFixedPos) |
| 1936 mode &= ~IsFixed; | 1976 mode &= ~IsFixed; |
| 1937 else if (isFixedPos) | 1977 else if (isFixedPos) |
| 1938 mode |= IsFixed; | 1978 mode |= IsFixed; |
| 1939 | 1979 |
| 1940 LayoutBoxModelObject::mapLocalToAncestor(ancestor, transformState, mode); | 1980 LayoutBoxModelObject::mapLocalToAncestor(ancestor, transformState, mode); |
| 1941 } | 1981 } |
| 1942 | 1982 |
| 1943 void LayoutBox::mapAncestorToLocal(const LayoutBoxModelObject* ancestor, | 1983 void LayoutBox::mapAncestorToLocal(const LayoutBoxModelObject* ancestor, |
| 1944 TransformState& transformState, | 1984 TransformState& transformState, |
| 1945 MapCoordinatesFlags mode) const { | 1985 MapCoordinatesFlags mode) const { |
| 1946 if (this == ancestor) | 1986 if (this == ancestor) |
| 1947 return; | 1987 return; |
| 1948 | 1988 |
| 1949 bool isFixedPos = style()->position() == FixedPosition; | 1989 bool isFixedPos = style()->position() == FixedPosition; |
| 1950 | 1990 |
| 1951 // If this box has a transform or contains paint, it acts as a fixed position container for fixed descendants, | 1991 // If this box has a transform or contains paint, it acts as a fixed position |
| 1952 // and may itself also be fixed position. So propagate 'fixed' up only if this box is fixed position. | 1992 // container for fixed descendants, and may itself also be fixed position. So |
| 1993 // propagate 'fixed' up only if this box is fixed position. | |
| 1953 if (style()->canContainFixedPositionObjects() && !isFixedPos) | 1994 if (style()->canContainFixedPositionObjects() && !isFixedPos) |
| 1954 mode &= ~IsFixed; | 1995 mode &= ~IsFixed; |
| 1955 else if (isFixedPos) | 1996 else if (isFixedPos) |
| 1956 mode |= IsFixed; | 1997 mode |= IsFixed; |
| 1957 | 1998 |
| 1958 LayoutBoxModelObject::mapAncestorToLocal(ancestor, transformState, mode); | 1999 LayoutBoxModelObject::mapAncestorToLocal(ancestor, transformState, mode); |
| 1959 } | 2000 } |
| 1960 | 2001 |
| 1961 LayoutSize LayoutBox::offsetFromContainer(const LayoutObject* o) const { | 2002 LayoutSize LayoutBox::offsetFromContainer(const LayoutObject* o) const { |
| 1962 ASSERT(o == container()); | 2003 ASSERT(o == container()); |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1991 } | 2032 } |
| 1992 } | 2033 } |
| 1993 } | 2034 } |
| 1994 | 2035 |
| 1995 void LayoutBox::positionLineBox(InlineBox* box) { | 2036 void LayoutBox::positionLineBox(InlineBox* box) { |
| 1996 if (isOutOfFlowPositioned()) { | 2037 if (isOutOfFlowPositioned()) { |
| 1997 // Cache the x position only if we were an INLINE type originally. | 2038 // Cache the x position only if we were an INLINE type originally. |
| 1998 bool originallyInline = style()->isOriginalDisplayInlineType(); | 2039 bool originallyInline = style()->isOriginalDisplayInlineType(); |
| 1999 if (originallyInline) { | 2040 if (originallyInline) { |
| 2000 // The value is cached in the xPos of the box. We only need this value if | 2041 // The value is cached in the xPos of the box. We only need this value if |
| 2001 // our object was inline originally, since otherwise it would have ended u p underneath | 2042 // our object was inline originally, since otherwise it would have ended |
| 2002 // the inlines. | 2043 // up underneath the inlines. |
| 2003 RootInlineBox& root = box->root(); | 2044 RootInlineBox& root = box->root(); |
| 2004 root.block().setStaticInlinePositionForChild(LineLayoutBox(this), | 2045 root.block().setStaticInlinePositionForChild(LineLayoutBox(this), |
| 2005 box->logicalLeft()); | 2046 box->logicalLeft()); |
| 2006 } else { | 2047 } else { |
| 2007 // Our object was a block originally, so we make our normal flow position be | 2048 // Our object was a block originally, so we make our normal flow position |
| 2008 // just below the line box (as though all the inlines that came before us got | 2049 // be just below the line box (as though all the inlines that came before |
| 2009 // wrapped in an anonymous block, which is what would have happened had we been | 2050 // us got wrapped in an anonymous block, which is what would have happened |
| 2010 // in flow). This value was cached in the y() of the box. | 2051 // had we been in flow). This value was cached in the y() of the box. |
| 2011 layer()->setStaticBlockPosition(box->logicalTop()); | 2052 layer()->setStaticBlockPosition(box->logicalTop()); |
| 2012 } | 2053 } |
| 2013 | 2054 |
| 2014 if (container()->isLayoutInline()) | 2055 if (container()->isLayoutInline()) |
| 2015 moveWithEdgeOfInlineContainerIfNecessary(box->isHorizontal()); | 2056 moveWithEdgeOfInlineContainerIfNecessary(box->isHorizontal()); |
| 2016 | 2057 |
| 2017 // Nuke the box. | 2058 // Nuke the box. |
| 2018 box->remove(DontMarkLineBoxes); | 2059 box->remove(DontMarkLineBoxes); |
| 2019 box->destroy(); | 2060 box->destroy(); |
| 2020 } else if (isAtomicInlineLevel()) { | 2061 } else if (isAtomicInlineLevel()) { |
| 2021 // FIXME: the call to roundedLayoutPoint() below is temporary and should be removed once | 2062 // FIXME: the call to roundedLayoutPoint() below is temporary and should be |
| 2022 // the transition to LayoutUnit-based types is complete (crbug.com/321237) | 2063 // removed once the transition to LayoutUnit-based types is complete |
| 2064 // (crbug.com/321237). | |
| 2023 setLocationAndUpdateOverflowControlsIfNeeded(box->topLeft()); | 2065 setLocationAndUpdateOverflowControlsIfNeeded(box->topLeft()); |
| 2024 setInlineBoxWrapper(box); | 2066 setInlineBoxWrapper(box); |
| 2025 } | 2067 } |
| 2026 } | 2068 } |
| 2027 | 2069 |
| 2028 void LayoutBox::moveWithEdgeOfInlineContainerIfNecessary(bool isHorizontal) { | 2070 void LayoutBox::moveWithEdgeOfInlineContainerIfNecessary(bool isHorizontal) { |
| 2029 ASSERT(isOutOfFlowPositioned() && container()->isLayoutInline() && | 2071 ASSERT(isOutOfFlowPositioned() && container()->isLayoutInline() && |
| 2030 container()->isInFlowPositioned()); | 2072 container()->isInFlowPositioned()); |
| 2031 // If this object is inside a relative positioned inline and its inline positi on is an explicit offset from the edge of its container | 2073 // If this object is inside a relative positioned inline and its inline |
| 2032 // then it will need to move if its inline container has changed width. We do not track if the width has changed | 2074 // position is an explicit offset from the edge of its container then it will |
| 2033 // but if we are here then we are laying out lines inside it, so it probably h as - mark our object for layout so that it can | 2075 // need to move if its inline container has changed width. We do not track if |
| 2076 // the width has changed but if we are here then we are laying out lines | |
| 2077 // inside it, so it probably has - mark our object for layout so that it can | |
| 2034 // move to the new offset created by the new width. | 2078 // move to the new offset created by the new width. |
| 2035 if (!normalChildNeedsLayout() && | 2079 if (!normalChildNeedsLayout() && |
| 2036 !style()->hasStaticInlinePosition(isHorizontal)) | 2080 !style()->hasStaticInlinePosition(isHorizontal)) |
| 2037 setChildNeedsLayout(MarkOnlyThis); | 2081 setChildNeedsLayout(MarkOnlyThis); |
| 2038 } | 2082 } |
| 2039 | 2083 |
| 2040 void LayoutBox::deleteLineBoxWrapper() { | 2084 void LayoutBox::deleteLineBoxWrapper() { |
| 2041 if (m_inlineBoxWrapper) { | 2085 if (m_inlineBoxWrapper) { |
| 2042 if (!documentBeingDestroyed()) | 2086 if (!documentBeingDestroyed()) |
| 2043 m_inlineBoxWrapper->remove(); | 2087 m_inlineBoxWrapper->remove(); |
| 2044 m_inlineBoxWrapper->destroy(); | 2088 m_inlineBoxWrapper->destroy(); |
| 2045 m_inlineBoxWrapper = nullptr; | 2089 m_inlineBoxWrapper = nullptr; |
| 2046 } | 2090 } |
| 2047 } | 2091 } |
| 2048 | 2092 |
| 2049 void LayoutBox::setSpannerPlaceholder( | 2093 void LayoutBox::setSpannerPlaceholder( |
| 2050 LayoutMultiColumnSpannerPlaceholder& placeholder) { | 2094 LayoutMultiColumnSpannerPlaceholder& placeholder) { |
| 2051 RELEASE_ASSERT( | 2095 RELEASE_ASSERT(!m_rareData || |
| 2052 !m_rareData || | 2096 !m_rareData->m_spannerPlaceholder); // not expected to change |
|
ikilpatrick
2016/10/04 16:39:02
more icky.
| |
| 2053 !m_rareData | 2097 // directly from one |
| 2054 ->m_spannerPlaceholder); // not expected to change directly from one spanner to another. | 2098 // spanner to another. |
| 2055 ensureRareData().m_spannerPlaceholder = &placeholder; | 2099 ensureRareData().m_spannerPlaceholder = &placeholder; |
| 2056 } | 2100 } |
| 2057 | 2101 |
| 2058 void LayoutBox::clearSpannerPlaceholder() { | 2102 void LayoutBox::clearSpannerPlaceholder() { |
| 2059 if (!m_rareData) | 2103 if (!m_rareData) |
| 2060 return; | 2104 return; |
| 2061 m_rareData->m_spannerPlaceholder = nullptr; | 2105 m_rareData->m_spannerPlaceholder = nullptr; |
| 2062 } | 2106 } |
| 2063 | 2107 |
| 2064 void LayoutBox::setPaginationStrut(LayoutUnit strut) { | 2108 void LayoutBox::setPaginationStrut(LayoutUnit strut) { |
| 2065 if (!strut && !m_rareData) | 2109 if (!strut && !m_rareData) |
| 2066 return; | 2110 return; |
| 2067 ensureRareData().m_paginationStrut = strut; | 2111 ensureRareData().m_paginationStrut = strut; |
| 2068 } | 2112 } |
| 2069 | 2113 |
| 2070 bool LayoutBox::isBreakBetweenControllable(EBreak breakValue) const { | 2114 bool LayoutBox::isBreakBetweenControllable(EBreak breakValue) const { |
| 2071 if (breakValue == BreakAuto) | 2115 if (breakValue == BreakAuto) |
| 2072 return true; | 2116 return true; |
| 2073 // We currently only support non-auto break-before and break-after values on i n-flow block | 2117 // We currently only support non-auto break-before and break-after values on |
| 2074 // level elements, which is the minimum requirement according to the spec. | 2118 // in-flow block level elements, which is the minimum requirement according to |
| 2119 // the spec. | |
| 2075 if (isInline() || isFloatingOrOutOfFlowPositioned()) | 2120 if (isInline() || isFloatingOrOutOfFlowPositioned()) |
| 2076 return false; | 2121 return false; |
| 2077 const LayoutBlock* curr = containingBlock(); | 2122 const LayoutBlock* curr = containingBlock(); |
| 2078 if (!curr || !curr->isLayoutBlockFlow()) | 2123 if (!curr || !curr->isLayoutBlockFlow()) |
| 2079 return false; | 2124 return false; |
| 2080 const LayoutView* layoutView = view(); | 2125 const LayoutView* layoutView = view(); |
| 2081 bool viewIsPaginated = layoutView->fragmentationContext(); | 2126 bool viewIsPaginated = layoutView->fragmentationContext(); |
| 2082 if (!viewIsPaginated && !flowThreadContainingBlock()) | 2127 if (!viewIsPaginated && !flowThreadContainingBlock()) |
| 2083 return false; | 2128 return false; |
| 2084 while (curr) { | 2129 while (curr) { |
| 2085 if (curr == layoutView) | 2130 if (curr == layoutView) |
| 2086 return viewIsPaginated && breakValue != BreakColumn && | 2131 return viewIsPaginated && breakValue != BreakColumn && |
| 2087 breakValue != BreakAvoidColumn; | 2132 breakValue != BreakAvoidColumn; |
| 2088 if (curr->isLayoutFlowThread()) { | 2133 if (curr->isLayoutFlowThread()) { |
| 2089 if (breakValue == | 2134 if (breakValue == |
| 2090 BreakAvoid) // Valid in any kind of fragmentation context. | 2135 BreakAvoid) // Valid in any kind of fragmentation context. |
| 2091 return true; | 2136 return true; |
| 2092 bool isMulticolValue = | 2137 bool isMulticolValue = |
| 2093 breakValue == BreakColumn || breakValue == BreakAvoidColumn; | 2138 breakValue == BreakColumn || breakValue == BreakAvoidColumn; |
| 2094 if (toLayoutFlowThread(curr)->isLayoutPagedFlowThread()) | 2139 if (toLayoutFlowThread(curr)->isLayoutPagedFlowThread()) |
| 2095 return !isMulticolValue; | 2140 return !isMulticolValue; |
| 2096 if (isMulticolValue) | 2141 if (isMulticolValue) |
| 2097 return true; | 2142 return true; |
| 2098 // If this is a flow thread for a multicol container, and we have a break value for | 2143 // If this is a flow thread for a multicol container, and we have a break |
| 2099 // paged, we need to keep looking. | 2144 // value for paged, we need to keep looking. |
| 2100 } | 2145 } |
| 2101 if (curr->isFloatingOrOutOfFlowPositioned()) | 2146 if (curr->isFloatingOrOutOfFlowPositioned()) |
| 2102 return false; | 2147 return false; |
| 2103 curr = curr->containingBlock(); | 2148 curr = curr->containingBlock(); |
| 2104 } | 2149 } |
| 2105 ASSERT_NOT_REACHED(); | 2150 ASSERT_NOT_REACHED(); |
| 2106 return false; | 2151 return false; |
| 2107 } | 2152 } |
| 2108 | 2153 |
| 2109 bool LayoutBox::isBreakInsideControllable(EBreak breakValue) const { | 2154 bool LayoutBox::isBreakInsideControllable(EBreak breakValue) const { |
| 2110 ASSERT(!isForcedFragmentainerBreakValue(breakValue)); | 2155 ASSERT(!isForcedFragmentainerBreakValue(breakValue)); |
| 2111 if (breakValue == BreakAuto) | 2156 if (breakValue == BreakAuto) |
| 2112 return true; | 2157 return true; |
| 2113 // First check multicol. | 2158 // First check multicol. |
| 2114 const LayoutFlowThread* flowThread = flowThreadContainingBlock(); | 2159 const LayoutFlowThread* flowThread = flowThreadContainingBlock(); |
| 2115 // 'avoid-column' is only valid in a multicol context. | 2160 // 'avoid-column' is only valid in a multicol context. |
| 2116 if (breakValue == BreakAvoidColumn) | 2161 if (breakValue == BreakAvoidColumn) |
| 2117 return flowThread && !flowThread->isLayoutPagedFlowThread(); | 2162 return flowThread && !flowThread->isLayoutPagedFlowThread(); |
| 2118 // 'avoid' is valid in any kind of fragmentation context. | 2163 // 'avoid' is valid in any kind of fragmentation context. |
| 2119 if (breakValue == BreakAvoid && flowThread) | 2164 if (breakValue == BreakAvoid && flowThread) |
| 2120 return true; | 2165 return true; |
| 2121 ASSERT(breakValue == BreakAvoidPage || breakValue == BreakAvoid); | 2166 ASSERT(breakValue == BreakAvoidPage || breakValue == BreakAvoid); |
| 2122 if (view()->fragmentationContext()) | 2167 if (view()->fragmentationContext()) |
| 2123 return true; // The view is paginated, probably because we're printing. | 2168 return true; // The view is paginated, probably because we're printing. |
| 2124 if (!flowThread) | 2169 if (!flowThread) |
| 2125 return false; // We're not inside any pagination context | 2170 return false; // We're not inside any pagination context |
| 2126 // We're inside a flow thread. We need to be contained by a flow thread for pa ged overflow in | 2171 // We're inside a flow thread. We need to be contained by a flow thread for |
| 2127 // order for pagination values to be valid, though. | 2172 // paged overflow in order for pagination values to be valid, though. |
| 2128 for (const LayoutBlock* ancestor = flowThread; ancestor; | 2173 for (const LayoutBlock* ancestor = flowThread; ancestor; |
| 2129 ancestor = ancestor->containingBlock()) { | 2174 ancestor = ancestor->containingBlock()) { |
| 2130 if (ancestor->isLayoutFlowThread() && | 2175 if (ancestor->isLayoutFlowThread() && |
| 2131 toLayoutFlowThread(ancestor)->isLayoutPagedFlowThread()) | 2176 toLayoutFlowThread(ancestor)->isLayoutPagedFlowThread()) |
| 2132 return true; | 2177 return true; |
| 2133 } | 2178 } |
| 2134 return false; | 2179 return false; |
| 2135 } | 2180 } |
| 2136 | 2181 |
| 2137 EBreak LayoutBox::breakAfter() const { | 2182 EBreak LayoutBox::breakAfter() const { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 2148 return BreakAuto; | 2193 return BreakAuto; |
| 2149 } | 2194 } |
| 2150 | 2195 |
| 2151 EBreak LayoutBox::breakInside() const { | 2196 EBreak LayoutBox::breakInside() const { |
| 2152 EBreak breakValue = style()->breakInside(); | 2197 EBreak breakValue = style()->breakInside(); |
| 2153 if (breakValue == BreakAuto || isBreakInsideControllable(breakValue)) | 2198 if (breakValue == BreakAuto || isBreakInsideControllable(breakValue)) |
| 2154 return breakValue; | 2199 return breakValue; |
| 2155 return BreakAuto; | 2200 return BreakAuto; |
| 2156 } | 2201 } |
| 2157 | 2202 |
| 2158 // At a class A break point [1], the break value with the highest precedence win s. If the two values | 2203 // At a class A break point [1], the break value with the highest precedence |
| 2159 // have the same precedence (e.g. "left" and "right"), the value specified on a latter object wins. | 2204 // wins. If the two values have the same precedence (e.g. "left" and "right"), |
| 2205 // the value specified on a latter object wins. | |
| 2160 // | 2206 // |
| 2161 // [1] https://drafts.csswg.org/css-break/#possible-breaks | 2207 // [1] https://drafts.csswg.org/css-break/#possible-breaks |
| 2162 static inline int fragmentainerBreakPrecedence(EBreak breakValue) { | 2208 static inline int fragmentainerBreakPrecedence(EBreak breakValue) { |
| 2163 // "auto" has the lowest priority. | 2209 // "auto" has the lowest priority. |
| 2164 // "avoid*" values win over "auto". | 2210 // "avoid*" values win over "auto". |
| 2165 // "avoid-page" wins over "avoid-column". | 2211 // "avoid-page" wins over "avoid-column". |
| 2166 // "avoid" wins over "avoid-page". | 2212 // "avoid" wins over "avoid-page". |
| 2167 // Forced break values win over "avoid". | 2213 // Forced break values win over "avoid". |
| 2168 // Any forced page break value wins over "column" forced break. | 2214 // Any forced page break value wins over "column" forced break. |
| 2169 // More specific break values (left, right, recto, verso) wins over generic "p age" values. | 2215 // More specific break values (left, right, recto, verso) wins over generic |
| 2216 // "page" values. | |
| 2170 | 2217 |
| 2171 switch (breakValue) { | 2218 switch (breakValue) { |
| 2172 default: | 2219 default: |
| 2173 ASSERT_NOT_REACHED(); | 2220 ASSERT_NOT_REACHED(); |
| 2174 // fall-through | 2221 // fall-through |
| 2175 case BreakAuto: | 2222 case BreakAuto: |
| 2176 return 0; | 2223 return 0; |
| 2177 case BreakAvoidColumn: | 2224 case BreakAvoidColumn: |
| 2178 return 1; | 2225 return 1; |
| 2179 case BreakAvoidPage: | 2226 case BreakAvoidPage: |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 2201 } | 2248 } |
| 2202 | 2249 |
| 2203 EBreak LayoutBox::classABreakPointValue(EBreak previousBreakAfterValue) const { | 2250 EBreak LayoutBox::classABreakPointValue(EBreak previousBreakAfterValue) const { |
| 2204 // First assert that we're at a class A break point. | 2251 // First assert that we're at a class A break point. |
| 2205 ASSERT(isBreakBetweenControllable(previousBreakAfterValue)); | 2252 ASSERT(isBreakBetweenControllable(previousBreakAfterValue)); |
| 2206 | 2253 |
| 2207 return joinFragmentainerBreakValues(previousBreakAfterValue, breakBefore()); | 2254 return joinFragmentainerBreakValues(previousBreakAfterValue, breakBefore()); |
| 2208 } | 2255 } |
| 2209 | 2256 |
| 2210 bool LayoutBox::needsForcedBreakBefore(EBreak previousBreakAfterValue) const { | 2257 bool LayoutBox::needsForcedBreakBefore(EBreak previousBreakAfterValue) const { |
| 2211 // Forced break values are only honored when specified on in-flow objects, but floats and | 2258 // Forced break values are only honored when specified on in-flow objects, but |
| 2212 // out-of-flow positioned objects may be affected by a break-after value of th e previous | 2259 // floats and out-of-flow positioned objects may be affected by a break-after |
| 2213 // in-flow object, even though we're not at a class A break point. | 2260 // value of the previous in-flow object, even though we're not at a class A |
| 2261 // break point. | |
| 2214 EBreak breakValue = isFloatingOrOutOfFlowPositioned() | 2262 EBreak breakValue = isFloatingOrOutOfFlowPositioned() |
| 2215 ? previousBreakAfterValue | 2263 ? previousBreakAfterValue |
| 2216 : classABreakPointValue(previousBreakAfterValue); | 2264 : classABreakPointValue(previousBreakAfterValue); |
| 2217 return isForcedFragmentainerBreakValue(breakValue); | 2265 return isForcedFragmentainerBreakValue(breakValue); |
| 2218 } | 2266 } |
| 2219 | 2267 |
| 2220 bool LayoutBox::paintedOutputOfObjectHasNoEffectRegardlessOfSize() const { | 2268 bool LayoutBox::paintedOutputOfObjectHasNoEffectRegardlessOfSize() const { |
| 2221 // In case scrollbars got repositioned (which will typically happen if the box got | 2269 // In case scrollbars got repositioned (which will typically happen if the box |
| 2222 // resized), we cannot skip invalidation. | 2270 // got resized), we cannot skip invalidation. |
| 2223 if (hasNonCompositedScrollbars()) | 2271 if (hasNonCompositedScrollbars()) |
| 2224 return false; | 2272 return false; |
| 2225 | 2273 |
| 2226 // Cannot skip paint invalidation if the box has real things to paint. | 2274 // Cannot skip paint invalidation if the box has real things to paint. |
| 2227 if (getSelectionState() != SelectionNone || hasBoxDecorationBackground() || | 2275 if (getSelectionState() != SelectionNone || hasBoxDecorationBackground() || |
| 2228 styleRef().hasBoxDecorations() || styleRef().hasVisualOverflowingEffect()) | 2276 styleRef().hasBoxDecorations() || styleRef().hasVisualOverflowingEffect()) |
| 2229 return false; | 2277 return false; |
| 2230 | 2278 |
| 2231 // If the box has clip, we need issue a paint invalidation to cover the change d part of | 2279 // If the box has clip, we need issue a paint invalidation to cover the |
| 2232 // children because of change of clip when the box got resized. In theory the children | 2280 // changed part of children because of change of clip when the box got |
| 2233 // should invalidate themselves when ancestor clip changes, but for now this i s missing | 2281 // resized. In theory the children should invalidate themselves when ancestor |
| 2234 // and ensuring it may hurt performance. | 2282 // clip changes, but for now this is missing and ensuring it may hurt |
| 2235 // TODO(wangxianzhu): Paint invalidation for clip change will be different in spv2. | 2283 // performance. |
| 2284 // TODO(wangxianzhu): Paint invalidation for clip change will be different in | |
| 2285 // spv2. | |
| 2236 if (hasClipRelatedProperty() || hasControlClip()) | 2286 if (hasClipRelatedProperty() || hasControlClip()) |
| 2237 return false; | 2287 return false; |
| 2238 | 2288 |
| 2239 return true; | 2289 return true; |
| 2240 } | 2290 } |
| 2241 | 2291 |
| 2242 LayoutRect LayoutBox::localOverflowRectForPaintInvalidation() const { | 2292 LayoutRect LayoutBox::localOverflowRectForPaintInvalidation() const { |
| 2243 if (style()->visibility() != EVisibility::Visible) | 2293 if (style()->visibility() != EVisibility::Visible) |
| 2244 return LayoutRect(); | 2294 return LayoutRect(); |
| 2245 | 2295 |
| 2246 return selfVisualOverflowRect(); | 2296 return selfVisualOverflowRect(); |
| 2247 } | 2297 } |
| 2248 | 2298 |
| 2249 void LayoutBox::inflateVisualRectForFilterUnderContainer( | 2299 void LayoutBox::inflateVisualRectForFilterUnderContainer( |
| 2250 LayoutRect& rect, | 2300 LayoutRect& rect, |
| 2251 const LayoutObject& container, | 2301 const LayoutObject& container, |
| 2252 const LayoutBoxModelObject* ancestorToStopAt) const { | 2302 const LayoutBoxModelObject* ancestorToStopAt) const { |
| 2253 // Apply visual overflow caused by reflections and filters defined on objects between this object | 2303 // Apply visual overflow caused by reflections and filters defined on objects |
| 2254 // and container (not included) or ancestorToStopAt (included). | 2304 // between this object and container (not included) or ancestorToStopAt |
| 2305 // (included). | |
| 2255 LayoutSize offsetFromContainer = this->offsetFromContainer(&container); | 2306 LayoutSize offsetFromContainer = this->offsetFromContainer(&container); |
| 2256 rect.move(offsetFromContainer); | 2307 rect.move(offsetFromContainer); |
| 2257 for (LayoutObject* parent = this->parent(); parent && parent != container; | 2308 for (LayoutObject* parent = this->parent(); parent && parent != container; |
| 2258 parent = parent->parent()) { | 2309 parent = parent->parent()) { |
| 2259 if (parent->isBox()) { | 2310 if (parent->isBox()) { |
| 2260 // Convert rect into coordinate space of parent to apply parent's reflecti on and filter. | 2311 // Convert rect into coordinate space of parent to apply parent's |
| 2312 // reflection and filter. | |
| 2261 LayoutSize parentOffset = parent->offsetFromAncestorContainer(&container); | 2313 LayoutSize parentOffset = parent->offsetFromAncestorContainer(&container); |
| 2262 rect.move(-parentOffset); | 2314 rect.move(-parentOffset); |
| 2263 toLayoutBox(parent)->inflateVisualRectForFilter(rect); | 2315 toLayoutBox(parent)->inflateVisualRectForFilter(rect); |
| 2264 rect.move(parentOffset); | 2316 rect.move(parentOffset); |
| 2265 } | 2317 } |
| 2266 if (parent == ancestorToStopAt) | 2318 if (parent == ancestorToStopAt) |
| 2267 break; | 2319 break; |
| 2268 } | 2320 } |
| 2269 rect.move(-offsetFromContainer); | 2321 rect.move(-offsetFromContainer); |
| 2270 } | 2322 } |
| 2271 | 2323 |
| 2272 bool LayoutBox::mapToVisualRectInAncestorSpace( | 2324 bool LayoutBox::mapToVisualRectInAncestorSpace( |
| 2273 const LayoutBoxModelObject* ancestor, | 2325 const LayoutBoxModelObject* ancestor, |
| 2274 LayoutRect& rect, | 2326 LayoutRect& rect, |
| 2275 VisualRectFlags visualRectFlags) const { | 2327 VisualRectFlags visualRectFlags) const { |
| 2276 inflateVisualRectForFilter(rect); | 2328 inflateVisualRectForFilter(rect); |
| 2277 | 2329 |
| 2278 if (ancestor == this) | 2330 if (ancestor == this) |
| 2279 return true; | 2331 return true; |
| 2280 | 2332 |
| 2281 bool ancestorSkipped; | 2333 bool ancestorSkipped; |
| 2282 bool filterSkipped; | 2334 bool filterSkipped; |
| 2283 LayoutObject* container = | 2335 LayoutObject* container = |
| 2284 this->container(ancestor, &ancestorSkipped, &filterSkipped); | 2336 this->container(ancestor, &ancestorSkipped, &filterSkipped); |
| 2285 LayoutBox* tableRowContainer = nullptr; | 2337 LayoutBox* tableRowContainer = nullptr; |
| 2286 // Skip table row because cells and rows are in the same coordinate space | 2338 // Skip table row because cells and rows are in the same coordinate space |
| 2287 // (see below, however for more comments about when |ancestor| is the table ro w). | 2339 // (see below, however for more comments about when |ancestor| is the table |
| 2288 // The second and third conditionals below are to skip cases where content has display: table-row or display: table-cell but is not | 2340 // row). The second and third conditionals below are to skip cases where |
| 2289 // parented like a cell/row combo. | 2341 // content has display: table-row or display: table-cell but is not parented |
| 2342 // like a cell/row combo. | |
| 2290 if (container->isTableRow() && isTableCell() && parentBox() == container) { | 2343 if (container->isTableRow() && isTableCell() && parentBox() == container) { |
| 2291 if (container != ancestor) | 2344 if (container != ancestor) |
| 2292 container = container->parent(); | 2345 container = container->parent(); |
| 2293 else | 2346 else |
| 2294 tableRowContainer = toLayoutBox(container); | 2347 tableRowContainer = toLayoutBox(container); |
| 2295 } | 2348 } |
| 2296 if (!container) | 2349 if (!container) |
| 2297 return true; | 2350 return true; |
| 2298 | 2351 |
| 2299 if (filterSkipped) | 2352 if (filterSkipped) |
| 2300 inflateVisualRectForFilterUnderContainer(rect, *container, ancestor); | 2353 inflateVisualRectForFilterUnderContainer(rect, *container, ancestor); |
| 2301 | 2354 |
| 2302 // We are now in our parent container's coordinate space. Apply our transform to obtain a bounding box | 2355 // We are now in our parent container's coordinate space. Apply our transform |
| 2303 // in the parent's coordinate space that encloses us. | 2356 // to obtain a bounding box in the parent's coordinate space that encloses us. |
| 2304 if (hasLayer() && layer()->transform()) { | 2357 if (hasLayer() && layer()->transform()) { |
| 2305 // Use enclosingIntRect because we cannot properly compute pixel snapping fo r painted elements within | 2358 // Use enclosingIntRect because we cannot properly compute pixel snapping |
| 2306 // the transform since we don't know the desired subpixel accumulation at th is point, and the transform may | 2359 // for painted elements within the transform since we don't know the desired |
| 2307 // include a scale. | 2360 // subpixel accumulation at this point, and the transform may include a |
| 2361 // scale. | |
| 2308 rect = LayoutRect(layer()->transform()->mapRect(enclosingIntRect(rect))); | 2362 rect = LayoutRect(layer()->transform()->mapRect(enclosingIntRect(rect))); |
| 2309 } | 2363 } |
| 2310 LayoutPoint topLeft = rect.location(); | 2364 LayoutPoint topLeft = rect.location(); |
| 2311 if (container->isBox()) { | 2365 if (container->isBox()) { |
| 2312 topLeft.moveBy(topLeftLocation(toLayoutBox(container))); | 2366 topLeft.moveBy(topLeftLocation(toLayoutBox(container))); |
| 2313 // If the row is the ancestor, however, add its offset back in. In effect, t his passes from the joint <td> / <tr> | 2367 // If the row is the ancestor, however, add its offset back in. In effect, |
| 2314 // coordinate space to the parent space, then back to <tr> / <td>. | 2368 // this passes from the joint <td> / <tr> coordinate space to the parent |
| 2369 // space, then back to <tr> / <td>. | |
| 2315 if (tableRowContainer) | 2370 if (tableRowContainer) |
| 2316 topLeft.moveBy( | 2371 topLeft.moveBy( |
| 2317 -tableRowContainer->topLeftLocation(toLayoutBox(container))); | 2372 -tableRowContainer->topLeftLocation(toLayoutBox(container))); |
| 2318 } else if (container->isRuby()) { | 2373 } else if (container->isRuby()) { |
| 2319 // TODO(wkorman): Generalize Ruby specialization and/or document more clearl y. | 2374 // TODO(wkorman): Generalize Ruby specialization and/or document more |
| 2320 // See the accompanying specialization in LayoutInline::mapToVisualRectInAnc estorSpace. | 2375 // clearly. See the accompanying specialization in |
| 2376 // LayoutInline::mapToVisualRectInAncestorSpace. | |
| 2321 topLeft.moveBy(topLeftLocation()); | 2377 topLeft.moveBy(topLeftLocation()); |
| 2322 } else { | 2378 } else { |
| 2323 topLeft.moveBy(location()); | 2379 topLeft.moveBy(location()); |
| 2324 } | 2380 } |
| 2325 | 2381 |
| 2326 const ComputedStyle& styleToUse = styleRef(); | 2382 const ComputedStyle& styleToUse = styleRef(); |
| 2327 EPosition position = styleToUse.position(); | 2383 EPosition position = styleToUse.position(); |
| 2328 if (position == AbsolutePosition && container->isInFlowPositioned() && | 2384 if (position == AbsolutePosition && container->isInFlowPositioned() && |
| 2329 container->isLayoutInline()) { | 2385 container->isLayoutInline()) { |
| 2330 topLeft += | 2386 topLeft += |
| 2331 toLayoutInline(container)->offsetForInFlowPositionedInline(*this); | 2387 toLayoutInline(container)->offsetForInFlowPositionedInline(*this); |
| 2332 } else if (styleToUse.hasInFlowPosition() && layer()) { | 2388 } else if (styleToUse.hasInFlowPosition() && layer()) { |
| 2333 // Apply the relative position offset when invalidating a rectangle. The la yer | 2389 // Apply the relative position offset when invalidating a rectangle. The |
| 2334 // is translated, but the layout box isn't, so we need to do this to get the | 2390 // layer is translated, but the layout box isn't, so we need to do this to |
| 2335 // right dirty rect. Since this is called from LayoutObject::setStyle, the relative position | 2391 // get the right dirty rect. Since this is called from |
| 2336 // flag on the LayoutObject has been cleared, so use the one on the style(). | 2392 // LayoutObject::setStyle, the relative position flag on the LayoutObject |
| 2393 // has been cleared, so use the one on the style(). | |
| 2337 topLeft += layer()->offsetForInFlowPosition(); | 2394 topLeft += layer()->offsetForInFlowPosition(); |
| 2338 } | 2395 } |
| 2339 | 2396 |
| 2340 // FIXME: We ignore the lightweight clipping rect that controls use, since if |o| is in mid-layout, | 2397 // FIXME: We ignore the lightweight clipping rect that controls use, since if |
| 2341 // its controlClipRect will be wrong. For overflow clip we use the values cach ed by the layer. | 2398 // |o| is in mid-layout, its controlClipRect will be wrong. For overflow clip |
| 2399 // we use the values cached by the layer. | |
| 2342 rect.setLocation(topLeft); | 2400 rect.setLocation(topLeft); |
| 2343 | 2401 |
| 2344 if (container->isBox() && | 2402 if (container->isBox() && |
| 2345 !toLayoutBox(container)->mapScrollingContentsRectToBoxSpace( | 2403 !toLayoutBox(container)->mapScrollingContentsRectToBoxSpace( |
| 2346 rect, container == ancestor ? ApplyNonScrollOverflowClip | 2404 rect, container == ancestor ? ApplyNonScrollOverflowClip |
| 2347 : ApplyOverflowClip, | 2405 : ApplyOverflowClip, |
| 2348 visualRectFlags)) | 2406 visualRectFlags)) |
| 2349 return false; | 2407 return false; |
| 2350 | 2408 |
| 2351 if (ancestorSkipped) { | 2409 if (ancestorSkipped) { |
| 2352 // If the ancestor is below the container, then we need to map the rect into ancestor's coordinates. | 2410 // If the ancestor is below the container, then we need to map the rect into |
| 2411 // ancestor's coordinates. | |
| 2353 LayoutSize containerOffset = | 2412 LayoutSize containerOffset = |
| 2354 ancestor->offsetFromAncestorContainer(container); | 2413 ancestor->offsetFromAncestorContainer(container); |
| 2355 rect.move(-containerOffset); | 2414 rect.move(-containerOffset); |
| 2356 // If the ancestor is fixed, then the rect is already in its coordinates so doesn't need viewport-adjusting. | 2415 // If the ancestor is fixed, then the rect is already in its coordinates so |
| 2416 // doesn't need viewport-adjusting. | |
| 2357 if (ancestor->style()->position() != FixedPosition && | 2417 if (ancestor->style()->position() != FixedPosition && |
| 2358 container->isLayoutView() && position == FixedPosition) | 2418 container->isLayoutView() && position == FixedPosition) |
| 2359 toLayoutView(container)->adjustOffsetForFixedPosition(rect); | 2419 toLayoutView(container)->adjustOffsetForFixedPosition(rect); |
| 2360 return true; | 2420 return true; |
| 2361 } | 2421 } |
| 2362 | 2422 |
| 2363 if (container->isLayoutView()) | 2423 if (container->isLayoutView()) |
| 2364 return toLayoutView(container)->mapToVisualRectInAncestorSpace( | 2424 return toLayoutView(container)->mapToVisualRectInAncestorSpace( |
| 2365 ancestor, rect, position == FixedPosition ? IsFixed : 0, | 2425 ancestor, rect, position == FixedPosition ? IsFixed : 0, |
| 2366 visualRectFlags); | 2426 visualRectFlags); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2440 computedValues.m_extent = | 2500 computedValues.m_extent = |
| 2441 overrideLogicalContentWidth() + borderAndPaddingLogicalWidth(); | 2501 overrideLogicalContentWidth() + borderAndPaddingLogicalWidth(); |
| 2442 return; | 2502 return; |
| 2443 } | 2503 } |
| 2444 | 2504 |
| 2445 // FIXME: Account for writing-mode in flexible boxes. | 2505 // FIXME: Account for writing-mode in flexible boxes. |
| 2446 // https://bugs.webkit.org/show_bug.cgi?id=46418 | 2506 // https://bugs.webkit.org/show_bug.cgi?id=46418 |
| 2447 bool inVerticalBox = parent()->isDeprecatedFlexibleBox() && | 2507 bool inVerticalBox = parent()->isDeprecatedFlexibleBox() && |
| 2448 (parent()->style()->boxOrient() == VERTICAL); | 2508 (parent()->style()->boxOrient() == VERTICAL); |
| 2449 bool stretching = (parent()->style()->boxAlign() == BSTRETCH); | 2509 bool stretching = (parent()->style()->boxAlign() == BSTRETCH); |
| 2450 // TODO (lajava): Stretching is the only reason why we don't want the box to b e treated as a replaced element, so we could perhaps | 2510 // TODO (lajava): Stretching is the only reason why we don't want the box to |
| 2451 // refactor all this logic, not only for flex and grid since alignment is inte nded to be applied to any block. | 2511 // be treated as a replaced element, so we could perhaps refactor all this |
| 2512 // logic, not only for flex and grid since alignment is intended to be applied | |
| 2513 // to any block. | |
| 2452 bool treatAsReplaced = shouldComputeSizeAsReplaced() && | 2514 bool treatAsReplaced = shouldComputeSizeAsReplaced() && |
| 2453 (!inVerticalBox || !stretching) && | 2515 (!inVerticalBox || !stretching) && |
| 2454 (!isGridItem() || !hasStretchedLogicalWidth()); | 2516 (!isGridItem() || !hasStretchedLogicalWidth()); |
| 2455 const ComputedStyle& styleToUse = styleRef(); | 2517 const ComputedStyle& styleToUse = styleRef(); |
| 2456 Length logicalWidthLength = treatAsReplaced | 2518 Length logicalWidthLength = treatAsReplaced |
| 2457 ? Length(computeReplacedLogicalWidth(), Fixed) | 2519 ? Length(computeReplacedLogicalWidth(), Fixed) |
| 2458 : styleToUse.logicalWidth(); | 2520 : styleToUse.logicalWidth(); |
| 2459 | 2521 |
| 2460 LayoutBlock* cb = containingBlock(); | 2522 LayoutBlock* cb = containingBlock(); |
| 2461 LayoutUnit containerLogicalWidth = | 2523 LayoutUnit containerLogicalWidth = |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2522 computedValues.m_margins.m_start = newMargin; | 2584 computedValues.m_margins.m_start = newMargin; |
| 2523 else | 2585 else |
| 2524 computedValues.m_margins.m_end = newMargin; | 2586 computedValues.m_margins.m_end = newMargin; |
| 2525 } | 2587 } |
| 2526 | 2588 |
| 2527 if (styleToUse.textAutosizingMultiplier() != 1 && | 2589 if (styleToUse.textAutosizingMultiplier() != 1 && |
| 2528 styleToUse.marginStart().type() == Fixed) { | 2590 styleToUse.marginStart().type() == Fixed) { |
| 2529 Node* parentNode = generatingNode(); | 2591 Node* parentNode = generatingNode(); |
| 2530 if (parentNode && | 2592 if (parentNode && |
| 2531 (isHTMLOListElement(*parentNode) || isHTMLUListElement(*parentNode))) { | 2593 (isHTMLOListElement(*parentNode) || isHTMLUListElement(*parentNode))) { |
| 2532 // Make sure the markers in a list are properly positioned (i.e. not chopp ed off) when autosized. | 2594 // Make sure the markers in a list are properly positioned (i.e. not |
| 2595 // chopped off) when autosized. | |
| 2533 const float adjustedMargin = | 2596 const float adjustedMargin = |
| 2534 (1 - 1.0 / styleToUse.textAutosizingMultiplier()) * | 2597 (1 - 1.0 / styleToUse.textAutosizingMultiplier()) * |
| 2535 getMaxWidthListMarker(this); | 2598 getMaxWidthListMarker(this); |
| 2536 bool hasInvertedDirection = cb->style()->isLeftToRightDirection() != | 2599 bool hasInvertedDirection = cb->style()->isLeftToRightDirection() != |
| 2537 style()->isLeftToRightDirection(); | 2600 style()->isLeftToRightDirection(); |
| 2538 if (hasInvertedDirection) | 2601 if (hasInvertedDirection) |
| 2539 computedValues.m_margins.m_end += adjustedMargin; | 2602 computedValues.m_margins.m_end += adjustedMargin; |
| 2540 else | 2603 else |
| 2541 computedValues.m_margins.m_start += adjustedMargin; | 2604 computedValues.m_margins.m_start += adjustedMargin; |
| 2542 } | 2605 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2598 LayoutUnit LayoutBox::computeLogicalWidthUsing(SizeType widthType, | 2661 LayoutUnit LayoutBox::computeLogicalWidthUsing(SizeType widthType, |
| 2599 const Length& logicalWidth, | 2662 const Length& logicalWidth, |
| 2600 LayoutUnit availableLogicalWidth, | 2663 LayoutUnit availableLogicalWidth, |
| 2601 const LayoutBlock* cb) const { | 2664 const LayoutBlock* cb) const { |
| 2602 ASSERT(widthType == MinSize || widthType == MainOrPreferredSize || | 2665 ASSERT(widthType == MinSize || widthType == MainOrPreferredSize || |
| 2603 !logicalWidth.isAuto()); | 2666 !logicalWidth.isAuto()); |
| 2604 if (widthType == MinSize && logicalWidth.isAuto()) | 2667 if (widthType == MinSize && logicalWidth.isAuto()) |
| 2605 return adjustBorderBoxLogicalWidthForBoxSizing(0); | 2668 return adjustBorderBoxLogicalWidthForBoxSizing(0); |
| 2606 | 2669 |
| 2607 if (!logicalWidth.isIntrinsicOrAuto()) { | 2670 if (!logicalWidth.isIntrinsicOrAuto()) { |
| 2608 // FIXME: If the containing block flow is perpendicular to our direction we need to use the available logical height instead. | 2671 // FIXME: If the containing block flow is perpendicular to our direction we |
| 2672 // need to use the available logical height instead. | |
| 2609 return adjustBorderBoxLogicalWidthForBoxSizing( | 2673 return adjustBorderBoxLogicalWidthForBoxSizing( |
| 2610 valueForLength(logicalWidth, availableLogicalWidth)); | 2674 valueForLength(logicalWidth, availableLogicalWidth)); |
| 2611 } | 2675 } |
| 2612 | 2676 |
| 2613 if (logicalWidth.isIntrinsic()) | 2677 if (logicalWidth.isIntrinsic()) |
| 2614 return computeIntrinsicLogicalWidthUsing( | 2678 return computeIntrinsicLogicalWidthUsing( |
| 2615 logicalWidth, availableLogicalWidth, borderAndPaddingLogicalWidth()); | 2679 logicalWidth, availableLogicalWidth, borderAndPaddingLogicalWidth()); |
| 2616 | 2680 |
| 2617 LayoutUnit marginStart; | 2681 LayoutUnit marginStart; |
| 2618 LayoutUnit marginEnd; | 2682 LayoutUnit marginEnd; |
| 2619 LayoutUnit logicalWidthResult = | 2683 LayoutUnit logicalWidthResult = |
| 2620 fillAvailableMeasure(availableLogicalWidth, marginStart, marginEnd); | 2684 fillAvailableMeasure(availableLogicalWidth, marginStart, marginEnd); |
| 2621 | 2685 |
| 2622 if (shrinkToAvoidFloats() && cb->isLayoutBlockFlow() && | 2686 if (shrinkToAvoidFloats() && cb->isLayoutBlockFlow() && |
| 2623 toLayoutBlockFlow(cb)->containsFloats()) | 2687 toLayoutBlockFlow(cb)->containsFloats()) |
| 2624 logicalWidthResult = std::min( | 2688 logicalWidthResult = std::min( |
| 2625 logicalWidthResult, shrinkLogicalWidthToAvoidFloats( | 2689 logicalWidthResult, shrinkLogicalWidthToAvoidFloats( |
| 2626 marginStart, marginEnd, toLayoutBlockFlow(cb))); | 2690 marginStart, marginEnd, toLayoutBlockFlow(cb))); |
| 2627 | 2691 |
| 2628 if (widthType == MainOrPreferredSize && | 2692 if (widthType == MainOrPreferredSize && |
| 2629 sizesLogicalWidthToFitContent(logicalWidth)) | 2693 sizesLogicalWidthToFitContent(logicalWidth)) |
| 2630 return std::max(minPreferredLogicalWidth(), | 2694 return std::max(minPreferredLogicalWidth(), |
| 2631 std::min(maxPreferredLogicalWidth(), logicalWidthResult)); | 2695 std::min(maxPreferredLogicalWidth(), logicalWidthResult)); |
| 2632 return logicalWidthResult; | 2696 return logicalWidthResult; |
| 2633 } | 2697 } |
| 2634 | 2698 |
| 2635 bool LayoutBox::columnFlexItemHasStretchAlignment() const { | 2699 bool LayoutBox::columnFlexItemHasStretchAlignment() const { |
| 2636 // auto margins mean we don't stretch. Note that this function will only be us ed for | 2700 // auto margins mean we don't stretch. Note that this function will only be |
| 2637 // widths, so we don't have to check marginBefore/marginAfter. | 2701 // used for widths, so we don't have to check marginBefore/marginAfter. |
| 2638 const auto& parentStyle = parent()->styleRef(); | 2702 const auto& parentStyle = parent()->styleRef(); |
| 2639 DCHECK(parentStyle.isColumnFlexDirection()); | 2703 DCHECK(parentStyle.isColumnFlexDirection()); |
| 2640 if (styleRef().marginStart().isAuto() || styleRef().marginEnd().isAuto()) | 2704 if (styleRef().marginStart().isAuto() || styleRef().marginEnd().isAuto()) |
| 2641 return false; | 2705 return false; |
| 2642 return styleRef() | 2706 return styleRef() |
| 2643 .resolvedAlignSelf( | 2707 .resolvedAlignSelf( |
| 2644 containingBlock()->selfAlignmentNormalBehavior(), | 2708 containingBlock()->selfAlignmentNormalBehavior(), |
| 2645 isAnonymous() ? &parentStyle : nullptr) | 2709 isAnonymous() ? &parentStyle : nullptr) |
| 2646 .position() == ItemPositionStretch; | 2710 .position() == ItemPositionStretch; |
| 2647 } | 2711 } |
| 2648 | 2712 |
| 2649 bool LayoutBox::isStretchingColumnFlexItem() const { | 2713 bool LayoutBox::isStretchingColumnFlexItem() const { |
| 2650 LayoutObject* parent = this->parent(); | 2714 LayoutObject* parent = this->parent(); |
| 2651 if (parent->isDeprecatedFlexibleBox() && | 2715 if (parent->isDeprecatedFlexibleBox() && |
| 2652 parent->style()->boxOrient() == VERTICAL && | 2716 parent->style()->boxOrient() == VERTICAL && |
| 2653 parent->style()->boxAlign() == BSTRETCH) | 2717 parent->style()->boxAlign() == BSTRETCH) |
| 2654 return true; | 2718 return true; |
| 2655 | 2719 |
| 2656 // We don't stretch multiline flexboxes because they need to apply line spacin g (align-content) first. | 2720 // We don't stretch multiline flexboxes because they need to apply line |
| 2721 // spacing (align-content) first. | |
| 2657 if (parent->isFlexibleBox() && parent->style()->flexWrap() == FlexNoWrap && | 2722 if (parent->isFlexibleBox() && parent->style()->flexWrap() == FlexNoWrap && |
| 2658 parent->style()->isColumnFlexDirection() && | 2723 parent->style()->isColumnFlexDirection() && |
| 2659 columnFlexItemHasStretchAlignment()) | 2724 columnFlexItemHasStretchAlignment()) |
| 2660 return true; | 2725 return true; |
| 2661 return false; | 2726 return false; |
| 2662 } | 2727 } |
| 2663 | 2728 |
| 2664 // TODO (lajava) Can/Should we move this inside specific layout classes (flex. g rid)? Can we refactor columnFlexItemHasStretchAlignment logic? | 2729 // TODO (lajava) Can/Should we move this inside specific layout classes (flex. |
| 2730 // grid)? Can we refactor columnFlexItemHasStretchAlignment logic? | |
| 2665 bool LayoutBox::hasStretchedLogicalWidth() const { | 2731 bool LayoutBox::hasStretchedLogicalWidth() const { |
| 2666 const ComputedStyle& style = styleRef(); | 2732 const ComputedStyle& style = styleRef(); |
| 2667 if (!style.logicalWidth().isAuto() || style.marginStart().isAuto() || | 2733 if (!style.logicalWidth().isAuto() || style.marginStart().isAuto() || |
| 2668 style.marginEnd().isAuto()) | 2734 style.marginEnd().isAuto()) |
| 2669 return false; | 2735 return false; |
| 2670 LayoutBlock* cb = containingBlock(); | 2736 LayoutBlock* cb = containingBlock(); |
| 2671 if (!cb) { | 2737 if (!cb) { |
| 2672 // We are evaluating align-self/justify-self, which default to 'normal' for the root element. | 2738 // We are evaluating align-self/justify-self, which default to 'normal' for |
| 2673 // The 'normal' value behaves like 'start' except for Flexbox Items, which o bviously should have a container. | 2739 // the root element. The 'normal' value behaves like 'start' except for |
| 2740 // Flexbox Items, which obviously should have a container. | |
| 2674 return false; | 2741 return false; |
| 2675 } | 2742 } |
| 2676 const ComputedStyle* parentStyle = isAnonymous() ? cb->style() : nullptr; | 2743 const ComputedStyle* parentStyle = isAnonymous() ? cb->style() : nullptr; |
| 2677 if (cb->isHorizontalWritingMode() != isHorizontalWritingMode()) | 2744 if (cb->isHorizontalWritingMode() != isHorizontalWritingMode()) |
| 2678 return style | 2745 return style |
| 2679 .resolvedAlignSelf(cb->selfAlignmentNormalBehavior(), | 2746 .resolvedAlignSelf(cb->selfAlignmentNormalBehavior(), |
| 2680 parentStyle) | 2747 parentStyle) |
| 2681 .position() == ItemPositionStretch; | 2748 .position() == ItemPositionStretch; |
| 2682 return style | 2749 return style |
| 2683 .resolvedJustifySelf(cb->selfAlignmentNormalBehavior(), | 2750 .resolvedJustifySelf(cb->selfAlignmentNormalBehavior(), |
| 2684 parentStyle) | 2751 parentStyle) |
| 2685 .position() == ItemPositionStretch; | 2752 .position() == ItemPositionStretch; |
| 2686 } | 2753 } |
| 2687 | 2754 |
| 2688 bool LayoutBox::sizesLogicalWidthToFitContent( | 2755 bool LayoutBox::sizesLogicalWidthToFitContent( |
| 2689 const Length& logicalWidth) const { | 2756 const Length& logicalWidth) const { |
| 2690 if (isFloating() || isInlineBlockOrInlineTable()) | 2757 if (isFloating() || isInlineBlockOrInlineTable()) |
| 2691 return true; | 2758 return true; |
| 2692 | 2759 |
| 2693 if (isGridItem()) | 2760 if (isGridItem()) |
| 2694 return !hasStretchedLogicalWidth(); | 2761 return !hasStretchedLogicalWidth(); |
| 2695 | 2762 |
| 2696 // Flexible box items should shrink wrap, so we lay them out at their intrinsi c widths. | 2763 // Flexible box items should shrink wrap, so we lay them out at their |
| 2697 // In the case of columns that have a stretch alignment, we go ahead and layou t at the | 2764 // intrinsic widths. In the case of columns that have a stretch alignment, we |
| 2698 // stretched size to avoid an extra layout when applying alignment. | 2765 // go ahead and layout at the stretched size to avoid an extra layout when |
| 2766 // applying alignment. | |
| 2699 if (parent()->isFlexibleBox()) { | 2767 if (parent()->isFlexibleBox()) { |
| 2700 // For multiline columns, we need to apply align-content first, so we can't stretch now. | 2768 // For multiline columns, we need to apply align-content first, so we can't |
| 2769 // stretch now. | |
| 2701 if (!parent()->style()->isColumnFlexDirection() || | 2770 if (!parent()->style()->isColumnFlexDirection() || |
| 2702 parent()->style()->flexWrap() != FlexNoWrap) | 2771 parent()->style()->flexWrap() != FlexNoWrap) |
| 2703 return true; | 2772 return true; |
| 2704 if (!columnFlexItemHasStretchAlignment()) | 2773 if (!columnFlexItemHasStretchAlignment()) |
| 2705 return true; | 2774 return true; |
| 2706 } | 2775 } |
| 2707 | 2776 |
| 2708 // Flexible horizontal boxes lay out children at their intrinsic widths. Also vertical boxes | 2777 // Flexible horizontal boxes lay out children at their intrinsic widths. Also |
| 2709 // that don't stretch their kids lay out their children at their intrinsic wid ths. | 2778 // vertical boxes that don't stretch their kids lay out their children at |
| 2779 // their intrinsic widths. | |
| 2710 // FIXME: Think about writing-mode here. | 2780 // FIXME: Think about writing-mode here. |
| 2711 // https://bugs.webkit.org/show_bug.cgi?id=46473 | 2781 // https://bugs.webkit.org/show_bug.cgi?id=46473 |
| 2712 if (parent()->isDeprecatedFlexibleBox() && | 2782 if (parent()->isDeprecatedFlexibleBox() && |
| 2713 (parent()->style()->boxOrient() == HORIZONTAL || | 2783 (parent()->style()->boxOrient() == HORIZONTAL || |
| 2714 parent()->style()->boxAlign() != BSTRETCH)) | 2784 parent()->style()->boxAlign() != BSTRETCH)) |
| 2715 return true; | 2785 return true; |
| 2716 | 2786 |
| 2717 // Button, input, select, textarea, and legend treat width value of 'auto' as 'intrinsic' unless it's in a | 2787 // Button, input, select, textarea, and legend treat width value of 'auto' as |
| 2718 // stretching column flexbox. | 2788 // 'intrinsic' unless it's in a stretching column flexbox. |
| 2719 // FIXME: Think about writing-mode here. | 2789 // FIXME: Think about writing-mode here. |
| 2720 // https://bugs.webkit.org/show_bug.cgi?id=46473 | 2790 // https://bugs.webkit.org/show_bug.cgi?id=46473 |
| 2721 if (logicalWidth.isAuto() && !isStretchingColumnFlexItem() && | 2791 if (logicalWidth.isAuto() && !isStretchingColumnFlexItem() && |
| 2722 autoWidthShouldFitContent()) | 2792 autoWidthShouldFitContent()) |
| 2723 return true; | 2793 return true; |
| 2724 | 2794 |
| 2725 if (isHorizontalWritingMode() != containingBlock()->isHorizontalWritingMode()) | 2795 if (isHorizontalWritingMode() != containingBlock()->isHorizontalWritingMode()) |
| 2726 return true; | 2796 return true; |
| 2727 | 2797 |
| 2728 return false; | 2798 return false; |
| 2729 } | 2799 } |
| 2730 | 2800 |
| 2731 bool LayoutBox::autoWidthShouldFitContent() const { | 2801 bool LayoutBox::autoWidthShouldFitContent() const { |
| 2732 return node() && | 2802 return node() && |
| 2733 (isHTMLInputElement(*node()) || isHTMLSelectElement(*node()) || | 2803 (isHTMLInputElement(*node()) || isHTMLSelectElement(*node()) || |
| 2734 isHTMLButtonElement(*node()) || isHTMLTextAreaElement(*node()) || | 2804 isHTMLButtonElement(*node()) || isHTMLTextAreaElement(*node()) || |
| 2735 (isHTMLLegendElement(*node()) && !style()->hasOutOfFlowPosition())); | 2805 (isHTMLLegendElement(*node()) && !style()->hasOutOfFlowPosition())); |
| 2736 } | 2806 } |
| 2737 | 2807 |
| 2738 void LayoutBox::computeMarginsForDirection(MarginDirection flowDirection, | 2808 void LayoutBox::computeMarginsForDirection(MarginDirection flowDirection, |
| 2739 const LayoutBlock* containingBlock, | 2809 const LayoutBlock* containingBlock, |
| 2740 LayoutUnit containerWidth, | 2810 LayoutUnit containerWidth, |
| 2741 LayoutUnit childWidth, | 2811 LayoutUnit childWidth, |
| 2742 LayoutUnit& marginStart, | 2812 LayoutUnit& marginStart, |
| 2743 LayoutUnit& marginEnd, | 2813 LayoutUnit& marginEnd, |
| 2744 Length marginStartLength, | 2814 Length marginStartLength, |
| 2745 Length marginEndLength) const { | 2815 Length marginEndLength) const { |
| 2746 // First assert that we're not calling this method on box types that don't sup port margins. | 2816 // First assert that we're not calling this method on box types that don't |
| 2817 // support margins. | |
| 2747 ASSERT(!isTableCell()); | 2818 ASSERT(!isTableCell()); |
| 2748 ASSERT(!isTableRow()); | 2819 ASSERT(!isTableRow()); |
| 2749 ASSERT(!isTableSection()); | 2820 ASSERT(!isTableSection()); |
| 2750 ASSERT(!isLayoutTableCol()); | 2821 ASSERT(!isLayoutTableCol()); |
| 2751 if (flowDirection == BlockDirection || isFloating() || isInline()) { | 2822 if (flowDirection == BlockDirection || isFloating() || isInline()) { |
| 2752 // Margins are calculated with respect to the logical width of | 2823 // Margins are calculated with respect to the logical width of |
| 2753 // the containing block (8.3) | 2824 // the containing block (8.3) |
| 2754 // Inline blocks/tables and floats don't have their margins increased. | 2825 // Inline blocks/tables and floats don't have their margins increased. |
| 2755 marginStart = minimumValueForLength(marginStartLength, containerWidth); | 2826 marginStart = minimumValueForLength(marginStartLength, containerWidth); |
| 2756 marginEnd = minimumValueForLength(marginEndLength, containerWidth); | 2827 marginEnd = minimumValueForLength(marginEndLength, containerWidth); |
| 2757 return; | 2828 return; |
| 2758 } | 2829 } |
| 2759 | 2830 |
| 2760 if (containingBlock->isFlexibleBox()) { | 2831 if (containingBlock->isFlexibleBox()) { |
| 2761 // We need to let flexbox handle the margin adjustment - otherwise, flexbox | 2832 // We need to let flexbox handle the margin adjustment - otherwise, flexbox |
| 2762 // will think we're wider than we actually are and calculate line sizes wron g. | 2833 // will think we're wider than we actually are and calculate line sizes |
| 2763 // See also http://dev.w3.org/csswg/css-flexbox/#auto-margins | 2834 // wrong. See also http://dev.w3.org/csswg/css-flexbox/#auto-margins |
| 2764 if (marginStartLength.isAuto()) | 2835 if (marginStartLength.isAuto()) |
| 2765 marginStartLength.setValue(0); | 2836 marginStartLength.setValue(0); |
| 2766 if (marginEndLength.isAuto()) | 2837 if (marginEndLength.isAuto()) |
| 2767 marginEndLength.setValue(0); | 2838 marginEndLength.setValue(0); |
| 2768 } | 2839 } |
| 2769 | 2840 |
| 2770 LayoutUnit marginStartWidth = | 2841 LayoutUnit marginStartWidth = |
| 2771 minimumValueForLength(marginStartLength, containerWidth); | 2842 minimumValueForLength(marginStartLength, containerWidth); |
| 2772 LayoutUnit marginEndWidth = | 2843 LayoutUnit marginEndWidth = |
| 2773 minimumValueForLength(marginEndLength, containerWidth); | 2844 minimumValueForLength(marginEndLength, containerWidth); |
| 2774 | 2845 |
| 2775 LayoutUnit availableWidth = containerWidth; | 2846 LayoutUnit availableWidth = containerWidth; |
| 2776 if (avoidsFloats() && containingBlock->isLayoutBlockFlow() && | 2847 if (avoidsFloats() && containingBlock->isLayoutBlockFlow() && |
| 2777 toLayoutBlockFlow(containingBlock)->containsFloats()) { | 2848 toLayoutBlockFlow(containingBlock)->containsFloats()) { |
| 2778 availableWidth = containingBlockAvailableLineWidth(); | 2849 availableWidth = containingBlockAvailableLineWidth(); |
| 2779 if (shrinkToAvoidFloats() && availableWidth < containerWidth) { | 2850 if (shrinkToAvoidFloats() && availableWidth < containerWidth) { |
| 2780 marginStart = std::max(LayoutUnit(), marginStartWidth); | 2851 marginStart = std::max(LayoutUnit(), marginStartWidth); |
| 2781 marginEnd = std::max(LayoutUnit(), marginEndWidth); | 2852 marginEnd = std::max(LayoutUnit(), marginEndWidth); |
| 2782 } | 2853 } |
| 2783 } | 2854 } |
| 2784 | 2855 |
| 2785 // CSS 2.1 (10.3.3): "If 'width' is not 'auto' and 'border-left-width' + 'padd ing-left' + 'width' + 'padding-right' + 'border-right-width' | 2856 // CSS 2.1 (10.3.3): "If 'width' is not 'auto' and 'border-left-width' + |
| 2786 // (plus any of 'margin-left' or 'margin-right' that are not 'auto') is larger than the width of the containing block, then any 'auto' | 2857 // 'padding-left' + 'width' + 'padding-right' + 'border-right-width' (plus any |
| 2787 // values for 'margin-left' or 'margin-right' are, for the following rules, tr eated as zero. | 2858 // of 'margin-left' or 'margin-right' that are not 'auto') is larger than the |
| 2859 // width of the containing block, then any 'auto' values for 'margin-left' or | |
| 2860 // 'margin-right' are, for the following rules, treated as zero. | |
| 2788 LayoutUnit marginBoxWidth = | 2861 LayoutUnit marginBoxWidth = |
| 2789 childWidth + (!style()->width().isAuto() | 2862 childWidth + (!style()->width().isAuto() |
| 2790 ? marginStartWidth + marginEndWidth | 2863 ? marginStartWidth + marginEndWidth |
| 2791 : LayoutUnit()); | 2864 : LayoutUnit()); |
| 2792 | 2865 |
| 2793 if (marginBoxWidth < availableWidth) { | 2866 if (marginBoxWidth < availableWidth) { |
| 2794 // CSS 2.1: "If both 'margin-left' and 'margin-right' are 'auto', their used values are equal. This horizontally centers the element | 2867 // CSS 2.1: "If both 'margin-left' and 'margin-right' are 'auto', their used |
| 2795 // with respect to the edges of the containing block." | 2868 // values are equal. This horizontally centers the element with respect to |
| 2869 // the edges of the containing block." | |
| 2796 const ComputedStyle& containingBlockStyle = containingBlock->styleRef(); | 2870 const ComputedStyle& containingBlockStyle = containingBlock->styleRef(); |
| 2797 if ((marginStartLength.isAuto() && marginEndLength.isAuto()) || | 2871 if ((marginStartLength.isAuto() && marginEndLength.isAuto()) || |
| 2798 (!marginStartLength.isAuto() && !marginEndLength.isAuto() && | 2872 (!marginStartLength.isAuto() && !marginEndLength.isAuto() && |
| 2799 containingBlockStyle.textAlign() == WEBKIT_CENTER)) { | 2873 containingBlockStyle.textAlign() == WEBKIT_CENTER)) { |
| 2800 // Other browsers center the margin box for align=center elements so we ma tch them here. | 2874 // Other browsers center the margin box for align=center elements so we |
| 2875 // match them here. | |
| 2801 LayoutUnit centeredMarginBoxStart = std::max( | 2876 LayoutUnit centeredMarginBoxStart = std::max( |
| 2802 LayoutUnit(), | 2877 LayoutUnit(), |
| 2803 (availableWidth - childWidth - marginStartWidth - marginEndWidth) / | 2878 (availableWidth - childWidth - marginStartWidth - marginEndWidth) / |
| 2804 2); | 2879 2); |
| 2805 marginStart = centeredMarginBoxStart + marginStartWidth; | 2880 marginStart = centeredMarginBoxStart + marginStartWidth; |
| 2806 marginEnd = availableWidth - childWidth - marginStart + marginEndWidth; | 2881 marginEnd = availableWidth - childWidth - marginStart + marginEndWidth; |
| 2807 return; | 2882 return; |
| 2808 } | 2883 } |
| 2809 | 2884 |
| 2810 // Adjust margins for the align attribute | 2885 // Adjust margins for the align attribute |
| 2811 if ((!containingBlockStyle.isLeftToRightDirection() && | 2886 if ((!containingBlockStyle.isLeftToRightDirection() && |
| 2812 containingBlockStyle.textAlign() == WEBKIT_LEFT) || | 2887 containingBlockStyle.textAlign() == WEBKIT_LEFT) || |
| 2813 (containingBlockStyle.isLeftToRightDirection() && | 2888 (containingBlockStyle.isLeftToRightDirection() && |
| 2814 containingBlockStyle.textAlign() == WEBKIT_RIGHT)) { | 2889 containingBlockStyle.textAlign() == WEBKIT_RIGHT)) { |
| 2815 if (containingBlockStyle.isLeftToRightDirection() != | 2890 if (containingBlockStyle.isLeftToRightDirection() != |
| 2816 styleRef().isLeftToRightDirection()) { | 2891 styleRef().isLeftToRightDirection()) { |
| 2817 if (!marginStartLength.isAuto()) | 2892 if (!marginStartLength.isAuto()) |
| 2818 marginEndLength = Length(Auto); | 2893 marginEndLength = Length(Auto); |
| 2819 } else { | 2894 } else { |
| 2820 if (!marginEndLength.isAuto()) | 2895 if (!marginEndLength.isAuto()) |
| 2821 marginStartLength = Length(Auto); | 2896 marginStartLength = Length(Auto); |
| 2822 } | 2897 } |
| 2823 } | 2898 } |
| 2824 | 2899 |
| 2825 // CSS 2.1: "If there is exactly one value specified as 'auto', its used val ue follows from the equality." | 2900 // CSS 2.1: "If there is exactly one value specified as 'auto', its used |
| 2901 // value follows from the equality." | |
| 2826 if (marginEndLength.isAuto()) { | 2902 if (marginEndLength.isAuto()) { |
| 2827 marginStart = marginStartWidth; | 2903 marginStart = marginStartWidth; |
| 2828 marginEnd = availableWidth - childWidth - marginStart; | 2904 marginEnd = availableWidth - childWidth - marginStart; |
| 2829 return; | 2905 return; |
| 2830 } | 2906 } |
| 2831 | 2907 |
| 2832 if (marginStartLength.isAuto()) { | 2908 if (marginStartLength.isAuto()) { |
| 2833 marginEnd = marginEndWidth; | 2909 marginEnd = marginEndWidth; |
| 2834 marginStart = availableWidth - childWidth - marginEnd; | 2910 marginStart = availableWidth - childWidth - marginEnd; |
| 2835 return; | 2911 return; |
| 2836 } | 2912 } |
| 2837 } | 2913 } |
| 2838 | 2914 |
| 2839 // Either no auto margins, or our margin box width is >= the container width, auto margins will just turn into 0. | 2915 // Either no auto margins, or our margin box width is >= the container width, |
| 2916 // auto margins will just turn into 0. | |
| 2840 marginStart = marginStartWidth; | 2917 marginStart = marginStartWidth; |
| 2841 marginEnd = marginEndWidth; | 2918 marginEnd = marginEndWidth; |
| 2842 } | 2919 } |
| 2843 | 2920 |
| 2844 DISABLE_CFI_PERF | 2921 DISABLE_CFI_PERF |
| 2845 void LayoutBox::updateLogicalHeight() { | 2922 void LayoutBox::updateLogicalHeight() { |
| 2846 m_intrinsicContentLogicalHeight = contentLogicalHeight(); | 2923 m_intrinsicContentLogicalHeight = contentLogicalHeight(); |
| 2847 | 2924 |
| 2848 LogicalExtentComputedValues computedValues; | 2925 LogicalExtentComputedValues computedValues; |
| 2849 LayoutUnit height = style()->containsSize() ? borderAndPaddingLogicalHeight() | 2926 LayoutUnit height = style()->containsSize() ? borderAndPaddingLogicalHeight() |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 2866 // Cell height is managed by the table. | 2943 // Cell height is managed by the table. |
| 2867 if (isTableCell()) | 2944 if (isTableCell()) |
| 2868 return; | 2945 return; |
| 2869 | 2946 |
| 2870 Length h; | 2947 Length h; |
| 2871 if (isOutOfFlowPositioned()) { | 2948 if (isOutOfFlowPositioned()) { |
| 2872 computePositionedLogicalHeight(computedValues); | 2949 computePositionedLogicalHeight(computedValues); |
| 2873 } else { | 2950 } else { |
| 2874 LayoutBlock* cb = containingBlock(); | 2951 LayoutBlock* cb = containingBlock(); |
| 2875 | 2952 |
| 2876 // If we are perpendicular to our containing block then we need to resolve o ur block-start and block-end margins so that if they | 2953 // If we are perpendicular to our containing block then we need to resolve |
| 2877 // are 'auto' we are centred or aligned within the inline flow containing bl ock: this is done by computing the margins as though they are inline. | 2954 // our block-start and block-end margins so that if they are 'auto' we are |
| 2878 // Note that as this is the 'sizing phase' we are using our own writing mode rather than the containing block's. We use the containing block's | 2955 // centred or aligned within the inline flow containing block: this is done |
| 2879 // writing mode when figuring out the block-direction margins for positionin g in |computeAndSetBlockDirectionMargins| (i.e. margin collapsing etc.). | 2956 // by computing the margins as though they are inline. |
| 2880 // See http://www.w3.org/TR/2014/CR-css-writing-modes-3-20140320/#orthogonal -flows | 2957 // Note that as this is the 'sizing phase' we are using our own writing mode |
| 2958 // rather than the containing block's. We use the containing block's writing | |
| 2959 // mode when figuring out the block-direction margins for positioning in | |
| 2960 // |computeAndSetBlockDirectionMargins| (i.e. margin collapsing etc.). | |
| 2961 // http://www.w3.org/TR/2014/CR-css-writing-modes-3-20140320/#orthogonal-flo ws | |
| 2881 MarginDirection flowDirection = | 2962 MarginDirection flowDirection = |
| 2882 isHorizontalWritingMode() != cb->isHorizontalWritingMode() | 2963 isHorizontalWritingMode() != cb->isHorizontalWritingMode() |
| 2883 ? InlineDirection | 2964 ? InlineDirection |
| 2884 : BlockDirection; | 2965 : BlockDirection; |
| 2885 | 2966 |
| 2886 // For tables, calculate margins only. | 2967 // For tables, calculate margins only. |
| 2887 if (isTable()) { | 2968 if (isTable()) { |
| 2888 computeMarginsForDirection( | 2969 computeMarginsForDirection( |
| 2889 flowDirection, cb, containingBlockLogicalWidthForContent(), | 2970 flowDirection, cb, containingBlockLogicalWidthForContent(), |
| 2890 computedValues.m_extent, computedValues.m_margins.m_before, | 2971 computedValues.m_extent, computedValues.m_margins.m_before, |
| 2891 computedValues.m_margins.m_after, style()->marginBefore(), | 2972 computedValues.m_margins.m_after, style()->marginBefore(), |
| 2892 style()->marginAfter()); | 2973 style()->marginAfter()); |
| 2893 return; | 2974 return; |
| 2894 } | 2975 } |
| 2895 | 2976 |
| 2896 // FIXME: Account for writing-mode in flexible boxes. | 2977 // FIXME: Account for writing-mode in flexible boxes. |
| 2897 // https://bugs.webkit.org/show_bug.cgi?id=46418 | 2978 // https://bugs.webkit.org/show_bug.cgi?id=46418 |
| 2898 bool inHorizontalBox = parent()->isDeprecatedFlexibleBox() && | 2979 bool inHorizontalBox = parent()->isDeprecatedFlexibleBox() && |
| 2899 parent()->style()->boxOrient() == HORIZONTAL; | 2980 parent()->style()->boxOrient() == HORIZONTAL; |
| 2900 bool stretching = parent()->style()->boxAlign() == BSTRETCH; | 2981 bool stretching = parent()->style()->boxAlign() == BSTRETCH; |
| 2901 bool treatAsReplaced = | 2982 bool treatAsReplaced = |
| 2902 shouldComputeSizeAsReplaced() && (!inHorizontalBox || !stretching); | 2983 shouldComputeSizeAsReplaced() && (!inHorizontalBox || !stretching); |
| 2903 bool checkMinMaxHeight = false; | 2984 bool checkMinMaxHeight = false; |
| 2904 | 2985 |
| 2905 // The parent box is flexing us, so it has increased or decreased our height . We have to | 2986 // The parent box is flexing us, so it has increased or decreased our |
| 2906 // grab our cached flexible height. | 2987 // height. We have to grab our cached flexible height. |
| 2907 // FIXME: Account for writing-mode in flexible boxes. | 2988 // FIXME: Account for writing-mode in flexible boxes. |
| 2908 // https://bugs.webkit.org/show_bug.cgi?id=46418 | 2989 // https://bugs.webkit.org/show_bug.cgi?id=46418 |
| 2909 if (hasOverrideLogicalContentHeight()) { | 2990 if (hasOverrideLogicalContentHeight()) { |
| 2910 LayoutUnit contentHeight = overrideLogicalContentHeight(); | 2991 LayoutUnit contentHeight = overrideLogicalContentHeight(); |
| 2911 if (parent()->isLayoutGrid() && style()->logicalMinHeight().isAuto() && | 2992 if (parent()->isLayoutGrid() && style()->logicalMinHeight().isAuto() && |
| 2912 style()->overflowY() == OverflowVisible) { | 2993 style()->overflowY() == OverflowVisible) { |
| 2913 ASSERT(style()->logicalHeight().isAuto()); | 2994 ASSERT(style()->logicalHeight().isAuto()); |
| 2914 LayoutUnit minContentHeight = computeContentLogicalHeight( | 2995 LayoutUnit minContentHeight = computeContentLogicalHeight( |
| 2915 MinSize, Length(MinContent), | 2996 MinSize, Length(MinContent), |
| 2916 computedValues.m_extent - borderAndPaddingLogicalHeight()); | 2997 computedValues.m_extent - borderAndPaddingLogicalHeight()); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 2943 if (checkMinMaxHeight) { | 3024 if (checkMinMaxHeight) { |
| 2944 heightResult = computeLogicalHeightUsing( | 3025 heightResult = computeLogicalHeightUsing( |
| 2945 MainOrPreferredSize, style()->logicalHeight(), | 3026 MainOrPreferredSize, style()->logicalHeight(), |
| 2946 computedValues.m_extent - borderAndPaddingLogicalHeight()); | 3027 computedValues.m_extent - borderAndPaddingLogicalHeight()); |
| 2947 if (heightResult == -1) | 3028 if (heightResult == -1) |
| 2948 heightResult = computedValues.m_extent; | 3029 heightResult = computedValues.m_extent; |
| 2949 heightResult = constrainLogicalHeightByMinMax( | 3030 heightResult = constrainLogicalHeightByMinMax( |
| 2950 heightResult, | 3031 heightResult, |
| 2951 computedValues.m_extent - borderAndPaddingLogicalHeight()); | 3032 computedValues.m_extent - borderAndPaddingLogicalHeight()); |
| 2952 } else { | 3033 } else { |
| 2953 // The only times we don't check min/max height are when a fixed length ha s | 3034 // The only times we don't check min/max height are when a fixed length |
| 2954 // been given as an override. Just use that. The value has already been adjusted | 3035 // has been given as an override. Just use that. The value has already |
| 2955 // for box-sizing. | 3036 // been adjusted for box-sizing. |
| 2956 ASSERT(h.isFixed()); | 3037 ASSERT(h.isFixed()); |
| 2957 heightResult = LayoutUnit(h.value()) + borderAndPaddingLogicalHeight(); | 3038 heightResult = LayoutUnit(h.value()) + borderAndPaddingLogicalHeight(); |
| 2958 } | 3039 } |
| 2959 | 3040 |
| 2960 computedValues.m_extent = heightResult; | 3041 computedValues.m_extent = heightResult; |
| 2961 computeMarginsForDirection( | 3042 computeMarginsForDirection( |
| 2962 flowDirection, cb, containingBlockLogicalWidthForContent(), | 3043 flowDirection, cb, containingBlockLogicalWidthForContent(), |
| 2963 computedValues.m_extent, computedValues.m_margins.m_before, | 3044 computedValues.m_extent, computedValues.m_margins.m_before, |
| 2964 computedValues.m_margins.m_after, style()->marginBefore(), | 3045 computedValues.m_margins.m_after, style()->marginBefore(), |
| 2965 style()->marginAfter()); | 3046 style()->marginAfter()); |
| 2966 } | 3047 } |
| 2967 | 3048 |
| 2968 // WinIE quirk: The <html> block always fills the entire canvas in quirks mode . The <body> always fills the | 3049 // WinIE quirk: The <html> block always fills the entire canvas in quirks |
| 2969 // <html> block in quirks mode. Only apply this quirk if the block is normal flow and no height | 3050 // mode. The <body> always fills the <html> block in quirks mode. Only apply |
| 2970 // is specified. When we're printing, we also need this quirk if the body or r oot has a percentage | 3051 // this quirk if the block is normal flow and no height is specified. When |
| 2971 // height since we don't set a height in LayoutView when we're printing. So wi thout this quirk, the | 3052 // we're printing, we also need this quirk if the body or root has a |
| 2972 // height has nothing to be a percentage of, and it ends up being 0. That is b ad. | 3053 // percentage height since we don't set a height in LayoutView when we're |
| 3054 // printing. So without this quirk, the height has nothing to be a percentage | |
| 3055 // of, and it ends up being 0. That is bad. | |
| 2973 bool paginatedContentNeedsBaseHeight = | 3056 bool paginatedContentNeedsBaseHeight = |
| 2974 document().printing() && h.isPercentOrCalc() && | 3057 document().printing() && h.isPercentOrCalc() && |
| 2975 (isDocumentElement() || (isBody() && | 3058 (isDocumentElement() || (isBody() && |
| 2976 document() | 3059 document() |
| 2977 .documentElement() | 3060 .documentElement() |
| 2978 ->layoutObject() | 3061 ->layoutObject() |
| 2979 ->style() | 3062 ->style() |
| 2980 ->logicalHeight() | 3063 ->logicalHeight() |
| 2981 .isPercentOrCalc())) && | 3064 .isPercentOrCalc())) && |
| 2982 !isInline(); | 3065 !isInline(); |
| 2983 if (stretchesToViewport() || paginatedContentNeedsBaseHeight) { | 3066 if (stretchesToViewport() || paginatedContentNeedsBaseHeight) { |
| 2984 LayoutUnit margins = collapsedMarginBefore() + collapsedMarginAfter(); | 3067 LayoutUnit margins = collapsedMarginBefore() + collapsedMarginAfter(); |
| 2985 LayoutUnit visibleHeight = view()->viewLogicalHeightForPercentages(); | 3068 LayoutUnit visibleHeight = view()->viewLogicalHeightForPercentages(); |
| 2986 if (isDocumentElement()) { | 3069 if (isDocumentElement()) { |
| 2987 computedValues.m_extent = | 3070 computedValues.m_extent = |
| 2988 std::max(computedValues.m_extent, visibleHeight - margins); | 3071 std::max(computedValues.m_extent, visibleHeight - margins); |
| 2989 } else { | 3072 } else { |
| 2990 LayoutUnit marginsBordersPadding = | 3073 LayoutUnit marginsBordersPadding = |
| 2991 margins + parentBox()->marginBefore() + parentBox()->marginAfter() + | 3074 margins + parentBox()->marginBefore() + parentBox()->marginAfter() + |
| 2992 parentBox()->borderAndPaddingLogicalHeight(); | 3075 parentBox()->borderAndPaddingLogicalHeight(); |
| 2993 computedValues.m_extent = std::max(computedValues.m_extent, | 3076 computedValues.m_extent = std::max(computedValues.m_extent, |
| 2994 visibleHeight - marginsBordersPadding); | 3077 visibleHeight - marginsBordersPadding); |
| 2995 } | 3078 } |
| 2996 } | 3079 } |
| 2997 } | 3080 } |
| 2998 | 3081 |
| 2999 LayoutUnit LayoutBox::computeLogicalHeightWithoutLayout() const { | 3082 LayoutUnit LayoutBox::computeLogicalHeightWithoutLayout() const { |
| 3000 // TODO(cbiesinger): We should probably return something other than just borde r + padding, but for now | 3083 // TODO(cbiesinger): We should probably return something other than just |
| 3001 // we have no good way to do anything else without layout, so we just use that . | 3084 // border + padding, but for now we have no good way to do anything else |
| 3085 // without layout, so we just use that. | |
| 3002 LogicalExtentComputedValues computedValues; | 3086 LogicalExtentComputedValues computedValues; |
| 3003 computeLogicalHeight(borderAndPaddingLogicalHeight(), LayoutUnit(), | 3087 computeLogicalHeight(borderAndPaddingLogicalHeight(), LayoutUnit(), |
| 3004 computedValues); | 3088 computedValues); |
| 3005 return computedValues.m_extent; | 3089 return computedValues.m_extent; |
| 3006 } | 3090 } |
| 3007 | 3091 |
| 3008 LayoutUnit LayoutBox::computeLogicalHeightUsing( | 3092 LayoutUnit LayoutBox::computeLogicalHeightUsing( |
| 3009 SizeType heightType, | 3093 SizeType heightType, |
| 3010 const Length& height, | 3094 const Length& height, |
| 3011 LayoutUnit intrinsicContentHeight) const { | 3095 LayoutUnit intrinsicContentHeight) const { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 3035 adjusted = | 3119 adjusted = |
| 3036 adjustContentBoxLogicalHeightForBoxSizing(heightIncludingScrollbar); | 3120 adjustContentBoxLogicalHeightForBoxSizing(heightIncludingScrollbar); |
| 3037 } | 3121 } |
| 3038 return std::max(LayoutUnit(), adjusted - scrollbarLogicalHeight()); | 3122 return std::max(LayoutUnit(), adjusted - scrollbarLogicalHeight()); |
| 3039 } | 3123 } |
| 3040 | 3124 |
| 3041 LayoutUnit LayoutBox::computeIntrinsicLogicalContentHeightUsing( | 3125 LayoutUnit LayoutBox::computeIntrinsicLogicalContentHeightUsing( |
| 3042 const Length& logicalHeightLength, | 3126 const Length& logicalHeightLength, |
| 3043 LayoutUnit intrinsicContentHeight, | 3127 LayoutUnit intrinsicContentHeight, |
| 3044 LayoutUnit borderAndPadding) const { | 3128 LayoutUnit borderAndPadding) const { |
| 3045 // FIXME(cbiesinger): The css-sizing spec is considering changing what min-con tent/max-content should resolve to. | 3129 // FIXME(cbiesinger): The css-sizing spec is considering changing what |
| 3130 // min-content/max-content should resolve to. | |
| 3046 // If that happens, this code will have to change. | 3131 // If that happens, this code will have to change. |
| 3047 if (logicalHeightLength.isMinContent() || | 3132 if (logicalHeightLength.isMinContent() || |
| 3048 logicalHeightLength.isMaxContent() || | 3133 logicalHeightLength.isMaxContent() || |
| 3049 logicalHeightLength.isFitContent()) { | 3134 logicalHeightLength.isFitContent()) { |
| 3050 if (isAtomicInlineLevel()) | 3135 if (isAtomicInlineLevel()) |
| 3051 return intrinsicSize().height(); | 3136 return intrinsicSize().height(); |
| 3052 return intrinsicContentHeight; | 3137 return intrinsicContentHeight; |
| 3053 } | 3138 } |
| 3054 if (logicalHeightLength.isFillAvailable()) | 3139 if (logicalHeightLength.isFillAvailable()) |
| 3055 return containingBlock()->availableLogicalHeight( | 3140 return containingBlock()->availableLogicalHeight( |
| 3056 ExcludeMarginBorderPadding) - | 3141 ExcludeMarginBorderPadding) - |
| 3057 borderAndPadding; | 3142 borderAndPadding; |
| 3058 ASSERT_NOT_REACHED(); | 3143 ASSERT_NOT_REACHED(); |
| 3059 return LayoutUnit(); | 3144 return LayoutUnit(); |
| 3060 } | 3145 } |
| 3061 | 3146 |
| 3062 LayoutUnit LayoutBox::computeContentAndScrollbarLogicalHeightUsing( | 3147 LayoutUnit LayoutBox::computeContentAndScrollbarLogicalHeightUsing( |
| 3063 SizeType heightType, | 3148 SizeType heightType, |
| 3064 const Length& height, | 3149 const Length& height, |
| 3065 LayoutUnit intrinsicContentHeight) const { | 3150 LayoutUnit intrinsicContentHeight) const { |
| 3066 if (height.isAuto()) | 3151 if (height.isAuto()) |
| 3067 return heightType == MinSize ? LayoutUnit() : LayoutUnit(-1); | 3152 return heightType == MinSize ? LayoutUnit() : LayoutUnit(-1); |
| 3068 // FIXME(cbiesinger): The css-sizing spec is considering changing what min-con tent/max-content should resolve to. | 3153 // FIXME(cbiesinger): The css-sizing spec is considering changing what |
| 3154 // min-content/max-content should resolve to. | |
| 3069 // If that happens, this code will have to change. | 3155 // If that happens, this code will have to change. |
| 3070 if (height.isIntrinsic()) { | 3156 if (height.isIntrinsic()) { |
| 3071 if (intrinsicContentHeight == -1) | 3157 if (intrinsicContentHeight == -1) |
| 3072 return LayoutUnit(-1); // Intrinsic height isn't available. | 3158 return LayoutUnit(-1); // Intrinsic height isn't available. |
| 3073 return computeIntrinsicLogicalContentHeightUsing( | 3159 return computeIntrinsicLogicalContentHeightUsing( |
| 3074 height, intrinsicContentHeight, | 3160 height, intrinsicContentHeight, |
| 3075 borderAndPaddingLogicalHeight()) + | 3161 borderAndPaddingLogicalHeight()) + |
| 3076 scrollbarLogicalHeight(); | 3162 scrollbarLogicalHeight(); |
| 3077 } | 3163 } |
| 3078 if (height.isFixed()) | 3164 if (height.isFixed()) |
| 3079 return LayoutUnit(height.value()); | 3165 return LayoutUnit(height.value()); |
| 3080 if (height.isPercentOrCalc()) | 3166 if (height.isPercentOrCalc()) |
| 3081 return computePercentageLogicalHeight(height); | 3167 return computePercentageLogicalHeight(height); |
| 3082 return LayoutUnit(-1); | 3168 return LayoutUnit(-1); |
| 3083 } | 3169 } |
| 3084 | 3170 |
| 3085 bool LayoutBox::stretchesToViewportInQuirksMode() const { | 3171 bool LayoutBox::stretchesToViewportInQuirksMode() const { |
| 3086 if (!isDocumentElement() && !isBody()) | 3172 if (!isDocumentElement() && !isBody()) |
| 3087 return false; | 3173 return false; |
| 3088 return style()->logicalHeight().isAuto() && | 3174 return style()->logicalHeight().isAuto() && |
| 3089 !isFloatingOrOutOfFlowPositioned() && !isInline() && | 3175 !isFloatingOrOutOfFlowPositioned() && !isInline() && |
| 3090 !flowThreadContainingBlock(); | 3176 !flowThreadContainingBlock(); |
| 3091 } | 3177 } |
| 3092 | 3178 |
| 3093 bool LayoutBox::skipContainingBlockForPercentHeightCalculation( | 3179 bool LayoutBox::skipContainingBlockForPercentHeightCalculation( |
| 3094 const LayoutBox* containingBlock) const { | 3180 const LayoutBox* containingBlock) const { |
| 3095 // If the writing mode of the containing block is orthogonal to ours, it means that we shouldn't | 3181 // If the writing mode of the containing block is orthogonal to ours, it means |
| 3096 // skip anything, since we're going to resolve the percentage height against a containing block *width*. | 3182 // that we shouldn't skip anything, since we're going to resolve the |
| 3183 // percentage height against a containing block *width*. | |
| 3097 if (isHorizontalWritingMode() != containingBlock->isHorizontalWritingMode()) | 3184 if (isHorizontalWritingMode() != containingBlock->isHorizontalWritingMode()) |
| 3098 return false; | 3185 return false; |
| 3099 | 3186 |
| 3100 // Anonymous blocks should not impede percentage resolution on a child. Exampl es of such | 3187 // Anonymous blocks should not impede percentage resolution on a child. |
| 3101 // anonymous blocks are blocks wrapped around inlines that have block siblings (from the CSS | 3188 // Examples of such anonymous blocks are blocks wrapped around inlines that |
| 3102 // spec) and multicol flow threads (an implementation detail). Another impleme ntation detail, | 3189 // have block siblings (from the CSS spec) and multicol flow threads (an |
| 3103 // ruby runs, create anonymous inline-blocks, so skip those too. All other typ es of anonymous | 3190 // implementation detail). Another implementation detail, ruby runs, create |
| 3104 // objects, such as table-cells, will be treated just as if they were non-anon ymous. | 3191 // anonymous inline-blocks, so skip those too. All other types of anonymous |
| 3192 // objects, such as table-cells, will be treated just as if they were | |
| 3193 // non-anonymous. | |
| 3105 if (containingBlock->isAnonymous()) { | 3194 if (containingBlock->isAnonymous()) { |
| 3106 EDisplay display = containingBlock->styleRef().display(); | 3195 EDisplay display = containingBlock->styleRef().display(); |
| 3107 return display == EDisplay::Block || display == EDisplay::InlineBlock; | 3196 return display == EDisplay::Block || display == EDisplay::InlineBlock; |
| 3108 } | 3197 } |
| 3109 | 3198 |
| 3110 // For quirks mode, we skip most auto-height containing blocks when computing percentages. | 3199 // For quirks mode, we skip most auto-height containing blocks when computing |
| 3200 // percentages. | |
| 3111 return document().inQuirksMode() && !containingBlock->isTableCell() && | 3201 return document().inQuirksMode() && !containingBlock->isTableCell() && |
| 3112 !containingBlock->isOutOfFlowPositioned() && | 3202 !containingBlock->isOutOfFlowPositioned() && |
| 3113 !containingBlock->isLayoutGrid() && | 3203 !containingBlock->isLayoutGrid() && |
| 3114 containingBlock->style()->logicalHeight().isAuto(); | 3204 containingBlock->style()->logicalHeight().isAuto(); |
| 3115 } | 3205 } |
| 3116 | 3206 |
| 3117 LayoutUnit LayoutBox::computePercentageLogicalHeight( | 3207 LayoutUnit LayoutBox::computePercentageLogicalHeight( |
| 3118 const Length& height) const { | 3208 const Length& height) const { |
| 3119 LayoutBlock* cb = containingBlock(); | 3209 LayoutBlock* cb = containingBlock(); |
| 3120 const LayoutBox* containingBlockChild = this; | 3210 const LayoutBox* containingBlockChild = this; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 3132 cb->addPercentHeightDescendant(const_cast<LayoutBox*>(this)); | 3222 cb->addPercentHeightDescendant(const_cast<LayoutBox*>(this)); |
| 3133 | 3223 |
| 3134 LayoutUnit availableHeight(-1); | 3224 LayoutUnit availableHeight(-1); |
| 3135 if (isHorizontalWritingMode() != cb->isHorizontalWritingMode()) { | 3225 if (isHorizontalWritingMode() != cb->isHorizontalWritingMode()) { |
| 3136 availableHeight = | 3226 availableHeight = |
| 3137 containingBlockChild->containingBlockLogicalWidthForContent(); | 3227 containingBlockChild->containingBlockLogicalWidthForContent(); |
| 3138 } else if (hasOverrideContainingBlockLogicalHeight()) { | 3228 } else if (hasOverrideContainingBlockLogicalHeight()) { |
| 3139 availableHeight = overrideContainingBlockContentLogicalHeight(); | 3229 availableHeight = overrideContainingBlockContentLogicalHeight(); |
| 3140 } else if (cb->isTableCell()) { | 3230 } else if (cb->isTableCell()) { |
| 3141 if (!skippedAutoHeightContainingBlock) { | 3231 if (!skippedAutoHeightContainingBlock) { |
| 3142 // Table cells violate what the CSS spec says to do with heights. Basicall y we | 3232 // Table cells violate what the CSS spec says to do with heights. |
| 3143 // don't care if the cell specified a height or not. We just always make o urselves | 3233 // Basically we don't care if the cell specified a height or not. We just |
| 3144 // be a percentage of the cell's current content height. | 3234 // always make ourselves be a percentage of the cell's current content |
| 3235 // height. | |
| 3145 if (!cb->hasOverrideLogicalContentHeight()) { | 3236 if (!cb->hasOverrideLogicalContentHeight()) { |
| 3146 // Normally we would let the cell size intrinsically, but scrolling over flow has to be | 3237 // Normally we would let the cell size intrinsically, but scrolling |
| 3147 // treated differently, since WinIE lets scrolled overflow regions shrin k as needed. | 3238 // overflow has to be treated differently, since WinIE lets scrolled |
| 3148 // While we can't get all cases right, we can at least detect when the c ell has a specified | 3239 // overflow regions shrink as needed. |
| 3149 // height or when the table has a specified height. In these cases we wa nt to initially have | 3240 // While we can't get all cases right, we can at least detect when the |
| 3150 // no size and allow the flexing of the table or the cell to its specifi ed height to cause us | 3241 // cell has a specified height or when the table has a specified height. |
| 3151 // to grow to fill the space. This could end up being wrong in some case s, but it is | 3242 // In these cases we want to initially have no size and allow the |
| 3152 // preferable to the alternative (sizing intrinsically and making the ro w end up too big). | 3243 // flexing of the table or the cell to its specified height to cause us |
| 3244 // to grow to fill the space. This could end up being wrong in some | |
| 3245 // cases, but it is preferable to the alternative (sizing intrinsically | |
| 3246 // and making the row end up too big). | |
| 3153 LayoutTableCell* cell = toLayoutTableCell(cb); | 3247 LayoutTableCell* cell = toLayoutTableCell(cb); |
| 3154 if (scrollsOverflowY() && | 3248 if (scrollsOverflowY() && |
| 3155 (!cell->style()->logicalHeight().isAuto() || | 3249 (!cell->style()->logicalHeight().isAuto() || |
| 3156 !cell->table()->style()->logicalHeight().isAuto())) | 3250 !cell->table()->style()->logicalHeight().isAuto())) |
| 3157 return LayoutUnit(); | 3251 return LayoutUnit(); |
| 3158 return LayoutUnit(-1); | 3252 return LayoutUnit(-1); |
| 3159 } | 3253 } |
| 3160 availableHeight = cb->overrideLogicalContentHeight(); | 3254 availableHeight = cb->overrideLogicalContentHeight(); |
| 3161 } | 3255 } |
| 3162 } else { | 3256 } else { |
| 3163 availableHeight = cb->availableLogicalHeightForPercentageComputation(); | 3257 availableHeight = cb->availableLogicalHeightForPercentageComputation(); |
| 3164 } | 3258 } |
| 3165 | 3259 |
| 3166 if (availableHeight == -1) | 3260 if (availableHeight == -1) |
| 3167 return availableHeight; | 3261 return availableHeight; |
| 3168 | 3262 |
| 3169 availableHeight -= rootMarginBorderPaddingHeight; | 3263 availableHeight -= rootMarginBorderPaddingHeight; |
| 3170 | 3264 |
| 3171 if (isTable() && isOutOfFlowPositioned()) | 3265 if (isTable() && isOutOfFlowPositioned()) |
| 3172 availableHeight += cb->paddingLogicalHeight(); | 3266 availableHeight += cb->paddingLogicalHeight(); |
| 3173 | 3267 |
| 3174 LayoutUnit result = valueForLength(height, availableHeight); | 3268 LayoutUnit result = valueForLength(height, availableHeight); |
| 3175 bool includeBorderPadding = | 3269 bool includeBorderPadding = |
| 3176 isTable() || (cb->isTableCell() && !skippedAutoHeightContainingBlock && | 3270 isTable() || (cb->isTableCell() && !skippedAutoHeightContainingBlock && |
| 3177 cb->hasOverrideLogicalContentHeight()); | 3271 cb->hasOverrideLogicalContentHeight()); |
| 3178 | 3272 |
| 3179 if (includeBorderPadding) { | 3273 if (includeBorderPadding) { |
| 3180 // FIXME: Table cells should default to box-sizing: border-box so we can avo id this hack. | 3274 // FIXME: Table cells should default to box-sizing: border-box so we can |
| 3275 // avoid this hack. | |
| 3181 // It is necessary to use the border-box to match WinIE's broken | 3276 // It is necessary to use the border-box to match WinIE's broken |
| 3182 // box model. This is essential for sizing inside | 3277 // box model. This is essential for sizing inside |
| 3183 // table cells using percentage heights. | 3278 // table cells using percentage heights. |
| 3184 result -= borderAndPaddingLogicalHeight(); | 3279 result -= borderAndPaddingLogicalHeight(); |
| 3185 return std::max(LayoutUnit(), result); | 3280 return std::max(LayoutUnit(), result); |
| 3186 } | 3281 } |
| 3187 return result; | 3282 return result; |
| 3188 } | 3283 } |
| 3189 | 3284 |
| 3190 LayoutUnit LayoutBox::computeReplacedLogicalWidth( | 3285 LayoutUnit LayoutBox::computeReplacedLogicalWidth( |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3230 LayoutUnit availableLogicalWidth; | 3325 LayoutUnit availableLogicalWidth; |
| 3231 return computeIntrinsicLogicalWidthUsing(logicalWidth, | 3326 return computeIntrinsicLogicalWidthUsing(logicalWidth, |
| 3232 availableLogicalWidth, | 3327 availableLogicalWidth, |
| 3233 borderAndPaddingLogicalWidth()) - | 3328 borderAndPaddingLogicalWidth()) - |
| 3234 borderAndPaddingLogicalWidth(); | 3329 borderAndPaddingLogicalWidth(); |
| 3235 } | 3330 } |
| 3236 case FitContent: | 3331 case FitContent: |
| 3237 case FillAvailable: | 3332 case FillAvailable: |
| 3238 case Percent: | 3333 case Percent: |
| 3239 case Calculated: { | 3334 case Calculated: { |
| 3240 // FIXME: containingBlockLogicalWidthForContent() is wrong if the replaced element's writing-mode is perpendicular to the | 3335 // FIXME: containingBlockLogicalWidthForContent() is wrong if the replaced |
| 3241 // containing block's writing-mode. | 3336 // element's writing-mode is perpendicular to the containing block's |
| 3242 // https://bugs.webkit.org/show_bug.cgi?id=46496 | 3337 // writing-mode. https://bugs.webkit.org/show_bug.cgi?id=46496 |
| 3243 const LayoutUnit cw = isOutOfFlowPositioned() | 3338 const LayoutUnit cw = isOutOfFlowPositioned() |
| 3244 ? containingBlockLogicalWidthForPositioned( | 3339 ? containingBlockLogicalWidthForPositioned( |
| 3245 toLayoutBoxModelObject(container())) | 3340 toLayoutBoxModelObject(container())) |
| 3246 : containingBlockLogicalWidthForContent(); | 3341 : containingBlockLogicalWidthForContent(); |
| 3247 Length containerLogicalWidth = containingBlock()->style()->logicalWidth(); | 3342 Length containerLogicalWidth = containingBlock()->style()->logicalWidth(); |
| 3248 // FIXME: Handle cases when containing block width is calculated or viewpo rt percent. | 3343 // FIXME: Handle cases when containing block width is calculated or |
| 3249 // https://bugs.webkit.org/show_bug.cgi?id=91071 | 3344 // viewport percent. https://bugs.webkit.org/show_bug.cgi?id=91071 |
| 3250 if (logicalWidth.isIntrinsic()) | 3345 if (logicalWidth.isIntrinsic()) |
| 3251 return computeIntrinsicLogicalWidthUsing( | 3346 return computeIntrinsicLogicalWidthUsing( |
| 3252 logicalWidth, cw, borderAndPaddingLogicalWidth()) - | 3347 logicalWidth, cw, borderAndPaddingLogicalWidth()) - |
| 3253 borderAndPaddingLogicalWidth(); | 3348 borderAndPaddingLogicalWidth(); |
| 3254 if (cw > 0 || (!cw && (containerLogicalWidth.isFixed() || | 3349 if (cw > 0 || (!cw && (containerLogicalWidth.isFixed() || |
| 3255 containerLogicalWidth.isPercentOrCalc()))) | 3350 containerLogicalWidth.isPercentOrCalc()))) |
| 3256 return adjustContentBoxLogicalWidthForBoxSizing( | 3351 return adjustContentBoxLogicalWidthForBoxSizing( |
| 3257 minimumValueForLength(logicalWidth, cw)); | 3352 minimumValueForLength(logicalWidth, cw)); |
| 3258 return LayoutUnit(); | 3353 return LayoutUnit(); |
| 3259 } | 3354 } |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 3287 if (logicalHeight == initialLogicalHeight) | 3382 if (logicalHeight == initialLogicalHeight) |
| 3288 return true; | 3383 return true; |
| 3289 | 3384 |
| 3290 if (LayoutBlock* cb = containingBlockForAutoHeightDetection(logicalHeight)) | 3385 if (LayoutBlock* cb = containingBlockForAutoHeightDetection(logicalHeight)) |
| 3291 return cb->hasAutoHeightOrContainingBlockWithAutoHeight(); | 3386 return cb->hasAutoHeightOrContainingBlockWithAutoHeight(); |
| 3292 return false; | 3387 return false; |
| 3293 } | 3388 } |
| 3294 | 3389 |
| 3295 LayoutUnit LayoutBox::computeReplacedLogicalHeightRespectingMinMaxHeight( | 3390 LayoutUnit LayoutBox::computeReplacedLogicalHeightRespectingMinMaxHeight( |
| 3296 LayoutUnit logicalHeight) const { | 3391 LayoutUnit logicalHeight) const { |
| 3297 // If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, | 3392 // If the height of the containing block is not specified explicitly (i.e., it |
| 3298 // the percentage value is treated as '0' (for 'min-height') or 'none' (for 'm ax-height'). | 3393 // depends on content height), and this element is not absolutely positioned, |
| 3394 // the percentage value is treated as '0' (for 'min-height') or 'none' (for | |
| 3395 // 'max-height'). | |
| 3299 LayoutUnit minLogicalHeight; | 3396 LayoutUnit minLogicalHeight; |
| 3300 if (!logicalHeightComputesAsNone(MinSize)) | 3397 if (!logicalHeightComputesAsNone(MinSize)) |
| 3301 minLogicalHeight = | 3398 minLogicalHeight = |
| 3302 computeReplacedLogicalHeightUsing(MinSize, style()->logicalMinHeight()); | 3399 computeReplacedLogicalHeightUsing(MinSize, style()->logicalMinHeight()); |
| 3303 LayoutUnit maxLogicalHeight = logicalHeight; | 3400 LayoutUnit maxLogicalHeight = logicalHeight; |
| 3304 if (!logicalHeightComputesAsNone(MaxSize)) | 3401 if (!logicalHeightComputesAsNone(MaxSize)) |
| 3305 maxLogicalHeight = | 3402 maxLogicalHeight = |
| 3306 computeReplacedLogicalHeightUsing(MaxSize, style()->logicalMaxHeight()); | 3403 computeReplacedLogicalHeightUsing(MaxSize, style()->logicalMaxHeight()); |
| 3307 return std::max(minLogicalHeight, std::min(logicalHeight, maxLogicalHeight)); | 3404 return std::max(minLogicalHeight, std::min(logicalHeight, maxLogicalHeight)); |
| 3308 } | 3405 } |
| 3309 | 3406 |
| 3310 LayoutUnit LayoutBox::computeReplacedLogicalHeightUsing( | 3407 LayoutUnit LayoutBox::computeReplacedLogicalHeightUsing( |
| 3311 SizeType sizeType, | 3408 SizeType sizeType, |
| 3312 const Length& logicalHeight) const { | 3409 const Length& logicalHeight) const { |
| 3313 ASSERT(sizeType == MinSize || sizeType == MainOrPreferredSize || | 3410 ASSERT(sizeType == MinSize || sizeType == MainOrPreferredSize || |
| 3314 !logicalHeight.isAuto()); | 3411 !logicalHeight.isAuto()); |
| 3315 if (sizeType == MinSize && logicalHeight.isAuto()) | 3412 if (sizeType == MinSize && logicalHeight.isAuto()) |
| 3316 return adjustContentBoxLogicalHeightForBoxSizing(LayoutUnit()); | 3413 return adjustContentBoxLogicalHeightForBoxSizing(LayoutUnit()); |
| 3317 | 3414 |
| 3318 switch (logicalHeight.type()) { | 3415 switch (logicalHeight.type()) { |
| 3319 case Fixed: | 3416 case Fixed: |
| 3320 return adjustContentBoxLogicalHeightForBoxSizing(logicalHeight.value()); | 3417 return adjustContentBoxLogicalHeightForBoxSizing(logicalHeight.value()); |
| 3321 case Percent: | 3418 case Percent: |
| 3322 case Calculated: { | 3419 case Calculated: { |
| 3323 // TODO(rego): Check if we can somehow reuse LayoutBox::computePercentageL ogicalHeight() and/or | 3420 // TODO(rego): Check if we can somehow reuse |
| 3324 // LayoutBlock::availableLogicalHeightForPercentageComputation() (see http ://crbug.com/635655). | 3421 // LayoutBox::computePercentageLogicalHeight() and/or |
| 3422 // LayoutBlock::availableLogicalHeightForPercentageComputation() (see | |
| 3423 // http://crbug.com/635655). | |
| 3325 LayoutObject* cb = | 3424 LayoutObject* cb = |
| 3326 isOutOfFlowPositioned() ? container() : containingBlock(); | 3425 isOutOfFlowPositioned() ? container() : containingBlock(); |
| 3327 while (cb->isAnonymous()) | 3426 while (cb->isAnonymous()) |
| 3328 cb = cb->containingBlock(); | 3427 cb = cb->containingBlock(); |
| 3329 LayoutUnit stretchedHeight(-1); | 3428 LayoutUnit stretchedHeight(-1); |
| 3330 if (cb->isLayoutBlock()) { | 3429 if (cb->isLayoutBlock()) { |
| 3331 LayoutBlock* block = toLayoutBlock(cb); | 3430 LayoutBlock* block = toLayoutBlock(cb); |
| 3332 block->addPercentHeightDescendant(const_cast<LayoutBox*>(this)); | 3431 block->addPercentHeightDescendant(const_cast<LayoutBox*>(this)); |
| 3333 if (block->isFlexItem()) | 3432 if (block->isFlexItem()) |
| 3334 stretchedHeight = | 3433 stretchedHeight = |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 3348 computedValues); | 3447 computedValues); |
| 3349 LayoutUnit newContentHeight = computedValues.m_extent - | 3448 LayoutUnit newContentHeight = computedValues.m_extent - |
| 3350 block->borderAndPaddingLogicalHeight() - | 3449 block->borderAndPaddingLogicalHeight() - |
| 3351 block->scrollbarLogicalHeight(); | 3450 block->scrollbarLogicalHeight(); |
| 3352 LayoutUnit newHeight = | 3451 LayoutUnit newHeight = |
| 3353 block->adjustContentBoxLogicalHeightForBoxSizing(newContentHeight); | 3452 block->adjustContentBoxLogicalHeightForBoxSizing(newContentHeight); |
| 3354 return adjustContentBoxLogicalHeightForBoxSizing( | 3453 return adjustContentBoxLogicalHeightForBoxSizing( |
| 3355 valueForLength(logicalHeight, newHeight)); | 3454 valueForLength(logicalHeight, newHeight)); |
| 3356 } | 3455 } |
| 3357 | 3456 |
| 3358 // FIXME: availableLogicalHeight() is wrong if the replaced element's writ ing-mode is perpendicular to the | 3457 // FIXME: availableLogicalHeight() is wrong if the replaced element's |
| 3359 // containing block's writing-mode. | 3458 // writing-mode is perpendicular to the containing block's writing-mode. |
| 3360 // https://bugs.webkit.org/show_bug.cgi?id=46496 | 3459 // https://bugs.webkit.org/show_bug.cgi?id=46496 |
| 3361 LayoutUnit availableHeight; | 3460 LayoutUnit availableHeight; |
| 3362 if (isOutOfFlowPositioned()) { | 3461 if (isOutOfFlowPositioned()) { |
| 3363 availableHeight = containingBlockLogicalHeightForPositioned( | 3462 availableHeight = containingBlockLogicalHeightForPositioned( |
| 3364 toLayoutBoxModelObject(cb)); | 3463 toLayoutBoxModelObject(cb)); |
| 3365 } else if (stretchedHeight != -1) { | 3464 } else if (stretchedHeight != -1) { |
| 3366 availableHeight = stretchedHeight; | 3465 availableHeight = stretchedHeight; |
| 3367 } else if (hasOverrideContainingBlockLogicalHeight()) { | 3466 } else if (hasOverrideContainingBlockLogicalHeight()) { |
| 3368 availableHeight = overrideContainingBlockContentLogicalHeight(); | 3467 availableHeight = overrideContainingBlockContentLogicalHeight(); |
| 3369 } else { | 3468 } else { |
| 3370 availableHeight = | 3469 availableHeight = |
| 3371 containingBlockLogicalHeightForContent(IncludeMarginBorderPadding); | 3470 containingBlockLogicalHeightForContent(IncludeMarginBorderPadding); |
| 3372 // It is necessary to use the border-box to match WinIE's broken | 3471 // It is necessary to use the border-box to match WinIE's broken |
| 3373 // box model. This is essential for sizing inside | 3472 // box model. This is essential for sizing inside |
| 3374 // table cells using percentage heights. | 3473 // table cells using percentage heights. |
| 3375 // FIXME: This needs to be made writing-mode-aware. If the cell and imag e are perpendicular writing-modes, this isn't right. | 3474 // FIXME: This needs to be made writing-mode-aware. If the cell and |
| 3475 // image are perpendicular writing-modes, this isn't right. | |
| 3376 // https://bugs.webkit.org/show_bug.cgi?id=46997 | 3476 // https://bugs.webkit.org/show_bug.cgi?id=46997 |
| 3377 while (cb && !cb->isLayoutView() && | 3477 while (cb && !cb->isLayoutView() && |
| 3378 (cb->style()->logicalHeight().isAuto() || | 3478 (cb->style()->logicalHeight().isAuto() || |
| 3379 cb->style()->logicalHeight().isPercentOrCalc())) { | 3479 cb->style()->logicalHeight().isPercentOrCalc())) { |
| 3380 if (cb->isTableCell()) { | 3480 if (cb->isTableCell()) { |
| 3381 // Don't let table cells squeeze percent-height replaced elements | 3481 // Don't let table cells squeeze percent-height replaced elements |
| 3382 // <http://bugs.webkit.org/show_bug.cgi?id=15359> | 3482 // <http://bugs.webkit.org/show_bug.cgi?id=15359> |
| 3383 availableHeight = | 3483 availableHeight = |
| 3384 std::max(availableHeight, intrinsicLogicalHeight()); | 3484 std::max(availableHeight, intrinsicLogicalHeight()); |
| 3385 return valueForLength( | 3485 return valueForLength( |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 3402 computeIntrinsicLogicalContentHeightUsing(logicalHeight, | 3502 computeIntrinsicLogicalContentHeightUsing(logicalHeight, |
| 3403 intrinsicLogicalHeight(), | 3503 intrinsicLogicalHeight(), |
| 3404 borderAndPaddingHeight())); | 3504 borderAndPaddingHeight())); |
| 3405 default: | 3505 default: |
| 3406 return intrinsicLogicalHeight(); | 3506 return intrinsicLogicalHeight(); |
| 3407 } | 3507 } |
| 3408 } | 3508 } |
| 3409 | 3509 |
| 3410 LayoutUnit LayoutBox::availableLogicalHeight( | 3510 LayoutUnit LayoutBox::availableLogicalHeight( |
| 3411 AvailableLogicalHeightType heightType) const { | 3511 AvailableLogicalHeightType heightType) const { |
| 3412 // http://www.w3.org/TR/CSS2/visudet.html#propdef-height - We are interested i n the content height. | 3512 // http://www.w3.org/TR/CSS2/visudet.html#propdef-height - We are interested |
| 3513 // in the content height. | |
| 3413 // FIXME: Should we pass intrinsicContentLogicalHeight() instead of -1 here? | 3514 // FIXME: Should we pass intrinsicContentLogicalHeight() instead of -1 here? |
| 3414 return constrainContentBoxLogicalHeightByMinMax( | 3515 return constrainContentBoxLogicalHeightByMinMax( |
| 3415 availableLogicalHeightUsing(style()->logicalHeight(), heightType), | 3516 availableLogicalHeightUsing(style()->logicalHeight(), heightType), |
| 3416 LayoutUnit(-1)); | 3517 LayoutUnit(-1)); |
| 3417 } | 3518 } |
| 3418 | 3519 |
| 3419 LayoutUnit LayoutBox::availableLogicalHeightUsing( | 3520 LayoutUnit LayoutBox::availableLogicalHeightUsing( |
| 3420 const Length& h, | 3521 const Length& h, |
| 3421 AvailableLogicalHeightType heightType) const { | 3522 AvailableLogicalHeightType heightType) const { |
| 3422 if (isLayoutView()) { | 3523 if (isLayoutView()) { |
| 3423 return LayoutUnit( | 3524 return LayoutUnit( |
| 3424 isHorizontalWritingMode() | 3525 isHorizontalWritingMode() |
| 3425 ? toLayoutView(this)->frameView()->visibleContentSize().height() | 3526 ? toLayoutView(this)->frameView()->visibleContentSize().height() |
| 3426 : toLayoutView(this)->frameView()->visibleContentSize().width()); | 3527 : toLayoutView(this)->frameView()->visibleContentSize().width()); |
| 3427 } | 3528 } |
| 3428 | 3529 |
| 3429 // We need to stop here, since we don't want to increase the height of the tab le | 3530 // We need to stop here, since we don't want to increase the height of the |
| 3430 // artificially. We're going to rely on this cell getting expanded to some ne w | 3531 // table artificially. We're going to rely on this cell getting expanded to |
| 3431 // height, and then when we lay out again we'll use the calculation below. | 3532 // some new height, and then when we lay out again we'll use the calculation |
| 3533 // below. | |
| 3432 if (isTableCell() && (h.isAuto() || h.isPercentOrCalc())) { | 3534 if (isTableCell() && (h.isAuto() || h.isPercentOrCalc())) { |
| 3433 if (hasOverrideLogicalContentHeight()) | 3535 if (hasOverrideLogicalContentHeight()) |
| 3434 return overrideLogicalContentHeight(); | 3536 return overrideLogicalContentHeight(); |
| 3435 return logicalHeight() - borderAndPaddingLogicalHeight(); | 3537 return logicalHeight() - borderAndPaddingLogicalHeight(); |
| 3436 } | 3538 } |
| 3437 | 3539 |
| 3438 if (isFlexItem()) { | 3540 if (isFlexItem()) { |
| 3439 LayoutFlexibleBox& flexBox = toLayoutFlexibleBox(*parent()); | 3541 LayoutFlexibleBox& flexBox = toLayoutFlexibleBox(*parent()); |
| 3440 LayoutUnit stretchedHeight = | 3542 LayoutUnit stretchedHeight = |
| 3441 flexBox.childLogicalHeightForPercentageResolution(*this); | 3543 flexBox.childLogicalHeightForPercentageResolution(*this); |
| 3442 if (stretchedHeight != LayoutUnit(-1)) | 3544 if (stretchedHeight != LayoutUnit(-1)) |
| 3443 return stretchedHeight; | 3545 return stretchedHeight; |
| 3444 } | 3546 } |
| 3445 | 3547 |
| 3446 if (h.isPercentOrCalc() && isOutOfFlowPositioned()) { | 3548 if (h.isPercentOrCalc() && isOutOfFlowPositioned()) { |
| 3447 // FIXME: This is wrong if the containingBlock has a perpendicular writing m ode. | 3549 // FIXME: This is wrong if the containingBlock has a perpendicular writing |
| 3550 // mode. | |
| 3448 LayoutUnit availableHeight = | 3551 LayoutUnit availableHeight = |
| 3449 containingBlockLogicalHeightForPositioned(containingBlock()); | 3552 containingBlockLogicalHeightForPositioned(containingBlock()); |
| 3450 return adjustContentBoxLogicalHeightForBoxSizing( | 3553 return adjustContentBoxLogicalHeightForBoxSizing( |
| 3451 valueForLength(h, availableHeight)); | 3554 valueForLength(h, availableHeight)); |
| 3452 } | 3555 } |
| 3453 | 3556 |
| 3454 // FIXME: Should we pass intrinsicContentLogicalHeight() instead of -1 here? | 3557 // FIXME: Should we pass intrinsicContentLogicalHeight() instead of -1 here? |
| 3455 LayoutUnit heightIncludingScrollbar = | 3558 LayoutUnit heightIncludingScrollbar = |
| 3456 computeContentAndScrollbarLogicalHeightUsing(MainOrPreferredSize, h, | 3559 computeContentAndScrollbarLogicalHeightUsing(MainOrPreferredSize, h, |
| 3457 LayoutUnit(-1)); | 3560 LayoutUnit(-1)); |
| 3458 if (heightIncludingScrollbar != -1) | 3561 if (heightIncludingScrollbar != -1) |
| 3459 return std::max(LayoutUnit(), adjustContentBoxLogicalHeightForBoxSizing( | 3562 return std::max(LayoutUnit(), adjustContentBoxLogicalHeightForBoxSizing( |
| 3460 heightIncludingScrollbar) - | 3563 heightIncludingScrollbar) - |
| 3461 scrollbarLogicalHeight()); | 3564 scrollbarLogicalHeight()); |
| 3462 | 3565 |
| 3463 // FIXME: Check logicalTop/logicalBottom here to correctly handle vertical wri ting-mode. | 3566 // FIXME: Check logicalTop/logicalBottom here to correctly handle vertical |
| 3567 // writing-mode. | |
| 3464 // https://bugs.webkit.org/show_bug.cgi?id=46500 | 3568 // https://bugs.webkit.org/show_bug.cgi?id=46500 |
| 3465 if (isLayoutBlock() && isOutOfFlowPositioned() && | 3569 if (isLayoutBlock() && isOutOfFlowPositioned() && |
| 3466 style()->height().isAuto() && | 3570 style()->height().isAuto() && |
| 3467 !(style()->top().isAuto() || style()->bottom().isAuto())) { | 3571 !(style()->top().isAuto() || style()->bottom().isAuto())) { |
| 3468 LayoutBlock* block = const_cast<LayoutBlock*>(toLayoutBlock(this)); | 3572 LayoutBlock* block = const_cast<LayoutBlock*>(toLayoutBlock(this)); |
| 3469 LogicalExtentComputedValues computedValues; | 3573 LogicalExtentComputedValues computedValues; |
| 3470 block->computeLogicalHeight(block->logicalHeight(), LayoutUnit(), | 3574 block->computeLogicalHeight(block->logicalHeight(), LayoutUnit(), |
| 3471 computedValues); | 3575 computedValues); |
| 3472 LayoutUnit newContentHeight = computedValues.m_extent - | 3576 LayoutUnit newContentHeight = computedValues.m_extent - |
| 3473 block->borderAndPaddingLogicalHeight() - | 3577 block->borderAndPaddingLogicalHeight() - |
| 3474 block->scrollbarLogicalHeight(); | 3578 block->scrollbarLogicalHeight(); |
| 3475 return adjustContentBoxLogicalHeightForBoxSizing(newContentHeight); | 3579 return adjustContentBoxLogicalHeightForBoxSizing(newContentHeight); |
| 3476 } | 3580 } |
| 3477 | 3581 |
| 3478 // FIXME: This is wrong if the containingBlock has a perpendicular writing mod e. | 3582 // FIXME: This is wrong if the containingBlock has a perpendicular writing |
| 3583 // mode. | |
| 3479 LayoutUnit availableHeight = | 3584 LayoutUnit availableHeight = |
| 3480 containingBlockLogicalHeightForContent(heightType); | 3585 containingBlockLogicalHeightForContent(heightType); |
| 3481 if (heightType == ExcludeMarginBorderPadding) { | 3586 if (heightType == ExcludeMarginBorderPadding) { |
| 3482 // FIXME: Margin collapsing hasn't happened yet, so this incorrectly removes collapsed margins. | 3587 // FIXME: Margin collapsing hasn't happened yet, so this incorrectly removes |
| 3588 // collapsed margins. | |
| 3483 availableHeight -= | 3589 availableHeight -= |
| 3484 marginBefore() + marginAfter() + borderAndPaddingLogicalHeight(); | 3590 marginBefore() + marginAfter() + borderAndPaddingLogicalHeight(); |
| 3485 } | 3591 } |
| 3486 return availableHeight; | 3592 return availableHeight; |
| 3487 } | 3593 } |
| 3488 | 3594 |
| 3489 void LayoutBox::computeAndSetBlockDirectionMargins( | 3595 void LayoutBox::computeAndSetBlockDirectionMargins( |
| 3490 const LayoutBlock* containingBlock) { | 3596 const LayoutBlock* containingBlock) { |
| 3491 LayoutUnit marginBefore; | 3597 LayoutUnit marginBefore; |
| 3492 LayoutUnit marginAfter; | 3598 LayoutUnit marginAfter; |
| 3493 computeMarginsForDirection( | 3599 computeMarginsForDirection( |
| 3494 BlockDirection, containingBlock, containingBlockLogicalWidthForContent(), | 3600 BlockDirection, containingBlock, containingBlockLogicalWidthForContent(), |
| 3495 logicalHeight(), marginBefore, marginAfter, | 3601 logicalHeight(), marginBefore, marginAfter, |
| 3496 style()->marginBeforeUsing(containingBlock->style()), | 3602 style()->marginBeforeUsing(containingBlock->style()), |
| 3497 style()->marginAfterUsing(containingBlock->style())); | 3603 style()->marginAfterUsing(containingBlock->style())); |
| 3498 // Note that in this 'positioning phase' of the layout we are using the contai ning block's writing mode rather than our own when calculating margins. | 3604 // Note that in this 'positioning phase' of the layout we are using the |
| 3499 // See http://www.w3.org/TR/2014/CR-css-writing-modes-3-20140320/#orthogonal-f lows | 3605 // containing block's writing mode rather than our own when calculating |
| 3606 // margins. | |
| 3607 // http://www.w3.org/TR/2014/CR-css-writing-modes-3-20140320/#orthogonal-flows | |
| 3500 containingBlock->setMarginBeforeForChild(*this, marginBefore); | 3608 containingBlock->setMarginBeforeForChild(*this, marginBefore); |
| 3501 containingBlock->setMarginAfterForChild(*this, marginAfter); | 3609 containingBlock->setMarginAfterForChild(*this, marginAfter); |
| 3502 } | 3610 } |
| 3503 | 3611 |
| 3504 LayoutUnit LayoutBox::containingBlockLogicalWidthForPositioned( | 3612 LayoutUnit LayoutBox::containingBlockLogicalWidthForPositioned( |
| 3505 const LayoutBoxModelObject* containingBlock, | 3613 const LayoutBoxModelObject* containingBlock, |
| 3506 bool checkForPerpendicularWritingMode) const { | 3614 bool checkForPerpendicularWritingMode) const { |
| 3507 if (checkForPerpendicularWritingMode && | 3615 if (checkForPerpendicularWritingMode && |
| 3508 containingBlock->isHorizontalWritingMode() != isHorizontalWritingMode()) | 3616 containingBlock->isHorizontalWritingMode() != isHorizontalWritingMode()) |
| 3509 return containingBlockLogicalHeightForPositioned(containingBlock, false); | 3617 return containingBlockLogicalHeightForPositioned(containingBlock, false); |
| 3510 | 3618 |
| 3511 // Use viewport as container for top-level fixed-position elements. | 3619 // Use viewport as container for top-level fixed-position elements. |
| 3512 if (style()->position() == FixedPosition && containingBlock->isLayoutView() && | 3620 if (style()->position() == FixedPosition && containingBlock->isLayoutView() && |
| 3513 !document().printing()) { | 3621 !document().printing()) { |
| 3514 const LayoutView* view = toLayoutView(containingBlock); | 3622 const LayoutView* view = toLayoutView(containingBlock); |
| 3515 if (FrameView* frameView = view->frameView()) { | 3623 if (FrameView* frameView = view->frameView()) { |
| 3516 // Don't use visibleContentRect since the PaintLayer's size has not been s et yet. | 3624 // Don't use visibleContentRect since the PaintLayer's size has not been |
| 3625 // set yet. | |
| 3517 LayoutSize viewportSize( | 3626 LayoutSize viewportSize( |
| 3518 frameView->layoutViewportScrollableArea()->excludeScrollbars( | 3627 frameView->layoutViewportScrollableArea()->excludeScrollbars( |
| 3519 frameView->frameRect().size())); | 3628 frameView->frameRect().size())); |
| 3520 return LayoutUnit(containingBlock->isHorizontalWritingMode() | 3629 return LayoutUnit(containingBlock->isHorizontalWritingMode() |
| 3521 ? viewportSize.width() | 3630 ? viewportSize.width() |
| 3522 : viewportSize.height()); | 3631 : viewportSize.height()); |
| 3523 } | 3632 } |
| 3524 } | 3633 } |
| 3525 | 3634 |
| 3526 if (hasOverrideContainingBlockLogicalWidth()) | 3635 if (hasOverrideContainingBlockLogicalWidth()) |
| 3527 return overrideContainingBlockContentLogicalWidth(); | 3636 return overrideContainingBlockContentLogicalWidth(); |
| 3528 | 3637 |
| 3529 // Ensure we compute our width based on the width of our rel-pos inline contai ner rather than any anonymous block | 3638 // Ensure we compute our width based on the width of our rel-pos inline |
| 3530 // created to manage a block-flow ancestor of ours in the rel-pos inline's inl ine flow. | 3639 // container rather than any anonymous block created to manage a block-flow |
| 3640 // ancestor of ours in the rel-pos inline's inline flow. | |
| 3531 if (containingBlock->isAnonymousBlock() && containingBlock->isRelPositioned()) | 3641 if (containingBlock->isAnonymousBlock() && containingBlock->isRelPositioned()) |
| 3532 containingBlock = toLayoutBox(containingBlock)->continuation(); | 3642 containingBlock = toLayoutBox(containingBlock)->continuation(); |
| 3533 else if (containingBlock->isBox()) | 3643 else if (containingBlock->isBox()) |
| 3534 return std::max(LayoutUnit(), | 3644 return std::max(LayoutUnit(), |
| 3535 toLayoutBox(containingBlock)->clientLogicalWidth()); | 3645 toLayoutBox(containingBlock)->clientLogicalWidth()); |
| 3536 | 3646 |
| 3537 ASSERT(containingBlock->isLayoutInline() && | 3647 ASSERT(containingBlock->isLayoutInline() && |
| 3538 containingBlock->isInFlowPositioned()); | 3648 containingBlock->isInFlowPositioned()); |
| 3539 | 3649 |
| 3540 const LayoutInline* flow = toLayoutInline(containingBlock); | 3650 const LayoutInline* flow = toLayoutInline(containingBlock); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 3565 bool checkForPerpendicularWritingMode) const { | 3675 bool checkForPerpendicularWritingMode) const { |
| 3566 if (checkForPerpendicularWritingMode && | 3676 if (checkForPerpendicularWritingMode && |
| 3567 containingBlock->isHorizontalWritingMode() != isHorizontalWritingMode()) | 3677 containingBlock->isHorizontalWritingMode() != isHorizontalWritingMode()) |
| 3568 return containingBlockLogicalWidthForPositioned(containingBlock, false); | 3678 return containingBlockLogicalWidthForPositioned(containingBlock, false); |
| 3569 | 3679 |
| 3570 // Use viewport as container for top-level fixed-position elements. | 3680 // Use viewport as container for top-level fixed-position elements. |
| 3571 if (style()->position() == FixedPosition && containingBlock->isLayoutView() && | 3681 if (style()->position() == FixedPosition && containingBlock->isLayoutView() && |
| 3572 !document().printing()) { | 3682 !document().printing()) { |
| 3573 const LayoutView* view = toLayoutView(containingBlock); | 3683 const LayoutView* view = toLayoutView(containingBlock); |
| 3574 if (FrameView* frameView = view->frameView()) { | 3684 if (FrameView* frameView = view->frameView()) { |
| 3575 // Don't use visibleContentRect since the PaintLayer's size has not been s et yet. | 3685 // Don't use visibleContentRect since the PaintLayer's size has not been |
| 3686 // set yet. | |
| 3576 LayoutSize viewportSize( | 3687 LayoutSize viewportSize( |
| 3577 frameView->layoutViewportScrollableArea()->excludeScrollbars( | 3688 frameView->layoutViewportScrollableArea()->excludeScrollbars( |
| 3578 frameView->frameRect().size())); | 3689 frameView->frameRect().size())); |
| 3579 return containingBlock->isHorizontalWritingMode() ? viewportSize.height() | 3690 return containingBlock->isHorizontalWritingMode() ? viewportSize.height() |
| 3580 : viewportSize.width(); | 3691 : viewportSize.width(); |
| 3581 } | 3692 } |
| 3582 } | 3693 } |
| 3583 | 3694 |
| 3584 if (hasOverrideContainingBlockLogicalHeight()) | 3695 if (hasOverrideContainingBlockLogicalHeight()) |
| 3585 return overrideContainingBlockContentLogicalHeight(); | 3696 return overrideContainingBlockContentLogicalHeight(); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 3616 static LayoutUnit accumulateStaticOffsetForFlowThread( | 3727 static LayoutUnit accumulateStaticOffsetForFlowThread( |
| 3617 LayoutBox& layoutBox, | 3728 LayoutBox& layoutBox, |
| 3618 LayoutUnit inlinePosition, | 3729 LayoutUnit inlinePosition, |
| 3619 LayoutUnit& blockPosition) { | 3730 LayoutUnit& blockPosition) { |
| 3620 if (layoutBox.isTableRow()) | 3731 if (layoutBox.isTableRow()) |
| 3621 return LayoutUnit(); | 3732 return LayoutUnit(); |
| 3622 blockPosition += layoutBox.logicalTop(); | 3733 blockPosition += layoutBox.logicalTop(); |
| 3623 if (!layoutBox.isLayoutFlowThread()) | 3734 if (!layoutBox.isLayoutFlowThread()) |
| 3624 return LayoutUnit(); | 3735 return LayoutUnit(); |
| 3625 LayoutUnit previousInlinePosition = inlinePosition; | 3736 LayoutUnit previousInlinePosition = inlinePosition; |
| 3626 // We're walking out of a flowthread here. This flow thread is not in the cont aining block | 3737 // We're walking out of a flowthread here. This flow thread is not in the |
| 3627 // chain, so we need to convert the position from the coordinate space of this flowthread to | 3738 // containing block chain, so we need to convert the position from the |
| 3628 // the containing coordinate space. | 3739 // coordinate space of this flowthread to the containing coordinate space. |
| 3629 toLayoutFlowThread(layoutBox).flowThreadToContainingCoordinateSpace( | 3740 toLayoutFlowThread(layoutBox).flowThreadToContainingCoordinateSpace( |
| 3630 blockPosition, inlinePosition); | 3741 blockPosition, inlinePosition); |
| 3631 return inlinePosition - previousInlinePosition; | 3742 return inlinePosition - previousInlinePosition; |
| 3632 } | 3743 } |
| 3633 | 3744 |
| 3634 void LayoutBox::computeInlineStaticDistance( | 3745 void LayoutBox::computeInlineStaticDistance( |
| 3635 Length& logicalLeft, | 3746 Length& logicalLeft, |
| 3636 Length& logicalRight, | 3747 Length& logicalRight, |
| 3637 const LayoutBox* child, | 3748 const LayoutBox* child, |
| 3638 const LayoutBoxModelObject* containerBlock, | 3749 const LayoutBoxModelObject* containerBlock, |
| 3639 LayoutUnit containerLogicalWidth) { | 3750 LayoutUnit containerLogicalWidth) { |
| 3640 if (!logicalLeft.isAuto() || !logicalRight.isAuto()) | 3751 if (!logicalLeft.isAuto() || !logicalRight.isAuto()) |
| 3641 return; | 3752 return; |
| 3642 | 3753 |
| 3643 // For multicol we also need to keep track of the block position, since that d etermines which | 3754 // For multicol we also need to keep track of the block position, since that |
| 3644 // column we're in and thus affects the inline position. | 3755 // determines which column we're in and thus affects the inline position. |
| 3645 LayoutUnit staticBlockPosition = child->layer()->staticBlockPosition(); | 3756 LayoutUnit staticBlockPosition = child->layer()->staticBlockPosition(); |
| 3646 | 3757 |
| 3647 // FIXME: The static distance computation has not been patched for mixed writi ng modes yet. | 3758 // FIXME: The static distance computation has not been patched for mixed |
| 3759 // writing modes yet. | |
| 3648 if (child->parent()->style()->direction() == LTR) { | 3760 if (child->parent()->style()->direction() == LTR) { |
| 3649 LayoutUnit staticPosition = child->layer()->staticInlinePosition() - | 3761 LayoutUnit staticPosition = child->layer()->staticInlinePosition() - |
| 3650 containerBlock->borderLogicalLeft(); | 3762 containerBlock->borderLogicalLeft(); |
| 3651 for (LayoutObject* curr = child->parent(); curr && curr != containerBlock; | 3763 for (LayoutObject* curr = child->parent(); curr && curr != containerBlock; |
| 3652 curr = curr->container()) { | 3764 curr = curr->container()) { |
| 3653 if (curr->isBox()) { | 3765 if (curr->isBox()) { |
| 3654 staticPosition += toLayoutBox(curr)->logicalLeft(); | 3766 staticPosition += toLayoutBox(curr)->logicalLeft(); |
| 3655 if (toLayoutBox(curr)->isInFlowPositioned()) | 3767 if (toLayoutBox(curr)->isInFlowPositioned()) |
| 3656 staticPosition += | 3768 staticPosition += |
| 3657 toLayoutBox(curr)->offsetForInFlowPosition().width(); | 3769 toLayoutBox(curr)->offsetForInFlowPosition().width(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3705 if (curr == containerBlock) | 3817 if (curr == containerBlock) |
| 3706 break; | 3818 break; |
| 3707 } | 3819 } |
| 3708 logicalRight.setValue(Fixed, staticPosition); | 3820 logicalRight.setValue(Fixed, staticPosition); |
| 3709 } | 3821 } |
| 3710 } | 3822 } |
| 3711 | 3823 |
| 3712 void LayoutBox::computePositionedLogicalWidth( | 3824 void LayoutBox::computePositionedLogicalWidth( |
| 3713 LogicalExtentComputedValues& computedValues) const { | 3825 LogicalExtentComputedValues& computedValues) const { |
| 3714 // QUESTIONS | 3826 // QUESTIONS |
| 3715 // FIXME 1: Should we still deal with these the cases of 'left' or 'right' hav ing | 3827 // FIXME 1: Should we still deal with these the cases of 'left' or 'right' |
| 3716 // the type 'static' in determining whether to calculate the static distance? | 3828 // having the type 'static' in determining whether to calculate the static |
| 3829 // distance? | |
| 3717 // NOTE: 'static' is not a legal value for 'left' or 'right' as of CSS 2.1. | 3830 // NOTE: 'static' is not a legal value for 'left' or 'right' as of CSS 2.1. |
| 3718 | 3831 |
| 3719 // FIXME 2: Can perhaps optimize out cases when max-width/min-width are greate r | 3832 // FIXME 2: Can perhaps optimize out cases when max-width/min-width are |
| 3720 // than or less than the computed width(). Be careful of box-sizing and | 3833 // greater than or less than the computed width(). Be careful of box-sizing |
| 3721 // percentage issues. | 3834 // and percentage issues. |
| 3722 | 3835 |
| 3723 // The following is based off of the W3C Working Draft from April 11, 2006 of | 3836 // The following is based off of the W3C Working Draft from April 11, 2006 of |
| 3724 // CSS 2.1: Section 10.3.7 "Absolutely positioned, non-replaced elements" | 3837 // CSS 2.1: Section 10.3.7 "Absolutely positioned, non-replaced elements" |
| 3725 // <http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width> | 3838 // <http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width> |
| 3726 // (block-style-comments in this function and in computePositionedLogicalWidth Using() | 3839 // (block-style-comments in this function and in |
| 3727 // correspond to text from the spec) | 3840 // computePositionedLogicalWidthUsing() correspond to text from the spec) |
| 3728 | 3841 |
| 3729 // We don't use containingBlock(), since we may be positioned by an enclosing | 3842 // We don't use containingBlock(), since we may be positioned by an enclosing |
| 3730 // relative positioned inline. | 3843 // relative positioned inline. |
| 3731 const LayoutBoxModelObject* containerBlock = | 3844 const LayoutBoxModelObject* containerBlock = |
| 3732 toLayoutBoxModelObject(container()); | 3845 toLayoutBoxModelObject(container()); |
| 3733 | 3846 |
| 3734 const LayoutUnit containerLogicalWidth = | 3847 const LayoutUnit containerLogicalWidth = |
| 3735 containingBlockLogicalWidthForPositioned(containerBlock); | 3848 containingBlockLogicalWidthForPositioned(containerBlock); |
| 3736 | 3849 |
| 3737 // Use the container block's direction except when calculating the static dist ance | 3850 // Use the container block's direction except when calculating the static |
| 3738 // This conforms with the reference results for abspos-replaced-width-margin-0 00.htm | 3851 // distance. This conforms with the reference results for |
| 3739 // of the CSS 2.1 test suite | 3852 // abspos-replaced-width-margin-000.htm of the CSS 2.1 test suite. |
| 3740 TextDirection containerDirection = containerBlock->style()->direction(); | 3853 TextDirection containerDirection = containerBlock->style()->direction(); |
| 3741 | 3854 |
| 3742 bool isHorizontal = isHorizontalWritingMode(); | 3855 bool isHorizontal = isHorizontalWritingMode(); |
| 3743 const LayoutUnit bordersPlusPadding = borderAndPaddingLogicalWidth(); | 3856 const LayoutUnit bordersPlusPadding = borderAndPaddingLogicalWidth(); |
| 3744 const Length marginLogicalLeft = | 3857 const Length marginLogicalLeft = |
| 3745 isHorizontal ? style()->marginLeft() : style()->marginTop(); | 3858 isHorizontal ? style()->marginLeft() : style()->marginTop(); |
| 3746 const Length marginLogicalRight = | 3859 const Length marginLogicalRight = |
| 3747 isHorizontal ? style()->marginRight() : style()->marginBottom(); | 3860 isHorizontal ? style()->marginRight() : style()->marginBottom(); |
| 3748 | 3861 |
| 3749 Length logicalLeftLength = style()->logicalLeft(); | 3862 Length logicalLeftLength = style()->logicalLeft(); |
| 3750 Length logicalRightLength = style()->logicalRight(); | 3863 Length logicalRightLength = style()->logicalRight(); |
| 3751 | 3864 // --------------------------------------------------------------------------- |
| 3752 /*---------------------------------------------------------------------------* \ | 3865 // For the purposes of this section and the next, the term "static position" |
| 3753 * For the purposes of this section and the next, the term "static position" | 3866 // (of an element) refers, roughly, to the position an element would have had |
| 3754 * (of an element) refers, roughly, to the position an element would have ha d | 3867 // in the normal flow. More precisely: |
| 3755 * in the normal flow. More precisely: | 3868 // |
| 3756 * | 3869 // * The static position for 'left' is the distance from the left edge of the |
| 3757 * * The static position for 'left' is the distance from the left edge of th e | 3870 // containing block to the left margin edge of a hypothetical box that |
| 3758 * containing block to the left margin edge of a hypothetical box that wou ld | 3871 // would have been the first box of the element if its 'position' property |
| 3759 * have been the first box of the element if its 'position' property had | 3872 // had been 'static' and 'float' had been 'none'. The value is negative if |
| 3760 * been 'static' and 'float' had been 'none'. The value is negative if the | 3873 // the hypothetical box is to the left of the containing block. |
| 3761 * hypothetical box is to the left of the containing block. | 3874 // * The static position for 'right' is the distance from the right edge of |
| 3762 * * The static position for 'right' is the distance from the right edge of the | 3875 // the containing block to the right margin edge of the same hypothetical |
| 3763 * containing block to the right margin edge of the same hypothetical box as | 3876 // box as above. The value is positive if the hypothetical box is to the |
| 3764 * above. The value is positive if the hypothetical box is to the left of the | 3877 // left of the containing block's edge. |
| 3765 * containing block's edge. | 3878 // |
| 3766 * | 3879 // But rather than actually calculating the dimensions of that hypothetical |
| 3767 * But rather than actually calculating the dimensions of that hypothetical box, | 3880 // box, user agents are free to make a guess at its probable position. |
| 3768 * user agents are free to make a guess at its probable position. | 3881 // |
| 3769 * | 3882 // For the purposes of calculating the static position, the containing block |
| 3770 * For the purposes of calculating the static position, the containing block of | 3883 // of fixed positioned elements is the initial containing block instead of |
| 3771 * fixed positioned elements is the initial containing block instead of the | 3884 // the viewport, and all scrollable boxes should be assumed to be scrolled to |
| 3772 * viewport, and all scrollable boxes should be assumed to be scrolled to th eir | 3885 // their origin. |
| 3773 * origin. | 3886 // --------------------------------------------------------------------------- |
| 3774 \*-------------------------------------------------------------------------- -*/ | |
| 3775 | |
| 3776 // see FIXME 1 | 3887 // see FIXME 1 |
| 3777 // Calculate the static distance if needed. | 3888 // Calculate the static distance if needed. |
| 3778 computeInlineStaticDistance(logicalLeftLength, logicalRightLength, this, | 3889 computeInlineStaticDistance(logicalLeftLength, logicalRightLength, this, |
| 3779 containerBlock, containerLogicalWidth); | 3890 containerBlock, containerLogicalWidth); |
| 3780 | 3891 |
| 3781 // Calculate constraint equation values for 'width' case. | 3892 // Calculate constraint equation values for 'width' case. |
| 3782 computePositionedLogicalWidthUsing( | 3893 computePositionedLogicalWidthUsing( |
| 3783 MainOrPreferredSize, style()->logicalWidth(), containerBlock, | 3894 MainOrPreferredSize, style()->logicalWidth(), containerBlock, |
| 3784 containerDirection, containerLogicalWidth, bordersPlusPadding, | 3895 containerDirection, containerLogicalWidth, bordersPlusPadding, |
| 3785 logicalLeftLength, logicalRightLength, marginLogicalLeft, | 3896 logicalLeftLength, logicalRightLength, marginLogicalLeft, |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3825 | 3936 |
| 3826 computedValues.m_extent += bordersPlusPadding; | 3937 computedValues.m_extent += bordersPlusPadding; |
| 3827 } | 3938 } |
| 3828 | 3939 |
| 3829 void LayoutBox::computeLogicalLeftPositionedOffset( | 3940 void LayoutBox::computeLogicalLeftPositionedOffset( |
| 3830 LayoutUnit& logicalLeftPos, | 3941 LayoutUnit& logicalLeftPos, |
| 3831 const LayoutBox* child, | 3942 const LayoutBox* child, |
| 3832 LayoutUnit logicalWidthValue, | 3943 LayoutUnit logicalWidthValue, |
| 3833 const LayoutBoxModelObject* containerBlock, | 3944 const LayoutBoxModelObject* containerBlock, |
| 3834 LayoutUnit containerLogicalWidth) { | 3945 LayoutUnit containerLogicalWidth) { |
| 3835 // Deal with differing writing modes here. Our offset needs to be in the cont aining block's coordinate space. If the containing block is flipped | 3946 // Deal with differing writing modes here. Our offset needs to be in the |
| 3836 // along this axis, then we need to flip the coordinate. This can only happen if the containing block is both a flipped mode and perpendicular to us. | 3947 // containing block's coordinate space. If the containing block is flipped |
| 3948 // along this axis, then we need to flip the coordinate. This can only happen | |
| 3949 // if the containing block is both a flipped mode and perpendicular to us. | |
| 3837 if (containerBlock->isHorizontalWritingMode() != | 3950 if (containerBlock->isHorizontalWritingMode() != |
| 3838 child->isHorizontalWritingMode() && | 3951 child->isHorizontalWritingMode() && |
| 3839 containerBlock->style()->isFlippedBlocksWritingMode()) { | 3952 containerBlock->style()->isFlippedBlocksWritingMode()) { |
| 3840 logicalLeftPos = containerLogicalWidth - logicalWidthValue - logicalLeftPos; | 3953 logicalLeftPos = containerLogicalWidth - logicalWidthValue - logicalLeftPos; |
| 3841 logicalLeftPos += | 3954 logicalLeftPos += |
| 3842 (child->isHorizontalWritingMode() ? containerBlock->borderRight() | 3955 (child->isHorizontalWritingMode() ? containerBlock->borderRight() |
| 3843 : containerBlock->borderBottom()); | 3956 : containerBlock->borderBottom()); |
| 3844 } else { | 3957 } else { |
| 3845 logicalLeftPos += | 3958 logicalLeftPos += |
| 3846 (child->isHorizontalWritingMode() ? containerBlock->borderLeft() | 3959 (child->isHorizontalWritingMode() ? containerBlock->borderLeft() |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3883 bordersPlusPadding) - | 3996 bordersPlusPadding) - |
| 3884 bordersPlusPadding; | 3997 bordersPlusPadding; |
| 3885 else | 3998 else |
| 3886 logicalWidthValue = adjustContentBoxLogicalWidthForBoxSizing( | 3999 logicalWidthValue = adjustContentBoxLogicalWidthForBoxSizing( |
| 3887 valueForLength(logicalWidth, containerLogicalWidth)); | 4000 valueForLength(logicalWidth, containerLogicalWidth)); |
| 3888 | 4001 |
| 3889 // 'left' and 'right' cannot both be 'auto' because one would of been | 4002 // 'left' and 'right' cannot both be 'auto' because one would of been |
| 3890 // converted to the static position already | 4003 // converted to the static position already |
| 3891 ASSERT(!(logicalLeft.isAuto() && logicalRight.isAuto())); | 4004 ASSERT(!(logicalLeft.isAuto() && logicalRight.isAuto())); |
| 3892 | 4005 |
| 3893 // minimumValueForLength will convert 'auto' to 0 so that it doesn't impact th e available space computation below. | 4006 // minimumValueForLength will convert 'auto' to 0 so that it doesn't impact |
| 4007 // the available space computation below. | |
| 3894 LayoutUnit logicalLeftValue = | 4008 LayoutUnit logicalLeftValue = |
| 3895 minimumValueForLength(logicalLeft, containerLogicalWidth); | 4009 minimumValueForLength(logicalLeft, containerLogicalWidth); |
| 3896 LayoutUnit logicalRightValue = | 4010 LayoutUnit logicalRightValue = |
| 3897 minimumValueForLength(logicalRight, containerLogicalWidth); | 4011 minimumValueForLength(logicalRight, containerLogicalWidth); |
| 3898 | 4012 |
| 3899 const LayoutUnit containerRelativeLogicalWidth = | 4013 const LayoutUnit containerRelativeLogicalWidth = |
| 3900 containingBlockLogicalWidthForPositioned(containerBlock, false); | 4014 containingBlockLogicalWidthForPositioned(containerBlock, false); |
| 3901 | 4015 |
| 3902 bool logicalWidthIsAuto = logicalWidth.isAuto(); | 4016 bool logicalWidthIsAuto = logicalWidth.isAuto(); |
| 3903 bool logicalLeftIsAuto = logicalLeft.isAuto(); | 4017 bool logicalLeftIsAuto = logicalLeft.isAuto(); |
| 3904 bool logicalRightIsAuto = logicalRight.isAuto(); | 4018 bool logicalRightIsAuto = logicalRight.isAuto(); |
| 3905 LayoutUnit& marginLogicalLeftValue = style()->isLeftToRightDirection() | 4019 LayoutUnit& marginLogicalLeftValue = style()->isLeftToRightDirection() |
| 3906 ? computedValues.m_margins.m_start | 4020 ? computedValues.m_margins.m_start |
| 3907 : computedValues.m_margins.m_end; | 4021 : computedValues.m_margins.m_end; |
| 3908 LayoutUnit& marginLogicalRightValue = style()->isLeftToRightDirection() | 4022 LayoutUnit& marginLogicalRightValue = style()->isLeftToRightDirection() |
| 3909 ? computedValues.m_margins.m_end | 4023 ? computedValues.m_margins.m_end |
| 3910 : computedValues.m_margins.m_start; | 4024 : computedValues.m_margins.m_start; |
| 3911 if (!logicalLeftIsAuto && !logicalWidthIsAuto && !logicalRightIsAuto) { | 4025 if (!logicalLeftIsAuto && !logicalWidthIsAuto && !logicalRightIsAuto) { |
| 3912 /*-----------------------------------------------------------------------*\ | 4026 // ------------------------------------------------------------------------- |
| 3913 * If none of the three is 'auto': If both 'margin-left' and 'margin- | 4027 // If none of the three is 'auto': If both 'margin-left' and 'margin- |
| 3914 * right' are 'auto', solve the equation under the extra constraint that | 4028 // right' are 'auto', solve the equation under the extra constraint that |
| 3915 * the two margins get equal values, unless this would make them negativ e, | 4029 // the two margins get equal values, unless this would make them negative, |
| 3916 * in which case when direction of the containing block is 'ltr' ('rtl') , | 4030 // in which case when direction of the containing block is 'ltr' ('rtl'), |
| 3917 * set 'margin-left' ('margin-right') to zero and solve for 'margin-righ t' | 4031 // set 'margin-left' ('margin-right') to zero and solve for 'margin-right' |
| 3918 * ('margin-left'). If one of 'margin-left' or 'margin-right' is 'auto', | 4032 // ('margin-left'). If one of 'margin-left' or 'margin-right' is 'auto', |
| 3919 * solve the equation for that value. If the values are over-constrained , | 4033 // solve the equation for that value. If the values are over-constrained, |
| 3920 * ignore the value for 'left' (in case the 'direction' property of the | 4034 // ignore the value for 'left' (in case the 'direction' property of the |
| 3921 * containing block is 'rtl') or 'right' (in case 'direction' is 'ltr') | 4035 // containing block is 'rtl') or 'right' (in case 'direction' is 'ltr') |
| 3922 * and solve for that value. | 4036 // and solve for that value. |
| 3923 \*---------------------------------------------------------------------- -*/ | 4037 // ------------------------------------------------------------------------- |
| 3924 // NOTE: It is not necessary to solve for 'right' in the over constrained | 4038 // NOTE: It is not necessary to solve for 'right' in the over constrained |
| 3925 // case because the value is not used for any further calculations. | 4039 // case because the value is not used for any further calculations. |
| 3926 | 4040 |
| 3927 computedValues.m_extent = logicalWidthValue; | 4041 computedValues.m_extent = logicalWidthValue; |
| 3928 | 4042 |
| 3929 const LayoutUnit availableSpace = | 4043 const LayoutUnit availableSpace = |
| 3930 containerLogicalWidth - (logicalLeftValue + computedValues.m_extent + | 4044 containerLogicalWidth - (logicalLeftValue + computedValues.m_extent + |
| 3931 logicalRightValue + bordersPlusPadding); | 4045 logicalRightValue + bordersPlusPadding); |
| 3932 | 4046 |
| 3933 // Margins are now the only unknown | 4047 // Margins are now the only unknown |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3966 marginLogicalRightValue = | 4080 marginLogicalRightValue = |
| 3967 valueForLength(marginLogicalRight, containerRelativeLogicalWidth); | 4081 valueForLength(marginLogicalRight, containerRelativeLogicalWidth); |
| 3968 | 4082 |
| 3969 // Use the containing block's direction rather than the parent block's | 4083 // Use the containing block's direction rather than the parent block's |
| 3970 // per CSS 2.1 reference test abspos-non-replaced-width-margin-000. | 4084 // per CSS 2.1 reference test abspos-non-replaced-width-margin-000. |
| 3971 if (containerDirection == RTL) | 4085 if (containerDirection == RTL) |
| 3972 logicalLeftValue = (availableSpace + logicalLeftValue) - | 4086 logicalLeftValue = (availableSpace + logicalLeftValue) - |
| 3973 marginLogicalLeftValue - marginLogicalRightValue; | 4087 marginLogicalLeftValue - marginLogicalRightValue; |
| 3974 } | 4088 } |
| 3975 } else { | 4089 } else { |
| 3976 /*--------------------------------------------------------------------*\ | 4090 // ------------------------------------------------------------------------- |
| 3977 * Otherwise, set 'auto' values for 'margin-left' and 'margin-right' | 4091 // Otherwise, set 'auto' values for 'margin-left' and 'margin-right' |
| 3978 * to 0, and pick the one of the following six rules that applies. | 4092 // to 0, and pick the one of the following six rules that applies. |
| 3979 * | 4093 // |
| 3980 * 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the | 4094 // 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the |
| 3981 * width is shrink-to-fit. Then solve for 'left' | 4095 // width is shrink-to-fit. Then solve for 'left' |
| 3982 * | 4096 // |
| 3983 * OMIT RULE 2 AS IT SHOULD NEVER BE HIT | 4097 // OMIT RULE 2 AS IT SHOULD NEVER BE HIT |
| 3984 * ------------------------------------------------------------------ | 4098 // ------------------------------------------------------------------ |
| 3985 * 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if | 4099 // 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if |
| 3986 * the 'direction' property of the containing block is 'ltr' set | 4100 // the 'direction' property of the containing block is 'ltr' set |
| 3987 * 'left' to the static position, otherwise set 'right' to the | 4101 // 'left' to the static position, otherwise set 'right' to the |
| 3988 * static position. Then solve for 'left' (if 'direction is 'rtl') | 4102 // static position. Then solve for 'left' (if 'direction is 'rtl') |
| 3989 * or 'right' (if 'direction' is 'ltr'). | 4103 // or 'right' (if 'direction' is 'ltr'). |
| 3990 * ------------------------------------------------------------------ | 4104 // ------------------------------------------------------------------ |
| 3991 * | 4105 // |
| 3992 * 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the | 4106 // 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the |
| 3993 * width is shrink-to-fit . Then solve for 'right' | 4107 // width is shrink-to-fit . Then solve for 'right' |
| 3994 * 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve | 4108 // 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve |
| 3995 * for 'left' | 4109 // for 'left' |
| 3996 * 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve | 4110 // 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve |
| 3997 * for 'width' | 4111 // for 'width' |
| 3998 * 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve | 4112 // 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve |
| 3999 * for 'right' | 4113 // for 'right' |
| 4000 * | 4114 // |
| 4001 * Calculation of the shrink-to-fit width is similar to calculating the | 4115 // Calculation of the shrink-to-fit width is similar to calculating the |
| 4002 * width of a table cell using the automatic table layout algorithm. | 4116 // width of a table cell using the automatic table layout algorithm. |
| 4003 * Roughly: calculate the preferred width by formatting the content | 4117 // Roughly: calculate the preferred width by formatting the content without |
| 4004 * without breaking lines other than where explicit line breaks occur, | 4118 // breaking lines other than where explicit line breaks occur, and also |
| 4005 * and also calculate the preferred minimum width, e.g., by trying all | 4119 // calculate the preferred minimum width, e.g., by trying all possible line |
| 4006 * possible line breaks. CSS 2.1 does not define the exact algorithm. | 4120 // breaks. CSS 2.1 does not define the exact algorithm. |
| 4007 * Thirdly, calculate the available width: this is found by solving | 4121 // Thirdly, calculate the available width: this is found by solving for |
| 4008 * for 'width' after setting 'left' (in case 1) or 'right' (in case 3) | 4122 // 'width' after setting 'left' (in case 1) or 'right' (in case 3) to 0. |
| 4009 * to 0. | 4123 // |
| 4010 * | 4124 // Then the shrink-to-fit width is: |
| 4011 * Then the shrink-to-fit width is: | 4125 // min(max(preferred minimum width, available width), preferred width). |
| 4012 * min(max(preferred minimum width, available width), preferred width). | 4126 // ------------------------------------------------------------------------- |
| 4013 \*--------------------------------------------------------------------*/ | |
| 4014 // NOTE: For rules 3 and 6 it is not necessary to solve for 'right' | 4127 // NOTE: For rules 3 and 6 it is not necessary to solve for 'right' |
| 4015 // because the value is not used for any further calculations. | 4128 // because the value is not used for any further calculations. |
| 4016 | 4129 |
| 4017 // Calculate margins, 'auto' margins are ignored. | 4130 // Calculate margins, 'auto' margins are ignored. |
| 4018 marginLogicalLeftValue = | 4131 marginLogicalLeftValue = |
| 4019 minimumValueForLength(marginLogicalLeft, containerRelativeLogicalWidth); | 4132 minimumValueForLength(marginLogicalLeft, containerRelativeLogicalWidth); |
| 4020 marginLogicalRightValue = minimumValueForLength( | 4133 marginLogicalRightValue = minimumValueForLength( |
| 4021 marginLogicalRight, containerRelativeLogicalWidth); | 4134 marginLogicalRight, containerRelativeLogicalWidth); |
| 4022 | 4135 |
| 4023 const LayoutUnit availableSpace = | 4136 const LayoutUnit availableSpace = |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 4051 computedValues.m_extent = std::max(LayoutUnit(), availableSpace); | 4164 computedValues.m_extent = std::max(LayoutUnit(), availableSpace); |
| 4052 } else if (!logicalLeftIsAuto && !logicalWidthIsAuto && | 4165 } else if (!logicalLeftIsAuto && !logicalWidthIsAuto && |
| 4053 logicalRightIsAuto) { | 4166 logicalRightIsAuto) { |
| 4054 // RULE 6: (no need solve for right) | 4167 // RULE 6: (no need solve for right) |
| 4055 computedValues.m_extent = logicalWidthValue; | 4168 computedValues.m_extent = logicalWidthValue; |
| 4056 } | 4169 } |
| 4057 } | 4170 } |
| 4058 | 4171 |
| 4059 // Use computed values to calculate the horizontal position. | 4172 // Use computed values to calculate the horizontal position. |
| 4060 | 4173 |
| 4061 // FIXME: This hack is needed to calculate the logical left position for a 'r tl' relatively | 4174 // FIXME: This hack is needed to calculate the logical left position for a |
| 4062 // positioned, inline because right now, it is using the logical left position | 4175 // 'rtl' relatively positioned, inline because right now, it is using the |
| 4063 // of the first line box when really it should use the last line box. When | 4176 // logical left position of the first line box when really it should use the |
| 4064 // this is fixed elsewhere, this block should be removed. | 4177 // last line box. When this is fixed elsewhere, this block should be removed. |
| 4065 if (containerBlock->isLayoutInline() && | 4178 if (containerBlock->isLayoutInline() && |
| 4066 !containerBlock->style()->isLeftToRightDirection()) { | 4179 !containerBlock->style()->isLeftToRightDirection()) { |
| 4067 const LayoutInline* flow = toLayoutInline(containerBlock); | 4180 const LayoutInline* flow = toLayoutInline(containerBlock); |
| 4068 InlineFlowBox* firstLine = flow->firstLineBox(); | 4181 InlineFlowBox* firstLine = flow->firstLineBox(); |
| 4069 InlineFlowBox* lastLine = flow->lastLineBox(); | 4182 InlineFlowBox* lastLine = flow->lastLineBox(); |
| 4070 if (firstLine && lastLine && firstLine != lastLine) { | 4183 if (firstLine && lastLine && firstLine != lastLine) { |
| 4071 computedValues.m_position = | 4184 computedValues.m_position = |
| 4072 logicalLeftValue + marginLogicalLeftValue + | 4185 logicalLeftValue + marginLogicalLeftValue + |
| 4073 lastLine->borderLogicalLeft() + | 4186 lastLine->borderLogicalLeft() + |
| 4074 (lastLine->logicalLeft() - firstLine->logicalLeft()); | 4187 (lastLine->logicalLeft() - firstLine->logicalLeft()); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 4091 } | 4204 } |
| 4092 | 4205 |
| 4093 void LayoutBox::computeBlockStaticDistance( | 4206 void LayoutBox::computeBlockStaticDistance( |
| 4094 Length& logicalTop, | 4207 Length& logicalTop, |
| 4095 Length& logicalBottom, | 4208 Length& logicalBottom, |
| 4096 const LayoutBox* child, | 4209 const LayoutBox* child, |
| 4097 const LayoutBoxModelObject* containerBlock) { | 4210 const LayoutBoxModelObject* containerBlock) { |
| 4098 if (!logicalTop.isAuto() || !logicalBottom.isAuto()) | 4211 if (!logicalTop.isAuto() || !logicalBottom.isAuto()) |
| 4099 return; | 4212 return; |
| 4100 | 4213 |
| 4101 // FIXME: The static distance computation has not been patched for mixed writi ng modes. | 4214 // FIXME: The static distance computation has not been patched for mixed |
| 4215 // writing modes. | |
| 4102 LayoutUnit staticLogicalTop = child->layer()->staticBlockPosition(); | 4216 LayoutUnit staticLogicalTop = child->layer()->staticBlockPosition(); |
| 4103 for (LayoutObject* curr = child->parent(); curr && curr != containerBlock; | 4217 for (LayoutObject* curr = child->parent(); curr && curr != containerBlock; |
| 4104 curr = curr->container()) { | 4218 curr = curr->container()) { |
| 4105 if (!curr->isBox() || curr->isTableRow()) | 4219 if (!curr->isBox() || curr->isTableRow()) |
| 4106 continue; | 4220 continue; |
| 4107 const LayoutBox& box = *toLayoutBox(curr); | 4221 const LayoutBox& box = *toLayoutBox(curr); |
| 4108 staticLogicalTop += box.logicalTop(); | 4222 staticLogicalTop += box.logicalTop(); |
| 4109 if (!box.isLayoutFlowThread()) | 4223 if (!box.isLayoutFlowThread()) |
| 4110 continue; | 4224 continue; |
| 4111 // We're walking out of a flowthread here. This flow thread is not in the co ntaining block | 4225 // We're walking out of a flowthread here. This flow thread is not in the |
| 4112 // chain, so we need to convert the position from the coordinate space of th is flowthread | 4226 // containing block chain, so we need to convert the position from the |
| 4113 // to the containing coordinate space. The inline position cannot affect the block | 4227 // coordinate space of this flowthread to the containing coordinate space. |
| 4114 // position, so we don't bother calculating it. | 4228 // The inline position cannot affect the block position, so we don't bother |
| 4229 // calculating it. | |
| 4115 LayoutUnit dummyInlinePosition; | 4230 LayoutUnit dummyInlinePosition; |
| 4116 toLayoutFlowThread(box).flowThreadToContainingCoordinateSpace( | 4231 toLayoutFlowThread(box).flowThreadToContainingCoordinateSpace( |
| 4117 staticLogicalTop, dummyInlinePosition); | 4232 staticLogicalTop, dummyInlinePosition); |
| 4118 } | 4233 } |
| 4119 logicalTop.setValue(Fixed, staticLogicalTop - containerBlock->borderBefore()); | 4234 logicalTop.setValue(Fixed, staticLogicalTop - containerBlock->borderBefore()); |
| 4120 } | 4235 } |
| 4121 | 4236 |
| 4122 void LayoutBox::computePositionedLogicalHeight( | 4237 void LayoutBox::computePositionedLogicalHeight( |
| 4123 LogicalExtentComputedValues& computedValues) const { | 4238 LogicalExtentComputedValues& computedValues) const { |
| 4124 // The following is based off of the W3C Working Draft from April 11, 2006 of | 4239 // The following is based off of the W3C Working Draft from April 11, 2006 of |
| 4125 // CSS 2.1: Section 10.6.4 "Absolutely positioned, non-replaced elements" | 4240 // CSS 2.1: Section 10.6.4 "Absolutely positioned, non-replaced elements" |
| 4126 // <http://www.w3.org/TR/2005/WD-CSS21-20050613/visudet.html#abs-non-replaced- height> | 4241 // <http://www.w3.org/TR/2005/WD-CSS21-20050613/visudet.html#abs-non-replaced- height> |
| 4127 // (block-style-comments in this function and in computePositionedLogicalHeigh tUsing() | 4242 // (block-style-comments in this function and in |
| 4243 // computePositionedLogicalHeightUsing() | |
| 4128 // correspond to text from the spec) | 4244 // correspond to text from the spec) |
| 4129 | 4245 |
| 4130 // We don't use containingBlock(), since we may be positioned by an enclosing relpositioned inline. | 4246 // We don't use containingBlock(), since we may be positioned by an enclosing |
| 4247 // relpositioned inline. | |
| 4131 const LayoutBoxModelObject* containerBlock = | 4248 const LayoutBoxModelObject* containerBlock = |
| 4132 toLayoutBoxModelObject(container()); | 4249 toLayoutBoxModelObject(container()); |
| 4133 | 4250 |
| 4134 const LayoutUnit containerLogicalHeight = | 4251 const LayoutUnit containerLogicalHeight = |
| 4135 containingBlockLogicalHeightForPositioned(containerBlock); | 4252 containingBlockLogicalHeightForPositioned(containerBlock); |
| 4136 | 4253 |
| 4137 const ComputedStyle& styleToUse = styleRef(); | 4254 const ComputedStyle& styleToUse = styleRef(); |
| 4138 const LayoutUnit bordersPlusPadding = borderAndPaddingLogicalHeight(); | 4255 const LayoutUnit bordersPlusPadding = borderAndPaddingLogicalHeight(); |
| 4139 const Length marginBefore = styleToUse.marginBefore(); | 4256 const Length marginBefore = styleToUse.marginBefore(); |
| 4140 const Length marginAfter = styleToUse.marginAfter(); | 4257 const Length marginAfter = styleToUse.marginAfter(); |
| 4141 Length logicalTopLength = styleToUse.logicalTop(); | 4258 Length logicalTopLength = styleToUse.logicalTop(); |
| 4142 Length logicalBottomLength = styleToUse.logicalBottom(); | 4259 Length logicalBottomLength = styleToUse.logicalBottom(); |
| 4143 | 4260 |
| 4144 /*---------------------------------------------------------------------------* \ | 4261 // --------------------------------------------------------------------------- |
| 4145 * For the purposes of this section and the next, the term "static position" | 4262 // For the purposes of this section and the next, the term "static position" |
| 4146 * (of an element) refers, roughly, to the position an element would have ha d | 4263 // (of an element) refers, roughly, to the position an element would have had |
| 4147 * in the normal flow. More precisely, the static position for 'top' is the | 4264 // in the normal flow. More precisely, the static position for 'top' is the |
| 4148 * distance from the top edge of the containing block to the top margin edge | 4265 // distance from the top edge of the containing block to the top margin edge |
| 4149 * of a hypothetical box that would have been the first box of the element i f | 4266 // of a hypothetical box that would have been the first box of the element if |
| 4150 * its 'position' property had been 'static' and 'float' had been 'none'. Th e | 4267 // its 'position' property had been 'static' and 'float' had been 'none'. The |
| 4151 * value is negative if the hypothetical box is above the containing block. | 4268 // value is negative if the hypothetical box is above the containing block. |
| 4152 * | 4269 // |
| 4153 * But rather than actually calculating the dimensions of that hypothetical | 4270 // But rather than actually calculating the dimensions of that hypothetical |
| 4154 * box, user agents are free to make a guess at its probable position. | 4271 // box, user agents are free to make a guess at its probable position. |
| 4155 * | 4272 // |
| 4156 * For the purposes of calculating the static position, the containing block | 4273 // For the purposes of calculating the static position, the containing block |
| 4157 * of fixed positioned elements is the initial containing block instead of | 4274 // of fixed positioned elements is the initial containing block instead of |
| 4158 * the viewport. | 4275 // the viewport. |
| 4159 \*-------------------------------------------------------------------------- -*/ | 4276 // --------------------------------------------------------------------------- |
| 4160 | |
| 4161 // see FIXME 1 | 4277 // see FIXME 1 |
| 4162 // Calculate the static distance if needed. | 4278 // Calculate the static distance if needed. |
| 4163 computeBlockStaticDistance(logicalTopLength, logicalBottomLength, this, | 4279 computeBlockStaticDistance(logicalTopLength, logicalBottomLength, this, |
| 4164 containerBlock); | 4280 containerBlock); |
| 4165 | 4281 |
| 4166 // Calculate constraint equation values for 'height' case. | 4282 // Calculate constraint equation values for 'height' case. |
| 4167 LayoutUnit logicalHeight = computedValues.m_extent; | 4283 LayoutUnit logicalHeight = computedValues.m_extent; |
| 4168 computePositionedLogicalHeightUsing( | 4284 computePositionedLogicalHeightUsing( |
| 4169 MainOrPreferredSize, styleToUse.logicalHeight(), containerBlock, | 4285 MainOrPreferredSize, styleToUse.logicalHeight(), containerBlock, |
| 4170 containerLogicalHeight, bordersPlusPadding, logicalHeight, | 4286 containerLogicalHeight, bordersPlusPadding, logicalHeight, |
| 4171 logicalTopLength, logicalBottomLength, marginBefore, marginAfter, | 4287 logicalTopLength, logicalBottomLength, marginBefore, marginAfter, |
| 4172 computedValues); | 4288 computedValues); |
| 4173 | 4289 |
| 4174 // Avoid doing any work in the common case (where the values of min-height and max-height are their defaults). | 4290 // Avoid doing any work in the common case (where the values of min-height and |
| 4291 // max-height are their defaults). | |
| 4175 // see FIXME 2 | 4292 // see FIXME 2 |
| 4176 | 4293 |
| 4177 // Calculate constraint equation values for 'max-height' case. | 4294 // Calculate constraint equation values for 'max-height' case. |
| 4178 if (!styleToUse.logicalMaxHeight().isMaxSizeNone()) { | 4295 if (!styleToUse.logicalMaxHeight().isMaxSizeNone()) { |
| 4179 LogicalExtentComputedValues maxValues; | 4296 LogicalExtentComputedValues maxValues; |
| 4180 | 4297 |
| 4181 computePositionedLogicalHeightUsing(MaxSize, styleToUse.logicalMaxHeight(), | 4298 computePositionedLogicalHeightUsing(MaxSize, styleToUse.logicalMaxHeight(), |
| 4182 containerBlock, containerLogicalHeight, | 4299 containerBlock, containerLogicalHeight, |
| 4183 bordersPlusPadding, logicalHeight, | 4300 bordersPlusPadding, logicalHeight, |
| 4184 logicalTopLength, logicalBottomLength, | 4301 logicalTopLength, logicalBottomLength, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4217 // Set final height value. | 4334 // Set final height value. |
| 4218 computedValues.m_extent += bordersPlusPadding; | 4335 computedValues.m_extent += bordersPlusPadding; |
| 4219 } | 4336 } |
| 4220 | 4337 |
| 4221 void LayoutBox::computeLogicalTopPositionedOffset( | 4338 void LayoutBox::computeLogicalTopPositionedOffset( |
| 4222 LayoutUnit& logicalTopPos, | 4339 LayoutUnit& logicalTopPos, |
| 4223 const LayoutBox* child, | 4340 const LayoutBox* child, |
| 4224 LayoutUnit logicalHeightValue, | 4341 LayoutUnit logicalHeightValue, |
| 4225 const LayoutBoxModelObject* containerBlock, | 4342 const LayoutBoxModelObject* containerBlock, |
| 4226 LayoutUnit containerLogicalHeight) { | 4343 LayoutUnit containerLogicalHeight) { |
| 4227 // Deal with differing writing modes here. Our offset needs to be in the cont aining block's coordinate space. If the containing block is flipped | 4344 // Deal with differing writing modes here. Our offset needs to be in the |
| 4228 // along this axis, then we need to flip the coordinate. This can only happen if the containing block is both a flipped mode and perpendicular to us. | 4345 // containing block's coordinate space. If the containing block is flipped |
| 4346 // along this axis, then we need to flip the coordinate. This can only happen | |
| 4347 // if the containing block is both a flipped mode and perpendicular to us. | |
| 4229 if ((child->style()->isFlippedBlocksWritingMode() && | 4348 if ((child->style()->isFlippedBlocksWritingMode() && |
| 4230 child->isHorizontalWritingMode() != | 4349 child->isHorizontalWritingMode() != |
| 4231 containerBlock->isHorizontalWritingMode()) || | 4350 containerBlock->isHorizontalWritingMode()) || |
| 4232 (child->style()->isFlippedBlocksWritingMode() != | 4351 (child->style()->isFlippedBlocksWritingMode() != |
| 4233 containerBlock->style()->isFlippedBlocksWritingMode() && | 4352 containerBlock->style()->isFlippedBlocksWritingMode() && |
| 4234 child->isHorizontalWritingMode() == | 4353 child->isHorizontalWritingMode() == |
| 4235 containerBlock->isHorizontalWritingMode())) | 4354 containerBlock->isHorizontalWritingMode())) |
| 4236 logicalTopPos = containerLogicalHeight - logicalHeightValue - logicalTopPos; | 4355 logicalTopPos = containerLogicalHeight - logicalHeightValue - logicalTopPos; |
| 4237 | 4356 |
| 4238 // Our offset is from the logical bottom edge in a flipped environment, e.g., right for vertical-rl. | 4357 // Our offset is from the logical bottom edge in a flipped environment, e.g., |
| 4358 // right for vertical-rl. | |
| 4239 if (containerBlock->style()->isFlippedBlocksWritingMode() && | 4359 if (containerBlock->style()->isFlippedBlocksWritingMode() && |
| 4240 child->isHorizontalWritingMode() == | 4360 child->isHorizontalWritingMode() == |
| 4241 containerBlock->isHorizontalWritingMode()) { | 4361 containerBlock->isHorizontalWritingMode()) { |
| 4242 if (child->isHorizontalWritingMode()) | 4362 if (child->isHorizontalWritingMode()) |
| 4243 logicalTopPos += containerBlock->borderBottom(); | 4363 logicalTopPos += containerBlock->borderBottom(); |
| 4244 else | 4364 else |
| 4245 logicalTopPos += containerBlock->borderRight(); | 4365 logicalTopPos += containerBlock->borderRight(); |
| 4246 } else { | 4366 } else { |
| 4247 if (child->isHorizontalWritingMode()) | 4367 if (child->isHorizontalWritingMode()) |
| 4248 logicalTopPos += containerBlock->borderTop(); | 4368 logicalTopPos += containerBlock->borderTop(); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4292 } else { | 4412 } else { |
| 4293 if (logicalHeightLength.isIntrinsic()) | 4413 if (logicalHeightLength.isIntrinsic()) |
| 4294 resolvedLogicalHeight = computeIntrinsicLogicalContentHeightUsing( | 4414 resolvedLogicalHeight = computeIntrinsicLogicalContentHeightUsing( |
| 4295 logicalHeightLength, contentLogicalHeight, bordersPlusPadding); | 4415 logicalHeightLength, contentLogicalHeight, bordersPlusPadding); |
| 4296 else | 4416 else |
| 4297 resolvedLogicalHeight = adjustContentBoxLogicalHeightForBoxSizing( | 4417 resolvedLogicalHeight = adjustContentBoxLogicalHeightForBoxSizing( |
| 4298 valueForLength(logicalHeightLength, containerLogicalHeight)); | 4418 valueForLength(logicalHeightLength, containerLogicalHeight)); |
| 4299 } | 4419 } |
| 4300 | 4420 |
| 4301 if (!logicalTopIsAuto && !logicalHeightIsAuto && !logicalBottomIsAuto) { | 4421 if (!logicalTopIsAuto && !logicalHeightIsAuto && !logicalBottomIsAuto) { |
| 4302 /*-----------------------------------------------------------------------*\ | 4422 // ------------------------------------------------------------------------- |
| 4303 * If none of the three are 'auto': If both 'margin-top' and 'margin- | 4423 // If none of the three are 'auto': If both 'margin-top' and 'margin-bottom' |
| 4304 * bottom' are 'auto', solve the equation under the extra constraint tha t | 4424 // are 'auto', solve the equation under the extra constraint that the two |
| 4305 * the two margins get equal values. If one of 'margin-top' or 'margin- | 4425 // margins get equal values. If one of 'margin-top' or 'margin- bottom' is |
| 4306 * bottom' is 'auto', solve the equation for that value. If the values | 4426 // 'auto', solve the equation for that value. If the values are over- |
| 4307 * are over-constrained, ignore the value for 'bottom' and solve for tha t | 4427 // constrained, ignore the value for 'bottom' and solve for that value. |
| 4308 * value. | 4428 // ------------------------------------------------------------------------- |
| 4309 \*---------------------------------------------------------------------- -*/ | |
| 4310 // NOTE: It is not necessary to solve for 'bottom' in the over constrained | 4429 // NOTE: It is not necessary to solve for 'bottom' in the over constrained |
| 4311 // case because the value is not used for any further calculations. | 4430 // case because the value is not used for any further calculations. |
| 4312 | 4431 |
| 4313 logicalHeightValue = resolvedLogicalHeight; | 4432 logicalHeightValue = resolvedLogicalHeight; |
| 4314 logicalTopValue = valueForLength(logicalTop, containerLogicalHeight); | 4433 logicalTopValue = valueForLength(logicalTop, containerLogicalHeight); |
| 4315 | 4434 |
| 4316 const LayoutUnit availableSpace = | 4435 const LayoutUnit availableSpace = |
| 4317 containerLogicalHeight - | 4436 containerLogicalHeight - |
| 4318 (logicalTopValue + logicalHeightValue + | 4437 (logicalTopValue + logicalHeightValue + |
| 4319 valueForLength(logicalBottom, containerLogicalHeight) + | 4438 valueForLength(logicalBottom, containerLogicalHeight) + |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 4342 computedValues.m_margins.m_after = | 4461 computedValues.m_margins.m_after = |
| 4343 availableSpace - computedValues.m_margins.m_before; | 4462 availableSpace - computedValues.m_margins.m_before; |
| 4344 } else { | 4463 } else { |
| 4345 // Over-constrained, (no need solve for bottom) | 4464 // Over-constrained, (no need solve for bottom) |
| 4346 computedValues.m_margins.m_before = | 4465 computedValues.m_margins.m_before = |
| 4347 valueForLength(marginBefore, containerRelativeLogicalWidth); | 4466 valueForLength(marginBefore, containerRelativeLogicalWidth); |
| 4348 computedValues.m_margins.m_after = | 4467 computedValues.m_margins.m_after = |
| 4349 valueForLength(marginAfter, containerRelativeLogicalWidth); | 4468 valueForLength(marginAfter, containerRelativeLogicalWidth); |
| 4350 } | 4469 } |
| 4351 } else { | 4470 } else { |
| 4352 /*--------------------------------------------------------------------*\ | 4471 // ------------------------------------------------------------------------- |
| 4353 * Otherwise, set 'auto' values for 'margin-top' and 'margin-bottom' | 4472 // Otherwise, set 'auto' values for 'margin-top' and 'margin-bottom' |
| 4354 * to 0, and pick the one of the following six rules that applies. | 4473 // to 0, and pick the one of the following six rules that applies. |
| 4355 * | 4474 // |
| 4356 * 1. 'top' and 'height' are 'auto' and 'bottom' is not 'auto', then | 4475 // 1. 'top' and 'height' are 'auto' and 'bottom' is not 'auto', then |
| 4357 * the height is based on the content, and solve for 'top'. | 4476 // the height is based on the content, and solve for 'top'. |
| 4358 * | 4477 // |
| 4359 * OMIT RULE 2 AS IT SHOULD NEVER BE HIT | 4478 // OMIT RULE 2 AS IT SHOULD NEVER BE HIT |
| 4360 * ------------------------------------------------------------------ | 4479 // ------------------------------------------------------------------ |
| 4361 * 2. 'top' and 'bottom' are 'auto' and 'height' is not 'auto', then | 4480 // 2. 'top' and 'bottom' are 'auto' and 'height' is not 'auto', then |
| 4362 * set 'top' to the static position, and solve for 'bottom'. | 4481 // set 'top' to the static position, and solve for 'bottom'. |
| 4363 * ------------------------------------------------------------------ | 4482 // ------------------------------------------------------------------ |
| 4364 * | 4483 // |
| 4365 * 3. 'height' and 'bottom' are 'auto' and 'top' is not 'auto', then | 4484 // 3. 'height' and 'bottom' are 'auto' and 'top' is not 'auto', then |
| 4366 * the height is based on the content, and solve for 'bottom'. | 4485 // the height is based on the content, and solve for 'bottom'. |
| 4367 * 4. 'top' is 'auto', 'height' and 'bottom' are not 'auto', and | 4486 // 4. 'top' is 'auto', 'height' and 'bottom' are not 'auto', and |
| 4368 * solve for 'top'. | 4487 // solve for 'top'. |
| 4369 * 5. 'height' is 'auto', 'top' and 'bottom' are not 'auto', and | 4488 // 5. 'height' is 'auto', 'top' and 'bottom' are not 'auto', and |
| 4370 * solve for 'height'. | 4489 // solve for 'height'. |
| 4371 * 6. 'bottom' is 'auto', 'top' and 'height' are not 'auto', and | 4490 // 6. 'bottom' is 'auto', 'top' and 'height' are not 'auto', and |
| 4372 * solve for 'bottom'. | 4491 // solve for 'bottom'. |
| 4373 \*--------------------------------------------------------------------*/ | 4492 // ------------------------------------------------------------------------- |
| 4374 // NOTE: For rules 3 and 6 it is not necessary to solve for 'bottom' | 4493 // NOTE: For rules 3 and 6 it is not necessary to solve for 'bottom' |
| 4375 // because the value is not used for any further calculations. | 4494 // because the value is not used for any further calculations. |
| 4376 | 4495 |
| 4377 // Calculate margins, 'auto' margins are ignored. | 4496 // Calculate margins, 'auto' margins are ignored. |
| 4378 computedValues.m_margins.m_before = | 4497 computedValues.m_margins.m_before = |
| 4379 minimumValueForLength(marginBefore, containerRelativeLogicalWidth); | 4498 minimumValueForLength(marginBefore, containerRelativeLogicalWidth); |
| 4380 computedValues.m_margins.m_after = | 4499 computedValues.m_margins.m_after = |
| 4381 minimumValueForLength(marginAfter, containerRelativeLogicalWidth); | 4500 minimumValueForLength(marginAfter, containerRelativeLogicalWidth); |
| 4382 | 4501 |
| 4383 const LayoutUnit availableSpace = | 4502 const LayoutUnit availableSpace = |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4426 computedValues.m_position = | 4545 computedValues.m_position = |
| 4427 logicalTopValue + computedValues.m_margins.m_before; | 4546 logicalTopValue + computedValues.m_margins.m_before; |
| 4428 computeLogicalTopPositionedOffset(computedValues.m_position, this, | 4547 computeLogicalTopPositionedOffset(computedValues.m_position, this, |
| 4429 logicalHeightValue, containerBlock, | 4548 logicalHeightValue, containerBlock, |
| 4430 containerLogicalHeight); | 4549 containerLogicalHeight); |
| 4431 } | 4550 } |
| 4432 | 4551 |
| 4433 LayoutRect LayoutBox::localCaretRect(InlineBox* box, | 4552 LayoutRect LayoutBox::localCaretRect(InlineBox* box, |
| 4434 int caretOffset, | 4553 int caretOffset, |
| 4435 LayoutUnit* extraWidthToEndOfLine) { | 4554 LayoutUnit* extraWidthToEndOfLine) { |
| 4436 // VisiblePositions at offsets inside containers either a) refer to the positi ons before/after | 4555 // VisiblePositions at offsets inside containers either a) refer to the |
| 4437 // those containers (tables and select elements) or b) refer to the position i nside an empty block. | 4556 // positions before/after those containers (tables and select elements) or |
| 4557 // b) refer to the position inside an empty block. | |
| 4438 // They never refer to children. | 4558 // They never refer to children. |
| 4439 // FIXME: Paint the carets inside empty blocks differently than the carets bef ore/after elements. | 4559 // FIXME: Paint the carets inside empty blocks differently than the carets |
| 4560 // before/after elements. | |
| 4440 | 4561 |
| 4441 LayoutRect rect(location(), LayoutSize(caretWidth(), size().height())); | 4562 LayoutRect rect(location(), LayoutSize(caretWidth(), size().height())); |
| 4442 bool ltr = | 4563 bool ltr = |
| 4443 box ? box->isLeftToRightDirection() : style()->isLeftToRightDirection(); | 4564 box ? box->isLeftToRightDirection() : style()->isLeftToRightDirection(); |
| 4444 | 4565 |
| 4445 if ((!caretOffset) ^ ltr) | 4566 if ((!caretOffset) ^ ltr) |
| 4446 rect.move(LayoutSize(size().width() - caretWidth(), LayoutUnit())); | 4567 rect.move(LayoutSize(size().width() - caretWidth(), LayoutUnit())); |
| 4447 | 4568 |
| 4448 if (box) { | 4569 if (box) { |
| 4449 RootInlineBox& rootBox = box->root(); | 4570 RootInlineBox& rootBox = box->root(); |
| 4450 LayoutUnit top = rootBox.lineTop(); | 4571 LayoutUnit top = rootBox.lineTop(); |
| 4451 rect.setY(top); | 4572 rect.setY(top); |
| 4452 rect.setHeight(rootBox.lineBottom() - top); | 4573 rect.setHeight(rootBox.lineBottom() - top); |
| 4453 } | 4574 } |
| 4454 | 4575 |
| 4455 // If height of box is smaller than font height, use the latter one, | 4576 // If height of box is smaller than font height, use the latter one, |
| 4456 // otherwise the caret might become invisible. | 4577 // otherwise the caret might become invisible. |
| 4457 // | 4578 // |
| 4458 // Also, if the box is not an atomic inline-level element, always use the font height. | 4579 // Also, if the box is not an atomic inline-level element, always use the font |
| 4459 // This prevents the "big caret" bug described in: | 4580 // height. This prevents the "big caret" bug described in: |
| 4460 // <rdar://problem/3777804> Deleting all content in a document can result in g iant tall-as-window insertion point | 4581 // <rdar://problem/3777804> Deleting all content in a document can result in |
| 4582 // giant tall-as-window insertion point | |
| 4461 // | 4583 // |
| 4462 // FIXME: ignoring :first-line, missing good reason to take care of | 4584 // FIXME: ignoring :first-line, missing good reason to take care of |
| 4463 LayoutUnit fontHeight = LayoutUnit(style()->getFontMetrics().height()); | 4585 LayoutUnit fontHeight = LayoutUnit(style()->getFontMetrics().height()); |
| 4464 if (fontHeight > rect.height() || (!isAtomicInlineLevel() && !isTable())) | 4586 if (fontHeight > rect.height() || (!isAtomicInlineLevel() && !isTable())) |
| 4465 rect.setHeight(fontHeight); | 4587 rect.setHeight(fontHeight); |
| 4466 | 4588 |
| 4467 if (extraWidthToEndOfLine) | 4589 if (extraWidthToEndOfLine) |
| 4468 *extraWidthToEndOfLine = location().x() + size().width() - rect.maxX(); | 4590 *extraWidthToEndOfLine = location().x() + size().width() - rect.maxX(); |
| 4469 | 4591 |
| 4470 // Move to local coords | 4592 // Move to local coords |
| 4471 rect.moveBy(-location()); | 4593 rect.moveBy(-location()); |
| 4472 | 4594 |
| 4473 // FIXME: Border/padding should be added for all elements but this workaround | 4595 // FIXME: Border/padding should be added for all elements but this workaround |
| 4474 // is needed because we use offsets inside an "atomic" element to represent | 4596 // is needed because we use offsets inside an "atomic" element to represent |
| 4475 // positions before and after the element in deprecated editing offsets. | 4597 // positions before and after the element in deprecated editing offsets. |
| 4476 if (node() && | 4598 if (node() && |
| 4477 !(editingIgnoresContent(node()) || isDisplayInsideTable(node()))) { | 4599 !(editingIgnoresContent(node()) || isDisplayInsideTable(node()))) { |
| 4478 rect.setX(rect.x() + borderLeft() + paddingLeft()); | 4600 rect.setX(rect.x() + borderLeft() + paddingLeft()); |
| 4479 rect.setY(rect.y() + paddingTop() + borderTop()); | 4601 rect.setY(rect.y() + paddingTop() + borderTop()); |
| 4480 } | 4602 } |
| 4481 | 4603 |
| 4482 if (!isHorizontalWritingMode()) | 4604 if (!isHorizontalWritingMode()) |
| 4483 return rect.transposedRect(); | 4605 return rect.transposedRect(); |
| 4484 | 4606 |
| 4485 return rect; | 4607 return rect; |
| 4486 } | 4608 } |
| 4487 | 4609 |
| 4488 PositionWithAffinity LayoutBox::positionForPoint(const LayoutPoint& point) { | 4610 PositionWithAffinity LayoutBox::positionForPoint(const LayoutPoint& point) { |
| 4489 // no children...return this layout object's element, if there is one, and off set 0 | 4611 // no children...return this layout object's element, if there is one, and |
| 4612 // offset 0 | |
| 4490 LayoutObject* firstChild = slowFirstChild(); | 4613 LayoutObject* firstChild = slowFirstChild(); |
| 4491 if (!firstChild) | 4614 if (!firstChild) |
| 4492 return createPositionWithAffinity( | 4615 return createPositionWithAffinity( |
| 4493 nonPseudoNode() ? firstPositionInOrBeforeNode(nonPseudoNode()) | 4616 nonPseudoNode() ? firstPositionInOrBeforeNode(nonPseudoNode()) |
| 4494 : Position()); | 4617 : Position()); |
| 4495 | 4618 |
| 4496 if (isTable() && nonPseudoNode()) { | 4619 if (isTable() && nonPseudoNode()) { |
| 4497 LayoutUnit right = size().width() - verticalScrollbarWidth(); | 4620 LayoutUnit right = size().width() - verticalScrollbarWidth(); |
| 4498 LayoutUnit bottom = size().height() - horizontalScrollbarHeight(); | 4621 LayoutUnit bottom = size().height() - horizontalScrollbarHeight(); |
| 4499 | 4622 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4534 LayoutUnit right = left + layoutBox->contentWidth(); | 4657 LayoutUnit right = left + layoutBox->contentWidth(); |
| 4535 | 4658 |
| 4536 if (point.x() <= right && point.x() >= left && point.y() <= top && | 4659 if (point.x() <= right && point.x() >= left && point.y() <= top && |
| 4537 point.y() >= bottom) { | 4660 point.y() >= bottom) { |
| 4538 if (layoutBox->isTableRow()) | 4661 if (layoutBox->isTableRow()) |
| 4539 return layoutBox->positionForPoint(point + adjustedPoint - | 4662 return layoutBox->positionForPoint(point + adjustedPoint - |
| 4540 layoutBox->locationOffset()); | 4663 layoutBox->locationOffset()); |
| 4541 return layoutBox->positionForPoint(point - layoutBox->locationOffset()); | 4664 return layoutBox->positionForPoint(point - layoutBox->locationOffset()); |
| 4542 } | 4665 } |
| 4543 | 4666 |
| 4544 // Find the distance from (x, y) to the box. Split the space around the box into 8 pieces | 4667 // Find the distance from (x, y) to the box. Split the space around the box |
| 4545 // and use a different compare depending on which piece (x, y) is in. | 4668 // into 8 pieces and use a different compare depending on which piece (x, y) |
| 4669 // is in. | |
| 4546 LayoutPoint cmp; | 4670 LayoutPoint cmp; |
| 4547 if (point.x() > right) { | 4671 if (point.x() > right) { |
| 4548 if (point.y() < top) | 4672 if (point.y() < top) |
| 4549 cmp = LayoutPoint(right, top); | 4673 cmp = LayoutPoint(right, top); |
| 4550 else if (point.y() > bottom) | 4674 else if (point.y() > bottom) |
| 4551 cmp = LayoutPoint(right, bottom); | 4675 cmp = LayoutPoint(right, bottom); |
| 4552 else | 4676 else |
| 4553 cmp = LayoutPoint(right, point.y()); | 4677 cmp = LayoutPoint(right, point.y()); |
| 4554 } else if (point.x() < left) { | 4678 } else if (point.x() < left) { |
| 4555 if (point.y() < top) | 4679 if (point.y() < top) |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 4577 | 4701 |
| 4578 if (closestLayoutObject) | 4702 if (closestLayoutObject) |
| 4579 return closestLayoutObject->positionForPoint( | 4703 return closestLayoutObject->positionForPoint( |
| 4580 adjustedPoint - closestLayoutObject->locationOffset()); | 4704 adjustedPoint - closestLayoutObject->locationOffset()); |
| 4581 return createPositionWithAffinity( | 4705 return createPositionWithAffinity( |
| 4582 firstPositionInOrBeforeNode(nonPseudoNode())); | 4706 firstPositionInOrBeforeNode(nonPseudoNode())); |
| 4583 } | 4707 } |
| 4584 | 4708 |
| 4585 DISABLE_CFI_PERF | 4709 DISABLE_CFI_PERF |
| 4586 bool LayoutBox::shrinkToAvoidFloats() const { | 4710 bool LayoutBox::shrinkToAvoidFloats() const { |
| 4587 // Floating objects don't shrink. Objects that don't avoid floats don't shrin k. | 4711 // Floating objects don't shrink. Objects that don't avoid floats don't |
| 4712 // shrink. | |
| 4588 if (isInline() || !avoidsFloats() || isFloating()) | 4713 if (isInline() || !avoidsFloats() || isFloating()) |
| 4589 return false; | 4714 return false; |
| 4590 | 4715 |
| 4591 // Only auto width objects can possibly shrink to avoid floats. | 4716 // Only auto width objects can possibly shrink to avoid floats. |
| 4592 return style()->width().isAuto(); | 4717 return style()->width().isAuto(); |
| 4593 } | 4718 } |
| 4594 | 4719 |
| 4595 static bool shouldBeConsideredAsReplaced(Node* node) { | 4720 static bool shouldBeConsideredAsReplaced(Node* node) { |
| 4596 // Checkboxes and radioboxes are not isAtomicInlineLevel() nor do they have th eir own layoutObject in which to override avoidFloats(). | 4721 // Checkboxes and radioboxes are not isAtomicInlineLevel() nor do they have |
| 4722 // their own layoutObject in which to override avoidFloats(). | |
| 4597 return node && node->isElementNode() && | 4723 return node && node->isElementNode() && |
| 4598 (toElement(node)->isFormControlElement() || | 4724 (toElement(node)->isFormControlElement() || |
| 4599 isHTMLImageElement(toElement(node))); | 4725 isHTMLImageElement(toElement(node))); |
| 4600 } | 4726 } |
| 4601 | 4727 |
| 4602 DISABLE_CFI_PERF | 4728 DISABLE_CFI_PERF |
| 4603 bool LayoutBox::avoidsFloats() const { | 4729 bool LayoutBox::avoidsFloats() const { |
| 4604 return isAtomicInlineLevel() || shouldBeConsideredAsReplaced(node()) || | 4730 return isAtomicInlineLevel() || shouldBeConsideredAsReplaced(node()) || |
| 4605 hasOverflowClip() || isHR() || isLegend() || isWritingModeRoot() || | 4731 hasOverflowClip() || isHR() || isLegend() || isWritingModeRoot() || |
| 4606 isFlexItemIncludingDeprecated() || style()->containsPaint() || | 4732 isFlexItemIncludingDeprecated() || style()->containsPaint() || |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4672 } | 4798 } |
| 4673 | 4799 |
| 4674 if (style()->hasBorderImageOutsets()) { | 4800 if (style()->hasBorderImageOutsets()) { |
| 4675 LayoutRectOutsets borderOutsets = style()->borderImageOutsets(); | 4801 LayoutRectOutsets borderOutsets = style()->borderImageOutsets(); |
| 4676 top = std::max(top, borderOutsets.top()); | 4802 top = std::max(top, borderOutsets.top()); |
| 4677 right = std::max(right, borderOutsets.right()); | 4803 right = std::max(right, borderOutsets.right()); |
| 4678 bottom = std::max(bottom, borderOutsets.bottom()); | 4804 bottom = std::max(bottom, borderOutsets.bottom()); |
| 4679 left = std::max(left, borderOutsets.left()); | 4805 left = std::max(left, borderOutsets.left()); |
| 4680 } | 4806 } |
| 4681 | 4807 |
| 4682 // Box-shadow and border-image-outsets are in physical direction. Flip into bl ock direction. | 4808 // Box-shadow and border-image-outsets are in physical direction. Flip into |
| 4809 // block direction. | |
| 4683 if (UNLIKELY(hasFlippedBlocksWritingMode())) | 4810 if (UNLIKELY(hasFlippedBlocksWritingMode())) |
| 4684 std::swap(left, right); | 4811 std::swap(left, right); |
| 4685 | 4812 |
| 4686 if (style()->hasOutline()) { | 4813 if (style()->hasOutline()) { |
| 4687 Vector<LayoutRect> outlineRects; | 4814 Vector<LayoutRect> outlineRects; |
| 4688 // The result rects are in coordinates of this object's border box. | 4815 // The result rects are in coordinates of this object's border box. |
| 4689 addOutlineRects(outlineRects, LayoutPoint(), | 4816 addOutlineRects(outlineRects, LayoutPoint(), |
| 4690 outlineRectsShouldIncludeBlockVisualOverflow()); | 4817 outlineRectsShouldIncludeBlockVisualOverflow()); |
| 4691 LayoutRect rect = unionRectEvenIfEmpty(outlineRects); | 4818 LayoutRect rect = unionRectEvenIfEmpty(outlineRects); |
| 4692 int outlineOutset = style()->outlineOutsetExtent(); | 4819 int outlineOutset = style()->outlineOutsetExtent(); |
| 4693 top = std::max(top, -rect.y() + outlineOutset); | 4820 top = std::max(top, -rect.y() + outlineOutset); |
| 4694 right = std::max(right, rect.maxX() - size().width() + outlineOutset); | 4821 right = std::max(right, rect.maxX() - size().width() + outlineOutset); |
| 4695 bottom = std::max(bottom, rect.maxY() - size().height() + outlineOutset); | 4822 bottom = std::max(bottom, rect.maxY() - size().height() + outlineOutset); |
| 4696 left = std::max(left, -rect.x() + outlineOutset); | 4823 left = std::max(left, -rect.x() + outlineOutset); |
| 4697 } | 4824 } |
| 4698 | 4825 |
| 4699 return LayoutRectOutsets(top, right, bottom, left); | 4826 return LayoutRectOutsets(top, right, bottom, left); |
| 4700 } | 4827 } |
| 4701 | 4828 |
| 4702 DISABLE_CFI_PERF | 4829 DISABLE_CFI_PERF |
| 4703 void LayoutBox::addOverflowFromChild(LayoutBox* child, | 4830 void LayoutBox::addOverflowFromChild(LayoutBox* child, |
| 4704 const LayoutSize& delta) { | 4831 const LayoutSize& delta) { |
| 4705 // Never allow flow threads to propagate overflow up to a parent. | 4832 // Never allow flow threads to propagate overflow up to a parent. |
| 4706 if (child->isLayoutFlowThread()) | 4833 if (child->isLayoutFlowThread()) |
| 4707 return; | 4834 return; |
| 4708 | 4835 |
| 4709 // Only propagate layout overflow from the child if the child isn't clipping i ts overflow. If it is, then | 4836 // Only propagate layout overflow from the child if the child isn't clipping |
| 4710 // its overflow is internal to it, and we don't care about it. layoutOverflow RectForPropagation takes care of this | 4837 // its overflow. If it is, then its overflow is internal to it, and we don't |
| 4711 // and just propagates the border box rect instead. | 4838 // care about it. layoutOverflowRectForPropagation takes care of this and just |
| 4839 // propagates the border box rect instead. | |
| 4712 LayoutRect childLayoutOverflowRect = | 4840 LayoutRect childLayoutOverflowRect = |
| 4713 child->layoutOverflowRectForPropagation(styleRef()); | 4841 child->layoutOverflowRectForPropagation(styleRef()); |
| 4714 childLayoutOverflowRect.move(delta); | 4842 childLayoutOverflowRect.move(delta); |
| 4715 addLayoutOverflow(childLayoutOverflowRect); | 4843 addLayoutOverflow(childLayoutOverflowRect); |
| 4716 | 4844 |
| 4717 // Add in visual overflow from the child. Even if the child clips its overflo w, it may still | 4845 // Add in visual overflow from the child. Even if the child clips its |
| 4718 // have visual overflow of its own set from box shadows or reflections. It is unnecessary to propagate this | 4846 // overflow, it may still have visual overflow of its own set from box shadows |
| 4719 // overflow if we are clipping our own overflow. | 4847 // or reflections. It is unnecessary to propagate this overflow if we are |
| 4848 // clipping our own overflow. | |
| 4720 if (child->hasSelfPaintingLayer()) | 4849 if (child->hasSelfPaintingLayer()) |
| 4721 return; | 4850 return; |
| 4722 LayoutRect childVisualOverflowRect = | 4851 LayoutRect childVisualOverflowRect = |
| 4723 child->visualOverflowRectForPropagation(styleRef()); | 4852 child->visualOverflowRectForPropagation(styleRef()); |
| 4724 childVisualOverflowRect.move(delta); | 4853 childVisualOverflowRect.move(delta); |
| 4725 addContentsVisualOverflow(childVisualOverflowRect); | 4854 addContentsVisualOverflow(childVisualOverflowRect); |
| 4726 } | 4855 } |
| 4727 | 4856 |
| 4728 bool LayoutBox::hasTopOverflow() const { | 4857 bool LayoutBox::hasTopOverflow() const { |
| 4729 return !style()->isLeftToRightDirection() && !isHorizontalWritingMode(); | 4858 return !style()->isLeftToRightDirection() && !isHorizontalWritingMode(); |
| 4730 } | 4859 } |
| 4731 | 4860 |
| 4732 bool LayoutBox::hasLeftOverflow() const { | 4861 bool LayoutBox::hasLeftOverflow() const { |
| 4733 return !style()->isLeftToRightDirection() && isHorizontalWritingMode(); | 4862 return !style()->isLeftToRightDirection() && isHorizontalWritingMode(); |
| 4734 } | 4863 } |
| 4735 | 4864 |
| 4736 DISABLE_CFI_PERF | 4865 DISABLE_CFI_PERF |
| 4737 void LayoutBox::addLayoutOverflow(const LayoutRect& rect) { | 4866 void LayoutBox::addLayoutOverflow(const LayoutRect& rect) { |
| 4738 if (rect.isEmpty()) | 4867 if (rect.isEmpty()) |
| 4739 return; | 4868 return; |
| 4740 | 4869 |
| 4741 LayoutRect clientBox = noOverflowRect(); | 4870 LayoutRect clientBox = noOverflowRect(); |
| 4742 if (clientBox.contains(rect)) | 4871 if (clientBox.contains(rect)) |
| 4743 return; | 4872 return; |
| 4744 | 4873 |
| 4745 // For overflow clip objects, we don't want to propagate overflow into unreach able areas. | 4874 // For overflow clip objects, we don't want to propagate overflow into |
| 4875 // unreachable areas. | |
| 4746 LayoutRect overflowRect(rect); | 4876 LayoutRect overflowRect(rect); |
| 4747 if (hasOverflowClip() || isLayoutView()) { | 4877 if (hasOverflowClip() || isLayoutView()) { |
| 4748 // Overflow is in the block's coordinate space and thus is flipped for verti cal-rl writing | 4878 // Overflow is in the block's coordinate space and thus is flipped for |
| 4749 // mode. At this stage that is actually a simplification, since we can trea t vertical-lr/rl | 4879 // vertical-rl writing |
| 4880 // mode. At this stage that is actually a simplification, since we can | |
| 4881 // treat vertical-lr/rl | |
| 4750 // as the same. | 4882 // as the same. |
| 4751 if (hasTopOverflow()) | 4883 if (hasTopOverflow()) |
| 4752 overflowRect.shiftMaxYEdgeTo( | 4884 overflowRect.shiftMaxYEdgeTo( |
| 4753 std::min(overflowRect.maxY(), clientBox.maxY())); | 4885 std::min(overflowRect.maxY(), clientBox.maxY())); |
| 4754 else | 4886 else |
| 4755 overflowRect.shiftYEdgeTo(std::max(overflowRect.y(), clientBox.y())); | 4887 overflowRect.shiftYEdgeTo(std::max(overflowRect.y(), clientBox.y())); |
| 4756 if (hasLeftOverflow()) | 4888 if (hasLeftOverflow()) |
| 4757 overflowRect.shiftMaxXEdgeTo( | 4889 overflowRect.shiftMaxXEdgeTo( |
| 4758 std::min(overflowRect.maxX(), clientBox.maxX())); | 4890 std::min(overflowRect.maxX(), clientBox.maxX())); |
| 4759 else | 4891 else |
| 4760 overflowRect.shiftXEdgeTo(std::max(overflowRect.x(), clientBox.x())); | 4892 overflowRect.shiftXEdgeTo(std::max(overflowRect.x(), clientBox.x())); |
| 4761 | 4893 |
| 4762 // Now re-test with the adjusted rectangle and see if it has become unreacha ble or fully | 4894 // Now re-test with the adjusted rectangle and see if it has become |
| 4895 // unreachable or fully | |
| 4763 // contained. | 4896 // contained. |
| 4764 if (clientBox.contains(overflowRect) || overflowRect.isEmpty()) | 4897 if (clientBox.contains(overflowRect) || overflowRect.isEmpty()) |
| 4765 return; | 4898 return; |
| 4766 } | 4899 } |
| 4767 | 4900 |
| 4768 if (!m_overflow) | 4901 if (!m_overflow) |
| 4769 m_overflow = wrapUnique(new BoxOverflowModel(clientBox, borderBoxRect())); | 4902 m_overflow = wrapUnique(new BoxOverflowModel(clientBox, borderBoxRect())); |
| 4770 | 4903 |
| 4771 m_overflow->addLayoutOverflow(overflowRect); | 4904 m_overflow->addLayoutOverflow(overflowRect); |
| 4772 } | 4905 } |
| 4773 | 4906 |
| 4774 void LayoutBox::addSelfVisualOverflow(const LayoutRect& rect) { | 4907 void LayoutBox::addSelfVisualOverflow(const LayoutRect& rect) { |
| 4775 if (rect.isEmpty()) | 4908 if (rect.isEmpty()) |
| 4776 return; | 4909 return; |
| 4777 | 4910 |
| 4778 LayoutRect borderBox = borderBoxRect(); | 4911 LayoutRect borderBox = borderBoxRect(); |
| 4779 if (borderBox.contains(rect)) | 4912 if (borderBox.contains(rect)) |
| 4780 return; | 4913 return; |
| 4781 | 4914 |
| 4782 if (!m_overflow) | 4915 if (!m_overflow) |
| 4783 m_overflow = wrapUnique(new BoxOverflowModel(noOverflowRect(), borderBox)); | 4916 m_overflow = wrapUnique(new BoxOverflowModel(noOverflowRect(), borderBox)); |
| 4784 | 4917 |
| 4785 m_overflow->addSelfVisualOverflow(rect); | 4918 m_overflow->addSelfVisualOverflow(rect); |
| 4786 } | 4919 } |
| 4787 | 4920 |
| 4788 void LayoutBox::addContentsVisualOverflow(const LayoutRect& rect) { | 4921 void LayoutBox::addContentsVisualOverflow(const LayoutRect& rect) { |
| 4789 if (rect.isEmpty()) | 4922 if (rect.isEmpty()) |
| 4790 return; | 4923 return; |
| 4791 | 4924 |
| 4792 // If hasOverflowClip() we always save contents visual overflow because we nee d it | 4925 // If hasOverflowClip() we always save contents visual overflow because we |
| 4926 // need it | |
| 4793 // e.g. to determine whether to apply rounded corner clip on contents. | 4927 // e.g. to determine whether to apply rounded corner clip on contents. |
| 4794 // Otherwise we save contents visual overflow only if it overflows the border box. | 4928 // Otherwise we save contents visual overflow only if it overflows the border |
| 4929 // box. | |
| 4795 LayoutRect borderBox = borderBoxRect(); | 4930 LayoutRect borderBox = borderBoxRect(); |
| 4796 if (!hasOverflowClip() && borderBox.contains(rect)) | 4931 if (!hasOverflowClip() && borderBox.contains(rect)) |
| 4797 return; | 4932 return; |
| 4798 | 4933 |
| 4799 if (!m_overflow) | 4934 if (!m_overflow) |
| 4800 m_overflow = wrapUnique(new BoxOverflowModel(noOverflowRect(), borderBox)); | 4935 m_overflow = wrapUnique(new BoxOverflowModel(noOverflowRect(), borderBox)); |
| 4801 m_overflow->addContentsVisualOverflow(rect); | 4936 m_overflow->addContentsVisualOverflow(rect); |
| 4802 } | 4937 } |
| 4803 | 4938 |
| 4804 void LayoutBox::clearLayoutOverflow() { | 4939 void LayoutBox::clearLayoutOverflow() { |
| 4805 if (!m_overflow) | 4940 if (!m_overflow) |
| 4806 return; | 4941 return; |
| 4807 | 4942 |
| 4808 if (!hasSelfVisualOverflow() && contentsVisualOverflowRect().isEmpty()) { | 4943 if (!hasSelfVisualOverflow() && contentsVisualOverflowRect().isEmpty()) { |
| 4809 clearAllOverflows(); | 4944 clearAllOverflows(); |
| 4810 return; | 4945 return; |
| 4811 } | 4946 } |
| 4812 | 4947 |
| 4813 m_overflow->setLayoutOverflow(noOverflowRect()); | 4948 m_overflow->setLayoutOverflow(noOverflowRect()); |
| 4814 } | 4949 } |
| 4815 | 4950 |
| 4816 bool LayoutBox::percentageLogicalHeightIsResolvable() const { | 4951 bool LayoutBox::percentageLogicalHeightIsResolvable() const { |
| 4817 Length fakeLength(100, Percent); | 4952 Length fakeLength(100, Percent); |
| 4818 return computePercentageLogicalHeight(fakeLength) != -1; | 4953 return computePercentageLogicalHeight(fakeLength) != -1; |
| 4819 } | 4954 } |
| 4820 | 4955 |
| 4821 DISABLE_CFI_PERF | 4956 DISABLE_CFI_PERF |
| 4822 bool LayoutBox::hasUnsplittableScrollingOverflow() const { | 4957 bool LayoutBox::hasUnsplittableScrollingOverflow() const { |
| 4823 // We will paginate as long as we don't scroll overflow in the pagination dire ction. | 4958 // We will paginate as long as we don't scroll overflow in the pagination |
| 4959 // direction. | |
| 4824 bool isHorizontal = isHorizontalWritingMode(); | 4960 bool isHorizontal = isHorizontalWritingMode(); |
| 4825 if ((isHorizontal && !scrollsOverflowY()) || | 4961 if ((isHorizontal && !scrollsOverflowY()) || |
| 4826 (!isHorizontal && !scrollsOverflowX())) | 4962 (!isHorizontal && !scrollsOverflowX())) |
| 4827 return false; | 4963 return false; |
| 4828 | 4964 |
| 4829 // Fragmenting scrollbars is only problematic in interactive media, e.g. multi col on a | 4965 // Fragmenting scrollbars is only problematic in interactive media, e.g. |
| 4830 // screen. If we're printing, which is non-interactive media, we should allow objects with | 4966 // multicol on a screen. If we're printing, which is non-interactive media, we |
| 4831 // non-visible overflow to be paginated as normally. | 4967 // should allow objects with non-visible overflow to be paginated as normally. |
| 4832 if (document().printing()) | 4968 if (document().printing()) |
| 4833 return false; | 4969 return false; |
| 4834 | 4970 |
| 4835 // We do have overflow. We'll still be willing to paginate as long as the bloc k | 4971 // We do have overflow. We'll still be willing to paginate as long as the |
| 4836 // has auto logical height, auto or undefined max-logical-height and a zero or auto min-logical-height. | 4972 // block has auto logical height, auto or undefined max-logical-height and a |
| 4837 // Note this is just a heuristic, and it's still possible to have overflow und er these | 4973 // zero or auto min-logical-height. |
| 4838 // conditions, but it should work out to be good enough for common cases. Pagi nating overflow | 4974 // Note this is just a heuristic, and it's still possible to have overflow |
| 4839 // with scrollbars present is not the end of the world and is what we used to do in the old model anyway. | 4975 // under these conditions, but it should work out to be good enough for common |
| 4976 // cases. Paginating overflow with scrollbars present is not the end of the | |
| 4977 // world and is what we used to do in the old model anyway. | |
| 4840 return !style()->logicalHeight().isIntrinsicOrAuto() || | 4978 return !style()->logicalHeight().isIntrinsicOrAuto() || |
| 4841 (!style()->logicalMaxHeight().isIntrinsicOrAuto() && | 4979 (!style()->logicalMaxHeight().isIntrinsicOrAuto() && |
| 4842 !style()->logicalMaxHeight().isMaxSizeNone() && | 4980 !style()->logicalMaxHeight().isMaxSizeNone() && |
| 4843 (!style()->logicalMaxHeight().isPercentOrCalc() || | 4981 (!style()->logicalMaxHeight().isPercentOrCalc() || |
| 4844 percentageLogicalHeightIsResolvable())) || | 4982 percentageLogicalHeightIsResolvable())) || |
| 4845 (!style()->logicalMinHeight().isIntrinsicOrAuto() && | 4983 (!style()->logicalMinHeight().isIntrinsicOrAuto() && |
| 4846 style()->logicalMinHeight().isPositive() && | 4984 style()->logicalMinHeight().isPositive() && |
| 4847 (!style()->logicalMinHeight().isPercentOrCalc() || | 4985 (!style()->logicalMinHeight().isPercentOrCalc() || |
| 4848 percentageLogicalHeightIsResolvable())); | 4986 percentageLogicalHeightIsResolvable())); |
| 4849 } | 4987 } |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4911 | 5049 |
| 4912 DISABLE_CFI_PERF | 5050 DISABLE_CFI_PERF |
| 4913 LayoutRect LayoutBox::visualOverflowRectForPropagation( | 5051 LayoutRect LayoutBox::visualOverflowRectForPropagation( |
| 4914 const ComputedStyle& parentStyle) const { | 5052 const ComputedStyle& parentStyle) const { |
| 4915 // If the writing modes of the child and parent match, then we don't have to | 5053 // If the writing modes of the child and parent match, then we don't have to |
| 4916 // do anything fancy. Just return the result. | 5054 // do anything fancy. Just return the result. |
| 4917 LayoutRect rect = visualOverflowRect(); | 5055 LayoutRect rect = visualOverflowRect(); |
| 4918 if (parentStyle.getWritingMode() == style()->getWritingMode()) | 5056 if (parentStyle.getWritingMode() == style()->getWritingMode()) |
| 4919 return rect; | 5057 return rect; |
| 4920 | 5058 |
| 4921 // We are putting ourselves into our parent's coordinate space. If there is a flipped block mismatch | 5059 // We are putting ourselves into our parent's coordinate space. If there is a |
| 4922 // in a particular axis, then we have to flip the rect along that axis. | 5060 // flipped block mismatch in a particular axis, then we have to flip the rect |
| 5061 // along that axis. | |
| 4923 if (style()->getWritingMode() == RightToLeftWritingMode || | 5062 if (style()->getWritingMode() == RightToLeftWritingMode || |
| 4924 parentStyle.getWritingMode() == RightToLeftWritingMode) | 5063 parentStyle.getWritingMode() == RightToLeftWritingMode) |
| 4925 rect.setX(size().width() - rect.maxX()); | 5064 rect.setX(size().width() - rect.maxX()); |
| 4926 | 5065 |
| 4927 return rect; | 5066 return rect; |
| 4928 } | 5067 } |
| 4929 | 5068 |
| 4930 DISABLE_CFI_PERF | 5069 DISABLE_CFI_PERF |
| 4931 LayoutRect LayoutBox::logicalLayoutOverflowRectForPropagation( | 5070 LayoutRect LayoutBox::logicalLayoutOverflowRectForPropagation( |
| 4932 const ComputedStyle& parentStyle) const { | 5071 const ComputedStyle& parentStyle) const { |
| 4933 LayoutRect rect = layoutOverflowRectForPropagation(parentStyle); | 5072 LayoutRect rect = layoutOverflowRectForPropagation(parentStyle); |
| 4934 if (!parentStyle.isHorizontalWritingMode()) | 5073 if (!parentStyle.isHorizontalWritingMode()) |
| 4935 return rect.transposedRect(); | 5074 return rect.transposedRect(); |
| 4936 return rect; | 5075 return rect; |
| 4937 } | 5076 } |
| 4938 | 5077 |
| 4939 DISABLE_CFI_PERF | 5078 DISABLE_CFI_PERF |
| 4940 LayoutRect LayoutBox::layoutOverflowRectForPropagation( | 5079 LayoutRect LayoutBox::layoutOverflowRectForPropagation( |
| 4941 const ComputedStyle& parentStyle) const { | 5080 const ComputedStyle& parentStyle) const { |
| 4942 // Only propagate interior layout overflow if we don't clip it. | 5081 // Only propagate interior layout overflow if we don't clip it. |
| 4943 LayoutRect rect = borderBoxRect(); | 5082 LayoutRect rect = borderBoxRect(); |
| 4944 // We want to include the margin, but only when it adds height. Quirky margins don't contribute height | 5083 // We want to include the margin, but only when it adds height. Quirky margins |
| 4945 // nor do the margins of self-collapsing blocks. | 5084 // don't contribute height nor do the margins of self-collapsing blocks. |
| 4946 if (!styleRef().hasMarginAfterQuirk() && !isSelfCollapsingBlock()) | 5085 if (!styleRef().hasMarginAfterQuirk() && !isSelfCollapsingBlock()) |
| 4947 rect.expand(isHorizontalWritingMode() | 5086 rect.expand(isHorizontalWritingMode() |
| 4948 ? LayoutSize(LayoutUnit(), marginAfter()) | 5087 ? LayoutSize(LayoutUnit(), marginAfter()) |
| 4949 : LayoutSize(marginAfter(), LayoutUnit())); | 5088 : LayoutSize(marginAfter(), LayoutUnit())); |
| 4950 | 5089 |
| 4951 if (!hasOverflowClip()) | 5090 if (!hasOverflowClip()) |
| 4952 rect.unite(layoutOverflowRect()); | 5091 rect.unite(layoutOverflowRect()); |
| 4953 | 5092 |
| 4954 bool hasTransform = hasLayer() && layer()->transform(); | 5093 bool hasTransform = hasLayer() && layer()->transform(); |
| 4955 if (isInFlowPositioned() || hasTransform) { | 5094 if (isInFlowPositioned() || hasTransform) { |
| 4956 // If we are relatively positioned or if we have a transform, then we have t o convert | 5095 // If we are relatively positioned or if we have a transform, then we have |
| 4957 // this rectangle into physical coordinates, apply relative positioning and transforms | 5096 // to convert this rectangle into physical coordinates, apply relative |
| 4958 // to it, and then convert it back. | 5097 // positioning and transforms to it, and then convert it back. |
| 4959 flipForWritingMode(rect); | 5098 flipForWritingMode(rect); |
| 4960 | 5099 |
| 4961 if (hasTransform) | 5100 if (hasTransform) |
| 4962 rect = layer()->currentTransform().mapRect(rect); | 5101 rect = layer()->currentTransform().mapRect(rect); |
| 4963 | 5102 |
| 4964 if (isInFlowPositioned()) | 5103 if (isInFlowPositioned()) |
| 4965 rect.move(offsetForInFlowPosition()); | 5104 rect.move(offsetForInFlowPosition()); |
| 4966 | 5105 |
| 4967 // Now we need to flip back. | 5106 // Now we need to flip back. |
| 4968 flipForWritingMode(rect); | 5107 flipForWritingMode(rect); |
| 4969 } | 5108 } |
| 4970 | 5109 |
| 4971 // If the writing modes of the child and parent match, then we don't have to | 5110 // If the writing modes of the child and parent match, then we don't have to |
| 4972 // do anything fancy. Just return the result. | 5111 // do anything fancy. Just return the result. |
| 4973 if (parentStyle.getWritingMode() == style()->getWritingMode()) | 5112 if (parentStyle.getWritingMode() == style()->getWritingMode()) |
| 4974 return rect; | 5113 return rect; |
| 4975 | 5114 |
| 4976 // We are putting ourselves into our parent's coordinate space. If there is a flipped block mismatch | 5115 // We are putting ourselves into our parent's coordinate space. If there is a |
| 4977 // in a particular axis, then we have to flip the rect along that axis. | 5116 // flipped block mismatch in a particular axis, then we have to flip the rect |
| 5117 // along that axis. | |
| 4978 if (style()->getWritingMode() == RightToLeftWritingMode || | 5118 if (style()->getWritingMode() == RightToLeftWritingMode || |
| 4979 parentStyle.getWritingMode() == RightToLeftWritingMode) | 5119 parentStyle.getWritingMode() == RightToLeftWritingMode) |
| 4980 rect.setX(size().width() - rect.maxX()); | 5120 rect.setX(size().width() - rect.maxX()); |
| 4981 | 5121 |
| 4982 return rect; | 5122 return rect; |
| 4983 } | 5123 } |
| 4984 | 5124 |
| 4985 DISABLE_CFI_PERF | 5125 DISABLE_CFI_PERF |
| 4986 LayoutRect LayoutBox::noOverflowRect() const { | 5126 LayoutRect LayoutBox::noOverflowRect() const { |
| 4987 // Because of the special coordinate system used for overflow rectangles and m any other | 5127 // Because of the special coordinate system used for overflow rectangles and |
| 4988 // rectangles (not quite logical, not quite physical), we need to flip the blo ck progression | 5128 // many other rectangles (not quite logical, not quite physical), we need to |
| 4989 // coordinate in vertical-rl writing mode. In other words, the rectangle retur ned is physical, | 5129 // flip the block progression coordinate in vertical-rl writing mode. In other |
| 4990 // except for the block direction progression coordinate (x in vertical writin g mode), which is | 5130 // words, the rectangle returned is physical, except for the block direction |
| 4991 // always "logical top". Apart from the flipping, this method does the same th ing as | 5131 // progression coordinate (x in vertical writing mode), which is always |
| 5132 // "logical top". Apart from the flipping, this method does the same thing as | |
| 4992 // clientBoxRect(). | 5133 // clientBoxRect(). |
| 4993 | 5134 |
| 4994 const int scrollBarWidth = verticalScrollbarWidth(); | 5135 const int scrollBarWidth = verticalScrollbarWidth(); |
| 4995 const int scrollBarHeight = horizontalScrollbarHeight(); | 5136 const int scrollBarHeight = horizontalScrollbarHeight(); |
| 4996 LayoutUnit left( | 5137 LayoutUnit left( |
| 4997 borderLeft() + | 5138 borderLeft() + |
| 4998 (shouldPlaceBlockDirectionScrollbarOnLogicalLeft() ? scrollBarWidth : 0)); | 5139 (shouldPlaceBlockDirectionScrollbarOnLogicalLeft() ? scrollBarWidth : 0)); |
| 4999 LayoutUnit top(borderTop()); | 5140 LayoutUnit top(borderTop()); |
| 5000 LayoutUnit right(borderRight()); | 5141 LayoutUnit right(borderRight()); |
| 5001 LayoutUnit bottom(borderBottom()); | 5142 LayoutUnit bottom(borderBottom()); |
| 5002 LayoutRect rect(left, top, size().width() - left - right, | 5143 LayoutRect rect(left, top, size().width() - left - right, |
| 5003 size().height() - top - bottom); | 5144 size().height() - top - bottom); |
| 5004 flipForWritingMode(rect); | 5145 flipForWritingMode(rect); |
| 5005 // Subtract space occupied by scrollbars. Order is important here: first flip, then subtract | 5146 // Subtract space occupied by scrollbars. Order is important here: first flip, |
| 5006 // scrollbars. This may seem backwards and weird, since one would think that a vertical | 5147 // then subtract scrollbars. This may seem backwards and weird, since one |
| 5007 // scrollbar at the physical right in vertical-rl ought to be at the logical l eft (physical | 5148 // would think that a vertical scrollbar at the physical right in vertical-rl |
| 5008 // right), between the logical left (physical right) border and the logical le ft (physical | 5149 // ought to be at the logical left (physical right), between the logical left |
| 5009 // right) padding. But this is how the rest of the code expects us to behave. This is highly | 5150 // (physical right) border and the logical left (physical right) padding. But |
| 5151 // this is how the rest of the code expects us to behave. This is highly | |
| 5010 // related to https://bugs.webkit.org/show_bug.cgi?id=76129 | 5152 // related to https://bugs.webkit.org/show_bug.cgi?id=76129 |
| 5011 // FIXME: when the above mentioned bug is fixed, it should hopefully be possib le to call | 5153 // FIXME: when the above mentioned bug is fixed, it should hopefully be |
| 5012 // clientBoxRect() or paddingBoxRect() in this method, rather than fiddling wi th the edges on | 5154 // possible to call clientBoxRect() or paddingBoxRect() in this method, rather |
| 5013 // our own. | 5155 // than fiddling with the edges on our own. |
| 5014 if (shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) | 5156 if (shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) |
| 5015 rect.contract(0, scrollBarHeight); | 5157 rect.contract(0, scrollBarHeight); |
| 5016 else | 5158 else |
| 5017 rect.contract(scrollBarWidth, scrollBarHeight); | 5159 rect.contract(scrollBarWidth, scrollBarHeight); |
| 5018 return rect; | 5160 return rect; |
| 5019 } | 5161 } |
| 5020 | 5162 |
| 5021 LayoutRect LayoutBox::visualOverflowRect() const { | 5163 LayoutRect LayoutBox::visualOverflowRect() const { |
| 5022 if (!m_overflow) | 5164 if (!m_overflow) |
| 5023 return borderBoxRect(); | 5165 return borderBoxRect(); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5066 bool LayoutBox::hasRelativeLogicalHeight() const { | 5208 bool LayoutBox::hasRelativeLogicalHeight() const { |
| 5067 return style()->logicalHeight().isPercentOrCalc() || | 5209 return style()->logicalHeight().isPercentOrCalc() || |
| 5068 style()->logicalMinHeight().isPercentOrCalc() || | 5210 style()->logicalMinHeight().isPercentOrCalc() || |
| 5069 style()->logicalMaxHeight().isPercentOrCalc(); | 5211 style()->logicalMaxHeight().isPercentOrCalc(); |
| 5070 } | 5212 } |
| 5071 | 5213 |
| 5072 static void markBoxForRelayoutAfterSplit(LayoutBox* box) { | 5214 static void markBoxForRelayoutAfterSplit(LayoutBox* box) { |
| 5073 // FIXME: The table code should handle that automatically. If not, | 5215 // FIXME: The table code should handle that automatically. If not, |
| 5074 // we should fix it and remove the table part checks. | 5216 // we should fix it and remove the table part checks. |
| 5075 if (box->isTable()) { | 5217 if (box->isTable()) { |
| 5076 // Because we may have added some sections with already computed column stru ctures, we need to | 5218 // Because we may have added some sections with already computed column |
| 5077 // sync the table structure with them now. This avoids crashes when adding n ew cells to the table. | 5219 // structures, we need to sync the table structure with them now. This |
| 5220 // avoids crashes when adding new cells to the table. | |
| 5078 toLayoutTable(box)->forceSectionsRecalc(); | 5221 toLayoutTable(box)->forceSectionsRecalc(); |
| 5079 } else if (box->isTableSection()) { | 5222 } else if (box->isTableSection()) { |
| 5080 toLayoutTableSection(box)->setNeedsCellRecalc(); | 5223 toLayoutTableSection(box)->setNeedsCellRecalc(); |
| 5081 } | 5224 } |
| 5082 | 5225 |
| 5083 box->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( | 5226 box->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( |
| 5084 LayoutInvalidationReason::AnonymousBlockChange); | 5227 LayoutInvalidationReason::AnonymousBlockChange); |
| 5085 } | 5228 } |
| 5086 | 5229 |
| 5087 static void collapseLoneAnonymousBlockChild(LayoutBox* parent, | 5230 static void collapseLoneAnonymousBlockChild(LayoutBox* parent, |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 5101 while (beforeChild->parent() != this) { | 5244 while (beforeChild->parent() != this) { |
| 5102 LayoutBox* boxToSplit = toLayoutBox(beforeChild->parent()); | 5245 LayoutBox* boxToSplit = toLayoutBox(beforeChild->parent()); |
| 5103 if (boxToSplit->slowFirstChild() != beforeChild && | 5246 if (boxToSplit->slowFirstChild() != beforeChild && |
| 5104 boxToSplit->isAnonymous()) { | 5247 boxToSplit->isAnonymous()) { |
| 5105 // We have to split the parent box into two boxes and move children | 5248 // We have to split the parent box into two boxes and move children |
| 5106 // from |beforeChild| to end into the new post box. | 5249 // from |beforeChild| to end into the new post box. |
| 5107 LayoutBox* postBox = boxToSplit->createAnonymousBoxWithSameTypeAs(this); | 5250 LayoutBox* postBox = boxToSplit->createAnonymousBoxWithSameTypeAs(this); |
| 5108 postBox->setChildrenInline(boxToSplit->childrenInline()); | 5251 postBox->setChildrenInline(boxToSplit->childrenInline()); |
| 5109 LayoutBox* parentBox = toLayoutBox(boxToSplit->parent()); | 5252 LayoutBox* parentBox = toLayoutBox(boxToSplit->parent()); |
| 5110 // We need to invalidate the |parentBox| before inserting the new node | 5253 // We need to invalidate the |parentBox| before inserting the new node |
| 5111 // so that the table paint invalidation logic knows the structure is dirty . | 5254 // so that the table paint invalidation logic knows the structure is |
| 5255 // dirty. | |
| 5112 // See for example LayoutTableCell:localOverflowRectForPaintInvalidation. | 5256 // See for example LayoutTableCell:localOverflowRectForPaintInvalidation. |
| 5113 markBoxForRelayoutAfterSplit(parentBox); | 5257 markBoxForRelayoutAfterSplit(parentBox); |
| 5114 parentBox->virtualChildren()->insertChildNode(parentBox, postBox, | 5258 parentBox->virtualChildren()->insertChildNode(parentBox, postBox, |
| 5115 boxToSplit->nextSibling()); | 5259 boxToSplit->nextSibling()); |
| 5116 boxToSplit->moveChildrenTo(postBox, beforeChild, 0, true); | 5260 boxToSplit->moveChildrenTo(postBox, beforeChild, 0, true); |
| 5117 | 5261 |
| 5118 LayoutObject* child = postBox->slowFirstChild(); | 5262 LayoutObject* child = postBox->slowFirstChild(); |
| 5119 ASSERT(child); | 5263 ASSERT(child); |
| 5120 if (child && !child->nextSibling()) | 5264 if (child && !child->nextSibling()) |
| 5121 collapseLoneAnonymousBlockChild(postBox, child); | 5265 collapseLoneAnonymousBlockChild(postBox, child); |
| 5122 child = boxToSplit->slowFirstChild(); | 5266 child = boxToSplit->slowFirstChild(); |
| 5123 ASSERT(child); | 5267 ASSERT(child); |
| 5124 if (child && !child->nextSibling()) | 5268 if (child && !child->nextSibling()) |
| 5125 collapseLoneAnonymousBlockChild(boxToSplit, child); | 5269 collapseLoneAnonymousBlockChild(boxToSplit, child); |
| 5126 | 5270 |
| 5127 markBoxForRelayoutAfterSplit(boxToSplit); | 5271 markBoxForRelayoutAfterSplit(boxToSplit); |
| 5128 markBoxForRelayoutAfterSplit(postBox); | 5272 markBoxForRelayoutAfterSplit(postBox); |
| 5129 boxAtTopOfNewBranch = postBox; | 5273 boxAtTopOfNewBranch = postBox; |
| 5130 | 5274 |
| 5131 beforeChild = postBox; | 5275 beforeChild = postBox; |
| 5132 } else { | 5276 } else { |
| 5133 beforeChild = boxToSplit; | 5277 beforeChild = boxToSplit; |
| 5134 } | 5278 } |
| 5135 } | 5279 } |
| 5136 | 5280 |
| 5137 // Splitting the box means the left side of the container chain will lose any percent height descendants | 5281 // Splitting the box means the left side of the container chain will lose any |
| 5138 // below |boxAtTopOfNewBranch| on the right hand side. | 5282 // percent height descendants below |boxAtTopOfNewBranch| on the right hand |
| 5283 // side. | |
| 5139 if (boxAtTopOfNewBranch) { | 5284 if (boxAtTopOfNewBranch) { |
| 5140 boxAtTopOfNewBranch->clearPercentHeightDescendants(); | 5285 boxAtTopOfNewBranch->clearPercentHeightDescendants(); |
| 5141 markBoxForRelayoutAfterSplit(this); | 5286 markBoxForRelayoutAfterSplit(this); |
| 5142 } | 5287 } |
| 5143 | 5288 |
| 5144 ASSERT(beforeChild->parent() == this); | 5289 ASSERT(beforeChild->parent() == this); |
| 5145 return beforeChild; | 5290 return beforeChild; |
| 5146 } | 5291 } |
| 5147 | 5292 |
| 5148 LayoutUnit LayoutBox::offsetFromLogicalTopOfFirstPage() const { | 5293 LayoutUnit LayoutBox::offsetFromLogicalTopOfFirstPage() const { |
| 5149 LayoutState* layoutState = view()->layoutState(); | 5294 LayoutState* layoutState = view()->layoutState(); |
| 5150 if (!layoutState || !layoutState->isPaginated()) | 5295 if (!layoutState || !layoutState->isPaginated()) |
| 5151 return LayoutUnit(); | 5296 return LayoutUnit(); |
| 5152 | 5297 |
| 5153 if (layoutState->layoutObject() == this) { | 5298 if (layoutState->layoutObject() == this) { |
| 5154 LayoutSize offsetDelta = | 5299 LayoutSize offsetDelta = |
| 5155 layoutState->layoutOffset() - layoutState->pageOffset(); | 5300 layoutState->layoutOffset() - layoutState->pageOffset(); |
| 5156 return isHorizontalWritingMode() ? offsetDelta.height() | 5301 return isHorizontalWritingMode() ? offsetDelta.height() |
| 5157 : offsetDelta.width(); | 5302 : offsetDelta.width(); |
| 5158 } | 5303 } |
| 5159 | 5304 |
| 5160 // A LayoutBlock always establishes a layout state, and this method is only me ant to be called | 5305 // A LayoutBlock always establishes a layout state, and this method is only |
| 5161 // on the object currently being laid out. | 5306 // meant to be called on the object currently being laid out. |
| 5162 ASSERT(!isLayoutBlock()); | 5307 ASSERT(!isLayoutBlock()); |
| 5163 | 5308 |
| 5164 // In case this box doesn't establish a layout state, try the containing block . | 5309 // In case this box doesn't establish a layout state, try the containing |
| 5310 // block. | |
| 5165 LayoutBlock* containerBlock = containingBlock(); | 5311 LayoutBlock* containerBlock = containingBlock(); |
| 5166 ASSERT(layoutState->layoutObject() == containerBlock); | 5312 ASSERT(layoutState->layoutObject() == containerBlock); |
| 5167 return containerBlock->offsetFromLogicalTopOfFirstPage() + logicalTop(); | 5313 return containerBlock->offsetFromLogicalTopOfFirstPage() + logicalTop(); |
| 5168 } | 5314 } |
| 5169 | 5315 |
| 5170 void LayoutBox::setPageLogicalOffset(LayoutUnit offset) { | 5316 void LayoutBox::setPageLogicalOffset(LayoutUnit offset) { |
| 5171 if (!m_rareData && !offset) | 5317 if (!m_rareData && !offset) |
| 5172 return; | 5318 return; |
| 5173 ensureRareData().m_pageLogicalOffset = offset; | 5319 ensureRareData().m_pageLogicalOffset = offset; |
| 5174 } | 5320 } |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5341 return; | 5487 return; |
| 5342 ensureRareData().m_percentHeightContainer = container; | 5488 ensureRareData().m_percentHeightContainer = container; |
| 5343 } | 5489 } |
| 5344 | 5490 |
| 5345 void LayoutBox::removeFromPercentHeightContainer() { | 5491 void LayoutBox::removeFromPercentHeightContainer() { |
| 5346 if (!percentHeightContainer()) | 5492 if (!percentHeightContainer()) |
| 5347 return; | 5493 return; |
| 5348 | 5494 |
| 5349 ASSERT(percentHeightContainer()->hasPercentHeightDescendant(this)); | 5495 ASSERT(percentHeightContainer()->hasPercentHeightDescendant(this)); |
| 5350 percentHeightContainer()->removePercentHeightDescendant(this); | 5496 percentHeightContainer()->removePercentHeightDescendant(this); |
| 5351 // The above call should call this object's setPercentHeightContainer(nullptr) . | 5497 // The above call should call this object's |
| 5498 // setPercentHeightContainer(nullptr). | |
| 5352 ASSERT(!percentHeightContainer()); | 5499 ASSERT(!percentHeightContainer()); |
| 5353 } | 5500 } |
| 5354 | 5501 |
| 5355 void LayoutBox::clearPercentHeightDescendants() { | 5502 void LayoutBox::clearPercentHeightDescendants() { |
| 5356 for (LayoutObject* curr = slowFirstChild(); curr; | 5503 for (LayoutObject* curr = slowFirstChild(); curr; |
| 5357 curr = curr->nextInPreOrder(this)) { | 5504 curr = curr->nextInPreOrder(this)) { |
| 5358 if (curr->isBox()) | 5505 if (curr->isBox()) |
| 5359 toLayoutBox(curr)->removeFromPercentHeightContainer(); | 5506 toLayoutBox(curr)->removeFromPercentHeightContainer(); |
| 5360 } | 5507 } |
| 5361 } | 5508 } |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 5374 PageBoundaryRule pageBoundaryRule) const { | 5521 PageBoundaryRule pageBoundaryRule) const { |
| 5375 LayoutView* layoutView = view(); | 5522 LayoutView* layoutView = view(); |
| 5376 offset += offsetFromLogicalTopOfFirstPage(); | 5523 offset += offsetFromLogicalTopOfFirstPage(); |
| 5377 | 5524 |
| 5378 LayoutFlowThread* flowThread = flowThreadContainingBlock(); | 5525 LayoutFlowThread* flowThread = flowThreadContainingBlock(); |
| 5379 if (!flowThread) { | 5526 if (!flowThread) { |
| 5380 LayoutUnit pageLogicalHeight = layoutView->pageLogicalHeight(); | 5527 LayoutUnit pageLogicalHeight = layoutView->pageLogicalHeight(); |
| 5381 LayoutUnit remainingHeight = | 5528 LayoutUnit remainingHeight = |
| 5382 pageLogicalHeight - intMod(offset, pageLogicalHeight); | 5529 pageLogicalHeight - intMod(offset, pageLogicalHeight); |
| 5383 if (pageBoundaryRule == AssociateWithFormerPage) { | 5530 if (pageBoundaryRule == AssociateWithFormerPage) { |
| 5384 // An offset exactly at a page boundary will act as being part of the form er page in | 5531 // An offset exactly at a page boundary will act as being part of the |
| 5385 // question (i.e. no remaining space), rather than being part of the latte r (i.e. one | 5532 // former page in question (i.e. no remaining space), rather than being |
| 5386 // whole page length of remaining space). | 5533 // part of the latter (i.e. one whole page length of remaining space). |
| 5387 remainingHeight = intMod(remainingHeight, pageLogicalHeight); | 5534 remainingHeight = intMod(remainingHeight, pageLogicalHeight); |
| 5388 } | 5535 } |
| 5389 return remainingHeight; | 5536 return remainingHeight; |
| 5390 } | 5537 } |
| 5391 | 5538 |
| 5392 return flowThread->pageRemainingLogicalHeightForOffset(offset, | 5539 return flowThread->pageRemainingLogicalHeightForOffset(offset, |
| 5393 pageBoundaryRule); | 5540 pageBoundaryRule); |
| 5394 } | 5541 } |
| 5395 | 5542 |
| 5396 LayoutUnit LayoutBox::calculatePaginationStrutToFitContent( | 5543 LayoutUnit LayoutBox::calculatePaginationStrutToFitContent( |
| 5397 LayoutUnit offset, | 5544 LayoutUnit offset, |
| 5398 LayoutUnit strutToNextPage, | 5545 LayoutUnit strutToNextPage, |
| 5399 LayoutUnit contentLogicalHeight) const { | 5546 LayoutUnit contentLogicalHeight) const { |
| 5400 ASSERT(strutToNextPage == | 5547 ASSERT(strutToNextPage == |
| 5401 pageRemainingLogicalHeightForOffset(offset, AssociateWithLatterPage)); | 5548 pageRemainingLogicalHeightForOffset(offset, AssociateWithLatterPage)); |
| 5402 LayoutUnit nextPageLogicalTop = offset + strutToNextPage; | 5549 LayoutUnit nextPageLogicalTop = offset + strutToNextPage; |
| 5403 if (pageLogicalHeightForOffset(nextPageLogicalTop) >= contentLogicalHeight) | 5550 if (pageLogicalHeightForOffset(nextPageLogicalTop) >= contentLogicalHeight) |
| 5404 return strutToNextPage; // Content fits just fine in the next page or colum n. | 5551 return strutToNextPage; // Content fits just fine in the next page or |
| 5552 // column. | |
| 5405 | 5553 |
| 5406 // Moving to the top of the next page or column doesn't result in enough space for the content | 5554 // Moving to the top of the next page or column doesn't result in enough space |
| 5407 // that we're trying to fit. If we're in a nested fragmentation context, we ma y find enough | 5555 // for the content that we're trying to fit. If we're in a nested |
| 5408 // space if we move to a column further ahead, by effectively breaking to the next outer | 5556 // fragmentation context, we may find enough space if we move to a column |
| 5409 // fragmentainer. | 5557 // further ahead, by effectively breaking to the next outer fragmentainer. |
| 5410 LayoutFlowThread* flowThread = flowThreadContainingBlock(); | 5558 LayoutFlowThread* flowThread = flowThreadContainingBlock(); |
| 5411 if (!flowThread) { | 5559 if (!flowThread) { |
| 5412 // If there's no flow thread, we're not nested. All pages have the same heig ht. Give up. | 5560 // If there's no flow thread, we're not nested. All pages have the same |
| 5561 // height. Give up. | |
| 5413 return strutToNextPage; | 5562 return strutToNextPage; |
| 5414 } | 5563 } |
| 5415 // Start searching for a suitable offset at the top of the next page or column . | 5564 // Start searching for a suitable offset at the top of the next page or |
| 5565 // column. | |
| 5416 LayoutUnit flowThreadOffset = | 5566 LayoutUnit flowThreadOffset = |
| 5417 offsetFromLogicalTopOfFirstPage() + nextPageLogicalTop; | 5567 offsetFromLogicalTopOfFirstPage() + nextPageLogicalTop; |
| 5418 return strutToNextPage + | 5568 return strutToNextPage + |
| 5419 flowThread->nextLogicalTopForUnbreakableContent(flowThreadOffset, | 5569 flowThread->nextLogicalTopForUnbreakableContent(flowThreadOffset, |
| 5420 contentLogicalHeight) - | 5570 contentLogicalHeight) - |
| 5421 flowThreadOffset; | 5571 flowThreadOffset; |
| 5422 } | 5572 } |
| 5423 | 5573 |
| 5424 LayoutBox* LayoutBox::snapContainer() const { | 5574 LayoutBox* LayoutBox::snapContainer() const { |
| 5425 return m_rareData ? m_rareData->m_snapContainer : nullptr; | 5575 return m_rareData ? m_rareData->m_snapContainer : nullptr; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5465 LayoutRect rect = frameRect(); | 5615 LayoutRect rect = frameRect(); |
| 5466 | 5616 |
| 5467 LayoutBlock* block = containingBlock(); | 5617 LayoutBlock* block = containingBlock(); |
| 5468 if (block) | 5618 if (block) |
| 5469 block->adjustChildDebugRect(rect); | 5619 block->adjustChildDebugRect(rect); |
| 5470 | 5620 |
| 5471 return rect; | 5621 return rect; |
| 5472 } | 5622 } |
| 5473 | 5623 |
| 5474 } // namespace blink | 5624 } // namespace blink |
| OLD | NEW |