Remove obsolete NEW_CONTEXT_PARENTAGE_INVARIANT ifdefs, and add a few bits of debugging code. b=120888 sr=attinasi r=bzbarsky a=asa

git-svn-id: svn://10.0.0.236/trunk@116718 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
dbaron%fas.harvard.edu
2002-03-16 15:26:56 +00:00
parent c3a4b79934
commit d2693dd0ff
2 changed files with 70 additions and 702 deletions

View File

@@ -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<nsIStyleContext> top1 = aContext1;
nsCOMPtr<nsIStyleContext> top2 = aContext2;
nsCOMPtr<nsIStyleContext> 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<nsIAtom> 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);

View File

@@ -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<nsIStyleContext> top1 = aContext1;
nsCOMPtr<nsIStyleContext> top2 = aContext2;
nsCOMPtr<nsIStyleContext> 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<nsIAtom> 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);