diff --git a/mozilla/layout/base/nsFrameManager.cpp b/mozilla/layout/base/nsFrameManager.cpp index 9fff2ba5b01..3cef758a03b 100644 --- a/mozilla/layout/base/nsFrameManager.cpp +++ b/mozilla/layout/base/nsFrameManager.cpp @@ -72,10 +72,6 @@ #include "nsReadableUtils.h" #include "nsUnicharUtils.h" -#define NEW_CONTEXT_PARENTAGE_INVARIANT - -#ifdef NEW_CONTEXT_PARENTAGE_INVARIANT - #ifdef DEBUG #undef NOISY_DEBUG #else @@ -92,8 +88,6 @@ #define NOISY_TRACE_FRAME(_msg,_frame); #endif -#endif // NEW_CONTEXT_PARENTAGE_INVARIANT - // Class IID's static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); @@ -1254,7 +1248,28 @@ DumpContext(nsIFrame* aFrame, nsIStyleContext* aContext) } } -#ifdef NEW_CONTEXT_PARENTAGE_INVARIANT +static void +VerifySameTree(nsIStyleContext* aContext1, nsIStyleContext* aContext2) +{ + nsCOMPtr top1 = aContext1; + nsCOMPtr top2 = aContext2; + nsCOMPtr parent; + for (;;) { + parent = dont_AddRef(top1->GetParent()); + if (!parent) + break; + top1 = parent; + } + for (;;) { + parent = dont_AddRef(top2->GetParent()); + if (!parent) + break; + top2 = parent; + } + if (top1 != top2) + printf("Style contexts are not in the same style context tree.\n"); +} + static void VerifyContextParent(nsIPresContext* aPresContext, nsIFrame* aFrame, nsIStyleContext* aContext, nsIStyleContext* aParentContext) @@ -1310,6 +1325,7 @@ VerifyContextParent(nsIPresContext* aPresContext, nsIFrame* aFrame, DumpContext(nsnull, actualParentContext); fputs("should be using: ", stdout); DumpContext(nsnull, aParentContext); + VerifySameTree(actualParentContext, aParentContext); fputs("\n", stdout); } } @@ -1408,126 +1424,6 @@ FrameManager::DebugVerifyStyleTree(nsIPresContext* aPresContext, nsIFrame* aFram return NS_OK; } -#else // NEW_CONTEXT_PARENTAGE_INVARIANT - -static void -VerifyContextParent(nsIFrame* aFrame, nsIStyleContext* aContext, nsIStyleContext* aParentContext) -{ - nsIStyleContext* actualParentContext = aContext->GetParent(); - - if (aParentContext) { - if (aParentContext != actualParentContext) { - DumpContext(aFrame, aContext); - if (aContext == aParentContext) { - fputs("Using parent's style context\n\n", stdout); - } - else { - fputs("Wrong parent style context: ", stdout); - DumpContext(nsnull, actualParentContext); - fputs("should be using: ", stdout); - DumpContext(nsnull, aParentContext); - fputs("\n", stdout); - } - } - } - else { - if (actualParentContext) { - DumpContext(aFrame, aContext); - fputs("Has parent context: ", stdout); - DumpContext(nsnull, actualParentContext); - fputs("Should be null\n\n", stdout); - } - } - NS_IF_RELEASE(actualParentContext); -} - -static void -VerifyContextParent(nsIFrame* aFrame, nsIStyleContext* aParentContext) -{ - nsIStyleContext* context; - aFrame->GetStyleContext(&context); - VerifyContextParent(aFrame, context, aParentContext); - NS_RELEASE(context); -} - -static void -VerifyStyleTree(nsIPresContext* aPresContext, nsIFrame* aFrame, nsIStyleContext* aParentContext) -{ - nsIStyleContext* context; - aFrame->GetStyleContext(&context); - - VerifyContextParent(aFrame, aParentContext); - - PRInt32 listIndex = 0; - nsIAtom* childList = nsnull; - nsIFrame* child; - nsIAtom* frameType; - - do { - child = nsnull; - nsresult result = aFrame->FirstChild(aPresContext, childList, &child); - while ((NS_SUCCEEDED(result)) && child) { - nsFrameState state; - child->GetFrameState(&state); - if (NS_FRAME_OUT_OF_FLOW != (state & NS_FRAME_OUT_OF_FLOW)) { - // only do frames that are in flow - child->GetFrameType(&frameType); - if (nsLayoutAtoms::placeholderFrame == frameType) { // placeholder - // get out of flow frame and recurse there - nsIFrame* outOfFlowFrame = ((nsPlaceholderFrame*)child)->GetOutOfFlowFrame(); - NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame"); - - nsIStyleContext* outOfFlowContext; - outOfFlowFrame->GetStyleContext(&outOfFlowContext); - VerifyContextParent(child, outOfFlowContext); - NS_RELEASE(outOfFlowContext); - - VerifyStyleTree(aPresContext, outOfFlowFrame, context); - } - else { // regular frame - VerifyStyleTree(aPresContext, child, context); - } - NS_IF_RELEASE(frameType); - } - - child->GetNextSibling(&child); - } - - NS_IF_RELEASE(childList); - aFrame->GetAdditionalChildListName(listIndex++, &childList); - } while (childList); - - // do additional contexts - PRInt32 contextIndex = -1; - while (1 == 1) { - nsIStyleContext* extraContext = nsnull; - aFrame->GetAdditionalStyleContext(++contextIndex, &extraContext); - if (extraContext) { - VerifyContextParent(aFrame, extraContext, context); - NS_RELEASE(extraContext); - } - else { - break; - } - } - NS_RELEASE(context); -} - -NS_IMETHODIMP -FrameManager::DebugVerifyStyleTree(nsIPresContext* aPresContext, nsIFrame* aFrame) -{ - NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE); - if (aFrame) { - nsIStyleContext* context; - aFrame->GetStyleContext(&context); - nsIStyleContext* parentContext = context->GetParent(); - VerifyStyleTree(aPresContext, aFrame, parentContext); - NS_IF_RELEASE(parentContext); - NS_RELEASE(context); - } - return NS_OK; -} -#endif //NEW_CONTEXT_PARENTAGE_INVARIANT #endif // DEBUG NS_IMETHODIMP @@ -1670,7 +1566,6 @@ HasAttributeContent(nsIStyleContext* aStyleContext, } return result; } - static PRInt32 CaptureChange(nsIStyleContext* aOldContext, nsIStyleContext* aNewContext, @@ -1686,8 +1581,6 @@ CaptureChange(nsIStyleContext* aOldContext, nsIStyleContext* aNewContext, return aMinChange; } -#ifdef NEW_CONTEXT_PARENTAGE_INVARIANT - void FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext, nsIFrame* aFrame, @@ -1699,6 +1592,10 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext, PRInt32 aMinChange, PRInt32& aResultChange) { + // XXXldb get new context from prev-in-flow if possible, to avoid + // duplication. (Or should we just let |GetContext| handle that?) + // Getting the hint would be nice too, but that's harder. + nsIStyleContext* oldContext = nsnull; nsresult result = aFrame->GetStyleContext(&oldContext); if (NS_SUCCEEDED(result) && oldContext) { @@ -1964,227 +1861,6 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext, } } -#else // NEW_CONTEXT_PARENTAGE_INVARIANT - -void -FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext, - nsIFrame* aFrame, - nsIStyleContext* aParentContext, - nsIContent* aParentContent, - PRInt32 aAttrNameSpaceID, - nsIAtom* aAttribute, - nsStyleChangeList& aChangeList, - PRInt32 aMinChange, - PRInt32& aResultChange) -{ - nsIStyleContext* oldContext = nsnull; - nsresult result = aFrame->GetStyleContext(&oldContext); - if (NS_SUCCEEDED(result) && oldContext) { - nsIAtom* pseudoTag = nsnull; - oldContext->GetPseudoType(pseudoTag); - nsIContent* localContent = nsnull; - nsIContent* content = nsnull; - result = aFrame->GetContent(&localContent); - if (NS_SUCCEEDED(result) && localContent) { - content = localContent; - } - else { - content = aParentContent; - } - if (aParentContent && aAttribute) { // attribute came from parent, we don't care about it here when recursing - nsFrameState frameState; - aFrame->GetFrameState(&frameState); - if (0 == (frameState & NS_FRAME_GENERATED_CONTENT)) { // keep it for generated content - aAttribute = nsnull; - } - } - - // do primary context - nsIStyleContext* newContext = nsnull; - if (pseudoTag) { - aPresContext->ResolvePseudoStyleContextFor(aParentContent, pseudoTag, aParentContext, PR_FALSE, - &newContext); - NS_RELEASE(pseudoTag); - } - else { - NS_ASSERTION(localContent, "non pseudo-element frame without content node"); - if (content->IsContentOfType(nsIContent::eELEMENT)) { - aPresContext->ResolveStyleContextFor(content, aParentContext, - PR_TRUE, &newContext); - } else { - aPresContext->ResolveStyleContextForNonElement(aParentContext, - PR_TRUE, &newContext); - } - } - NS_ASSERTION(newContext, "failed to get new style context"); - if (newContext) { - if (newContext != oldContext) { - aMinChange = CaptureChange(oldContext, newContext, aFrame, content, aChangeList, aMinChange); - if (aMinChange < NS_STYLE_HINT_FRAMECHANGE) { // if frame gets regenerated, let it keep old context - aFrame->SetStyleContext(aPresContext, newContext); - } - // if old context had image and new context does not have the same image, - // stop the image load for the frame - nsStyleColor* oldColor; - nsStyleColor* newColor; - oldContext->GetStyle(eStyleStruct_Color, &oldColor); - newContext->GetStyle(eStyleStruct_Color, &newColor); - if(oldColor.mBackgroundImage.Length() > 0 && - oldColor.mBackgroundImage != newColor.mBackgroundImage ){ - // stop the image loading for the frame, the image has changed - aPresContext->StopImagesFor(aFrame); - } - } - else { - // XXXdwh figure this out. - // oldContext->RemapStyle(aPresContext, PR_FALSE); - if (aAttribute && (aMinChange < NS_STYLE_HINT_REFLOW) && - HasAttributeContent(oldContext, aAttrNameSpaceID, aAttribute)) { - aChangeList.AppendChange(aFrame, content, NS_STYLE_HINT_REFLOW); - } - } - NS_RELEASE(oldContext); - } - else { - NS_ERROR("resolve style context failed"); - newContext = oldContext; // new context failed, recover... (take ref) - } - - // do additional contexts - PRInt32 contextIndex = -1; - while (1 == 1) { - nsIStyleContext* oldExtraContext = nsnull; - result = aFrame->GetAdditionalStyleContext(++contextIndex, &oldExtraContext); - if (NS_SUCCEEDED(result)) { - if (oldExtraContext) { - nsIStyleContext* newExtraContext = nsnull; - oldExtraContext->GetPseudoType(pseudoTag); - NS_ASSERTION(pseudoTag, "extra style context is not pseudo element"); - result = aPresContext->ResolvePseudoStyleContextFor(content, pseudoTag, newContext, - PR_FALSE, &newExtraContext); - NS_RELEASE(pseudoTag); - if (NS_SUCCEEDED(result) && newExtraContext) { - if (oldExtraContext != newExtraContext) { - aMinChange = CaptureChange(oldExtraContext, newExtraContext, aFrame, - content, aChangeList, aMinChange); - if (aMinChange < NS_STYLE_HINT_FRAMECHANGE) { - aFrame->SetAdditionalStyleContext(contextIndex, newExtraContext); - } - } - else { - // XXXdwh figure this out. - // oldExtraContext->RemapStyle(aPresContext, PR_FALSE); - if (aAttribute && (aMinChange < NS_STYLE_HINT_REFLOW) && - HasAttributeContent(oldContext, aAttrNameSpaceID, aAttribute)) { - aChangeList.AppendChange(aFrame, content, NS_STYLE_HINT_REFLOW); - } - } - NS_RELEASE(newExtraContext); - } - NS_RELEASE(oldExtraContext); - } - } - else { - break; - } - } - - // now look for undisplayed child content and pseudos - if (localContent && mUndisplayedMap) { - UndisplayedNode* undisplayed = mUndisplayedMap->GetFirstNode(localContent); - while (undisplayed) { - nsIStyleContext* undisplayedContext = nsnull; - undisplayed->mStyle->GetPseudoType(pseudoTag); - if (undisplayed->mContent && pseudoTag == nsnull) { // child content - if (undisplayed->mContent->IsContentOfType(nsIContent::eELEMENT)) { - aPresContext->ResolveStyleContextFor(undisplayed->mContent, - newContext, - PR_TRUE, &undisplayedContext); - } else { - aPresContext->ResolveStyleContextForNonElement(newContext, - PR_TRUE, &undisplayedContext); - } - } - else { // pseudo element - NS_ASSERTION(pseudoTag, "pseudo element without tag"); - aPresContext->ResolvePseudoStyleContextFor(localContent, pseudoTag, - newContext, PR_FALSE, - &undisplayedContext); - } - NS_IF_RELEASE(pseudoTag); - if (undisplayedContext) { - if (undisplayedContext == undisplayed->mStyle) { - // XXXdwh figure this out. - // undisplayedContext->RemapStyle(aPresContext); - } - const nsStyleDisplay* display = - (const nsStyleDisplay*)undisplayedContext->GetStyleData(eStyleStruct_Display); - if (display->mDisplay != NS_STYLE_DISPLAY_NONE) { - aChangeList.AppendChange(nsnull, ((undisplayed->mContent) ? undisplayed->mContent : localContent), - NS_STYLE_HINT_FRAMECHANGE); - } - NS_RELEASE(undisplayedContext); - } - undisplayed = undisplayed->mNext; - } - } - - aResultChange = aMinChange; - - // now do children - PRInt32 listIndex = 0; - nsIAtom* childList = nsnull; - PRInt32 childChange; - nsIFrame* child; - - do { - child = nsnull; - result = aFrame->FirstChild(aPresContext, childList, &child); - while ((NS_SUCCEEDED(result)) && (child)) { - nsFrameState state; - child->GetFrameState(&state); - if (NS_FRAME_OUT_OF_FLOW != (state & NS_FRAME_OUT_OF_FLOW)) { - // only do frames that are in flow - nsCOMPtr frameType; - child->GetFrameType(getter_AddRefs(frameType)); - if (nsLayoutAtoms::placeholderFrame == frameType.get()) { // placeholder - // get out of flow frame and recurse there - nsIFrame* outOfFlowFrame = ((nsPlaceholderFrame*)child)->GetOutOfFlowFrame(); - NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame"); - - ReResolveStyleContext(aPresContext, outOfFlowFrame, newContext, content, - aAttrNameSpaceID, aAttribute, - aChangeList, aMinChange, childChange); - - // reresolve placeholder's context under out of flow frame - nsIStyleContext* outOfFlowContext; - outOfFlowFrame->GetStyleContext(&outOfFlowContext); - ReResolveStyleContext(aPresContext, child, outOfFlowContext, content, - kNameSpaceID_Unknown, nsnull, - aChangeList, aMinChange, childChange); - NS_RELEASE(outOfFlowContext); - } - else { // regular child frame - ReResolveStyleContext(aPresContext, child, newContext, content, - aAttrNameSpaceID, aAttribute, - aChangeList, aMinChange, childChange); - } - } - child->GetNextSibling(&child); - } - - NS_IF_RELEASE(childList); - aFrame->GetAdditionalChildListName(listIndex++, &childList); - } while (childList); - // XXX need to do overflow frames??? - - NS_RELEASE(newContext); - NS_IF_RELEASE(localContent); - } -} - -#endif // NEW_CONTEXT_PARENTAGE_INVARIANT - NS_IMETHODIMP FrameManager::ComputeStyleChangeFor(nsIPresContext* aPresContext, nsIFrame* aFrame, @@ -2198,6 +1874,14 @@ FrameManager::ComputeStyleChangeFor(nsIPresContext* aPresContext, aTopLevelChange = NS_STYLE_HINT_NONE; nsIFrame* frame = aFrame; +#ifdef DEBUG + { + nsIFrame* prevInFlow; + frame->GetPrevInFlow(&prevInFlow); + NS_ASSERTION(!prevInFlow, "must start with the first in flow"); + } +#endif + do { nsIStyleContext* styleContext = nsnull; frame->GetStyleContext(&styleContext); diff --git a/mozilla/layout/html/base/src/nsFrameManager.cpp b/mozilla/layout/html/base/src/nsFrameManager.cpp index 9fff2ba5b01..3cef758a03b 100644 --- a/mozilla/layout/html/base/src/nsFrameManager.cpp +++ b/mozilla/layout/html/base/src/nsFrameManager.cpp @@ -72,10 +72,6 @@ #include "nsReadableUtils.h" #include "nsUnicharUtils.h" -#define NEW_CONTEXT_PARENTAGE_INVARIANT - -#ifdef NEW_CONTEXT_PARENTAGE_INVARIANT - #ifdef DEBUG #undef NOISY_DEBUG #else @@ -92,8 +88,6 @@ #define NOISY_TRACE_FRAME(_msg,_frame); #endif -#endif // NEW_CONTEXT_PARENTAGE_INVARIANT - // Class IID's static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); @@ -1254,7 +1248,28 @@ DumpContext(nsIFrame* aFrame, nsIStyleContext* aContext) } } -#ifdef NEW_CONTEXT_PARENTAGE_INVARIANT +static void +VerifySameTree(nsIStyleContext* aContext1, nsIStyleContext* aContext2) +{ + nsCOMPtr top1 = aContext1; + nsCOMPtr top2 = aContext2; + nsCOMPtr parent; + for (;;) { + parent = dont_AddRef(top1->GetParent()); + if (!parent) + break; + top1 = parent; + } + for (;;) { + parent = dont_AddRef(top2->GetParent()); + if (!parent) + break; + top2 = parent; + } + if (top1 != top2) + printf("Style contexts are not in the same style context tree.\n"); +} + static void VerifyContextParent(nsIPresContext* aPresContext, nsIFrame* aFrame, nsIStyleContext* aContext, nsIStyleContext* aParentContext) @@ -1310,6 +1325,7 @@ VerifyContextParent(nsIPresContext* aPresContext, nsIFrame* aFrame, DumpContext(nsnull, actualParentContext); fputs("should be using: ", stdout); DumpContext(nsnull, aParentContext); + VerifySameTree(actualParentContext, aParentContext); fputs("\n", stdout); } } @@ -1408,126 +1424,6 @@ FrameManager::DebugVerifyStyleTree(nsIPresContext* aPresContext, nsIFrame* aFram return NS_OK; } -#else // NEW_CONTEXT_PARENTAGE_INVARIANT - -static void -VerifyContextParent(nsIFrame* aFrame, nsIStyleContext* aContext, nsIStyleContext* aParentContext) -{ - nsIStyleContext* actualParentContext = aContext->GetParent(); - - if (aParentContext) { - if (aParentContext != actualParentContext) { - DumpContext(aFrame, aContext); - if (aContext == aParentContext) { - fputs("Using parent's style context\n\n", stdout); - } - else { - fputs("Wrong parent style context: ", stdout); - DumpContext(nsnull, actualParentContext); - fputs("should be using: ", stdout); - DumpContext(nsnull, aParentContext); - fputs("\n", stdout); - } - } - } - else { - if (actualParentContext) { - DumpContext(aFrame, aContext); - fputs("Has parent context: ", stdout); - DumpContext(nsnull, actualParentContext); - fputs("Should be null\n\n", stdout); - } - } - NS_IF_RELEASE(actualParentContext); -} - -static void -VerifyContextParent(nsIFrame* aFrame, nsIStyleContext* aParentContext) -{ - nsIStyleContext* context; - aFrame->GetStyleContext(&context); - VerifyContextParent(aFrame, context, aParentContext); - NS_RELEASE(context); -} - -static void -VerifyStyleTree(nsIPresContext* aPresContext, nsIFrame* aFrame, nsIStyleContext* aParentContext) -{ - nsIStyleContext* context; - aFrame->GetStyleContext(&context); - - VerifyContextParent(aFrame, aParentContext); - - PRInt32 listIndex = 0; - nsIAtom* childList = nsnull; - nsIFrame* child; - nsIAtom* frameType; - - do { - child = nsnull; - nsresult result = aFrame->FirstChild(aPresContext, childList, &child); - while ((NS_SUCCEEDED(result)) && child) { - nsFrameState state; - child->GetFrameState(&state); - if (NS_FRAME_OUT_OF_FLOW != (state & NS_FRAME_OUT_OF_FLOW)) { - // only do frames that are in flow - child->GetFrameType(&frameType); - if (nsLayoutAtoms::placeholderFrame == frameType) { // placeholder - // get out of flow frame and recurse there - nsIFrame* outOfFlowFrame = ((nsPlaceholderFrame*)child)->GetOutOfFlowFrame(); - NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame"); - - nsIStyleContext* outOfFlowContext; - outOfFlowFrame->GetStyleContext(&outOfFlowContext); - VerifyContextParent(child, outOfFlowContext); - NS_RELEASE(outOfFlowContext); - - VerifyStyleTree(aPresContext, outOfFlowFrame, context); - } - else { // regular frame - VerifyStyleTree(aPresContext, child, context); - } - NS_IF_RELEASE(frameType); - } - - child->GetNextSibling(&child); - } - - NS_IF_RELEASE(childList); - aFrame->GetAdditionalChildListName(listIndex++, &childList); - } while (childList); - - // do additional contexts - PRInt32 contextIndex = -1; - while (1 == 1) { - nsIStyleContext* extraContext = nsnull; - aFrame->GetAdditionalStyleContext(++contextIndex, &extraContext); - if (extraContext) { - VerifyContextParent(aFrame, extraContext, context); - NS_RELEASE(extraContext); - } - else { - break; - } - } - NS_RELEASE(context); -} - -NS_IMETHODIMP -FrameManager::DebugVerifyStyleTree(nsIPresContext* aPresContext, nsIFrame* aFrame) -{ - NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE); - if (aFrame) { - nsIStyleContext* context; - aFrame->GetStyleContext(&context); - nsIStyleContext* parentContext = context->GetParent(); - VerifyStyleTree(aPresContext, aFrame, parentContext); - NS_IF_RELEASE(parentContext); - NS_RELEASE(context); - } - return NS_OK; -} -#endif //NEW_CONTEXT_PARENTAGE_INVARIANT #endif // DEBUG NS_IMETHODIMP @@ -1670,7 +1566,6 @@ HasAttributeContent(nsIStyleContext* aStyleContext, } return result; } - static PRInt32 CaptureChange(nsIStyleContext* aOldContext, nsIStyleContext* aNewContext, @@ -1686,8 +1581,6 @@ CaptureChange(nsIStyleContext* aOldContext, nsIStyleContext* aNewContext, return aMinChange; } -#ifdef NEW_CONTEXT_PARENTAGE_INVARIANT - void FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext, nsIFrame* aFrame, @@ -1699,6 +1592,10 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext, PRInt32 aMinChange, PRInt32& aResultChange) { + // XXXldb get new context from prev-in-flow if possible, to avoid + // duplication. (Or should we just let |GetContext| handle that?) + // Getting the hint would be nice too, but that's harder. + nsIStyleContext* oldContext = nsnull; nsresult result = aFrame->GetStyleContext(&oldContext); if (NS_SUCCEEDED(result) && oldContext) { @@ -1964,227 +1861,6 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext, } } -#else // NEW_CONTEXT_PARENTAGE_INVARIANT - -void -FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext, - nsIFrame* aFrame, - nsIStyleContext* aParentContext, - nsIContent* aParentContent, - PRInt32 aAttrNameSpaceID, - nsIAtom* aAttribute, - nsStyleChangeList& aChangeList, - PRInt32 aMinChange, - PRInt32& aResultChange) -{ - nsIStyleContext* oldContext = nsnull; - nsresult result = aFrame->GetStyleContext(&oldContext); - if (NS_SUCCEEDED(result) && oldContext) { - nsIAtom* pseudoTag = nsnull; - oldContext->GetPseudoType(pseudoTag); - nsIContent* localContent = nsnull; - nsIContent* content = nsnull; - result = aFrame->GetContent(&localContent); - if (NS_SUCCEEDED(result) && localContent) { - content = localContent; - } - else { - content = aParentContent; - } - if (aParentContent && aAttribute) { // attribute came from parent, we don't care about it here when recursing - nsFrameState frameState; - aFrame->GetFrameState(&frameState); - if (0 == (frameState & NS_FRAME_GENERATED_CONTENT)) { // keep it for generated content - aAttribute = nsnull; - } - } - - // do primary context - nsIStyleContext* newContext = nsnull; - if (pseudoTag) { - aPresContext->ResolvePseudoStyleContextFor(aParentContent, pseudoTag, aParentContext, PR_FALSE, - &newContext); - NS_RELEASE(pseudoTag); - } - else { - NS_ASSERTION(localContent, "non pseudo-element frame without content node"); - if (content->IsContentOfType(nsIContent::eELEMENT)) { - aPresContext->ResolveStyleContextFor(content, aParentContext, - PR_TRUE, &newContext); - } else { - aPresContext->ResolveStyleContextForNonElement(aParentContext, - PR_TRUE, &newContext); - } - } - NS_ASSERTION(newContext, "failed to get new style context"); - if (newContext) { - if (newContext != oldContext) { - aMinChange = CaptureChange(oldContext, newContext, aFrame, content, aChangeList, aMinChange); - if (aMinChange < NS_STYLE_HINT_FRAMECHANGE) { // if frame gets regenerated, let it keep old context - aFrame->SetStyleContext(aPresContext, newContext); - } - // if old context had image and new context does not have the same image, - // stop the image load for the frame - nsStyleColor* oldColor; - nsStyleColor* newColor; - oldContext->GetStyle(eStyleStruct_Color, &oldColor); - newContext->GetStyle(eStyleStruct_Color, &newColor); - if(oldColor.mBackgroundImage.Length() > 0 && - oldColor.mBackgroundImage != newColor.mBackgroundImage ){ - // stop the image loading for the frame, the image has changed - aPresContext->StopImagesFor(aFrame); - } - } - else { - // XXXdwh figure this out. - // oldContext->RemapStyle(aPresContext, PR_FALSE); - if (aAttribute && (aMinChange < NS_STYLE_HINT_REFLOW) && - HasAttributeContent(oldContext, aAttrNameSpaceID, aAttribute)) { - aChangeList.AppendChange(aFrame, content, NS_STYLE_HINT_REFLOW); - } - } - NS_RELEASE(oldContext); - } - else { - NS_ERROR("resolve style context failed"); - newContext = oldContext; // new context failed, recover... (take ref) - } - - // do additional contexts - PRInt32 contextIndex = -1; - while (1 == 1) { - nsIStyleContext* oldExtraContext = nsnull; - result = aFrame->GetAdditionalStyleContext(++contextIndex, &oldExtraContext); - if (NS_SUCCEEDED(result)) { - if (oldExtraContext) { - nsIStyleContext* newExtraContext = nsnull; - oldExtraContext->GetPseudoType(pseudoTag); - NS_ASSERTION(pseudoTag, "extra style context is not pseudo element"); - result = aPresContext->ResolvePseudoStyleContextFor(content, pseudoTag, newContext, - PR_FALSE, &newExtraContext); - NS_RELEASE(pseudoTag); - if (NS_SUCCEEDED(result) && newExtraContext) { - if (oldExtraContext != newExtraContext) { - aMinChange = CaptureChange(oldExtraContext, newExtraContext, aFrame, - content, aChangeList, aMinChange); - if (aMinChange < NS_STYLE_HINT_FRAMECHANGE) { - aFrame->SetAdditionalStyleContext(contextIndex, newExtraContext); - } - } - else { - // XXXdwh figure this out. - // oldExtraContext->RemapStyle(aPresContext, PR_FALSE); - if (aAttribute && (aMinChange < NS_STYLE_HINT_REFLOW) && - HasAttributeContent(oldContext, aAttrNameSpaceID, aAttribute)) { - aChangeList.AppendChange(aFrame, content, NS_STYLE_HINT_REFLOW); - } - } - NS_RELEASE(newExtraContext); - } - NS_RELEASE(oldExtraContext); - } - } - else { - break; - } - } - - // now look for undisplayed child content and pseudos - if (localContent && mUndisplayedMap) { - UndisplayedNode* undisplayed = mUndisplayedMap->GetFirstNode(localContent); - while (undisplayed) { - nsIStyleContext* undisplayedContext = nsnull; - undisplayed->mStyle->GetPseudoType(pseudoTag); - if (undisplayed->mContent && pseudoTag == nsnull) { // child content - if (undisplayed->mContent->IsContentOfType(nsIContent::eELEMENT)) { - aPresContext->ResolveStyleContextFor(undisplayed->mContent, - newContext, - PR_TRUE, &undisplayedContext); - } else { - aPresContext->ResolveStyleContextForNonElement(newContext, - PR_TRUE, &undisplayedContext); - } - } - else { // pseudo element - NS_ASSERTION(pseudoTag, "pseudo element without tag"); - aPresContext->ResolvePseudoStyleContextFor(localContent, pseudoTag, - newContext, PR_FALSE, - &undisplayedContext); - } - NS_IF_RELEASE(pseudoTag); - if (undisplayedContext) { - if (undisplayedContext == undisplayed->mStyle) { - // XXXdwh figure this out. - // undisplayedContext->RemapStyle(aPresContext); - } - const nsStyleDisplay* display = - (const nsStyleDisplay*)undisplayedContext->GetStyleData(eStyleStruct_Display); - if (display->mDisplay != NS_STYLE_DISPLAY_NONE) { - aChangeList.AppendChange(nsnull, ((undisplayed->mContent) ? undisplayed->mContent : localContent), - NS_STYLE_HINT_FRAMECHANGE); - } - NS_RELEASE(undisplayedContext); - } - undisplayed = undisplayed->mNext; - } - } - - aResultChange = aMinChange; - - // now do children - PRInt32 listIndex = 0; - nsIAtom* childList = nsnull; - PRInt32 childChange; - nsIFrame* child; - - do { - child = nsnull; - result = aFrame->FirstChild(aPresContext, childList, &child); - while ((NS_SUCCEEDED(result)) && (child)) { - nsFrameState state; - child->GetFrameState(&state); - if (NS_FRAME_OUT_OF_FLOW != (state & NS_FRAME_OUT_OF_FLOW)) { - // only do frames that are in flow - nsCOMPtr frameType; - child->GetFrameType(getter_AddRefs(frameType)); - if (nsLayoutAtoms::placeholderFrame == frameType.get()) { // placeholder - // get out of flow frame and recurse there - nsIFrame* outOfFlowFrame = ((nsPlaceholderFrame*)child)->GetOutOfFlowFrame(); - NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame"); - - ReResolveStyleContext(aPresContext, outOfFlowFrame, newContext, content, - aAttrNameSpaceID, aAttribute, - aChangeList, aMinChange, childChange); - - // reresolve placeholder's context under out of flow frame - nsIStyleContext* outOfFlowContext; - outOfFlowFrame->GetStyleContext(&outOfFlowContext); - ReResolveStyleContext(aPresContext, child, outOfFlowContext, content, - kNameSpaceID_Unknown, nsnull, - aChangeList, aMinChange, childChange); - NS_RELEASE(outOfFlowContext); - } - else { // regular child frame - ReResolveStyleContext(aPresContext, child, newContext, content, - aAttrNameSpaceID, aAttribute, - aChangeList, aMinChange, childChange); - } - } - child->GetNextSibling(&child); - } - - NS_IF_RELEASE(childList); - aFrame->GetAdditionalChildListName(listIndex++, &childList); - } while (childList); - // XXX need to do overflow frames??? - - NS_RELEASE(newContext); - NS_IF_RELEASE(localContent); - } -} - -#endif // NEW_CONTEXT_PARENTAGE_INVARIANT - NS_IMETHODIMP FrameManager::ComputeStyleChangeFor(nsIPresContext* aPresContext, nsIFrame* aFrame, @@ -2198,6 +1874,14 @@ FrameManager::ComputeStyleChangeFor(nsIPresContext* aPresContext, aTopLevelChange = NS_STYLE_HINT_NONE; nsIFrame* frame = aFrame; +#ifdef DEBUG + { + nsIFrame* prevInFlow; + frame->GetPrevInFlow(&prevInFlow); + NS_ASSERTION(!prevInFlow, "must start with the first in flow"); + } +#endif + do { nsIStyleContext* styleContext = nsnull; frame->GetStyleContext(&styleContext);