Make ReconstructDocElementHierarchy work correctly even if we first blew away a pseudo which had the root as its content. Bug 343293, r+sr=roc, a=dveditz

git-svn-id: svn://10.0.0.236/branches/MOZILLA_1_8_0_BRANCH@217178 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
bzbarsky%mit.edu
2006-12-19 04:42:12 +00:00
parent d70ccbda72
commit a85a7386ec
4 changed files with 49 additions and 31 deletions

View File

@@ -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);
}

View File

@@ -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()
{

View File

@@ -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

View File

@@ -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<nsIContent> areaContent;
area->GetArea(getter_AddRefs(areaContent));