Index: Source/core/rendering/RenderLayer.cpp |
diff --git a/Source/core/rendering/RenderLayer.cpp b/Source/core/rendering/RenderLayer.cpp |
index 96d3a7e4506632712e58b04af6d1e62fdd18eaf4..6801e4662ef9bb6cd009f21dfef130d74e575c9c 100644 |
--- a/Source/core/rendering/RenderLayer.cpp |
+++ b/Source/core/rendering/RenderLayer.cpp |
@@ -1812,6 +1812,19 @@ RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild) |
return oldChild; |
} |
+bool RenderLayer::hasAncestor(const RenderLayer* ancestor) const |
+{ |
+ if (!ancestor) |
+ return false; |
+ |
+ for (const RenderLayer* layer = this; layer; layer = layer->parent()) { |
+ if (layer == ancestor) |
+ return true; |
+ } |
+ |
+ return false; |
+} |
+ |
void RenderLayer::removeOnlyThisLayer() |
{ |
if (!m_parent) |
@@ -4895,10 +4908,11 @@ void RenderLayer::calculateClipRects(const ClipRectsContext& clipRectsContext, C |
ClipRectsType clipRectsType = clipRectsContext.clipRectsType; |
bool useCached = clipRectsType != TemporaryClipRects; |
+ bool isRoot = this == clipRectsContext.rootLayer; |
// For transformed layers, the root layer was shifted to be us, so there is no need to |
// examine the parent. We want to cache clip rects with us as the root. |
- RenderLayer* parentLayer = clipRectsContext.rootLayer != this ? parent() : 0; |
+ RenderLayer* parentLayer = isRoot ? 0 : parent(); |
// Ensure that our parent's clip has been calculated so that we can examine the values. |
if (parentLayer) { |
@@ -4907,6 +4921,8 @@ void RenderLayer::calculateClipRects(const ClipRectsContext& clipRectsContext, C |
else { |
ClipRectsContext parentContext(clipRectsContext); |
parentContext.overlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize; // FIXME: why? |
+ if (this == clipRectsContext.scrollParent) |
+ parentContext.scrollParent = 0; |
parentLayer->calculateClipRects(parentContext, clipRects); |
} |
} else |
@@ -4923,8 +4939,21 @@ void RenderLayer::calculateClipRects(const ClipRectsContext& clipRectsContext, C |
else if (renderer()->style()->position() == AbsolutePosition) |
clipRects.setOverflowClipRect(clipRects.posClipRect()); |
- // Update the clip rects that will be passed to child layers. |
- if ((renderer()->hasOverflowClip() && (clipRectsContext.respectOverflowClip == RespectOverflowClip || this != clipRectsContext.rootLayer)) || renderer()->hasClip()) { |
+ // Update the clip rects that will be passed to child layers. There are two reasons |
+ // we may ignor the cilp here. If we've been told to ignore the overflow clip (via |
+ // ClipRectsContext::respectOverflowClip), we do so, but only if this is the clip |
+ // root (this setting only applies to the root layer). Also, if a scroll parent is |
+ // set, we ignore all clips until we've reached it (the point of the scrollParent |
+ // member of ClipRectsContext is to determine the clip the scrollParent establishes |
+ // with respect to the clipRoot, regardless of any subsequent clipping that may happen |
+ // between us and our scroll parent). |
+ bool shouldIgnoreClip = clipRectsContext.scrollParent && this != clipRectsContext.scrollParent; |
+ bool shouldIgnoreOverflowClip = clipRectsContext.respectOverflowClip == IgnoreOverflowClip && isRoot; |
+ |
+ bool shouldApplyClip = renderer()->hasClip() && !shouldIgnoreClip; |
+ bool shouldApplyOverflowClip = renderer()->hasOverflowClip() && !shouldIgnoreOverflowClip && !shouldIgnoreClip; |
+ |
+ if (shouldApplyOverflowClip || shouldApplyClip) { |
// This layer establishes a clip of some kind. |
// This offset cannot use convertToLayerCoords, because sometimes our rootLayer may be across |
@@ -5438,6 +5467,29 @@ GraphicsLayer* RenderLayer::layerForScrolling() const |
return m_backing ? m_backing->scrollingContentsLayer() : 0; |
} |
+GraphicsLayer* RenderLayer::layerForScrollChild() const |
+{ |
+ // If we have an ancestor clipping layer because of our scroll parent, we do not want to |
+ // scroll that clip layer -- we need it to stay put and we will slide within it. If, on |
+ // the other hand, we have an ancestor clipping layer due to some other clipping layer, we |
+ // want to scroll the root of the layer's associate graphics layer subtree. I.e., we want it |
+ // and its clip to move in concert. |
+ |
+ if (!backing()) |
+ return 0; |
+ |
+ if (backing()->hasAncestorScrollClippingLayer()) { |
+ return backing()->hasAncestorClippingLayer() |
+ ? backing()->ancestorClippingLayer() |
+ : backing()->graphicsLayer(); |
+ } |
+ |
+ if (renderer()->containingBlock()->enclosingLayer() == ancestorScrollingLayer()) |
+ return backing()->graphicsLayer(); |
+ |
+ return backing()->childForSuperlayers(); |
+} |
+ |
GraphicsLayer* RenderLayer::layerForHorizontalScrollbar() const |
{ |
return m_backing ? m_backing->layerForHorizontalScrollbar() : 0; |