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