Bug 348577 - Implement MathML <mtable> with display:inline-table (mtable has incorrect baseline). Patch by Bill Gianopoulos <wgianopoulos@yahoo.com>, r=rbs, sr=bzbarsky.

This commit is contained in:
karlt+@karlt.net 2008-01-08 18:14:35 -08:00
Родитель 220e96b5cc
Коммит 04c40a6aa8
6 изменённых файлов: 23 добавлений и 132 удалений

Просмотреть файл

@ -2860,7 +2860,7 @@ nsCSSFrameConstructor::CreatePseudoTableFrame(PRInt32 aNameSpac
nsFrameItems items;
rv = ConstructTableFrame(aState, parentContent,
parentFrame, childStyle, aNameSpaceID,
PR_TRUE, items, PR_TRUE, pseudoOuter.mFrame,
PR_TRUE, items, pseudoOuter.mFrame,
pseudoInner.mFrame);
if (NS_FAILED(rv)) return rv;
@ -3489,8 +3489,6 @@ IsSpecialContent(nsIContent* aContent,
aTag == nsGkAtoms::merror_ ||
aTag == nsGkAtoms::none ||
aTag == nsGkAtoms::mprescripts_ ||
(aTag == nsGkAtoms::mtable_ &&
aStyleContext->GetStyleDisplay()->mDisplay == NS_STYLE_DISPLAY_TABLE) ||
aTag == nsGkAtoms::math;
#endif
return PR_FALSE;
@ -3595,7 +3593,6 @@ nsCSSFrameConstructor::ConstructTableFrame(nsFrameConstructorState& aState,
PRInt32 aNameSpaceID,
PRBool aIsPseudo,
nsFrameItems& aChildItems,
PRBool aAllowOutOfFlow,
nsIFrame*& aNewOuterFrame,
nsIFrame*& aNewInnerFrame)
{
@ -3638,14 +3635,9 @@ nsCSSFrameConstructor::ConstructTableFrame(nsFrameConstructorState& aState,
}
}
// We need the aAllowOutOfFlow thing for MathML. See bug 355993.
// Once bug 348577 is fixed, we should remove this code. At that
// point, the aAllowOutOfFlow arg can go away.
nsIFrame* geometricParent =
aAllowOutOfFlow ?
aState.GetGeometricParent(outerStyleContext->GetStyleDisplay(),
parentFrame) :
parentFrame;
nsIFrame* geometricParent = aState.GetGeometricParent
(outerStyleContext->GetStyleDisplay(),
parentFrame);
// Init the table outer frame and see if we need to create a view, e.g.
// the frame is absolutely positioned
@ -3669,8 +3661,7 @@ nsCSSFrameConstructor::ConstructTableFrame(nsFrameConstructorState& aState,
aNewOuterFrame->SetInitialChildList(nsnull, aNewInnerFrame);
rv = aState.AddChild(aNewOuterFrame, *frameItems, aContent,
aStyleContext, parentFrame, aAllowOutOfFlow,
aAllowOutOfFlow);
aStyleContext, parentFrame);
if (NS_FAILED(rv)) {
return rv;
}
@ -6661,8 +6652,8 @@ nsCSSFrameConstructor::ConstructFrameByDisplayType(nsFrameConstructorState& aSta
nsIFrame* innerTable;
rv = ConstructTableFrame(aState, aContent,
aParentFrame, aStyleContext,
aNameSpaceID, PR_FALSE, aFrameItems, PR_TRUE,
newFrame, innerTable);
aNameSpaceID, PR_FALSE, aFrameItems, newFrame,
innerTable);
addedToFrameList = PR_TRUE;
// Note: table construction function takes care of initializing
// the frame, processing children, and setting the initial child
@ -6956,93 +6947,6 @@ nsCSSFrameConstructor::ConstructMathMLFrame(nsFrameConstructorState& aState,
else if (aTag == nsGkAtoms::mrow_ ||
aTag == nsGkAtoms::merror_)
newFrame = NS_NewMathMLmrowFrame(mPresShell, aStyleContext);
// CONSTRUCTION of MTABLE elements
else if (aTag == nsGkAtoms::mtable_ &&
disp->mDisplay == NS_STYLE_DISPLAY_TABLE) {
// <mtable> is an inline-table -- but this isn't yet supported.
// What we do here is to wrap the table in an anonymous containing
// block so that it can mix better with other surrounding MathML markups
// This assumes that the <mtable> is not positioned or floated.
// (MathML does not allow/support positioned or floated elements at all.)
// XXXbz once we stop doing this mess, fix IsSpecialContent accordingly.
nsStyleContext* parentContext = aParentFrame->GetStyleContext();
nsStyleSet *styleSet = mPresShell->StyleSet();
// first, create a MathML mrow frame that will wrap the block frame
nsRefPtr<nsStyleContext> mrowContext;
mrowContext = styleSet->ResolvePseudoStyleFor(aContent,
nsCSSAnonBoxes::mozMathInline,
parentContext);
newFrame = NS_NewMathMLmrowFrame(mPresShell, mrowContext);
if (NS_UNLIKELY(!newFrame)) {
return NS_ERROR_OUT_OF_MEMORY;
}
InitAndRestoreFrame(aState, aContent, aParentFrame, nsnull, newFrame);
nsRefPtr<nsStyleContext> blockContext;
blockContext = styleSet->ResolvePseudoStyleFor(aContent,
nsCSSAnonBoxes::mozMathMLAnonymousBlock,
mrowContext);
// then, create a block frame that will wrap the table frame
nsIFrame* blockFrame = NS_NewBlockFrame(mPresShell, blockContext,
NS_BLOCK_SPACE_MGR |
NS_BLOCK_MARGIN_ROOT);
if (NS_UNLIKELY(!blockFrame)) {
newFrame->Destroy();
return NS_ERROR_OUT_OF_MEMORY;
}
InitAndRestoreFrame(aState, aContent, newFrame, nsnull, blockFrame);
// then, create the table frame itself
nsRefPtr<nsStyleContext> tableContext =
ResolveStyleContext(blockFrame, aContent);
nsFrameItems tempItems;
nsIFrame* outerTable;
nsIFrame* innerTable;
// XXXbz note: since we're constructing a table frame, and it does things
// based on whether its parent is a pseudo or not, we need to save our
// pseudo state here. This can go away if we switch to a direct
// construction of mtable as an inline-table.
nsPseudoFrames priorPseudoFrames;
aState.mPseudoFrames.Reset(&priorPseudoFrames);
// Pass PR_FALSE for aAllowOutOfFlow so that the resulting table will be
// guaranteed to be in-flow (and in particular, a descendant of the <math>
// in the _frame_ tree).
rv = ConstructTableFrame(aState, aContent, blockFrame, tableContext,
aNameSpaceID, PR_FALSE, tempItems, PR_FALSE,
outerTable, innerTable);
// Note: table construction function takes care of initializing the frame,
// processing children, and setting the initial child list
NS_ASSERTION(aState.mPseudoFrames.IsEmpty(),
"How did we end up with pseudo-frames here?");
// restore the incoming pseudo frame state. Note that we MUST do this
// before adding things to aFrameItems.
aState.mPseudoFrames = priorPseudoFrames;
// set the outerTable as the initial child of the anonymous block
blockFrame->SetInitialChildList(nsnull, outerTable);
// set the block frame as the initial child of the mrow frame
newFrame->SetInitialChildList(nsnull, blockFrame);
// add the new frame to the flow
// XXXbz this is wrong. What if it's out-of-flow? For that matter, this
// is putting the frame in the wrong child list in the "pseudoParent ==
// PR_TRUE" case, which I assume we can hit.
aFrameItems.AddChild(newFrame);
return rv;
}
// End CONSTRUCTION of MTABLE elements
else if (aTag == nsGkAtoms::math) {
// root <math> element
const nsStyleDisplay* display = aStyleContext->GetStyleDisplay();

Просмотреть файл

@ -324,8 +324,7 @@ private:
* to create into aChildItems. The newly-created outer frame will either be
* in aChildItems or a descendant of a pseudo in aChildItems (unless it's
* positioned or floated, in which case its placeholder will be in
* aChildItems). If aAllowOutOfFlow is false, the table frame will be forced
* to be in-flow no matter what its float or position values are.
* aChildItems).
*/
nsresult ConstructTableFrame(nsFrameConstructorState& aState,
nsIContent* aContent,
@ -334,7 +333,6 @@ private:
PRInt32 aNameSpaceID,
PRBool aIsPseudo,
nsFrameItems& aChildItems,
PRBool aAllowOutOfFlow,
nsIFrame*& aNewOuterFrame,
nsIFrame*& aNewInnerFrame);

Просмотреть файл

@ -93,23 +93,3 @@ nsMathMLmrowFrame::AttributeChanged(PRInt32 aNameSpaceID,
return nsMathMLContainerFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);
}
nsIFrame*
nsMathMLmrowFrame::GetContentInsertionFrame()
{
// Special for <mtable>: In the frame construction code, we also use
// this frame class as a wrapper for mtable. Hence, if we are asked
// for the insertion frame in the context where we are such a wrapper,
// we should return the real frame intended for mtable
if (mContent->Tag() == nsGkAtoms::mtable_) {
nsIFrame* frame = mFrames.FirstChild();
for ( ; frame; frame = frame->GetFirstChild(nsnull)) {
// drill down to the real mtable
if (frame->GetType() == nsGkAtoms::tableOuterFrame)
return frame->GetContentInsertionFrame();
}
NS_NOTREACHED("mtable wrapper without the real table frame");
}
return nsMathMLContainerFrame::GetContentInsertionFrame();
}

Просмотреть файл

@ -56,9 +56,6 @@ public:
nsIAtom* aAttribute,
PRInt32 aModType);
virtual nsIFrame*
GetContentInsertionFrame();
NS_IMETHOD
InheritAutomaticData(nsIFrame* aParent);

Просмотреть файл

@ -145,10 +145,22 @@ GetValueAt(nsIFrame* aTableOrRowFrame,
}
#ifdef NS_DEBUG
static PRBool
IsTable(PRUint8 aDisplay)
{
if ((aDisplay == NS_STYLE_DISPLAY_TABLE) ||
(aDisplay == NS_STYLE_DISPLAY_INLINE_TABLE))
return PR_TRUE;
return PR_FALSE;
}
#define DEBUG_VERIFY_THAT_FRAME_IS(_frame, _expected) \
NS_ASSERTION(NS_STYLE_DISPLAY_##_expected == _frame->GetStyleDisplay()->mDisplay, "internal error");
#define DEBUG_VERIFY_THAT_FRAME_IS_TABLE(_frame) \
NS_ASSERTION(IsTable(_frame->GetStyleDisplay()->mDisplay), "internal error");
#else
#define DEBUG_VERIFY_THAT_FRAME_IS(_frame, _expected)
#define DEBUG_VERIFY_THAT_FRAME_IS_TABLE(_frame)
#endif
// map attributes that depend on the index of the row:
@ -157,7 +169,7 @@ static void
MapRowAttributesIntoCSS(nsIFrame* aTableFrame,
nsIFrame* aRowFrame)
{
DEBUG_VERIFY_THAT_FRAME_IS(aTableFrame, TABLE);
DEBUG_VERIFY_THAT_FRAME_IS_TABLE(aTableFrame);
DEBUG_VERIFY_THAT_FRAME_IS(aRowFrame, TABLE_ROW);
PRInt32 rowIndex = ((nsTableRowFrame*)aRowFrame)->GetRowIndex();
nsIContent* rowContent = aRowFrame->GetContent();
@ -198,7 +210,7 @@ MapColAttributesIntoCSS(nsIFrame* aTableFrame,
nsIFrame* aRowFrame,
nsIFrame* aCellFrame)
{
DEBUG_VERIFY_THAT_FRAME_IS(aTableFrame, TABLE);
DEBUG_VERIFY_THAT_FRAME_IS_TABLE(aTableFrame);
DEBUG_VERIFY_THAT_FRAME_IS(aRowFrame, TABLE_ROW);
DEBUG_VERIFY_THAT_FRAME_IS(aCellFrame, TABLE_CELL);
PRInt32 rowIndex, colIndex;

Просмотреть файл

@ -271,7 +271,7 @@ merror {
/**************************************************************************/
mtable {
display: table;
display: inline-table;
border-collapse: separate;
border-spacing: 0;
}