Chromium Code Reviews| 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 20 matching lines...) Expand all Loading... | |
| 31 #include "core/layout/ImageQualityController.h" | 31 #include "core/layout/ImageQualityController.h" |
| 32 #include "core/layout/LayoutBlock.h" | 32 #include "core/layout/LayoutBlock.h" |
| 33 #include "core/layout/LayoutFlowThread.h" | 33 #include "core/layout/LayoutFlowThread.h" |
| 34 #include "core/layout/LayoutGeometryMap.h" | 34 #include "core/layout/LayoutGeometryMap.h" |
| 35 #include "core/layout/LayoutInline.h" | 35 #include "core/layout/LayoutInline.h" |
| 36 #include "core/layout/LayoutObject.h" | 36 #include "core/layout/LayoutObject.h" |
| 37 #include "core/layout/LayoutTextFragment.h" | 37 #include "core/layout/LayoutTextFragment.h" |
| 38 #include "core/layout/LayoutView.h" | 38 #include "core/layout/LayoutView.h" |
| 39 #include "core/layout/compositing/CompositedLayerMapping.h" | 39 #include "core/layout/compositing/CompositedLayerMapping.h" |
| 40 #include "core/layout/compositing/PaintLayerCompositor.h" | 40 #include "core/layout/compositing/PaintLayerCompositor.h" |
| 41 #include "core/page/scrolling/ScrollingConstraints.h" | 41 #include "core/page/scrolling/StickyPositionViewportConstraints.h" |
| 42 #include "core/page/scrolling/ViewportConstraints.h" | |
| 42 #include "core/paint/PaintLayer.h" | 43 #include "core/paint/PaintLayer.h" |
| 43 #include "core/style/BorderEdge.h" | 44 #include "core/style/BorderEdge.h" |
| 44 #include "core/style/ShadowList.h" | 45 #include "core/style/ShadowList.h" |
| 45 #include "platform/LengthFunctions.h" | 46 #include "platform/LengthFunctions.h" |
| 46 #include "platform/geometry/TransformState.h" | 47 #include "platform/geometry/TransformState.h" |
| 47 #include "wtf/CurrentTime.h" | 48 #include "wtf/CurrentTime.h" |
| 48 | 49 |
| 49 namespace blink { | 50 namespace blink { |
| 50 | 51 |
| 51 class FloatStateForStyleChange { | 52 class FloatStateForStyleChange { |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 170 if (parent() && diff.needsPaintInvalidationLayer()) { | 171 if (parent() && diff.needsPaintInvalidationLayer()) { |
| 171 if (oldStyle->hasAutoClip() != newStyle.hasAutoClip() | 172 if (oldStyle->hasAutoClip() != newStyle.hasAutoClip() |
| 172 || oldStyle->clip() != newStyle.clip()) | 173 || oldStyle->clip() != newStyle.clip()) |
| 173 layer()->clipper().clearClipRectsIncludingDescendants(); | 174 layer()->clipper().clearClipRectsIncludingDescendants(); |
| 174 } | 175 } |
| 175 } | 176 } |
| 176 | 177 |
| 177 LayoutObject::styleWillChange(diff, newStyle); | 178 LayoutObject::styleWillChange(diff, newStyle); |
| 178 } | 179 } |
| 179 | 180 |
| 181 static inline LayoutBox* findScrollAncestor(const LayoutObject* startObject) | |
| 182 { | |
| 183 // If compositing inputs should be fresh, we can get the scroll parent from | |
| 184 // the PaintLayer. | |
| 185 PaintLayer* layer = startObject->enclosingLayer(); | |
| 186 if (layer && !layer->needsCompositingInputsUpdate()) { | |
|
chrishtr
2016/01/30 01:49:02
The computations for position:sticky should be don
flackr
2016/02/03 22:48:38
Currently this is also called during styleChanged
| |
| 187 const PaintLayer* scrollAncestor = layer->ancestorScrollingLayer(); | |
| 188 if (!scrollAncestor) | |
| 189 return nullptr; | |
| 190 return toLayoutBox(scrollAncestor->layoutObject()); | |
| 191 } | |
| 192 | |
| 193 LayoutBox* curBox = startObject->containingBlock(); | |
| 194 // Scrolling propagates along the containing block chain. | |
| 195 // TODO(flackr): We could add scroll ancestor as an input to layout so that | |
|
chrishtr
2016/01/30 01:49:03
PaintLayer's scrollParent ancestor-dependent input
| |
| 196 // we don't have to walk up to find the scroll ancestor. | |
| 197 while (curBox && !curBox->isLayoutView()) { | |
| 198 if (curBox->hasOverflowClip()) | |
| 199 return curBox; | |
| 200 curBox = curBox->containingBlock(); | |
| 201 } | |
| 202 | |
| 203 return nullptr; | |
| 204 } | |
| 205 | |
| 180 void LayoutBoxModelObject::styleDidChange(StyleDifference diff, const ComputedSt yle* oldStyle) | 206 void LayoutBoxModelObject::styleDidChange(StyleDifference diff, const ComputedSt yle* oldStyle) |
| 181 { | 207 { |
| 182 bool hadTransform = hasTransformRelatedProperty(); | 208 bool hadTransform = hasTransformRelatedProperty(); |
| 183 bool hadLayer = hasLayer(); | 209 bool hadLayer = hasLayer(); |
| 184 bool layerWasSelfPainting = hadLayer && layer()->isSelfPaintingLayer(); | 210 bool layerWasSelfPainting = hadLayer && layer()->isSelfPaintingLayer(); |
| 185 bool wasFloatingBeforeStyleChanged = FloatStateForStyleChange::wasFloating(t his); | 211 bool wasFloatingBeforeStyleChanged = FloatStateForStyleChange::wasFloating(t his); |
| 186 | 212 |
| 187 LayoutObject::styleDidChange(diff, oldStyle); | 213 LayoutObject::styleDidChange(diff, oldStyle); |
| 188 updateFromStyle(); | 214 updateFromStyle(); |
| 189 | 215 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 260 bool newStoleBodyBackground = toLayoutBoxModelObject(bodyLayout)->ba ckgroundStolenForBeingBody(style()); | 286 bool newStoleBodyBackground = toLayoutBoxModelObject(bodyLayout)->ba ckgroundStolenForBeingBody(style()); |
| 261 bool oldStoleBodyBackground = oldStyle && toLayoutBoxModelObject(bod yLayout)->backgroundStolenForBeingBody(oldStyle); | 287 bool oldStoleBodyBackground = oldStyle && toLayoutBoxModelObject(bod yLayout)->backgroundStolenForBeingBody(oldStyle); |
| 262 if (newStoleBodyBackground != oldStoleBodyBackground | 288 if (newStoleBodyBackground != oldStoleBodyBackground |
| 263 && bodyLayout->style() && bodyLayout->style()->hasBackground()) { | 289 && bodyLayout->style() && bodyLayout->style()->hasBackground()) { |
| 264 bodyLayout->setShouldDoFullPaintInvalidation(); | 290 bodyLayout->setShouldDoFullPaintInvalidation(); |
| 265 } | 291 } |
| 266 } | 292 } |
| 267 } | 293 } |
| 268 | 294 |
| 269 if (FrameView *frameView = view()->frameView()) { | 295 if (FrameView *frameView = view()->frameView()) { |
| 270 bool newStyleIsViewportConstained = style()->hasViewportConstrainedPosit ion(); | 296 bool newStyleIsViewportConstained = style()->position() == FixedPosition ; |
| 271 bool oldStyleIsViewportConstrained = oldStyle && oldStyle->hasViewportCo nstrainedPosition(); | 297 bool oldStyleIsViewportConstrained = oldStyle && oldStyle->position() == FixedPosition; |
| 298 bool newStyleIsSticky = style()->position() == StickyPosition; | |
| 299 bool oldStyleIsSticky = oldStyle && oldStyle->position() == StickyPositi on; | |
| 300 | |
| 301 // Sticky positioned elements are only viewport constrained if they have no ancestor scroller. | |
| 302 if (newStyleIsSticky || oldStyleIsSticky) { | |
| 303 if (!findScrollAncestor(this)) { | |
| 304 newStyleIsViewportConstained |= newStyleIsSticky; | |
| 305 oldStyleIsViewportConstrained |= oldStyleIsSticky; | |
| 306 } | |
| 307 } | |
| 308 | |
| 272 if (newStyleIsViewportConstained != oldStyleIsViewportConstrained) { | 309 if (newStyleIsViewportConstained != oldStyleIsViewportConstrained) { |
| 273 if (newStyleIsViewportConstained && layer()) | 310 if (newStyleIsViewportConstained && layer()) |
| 274 frameView->addViewportConstrainedObject(this); | 311 frameView->addViewportConstrainedObject(this); |
| 275 else | 312 else |
| 276 frameView->removeViewportConstrainedObject(this); | 313 frameView->removeViewportConstrainedObject(this); |
| 277 } | 314 } |
| 315 | |
| 316 if (newStyleIsSticky != oldStyleIsSticky) { | |
| 317 if (newStyleIsSticky) | |
| 318 frameView->addStickyPositionObject(); | |
| 319 else | |
| 320 frameView->removeStickyPositionObject(); | |
| 321 } | |
| 278 } | 322 } |
| 279 } | 323 } |
| 280 | 324 |
| 281 void LayoutBoxModelObject::createLayer(PaintLayerType type) | 325 void LayoutBoxModelObject::createLayer(PaintLayerType type) |
| 282 { | 326 { |
| 283 // If the current paint invalidation container is not a stacking context and this object is | 327 // If the current paint invalidation container is not a stacking context and this object is |
| 284 // a or treated as a stacking context, creating this layer may cause this ob ject and its | 328 // a or treated as a stacking context, creating this layer may cause this ob ject and its |
| 285 // descendants to change paint invalidation container. Therefore we must eag erly invalidate | 329 // descendants to change paint invalidation container. Therefore we must eag erly invalidate |
| 286 // them on the original paint invalidation container before creating the lay er. | 330 // them on the original paint invalidation container before creating the lay er. |
| 287 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && isRooted() && style Ref().isTreatedAsOrStackingContext()) { | 331 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && isRooted() && style Ref().isTreatedAsOrStackingContext()) { |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 589 | 633 |
| 590 else if (!style()->bottom().isAuto() | 634 else if (!style()->bottom().isAuto() |
| 591 && (!containingBlock->hasAutoHeightOrContainingBlockWithAutoHeight() | 635 && (!containingBlock->hasAutoHeightOrContainingBlockWithAutoHeight() |
| 592 || !style()->bottom().hasPercent() | 636 || !style()->bottom().hasPercent() |
| 593 || containingBlock->stretchesToViewport())) | 637 || containingBlock->stretchesToViewport())) |
| 594 offset.expand(0, -valueForLength(style()->bottom(), containingBlock->ava ilableHeight())); | 638 offset.expand(0, -valueForLength(style()->bottom(), containingBlock->ava ilableHeight())); |
| 595 | 639 |
| 596 return offset; | 640 return offset; |
| 597 } | 641 } |
| 598 | 642 |
| 643 void LayoutBoxModelObject::computeStickyPositionConstraints(StickyPositionViewpo rtConstraints& constraints, const FloatRect& constrainingRect) const | |
| 644 { | |
| 645 FloatSize skippedContainersOffset; | |
| 646 LayoutBlock* containingBlock = this->containingBlock(); | |
| 647 // Skip anonymous containing blocks. | |
| 648 while (containingBlock->isAnonymous()) { | |
|
chrishtr
2016/01/30 01:49:02
Why exactly? Is there a test for this?
flackr
2016/02/03 22:48:38
I was matching firefox and safari on http://flackr
chrishtr
2016/02/23 16:31:51
And file a spec bug?
flackr
2016/03/07 19:07:33
Done: bug is here https://www.w3.org/Bugs/Public/s
| |
| 649 skippedContainersOffset += toFloatSize(FloatPoint(containingBlock->frame Rect().location())); | |
| 650 containingBlock = containingBlock->containingBlock(); | |
| 651 } | |
| 652 LayoutBox* scrollAncestor = findScrollAncestor(this); | |
| 653 | |
| 654 LayoutRect containerContentRect = containingBlock->contentBoxRect(); | |
| 655 LayoutUnit maxWidth = containingBlock->availableLogicalWidth(); | |
| 656 | |
| 657 // Sticky positioned element ignore any override logical width on the contai ning block (as they don't call | |
| 658 // containingBlockLogicalWidthForContent). It's unclear whether this is tota lly fine. | |
| 659 // Compute the container-relative area within which the sticky element is al lowed to move. | |
| 660 containerContentRect.contractEdges( | |
| 661 minimumValueForLength(style()->marginTop(), maxWidth), | |
| 662 minimumValueForLength(style()->marginRight(), maxWidth), | |
| 663 minimumValueForLength(style()->marginBottom(), maxWidth), | |
| 664 minimumValueForLength(style()->marginLeft(), maxWidth)); | |
| 665 | |
| 666 // Map to the scroll ancestor. | |
| 667 constraints.setAbsoluteContainingBlockRect(containingBlock->localToAncestorQ uad(FloatRect(containerContentRect), scrollAncestor).boundingBox()); | |
| 668 | |
| 669 FloatRect stickyBoxRect = isLayoutInline() | |
| 670 ? FloatRect(toLayoutInline(this)->linesBoundingBox()) | |
| 671 : FloatRect(toLayoutBox(this)->frameRect()); | |
| 672 FloatRect flippedStickyBoxRect = stickyBoxRect; | |
| 673 containingBlock->flipForWritingMode(flippedStickyBoxRect); | |
| 674 FloatPoint stickyLocation = flippedStickyBoxRect.location() + skippedContain ersOffset; | |
| 675 | |
| 676 // FIXME: sucks to call localToAbsolute again, but we can't just offset from the previously computed rect if there are transforms. | |
|
chrishtr
2016/01/30 01:49:02
s/localToAbsolute/localToAncestorQuad
flackr
2016/02/22 22:55:23
Done.
| |
| 677 // Map to the view to avoid including page scale factor. | |
| 678 FloatRect absContainerFrame = containingBlock->localToAncestorQuad(FloatRect (FloatPoint(), FloatSize(containingBlock->size())), scrollAncestor).boundingBox( ); | |
|
chrishtr
2016/01/30 01:49:02
s/absContainerFrame/stickyBoxRect/
flackr
2016/02/22 22:55:23
This is the container's frame rect which we add to
| |
| 679 | |
| 680 // If the containing block is our scroll ancestor, its location will not inc lude the scroll offset which we need to include as | |
| 681 // part of the sticky box rect so we include it here. | |
| 682 if (containingBlock->hasOverflowClip()) { | |
| 683 FloatSize scrollOffset(toFloatSize(containingBlock->layer()->scrollableA rea()->adjustedScrollOffset())); | |
| 684 stickyLocation -= scrollOffset; | |
| 685 } | |
| 686 | |
| 687 // We can't call localToAbsolute on |this| because that will recur. FIXME: F or now, assume that |this| is not transformed. | |
|
chrishtr
2016/01/30 01:49:02
What is this comment about again? Why a need to ma
flackr
2016/02/22 22:55:23
This actually seems unnecessary. If there is a tra
| |
| 688 constraints.setAbsoluteStickyBoxRect(FloatRect(absContainerFrame.location() + toFloatSize(stickyLocation), flippedStickyBoxRect.size())); | |
| 689 | |
| 690 LayoutUnit horizontalOffsets = minimumValueForLength(style()->right(), const rainingRect.width()) + | |
| 691 minimumValueForLength(style()->left(), constrainingRect.width()); | |
| 692 bool skipRight = false; | |
| 693 bool skipLeft = false; | |
| 694 if (!style()->left().isAuto() && !style()->right().isAuto()) { | |
|
chrishtr
2016/01/30 01:49:02
Document this code and what it's for.
flackr
2016/02/22 22:55:23
Done.
| |
| 695 if (horizontalOffsets > containerContentRect.width() | |
| 696 || horizontalOffsets + containerContentRect.width() > constrainingRe ct.width()) { | |
| 697 skipRight = style()->isLeftToRightDirection(); | |
| 698 skipLeft = !skipRight; | |
| 699 } | |
| 700 } | |
| 701 | |
| 702 if (!style()->left().isAuto() && !skipLeft) { | |
| 703 constraints.setLeftOffset(minimumValueForLength(style()->left(), constra iningRect.width())); | |
| 704 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeLeft); | |
| 705 } | |
| 706 | |
| 707 if (!style()->right().isAuto() && !skipRight) { | |
| 708 constraints.setRightOffset(minimumValueForLength(style()->right(), const rainingRect.width())); | |
| 709 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeRight); | |
| 710 } | |
| 711 | |
| 712 bool skipBottom = false; | |
| 713 // FIXME(ostap): Exclude top or bottom edge offset depending on the writing mode when related | |
|
chrishtr
2016/01/30 01:49:02
s/FIXME/TODO/ throughout, and replace names with f
flackr
2016/02/22 22:55:23
Done.
| |
| 714 // sections are fixed in spec: http://lists.w3.org/Archives/Public/www-style /2014May/0286.html | |
| 715 LayoutUnit verticalOffsets = minimumValueForLength(style()->top(), constrain ingRect.width()) + | |
| 716 minimumValueForLength(style()->bottom(), constrainingRect.width()); | |
| 717 if (!style()->top().isAuto() && !style()->bottom().isAuto()) { | |
| 718 if (verticalOffsets > containerContentRect.height() | |
| 719 || verticalOffsets + containerContentRect.height() > constrainingRec t.height()) { | |
| 720 skipBottom = true; | |
| 721 } | |
| 722 } | |
| 723 | |
| 724 if (!style()->top().isAuto()) { | |
| 725 constraints.setTopOffset(minimumValueForLength(style()->top(), constrain ingRect.height())); | |
| 726 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeTop); | |
| 727 } | |
| 728 | |
| 729 if (!style()->bottom().isAuto() && !skipBottom) { | |
| 730 constraints.setBottomOffset(minimumValueForLength(style()->bottom(), con strainingRect.height())); | |
| 731 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeBottom); | |
| 732 } | |
| 733 } | |
| 734 | |
| 735 FloatRect LayoutBoxModelObject::computeStickyConstrainingRect() const | |
| 736 { | |
| 737 FloatRect constrainingRect; | |
| 738 | |
| 739 ASSERT(hasLayer()); | |
| 740 LayoutBox* enclosingClippingBox = findScrollAncestor(this); | |
| 741 if (enclosingClippingBox) { | |
| 742 constrainingRect = FloatRect(enclosingClippingBox->overflowClipRect(Layo utPoint())); | |
| 743 constrainingRect.move(enclosingClippingBox->paddingLeft(), enclosingClip pingBox->paddingTop()); | |
| 744 constrainingRect.contract(FloatSize(enclosingClippingBox->paddingLeft() + enclosingClippingBox->paddingRight(), | |
| 745 enclosingClippingBox->paddingTop() + enclosingClippingBox->paddingBo ttom())); | |
| 746 } else { | |
| 747 constrainingRect = view()->frameView()->visibleContentRect(); | |
| 748 } | |
| 749 | |
| 750 return constrainingRect; | |
| 751 } | |
| 752 | |
| 753 LayoutSize LayoutBoxModelObject::stickyPositionOffset() const | |
| 754 { | |
| 755 FloatRect constrainingRect = computeStickyConstrainingRect(); | |
| 756 StickyPositionViewportConstraints constraints; | |
| 757 computeStickyPositionConstraints(constraints, constrainingRect); | |
| 758 | |
| 759 // The sticky offset is physical, so we can just return the delta computed i n absolute coords (though it may be wrong with transforms). | |
| 760 return LayoutSize(constraints.computeStickyOffset(constrainingRect)); | |
| 761 } | |
| 762 | |
| 599 LayoutPoint LayoutBoxModelObject::adjustedPositionRelativeToOffsetParent(const L ayoutPoint& startPoint) const | 763 LayoutPoint LayoutBoxModelObject::adjustedPositionRelativeToOffsetParent(const L ayoutPoint& startPoint) const |
| 600 { | 764 { |
| 601 // If the element is the HTML body element or doesn't have a parent | 765 // If the element is the HTML body element or doesn't have a parent |
| 602 // return 0 and stop this algorithm. | 766 // return 0 and stop this algorithm. |
| 603 if (isBody() || !parent()) | 767 if (isBody() || !parent()) |
| 604 return LayoutPoint(); | 768 return LayoutPoint(); |
| 605 | 769 |
| 606 LayoutPoint referencePoint = startPoint; | 770 LayoutPoint referencePoint = startPoint; |
| 607 referencePoint.move(parent()->columnOffset(referencePoint)); | 771 referencePoint.move(parent()->columnOffset(referencePoint)); |
| 608 | 772 |
| 609 // If the offsetParent of the element is null, or is the HTML body element, | 773 // If the offsetParent of the element is null, or is the HTML body element, |
| 610 // return the distance between the canvas origin and the left border edge | 774 // return the distance between the canvas origin and the left border edge |
| 611 // of the element and stop this algorithm. | 775 // of the element and stop this algorithm. |
| 612 Element* element = offsetParent(); | 776 Element* element = offsetParent(); |
| 613 if (!element) | 777 if (!element) |
| 614 return referencePoint; | 778 return referencePoint; |
| 615 | 779 |
| 616 if (const LayoutBoxModelObject* offsetParent = element->layoutBoxModelObject ()) { | 780 if (const LayoutBoxModelObject* offsetParent = element->layoutBoxModelObject ()) { |
| 617 if (offsetParent->isBox() && !offsetParent->isBody()) | 781 if (offsetParent->isBox() && !offsetParent->isBody()) |
| 618 referencePoint.move(-toLayoutBox(offsetParent)->borderLeft(), -toLay outBox(offsetParent)->borderTop()); | 782 referencePoint.move(-toLayoutBox(offsetParent)->borderLeft(), -toLay outBox(offsetParent)->borderTop()); |
| 619 if (!isOutOfFlowPositioned() || flowThreadContainingBlock()) { | 783 if (!isOutOfFlowPositioned() || flowThreadContainingBlock()) { |
| 620 if (isInFlowPositioned()) | 784 if (isInFlowPositioned()) |
| 621 referencePoint.move(relativePositionOffset()); | 785 referencePoint.move(offsetForInFlowPosition()); |
| 622 | 786 |
| 623 LayoutObject* current; | 787 LayoutObject* current; |
| 624 for (current = parent(); current != offsetParent && current->parent( ); current = current->parent()) { | 788 for (current = parent(); current != offsetParent && current->parent( ); current = current->parent()) { |
| 625 // FIXME: What are we supposed to do inside SVG content? | 789 // FIXME: What are we supposed to do inside SVG content? |
| 626 if (!isOutOfFlowPositioned()) { | 790 if (!isOutOfFlowPositioned()) { |
| 627 if (current->isBox() && !current->isTableRow()) | 791 if (current->isBox() && !current->isTableRow()) |
| 628 referencePoint.moveBy(toLayoutBox(current)->topLeftLocat ion()); | 792 referencePoint.moveBy(toLayoutBox(current)->topLeftLocat ion()); |
| 629 referencePoint.move(current->parent()->columnOffset(referenc ePoint)); | 793 referencePoint.move(current->parent()->columnOffset(referenc ePoint)); |
| 630 } | 794 } |
| 631 } | 795 } |
| 632 | 796 |
| 633 if (offsetParent->isBox() && offsetParent->isBody() && !offsetParent ->isPositioned()) | 797 if (offsetParent->isBox() && offsetParent->isBody() && !offsetParent ->isPositioned()) |
| 634 referencePoint.moveBy(toLayoutBox(offsetParent)->topLeftLocation ()); | 798 referencePoint.moveBy(toLayoutBox(offsetParent)->topLeftLocation ()); |
| 635 } | 799 } |
| 636 } | 800 } |
| 637 | 801 |
| 638 return referencePoint; | 802 return referencePoint; |
| 639 } | 803 } |
| 640 | 804 |
| 641 LayoutSize LayoutBoxModelObject::offsetForInFlowPosition() const | 805 LayoutSize LayoutBoxModelObject::offsetForInFlowPosition() const |
| 642 { | 806 { |
| 643 return isRelPositioned() ? relativePositionOffset() : LayoutSize(); | 807 if (isRelPositioned()) |
| 808 return relativePositionOffset(); | |
| 809 | |
| 810 if (isStickyPositioned()) | |
| 811 return stickyPositionOffset(); | |
| 812 | |
| 813 return LayoutSize(); | |
| 644 } | 814 } |
| 645 | 815 |
| 646 LayoutUnit LayoutBoxModelObject::offsetLeft() const | 816 LayoutUnit LayoutBoxModelObject::offsetLeft() const |
| 647 { | 817 { |
| 648 // Note that LayoutInline and LayoutBox override this to pass a different | 818 // Note that LayoutInline and LayoutBox override this to pass a different |
| 649 // startPoint to adjustedPositionRelativeToOffsetParent. | 819 // startPoint to adjustedPositionRelativeToOffsetParent. |
| 650 return adjustedPositionRelativeToOffsetParent(LayoutPoint()).x(); | 820 return adjustedPositionRelativeToOffsetParent(LayoutPoint()).x(); |
| 651 } | 821 } |
| 652 | 822 |
| 653 LayoutUnit LayoutBoxModelObject::offsetTop() const | 823 LayoutUnit LayoutBoxModelObject::offsetTop() const |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 956 const LayoutObject* LayoutBoxModelObject::pushMappingToContainer(const LayoutBox ModelObject* ancestorToStopAt, LayoutGeometryMap& geometryMap) const | 1126 const LayoutObject* LayoutBoxModelObject::pushMappingToContainer(const LayoutBox ModelObject* ancestorToStopAt, LayoutGeometryMap& geometryMap) const |
| 957 { | 1127 { |
| 958 ASSERT(ancestorToStopAt != this); | 1128 ASSERT(ancestorToStopAt != this); |
| 959 | 1129 |
| 960 bool ancestorSkipped; | 1130 bool ancestorSkipped; |
| 961 LayoutObject* container = this->container(ancestorToStopAt, &ancestorSkipped ); | 1131 LayoutObject* container = this->container(ancestorToStopAt, &ancestorSkipped ); |
| 962 if (!container) | 1132 if (!container) |
| 963 return nullptr; | 1133 return nullptr; |
| 964 | 1134 |
| 965 bool isInline = isLayoutInline(); | 1135 bool isInline = isLayoutInline(); |
| 966 bool isFixedPos = !isInline && style()->position() == FixedPosition; | 1136 bool isFixedPosition = !isInline && style()->position() == FixedPosition; |
| 967 bool hasTransform = !isInline && hasLayer() && layer()->transform(); | 1137 bool hasTransform = !isInline && hasLayer() && layer()->transform(); |
| 968 | 1138 |
| 969 LayoutSize adjustmentForSkippedAncestor; | 1139 LayoutSize adjustmentForSkippedAncestor; |
| 970 if (ancestorSkipped) { | 1140 if (ancestorSkipped) { |
| 971 // There can't be a transform between paintInvalidationContainer and anc estorToStopAt, because transforms create containers, so it should be safe | 1141 // There can't be a transform between paintInvalidationContainer and anc estorToStopAt, because transforms create containers, so it should be safe |
| 972 // to just subtract the delta between the ancestor and ancestorToStopAt. | 1142 // to just subtract the delta between the ancestor and ancestorToStopAt. |
| 973 adjustmentForSkippedAncestor = -ancestorToStopAt->offsetFromAncestorCont ainer(container); | 1143 adjustmentForSkippedAncestor = -ancestorToStopAt->offsetFromAncestorCont ainer(container); |
| 974 } | 1144 } |
| 975 | 1145 |
| 976 bool offsetDependsOnPoint = false; | 1146 bool offsetDependsOnPoint = false; |
| 977 LayoutSize containerOffset = offsetFromContainer(container, LayoutPoint(), & offsetDependsOnPoint); | 1147 LayoutSize containerOffset = offsetFromContainer(container, LayoutPoint(), & offsetDependsOnPoint); |
| 1148 LayoutSize stickyOffset; | |
| 1149 if (style()->position() == StickyPosition) | |
| 1150 stickyOffset = offsetForInFlowPosition(); | |
| 978 | 1151 |
| 979 bool preserve3D = container->style()->preserves3D() || style()->preserves3D( ); | 1152 bool preserve3D = container->style()->preserves3D() || style()->preserves3D( ); |
| 980 if (shouldUseTransformFromContainer(container)) { | 1153 if (shouldUseTransformFromContainer(container)) { |
| 981 TransformationMatrix t; | 1154 TransformationMatrix t; |
| 982 getTransformFromContainer(container, containerOffset, t); | 1155 getTransformFromContainer(container, containerOffset, t); |
| 983 t.translateRight(adjustmentForSkippedAncestor.width().toFloat(), adjustm entForSkippedAncestor.height().toFloat()); | 1156 t.translateRight(adjustmentForSkippedAncestor.width().toFloat(), adjustm entForSkippedAncestor.height().toFloat()); |
| 984 geometryMap.push(this, t, preserve3D, offsetDependsOnPoint, isFixedPos, hasTransform); | 1157 geometryMap.push(this, t, preserve3D, offsetDependsOnPoint, isFixedPosit ion, hasTransform, LayoutSize(), stickyOffset); |
| 985 } else { | 1158 } else { |
| 986 containerOffset += adjustmentForSkippedAncestor; | 1159 containerOffset += adjustmentForSkippedAncestor; |
| 987 geometryMap.push(this, containerOffset, preserve3D, offsetDependsOnPoint , isFixedPos, hasTransform); | 1160 geometryMap.push(this, containerOffset, preserve3D, offsetDependsOnPoint , isFixedPosition, hasTransform, LayoutSize(), stickyOffset); |
| 988 } | 1161 } |
| 989 | 1162 |
| 990 return ancestorSkipped ? ancestorToStopAt : container; | 1163 return ancestorSkipped ? ancestorToStopAt : container; |
| 991 } | 1164 } |
| 992 | 1165 |
| 993 void LayoutBoxModelObject::moveChildTo(LayoutBoxModelObject* toBoxModelObject, L ayoutObject* child, LayoutObject* beforeChild, bool fullRemoveInsert) | 1166 void LayoutBoxModelObject::moveChildTo(LayoutBoxModelObject* toBoxModelObject, L ayoutObject* child, LayoutObject* beforeChild, bool fullRemoveInsert) |
| 994 { | 1167 { |
| 995 // We assume that callers have cleared their positioned objects list for chi ld moves (!fullRemoveInsert) so the | 1168 // We assume that callers have cleared their positioned objects list for chi ld moves (!fullRemoveInsert) so the |
| 996 // positioned layoutObject maps don't become stale. It would be too slow to do the map lookup on each call. | 1169 // positioned layoutObject maps don't become stale. It would be too slow to do the map lookup on each call. |
| 997 ASSERT(!fullRemoveInsert || !isLayoutBlock() || !toLayoutBlock(this)->hasPos itionedObjects()); | 1170 ASSERT(!fullRemoveInsert || !isLayoutBlock() || !toLayoutBlock(this)->hasPos itionedObjects()); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1059 if (rootElementStyle->hasBackground()) | 1232 if (rootElementStyle->hasBackground()) |
| 1060 return false; | 1233 return false; |
| 1061 | 1234 |
| 1062 if (node() != document().firstBodyElement()) | 1235 if (node() != document().firstBodyElement()) |
| 1063 return false; | 1236 return false; |
| 1064 | 1237 |
| 1065 return true; | 1238 return true; |
| 1066 } | 1239 } |
| 1067 | 1240 |
| 1068 } // namespace blink | 1241 } // namespace blink |
| OLD | NEW |