103 lines
3.9 KiB
Diff
103 lines
3.9 KiB
Diff
From 2b1c90da3e849e1c9d7457658290aa8eb01d0fa9 Mon Sep 17 00:00:00 2001
|
|
From: Mats Palmgren <mats@mozilla.com>
|
|
Date: Thu, 16 Apr 2015 09:04:19 +0000
|
|
Subject: [PATCH] Bug 1153478 - Part 1: Add nsInlineFrame::StealFrame and make
|
|
it deal with being called on the wrong parent for aChild (due to lazy
|
|
reparenting). r=roc, a=sledru
|
|
|
|
---
|
|
layout/generic/nsContainerFrame.cpp | 7 +++----
|
|
layout/generic/nsInlineFrame.cpp | 39 +++++++++++++++++++++++++++++++++++++
|
|
layout/generic/nsInlineFrame.h | 4 +++-
|
|
3 files changed, 45 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp
|
|
index 3ffcba7..34878af 100644
|
|
--- a/layout/generic/nsContainerFrame.cpp
|
|
+++ b/layout/generic/nsContainerFrame.cpp
|
|
@@ -172,13 +172,12 @@ nsContainerFrame::RemoveFrame(ChildListID aListID,
|
|
nsIPresShell* shell = PresContext()->PresShell();
|
|
nsContainerFrame* lastParent = nullptr;
|
|
while (aOldFrame) {
|
|
- //XXXfr probably should use StealFrame here. I'm not sure if we need to
|
|
- // check the overflow lists atm, but we'll need a prescontext lookup
|
|
- // for overflow containers once we can split abspos elements with
|
|
- // inline containing blocks.
|
|
nsIFrame* oldFrameNextContinuation = aOldFrame->GetNextContinuation();
|
|
nsContainerFrame* parent =
|
|
static_cast<nsContainerFrame*>(aOldFrame->GetParent());
|
|
+ // Please note that 'parent' may not actually be where 'aOldFrame' lives.
|
|
+ // We really MUST use StealFrame() and nothing else here.
|
|
+ // @see nsInlineFrame::StealFrame for details.
|
|
parent->StealFrame(aOldFrame, true);
|
|
aOldFrame->Destroy();
|
|
aOldFrame = oldFrameNextContinuation;
|
|
diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp
|
|
index 526041e..a392a15 100644
|
|
--- a/layout/generic/nsInlineFrame.cpp
|
|
+++ b/layout/generic/nsInlineFrame.cpp
|
|
@@ -172,6 +172,45 @@ nsInlineFrame::PeekOffsetCharacter(bool aForward, int32_t* aOffset,
|
|
return CONTINUE;
|
|
}
|
|
|
|
+nsresult
|
|
+nsInlineFrame::StealFrame(nsIFrame* aChild,
|
|
+ bool aForceNormal)
|
|
+{
|
|
+ if (aChild->HasAnyStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER) &&
|
|
+ !aForceNormal) {
|
|
+ return nsContainerFrame::StealFrame(aChild, aForceNormal);
|
|
+ }
|
|
+
|
|
+ nsInlineFrame* parent = this;
|
|
+ bool removed = false;
|
|
+ do {
|
|
+ removed = parent->mFrames.StartRemoveFrame(aChild);
|
|
+ if (removed) {
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ // We didn't find the child in our principal child list.
|
|
+ // Maybe it's on the overflow list?
|
|
+ nsFrameList* frameList = parent->GetOverflowFrames();
|
|
+ if (frameList) {
|
|
+ removed = frameList->ContinueRemoveFrame(aChild);
|
|
+ if (frameList->IsEmpty()) {
|
|
+ parent->DestroyOverflowList();
|
|
+ }
|
|
+ if (removed) {
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // Due to our "lazy reparenting" optimization 'aChild' might not actually
|
|
+ // be on any of our child lists, but instead in one of our next-in-flows.
|
|
+ parent = static_cast<nsInlineFrame*>(parent->GetNextInFlow());
|
|
+ } while (parent);
|
|
+
|
|
+ MOZ_ASSERT(removed, "nsInlineFrame::StealFrame: can't find aChild");
|
|
+ return removed ? NS_OK : NS_ERROR_UNEXPECTED;
|
|
+}
|
|
+
|
|
void
|
|
nsInlineFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|
const nsRect& aDirtyRect,
|
|
diff --git a/layout/generic/nsInlineFrame.h b/layout/generic/nsInlineFrame.h
|
|
index 1a9899e..3e49241 100644
|
|
--- a/layout/generic/nsInlineFrame.h
|
|
+++ b/layout/generic/nsInlineFrame.h
|
|
@@ -61,7 +61,9 @@ public:
|
|
|
|
virtual FrameSearchResult PeekOffsetCharacter(bool aForward, int32_t* aOffset,
|
|
bool aRespectClusters = true) MOZ_OVERRIDE;
|
|
-
|
|
+
|
|
+ virtual nsresult StealFrame(nsIFrame* aChild, bool aForceNormal) MOZ_OVERRIDE;
|
|
+
|
|
// nsIHTMLReflow overrides
|
|
virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext,
|
|
InlineMinWidthData *aData) MOZ_OVERRIDE;
|
|
--
|
|
2.2.1
|
|
|