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