Bug 473390 part 18. Eliminate IsSpecialContent. r+sr=roc

This commit is contained in:
Boris Zbarsky 2009-01-19 13:31:35 -05:00
parent cecea72f97
commit ae739c1dd5
2 changed files with 106 additions and 132 deletions

View File

@ -3084,50 +3084,19 @@ nsCSSFrameConstructor::GetParentFrame(PRInt32 aNameSpaceID,
return rv;
}
/* static */
PRBool
nsCSSFrameConstructor::IsSpecialContent(nsIContent* aContent,
nsIAtom* aTag,
PRInt32 aNameSpaceID,
nsStyleContext* aStyleContext)
{
// Gross hack. Return true if this is a content node that we'd create a
// frame for based on something other than display -- in other words if this
// is a node that could never have a nsTableCellFrame, for example.
if (FindHTMLData(aContent, aTag, aNameSpaceID, aStyleContext) ||
FindXULTagData(aContent, aTag, aNameSpaceID, aStyleContext)) {
return PR_TRUE;
}
#ifdef MOZ_SVG
if (aNameSpaceID == kNameSpaceID_SVG && NS_SVGEnabled()) {
// All SVG content is special...
return PR_TRUE;
}
#endif
#ifdef MOZ_MATHML
if (FindMathMLData(aContent, aTag, aNameSpaceID, aStyleContext)) {
return PR_TRUE;
}
#endif
return PR_FALSE;
}
nsresult
nsCSSFrameConstructor::AdjustParentFrame(nsFrameConstructorState& aState,
nsIContent* aChildContent,
nsIFrame* & aParentFrame,
nsIAtom* aTag,
const FrameConstructionData* aFCData,
PRInt32 aNameSpaceID,
nsStyleContext* aChildStyle,
const nsStyleDisplay* aDisplay,
nsFrameItems* & aFrameItems,
nsFrameConstructorSaveState& aSaveState,
PRBool& aSuppressFrame,
PRBool& aCreatedPseudo)
{
NS_PRECONDITION(aChildStyle, "Must have child's style context");
NS_PRECONDITION(aDisplay, "Must have child's style context");
NS_PRECONDITION(aFrameItems, "Must have frame items to work with");
aSuppressFrame = PR_FALSE;
@ -3137,7 +3106,6 @@ nsCSSFrameConstructor::AdjustParentFrame(nsFrameConstructorState& aState,
return NS_OK;
}
PRBool childIsSpecialContent = PR_FALSE; // lazy lookup
// Only use the outer table frame as parent if the child is going to use a
// tableCaptionFrame, otherwise the inner table frame is the parent
// (bug 341858).
@ -3145,11 +3113,7 @@ nsCSSFrameConstructor::AdjustParentFrame(nsFrameConstructorState& aState,
NS_ASSERTION(parentType != nsGkAtoms::tableOuterFrame,
"Shouldn't be happening");
if (parentType == nsGkAtoms::tableColGroupFrame) {
childIsSpecialContent = IsSpecialContent(aChildContent, aTag, aNameSpaceID,
aChildStyle);
if (childIsSpecialContent ||
(aChildStyle->GetStyleDisplay()->mDisplay !=
NS_STYLE_DISPLAY_TABLE_COLUMN)) {
if (aFCData || aDisplay->mDisplay != NS_STYLE_DISPLAY_TABLE_COLUMN) {
aSuppressFrame = PR_TRUE;
return NS_OK;
}
@ -3159,11 +3123,10 @@ nsCSSFrameConstructor::AdjustParentFrame(nsFrameConstructorState& aState,
// we're not table-related in any way, we have to create table
// pseudo-frames so that we have a table cell to live in.
if (IsTableRelated(aParentFrame->GetType(), PR_FALSE) &&
(!IsTableRelated(aChildStyle->GetStyleDisplay()->mDisplay, PR_TRUE) ||
(!IsTableRelated(aDisplay->mDisplay, PR_TRUE) ||
// Also need to create a pseudo-parent if the child is going to end up
// with a frame based on something other than display.
childIsSpecialContent || // looked it up before
IsSpecialContent(aChildContent, aTag, aNameSpaceID, aChildStyle))) {
aFCData)) {
nsFrameState savedStateBits = aState.mAdditionalStateBits;
aState.mAdditionalStateBits &= ~NS_FRAME_GENERATED_CONTENT;
nsresult rv = GetPseudoCellFrame(aNameSpaceID, aState, *aParentFrame);
@ -4860,39 +4823,55 @@ FindAncestorWithGeneratedContentPseudo(nsIFrame* aFrame)
return nsnull;
}
nsresult
nsCSSFrameConstructor::ConstructTextFrame(nsFrameConstructorState& aState,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsStyleContext* aStyleContext,
nsFrameItems& aFrameItems,
PRBool aPseudoParent)
#define FCDATA_DECL(_flags, _func) \
{ _flags, { (FrameCreationFunc)_func } }
#define SIMPLE_FCDATA(_func) FCDATA_DECL(0, _func)
/* static */
const nsCSSFrameConstructor::FrameConstructionData*
nsCSSFrameConstructor::FindTextData(nsIFrame* aParentFrame)
{
// process pending pseudo frames. whitespace doesn't have an effect.
if (!aPseudoParent && !aState.mPseudoFrames.IsEmpty() &&
!TextIsOnlyWhitespace(aContent))
ProcessPseudoFrames(aState, aFrameItems);
nsIFrame* newFrame = nsnull;
#ifdef MOZ_SVG
if (aParentFrame->IsFrameOfType(nsIFrame::eSVG)) {
nsIFrame *ancestorFrame =
nsSVGUtils::GetFirstNonAAncestorFrame(aParentFrame);
if (ancestorFrame) {
nsISVGTextContentMetrics* metrics = do_QueryFrame(ancestorFrame);
if (!metrics) {
return NS_OK;
if (metrics) {
static const FrameConstructionData sSVGGlyphData =
SIMPLE_FCDATA(NS_NewSVGGlyphFrame);
return &sSVGGlyphData;
}
newFrame = NS_NewSVGGlyphFrame(mPresShell, aStyleContext);
}
return nsnull;
}
else
#endif
{
newFrame = NS_NewTextFrame(mPresShell, aStyleContext);
static const FrameConstructionData sTextData = SIMPLE_FCDATA(NS_NewTextFrame);
return &sTextData;
}
nsresult
nsCSSFrameConstructor::ConstructTextFrame(const FrameConstructionData* aData,
nsFrameConstructorState& aState,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsStyleContext* aStyleContext,
nsFrameItems& aFrameItems,
PRBool aPseudoParent)
{
if (!aData) {
// Nothing to do here: suppressed text inside SVG, say
return NS_OK;
}
// process pending pseudo frames. whitespace doesn't have an effect.
if (!aPseudoParent && !aState.mPseudoFrames.IsEmpty() &&
!TextIsOnlyWhitespace(aContent))
ProcessPseudoFrames(aState, aFrameItems);
nsIFrame* newFrame = (*aData->mFunc.mCreationFunc)(mPresShell, aStyleContext);
if (NS_UNLIKELY(!newFrame))
return NS_ERROR_OUT_OF_MEMORY;
@ -4979,9 +4958,6 @@ nsCSSFrameConstructor::FindDataByTag(nsIAtom* aTag,
return nsnull;
}
#define FCDATA_DECL(_flags, _func) \
{ _flags, { (FrameCreationFunc)_func } }
#define SIMPLE_FCDATA(_func) FCDATA_DECL(0, _func)
#define SUPPRESS_FCDATA() FCDATA_DECL(FCDATA_SUPPRESS_FRAME, nsnull)
#define SIMPLE_INT_CREATE(_int, _func) { _int, SIMPLE_FCDATA(_func) }
#define SIMPLE_INT_CHAIN(_int, _func) \
@ -5658,24 +5634,11 @@ nsCSSFrameConstructor::FindXULListItemData(nsIContent* aContent,
/* static */
const nsCSSFrameConstructor::FrameConstructionData*
nsCSSFrameConstructor::FindXULData(nsIContent* aContent,
nsIAtom* aTag,
PRInt32 aNameSpaceID,
nsStyleContext* aStyleContext)
nsCSSFrameConstructor::FindXULDisplayData(const nsStyleDisplay* aDisplay,
nsIContent* aContent,
nsStyleContext* aStyleContext)
{
const FrameConstructionData* data =
FindXULTagData(aContent, aTag, aNameSpaceID, aStyleContext);
if (data) {
return data;
}
// No data found by tag; try display
const nsStyleDisplay* display = aStyleContext->GetStyleDisplay();
PRBool isXULDisplay = IsXULDisplayType(display) &&
(aNameSpaceID == kNameSpaceID_XUL ||
!IsSpecialContent(aContent, aTag, aNameSpaceID, aStyleContext));
if (!isXULDisplay) {
if (!IsXULDisplayType(aDisplay)) {
return nsnull;
}
@ -5700,7 +5663,7 @@ nsCSSFrameConstructor::FindXULData(nsIContent* aContent,
};
// Processing by display here:
return FindDataByInt(display->mDisplay, aContent, aStyleContext,
return FindDataByInt(aDisplay->mDisplay, aContent, aStyleContext,
sXULDisplayData, NS_ARRAY_LENGTH(sXULDisplayData));
}
@ -6749,25 +6712,52 @@ nsCSSFrameConstructor::ConstructFrameInternal( nsFrameConstructorState& aState,
return NS_OK;
}
PRBool isText = aContent->IsNodeOfType(nsINode::eTEXT);
// Try to find frame construction data for this content
const FrameConstructionData* data;
if (isText) {
data = FindTextData(aParentFrame);
} else {
data = FindHTMLData(aContent, aTag, aNameSpaceID, styleContext);
if (!data) {
data = FindXULTagData(aContent, aTag, aNameSpaceID, styleContext);
}
#ifdef MOZ_MATHML
if (!data) {
data = FindMathMLData(aContent, aTag, aNameSpaceID, styleContext);
}
#endif
#ifdef MOZ_SVG
if (!data) {
data = FindSVGData(aContent, aTag, aNameSpaceID, aParentFrame,
styleContext);
}
#endif /* MOZ_SVG */
if (data && (data->mBits & FCDATA_SUPPRESS_FRAME)) {
return NS_OK;
}
}
nsIFrame* adjParentFrame = aParentFrame;
nsFrameItems* frameItems = &aFrameItems;
PRBool pseudoParent = PR_FALSE;
PRBool suppressFrame = PR_FALSE;
nsFrameConstructorSaveState pseudoSaveState;
nsresult rv = AdjustParentFrame(aState, aContent, adjParentFrame,
aTag, aNameSpaceID, styleContext,
frameItems, pseudoSaveState,
suppressFrame, pseudoParent);
data, aNameSpaceID, display, frameItems,
pseudoSaveState, suppressFrame, pseudoParent);
if (NS_FAILED(rv) || suppressFrame) {
return rv;
}
if (aContent->IsNodeOfType(nsINode::eTEXT))
return ConstructTextFrame(aState, aContent, adjParentFrame, styleContext,
*frameItems, pseudoParent);
if (isText) {
return ConstructTextFrame(data, aState, aContent, adjParentFrame,
styleContext, *frameItems, pseudoParent);
}
#ifdef MOZ_SVG
// Don't create frames for non-SVG children of SVG elements
// Don't create frames for non-SVG element children of SVG elements
if (aNameSpaceID != kNameSpaceID_SVG &&
aParentFrame &&
aParentFrame->IsFrameOfType(nsIFrame::eSVG) &&
@ -6793,35 +6783,19 @@ nsCSSFrameConstructor::ConstructFrameInternal( nsFrameConstructorState& aState,
styleContext->GetStyleBackground();
}
// Try to find frame construction data for this content
const FrameConstructionData* data = FindHTMLData(aContent, aTag, aNameSpaceID,
styleContext);
// Now check for XUL display types
if (!data) {
data = FindXULData(aContent, aTag, aNameSpaceID, styleContext);
data = FindXULDisplayData(display, aContent, aStyleContext);
}
#ifdef MOZ_MATHML
if (!data) {
data = FindMathMLData(aContent, aTag, aNameSpaceID, styleContext);
}
#endif /* MOZ_MATHML */
#ifdef MOZ_SVG
if (!data) {
data = FindSVGData(aContent, aTag, aNameSpaceID, adjParentFrame, styleContext);
}
#endif /* MOZ_SVG */
if (data) {
if ((data->mBits & FCDATA_SUPPRESS_FRAME)
#ifdef MOZ_XUL
|| ((data->mBits & FCDATA_IS_POPUP) &&
adjParentFrame->GetType() != nsGkAtoms::menuFrame &&
!aState.mPopupItems.containingBlock)
#endif /* MOZ_XUL */
) {
if ((data->mBits & FCDATA_IS_POPUP) &&
adjParentFrame->GetType() != nsGkAtoms::menuFrame &&
!aState.mPopupItems.containingBlock) {
return NS_OK;
}
#endif /* MOZ_XUL */
return ConstructFrameFromData(data, aState, aContent, adjParentFrame, aTag,
aNameSpaceID, styleContext, *frameItems,

View File

@ -686,9 +686,11 @@ private:
* @param aChildContent the content node we want to construct a frame for
* @param aParentFrame the frame we think should be the parent. This will be
* adjusted to point to a pseudo-frame if needed.
* @param aTag tag that would be used for frame construction
* @param aFCData the FrameConstructionData that would be used for frame
* construction. If this is null, then frame construction will be
* done based on the CSS display value.
* @param aNameSpaceID namespace that will be used for frame construction
* @param aChildStyle the style context for aChildContent
* @param aDisplay the display style struct for aChildContent
* @param aFrameItems the framelist we think we need to put the child frame
* into. If we have to construct pseudo-frames, we'll modify the
* pointer to point to the list the child frame should go into.
@ -706,9 +708,9 @@ private:
nsresult AdjustParentFrame(nsFrameConstructorState& aState,
nsIContent* aChildContent,
nsIFrame* & aParentFrame,
nsIAtom* aTag,
const FrameConstructionData* aFCData,
PRInt32 aNameSpaceID,
nsStyleContext* aChildStyle,
const nsStyleDisplay* aDisplay,
nsFrameItems* & aFrameItems,
nsFrameConstructorSaveState& aSaveState,
PRBool& aSuppressFrame,
@ -759,7 +761,10 @@ private:
nsFrameItems& aFrameItems,
nsIFrame** aNewFrame);
nsresult ConstructTextFrame(nsFrameConstructorState& aState,
static const FrameConstructionData* FindTextData(nsIFrame* aParentFrame);
nsresult ConstructTextFrame(const FrameConstructionData* aData,
nsFrameConstructorState& aState,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsStyleContext* aStyleContext,
@ -781,11 +786,6 @@ private:
nsStyleContext* aStyleContext,
nsFrameItems& aFrameItems);
static PRBool IsSpecialContent(nsIContent* aContent,
nsIAtom* aTag,
PRInt32 aNameSpaceID,
nsStyleContext* aStyleContext);
// Function to find FrameConstructionData for aContent. Will return
// null if aContent is not HTML.
static const FrameConstructionData* FindHTMLData(nsIContent* aContent,
@ -896,15 +896,15 @@ private:
FindXULListItemData(nsIContent* aContent, nsStyleContext* aStyleContext);
#endif /* MOZ_XUL */
// Function to find FrameConstructionData for aContent either using
// FindXULTagData or using one of the XUL display types. Will
// return null if aContent is not XUL and doesn't have a XUL display
// type (or even if it has a XUL display type but is HTML/MathML/SVG
// that would get a frame by tag).
static const FrameConstructionData* FindXULData(nsIContent* aContent,
nsIAtom* aTag,
PRInt32 aNameSpaceID,
nsStyleContext* aStyleContext);
// Function to find FrameConstructionData for aContent using one of the XUL
// display types. Will return null if aDisplay doesn't have a XUL display
// type. This function performs no other checks, so should only be called if
// we know for sure that the content is not something that should get a frame
// constructed by tag.
static const FrameConstructionData*
FindXULDisplayData(const nsStyleDisplay* aDisplay,
nsIContent* aContent,
nsStyleContext* aStyleContext);
// SVG - rods
#ifdef MOZ_SVG