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