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

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

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