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

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

Powered by Google App Engine
This is Rietveld 408576698