bug 23714 - don't resolve style for irrelevant whitespace. sr=waterson, r=rbs,hyatt

This commit is contained in:
karnaze%netscape.com 2001-03-21 05:10:40 +00:00
parent accd78ff55
commit c785e1439e
4 changed files with 66 additions and 68 deletions

View File

@ -3074,6 +3074,22 @@ nsCSSFrameConstructor::ConstructTableForeignFrame(nsIPresShell* aPres
return rv; return rv;
} }
PRBool
NeedFrameFor(nsIFrame* aParentFrame,
nsIContent* aChildContent)
{
// don't create a whitespace frame if aParentFrame doesn't want it
nsFrameState state;
aParentFrame->GetFrameState(&state);
if (NS_FRAME_EXCLUDE_IGNORABLE_WHITESPACE & state) {
if (IsOnlyWhiteSpace(aChildContent)) {
return PR_FALSE;
}
}
return PR_TRUE;
}
nsresult nsresult
nsCSSFrameConstructor::TableProcessChildren(nsIPresShell* aPresShell, nsCSSFrameConstructor::TableProcessChildren(nsIPresShell* aPresShell,
nsIPresContext* aPresContext, nsIPresContext* aPresContext,
@ -3102,7 +3118,7 @@ nsCSSFrameConstructor::TableProcessChildren(nsIPresShell* aPresShell,
while (iterator.HasMoreChildren()) { while (iterator.HasMoreChildren()) {
nsCOMPtr<nsIContent> childContent; nsCOMPtr<nsIContent> childContent;
iterator.NextChild(getter_AddRefs(childContent)); iterator.NextChild(getter_AddRefs(childContent));
if (childContent.get()) { if (childContent.get() && NeedFrameFor(aParentFrame, childContent.get())) {
rv = TableProcessChild(aPresShell, aPresContext, aState, *childContent.get(), aParentFrame, rv = TableProcessChild(aPresShell, aPresContext, aState, *childContent.get(), aParentFrame,
parentFrameType.get(), parentStyleContext.get(), parentFrameType.get(), parentStyleContext.get(),
aTableCreator, aChildItems, aCaption); aTableCreator, aChildItems, aCaption);
@ -4644,8 +4660,7 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresShell* aPresShell,
nsIAtom* aTag, nsIAtom* aTag,
PRInt32 aNameSpaceID, PRInt32 aNameSpaceID,
nsIStyleContext* aStyleContext, nsIStyleContext* aStyleContext,
nsFrameItems& aFrameItems, nsFrameItems& aFrameItems)
PRBool* aWhiteSpaceContent)
{ {
PRBool processChildren = PR_FALSE; // whether we should process child content PRBool processChildren = PR_FALSE; // whether we should process child content
PRBool isAbsolutelyPositioned = PR_FALSE; PRBool isAbsolutelyPositioned = PR_FALSE;
@ -4661,35 +4676,17 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresShell* aPresShell,
PRBool isPositionedContainingBlock = PR_FALSE; PRBool isPositionedContainingBlock = PR_FALSE;
nsresult rv = NS_OK; nsresult rv = NS_OK;
if (aWhiteSpaceContent) {
*aWhiteSpaceContent = PR_FALSE;
}
if (nsLayoutAtoms::textTagName == aTag) { if (nsLayoutAtoms::textTagName == aTag) {
PRBool isWhitespace = IsOnlyWhiteSpace(aContent); PRBool isWhitespace = IsOnlyWhiteSpace(aContent);
// process pending pseudo frames. whitespace doesn't have an effect. // process pending pseudo frames. whitespace doesn't have an effect.
if (!aState.mPseudoFrames.IsEmpty() && !isWhitespace) { if (!aState.mPseudoFrames.IsEmpty() && !isWhitespace) {
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems); ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
} }
// exclude whitespace from table and math elements in as efficient manner as possible rv = NS_NewTextFrame(aPresShell, &newFrame);
PRBool createFrame = PR_TRUE; // Text frames don't go in the content->frame hash table, because
if (isWhitespace) { // they're anonymous. This keeps the hash table smaller
nsFrameState state; addToHashTable = PR_FALSE;
aParentFrame->GetFrameState(&state); isReplaced = PR_TRUE; // XXX kipp: temporary
if (NS_FRAME_EXCLUDE_IGNORABLE_WHITESPACE & state) {
createFrame = PR_FALSE;
if (aWhiteSpaceContent) {
*aWhiteSpaceContent = PR_TRUE;
}
}
}
if (createFrame) {
rv = NS_NewTextFrame(aPresShell, &newFrame);
// Text frames don't go in the content->frame hash table, because
// they're anonymous. This keeps the hash table smaller
addToHashTable = PR_FALSE;
isReplaced = PR_TRUE; // XXX kipp: temporary
}
} }
else { else {
// Ignore the tag if it's not HTML content // Ignore the tag if it's not HTML content
@ -6093,7 +6090,7 @@ nsCSSFrameConstructor::BuildGfxScrollFrame (nsIPresShell* aPresShell,
} }
nsresult nsresult
nsCSSFrameConstructor::ConstructFrameByDisplayType(nsIPresShell* aPresShell, nsCSSFrameConstructor::ConstructFrameByDisplayType(nsIPresShell* aPresShell,
nsIPresContext* aPresContext, nsIPresContext* aPresContext,
nsFrameConstructorState& aState, nsFrameConstructorState& aState,
const nsStyleDisplay* aDisplay, const nsStyleDisplay* aDisplay,
@ -7050,7 +7047,12 @@ nsCSSFrameConstructor::ConstructFrame(nsIPresShell* aPresShell,
{ {
NS_PRECONDITION(nsnull != aParentFrame, "no parent frame"); NS_PRECONDITION(nsnull != aParentFrame, "no parent frame");
nsresult rv; nsresult rv = NS_OK;
// don't create a whitespace frame if aParent doesn't want it
if (!NeedFrameFor(aParentFrame, aContent)) {
return rv;
}
// Get the element's tag // Get the element's tag
nsCOMPtr<nsIAtom> tag; nsCOMPtr<nsIAtom> tag;
@ -7161,9 +7163,8 @@ nsCSSFrameConstructor::ConstructFrameInternal( nsIPresShell* aPresShe
nsIFrame* lastChild = aFrameItems.lastChild; nsIFrame* lastChild = aFrameItems.lastChild;
// Handle specific frame types // Handle specific frame types
PRBool whiteSpaceContent = PR_FALSE;
nsresult rv = ConstructFrameByTag(aPresShell, aPresContext, aState, aContent, aParentFrame, nsresult rv = ConstructFrameByTag(aPresShell, aPresContext, aState, aContent, aParentFrame,
aTag, aNameSpaceID, styleContext, aFrameItems, &whiteSpaceContent); aTag, aNameSpaceID, styleContext, aFrameItems);
#ifdef INCLUDE_XUL #ifdef INCLUDE_XUL
// Failing to find a matching HTML frame, try creating a specialized // Failing to find a matching HTML frame, try creating a specialized
@ -7198,8 +7199,7 @@ nsCSSFrameConstructor::ConstructFrameInternal( nsIPresShell* aPresShe
} }
#endif #endif
if (NS_SUCCEEDED(rv) && !whiteSpaceContent && if (NS_SUCCEEDED(rv) && ((nsnull == aFrameItems.childList) ||
((nsnull == aFrameItems.childList) ||
(lastChild == aFrameItems.lastChild))) { (lastChild == aFrameItems.lastChild))) {
// When there is no explicit frame to create, assume it's a // When there is no explicit frame to create, assume it's a
// container and let display style dictate the rest // container and let display style dictate the rest

View File

@ -496,8 +496,7 @@ protected:
nsIAtom* aTag, nsIAtom* aTag,
PRInt32 aNameSpaceID, PRInt32 aNameSpaceID,
nsIStyleContext* aStyleContext, nsIStyleContext* aStyleContext,
nsFrameItems& aFrameItems, nsFrameItems& aFrameItems);
PRBool* aWhiteSpaceContent = nsnull);
nsresult ConstructFrameInternal( nsIPresShell* aPresShell, nsresult ConstructFrameInternal( nsIPresShell* aPresShell,
nsIPresContext* aPresContext, nsIPresContext* aPresContext,

View File

@ -3074,6 +3074,22 @@ nsCSSFrameConstructor::ConstructTableForeignFrame(nsIPresShell* aPres
return rv; return rv;
} }
PRBool
NeedFrameFor(nsIFrame* aParentFrame,
nsIContent* aChildContent)
{
// don't create a whitespace frame if aParentFrame doesn't want it
nsFrameState state;
aParentFrame->GetFrameState(&state);
if (NS_FRAME_EXCLUDE_IGNORABLE_WHITESPACE & state) {
if (IsOnlyWhiteSpace(aChildContent)) {
return PR_FALSE;
}
}
return PR_TRUE;
}
nsresult nsresult
nsCSSFrameConstructor::TableProcessChildren(nsIPresShell* aPresShell, nsCSSFrameConstructor::TableProcessChildren(nsIPresShell* aPresShell,
nsIPresContext* aPresContext, nsIPresContext* aPresContext,
@ -3102,7 +3118,7 @@ nsCSSFrameConstructor::TableProcessChildren(nsIPresShell* aPresShell,
while (iterator.HasMoreChildren()) { while (iterator.HasMoreChildren()) {
nsCOMPtr<nsIContent> childContent; nsCOMPtr<nsIContent> childContent;
iterator.NextChild(getter_AddRefs(childContent)); iterator.NextChild(getter_AddRefs(childContent));
if (childContent.get()) { if (childContent.get() && NeedFrameFor(aParentFrame, childContent.get())) {
rv = TableProcessChild(aPresShell, aPresContext, aState, *childContent.get(), aParentFrame, rv = TableProcessChild(aPresShell, aPresContext, aState, *childContent.get(), aParentFrame,
parentFrameType.get(), parentStyleContext.get(), parentFrameType.get(), parentStyleContext.get(),
aTableCreator, aChildItems, aCaption); aTableCreator, aChildItems, aCaption);
@ -4644,8 +4660,7 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresShell* aPresShell,
nsIAtom* aTag, nsIAtom* aTag,
PRInt32 aNameSpaceID, PRInt32 aNameSpaceID,
nsIStyleContext* aStyleContext, nsIStyleContext* aStyleContext,
nsFrameItems& aFrameItems, nsFrameItems& aFrameItems)
PRBool* aWhiteSpaceContent)
{ {
PRBool processChildren = PR_FALSE; // whether we should process child content PRBool processChildren = PR_FALSE; // whether we should process child content
PRBool isAbsolutelyPositioned = PR_FALSE; PRBool isAbsolutelyPositioned = PR_FALSE;
@ -4661,35 +4676,17 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresShell* aPresShell,
PRBool isPositionedContainingBlock = PR_FALSE; PRBool isPositionedContainingBlock = PR_FALSE;
nsresult rv = NS_OK; nsresult rv = NS_OK;
if (aWhiteSpaceContent) {
*aWhiteSpaceContent = PR_FALSE;
}
if (nsLayoutAtoms::textTagName == aTag) { if (nsLayoutAtoms::textTagName == aTag) {
PRBool isWhitespace = IsOnlyWhiteSpace(aContent); PRBool isWhitespace = IsOnlyWhiteSpace(aContent);
// process pending pseudo frames. whitespace doesn't have an effect. // process pending pseudo frames. whitespace doesn't have an effect.
if (!aState.mPseudoFrames.IsEmpty() && !isWhitespace) { if (!aState.mPseudoFrames.IsEmpty() && !isWhitespace) {
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems); ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
} }
// exclude whitespace from table and math elements in as efficient manner as possible rv = NS_NewTextFrame(aPresShell, &newFrame);
PRBool createFrame = PR_TRUE; // Text frames don't go in the content->frame hash table, because
if (isWhitespace) { // they're anonymous. This keeps the hash table smaller
nsFrameState state; addToHashTable = PR_FALSE;
aParentFrame->GetFrameState(&state); isReplaced = PR_TRUE; // XXX kipp: temporary
if (NS_FRAME_EXCLUDE_IGNORABLE_WHITESPACE & state) {
createFrame = PR_FALSE;
if (aWhiteSpaceContent) {
*aWhiteSpaceContent = PR_TRUE;
}
}
}
if (createFrame) {
rv = NS_NewTextFrame(aPresShell, &newFrame);
// Text frames don't go in the content->frame hash table, because
// they're anonymous. This keeps the hash table smaller
addToHashTable = PR_FALSE;
isReplaced = PR_TRUE; // XXX kipp: temporary
}
} }
else { else {
// Ignore the tag if it's not HTML content // Ignore the tag if it's not HTML content
@ -6093,7 +6090,7 @@ nsCSSFrameConstructor::BuildGfxScrollFrame (nsIPresShell* aPresShell,
} }
nsresult nsresult
nsCSSFrameConstructor::ConstructFrameByDisplayType(nsIPresShell* aPresShell, nsCSSFrameConstructor::ConstructFrameByDisplayType(nsIPresShell* aPresShell,
nsIPresContext* aPresContext, nsIPresContext* aPresContext,
nsFrameConstructorState& aState, nsFrameConstructorState& aState,
const nsStyleDisplay* aDisplay, const nsStyleDisplay* aDisplay,
@ -7050,7 +7047,12 @@ nsCSSFrameConstructor::ConstructFrame(nsIPresShell* aPresShell,
{ {
NS_PRECONDITION(nsnull != aParentFrame, "no parent frame"); NS_PRECONDITION(nsnull != aParentFrame, "no parent frame");
nsresult rv; nsresult rv = NS_OK;
// don't create a whitespace frame if aParent doesn't want it
if (!NeedFrameFor(aParentFrame, aContent)) {
return rv;
}
// Get the element's tag // Get the element's tag
nsCOMPtr<nsIAtom> tag; nsCOMPtr<nsIAtom> tag;
@ -7161,9 +7163,8 @@ nsCSSFrameConstructor::ConstructFrameInternal( nsIPresShell* aPresShe
nsIFrame* lastChild = aFrameItems.lastChild; nsIFrame* lastChild = aFrameItems.lastChild;
// Handle specific frame types // Handle specific frame types
PRBool whiteSpaceContent = PR_FALSE;
nsresult rv = ConstructFrameByTag(aPresShell, aPresContext, aState, aContent, aParentFrame, nsresult rv = ConstructFrameByTag(aPresShell, aPresContext, aState, aContent, aParentFrame,
aTag, aNameSpaceID, styleContext, aFrameItems, &whiteSpaceContent); aTag, aNameSpaceID, styleContext, aFrameItems);
#ifdef INCLUDE_XUL #ifdef INCLUDE_XUL
// Failing to find a matching HTML frame, try creating a specialized // Failing to find a matching HTML frame, try creating a specialized
@ -7198,8 +7199,7 @@ nsCSSFrameConstructor::ConstructFrameInternal( nsIPresShell* aPresShe
} }
#endif #endif
if (NS_SUCCEEDED(rv) && !whiteSpaceContent && if (NS_SUCCEEDED(rv) && ((nsnull == aFrameItems.childList) ||
((nsnull == aFrameItems.childList) ||
(lastChild == aFrameItems.lastChild))) { (lastChild == aFrameItems.lastChild))) {
// When there is no explicit frame to create, assume it's a // When there is no explicit frame to create, assume it's a
// container and let display style dictate the rest // container and let display style dictate the rest

View File

@ -496,8 +496,7 @@ protected:
nsIAtom* aTag, nsIAtom* aTag,
PRInt32 aNameSpaceID, PRInt32 aNameSpaceID,
nsIStyleContext* aStyleContext, nsIStyleContext* aStyleContext,
nsFrameItems& aFrameItems, nsFrameItems& aFrameItems);
PRBool* aWhiteSpaceContent = nsnull);
nsresult ConstructFrameInternal( nsIPresShell* aPresShell, nsresult ConstructFrameInternal( nsIPresShell* aPresShell,
nsIPresContext* aPresContext, nsIPresContext* aPresContext,