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