Bug 914891 - Bail gracefully on sticky positioning with no scroll container. r=dholbert

This commit is contained in:
Corey Ford 2013-09-11 16:30:56 -07:00
parent 6ddc39293a
commit edc42fda9e
6 changed files with 35 additions and 12 deletions

View File

@ -41,13 +41,17 @@ StickyScrollContainer::~StickyScrollContainer()
// static
StickyScrollContainer*
StickyScrollContainer::StickyScrollContainerForFrame(nsIFrame* aFrame)
StickyScrollContainer::GetStickyScrollContainerForFrame(nsIFrame* aFrame)
{
nsIScrollableFrame* scrollFrame =
nsLayoutUtils::GetNearestScrollableFrame(aFrame->GetParent(),
nsLayoutUtils::SCROLLABLE_SAME_DOC |
nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN);
NS_ASSERTION(scrollFrame, "Need a scrolling container");
if (!scrollFrame) {
// We might not find any, for instance in the case of
// <html style="position: fixed">
return nullptr;
}
FrameProperties props = static_cast<nsIFrame*>(do_QueryFrame(scrollFrame))->
Properties();
StickyScrollContainer* s = static_cast<StickyScrollContainer*>
@ -90,8 +94,7 @@ StickyScrollContainer::ComputeStickyOffsets(nsIFrame* aFrame)
nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN);
if (!scrollableFrame) {
// Not sure how this would happen, but bail if it does.
NS_ERROR("Couldn't find a scrollable frame");
// Bail.
return;
}

View File

@ -26,10 +26,10 @@ class StickyScrollContainer MOZ_FINAL : public nsIScrollPositionListener
{
public:
/**
* Find the StickyScrollContainer associated with the scroll container of
* the given frame, creating it if necessary.
* Find (and create if necessary) the StickyScrollContainer associated with
* the scroll container of the given frame, if a scroll container exists.
*/
static StickyScrollContainer* StickyScrollContainerForFrame(nsIFrame* aFrame);
static StickyScrollContainer* GetStickyScrollContainerForFrame(nsIFrame* aFrame);
/**
* Find the StickyScrollContainer associated with the given scroll frame,

View File

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html style="position: fixed;">
<head>
<meta charset="UTF-8">
</head>
<body>
<div style="position: sticky;"></div>
</body>
</html>

View File

@ -500,3 +500,4 @@ test-pref(layout.css.flexbox.enabled,true) load 866547-1.html
asserts(1-4) test-pref(layout.css.flexbox.enabled,true) load 876074-1.html # bug 876749
load 885009-1.html
load 893523.html
test-pref(layout.css.sticky.enabled,true) load 914891.html

View File

@ -512,7 +512,11 @@ nsFrame::Init(nsIContent* aContent,
mState |= NS_FRAME_MAY_BE_TRANSFORMED;
}
if (disp->mPosition == NS_STYLE_POSITION_STICKY) {
StickyScrollContainer::StickyScrollContainerForFrame(this)->AddFrame(this);
StickyScrollContainer* ssc =
StickyScrollContainer::GetStickyScrollContainerForFrame(this);
if (ssc) {
ssc->AddFrame(this);
}
}
if (nsLayoutUtils::FontSizeInflationEnabled(PresContext()) || !GetParent()
@ -593,8 +597,11 @@ nsFrame::DestroyFrom(nsIFrame* aDestructRoot)
nsSVGEffects::InvalidateDirectRenderingObservers(this);
if (StyleDisplay()->mPosition == NS_STYLE_POSITION_STICKY) {
StickyScrollContainer::StickyScrollContainerForFrame(this)->
RemoveFrame(this);
StickyScrollContainer* ssc =
StickyScrollContainer::GetStickyScrollContainerForFrame(this);
if (ssc) {
ssc->RemoveFrame(this);
}
}
// Get the view pointer now before the frame properties disappear

View File

@ -852,8 +852,11 @@ nsHTMLReflowState::ApplyRelativePositioning(nsIFrame* aFrame,
if (NS_STYLE_POSITION_RELATIVE == display->mPosition) {
*aPosition += nsPoint(aComputedOffsets.left, aComputedOffsets.top);
} else if (NS_STYLE_POSITION_STICKY == display->mPosition) {
*aPosition = StickyScrollContainer::StickyScrollContainerForFrame(aFrame)->
ComputePosition(aFrame);
StickyScrollContainer* ssc =
StickyScrollContainer::GetStickyScrollContainerForFrame(aFrame);
if (ssc) {
*aPosition = ssc->ComputePosition(aFrame);
}
}
}