mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
incremental reflow: append/insert/delete row group, append/insert/delete col
This commit is contained in:
parent
19dbcd23cb
commit
0c1c724f56
@ -35,7 +35,13 @@ NS_DEF_PTR(nsIStyleContext);
|
||||
static NS_DEFINE_IID(kIHTMLTableColElementIID, NS_IHTMLTABLECOLELEMENT_IID);
|
||||
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
static PRBool gsDebug = PR_FALSE;
|
||||
static PRBool gsDebugIR = PR_FALSE;
|
||||
#else
|
||||
static const PRBool gsDebug = PR_FALSE;
|
||||
static const PRBool gsDebugIR = PR_FALSE;
|
||||
#endif
|
||||
|
||||
nsTableColGroupFrame::nsTableColGroupFrame(nsIContent* aContent,
|
||||
nsIFrame* aParentFrame)
|
||||
@ -48,7 +54,7 @@ nsTableColGroupFrame::~nsTableColGroupFrame()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_IMETHODIMP
|
||||
nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
@ -75,7 +81,6 @@ nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChi
|
||||
PRInt32 colIndex = mStartColIndex + mColCount;
|
||||
((nsTableColFrame *)(kidFrame))->InitColFrame (colIndex, repeat);
|
||||
mColCount+= repeat;
|
||||
((nsTableColFrame *)kidFrame)->SetColumnIndex(colIndex);
|
||||
tableFrame->AddColumnFrame((nsTableColFrame *)kidFrame);
|
||||
}
|
||||
// colgroup's span attribute is how many columns the group represents
|
||||
@ -138,7 +143,7 @@ nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChi
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_IMETHODIMP
|
||||
nsTableColGroupFrame::AppendNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList)
|
||||
{
|
||||
nsIFrame* lastChild = LastFrame(mFirstChild);
|
||||
@ -171,38 +176,19 @@ NS_METHOD nsTableColGroupFrame::Paint(nsIPresContext& aPresContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// TODO: incremental reflow
|
||||
// today, we just throw away the column frames and start over every time
|
||||
// this is dumb, we should be able to maintain column frames and adjust incrementally
|
||||
NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
NS_ASSERTION(nsnull!=mContent, "bad state -- null content for frame");
|
||||
|
||||
nsresult rv=NS_OK;
|
||||
// for every content child that (is a column thingy and does not already have a frame)
|
||||
// create a frame and adjust it's style
|
||||
nsIFrame* kidFrame = nsnull;
|
||||
|
||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
||||
NS_ASSERTION(nsnull != aReflowState.reflowCommand, "null reflow command");
|
||||
|
||||
// Get the type of reflow command
|
||||
nsIReflowCommand::ReflowType reflowCmdType;
|
||||
aReflowState.reflowCommand->GetType(reflowCmdType);
|
||||
|
||||
// Currently we only expect appended reflow commands
|
||||
NS_ASSERTION(nsIReflowCommand::FrameAppended == reflowCmdType,
|
||||
"unexpected reflow command");
|
||||
|
||||
// Get the new column frames
|
||||
nsIFrame* childList;
|
||||
aReflowState.reflowCommand->GetChildFrame(childList);
|
||||
|
||||
// Append them to the child list
|
||||
AppendNewFrames(aPresContext, childList);
|
||||
InitNewFrames(aPresContext, childList);
|
||||
rv = IncrementalReflow(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
}
|
||||
|
||||
for (kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) {
|
||||
@ -228,9 +214,355 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
|
||||
aDesiredSize.maxElementSize->height=0;
|
||||
}
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableColGroupFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTCGF IR: IncrementalReflow\n");
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// determine if this frame is the target or not
|
||||
nsIFrame *target=nsnull;
|
||||
rv = aReflowState.reflowCommand->GetTarget(target);
|
||||
if ((PR_TRUE==NS_SUCCEEDED(rv)) && (nsnull!=target))
|
||||
{
|
||||
if (this==target)
|
||||
rv = IR_TargetIsMe(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
else
|
||||
{
|
||||
// Get the next frame in the reflow chain
|
||||
nsIFrame* nextFrame;
|
||||
aReflowState.reflowCommand->GetNext(nextFrame);
|
||||
rv = IR_TargetIsChild(aPresContext, aDesiredSize, aReflowState, aStatus, nextFrame);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableColGroupFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
nsIReflowCommand::ReflowType type;
|
||||
aReflowState.reflowCommand->GetType(type);
|
||||
nsIFrame *objectFrame;
|
||||
aReflowState.reflowCommand->GetChildFrame(objectFrame);
|
||||
const nsStyleDisplay *childDisplay;
|
||||
objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (PR_TRUE==gsDebugIR) printf("nTCGF IR: IncrementalReflow_TargetIsMe with type=%d\n", type);
|
||||
switch (type)
|
||||
{
|
||||
case nsIReflowCommand::FrameInserted :
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_ColInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
(nsTableColFrame*)objectFrame, PR_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame, PR_FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::FrameAppended :
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_ColAppended(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
(nsTableColFrame*)objectFrame);
|
||||
}
|
||||
else
|
||||
{ // no optimization to be done for Unknown frame types, so just reuse the Inserted method
|
||||
rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame, PR_FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
case nsIReflowCommand::FrameReplaced :
|
||||
|
||||
*/
|
||||
|
||||
case nsIReflowCommand::FrameRemoved :
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_ColRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
(nsTableColFrame*)objectFrame);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
rv = IR_UnknownFrameRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::StyleChanged :
|
||||
NS_NOTYETIMPLEMENTED("unimplemented reflow command type");
|
||||
rv = NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (PR_TRUE==gsDebugIR) printf("TCGF IR: StyleChanged not implemented.\n");
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::ContentChanged :
|
||||
NS_ASSERTION(PR_FALSE, "illegal reflow type: ContentChanged");
|
||||
rv = NS_ERROR_ILLEGAL_VALUE;
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::PullupReflow:
|
||||
case nsIReflowCommand::PushReflow:
|
||||
case nsIReflowCommand::CheckPullupReflow :
|
||||
case nsIReflowCommand::UserDefined :
|
||||
NS_NOTYETIMPLEMENTED("unimplemented reflow command type");
|
||||
rv = NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (PR_TRUE==gsDebugIR) printf("TCGF IR: reflow command not implemented.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableColGroupFrame::IR_ColInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableColFrame * aInsertedFrame,
|
||||
PRBool aReplace)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
PRBool adjustStartingColIndex=PR_FALSE;
|
||||
rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState, aStatus, aInsertedFrame, aReplace);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
PRInt32 startingColIndex=mStartColIndex;
|
||||
startingColIndex += GetColumnCount(); // has the side effect of resetting all column indexes
|
||||
|
||||
nsIFrame *childFrame=nsnull;
|
||||
GetNextSibling(childFrame);
|
||||
while ((NS_SUCCEEDED(rv)) && (nsnull!=childFrame))
|
||||
{
|
||||
const nsStyleDisplay *display;
|
||||
childFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay)
|
||||
{
|
||||
startingColIndex += ((nsTableColGroupFrame *)childFrame)->SetStartColumnIndex(startingColIndex);
|
||||
}
|
||||
rv = childFrame->GetNextSibling(childFrame);
|
||||
}
|
||||
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame))
|
||||
tableFrame->InvalidateColumnCache();
|
||||
//XXX: what we want to do here is determine if the new COL information changes anything about layout
|
||||
// if not, we can skip rebalancing the columns
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableColGroupFrame::IR_ColAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableColFrame * aAppendedFrame)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
PRBool adjustStartingColIndex=PR_FALSE;
|
||||
rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState, aStatus, aAppendedFrame, PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
PRInt32 startingColIndex=mStartColIndex;
|
||||
// this could be optimized
|
||||
startingColIndex += GetColumnCount(); // has the side effect of resetting all column indexes
|
||||
|
||||
nsIFrame *childFrame=nsnull;
|
||||
GetNextSibling(childFrame);
|
||||
while ((NS_SUCCEEDED(rv)) && (nsnull!=childFrame))
|
||||
{
|
||||
const nsStyleDisplay *display;
|
||||
childFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay)
|
||||
{
|
||||
startingColIndex += ((nsTableColGroupFrame *)childFrame)->SetStartColumnIndex(startingColIndex);
|
||||
}
|
||||
rv = childFrame->GetNextSibling(childFrame);
|
||||
}
|
||||
|
||||
// today we need to rebuild the whole column cache
|
||||
// if the table frame is ever recoded to build the column cache incrementally, we could take
|
||||
// advantage of that here.
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame))
|
||||
tableFrame->InvalidateColumnCache();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_METHOD nsTableColGroupFrame::IR_ColRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableColFrame * aDeletedFrame)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
PRInt32 startingColIndex=mStartColIndex;
|
||||
nsIFrame *childFrame=mFirstChild;
|
||||
nsIFrame *prevSib=nsnull;
|
||||
while ((NS_SUCCEEDED(rv)) && (nsnull!=childFrame))
|
||||
{
|
||||
if (childFrame==aDeletedFrame)
|
||||
{
|
||||
nsIFrame *deleteFrameNextSib=nsnull;
|
||||
aDeletedFrame->GetNextSibling(deleteFrameNextSib);
|
||||
if (nsnull!=prevSib)
|
||||
prevSib->SetNextSibling(deleteFrameNextSib);
|
||||
else
|
||||
mFirstChild = deleteFrameNextSib;
|
||||
startingColIndex += GetColumnCount(); // resets all column indexes
|
||||
}
|
||||
const nsStyleDisplay *display;
|
||||
childFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay)
|
||||
{
|
||||
// we've removed aDeletedFrame, now adjust the starting col index of all subsequent col groups
|
||||
startingColIndex += ((nsTableColGroupFrame *)childFrame)->SetStartColumnIndex(startingColIndex);
|
||||
}
|
||||
prevSib=childFrame;
|
||||
rv = childFrame->GetNextSibling(childFrame);
|
||||
}
|
||||
|
||||
// today we need to rebuild the whole column cache
|
||||
// if the table frame is ever recoded to build the column cache incrementally, we could take
|
||||
// advantage of that here.
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame))
|
||||
tableFrame->InvalidateColumnCache();
|
||||
return rv;
|
||||
}
|
||||
|
||||
//XXX: handle aReplace
|
||||
NS_METHOD nsTableColGroupFrame::IR_UnknownFrameInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace)
|
||||
{
|
||||
nsIReflowCommand::ReflowType type;
|
||||
aReflowState.reflowCommand->GetType(type);
|
||||
// we have a generic frame that gets inserted but doesn't effect reflow
|
||||
// hook it up then ignore it
|
||||
if (nsIReflowCommand::FrameAppended==type)
|
||||
{ // frameAppended reflow -- find the last child and make aInsertedFrame its next sibling
|
||||
if (PR_TRUE==gsDebugIR) printf("TCGF IR: FrameAppended adding unknown frame type.\n");
|
||||
nsIFrame *lastChild=mFirstChild;
|
||||
nsIFrame *nextChild=mFirstChild;
|
||||
while (nsnull!=nextChild)
|
||||
{
|
||||
lastChild=nextChild;
|
||||
nextChild->GetNextSibling(nextChild);
|
||||
}
|
||||
if (nsnull==lastChild)
|
||||
mFirstChild = aInsertedFrame;
|
||||
else
|
||||
lastChild->SetNextSibling(aInsertedFrame);
|
||||
}
|
||||
else
|
||||
{ // frameInserted reflow -- hook up aInsertedFrame as prevSibling's next sibling,
|
||||
// and be sure to hook in aInsertedFrame's nextSibling (from prevSibling)
|
||||
if (PR_TRUE==gsDebugIR) printf("TCGF IR: FrameInserted adding unknown frame type.\n");
|
||||
nsIFrame *prevSibling=nsnull;
|
||||
nsresult rv = aReflowState.reflowCommand->GetPrevSiblingFrame(prevSibling);
|
||||
if (NS_SUCCEEDED(rv) && (nsnull!=prevSibling))
|
||||
{
|
||||
nsIFrame *nextSibling=nsnull;
|
||||
prevSibling->GetNextSibling(nextSibling);
|
||||
prevSibling->SetNextSibling(aInsertedFrame);
|
||||
aInsertedFrame->SetNextSibling(nextSibling);
|
||||
}
|
||||
else
|
||||
{
|
||||
nsIFrame *nextSibling=nsnull;
|
||||
if (nsnull!=mFirstChild)
|
||||
mFirstChild->GetNextSibling(nextSibling);
|
||||
mFirstChild = aInsertedFrame;
|
||||
aInsertedFrame->SetNextSibling(nextSibling);
|
||||
}
|
||||
}
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableColGroupFrame::IR_UnknownFrameRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aRemovedFrame)
|
||||
{
|
||||
// we have a generic frame that gets removed but doesn't effect reflow
|
||||
// unhook it then ignore it
|
||||
if (PR_TRUE==gsDebugIR) printf("TCGF IR: FrameRemoved removing unknown frame type.\n");
|
||||
nsIFrame *prevChild=nsnull;
|
||||
nsIFrame *nextChild=mFirstChild;
|
||||
while (nextChild!=aRemovedFrame)
|
||||
{
|
||||
prevChild=nextChild;
|
||||
nextChild->GetNextSibling(nextChild);
|
||||
}
|
||||
nextChild=nsnull;
|
||||
aRemovedFrame->GetNextSibling(nextChild);
|
||||
if (nsnull==prevChild) // objectFrame was first child
|
||||
mFirstChild = nextChild;
|
||||
else
|
||||
prevChild->SetNextSibling(nextChild);
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableColGroupFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aNextFrame)
|
||||
{
|
||||
nsresult rv;
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTCGF IR: IR_TargetIsChild\n");
|
||||
|
||||
// Remember the old col count
|
||||
const PRInt32 oldColCount = GetColumnCount();
|
||||
|
||||
// Pass along the reflow command
|
||||
nsHTMLReflowMetrics desiredSize(nsnull);
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aNextFrame,
|
||||
aReflowState,
|
||||
aReflowState.maxSize);
|
||||
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame))
|
||||
{
|
||||
// compare the new col count to the old col count.
|
||||
// If they are the same, we just need to rebalance column widths
|
||||
// If they differ, we need to fix up other column groups and the column cache
|
||||
const PRInt32 newColCount = GetColumnCount(); // this will set the new column indexes if necessary
|
||||
if (oldColCount==newColCount)
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
else
|
||||
tableFrame->InvalidateColumnCache();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Subclass hook for style post processing
|
||||
NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext& aPresContext)
|
||||
{
|
||||
|
@ -102,11 +102,63 @@ protected:
|
||||
* Since we need to know the full column structure before the COLS attribute
|
||||
* can be interpreted, we can't just use DidSetStyleContext
|
||||
*/
|
||||
NS_METHOD SetStyleContextForFirstPass(nsIPresContext& aPresContext);
|
||||
NS_IMETHOD SetStyleContextForFirstPass(nsIPresContext& aPresContext);
|
||||
|
||||
NS_IMETHOD InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList);
|
||||
NS_IMETHOD AppendNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList);
|
||||
|
||||
|
||||
NS_IMETHOD IncrementalReflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD IR_ColInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableColFrame * aInsertedFrame,
|
||||
PRBool aReplace);
|
||||
|
||||
NS_IMETHOD IR_ColAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableColFrame * aAppendedFrame);
|
||||
|
||||
NS_IMETHOD IR_ColRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableColFrame * aDeletedFrame);
|
||||
|
||||
NS_IMETHOD IR_UnknownFrameInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace);
|
||||
|
||||
NS_IMETHOD IR_UnknownFrameRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aRemovedFrame);
|
||||
|
||||
NS_IMETHOD IR_TargetIsChild(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aNextFrame);
|
||||
|
||||
|
||||
// data members
|
||||
|
||||
nsresult InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList);
|
||||
nsresult AppendNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList);
|
||||
|
||||
PRInt32 mColCount;
|
||||
|
||||
/** the starting column index this col group represents. Must be >= 0. */
|
||||
|
@ -52,7 +52,6 @@ static const PRBool gsDebug = PR_FALSE;
|
||||
static const PRBool gsDebugCLD = PR_FALSE;
|
||||
static const PRBool gsDebugNT = PR_FALSE;
|
||||
static const PRBool gsDebugIR = PR_FALSE;
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef max
|
||||
@ -271,6 +270,7 @@ nsTableFrame::nsTableFrame(nsIContent* aContent, nsIFrame* aParentFrame)
|
||||
mColCache(nsnull),
|
||||
mTableLayoutStrategy(nsnull),
|
||||
mFirstPassValid(PR_FALSE),
|
||||
mColumnWidthsValid(PR_FALSE),
|
||||
mColumnCacheValid(PR_FALSE),
|
||||
mCellMapValid(PR_TRUE),
|
||||
mIsInvariantWidth(PR_FALSE)
|
||||
@ -1565,7 +1565,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
|
||||
if (PR_TRUE==gsDebug) printf("TIF Reflow: needs reflow\n");
|
||||
if (eReflowReason_Initial!=aReflowState.reason && PR_FALSE==IsCellMapValid())
|
||||
{
|
||||
if (PR_TRUE==gsDebug) printf("TIF Reflow: not initial reflow, so resetting cell map.\n");
|
||||
if (PR_TRUE==gsDebug) printf("TIF Reflow: cell map invalid, rebuilding...\n");
|
||||
if (nsnull!=mCellMap)
|
||||
delete mCellMap;
|
||||
mCellMap = new nsCellMap(0,0);
|
||||
@ -1574,14 +1574,17 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
|
||||
}
|
||||
if (PR_FALSE==IsFirstPassValid())
|
||||
{
|
||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: first pass is invalid\n");
|
||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: first pass is invalid, rebuilding...\n");
|
||||
rv = ResizeReflowPass1(aPresContext, aDesiredSize, aReflowState, aStatus, nsnull, aReflowState.reason);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
needsRecalc=PR_TRUE;
|
||||
}
|
||||
if (PR_FALSE==IsColumnCacheValid())
|
||||
{
|
||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: column cache is invalid, rebuilding...\n");
|
||||
needsRecalc=PR_TRUE;
|
||||
}
|
||||
if (PR_TRUE==needsRecalc)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF Reflow: needs recalc.\n");
|
||||
@ -1590,11 +1593,20 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF Reflow: Re-init layout strategy\n");
|
||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize);
|
||||
mColumnWidthsValid=PR_TRUE;
|
||||
}
|
||||
BuildColumnCache(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
RecalcLayoutData(); // Recalculate Layout Dependencies
|
||||
}
|
||||
|
||||
if (PR_FALSE==IsColumnWidthsValid())
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF Reflow: Re-init layout strategy\n");
|
||||
if (nsnull!=mTableLayoutStrategy)
|
||||
{
|
||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize);
|
||||
mColumnWidthsValid=PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (nsnull==mPrevInFlow)
|
||||
{ // only do this for a first-in-flow table frame
|
||||
@ -1707,6 +1719,7 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext& aPresContext,
|
||||
PRInt32 yCoord = y;
|
||||
if (NS_UNCONSTRAINEDSIZE!=yCoord)
|
||||
yCoord+= topInset;
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTIF IR: Reflow Pass 1 of frame %p\n", kidFrame);
|
||||
ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, aStatus);
|
||||
|
||||
// Place the child since some of its content fit in us.
|
||||
@ -1875,7 +1888,8 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
InnerTableReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
nsresult rv = NS_FRAME_COMPLETE;
|
||||
nsresult rv = NS_OK;
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
nsIReflowCommand::ReflowType type;
|
||||
aReflowState.reflowState.reflowCommand->GetType(type);
|
||||
nsIFrame *objectFrame;
|
||||
@ -1962,7 +1976,7 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
case nsIReflowCommand::UserDefined :
|
||||
NS_NOTYETIMPLEMENTED("unimplemented reflow command type");
|
||||
rv = NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (PR_TRUE==gsDebugIR) printf("TOF IR: reflow command not implemented.\n");
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF IR: reflow command not implemented.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2172,6 +2186,13 @@ NS_METHOD nsTableFrame::IR_RowGroupInserted(nsIPresContext& aPresContext,
|
||||
nsresult rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState,
|
||||
aStatus, (nsIFrame*)aInsertedFrame, aReplace);
|
||||
// inserting the rowgroup only effects reflow if the rowgroup includes at least one row
|
||||
PRInt32 rowCount;
|
||||
aInsertedFrame->GetRowCount(rowCount);
|
||||
if (0>rowCount)
|
||||
{ // for now we will assume that if there are rows, then there are cells and we need to recalc table info
|
||||
InvalidateCellMap();
|
||||
InvalidateColumnCache();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -2189,6 +2210,7 @@ NS_METHOD nsTableFrame::IR_RowGroupAppended(nsIPresContext& aPresContext,
|
||||
return rv;
|
||||
|
||||
// account for the cells in the rows that are children of aAppendedFrame
|
||||
// this will add the content of the rowgroup to the cell map
|
||||
rv = DidAppendRowGroup((nsTableRowGroupFrame*)aAppendedFrame);
|
||||
|
||||
// do a pass-1 layout of all the cells in all the rows of the rowgroup
|
||||
@ -2198,7 +2220,8 @@ NS_METHOD nsTableFrame::IR_RowGroupAppended(nsIPresContext& aPresContext,
|
||||
return rv;
|
||||
|
||||
// if any column widths have to change due to this, rebalance column widths
|
||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize);
|
||||
//XXX need to calculate this, but for now just do it
|
||||
InvalidateColumnWidths();
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -2210,6 +2233,20 @@ NS_METHOD nsTableFrame::IR_RowGroupRemoved(nsIPresContext& aPresContext,
|
||||
nsTableRowGroupFrame * aDeletedFrame)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
rv = IR_UnknownFrameRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
aDeletedFrame);
|
||||
PRInt32 rowCount=0;
|
||||
aDeletedFrame->GetRowCount(rowCount);
|
||||
if (0>rowCount)
|
||||
{ // for now we will assume that if there are rows, then there are cells and we need to recalc table info
|
||||
InvalidateCellMap();
|
||||
InvalidateColumnCache();
|
||||
}
|
||||
// if any column widths have to change due to this, rebalance column widths
|
||||
//XXX need to calculate this, but for now just do it
|
||||
InvalidateColumnWidths();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -2262,7 +2299,8 @@ NS_METHOD nsTableFrame::IR_UnknownFrameInserted(nsIPresContext& aPresCont
|
||||
aInsertedFrame->SetNextSibling(nextSibling);
|
||||
}
|
||||
}
|
||||
return NS_FRAME_COMPLETE;
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableFrame::IR_UnknownFrameRemoved(nsIPresContext& aPresContext,
|
||||
@ -2287,7 +2325,8 @@ NS_METHOD nsTableFrame::IR_UnknownFrameRemoved(nsIPresContext& aPresConte
|
||||
mFirstChild = nextChild;
|
||||
else
|
||||
prevChild->SetNextSibling(nextChild);
|
||||
return NS_FRAME_COMPLETE;
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return NS_OK;;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
|
||||
@ -2322,10 +2361,7 @@ NS_METHOD nsTableFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
|
||||
// XXX For the time being just fall through and treat it like a
|
||||
// pass 2 reflow...
|
||||
// calling intialize here resets all the cached info based on new table content
|
||||
if (nsnull!=mTableLayoutStrategy)
|
||||
{
|
||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize);
|
||||
}
|
||||
InvalidateColumnWidths();
|
||||
#else
|
||||
// XXX Hack...
|
||||
AdjustSiblingsAfterReflow(&aPresContext, aReflowState, aNextFrame, desiredSize.height -
|
||||
@ -2459,6 +2495,7 @@ void nsTableFrame::PlaceChild(nsIPresContext& aPresContext,
|
||||
* @return true if we successfully reflowed all the mapped children and false
|
||||
* otherwise, e.g. we pushed children to the next in flow
|
||||
*/
|
||||
// XXX: this interface should change to pass in aStatus, return nsresult
|
||||
PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext& aPresContext,
|
||||
InnerTableReflowState& aState,
|
||||
nsSize* aMaxElementSize)
|
||||
@ -2518,6 +2555,7 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext& aPresContext,
|
||||
|
||||
nscoord x = aState.leftInset + kidMargin.left;
|
||||
nscoord y = aState.topInset + aState.y + topMargin;
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTIF IR: Reflow Pass 2 of frame %p\n", kidFrame);
|
||||
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status);
|
||||
// Did the child fit?
|
||||
if ((kidFrame != mFirstChild) && (desiredSize.height > kidAvailSize.height))
|
||||
@ -2800,6 +2838,7 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext& aPresContext,
|
||||
else
|
||||
mTableLayoutStrategy = new BasicTableLayoutStrategy(this, numCols);
|
||||
mTableLayoutStrategy->Initialize(aMaxElementSize);
|
||||
mColumnWidthsValid=PR_TRUE;
|
||||
}
|
||||
mTableLayoutStrategy->BalanceColumnWidths(mStyleContext, aReflowState, maxWidth);
|
||||
mColumnWidthsSet=PR_TRUE;
|
||||
@ -3024,11 +3063,10 @@ PRBool nsTableFrame::IsColumnWidthsSet()
|
||||
* Then we terminate that loop and start a second pass.
|
||||
* In the second pass, we build column and cell cache info.
|
||||
*/
|
||||
void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus
|
||||
)
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
NS_ASSERTION(nsnull==mPrevInFlow, "never ever call me on a continuing frame!");
|
||||
NS_ASSERTION(nsnull!=mCellMap, "never ever call me until the cell map is built!");
|
||||
@ -3124,6 +3162,20 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
|
||||
mColumnCacheValid=PR_TRUE;
|
||||
}
|
||||
|
||||
void nsTableFrame::InvalidateColumnWidths()
|
||||
{
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
|
||||
firstInFlow->mColumnWidthsValid=PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool nsTableFrame::IsColumnWidthsValid() const
|
||||
{
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
|
||||
return firstInFlow->mColumnWidthsValid;
|
||||
}
|
||||
|
||||
PRBool nsTableFrame::IsFirstPassValid() const
|
||||
{
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
|
@ -447,11 +447,16 @@ protected:
|
||||
/** returns PR_TRUE if the cached column info is still valid */
|
||||
virtual PRBool IsColumnCacheValid() const;
|
||||
|
||||
/** returns PR_TRUE if the cached column info is still valid */
|
||||
virtual PRBool IsColumnWidthsValid() const;
|
||||
|
||||
public:
|
||||
virtual void InvalidateFirstPassCache();
|
||||
|
||||
virtual void InvalidateColumnCache();
|
||||
|
||||
virtual void InvalidateColumnWidths();
|
||||
|
||||
protected:
|
||||
/** do post processing to setting up style information for the frame */
|
||||
NS_IMETHOD DidSetStyleContext(nsIPresContext& aPresContext);
|
||||
@ -600,9 +605,10 @@ private:
|
||||
PRInt32 *mColumnWidths; // widths of each column
|
||||
PRInt32 mColumnWidthsLength; // the number of column lengths this frame has allocated
|
||||
PRBool mColumnWidthsSet; // PR_TRUE if column widths have been set at least once
|
||||
PRBool mFirstPassValid; // PR_TRUE if first pass data is still legit
|
||||
PRBool mColumnCacheValid; // PR_TRUE if column cache info is still legit
|
||||
PRBool mCellMapValid; // PR_TRUE if cell map data is still legit
|
||||
PRBool mColumnWidthsValid; // PR_TRUE if column width data is still legit, PR_FALSE if it needs to be recalculated
|
||||
PRBool mFirstPassValid; // PR_TRUE if first pass data is still legit, PR_FALSE if it needs to be recalculated
|
||||
PRBool mColumnCacheValid; // PR_TRUE if column cache info is still legit, PR_FALSE if it needs to be recalculated
|
||||
PRBool mCellMapValid; // PR_TRUE if cell map data is still legit, PR_FALSE if it needs to be recalculated
|
||||
PRBool mIsInvariantWidth; // PR_TRUE if table width cannot change
|
||||
PRInt32 mColCount; // the number of columns in this table
|
||||
PRInt32 mEffectiveColCount; // the number of columns in this table adjusted for weird table attributes
|
||||
|
@ -35,7 +35,13 @@ NS_DEF_PTR(nsIStyleContext);
|
||||
static NS_DEFINE_IID(kIHTMLTableColElementIID, NS_IHTMLTABLECOLELEMENT_IID);
|
||||
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
static PRBool gsDebug = PR_FALSE;
|
||||
static PRBool gsDebugIR = PR_FALSE;
|
||||
#else
|
||||
static const PRBool gsDebug = PR_FALSE;
|
||||
static const PRBool gsDebugIR = PR_FALSE;
|
||||
#endif
|
||||
|
||||
nsTableColGroupFrame::nsTableColGroupFrame(nsIContent* aContent,
|
||||
nsIFrame* aParentFrame)
|
||||
@ -48,7 +54,7 @@ nsTableColGroupFrame::~nsTableColGroupFrame()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_IMETHODIMP
|
||||
nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
@ -75,7 +81,6 @@ nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChi
|
||||
PRInt32 colIndex = mStartColIndex + mColCount;
|
||||
((nsTableColFrame *)(kidFrame))->InitColFrame (colIndex, repeat);
|
||||
mColCount+= repeat;
|
||||
((nsTableColFrame *)kidFrame)->SetColumnIndex(colIndex);
|
||||
tableFrame->AddColumnFrame((nsTableColFrame *)kidFrame);
|
||||
}
|
||||
// colgroup's span attribute is how many columns the group represents
|
||||
@ -138,7 +143,7 @@ nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChi
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_IMETHODIMP
|
||||
nsTableColGroupFrame::AppendNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList)
|
||||
{
|
||||
nsIFrame* lastChild = LastFrame(mFirstChild);
|
||||
@ -171,38 +176,19 @@ NS_METHOD nsTableColGroupFrame::Paint(nsIPresContext& aPresContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// TODO: incremental reflow
|
||||
// today, we just throw away the column frames and start over every time
|
||||
// this is dumb, we should be able to maintain column frames and adjust incrementally
|
||||
NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
NS_ASSERTION(nsnull!=mContent, "bad state -- null content for frame");
|
||||
|
||||
nsresult rv=NS_OK;
|
||||
// for every content child that (is a column thingy and does not already have a frame)
|
||||
// create a frame and adjust it's style
|
||||
nsIFrame* kidFrame = nsnull;
|
||||
|
||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
||||
NS_ASSERTION(nsnull != aReflowState.reflowCommand, "null reflow command");
|
||||
|
||||
// Get the type of reflow command
|
||||
nsIReflowCommand::ReflowType reflowCmdType;
|
||||
aReflowState.reflowCommand->GetType(reflowCmdType);
|
||||
|
||||
// Currently we only expect appended reflow commands
|
||||
NS_ASSERTION(nsIReflowCommand::FrameAppended == reflowCmdType,
|
||||
"unexpected reflow command");
|
||||
|
||||
// Get the new column frames
|
||||
nsIFrame* childList;
|
||||
aReflowState.reflowCommand->GetChildFrame(childList);
|
||||
|
||||
// Append them to the child list
|
||||
AppendNewFrames(aPresContext, childList);
|
||||
InitNewFrames(aPresContext, childList);
|
||||
rv = IncrementalReflow(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
}
|
||||
|
||||
for (kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) {
|
||||
@ -228,9 +214,355 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
|
||||
aDesiredSize.maxElementSize->height=0;
|
||||
}
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableColGroupFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTCGF IR: IncrementalReflow\n");
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// determine if this frame is the target or not
|
||||
nsIFrame *target=nsnull;
|
||||
rv = aReflowState.reflowCommand->GetTarget(target);
|
||||
if ((PR_TRUE==NS_SUCCEEDED(rv)) && (nsnull!=target))
|
||||
{
|
||||
if (this==target)
|
||||
rv = IR_TargetIsMe(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
else
|
||||
{
|
||||
// Get the next frame in the reflow chain
|
||||
nsIFrame* nextFrame;
|
||||
aReflowState.reflowCommand->GetNext(nextFrame);
|
||||
rv = IR_TargetIsChild(aPresContext, aDesiredSize, aReflowState, aStatus, nextFrame);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableColGroupFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
nsIReflowCommand::ReflowType type;
|
||||
aReflowState.reflowCommand->GetType(type);
|
||||
nsIFrame *objectFrame;
|
||||
aReflowState.reflowCommand->GetChildFrame(objectFrame);
|
||||
const nsStyleDisplay *childDisplay;
|
||||
objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (PR_TRUE==gsDebugIR) printf("nTCGF IR: IncrementalReflow_TargetIsMe with type=%d\n", type);
|
||||
switch (type)
|
||||
{
|
||||
case nsIReflowCommand::FrameInserted :
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_ColInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
(nsTableColFrame*)objectFrame, PR_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame, PR_FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::FrameAppended :
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_ColAppended(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
(nsTableColFrame*)objectFrame);
|
||||
}
|
||||
else
|
||||
{ // no optimization to be done for Unknown frame types, so just reuse the Inserted method
|
||||
rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame, PR_FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
case nsIReflowCommand::FrameReplaced :
|
||||
|
||||
*/
|
||||
|
||||
case nsIReflowCommand::FrameRemoved :
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_ColRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
(nsTableColFrame*)objectFrame);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
rv = IR_UnknownFrameRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::StyleChanged :
|
||||
NS_NOTYETIMPLEMENTED("unimplemented reflow command type");
|
||||
rv = NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (PR_TRUE==gsDebugIR) printf("TCGF IR: StyleChanged not implemented.\n");
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::ContentChanged :
|
||||
NS_ASSERTION(PR_FALSE, "illegal reflow type: ContentChanged");
|
||||
rv = NS_ERROR_ILLEGAL_VALUE;
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::PullupReflow:
|
||||
case nsIReflowCommand::PushReflow:
|
||||
case nsIReflowCommand::CheckPullupReflow :
|
||||
case nsIReflowCommand::UserDefined :
|
||||
NS_NOTYETIMPLEMENTED("unimplemented reflow command type");
|
||||
rv = NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (PR_TRUE==gsDebugIR) printf("TCGF IR: reflow command not implemented.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableColGroupFrame::IR_ColInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableColFrame * aInsertedFrame,
|
||||
PRBool aReplace)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
PRBool adjustStartingColIndex=PR_FALSE;
|
||||
rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState, aStatus, aInsertedFrame, aReplace);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
PRInt32 startingColIndex=mStartColIndex;
|
||||
startingColIndex += GetColumnCount(); // has the side effect of resetting all column indexes
|
||||
|
||||
nsIFrame *childFrame=nsnull;
|
||||
GetNextSibling(childFrame);
|
||||
while ((NS_SUCCEEDED(rv)) && (nsnull!=childFrame))
|
||||
{
|
||||
const nsStyleDisplay *display;
|
||||
childFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay)
|
||||
{
|
||||
startingColIndex += ((nsTableColGroupFrame *)childFrame)->SetStartColumnIndex(startingColIndex);
|
||||
}
|
||||
rv = childFrame->GetNextSibling(childFrame);
|
||||
}
|
||||
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame))
|
||||
tableFrame->InvalidateColumnCache();
|
||||
//XXX: what we want to do here is determine if the new COL information changes anything about layout
|
||||
// if not, we can skip rebalancing the columns
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableColGroupFrame::IR_ColAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableColFrame * aAppendedFrame)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
PRBool adjustStartingColIndex=PR_FALSE;
|
||||
rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState, aStatus, aAppendedFrame, PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
PRInt32 startingColIndex=mStartColIndex;
|
||||
// this could be optimized
|
||||
startingColIndex += GetColumnCount(); // has the side effect of resetting all column indexes
|
||||
|
||||
nsIFrame *childFrame=nsnull;
|
||||
GetNextSibling(childFrame);
|
||||
while ((NS_SUCCEEDED(rv)) && (nsnull!=childFrame))
|
||||
{
|
||||
const nsStyleDisplay *display;
|
||||
childFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay)
|
||||
{
|
||||
startingColIndex += ((nsTableColGroupFrame *)childFrame)->SetStartColumnIndex(startingColIndex);
|
||||
}
|
||||
rv = childFrame->GetNextSibling(childFrame);
|
||||
}
|
||||
|
||||
// today we need to rebuild the whole column cache
|
||||
// if the table frame is ever recoded to build the column cache incrementally, we could take
|
||||
// advantage of that here.
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame))
|
||||
tableFrame->InvalidateColumnCache();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_METHOD nsTableColGroupFrame::IR_ColRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableColFrame * aDeletedFrame)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
PRInt32 startingColIndex=mStartColIndex;
|
||||
nsIFrame *childFrame=mFirstChild;
|
||||
nsIFrame *prevSib=nsnull;
|
||||
while ((NS_SUCCEEDED(rv)) && (nsnull!=childFrame))
|
||||
{
|
||||
if (childFrame==aDeletedFrame)
|
||||
{
|
||||
nsIFrame *deleteFrameNextSib=nsnull;
|
||||
aDeletedFrame->GetNextSibling(deleteFrameNextSib);
|
||||
if (nsnull!=prevSib)
|
||||
prevSib->SetNextSibling(deleteFrameNextSib);
|
||||
else
|
||||
mFirstChild = deleteFrameNextSib;
|
||||
startingColIndex += GetColumnCount(); // resets all column indexes
|
||||
}
|
||||
const nsStyleDisplay *display;
|
||||
childFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay)
|
||||
{
|
||||
// we've removed aDeletedFrame, now adjust the starting col index of all subsequent col groups
|
||||
startingColIndex += ((nsTableColGroupFrame *)childFrame)->SetStartColumnIndex(startingColIndex);
|
||||
}
|
||||
prevSib=childFrame;
|
||||
rv = childFrame->GetNextSibling(childFrame);
|
||||
}
|
||||
|
||||
// today we need to rebuild the whole column cache
|
||||
// if the table frame is ever recoded to build the column cache incrementally, we could take
|
||||
// advantage of that here.
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame))
|
||||
tableFrame->InvalidateColumnCache();
|
||||
return rv;
|
||||
}
|
||||
|
||||
//XXX: handle aReplace
|
||||
NS_METHOD nsTableColGroupFrame::IR_UnknownFrameInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace)
|
||||
{
|
||||
nsIReflowCommand::ReflowType type;
|
||||
aReflowState.reflowCommand->GetType(type);
|
||||
// we have a generic frame that gets inserted but doesn't effect reflow
|
||||
// hook it up then ignore it
|
||||
if (nsIReflowCommand::FrameAppended==type)
|
||||
{ // frameAppended reflow -- find the last child and make aInsertedFrame its next sibling
|
||||
if (PR_TRUE==gsDebugIR) printf("TCGF IR: FrameAppended adding unknown frame type.\n");
|
||||
nsIFrame *lastChild=mFirstChild;
|
||||
nsIFrame *nextChild=mFirstChild;
|
||||
while (nsnull!=nextChild)
|
||||
{
|
||||
lastChild=nextChild;
|
||||
nextChild->GetNextSibling(nextChild);
|
||||
}
|
||||
if (nsnull==lastChild)
|
||||
mFirstChild = aInsertedFrame;
|
||||
else
|
||||
lastChild->SetNextSibling(aInsertedFrame);
|
||||
}
|
||||
else
|
||||
{ // frameInserted reflow -- hook up aInsertedFrame as prevSibling's next sibling,
|
||||
// and be sure to hook in aInsertedFrame's nextSibling (from prevSibling)
|
||||
if (PR_TRUE==gsDebugIR) printf("TCGF IR: FrameInserted adding unknown frame type.\n");
|
||||
nsIFrame *prevSibling=nsnull;
|
||||
nsresult rv = aReflowState.reflowCommand->GetPrevSiblingFrame(prevSibling);
|
||||
if (NS_SUCCEEDED(rv) && (nsnull!=prevSibling))
|
||||
{
|
||||
nsIFrame *nextSibling=nsnull;
|
||||
prevSibling->GetNextSibling(nextSibling);
|
||||
prevSibling->SetNextSibling(aInsertedFrame);
|
||||
aInsertedFrame->SetNextSibling(nextSibling);
|
||||
}
|
||||
else
|
||||
{
|
||||
nsIFrame *nextSibling=nsnull;
|
||||
if (nsnull!=mFirstChild)
|
||||
mFirstChild->GetNextSibling(nextSibling);
|
||||
mFirstChild = aInsertedFrame;
|
||||
aInsertedFrame->SetNextSibling(nextSibling);
|
||||
}
|
||||
}
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableColGroupFrame::IR_UnknownFrameRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aRemovedFrame)
|
||||
{
|
||||
// we have a generic frame that gets removed but doesn't effect reflow
|
||||
// unhook it then ignore it
|
||||
if (PR_TRUE==gsDebugIR) printf("TCGF IR: FrameRemoved removing unknown frame type.\n");
|
||||
nsIFrame *prevChild=nsnull;
|
||||
nsIFrame *nextChild=mFirstChild;
|
||||
while (nextChild!=aRemovedFrame)
|
||||
{
|
||||
prevChild=nextChild;
|
||||
nextChild->GetNextSibling(nextChild);
|
||||
}
|
||||
nextChild=nsnull;
|
||||
aRemovedFrame->GetNextSibling(nextChild);
|
||||
if (nsnull==prevChild) // objectFrame was first child
|
||||
mFirstChild = nextChild;
|
||||
else
|
||||
prevChild->SetNextSibling(nextChild);
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableColGroupFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aNextFrame)
|
||||
{
|
||||
nsresult rv;
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTCGF IR: IR_TargetIsChild\n");
|
||||
|
||||
// Remember the old col count
|
||||
const PRInt32 oldColCount = GetColumnCount();
|
||||
|
||||
// Pass along the reflow command
|
||||
nsHTMLReflowMetrics desiredSize(nsnull);
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aNextFrame,
|
||||
aReflowState,
|
||||
aReflowState.maxSize);
|
||||
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame))
|
||||
{
|
||||
// compare the new col count to the old col count.
|
||||
// If they are the same, we just need to rebalance column widths
|
||||
// If they differ, we need to fix up other column groups and the column cache
|
||||
const PRInt32 newColCount = GetColumnCount(); // this will set the new column indexes if necessary
|
||||
if (oldColCount==newColCount)
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
else
|
||||
tableFrame->InvalidateColumnCache();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Subclass hook for style post processing
|
||||
NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext& aPresContext)
|
||||
{
|
||||
|
@ -102,11 +102,63 @@ protected:
|
||||
* Since we need to know the full column structure before the COLS attribute
|
||||
* can be interpreted, we can't just use DidSetStyleContext
|
||||
*/
|
||||
NS_METHOD SetStyleContextForFirstPass(nsIPresContext& aPresContext);
|
||||
NS_IMETHOD SetStyleContextForFirstPass(nsIPresContext& aPresContext);
|
||||
|
||||
NS_IMETHOD InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList);
|
||||
NS_IMETHOD AppendNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList);
|
||||
|
||||
|
||||
NS_IMETHOD IncrementalReflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD IR_ColInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableColFrame * aInsertedFrame,
|
||||
PRBool aReplace);
|
||||
|
||||
NS_IMETHOD IR_ColAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableColFrame * aAppendedFrame);
|
||||
|
||||
NS_IMETHOD IR_ColRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableColFrame * aDeletedFrame);
|
||||
|
||||
NS_IMETHOD IR_UnknownFrameInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace);
|
||||
|
||||
NS_IMETHOD IR_UnknownFrameRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aRemovedFrame);
|
||||
|
||||
NS_IMETHOD IR_TargetIsChild(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aNextFrame);
|
||||
|
||||
|
||||
// data members
|
||||
|
||||
nsresult InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList);
|
||||
nsresult AppendNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList);
|
||||
|
||||
PRInt32 mColCount;
|
||||
|
||||
/** the starting column index this col group represents. Must be >= 0. */
|
||||
|
@ -52,7 +52,6 @@ static const PRBool gsDebug = PR_FALSE;
|
||||
static const PRBool gsDebugCLD = PR_FALSE;
|
||||
static const PRBool gsDebugNT = PR_FALSE;
|
||||
static const PRBool gsDebugIR = PR_FALSE;
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef max
|
||||
@ -271,6 +270,7 @@ nsTableFrame::nsTableFrame(nsIContent* aContent, nsIFrame* aParentFrame)
|
||||
mColCache(nsnull),
|
||||
mTableLayoutStrategy(nsnull),
|
||||
mFirstPassValid(PR_FALSE),
|
||||
mColumnWidthsValid(PR_FALSE),
|
||||
mColumnCacheValid(PR_FALSE),
|
||||
mCellMapValid(PR_TRUE),
|
||||
mIsInvariantWidth(PR_FALSE)
|
||||
@ -1565,7 +1565,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
|
||||
if (PR_TRUE==gsDebug) printf("TIF Reflow: needs reflow\n");
|
||||
if (eReflowReason_Initial!=aReflowState.reason && PR_FALSE==IsCellMapValid())
|
||||
{
|
||||
if (PR_TRUE==gsDebug) printf("TIF Reflow: not initial reflow, so resetting cell map.\n");
|
||||
if (PR_TRUE==gsDebug) printf("TIF Reflow: cell map invalid, rebuilding...\n");
|
||||
if (nsnull!=mCellMap)
|
||||
delete mCellMap;
|
||||
mCellMap = new nsCellMap(0,0);
|
||||
@ -1574,14 +1574,17 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
|
||||
}
|
||||
if (PR_FALSE==IsFirstPassValid())
|
||||
{
|
||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: first pass is invalid\n");
|
||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: first pass is invalid, rebuilding...\n");
|
||||
rv = ResizeReflowPass1(aPresContext, aDesiredSize, aReflowState, aStatus, nsnull, aReflowState.reason);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
needsRecalc=PR_TRUE;
|
||||
}
|
||||
if (PR_FALSE==IsColumnCacheValid())
|
||||
{
|
||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: column cache is invalid, rebuilding...\n");
|
||||
needsRecalc=PR_TRUE;
|
||||
}
|
||||
if (PR_TRUE==needsRecalc)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF Reflow: needs recalc.\n");
|
||||
@ -1590,11 +1593,20 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF Reflow: Re-init layout strategy\n");
|
||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize);
|
||||
mColumnWidthsValid=PR_TRUE;
|
||||
}
|
||||
BuildColumnCache(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
RecalcLayoutData(); // Recalculate Layout Dependencies
|
||||
}
|
||||
|
||||
if (PR_FALSE==IsColumnWidthsValid())
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF Reflow: Re-init layout strategy\n");
|
||||
if (nsnull!=mTableLayoutStrategy)
|
||||
{
|
||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize);
|
||||
mColumnWidthsValid=PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (nsnull==mPrevInFlow)
|
||||
{ // only do this for a first-in-flow table frame
|
||||
@ -1707,6 +1719,7 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext& aPresContext,
|
||||
PRInt32 yCoord = y;
|
||||
if (NS_UNCONSTRAINEDSIZE!=yCoord)
|
||||
yCoord+= topInset;
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTIF IR: Reflow Pass 1 of frame %p\n", kidFrame);
|
||||
ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, aStatus);
|
||||
|
||||
// Place the child since some of its content fit in us.
|
||||
@ -1875,7 +1888,8 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
InnerTableReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
nsresult rv = NS_FRAME_COMPLETE;
|
||||
nsresult rv = NS_OK;
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
nsIReflowCommand::ReflowType type;
|
||||
aReflowState.reflowState.reflowCommand->GetType(type);
|
||||
nsIFrame *objectFrame;
|
||||
@ -1962,7 +1976,7 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
case nsIReflowCommand::UserDefined :
|
||||
NS_NOTYETIMPLEMENTED("unimplemented reflow command type");
|
||||
rv = NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (PR_TRUE==gsDebugIR) printf("TOF IR: reflow command not implemented.\n");
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF IR: reflow command not implemented.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2172,6 +2186,13 @@ NS_METHOD nsTableFrame::IR_RowGroupInserted(nsIPresContext& aPresContext,
|
||||
nsresult rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState,
|
||||
aStatus, (nsIFrame*)aInsertedFrame, aReplace);
|
||||
// inserting the rowgroup only effects reflow if the rowgroup includes at least one row
|
||||
PRInt32 rowCount;
|
||||
aInsertedFrame->GetRowCount(rowCount);
|
||||
if (0>rowCount)
|
||||
{ // for now we will assume that if there are rows, then there are cells and we need to recalc table info
|
||||
InvalidateCellMap();
|
||||
InvalidateColumnCache();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -2189,6 +2210,7 @@ NS_METHOD nsTableFrame::IR_RowGroupAppended(nsIPresContext& aPresContext,
|
||||
return rv;
|
||||
|
||||
// account for the cells in the rows that are children of aAppendedFrame
|
||||
// this will add the content of the rowgroup to the cell map
|
||||
rv = DidAppendRowGroup((nsTableRowGroupFrame*)aAppendedFrame);
|
||||
|
||||
// do a pass-1 layout of all the cells in all the rows of the rowgroup
|
||||
@ -2198,7 +2220,8 @@ NS_METHOD nsTableFrame::IR_RowGroupAppended(nsIPresContext& aPresContext,
|
||||
return rv;
|
||||
|
||||
// if any column widths have to change due to this, rebalance column widths
|
||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize);
|
||||
//XXX need to calculate this, but for now just do it
|
||||
InvalidateColumnWidths();
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -2210,6 +2233,20 @@ NS_METHOD nsTableFrame::IR_RowGroupRemoved(nsIPresContext& aPresContext,
|
||||
nsTableRowGroupFrame * aDeletedFrame)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
rv = IR_UnknownFrameRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
aDeletedFrame);
|
||||
PRInt32 rowCount=0;
|
||||
aDeletedFrame->GetRowCount(rowCount);
|
||||
if (0>rowCount)
|
||||
{ // for now we will assume that if there are rows, then there are cells and we need to recalc table info
|
||||
InvalidateCellMap();
|
||||
InvalidateColumnCache();
|
||||
}
|
||||
// if any column widths have to change due to this, rebalance column widths
|
||||
//XXX need to calculate this, but for now just do it
|
||||
InvalidateColumnWidths();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -2262,7 +2299,8 @@ NS_METHOD nsTableFrame::IR_UnknownFrameInserted(nsIPresContext& aPresCont
|
||||
aInsertedFrame->SetNextSibling(nextSibling);
|
||||
}
|
||||
}
|
||||
return NS_FRAME_COMPLETE;
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableFrame::IR_UnknownFrameRemoved(nsIPresContext& aPresContext,
|
||||
@ -2287,7 +2325,8 @@ NS_METHOD nsTableFrame::IR_UnknownFrameRemoved(nsIPresContext& aPresConte
|
||||
mFirstChild = nextChild;
|
||||
else
|
||||
prevChild->SetNextSibling(nextChild);
|
||||
return NS_FRAME_COMPLETE;
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return NS_OK;;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
|
||||
@ -2322,10 +2361,7 @@ NS_METHOD nsTableFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
|
||||
// XXX For the time being just fall through and treat it like a
|
||||
// pass 2 reflow...
|
||||
// calling intialize here resets all the cached info based on new table content
|
||||
if (nsnull!=mTableLayoutStrategy)
|
||||
{
|
||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize);
|
||||
}
|
||||
InvalidateColumnWidths();
|
||||
#else
|
||||
// XXX Hack...
|
||||
AdjustSiblingsAfterReflow(&aPresContext, aReflowState, aNextFrame, desiredSize.height -
|
||||
@ -2459,6 +2495,7 @@ void nsTableFrame::PlaceChild(nsIPresContext& aPresContext,
|
||||
* @return true if we successfully reflowed all the mapped children and false
|
||||
* otherwise, e.g. we pushed children to the next in flow
|
||||
*/
|
||||
// XXX: this interface should change to pass in aStatus, return nsresult
|
||||
PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext& aPresContext,
|
||||
InnerTableReflowState& aState,
|
||||
nsSize* aMaxElementSize)
|
||||
@ -2518,6 +2555,7 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext& aPresContext,
|
||||
|
||||
nscoord x = aState.leftInset + kidMargin.left;
|
||||
nscoord y = aState.topInset + aState.y + topMargin;
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTIF IR: Reflow Pass 2 of frame %p\n", kidFrame);
|
||||
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status);
|
||||
// Did the child fit?
|
||||
if ((kidFrame != mFirstChild) && (desiredSize.height > kidAvailSize.height))
|
||||
@ -2800,6 +2838,7 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext& aPresContext,
|
||||
else
|
||||
mTableLayoutStrategy = new BasicTableLayoutStrategy(this, numCols);
|
||||
mTableLayoutStrategy->Initialize(aMaxElementSize);
|
||||
mColumnWidthsValid=PR_TRUE;
|
||||
}
|
||||
mTableLayoutStrategy->BalanceColumnWidths(mStyleContext, aReflowState, maxWidth);
|
||||
mColumnWidthsSet=PR_TRUE;
|
||||
@ -3024,11 +3063,10 @@ PRBool nsTableFrame::IsColumnWidthsSet()
|
||||
* Then we terminate that loop and start a second pass.
|
||||
* In the second pass, we build column and cell cache info.
|
||||
*/
|
||||
void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus
|
||||
)
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
NS_ASSERTION(nsnull==mPrevInFlow, "never ever call me on a continuing frame!");
|
||||
NS_ASSERTION(nsnull!=mCellMap, "never ever call me until the cell map is built!");
|
||||
@ -3124,6 +3162,20 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
|
||||
mColumnCacheValid=PR_TRUE;
|
||||
}
|
||||
|
||||
void nsTableFrame::InvalidateColumnWidths()
|
||||
{
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
|
||||
firstInFlow->mColumnWidthsValid=PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool nsTableFrame::IsColumnWidthsValid() const
|
||||
{
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
|
||||
return firstInFlow->mColumnWidthsValid;
|
||||
}
|
||||
|
||||
PRBool nsTableFrame::IsFirstPassValid() const
|
||||
{
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
|
@ -447,11 +447,16 @@ protected:
|
||||
/** returns PR_TRUE if the cached column info is still valid */
|
||||
virtual PRBool IsColumnCacheValid() const;
|
||||
|
||||
/** returns PR_TRUE if the cached column info is still valid */
|
||||
virtual PRBool IsColumnWidthsValid() const;
|
||||
|
||||
public:
|
||||
virtual void InvalidateFirstPassCache();
|
||||
|
||||
virtual void InvalidateColumnCache();
|
||||
|
||||
virtual void InvalidateColumnWidths();
|
||||
|
||||
protected:
|
||||
/** do post processing to setting up style information for the frame */
|
||||
NS_IMETHOD DidSetStyleContext(nsIPresContext& aPresContext);
|
||||
@ -600,9 +605,10 @@ private:
|
||||
PRInt32 *mColumnWidths; // widths of each column
|
||||
PRInt32 mColumnWidthsLength; // the number of column lengths this frame has allocated
|
||||
PRBool mColumnWidthsSet; // PR_TRUE if column widths have been set at least once
|
||||
PRBool mFirstPassValid; // PR_TRUE if first pass data is still legit
|
||||
PRBool mColumnCacheValid; // PR_TRUE if column cache info is still legit
|
||||
PRBool mCellMapValid; // PR_TRUE if cell map data is still legit
|
||||
PRBool mColumnWidthsValid; // PR_TRUE if column width data is still legit, PR_FALSE if it needs to be recalculated
|
||||
PRBool mFirstPassValid; // PR_TRUE if first pass data is still legit, PR_FALSE if it needs to be recalculated
|
||||
PRBool mColumnCacheValid; // PR_TRUE if column cache info is still legit, PR_FALSE if it needs to be recalculated
|
||||
PRBool mCellMapValid; // PR_TRUE if cell map data is still legit, PR_FALSE if it needs to be recalculated
|
||||
PRBool mIsInvariantWidth; // PR_TRUE if table width cannot change
|
||||
PRInt32 mColCount; // the number of columns in this table
|
||||
PRInt32 mEffectiveColCount; // the number of columns in this table adjusted for weird table attributes
|
||||
|
Loading…
Reference in New Issue
Block a user