| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) | 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) |
| 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) | 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) |
| 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. | 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
| 7 * Copyright (C) 2010 Google Inc. All rights reserved. | 7 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 8 * | 8 * |
| 9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
| 10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 | 140 |
| 141 RenderStyle* styleToUse = style(); | 141 RenderStyle* styleToUse = style(); |
| 142 setHasBoxDecorations(calculateHasBoxDecorations()); | 142 setHasBoxDecorations(calculateHasBoxDecorations()); |
| 143 setInline(styleToUse->isDisplayInlineType()); | 143 setInline(styleToUse->isDisplayInlineType()); |
| 144 setPositionState(styleToUse->position()); | 144 setPositionState(styleToUse->position()); |
| 145 setHorizontalWritingMode(styleToUse->isHorizontalWritingMode()); | 145 setHorizontalWritingMode(styleToUse->isHorizontalWritingMode()); |
| 146 } | 146 } |
| 147 | 147 |
| 148 static LayoutSize accumulateInFlowPositionOffsets(const RenderObject* child) | 148 static LayoutSize accumulateInFlowPositionOffsets(const RenderObject* child) |
| 149 { | 149 { |
| 150 if (!child->isAnonymousBlock() || !child->isInFlowPositioned()) | 150 if (!child->isAnonymousBlock() || !child->isRelPositioned()) |
| 151 return LayoutSize(); | 151 return LayoutSize(); |
| 152 LayoutSize offset; | 152 LayoutSize offset; |
| 153 RenderObject* p = toRenderBlock(child)->inlineElementContinuation(); | 153 RenderObject* p = toRenderBlock(child)->inlineElementContinuation(); |
| 154 while (p && p->isRenderInline()) { | 154 while (p && p->isRenderInline()) { |
| 155 if (p->isInFlowPositioned()) { | 155 if (p->isRelPositioned()) { |
| 156 RenderInline* renderInline = toRenderInline(p); | 156 RenderInline* renderInline = toRenderInline(p); |
| 157 offset += renderInline->offsetForInFlowPosition(); | 157 offset += renderInline->offsetForInFlowPosition(); |
| 158 } | 158 } |
| 159 p = p->parent(); | 159 p = p->parent(); |
| 160 } | 160 } |
| 161 return offset; | 161 return offset; |
| 162 } | 162 } |
| 163 | 163 |
| 164 bool RenderBoxModelObject::hasAutoHeightOrContainingBlockWithAutoHeight() const | 164 bool RenderBoxModelObject::hasAutoHeightOrContainingBlockWithAutoHeight() const |
| 165 { | 165 { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 Element* element = offsetParent(); | 253 Element* element = offsetParent(); |
| 254 if (!element) | 254 if (!element) |
| 255 return referencePoint; | 255 return referencePoint; |
| 256 | 256 |
| 257 if (const RenderBoxModelObject* offsetParent = element->renderBoxModelObject
()) { | 257 if (const RenderBoxModelObject* offsetParent = element->renderBoxModelObject
()) { |
| 258 if (offsetParent->isBox() && !offsetParent->isBody()) | 258 if (offsetParent->isBox() && !offsetParent->isBody()) |
| 259 referencePoint.move(-toRenderBox(offsetParent)->borderLeft(), -toRen
derBox(offsetParent)->borderTop()); | 259 referencePoint.move(-toRenderBox(offsetParent)->borderLeft(), -toRen
derBox(offsetParent)->borderTop()); |
| 260 if (!isOutOfFlowPositioned() || flowThreadContainingBlock()) { | 260 if (!isOutOfFlowPositioned() || flowThreadContainingBlock()) { |
| 261 if (isRelPositioned()) | 261 if (isRelPositioned()) |
| 262 referencePoint.move(relativePositionOffset()); | 262 referencePoint.move(relativePositionOffset()); |
| 263 else if (isStickyPositioned()) | |
| 264 referencePoint.move(stickyPositionOffset()); | |
| 265 | 263 |
| 266 RenderObject* current; | 264 RenderObject* current; |
| 267 for (current = parent(); current != offsetParent && current->parent(
); current = current->parent()) { | 265 for (current = parent(); current != offsetParent && current->parent(
); current = current->parent()) { |
| 268 // FIXME: What are we supposed to do inside SVG content? | 266 // FIXME: What are we supposed to do inside SVG content? |
| 269 if (!isOutOfFlowPositioned()) { | 267 if (!isOutOfFlowPositioned()) { |
| 270 if (current->isBox() && !current->isTableRow()) | 268 if (current->isBox() && !current->isTableRow()) |
| 271 referencePoint.moveBy(toRenderBox(current)->topLeftLocat
ion()); | 269 referencePoint.moveBy(toRenderBox(current)->topLeftLocat
ion()); |
| 272 referencePoint.move(current->parent()->columnOffset(referenc
ePoint)); | 270 referencePoint.move(current->parent()->columnOffset(referenc
ePoint)); |
| 273 } | 271 } |
| 274 } | 272 } |
| 275 | 273 |
| 276 if (offsetParent->isBox() && offsetParent->isBody() && !offsetParent
->isPositioned()) | 274 if (offsetParent->isBox() && offsetParent->isBody() && !offsetParent
->isPositioned()) |
| 277 referencePoint.moveBy(toRenderBox(offsetParent)->topLeftLocation
()); | 275 referencePoint.moveBy(toRenderBox(offsetParent)->topLeftLocation
()); |
| 278 } | 276 } |
| 279 } | 277 } |
| 280 | 278 |
| 281 return referencePoint; | 279 return referencePoint; |
| 282 } | 280 } |
| 283 | 281 |
| 284 void RenderBoxModelObject::computeStickyPositionConstraints(StickyPositionViewpo
rtConstraints& constraints, const FloatRect& constrainingRect) const | |
| 285 { | |
| 286 RenderBlock* containingBlock = this->containingBlock(); | |
| 287 | |
| 288 LayoutRect containerContentRect = containingBlock->contentBoxRect(); | |
| 289 LayoutUnit maxWidth = containingBlock->availableLogicalWidth(); | |
| 290 | |
| 291 // Sticky positioned element ignore any override logical width on the contai
ning block (as they don't call | |
| 292 // containingBlockLogicalWidthForContent). It's unclear whether this is tota
lly fine. | |
| 293 LayoutBoxExtent minMargin(minimumValueForLength(style()->marginTop(), maxWid
th), | |
| 294 minimumValueForLength(style()->marginRight(), maxWidth), | |
| 295 minimumValueForLength(style()->marginBottom(), maxWidth), | |
| 296 minimumValueForLength(style()->marginLeft(), maxWidth)); | |
| 297 | |
| 298 // Compute the container-relative area within which the sticky element is al
lowed to move. | |
| 299 containerContentRect.contract(minMargin); | |
| 300 // Map to the view to avoid including page scale factor. | |
| 301 constraints.setAbsoluteContainingBlockRect(containingBlock->localToContainer
Quad(FloatRect(containerContentRect), view()).boundingBox()); | |
| 302 | |
| 303 LayoutRect stickyBoxRect = frameRectForStickyPositioning(); | |
| 304 LayoutRect flippedStickyBoxRect = stickyBoxRect; | |
| 305 containingBlock->flipForWritingMode(flippedStickyBoxRect); | |
| 306 LayoutPoint stickyLocation = flippedStickyBoxRect.location(); | |
| 307 | |
| 308 // FIXME: sucks to call localToAbsolute again, but we can't just offset from
the previously computed rect if there are transforms. | |
| 309 // Map to the view to avoid including page scale factor. | |
| 310 FloatRect absContainerFrame = containingBlock->localToContainerQuad(FloatRec
t(FloatPoint(), containingBlock->size()), view()).boundingBox(); | |
| 311 | |
| 312 if (containingBlock->hasOverflowClip()) { | |
| 313 IntSize scrollOffset = containingBlock->layer()->scrollableArea()->adjus
tedScrollOffset(); | |
| 314 stickyLocation -= scrollOffset; | |
| 315 } | |
| 316 | |
| 317 // We can't call localToAbsolute on |this| because that will recur. FIXME: F
or now, assume that |this| is not transformed. | |
| 318 FloatRect absoluteStickyBoxRect(absContainerFrame.location() + stickyLocatio
n, flippedStickyBoxRect.size()); | |
| 319 constraints.setAbsoluteStickyBoxRect(absoluteStickyBoxRect); | |
| 320 | |
| 321 float horizontalOffsets = constraints.rightOffset() + constraints.leftOffset
(); | |
| 322 bool skipRight = false; | |
| 323 bool skipLeft = false; | |
| 324 if (!style()->left().isAuto() && !style()->right().isAuto()) { | |
| 325 if (horizontalOffsets > containerContentRect.width().toFloat() | |
| 326 || horizontalOffsets + containerContentRect.width().toFloat() > cons
trainingRect.width()) { | |
| 327 skipRight = style()->isLeftToRightDirection(); | |
| 328 skipLeft = !skipRight; | |
| 329 } | |
| 330 } | |
| 331 | |
| 332 if (!style()->left().isAuto() && !skipLeft) { | |
| 333 constraints.setLeftOffset(floatValueForLength(style()->left(), constrain
ingRect.width())); | |
| 334 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeLeft); | |
| 335 } | |
| 336 | |
| 337 if (!style()->right().isAuto() && !skipRight) { | |
| 338 constraints.setRightOffset(floatValueForLength(style()->right(), constra
iningRect.width())); | |
| 339 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeRight); | |
| 340 } | |
| 341 | |
| 342 bool skipBottom = false; | |
| 343 // FIXME(ostap): Exclude top or bottom edge offset depending on the writing
mode when related | |
| 344 // sections are fixed in spec: http://lists.w3.org/Archives/Public/www-style
/2014May/0286.html | |
| 345 float verticalOffsets = constraints.topOffset() + constraints.bottomOffset()
; | |
| 346 if (!style()->top().isAuto() && !style()->bottom().isAuto()) { | |
| 347 if (verticalOffsets > containerContentRect.height().toFloat() | |
| 348 || verticalOffsets + containerContentRect.height().toFloat() > const
rainingRect.height()) { | |
| 349 skipBottom = true; | |
| 350 } | |
| 351 } | |
| 352 | |
| 353 if (!style()->top().isAuto()) { | |
| 354 constraints.setTopOffset(floatValueForLength(style()->top(), constrainin
gRect.height())); | |
| 355 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeTop); | |
| 356 } | |
| 357 | |
| 358 if (!style()->bottom().isAuto() && !skipBottom) { | |
| 359 constraints.setBottomOffset(floatValueForLength(style()->bottom(), const
rainingRect.height())); | |
| 360 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeBottom); | |
| 361 } | |
| 362 } | |
| 363 | |
| 364 LayoutSize RenderBoxModelObject::stickyPositionOffset() const | |
| 365 { | |
| 366 FloatRect constrainingRect; | |
| 367 | |
| 368 ASSERT(hasLayer()); | |
| 369 RenderLayer* enclosingClippingLayer = layer()->enclosingOverflowClipLayer(Ex
cludeSelf); | |
| 370 if (enclosingClippingLayer) { | |
| 371 RenderBox* enclosingClippingBox = toRenderBox(enclosingClippingLayer->re
nderer()); | |
| 372 LayoutRect clipRect = enclosingClippingBox->overflowClipRect(LayoutPoint
()); | |
| 373 clipRect.move(enclosingClippingBox->paddingLeft(), enclosingClippingBox-
>paddingTop()); | |
| 374 clipRect.contract(LayoutSize(enclosingClippingBox->paddingLeft() + enclo
singClippingBox->paddingRight(), | |
| 375 enclosingClippingBox->paddingTop() + enclosingClippingBox->paddingBo
ttom())); | |
| 376 constrainingRect = enclosingClippingBox->localToContainerQuad(FloatRect(
clipRect), view()).boundingBox(); | |
| 377 } else { | |
| 378 LayoutRect viewportRect = view()->frameView()->viewportConstrainedVisibl
eContentRect(); | |
| 379 constrainingRect = viewportRect; | |
| 380 } | |
| 381 | |
| 382 StickyPositionViewportConstraints constraints; | |
| 383 computeStickyPositionConstraints(constraints, constrainingRect); | |
| 384 | |
| 385 // The sticky offset is physical, so we can just return the delta computed i
n absolute coords (though it may be wrong with transforms). | |
| 386 return LayoutSize(constraints.computeStickyOffset(constrainingRect)); | |
| 387 } | |
| 388 | |
| 389 LayoutSize RenderBoxModelObject::offsetForInFlowPosition() const | 282 LayoutSize RenderBoxModelObject::offsetForInFlowPosition() const |
| 390 { | 283 { |
| 391 if (isRelPositioned()) | 284 return isRelPositioned() ? relativePositionOffset() : LayoutSize(); |
| 392 return relativePositionOffset(); | |
| 393 | |
| 394 if (isStickyPositioned()) | |
| 395 return stickyPositionOffset(); | |
| 396 | |
| 397 return LayoutSize(); | |
| 398 } | 285 } |
| 399 | 286 |
| 400 LayoutUnit RenderBoxModelObject::offsetLeft() const | 287 LayoutUnit RenderBoxModelObject::offsetLeft() const |
| 401 { | 288 { |
| 402 // Note that RenderInline and RenderBox override this to pass a different | 289 // Note that RenderInline and RenderBox override this to pass a different |
| 403 // startPoint to adjustedPositionRelativeToOffsetParent. | 290 // startPoint to adjustedPositionRelativeToOffsetParent. |
| 404 return adjustedPositionRelativeToOffsetParent(LayoutPoint()).x(); | 291 return adjustedPositionRelativeToOffsetParent(LayoutPoint()).x(); |
| 405 } | 292 } |
| 406 | 293 |
| 407 LayoutUnit RenderBoxModelObject::offsetTop() const | 294 LayoutUnit RenderBoxModelObject::offsetTop() const |
| (...skipping 2433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2841 ASSERT(!beforeChild || toBoxModelObject == beforeChild->parent()); | 2728 ASSERT(!beforeChild || toBoxModelObject == beforeChild->parent()); |
| 2842 for (RenderObject* child = startChild; child && child != endChild; ) { | 2729 for (RenderObject* child = startChild; child && child != endChild; ) { |
| 2843 // Save our next sibling as moveChildTo will clear it. | 2730 // Save our next sibling as moveChildTo will clear it. |
| 2844 RenderObject* nextSibling = child->nextSibling(); | 2731 RenderObject* nextSibling = child->nextSibling(); |
| 2845 moveChildTo(toBoxModelObject, child, beforeChild, fullRemoveInsert); | 2732 moveChildTo(toBoxModelObject, child, beforeChild, fullRemoveInsert); |
| 2846 child = nextSibling; | 2733 child = nextSibling; |
| 2847 } | 2734 } |
| 2848 } | 2735 } |
| 2849 | 2736 |
| 2850 } // namespace WebCore | 2737 } // namespace WebCore |
| OLD | NEW |