Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutBox.cpp

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

Powered by Google App Engine
This is Rietveld 408576698