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 // static
StickyScrollContainer* StickyScrollContainer*
StickyScrollContainer::StickyScrollContainerForFrame(nsIFrame* aFrame) StickyScrollContainer::GetStickyScrollContainerForFrame(nsIFrame* aFrame)
{ {
nsIScrollableFrame* scrollFrame = nsIScrollableFrame* scrollFrame =
nsLayoutUtils::GetNearestScrollableFrame(aFrame->GetParent(), nsLayoutUtils::GetNearestScrollableFrame(aFrame->GetParent(),
nsLayoutUtils::SCROLLABLE_SAME_DOC | nsLayoutUtils::SCROLLABLE_SAME_DOC |
nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN); 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))-> FrameProperties props = static_cast<nsIFrame*>(do_QueryFrame(scrollFrame))->
Properties(); Properties();
StickyScrollContainer* s = static_cast<StickyScrollContainer*> StickyScrollContainer* s = static_cast<StickyScrollContainer*>
@ -90,8 +94,7 @@ StickyScrollContainer::ComputeStickyOffsets(nsIFrame* aFrame)
nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN); nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN);
if (!scrollableFrame) { if (!scrollableFrame) {
// Not sure how this would happen, but bail if it does. // Bail.
NS_ERROR("Couldn't find a scrollable frame");
return; return;
} }

View File

@ -26,10 +26,10 @@ class StickyScrollContainer MOZ_FINAL : public nsIScrollPositionListener
{ {
public: public:
/** /**
* Find the StickyScrollContainer associated with the scroll container of * Find (and create if necessary) the StickyScrollContainer associated with
* the given frame, creating it if necessary. * 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, * 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 asserts(1-4) test-pref(layout.css.flexbox.enabled,true) load 876074-1.html # bug 876749
load 885009-1.html load 885009-1.html
load 893523.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; mState |= NS_FRAME_MAY_BE_TRANSFORMED;
} }
if (disp->mPosition == NS_STYLE_POSITION_STICKY) { 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() if (nsLayoutUtils::FontSizeInflationEnabled(PresContext()) || !GetParent()
@ -593,8 +597,11 @@ nsFrame::DestroyFrom(nsIFrame* aDestructRoot)
nsSVGEffects::InvalidateDirectRenderingObservers(this); nsSVGEffects::InvalidateDirectRenderingObservers(this);
if (StyleDisplay()->mPosition == NS_STYLE_POSITION_STICKY) { if (StyleDisplay()->mPosition == NS_STYLE_POSITION_STICKY) {
StickyScrollContainer::StickyScrollContainerForFrame(this)-> StickyScrollContainer* ssc =
RemoveFrame(this); StickyScrollContainer::GetStickyScrollContainerForFrame(this);
if (ssc) {
ssc->RemoveFrame(this);
}
} }
// Get the view pointer now before the frame properties disappear // 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) { if (NS_STYLE_POSITION_RELATIVE == display->mPosition) {
*aPosition += nsPoint(aComputedOffsets.left, aComputedOffsets.top); *aPosition += nsPoint(aComputedOffsets.left, aComputedOffsets.top);
} else if (NS_STYLE_POSITION_STICKY == display->mPosition) { } else if (NS_STYLE_POSITION_STICKY == display->mPosition) {
*aPosition = StickyScrollContainer::StickyScrollContainerForFrame(aFrame)-> StickyScrollContainer* ssc =
ComputePosition(aFrame); StickyScrollContainer::GetStickyScrollContainerForFrame(aFrame);
if (ssc) {
*aPosition = ssc->ComputePosition(aFrame);
}
} }
} }