diff --git a/mozilla/layout/base/nsCSSFrameConstructor.cpp b/mozilla/layout/base/nsCSSFrameConstructor.cpp index 131ef9fba68..e86f6f74853 100644 --- a/mozilla/layout/base/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/base/nsCSSFrameConstructor.cpp @@ -668,8 +668,7 @@ DoCleanupFrameReferences(nsPresContext* aPresContext, nsIFrame* frame = nsPlaceholderFrame::GetRealFrameFor(aFrameIn); // Remove the mapping from the content object to its frame - aFrameManager->SetPrimaryFrameFor(content, nsnull); - frame->RemovedAsPrimaryFrame(aPresContext); + aFrameManager->RemoveAsPrimaryFrame(content, frame); aFrameManager->ClearAllUndisplayedContentIn(content); // Recursively walk the child frames. @@ -9725,8 +9724,7 @@ DoDeletingFrameSubtree(nsPresContext* aPresContext, // Remove the mapping from the content object to its frame. nsIContent* content = aFrame->GetContent(); if (content) { - aFrameManager->SetPrimaryFrameFor(content, nsnull); - aFrame->RemovedAsPrimaryFrame(aPresContext); + aFrameManager->RemoveAsPrimaryFrame(content, aFrame); aFrameManager->ClearAllUndisplayedContentIn(content); } diff --git a/mozilla/layout/base/nsFrameManager.cpp b/mozilla/layout/base/nsFrameManager.cpp index 5ac5b94cb2f..cb7c41476fe 100644 --- a/mozilla/layout/base/nsFrameManager.cpp +++ b/mozilla/layout/base/nsFrameManager.cpp @@ -417,44 +417,56 @@ nsFrameManager::SetPrimaryFrameFor(nsIContent* aContent, nsIFrame* aPrimaryFrame) { NS_ENSURE_ARG_POINTER(aContent); - // it's ok if aPrimaryFrame is null + NS_ASSERTION(aPrimaryFrame && aPrimaryFrame->GetParent(), + "BOGUS!"); - // If aPrimaryFrame is NULL, then remove the mapping - if (!aPrimaryFrame) { - if (mPrimaryFrameMap.ops) { - PL_DHashTableOperate(&mPrimaryFrameMap, aContent, PL_DHASH_REMOVE); - } - } else { // This code should be used if/when we switch back to a 2-word entry // in the primary frame map. #if 0 - NS_PRECONDITION(aPrimaryFrame->GetContent() == aContent, "wrong content"); + NS_PRECONDITION(aPrimaryFrame->GetContent() == aContent, "wrong content"); #endif - // Create a new hashtable if necessary - if (!mPrimaryFrameMap.ops) { - if (!PL_DHashTableInit(&mPrimaryFrameMap, PL_DHashGetStubOps(), nsnull, - sizeof(PrimaryFrameMapEntry), 16)) { - mPrimaryFrameMap.ops = nsnull; - return NS_ERROR_OUT_OF_MEMORY; - } + // Create a new hashtable if necessary + if (!mPrimaryFrameMap.ops) { + if (!PL_DHashTableInit(&mPrimaryFrameMap, PL_DHashGetStubOps(), nsnull, + sizeof(PrimaryFrameMapEntry), 16)) { + mPrimaryFrameMap.ops = nsnull; + return NS_ERROR_OUT_OF_MEMORY; } - - // Add a mapping to the hash table - PrimaryFrameMapEntry *entry = NS_STATIC_CAST(PrimaryFrameMapEntry*, - PL_DHashTableOperate(&mPrimaryFrameMap, aContent, PL_DHASH_ADD)); -#ifdef DEBUG_dbaron - if (entry->frame) { - NS_WARNING("already have primary frame for content"); - } -#endif - entry->frame = aPrimaryFrame; - entry->content = aContent; } + + // Add a mapping to the hash table + PrimaryFrameMapEntry *entry = NS_STATIC_CAST(PrimaryFrameMapEntry*, + PL_DHashTableOperate(&mPrimaryFrameMap, aContent, PL_DHASH_ADD)); +#ifdef DEBUG_dbaron + if (entry->frame) { + NS_WARNING("already have primary frame for content"); + } +#endif + entry->frame = aPrimaryFrame; + entry->content = aContent; return NS_OK; } +void +nsFrameManager::RemoveAsPrimaryFrame(nsIContent* aContent, + nsIFrame* aPrimaryFrame) +{ + NS_PRECONDITION(aPrimaryFrame, "Must have a frame"); + if (aContent && mPrimaryFrameMap.ops) { + PrimaryFrameMapEntry *entry = NS_STATIC_CAST(PrimaryFrameMapEntry*, + PL_DHashTableOperate(&mPrimaryFrameMap, aContent, PL_DHASH_LOOKUP)); + if (PL_DHASH_ENTRY_IS_BUSY(entry) && entry->frame == aPrimaryFrame) { + // Don't use PL_DHashTableRawRemove, since we want the table to + // shrink as needed. + PL_DHashTableOperate(&mPrimaryFrameMap, aContent, PL_DHASH_REMOVE); + } + } + + aPrimaryFrame->RemovedAsPrimaryFrame(GetPresContext()); +} + void nsFrameManager::ClearPrimaryFrameMap() { diff --git a/mozilla/layout/base/nsFrameManager.h b/mozilla/layout/base/nsFrameManager.h index 1920e8b7733..da536912077 100644 --- a/mozilla/layout/base/nsFrameManager.h +++ b/mozilla/layout/base/nsFrameManager.h @@ -109,8 +109,16 @@ public: // Primary frame functions NS_HIDDEN_(nsIFrame*) GetPrimaryFrameFor(nsIContent* aContent); + // aPrimaryFrame must not be null. If you're trying to remove a primary frame + // mapping, use RemoveAsPrimaryFrame. NS_HIDDEN_(nsresult) SetPrimaryFrameFor(nsIContent* aContent, nsIFrame* aPrimaryFrame); + // If aPrimaryFrame is the current primary frame for aContent, remove the + // relevant hashtable entry. If the current primary frame for aContent is + // null, this does nothing. aPrimaryFrame must not be null, and this method + // handles calling RemovedAsPrimaryFrame on aPrimaryFrame. + NS_HIDDEN_(void) RemoveAsPrimaryFrame(nsIContent* aContent, + nsIFrame* aPrimaryFrame); NS_HIDDEN_(void) ClearPrimaryFrameMap(); // Placeholder frame functions diff --git a/mozilla/layout/generic/nsImageMap.cpp b/mozilla/layout/generic/nsImageMap.cpp index a85353270ce..9c8325bb484 100644 --- a/mozilla/layout/generic/nsImageMap.cpp +++ b/mozilla/layout/generic/nsImageMap.cpp @@ -762,7 +762,7 @@ nsImageMap::FreeAreas() PRInt32 i, n = mAreas.Count(); for (i = 0; i < n; i++) { Area* area = (Area*) mAreas.ElementAt(i); - frameManager->SetPrimaryFrameFor(area->mArea, nsnull); + frameManager->RemoveAsPrimaryFrame(area->mArea, mImageFrame); nsCOMPtr areaContent; area->GetArea(getter_AddRefs(areaContent));