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

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

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

Powered by Google App Engine
This is Rietveld 408576698