Bug 1409166 - Check whether the target animating frame is scrolled out of each scrollable ancestor. r?mattwoodrow,birtles
Before this patch, we had been checking each scrollable ancestor is scrolled
out of its scrollable ancestor. So if the target animating frame is at the
bottom of its scrollable parent and if half of the scrollable parent is
scrolled out of its ancestor, the animating frame was considered as 'in-view'.
MozReview-Commit-ID: BDueuF3cT4I
--- a/dom/animation/test/chrome/test_restyles.html
+++ b/dom/animation/test/chrome/test_restyles.html
@@ -317,17 +317,20 @@ waitForAllPaints(function() {
return;
}
var grandParent = addDiv(null,
{ style: 'overflow-y: scroll; height: 20px;' });
var parentElement = addDiv(null,
{ style: 'overflow-y: scroll; height: 100px;' });
var div = addDiv(null,
- { style: 'animation: background-color 100s; position: relative; top: 100px;' });
+ { style: 'animation: background-color 100s; ' +
+ 'position: relative; ' +
+ 'top: 60px;' }); // This element is in-view in the parent, but
+ // out of view in the grandparent.
grandParent.appendChild(parentElement);
parentElement.appendChild(div);
var animation = div.getAnimations()[0];
await animation.ready;
var markers = await observeStyling(5);
is(markers.length, 0,
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -10773,32 +10773,33 @@ nsIFrame::GetPseudoElement(CSSPseudoElem
if (aType == CSSPseudoElementType::after) {
return nsLayoutUtils::GetAfterPseudo(mContent);
}
return nullptr;
}
static bool
-IsFrameScrolledOutOfView(nsIFrame *aFrame)
+IsFrameScrolledOutOfView(nsIFrame* aTarget,
+ const nsRect& aTargetRect,
+ nsIFrame* aParent)
{
nsIScrollableFrame* scrollableFrame =
- nsLayoutUtils::GetNearestScrollableFrame(aFrame,
+ nsLayoutUtils::GetNearestScrollableFrame(aParent,
nsLayoutUtils::SCROLLABLE_SAME_DOC |
nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN);
if (!scrollableFrame) {
return false;
}
nsIFrame *scrollableParent = do_QueryFrame(scrollableFrame);
- nsRect rect = aFrame->GetVisualOverflowRectRelativeToSelf();
nsRect transformedRect =
- nsLayoutUtils::TransformFrameRectToAncestor(aFrame,
- rect,
+ nsLayoutUtils::TransformFrameRectToAncestor(aTarget,
+ aTargetRect,
scrollableParent);
nsRect scrollableRect = scrollableParent->GetVisualOverflowRect();
if (transformedRect.IsEmpty()) {
// If the transformed rect is empty it represents a line or a point that we
// should check is outside the the scrollable rect.
if (transformedRect.x > scrollableRect.XMost() ||
transformedRect.y > scrollableRect.YMost() ||
@@ -10810,23 +10811,24 @@ IsFrameScrolledOutOfView(nsIFrame *aFram
return true;
}
nsIFrame* parent = scrollableParent->GetParent();
if (!parent) {
return false;
}
- return IsFrameScrolledOutOfView(parent);
+ return IsFrameScrolledOutOfView(aTarget, aTargetRect, parent);
}
bool
nsIFrame::IsScrolledOutOfView()
{
- return IsFrameScrolledOutOfView(this);
+ nsRect rect = GetVisualOverflowRectRelativeToSelf();
+ return IsFrameScrolledOutOfView(this, rect, this);
}
gfx::Matrix
nsIFrame::ComputeWidgetTransform()
{
const nsStyleUIReset* uiReset = StyleUIReset();
if (!uiReset->mSpecifiedWindowTransform) {
return gfx::Matrix();