--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -172,16 +172,30 @@ nsInlineFrame::PeekOffsetCharacter(bool
// We're before the frame and moving forward, or after it and moving backwards:
// skip to the other side, but keep going.
*aOffset = 1 - startOffset;
}
return CONTINUE;
}
void
+nsInlineFrame::DestroyFrom(nsIFrame* aDestructRoot)
+{
+ nsFrameList* overflowFrames = GetOverflowFrames();
+ if (overflowFrames) {
+ // Fixup the parent pointers for any child frames on the OverflowList.
+ // nsIFrame::DestroyFrom depends on that to find the sticky scroll
+ // container (an ancestor).
+ nsIFrame* lineContainer = nsLayoutUtils::FindNearestBlockAncestor(this);
+ DrainSelfOverflowListInternal(eForDestroy, lineContainer);
+ }
+ nsContainerFrame::DestroyFrom(aDestructRoot);
+}
+
+void
nsInlineFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists)
{
BuildDisplayListForInline(aBuilder, aDirtyRect, aLists);
// The sole purpose of this is to trigger display of the selection
// window for Named Anchors, which don't have any children and
@@ -417,21 +431,22 @@ nsInlineFrame::DrainSelfOverflowListInte
// The frames on our own overflowlist may have been pushed by a
// previous lazilySetParentPointer Reflow so we need to ensure the
// correct parent pointer. This is sometimes skipped by Reflow.
if (!(aFlags & eDontReparentFrames)) {
nsIFrame* firstChild = overflowFrames->FirstChild();
if (aLineContainer && aLineContainer->GetPrevContinuation()) {
ReparentFloatsForInlineChild(aLineContainer, firstChild, true);
}
- const bool inFirstLine = (aFlags & eInFirstLine);
+ const bool doReparentSC =
+ (aFlags & eInFirstLine) && !(aFlags & eForDestroy);
RestyleManager* restyleManager = PresContext()->RestyleManager();
for (nsIFrame* f = firstChild; f; f = f->GetNextSibling()) {
f->SetParent(this);
- if (inFirstLine) {
+ if (doReparentSC) {
restyleManager->ReparentStyleContext(f);
nsLayoutUtils::MarkDescendantsDirty(f);
}
}
}
bool result = !overflowFrames->IsEmpty();
mFrames.AppendFrames(nullptr, *overflowFrames);
return result;
--- a/layout/generic/nsInlineFrame.h
+++ b/layout/generic/nsInlineFrame.h
@@ -58,16 +58,18 @@ public:
virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE;
virtual bool IsEmpty() MOZ_OVERRIDE;
virtual bool IsSelfEmpty() MOZ_OVERRIDE;
virtual FrameSearchResult PeekOffsetCharacter(bool aForward, int32_t* aOffset,
bool aRespectClusters = true) MOZ_OVERRIDE;
+ virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
+
// nsIHTMLReflow overrides
virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext,
InlineMinWidthData *aData) MOZ_OVERRIDE;
virtual void AddInlinePrefWidth(nsRenderingContext *aRenderingContext,
InlinePrefWidthData *aData) MOZ_OVERRIDE;
virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext,
nsSize aCBSize, nscoord aAvailableWidth,
nsSize aMargin, nsSize aBorder, nsSize aPadding,
@@ -160,16 +162,19 @@ protected:
InlineReflowState& aState);
private:
// Helper method for DrainSelfOverflowList() to deal with lazy parenting
// (which we only do for nsInlineFrame, not nsFirstLineFrame).
enum DrainFlags {
eDontReparentFrames = 1, // skip reparenting the overflow list frames
eInFirstLine = 2, // the request is for an inline descendant of a nsFirstLineFrame
+ eForDestroy = 4, // the request is from DestroyFrom; in this case we do the
+ // minimal work required since the frame is about to be
+ // destroyed (just fixup parent pointers)
};
/**
* Move any frames on our overflow list to the end of our principal list.
* @param aFlags one or more of the above DrainFlags
* @param aLineContainer the nearest line container ancestor
* @return true if there were any overflow frames
*/
bool DrainSelfOverflowListInternal(DrainFlags aFlags,