bug 1368547 part 1 - Remove nsFrameManagerBase::mPlaceholderMap and store the placeholder on a frame property on the out-of-flow instead. r=jfkthame

MozReview-Commit-ID: 6AOxc2XgtO1
This commit is contained in:
Mats Palmgren 2017-05-31 21:29:49 +02:00
parent f03ef6fe25
commit 2cecf134ac
5 changed files with 13 additions and 55 deletions

View File

@ -46,34 +46,9 @@ using namespace mozilla::dom;
//----------------------------------------------------------------------
struct PlaceholderMapEntry : public PLDHashEntryHdr {
// key (the out of flow frame) can be obtained through placeholder frame
nsPlaceholderFrame *placeholderFrame;
};
static bool
PlaceholderMapMatchEntry(const PLDHashEntryHdr *hdr, const void *key)
{
const PlaceholderMapEntry *entry =
static_cast<const PlaceholderMapEntry*>(hdr);
NS_ASSERTION(entry->placeholderFrame->GetOutOfFlowFrame() !=
(void*)0xdddddddd,
"Dead placeholder in placeholder map");
return entry->placeholderFrame->GetOutOfFlowFrame() == key;
}
static const PLDHashTableOps PlaceholderMapOps = {
PLDHashTable::HashVoidPtrKeyStub,
PlaceholderMapMatchEntry,
PLDHashTable::MoveEntryStub,
PLDHashTable::ClearEntryStub,
nullptr
};
nsFrameManagerBase::nsFrameManagerBase()
: mPresShell(nullptr)
, mRootFrame(nullptr)
, mPlaceholderMap(&PlaceholderMapOps, sizeof(PlaceholderMapEntry))
, mUndisplayedMap(nullptr)
, mDisplayContentsMap(nullptr)
, mIsDestroyingFrames(false)
@ -164,47 +139,30 @@ nsFrameManager::Destroy()
nsPlaceholderFrame*
nsFrameManager::GetPlaceholderFrameFor(const nsIFrame* aFrame)
{
NS_PRECONDITION(aFrame, "null param unexpected");
auto entry = static_cast<PlaceholderMapEntry*>
(const_cast<PLDHashTable*>(&mPlaceholderMap)->Search(aFrame));
if (entry) {
return entry->placeholderFrame;
}
return nullptr;
MOZ_ASSERT(aFrame);
MOZ_ASSERT(aFrame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW));
return aFrame->GetProperty(nsIFrame::PlaceholderFrameProperty());
}
void
nsFrameManager::RegisterPlaceholderFrame(nsPlaceholderFrame* aPlaceholderFrame)
{
MOZ_ASSERT(aPlaceholderFrame, "null param unexpected");
MOZ_ASSERT(aPlaceholderFrame->IsPlaceholderFrame(), "unexpected frame type");
auto entry = static_cast<PlaceholderMapEntry*>
(mPlaceholderMap.Add(aPlaceholderFrame->GetOutOfFlowFrame()));
MOZ_ASSERT(!entry->placeholderFrame,
MOZ_ASSERT(aPlaceholderFrame);
MOZ_ASSERT(!GetPlaceholderFrameFor(aPlaceholderFrame->GetOutOfFlowFrame()),
"Registering a placeholder for a frame that already has a placeholder!");
entry->placeholderFrame = aPlaceholderFrame;
aPlaceholderFrame->GetOutOfFlowFrame()->SetProperty(nsIFrame::PlaceholderFrameProperty(), aPlaceholderFrame);
}
void
nsFrameManager::UnregisterPlaceholderFrame(nsPlaceholderFrame* aPlaceholderFrame)
{
NS_PRECONDITION(aPlaceholderFrame, "null param unexpected");
NS_PRECONDITION(aPlaceholderFrame->IsPlaceholderFrame(),
"unexpected frame type");
mPlaceholderMap.Remove(aPlaceholderFrame->GetOutOfFlowFrame());
MOZ_ASSERT(aPlaceholderFrame);
aPlaceholderFrame->GetOutOfFlowFrame()->DeleteProperty(nsIFrame::PlaceholderFrameProperty());
}
void
nsFrameManager::ClearPlaceholderFrameMap()
{
for (auto iter = mPlaceholderMap.Iter(); !iter.Done(); iter.Next()) {
auto entry = static_cast<PlaceholderMapEntry*>(iter.Get());
entry->placeholderFrame->SetOutOfFlowFrame(nullptr);
}
mPlaceholderMap.Clear();
}
//----------------------------------------------------------------------

View File

@ -51,7 +51,6 @@ protected:
// weak link, because the pres shell owns us
nsIPresShell* MOZ_NON_OWNING_REF mPresShell;
nsIFrame* mRootFrame;
PLDHashTable mPlaceholderMap;
UndisplayedMap* mUndisplayedMap;
UndisplayedMap* mDisplayContentsMap;
bool mIsDestroyingFrames; // The frame manager is destroying some frame(s).

View File

@ -735,7 +735,6 @@ nsFrame::DestroyFrom(nsIFrame* aDestructRoot)
"Placeholder relationship should have been torn down already; "
"this might mean we have a stray placeholder in the tree.");
if (placeholder) {
shell->FrameManager()->UnregisterPlaceholderFrame(placeholder);
placeholder->SetOutOfFlowFrame(nullptr);
}
}

View File

@ -83,6 +83,7 @@ class nsLineList_iterator;
class nsAbsoluteContainingBlock;
class nsIContent;
class nsContainerFrame;
class nsPlaceholderFrame;
class nsStyleChangeList;
struct nsPeekOffsetStruct;
@ -1186,6 +1187,8 @@ public:
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(BidiDataProperty, mozilla::FrameBidiData)
NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(PlaceholderFrameProperty, nsPlaceholderFrame)
mozilla::FrameBidiData GetBidiData() const
{
bool exists;

View File

@ -160,16 +160,15 @@ nsPlaceholderFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
nsIFrame* oof = mOutOfFlowFrame;
if (oof) {
// Unregister out-of-flow frame
nsFrameManager* fm = PresContext()->GetPresShell()->FrameManager();
fm->UnregisterPlaceholderFrame(this);
mOutOfFlowFrame = nullptr;
oof->DeleteProperty(nsIFrame::PlaceholderFrameProperty());
// If aDestructRoot is not an ancestor of the out-of-flow frame,
// then call RemoveFrame on it here.
// Also destroy it here if it's a popup frame. (Bug 96291)
if ((GetStateBits() & PLACEHOLDER_FOR_POPUP) ||
!nsLayoutUtils::IsProperAncestorFrame(aDestructRoot, oof)) {
ChildListID listId = nsLayoutUtils::GetChildListNameFor(oof);
nsFrameManager* fm = PresContext()->GetPresShell()->FrameManager();
fm->RemoveFrame(listId, oof);
}
// else oof will be destroyed by its parent