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