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