From 4f72a32cd98e3558e1f40d722bffb86295015e4d Mon Sep 17 00:00:00 2001 From: "dbaron%fas.harvard.edu" Date: Thu, 16 May 2002 13:30:57 +0000 Subject: [PATCH] Attempt to refix bug 118014 crash by removing SetUndisplayedPseudoIn and doing run-time checks that we're not inserting the same node into the undisplayed map twice. b=136704 r=attinasi sr=waterson git-svn-id: svn://10.0.0.236/trunk@121617 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/base/nsCSSFrameConstructor.cpp | 6 +- mozilla/layout/base/nsFrameManager.cpp | 58 ++++--------------- mozilla/layout/base/public/nsIFrameManager.h | 2 - .../layout/html/base/src/nsFrameManager.cpp | 58 ++++--------------- .../html/style/src/nsCSSFrameConstructor.cpp | 6 +- 5 files changed, 28 insertions(+), 102 deletions(-) diff --git a/mozilla/layout/base/nsCSSFrameConstructor.cpp b/mozilla/layout/base/nsCSSFrameConstructor.cpp index a35aa01d45c..8e388a6faf9 100644 --- a/mozilla/layout/base/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/base/nsCSSFrameConstructor.cpp @@ -1531,15 +1531,13 @@ nsCSSFrameConstructor::CreateGeneratedContentFrame(nsIPresShell* aPresShe // See whether the generated content should be displayed. display = (const nsStyleDisplay*)pseudoStyleContext->GetStyleData(eStyleStruct_Display); - if (NS_STYLE_DISPLAY_NONE == display->mDisplay) { - aState.mFrameManager->SetUndisplayedPseudoIn(pseudoStyleContext, aContent); - } - else { // has valid display type + if (NS_STYLE_DISPLAY_NONE != display->mDisplay) { // See if there was any content specified const nsStyleContent* styleContent = (const nsStyleContent*)pseudoStyleContext->GetStyleData(eStyleStruct_Content); PRUint32 contentCount = styleContent->ContentCount(); + // XXXldb What is contentCount for |content: ""|? if (contentCount > 0) { // Create a block box or an inline box depending on the value of // the 'display' property diff --git a/mozilla/layout/base/nsFrameManager.cpp b/mozilla/layout/base/nsFrameManager.cpp index c071089270d..6ea022bb9c1 100644 --- a/mozilla/layout/base/nsFrameManager.cpp +++ b/mozilla/layout/base/nsFrameManager.cpp @@ -202,14 +202,6 @@ public: NS_ADDREF(mStyle); mNext = nsnull; } - UndisplayedNode(nsIStyleContext* aPseudoStyle) - { - MOZ_COUNT_CTOR(UndisplayedNode); - mContent = nsnull; - mStyle = aPseudoStyle; - NS_ADDREF(mStyle); - mNext = nsnull; - } ~UndisplayedNode(void) { MOZ_COUNT_DTOR(UndisplayedNode); @@ -232,7 +224,6 @@ public: UndisplayedNode* GetFirstNode(nsIContent* aParentContent); nsresult AddNodeFor(nsIContent* aParentContent, nsIContent* aChild, nsIStyleContext* aStyle); - nsresult AddNodeFor(nsIContent* aParentContent, nsIStyleContext* aPseudoStyle); nsresult RemoveNodeFor(nsIContent* aParentContent, UndisplayedNode* aNode); nsresult RemoveNodesFor(nsIContent* aParentContent); @@ -301,8 +292,6 @@ public: // Undisplayed content functions NS_IMETHOD GetUndisplayedContent(nsIContent* aContent, nsIStyleContext** aStyleContext); NS_IMETHOD SetUndisplayedContent(nsIContent* aContent, nsIStyleContext* aStyleContext); - NS_IMETHOD SetUndisplayedPseudoIn(nsIStyleContext* aPseudoContext, - nsIContent* aParentContent); NS_IMETHOD ClearUndisplayedContentIn(nsIContent* aContent, nsIContent* aParentContent); NS_IMETHOD ClearAllUndisplayedContentIn(nsIContent* aParentContent); NS_IMETHOD ClearUndisplayedContentMap(); @@ -876,26 +865,6 @@ FrameManager::SetUndisplayedContent(nsIContent* aContent, return NS_ERROR_OUT_OF_MEMORY; } -NS_IMETHODIMP -FrameManager::SetUndisplayedPseudoIn(nsIStyleContext* aPseudoContext, - nsIContent* aParentContent) -{ - NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE); - -#ifdef DEBUG_UNDISPLAYED_MAP - static int i = 0; - printf("SetUndisplayedPseudo(%d): sp=%p cp=%p \n", i++, (void *)aPseudoContext, (void *)aParentContent); -#endif - - if (! mUndisplayedMap) { - mUndisplayedMap = new UndisplayedMap; - } - if (mUndisplayedMap) { - return mUndisplayedMap->AddNodeFor(aParentContent, aPseudoContext); - } - return NS_ERROR_OUT_OF_MEMORY; -} - NS_IMETHODIMP FrameManager::ClearUndisplayedContentIn(nsIContent* aContent, nsIContent* aParentContent) { @@ -1803,8 +1772,9 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext, while (undisplayed) { nsIStyleContext* undisplayedContext = nsnull; undisplayed->mStyle->GetPseudoType(pseudoTag); - if (undisplayed->mContent && pseudoTag == nsnull) { // child content - aPresContext->ResolveStyleContextFor(undisplayed->mContent, newContext, + if (pseudoTag == nsnull) { // child content + aPresContext->ResolveStyleContextFor(undisplayed->mContent, + newContext, &undisplayedContext); } else if (pseudoTag == nsHTMLAtoms::mozNonElementPseudo) { @@ -1812,6 +1782,7 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext, &undisplayedContext); } else { // pseudo element + NS_NOTREACHED("no pseudo elements in undisplayed map"); NS_ASSERTION(pseudoTag, "pseudo element without tag"); aPresContext->ResolvePseudoStyleContextFor(localContent, pseudoTag, newContext, @@ -2480,9 +2451,14 @@ UndisplayedMap::AppendNodeFor(UndisplayedNode* aNode, nsIContent* aParentContent if (*entry) { UndisplayedNode* node = (UndisplayedNode*)((*entry)->value); while (node->mNext) { - NS_ASSERTION((node->mContent != aNode->mContent) || - ((node->mContent == nsnull) && - (node->mStyle != aNode->mStyle)), "node in map twice"); + if (node->mContent == aNode->mContent) { + // We actually need to check this in optimized builds because + // there are some callers that do this. See bug 118014, bug + // 136704, etc. + NS_NOTREACHED("node in map twice"); + delete aNode; + return NS_OK; + } node = node->mNext; } node->mNext = aNode; @@ -2506,16 +2482,6 @@ UndisplayedMap::AddNodeFor(nsIContent* aParentContent, nsIContent* aChild, return AppendNodeFor(node, aParentContent); } -nsresult -UndisplayedMap::AddNodeFor(nsIContent* aParentContent, nsIStyleContext* aPseudoStyle) -{ - UndisplayedNode* node = new UndisplayedNode(aPseudoStyle); - if (! node) { - return NS_ERROR_OUT_OF_MEMORY; - } - return AppendNodeFor(node, aParentContent); -} - nsresult UndisplayedMap::RemoveNodeFor(nsIContent* aParentContent, UndisplayedNode* aNode) { diff --git a/mozilla/layout/base/public/nsIFrameManager.h b/mozilla/layout/base/public/nsIFrameManager.h index caee02f5652..0439bfcb468 100644 --- a/mozilla/layout/base/public/nsIFrameManager.h +++ b/mozilla/layout/base/public/nsIFrameManager.h @@ -123,8 +123,6 @@ public: // Mapping undisplayed content NS_IMETHOD GetUndisplayedContent(nsIContent* aContent, nsIStyleContext** aStyleContext)=0; NS_IMETHOD SetUndisplayedContent(nsIContent* aContent, nsIStyleContext* aStyleContext) = 0; - NS_IMETHOD SetUndisplayedPseudoIn(nsIStyleContext* aPseudoContext, - nsIContent* aParentContent) = 0; NS_IMETHOD ClearUndisplayedContentIn(nsIContent* aContent, nsIContent* aParentContent) = 0; NS_IMETHOD ClearAllUndisplayedContentIn(nsIContent* aParentContent) = 0; NS_IMETHOD ClearUndisplayedContentMap() = 0; diff --git a/mozilla/layout/html/base/src/nsFrameManager.cpp b/mozilla/layout/html/base/src/nsFrameManager.cpp index c071089270d..6ea022bb9c1 100644 --- a/mozilla/layout/html/base/src/nsFrameManager.cpp +++ b/mozilla/layout/html/base/src/nsFrameManager.cpp @@ -202,14 +202,6 @@ public: NS_ADDREF(mStyle); mNext = nsnull; } - UndisplayedNode(nsIStyleContext* aPseudoStyle) - { - MOZ_COUNT_CTOR(UndisplayedNode); - mContent = nsnull; - mStyle = aPseudoStyle; - NS_ADDREF(mStyle); - mNext = nsnull; - } ~UndisplayedNode(void) { MOZ_COUNT_DTOR(UndisplayedNode); @@ -232,7 +224,6 @@ public: UndisplayedNode* GetFirstNode(nsIContent* aParentContent); nsresult AddNodeFor(nsIContent* aParentContent, nsIContent* aChild, nsIStyleContext* aStyle); - nsresult AddNodeFor(nsIContent* aParentContent, nsIStyleContext* aPseudoStyle); nsresult RemoveNodeFor(nsIContent* aParentContent, UndisplayedNode* aNode); nsresult RemoveNodesFor(nsIContent* aParentContent); @@ -301,8 +292,6 @@ public: // Undisplayed content functions NS_IMETHOD GetUndisplayedContent(nsIContent* aContent, nsIStyleContext** aStyleContext); NS_IMETHOD SetUndisplayedContent(nsIContent* aContent, nsIStyleContext* aStyleContext); - NS_IMETHOD SetUndisplayedPseudoIn(nsIStyleContext* aPseudoContext, - nsIContent* aParentContent); NS_IMETHOD ClearUndisplayedContentIn(nsIContent* aContent, nsIContent* aParentContent); NS_IMETHOD ClearAllUndisplayedContentIn(nsIContent* aParentContent); NS_IMETHOD ClearUndisplayedContentMap(); @@ -876,26 +865,6 @@ FrameManager::SetUndisplayedContent(nsIContent* aContent, return NS_ERROR_OUT_OF_MEMORY; } -NS_IMETHODIMP -FrameManager::SetUndisplayedPseudoIn(nsIStyleContext* aPseudoContext, - nsIContent* aParentContent) -{ - NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE); - -#ifdef DEBUG_UNDISPLAYED_MAP - static int i = 0; - printf("SetUndisplayedPseudo(%d): sp=%p cp=%p \n", i++, (void *)aPseudoContext, (void *)aParentContent); -#endif - - if (! mUndisplayedMap) { - mUndisplayedMap = new UndisplayedMap; - } - if (mUndisplayedMap) { - return mUndisplayedMap->AddNodeFor(aParentContent, aPseudoContext); - } - return NS_ERROR_OUT_OF_MEMORY; -} - NS_IMETHODIMP FrameManager::ClearUndisplayedContentIn(nsIContent* aContent, nsIContent* aParentContent) { @@ -1803,8 +1772,9 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext, while (undisplayed) { nsIStyleContext* undisplayedContext = nsnull; undisplayed->mStyle->GetPseudoType(pseudoTag); - if (undisplayed->mContent && pseudoTag == nsnull) { // child content - aPresContext->ResolveStyleContextFor(undisplayed->mContent, newContext, + if (pseudoTag == nsnull) { // child content + aPresContext->ResolveStyleContextFor(undisplayed->mContent, + newContext, &undisplayedContext); } else if (pseudoTag == nsHTMLAtoms::mozNonElementPseudo) { @@ -1812,6 +1782,7 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext, &undisplayedContext); } else { // pseudo element + NS_NOTREACHED("no pseudo elements in undisplayed map"); NS_ASSERTION(pseudoTag, "pseudo element without tag"); aPresContext->ResolvePseudoStyleContextFor(localContent, pseudoTag, newContext, @@ -2480,9 +2451,14 @@ UndisplayedMap::AppendNodeFor(UndisplayedNode* aNode, nsIContent* aParentContent if (*entry) { UndisplayedNode* node = (UndisplayedNode*)((*entry)->value); while (node->mNext) { - NS_ASSERTION((node->mContent != aNode->mContent) || - ((node->mContent == nsnull) && - (node->mStyle != aNode->mStyle)), "node in map twice"); + if (node->mContent == aNode->mContent) { + // We actually need to check this in optimized builds because + // there are some callers that do this. See bug 118014, bug + // 136704, etc. + NS_NOTREACHED("node in map twice"); + delete aNode; + return NS_OK; + } node = node->mNext; } node->mNext = aNode; @@ -2506,16 +2482,6 @@ UndisplayedMap::AddNodeFor(nsIContent* aParentContent, nsIContent* aChild, return AppendNodeFor(node, aParentContent); } -nsresult -UndisplayedMap::AddNodeFor(nsIContent* aParentContent, nsIStyleContext* aPseudoStyle) -{ - UndisplayedNode* node = new UndisplayedNode(aPseudoStyle); - if (! node) { - return NS_ERROR_OUT_OF_MEMORY; - } - return AppendNodeFor(node, aParentContent); -} - nsresult UndisplayedMap::RemoveNodeFor(nsIContent* aParentContent, UndisplayedNode* aNode) { diff --git a/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp b/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp index a35aa01d45c..8e388a6faf9 100644 --- a/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp @@ -1531,15 +1531,13 @@ nsCSSFrameConstructor::CreateGeneratedContentFrame(nsIPresShell* aPresShe // See whether the generated content should be displayed. display = (const nsStyleDisplay*)pseudoStyleContext->GetStyleData(eStyleStruct_Display); - if (NS_STYLE_DISPLAY_NONE == display->mDisplay) { - aState.mFrameManager->SetUndisplayedPseudoIn(pseudoStyleContext, aContent); - } - else { // has valid display type + if (NS_STYLE_DISPLAY_NONE != display->mDisplay) { // See if there was any content specified const nsStyleContent* styleContent = (const nsStyleContent*)pseudoStyleContext->GetStyleData(eStyleStruct_Content); PRUint32 contentCount = styleContent->ContentCount(); + // XXXldb What is contentCount for |content: ""|? if (contentCount > 0) { // Create a block box or an inline box depending on the value of // the 'display' property