зеркало из https://github.com/mozilla/pjs.git
Changed to new command reflow handling
This commit is contained in:
Родитель
131a39d47b
Коммит
b4f91e984d
|
@ -121,6 +121,151 @@ nsTableRowFrame::Init(nsIPresContext& aPresContext,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// Helper function. It marks the table frame as dirty and generates
|
||||
// a reflow command
|
||||
nsresult
|
||||
nsTableRowFrame::AddTableDirtyReflowCommand(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIFrame* aTableFrame)
|
||||
{
|
||||
nsFrameState frameState;
|
||||
nsIFrame* tableParentFrame;
|
||||
nsIReflowCommand* reflowCmd;
|
||||
nsresult rv;
|
||||
|
||||
// Mark the table frame as dirty
|
||||
aTableFrame->GetFrameState(&frameState);
|
||||
frameState |= NS_FRAME_IS_DIRTY;
|
||||
aTableFrame->SetFrameState(frameState);
|
||||
|
||||
// Target the reflow comamnd at its parent frame
|
||||
aTableFrame->GetParent(&tableParentFrame);
|
||||
rv = NS_NewHTMLReflowCommand(&reflowCmd, tableParentFrame,
|
||||
nsIReflowCommand::ReflowDirty);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Add the reflow command
|
||||
rv = aPresShell.AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableRowFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
// Append the frames
|
||||
mFrames.AppendFrames(nsnull, aFrameList);
|
||||
|
||||
// Add the new cell frames to the table
|
||||
nsTableFrame *tableFrame = nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
for (nsIFrame* childFrame = aFrameList; childFrame; childFrame->GetNextSibling(&childFrame)) {
|
||||
const nsStyleDisplay *display;
|
||||
childFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display));
|
||||
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == display->mDisplay) {
|
||||
// Add the cell to the cell map
|
||||
PRInt32 colIndex = tableFrame->AddCellToTable((nsTableCellFrame*)childFrame,
|
||||
GetRowIndex());
|
||||
|
||||
// Initialize the cell frame and give it its column index
|
||||
((nsTableCellFrame*)childFrame)->InitCellFrame(colIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// Reflow the new frames. They're already marked dirty, so generate a reflow
|
||||
// command that tells us to reflow our dirty child frames
|
||||
nsIReflowCommand* reflowCmd;
|
||||
|
||||
if (NS_SUCCEEDED(NS_NewHTMLReflowCommand(&reflowCmd, this,
|
||||
nsIReflowCommand::ReflowDirty))) {
|
||||
aPresShell.AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableRowFrame::InsertFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
// Get the table frame
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
|
||||
// Insert the frames
|
||||
mFrames.InsertFrames(nsnull, aPrevFrame, aFrameList);
|
||||
|
||||
// We need to rebuild the cell map, because currently we can't insert
|
||||
// new frames except at the end (append)
|
||||
tableFrame->InvalidateCellMap();
|
||||
|
||||
// We should try and avoid doing a pass1 reflow on all the cells and just
|
||||
// do it for the newly added frames, but we need to add these frames to the
|
||||
// cell map before we reflow them
|
||||
tableFrame->InvalidateFirstPassCache();
|
||||
|
||||
// Because the number of columns may have changed invalidate the column
|
||||
// cache. Note that this has the side effect of recomputing the column
|
||||
// widths, so we don't need to call InvalidateColumnWidths()
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
// Generate a reflow command so we reflow the table itself. This will
|
||||
// do a pass-1 reflow of all the rows including any rows we just added
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableRowFrame::RemoveFrame(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
// Get the table frame
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
|
||||
#if 0
|
||||
// XXX Currently we can't incrementally remove cells from the cell map
|
||||
PRInt32 colIndex;
|
||||
aDeletedFrame->GetColIndex(colIndex);
|
||||
tableFrame->RemoveCellFromTable(aOldFrame, GetRowIndex());
|
||||
|
||||
// Remove the frame and destroy it
|
||||
mFrames.DestroyFrame(aPresContext, (nsIFrame*)aOldFrame);
|
||||
|
||||
// XXX Reflow the row
|
||||
|
||||
#else
|
||||
// Remove the frame and destroy it
|
||||
mFrames.DestroyFrame(aPresContext, aOldFrame);
|
||||
|
||||
// We need to rebuild the cell map, because currently we can't incrementally
|
||||
// remove rows
|
||||
tableFrame->InvalidateCellMap();
|
||||
|
||||
// Because the number of columns may have changed invalidate the column
|
||||
// cache. Note that this has the side effect of recomputing the column
|
||||
// widths, so we don't need to call InvalidateColumnWidths()
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
// Because we haven't added any new frames we don't need to do a pass1
|
||||
// reflow. Just generate a reflow command so we reflow the table itself
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableRowFrame::InitChildren()
|
||||
{
|
||||
|
@ -550,12 +695,14 @@ void nsTableRowFrame::PlaceChild(nsIPresContext& aPresContext,
|
|||
|
||||
/**
|
||||
* Called for a resize reflow. Typically because the column widths have
|
||||
* changed. Reflows all the existing table cell frames
|
||||
* changed. Reflows all the existing table cell frames unless aDirtyOnly
|
||||
* is PR_TRUE in which case only reflow the dirty frames
|
||||
*/
|
||||
NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
nsReflowStatus& aStatus,
|
||||
PRBool aDirtyOnly)
|
||||
{
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
if (nsnull == mFrames.FirstChild()) {
|
||||
|
@ -592,177 +739,215 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
|||
// Reflow each of our existing cell frames
|
||||
nsIFrame* kidFrame = iter.First();
|
||||
while (nsnull != kidFrame) {
|
||||
const nsStyleDisplay *kidDisplay;
|
||||
kidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)kidDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay) {
|
||||
PRInt32 cellColIndex;
|
||||
((nsTableCellFrame *)kidFrame)->GetColIndex(cellColIndex);
|
||||
cellColSpan = aReflowState.tableFrame->GetEffectiveColSpan(cellColIndex,
|
||||
((nsTableCellFrame *)kidFrame));
|
||||
nsMargin kidMargin;
|
||||
aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame,kidMargin);
|
||||
if (kidMargin.top > maxCellTopMargin)
|
||||
maxCellTopMargin = kidMargin.top;
|
||||
if (kidMargin.bottom > maxCellBottomMargin)
|
||||
maxCellBottomMargin = kidMargin.bottom;
|
||||
|
||||
// Compute the x-origin for the child, taking into account straddlers (cells from prior
|
||||
// rows with rowspans > 1)
|
||||
// if this cell is not immediately adjacent to the previous cell, factor in missing col info
|
||||
if (iter.IsLeftToRight()) {
|
||||
if (prevColIndex != (cellColIndex - 1)) {
|
||||
for (PRInt32 colIndex = prevColIndex + 1; cellColIndex > colIndex; colIndex++) {
|
||||
aReflowState.x += aReflowState.tableFrame->GetColumnWidth(colIndex);
|
||||
if (aReflowState.tableFrame->GetNumCellsOriginatingIn(colIndex) > 0) {
|
||||
aReflowState.x += cellSpacingX;
|
||||
// Get the frame state bits
|
||||
nsFrameState frameState;
|
||||
kidFrame->GetFrameState(&frameState);
|
||||
|
||||
// See if we should only reflow the dirty child frames
|
||||
PRBool doReflowChild = PR_TRUE;
|
||||
if (aDirtyOnly) {
|
||||
if ((frameState & NS_FRAME_IS_DIRTY) == 0) {
|
||||
doReflowChild = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Reflow the child frame
|
||||
if (doReflowChild) {
|
||||
const nsStyleDisplay *kidDisplay;
|
||||
kidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)kidDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay) {
|
||||
PRInt32 cellColIndex;
|
||||
((nsTableCellFrame *)kidFrame)->GetColIndex(cellColIndex);
|
||||
cellColSpan = aReflowState.tableFrame->GetEffectiveColSpan(cellColIndex,
|
||||
((nsTableCellFrame *)kidFrame));
|
||||
nsMargin kidMargin;
|
||||
aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame,kidMargin);
|
||||
if (kidMargin.top > maxCellTopMargin)
|
||||
maxCellTopMargin = kidMargin.top;
|
||||
if (kidMargin.bottom > maxCellBottomMargin)
|
||||
maxCellBottomMargin = kidMargin.bottom;
|
||||
|
||||
// Compute the x-origin for the child, taking into account straddlers (cells from prior
|
||||
// rows with rowspans > 1)
|
||||
// if this cell is not immediately adjacent to the previous cell, factor in missing col info
|
||||
if (iter.IsLeftToRight()) {
|
||||
if (prevColIndex != (cellColIndex - 1)) {
|
||||
for (PRInt32 colIndex = prevColIndex + 1; cellColIndex > colIndex; colIndex++) {
|
||||
aReflowState.x += aReflowState.tableFrame->GetColumnWidth(colIndex);
|
||||
if (aReflowState.tableFrame->GetNumCellsOriginatingIn(colIndex) > 0) {
|
||||
aReflowState.x += cellSpacingX;
|
||||
}
|
||||
if (PR_TRUE==gsDebug)
|
||||
printf(" Row: in loop, aReflowState.x set to %d from cellSpacing %d and col width %d\n",
|
||||
aReflowState.x, cellSpacingX, aReflowState.tableFrame->GetColumnWidth(colIndex));
|
||||
}
|
||||
if (PR_TRUE==gsDebug)
|
||||
printf(" Row: in loop, aReflowState.x set to %d from cellSpacing %d and col width %d\n",
|
||||
aReflowState.x, cellSpacingX, aReflowState.tableFrame->GetColumnWidth(colIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (prevColIndex != cellColIndex + cellColSpan) {
|
||||
PRInt32 lastCol = cellColIndex + cellColSpan - 1;
|
||||
for (PRInt32 colIndex = prevColIndex - 1; colIndex > lastCol; colIndex--) {
|
||||
aReflowState.x += aReflowState.tableFrame->GetColumnWidth(colIndex);
|
||||
if (aReflowState.tableFrame->GetNumCellsOriginatingIn(colIndex) > 0) {
|
||||
aReflowState.x += cellSpacingX;
|
||||
else {
|
||||
if (prevColIndex != cellColIndex + cellColSpan) {
|
||||
PRInt32 lastCol = cellColIndex + cellColSpan - 1;
|
||||
for (PRInt32 colIndex = prevColIndex - 1; colIndex > lastCol; colIndex--) {
|
||||
aReflowState.x += aReflowState.tableFrame->GetColumnWidth(colIndex);
|
||||
if (aReflowState.tableFrame->GetNumCellsOriginatingIn(colIndex) > 0) {
|
||||
aReflowState.x += cellSpacingX;
|
||||
}
|
||||
if (PR_TRUE==gsDebug)
|
||||
printf(" Row: in loop, aReflowState.x set to %d from cellSpacing %d and col width %d\n",
|
||||
aReflowState.x, cellSpacingX, aReflowState.tableFrame->GetColumnWidth(colIndex));
|
||||
}
|
||||
if (PR_TRUE==gsDebug)
|
||||
printf(" Row: in loop, aReflowState.x set to %d from cellSpacing %d and col width %d\n",
|
||||
aReflowState.x, cellSpacingX, aReflowState.tableFrame->GetColumnWidth(colIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aReflowState.x += cellSpacingX;
|
||||
if (PR_TRUE==gsDebug) printf(" Row: past loop, aReflowState.x set to %d\n", aReflowState.x);
|
||||
|
||||
// at this point, we know the column widths.
|
||||
// so we get the avail width from the known column widths
|
||||
nscoord availWidth = 0;
|
||||
for (PRInt32 numColSpan=0; numColSpan<cellColSpan; numColSpan++) {
|
||||
availWidth += aReflowState.tableFrame->GetColumnWidth(cellColIndex+numColSpan);
|
||||
if ((numColSpan != 0) && (aReflowState.tableFrame->GetNumCellsOriginatingIn(cellColIndex + numColSpan) > 0)) {
|
||||
availWidth += cellSpacingX;
|
||||
|
||||
aReflowState.x += cellSpacingX;
|
||||
if (PR_TRUE==gsDebug) printf(" Row: past loop, aReflowState.x set to %d\n", aReflowState.x);
|
||||
|
||||
// at this point, we know the column widths.
|
||||
// so we get the avail width from the known column widths
|
||||
nscoord availWidth = 0;
|
||||
for (PRInt32 numColSpan=0; numColSpan<cellColSpan; numColSpan++) {
|
||||
availWidth += aReflowState.tableFrame->GetColumnWidth(cellColIndex+numColSpan);
|
||||
if ((numColSpan != 0) && (aReflowState.tableFrame->GetNumCellsOriginatingIn(cellColIndex + numColSpan) > 0)) {
|
||||
availWidth += cellSpacingX;
|
||||
}
|
||||
if (PR_TRUE==gsDebug) {
|
||||
printf(" Row: in loop, availWidth set to %d from colIndex %d width %d and cellSpacing\n",
|
||||
availWidth, cellColIndex, aReflowState.tableFrame->GetColumnWidth(cellColIndex+numColSpan));
|
||||
}
|
||||
}
|
||||
if (PR_TRUE==gsDebug) {
|
||||
printf(" Row: in loop, availWidth set to %d from colIndex %d width %d and cellSpacing\n",
|
||||
availWidth, cellColIndex, aReflowState.tableFrame->GetColumnWidth(cellColIndex+numColSpan));
|
||||
}
|
||||
}
|
||||
if (PR_TRUE==gsDebug) printf(" Row: availWidth for this cell is %d\n", availWidth);
|
||||
// remember the rightmost (ltr) or leftmost (rtl) column this cell spans into
|
||||
prevColIndex = (iter.IsLeftToRight()) ? cellColIndex + (cellColSpan - 1) : cellColIndex;
|
||||
nsHTMLReflowMetrics desiredSize(pKidMaxElementSize);
|
||||
if (PR_TRUE==gsDebug) printf(" Row: availWidth for this cell is %d\n", availWidth);
|
||||
// remember the rightmost (ltr) or leftmost (rtl) column this cell spans into
|
||||
prevColIndex = (iter.IsLeftToRight()) ? cellColIndex + (cellColSpan - 1) : cellColIndex;
|
||||
nsHTMLReflowMetrics desiredSize(pKidMaxElementSize);
|
||||
|
||||
// If the available width is the same as last time we reflowed the cell,
|
||||
// then just use the previous desired size and max element size.
|
||||
// if we need the max-element-size we don't need to reflow.
|
||||
// we just grab it from the cell frame which remembers it (see the else clause below).
|
||||
// Note: we can't do that optimization if our height is constrained or the
|
||||
// cell frame has a next-in-flow
|
||||
nsIFrame* kidNextInFlow;
|
||||
kidFrame->GetNextInFlow(&kidNextInFlow);
|
||||
if ((aReflowState.reflowState.availableHeight != NS_UNCONSTRAINEDSIZE) ||
|
||||
(availWidth != ((nsTableCellFrame *)kidFrame)->GetPriorAvailWidth()) ||
|
||||
(nsnull != kidNextInFlow))
|
||||
{
|
||||
// Reflow the cell to fit the available height
|
||||
nsSize kidAvailSize(availWidth, aReflowState.reflowState.availableHeight);
|
||||
nsSize kidMaxElementSize(0,0);
|
||||
|
||||
// If the available width is the same as last time we reflowed the cell,
|
||||
// then just use the previous desired size and max element size.
|
||||
// if we need the max-element-size we don't need to reflow.
|
||||
// we just grab it from the cell frame which remembers it (see the else clause below).
|
||||
// Note: we can't do that optimization if our height is constrained or the
|
||||
// cell frame has a next-in-flow
|
||||
nsIFrame* kidNextInFlow;
|
||||
kidFrame->GetNextInFlow(&kidNextInFlow);
|
||||
if ((aReflowState.reflowState.availableHeight != NS_UNCONSTRAINEDSIZE) ||
|
||||
(availWidth != ((nsTableCellFrame *)kidFrame)->GetPriorAvailWidth()) ||
|
||||
(nsnull != kidNextInFlow))
|
||||
{
|
||||
// Reflow the cell to fit the available height
|
||||
nsSize kidAvailSize(availWidth, aReflowState.reflowState.availableHeight);
|
||||
// If it's a dirty frame, then check whether it's the initial reflow
|
||||
nsReflowReason reason = eReflowReason_Resize;
|
||||
if (aDirtyOnly) {
|
||||
if (frameState & NS_FRAME_FIRST_REFLOW) {
|
||||
// Newly inserted frame
|
||||
reason = eReflowReason_Initial;
|
||||
|
||||
// Reflow the child
|
||||
nsHTMLReflowState kidReflowState(aPresContext,
|
||||
aReflowState.reflowState, kidFrame,
|
||||
kidAvailSize,
|
||||
eReflowReason_Resize);
|
||||
if (gsDebug) printf ("Row %p RR: avail=%d\n", this, availWidth);
|
||||
nsReflowStatus status;
|
||||
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status);
|
||||
if (gsDebug) printf ("Row %p RR: desired=%d\n", this, desiredSize.width);
|
||||
// Use an unconstrained width so we can get the child's maximum
|
||||
// width
|
||||
// XXX What about fixed layout tables?
|
||||
kidAvailSize.SizeTo(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
|
||||
desiredSize.maxElementSize=&kidMaxElementSize;
|
||||
}
|
||||
}
|
||||
|
||||
// Reflow the child
|
||||
nsHTMLReflowState kidReflowState(aPresContext,
|
||||
aReflowState.reflowState, kidFrame,
|
||||
kidAvailSize,
|
||||
reason);
|
||||
if (gsDebug) printf ("Row %p RR: avail=%d\n", this, availWidth);
|
||||
nsReflowStatus status;
|
||||
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status);
|
||||
if (gsDebug) printf ("Row %p RR: desired=%d\n", this, desiredSize.width);
|
||||
#ifdef NS_DEBUG
|
||||
if (desiredSize.width > availWidth)
|
||||
{
|
||||
printf("WARNING: cell returned desired width %d given avail width %d\n",
|
||||
desiredSize.width, availWidth);
|
||||
}
|
||||
if (desiredSize.width > availWidth)
|
||||
{
|
||||
printf("WARNING: cell returned desired width %d given avail width %d\n",
|
||||
desiredSize.width, availWidth);
|
||||
}
|
||||
#endif
|
||||
// If any of the cells are not complete, then we're not complete
|
||||
if (NS_FRAME_IS_NOT_COMPLETE(status)) {
|
||||
aStatus = NS_FRAME_NOT_COMPLETE;
|
||||
}
|
||||
|
||||
if (gsDebug)
|
||||
{
|
||||
if (nsnull!=pKidMaxElementSize)
|
||||
printf("Row: reflow of cell returned result = %s with desired=%d,%d, min = %d,%d\n",
|
||||
NS_FRAME_IS_COMPLETE(status)?"complete":"NOT complete",
|
||||
desiredSize.width, desiredSize.height,
|
||||
pKidMaxElementSize->width, pKidMaxElementSize->height);
|
||||
else
|
||||
printf("Row: reflow of cell returned result = %s with desired=%d,%d, min = nsnull\n",
|
||||
NS_FRAME_IS_COMPLETE(status)?"complete":"NOT complete",
|
||||
desiredSize.width, desiredSize.height);
|
||||
if (eReflowReason_Initial == reason) {
|
||||
// Save the pass1 reflow information
|
||||
((nsTableCellFrame *)kidFrame)->SetPass1DesiredSize(desiredSize);
|
||||
((nsTableCellFrame *)kidFrame)->SetPass1MaxElementSize(kidMaxElementSize);
|
||||
}
|
||||
|
||||
// If any of the cells are not complete, then we're not complete
|
||||
if (NS_FRAME_IS_NOT_COMPLETE(status)) {
|
||||
aStatus = NS_FRAME_NOT_COMPLETE;
|
||||
}
|
||||
|
||||
if (gsDebug)
|
||||
{
|
||||
if (nsnull!=pKidMaxElementSize)
|
||||
printf("Row: reflow of cell returned result = %s with desired=%d,%d, min = %d,%d\n",
|
||||
NS_FRAME_IS_COMPLETE(status)?"complete":"NOT complete",
|
||||
desiredSize.width, desiredSize.height,
|
||||
pKidMaxElementSize->width, pKidMaxElementSize->height);
|
||||
else
|
||||
printf("Row: reflow of cell returned result = %s with desired=%d,%d, min = nsnull\n",
|
||||
NS_FRAME_IS_COMPLETE(status)?"complete":"NOT complete",
|
||||
desiredSize.width, desiredSize.height);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nsSize priorSize = ((nsTableCellFrame *)kidFrame)->GetDesiredSize();
|
||||
desiredSize.width = priorSize.width;
|
||||
desiredSize.height = priorSize.height;
|
||||
if (nsnull != pKidMaxElementSize)
|
||||
*pKidMaxElementSize = ((nsTableCellFrame *)kidFrame)->GetPass1MaxElementSize();
|
||||
}
|
||||
|
||||
// Place the child after taking into account its margin and attributes
|
||||
nscoord specifiedHeight = 0;
|
||||
nscoord cellHeight = desiredSize.height;
|
||||
nsIStyleContextPtr kidSC;
|
||||
kidFrame->GetStyleContext(kidSC.AssignPtr());
|
||||
const nsStylePosition* kidPosition = (const nsStylePosition*)
|
||||
kidSC->GetStyleData(eStyleStruct_Position);
|
||||
switch (kidPosition->mHeight.GetUnit()) {
|
||||
case eStyleUnit_Coord:
|
||||
specifiedHeight = kidPosition->mHeight.GetCoordValue();
|
||||
break;
|
||||
|
||||
case eStyleUnit_Inherit:
|
||||
// XXX for now, do nothing
|
||||
default:
|
||||
case eStyleUnit_Auto:
|
||||
break;
|
||||
}
|
||||
if (specifiedHeight>cellHeight)
|
||||
cellHeight = specifiedHeight;
|
||||
|
||||
nscoord cellWidth = desiredSize.width;
|
||||
// begin special Nav4 compatibility code
|
||||
if (0==cellWidth)
|
||||
{
|
||||
cellWidth = availWidth;
|
||||
}
|
||||
// end special Nav4 compatibility code
|
||||
|
||||
// Place the child
|
||||
nsRect kidRect (aReflowState.x, kidMargin.top, cellWidth, cellHeight);
|
||||
|
||||
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect, aDesiredSize.maxElementSize,
|
||||
pKidMaxElementSize);
|
||||
|
||||
if (PR_TRUE==gsDebug) printf("Row: past PlaceChild, aReflowState.x set to %d\n", aReflowState.x);
|
||||
}
|
||||
else
|
||||
{
|
||||
nsSize priorSize = ((nsTableCellFrame *)kidFrame)->GetDesiredSize();
|
||||
desiredSize.width = priorSize.width;
|
||||
desiredSize.height = priorSize.height;
|
||||
if (nsnull != pKidMaxElementSize)
|
||||
*pKidMaxElementSize = ((nsTableCellFrame *)kidFrame)->GetPass1MaxElementSize();
|
||||
{// it's an unknown frame type, give it a generic reflow and ignore the results
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState,
|
||||
kidFrame,
|
||||
nsSize(0,0), eReflowReason_Resize);
|
||||
nsHTMLReflowMetrics desiredSize(nsnull);
|
||||
if (PR_TRUE==gsDebug) printf("\nRow: Resize Reflow of unknown frame %p of type %d with reason=%d\n",
|
||||
kidFrame, kidDisplay->mDisplay, eReflowReason_Resize);
|
||||
nsReflowStatus status;
|
||||
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status);
|
||||
}
|
||||
|
||||
// Place the child after taking into account its margin and attributes
|
||||
nscoord specifiedHeight = 0;
|
||||
nscoord cellHeight = desiredSize.height;
|
||||
nsIStyleContextPtr kidSC;
|
||||
kidFrame->GetStyleContext(kidSC.AssignPtr());
|
||||
const nsStylePosition* kidPosition = (const nsStylePosition*)
|
||||
kidSC->GetStyleData(eStyleStruct_Position);
|
||||
switch (kidPosition->mHeight.GetUnit()) {
|
||||
case eStyleUnit_Coord:
|
||||
specifiedHeight = kidPosition->mHeight.GetCoordValue();
|
||||
break;
|
||||
|
||||
case eStyleUnit_Inherit:
|
||||
// XXX for now, do nothing
|
||||
default:
|
||||
case eStyleUnit_Auto:
|
||||
break;
|
||||
}
|
||||
if (specifiedHeight>cellHeight)
|
||||
cellHeight = specifiedHeight;
|
||||
|
||||
nscoord cellWidth = desiredSize.width;
|
||||
// begin special Nav4 compatibility code
|
||||
if (0==cellWidth)
|
||||
{
|
||||
cellWidth = availWidth;
|
||||
}
|
||||
// end special Nav4 compatibility code
|
||||
|
||||
// Place the child
|
||||
nsRect kidRect (aReflowState.x, kidMargin.top, cellWidth, cellHeight);
|
||||
|
||||
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect, aDesiredSize.maxElementSize,
|
||||
pKidMaxElementSize);
|
||||
|
||||
if (PR_TRUE==gsDebug) printf("Row: past PlaceChild, aReflowState.x set to %d\n", aReflowState.x);
|
||||
}
|
||||
else
|
||||
{// it's an unknown frame type, give it a generic reflow and ignore the results
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState,
|
||||
kidFrame,
|
||||
nsSize(0,0), eReflowReason_Resize);
|
||||
nsHTMLReflowMetrics desiredSize(nsnull);
|
||||
if (PR_TRUE==gsDebug) printf("\nRow: Resize Reflow of unknown frame %p of type %d with reason=%d\n",
|
||||
kidFrame, kidDisplay->mDisplay, eReflowReason_Resize);
|
||||
nsReflowStatus status;
|
||||
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status);
|
||||
}
|
||||
|
||||
kidFrame = iter.Next(); // Get the next child
|
||||
|
@ -1067,52 +1252,21 @@ NS_METHOD nsTableRowFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
|||
if (PR_TRUE==gsDebugIR) printf("TRF IR: IncrementalReflow_TargetIsMe with type=%d\n", type);
|
||||
switch (type)
|
||||
{
|
||||
case nsIReflowCommand::FrameInserted :
|
||||
NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame");
|
||||
NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay");
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_CellInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
(nsTableCellFrame *)objectFrame, PR_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = AddFrame(aReflowState.reflowState, objectFrame);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::FrameAppended :
|
||||
NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame");
|
||||
NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay");
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_CellAppended(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
(nsTableCellFrame *)objectFrame);
|
||||
}
|
||||
else
|
||||
{ // no optimization to be done for Unknown frame types, so just reuse the Inserted method
|
||||
rv = AddFrame(aReflowState.reflowState, objectFrame);
|
||||
}
|
||||
break;
|
||||
case nsIReflowCommand::ReflowDirty:
|
||||
{
|
||||
// Reflow the dirty child frames. Typically this is newly added frames.
|
||||
// XXX What we really should do is do a pass-1 reflow of newly added
|
||||
// frames (only if necessary, i.e., the table isn't fixed layout), then
|
||||
// see if column widtsh changed and decide whether to do the pass-2 reflow
|
||||
// of just the dirty rows or have the table rebalance column widths and
|
||||
// do a pass-2 reflow of all rows
|
||||
rv = ResizeReflow(aPresContext, aDesiredSize, aReflowState, aStatus, PR_TRUE);
|
||||
|
||||
/*
|
||||
case nsIReflowCommand::FrameReplaced :
|
||||
|
||||
*/
|
||||
|
||||
case nsIReflowCommand::FrameRemoved :
|
||||
NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame");
|
||||
NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay");
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_CellRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
(nsTableCellFrame *)objectFrame);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = mFrames.DestroyFrame(aPresContext, objectFrame);
|
||||
}
|
||||
// If any column widths have to change due to this, rebalance column widths.
|
||||
// XXX need to calculate this, but for now just do it
|
||||
aReflowState.tableFrame->InvalidateColumnWidths();
|
||||
break;
|
||||
}
|
||||
|
||||
case nsIReflowCommand::StyleChanged :
|
||||
rv = IR_StyleChanged(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
|
@ -1123,192 +1277,16 @@ NS_METHOD nsTableRowFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
|||
rv = NS_ERROR_ILLEGAL_VALUE;
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::PullupReflow:
|
||||
case nsIReflowCommand::PushReflow:
|
||||
case nsIReflowCommand::CheckPullupReflow :
|
||||
case nsIReflowCommand::UserDefined :
|
||||
default:
|
||||
NS_NOTYETIMPLEMENTED("unimplemented reflow command type");
|
||||
NS_NOTYETIMPLEMENTED("unexpected reflow command type");
|
||||
rv = NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (PR_TRUE==gsDebugIR) printf("TRF IR: reflow command not implemented.\n");
|
||||
if (PR_TRUE==gsDebugIR) printf("TRF IR: unexpected reflow command not implemented.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowFrame::IR_CellInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableCellFrame * aInsertedFrame,
|
||||
PRBool aReplace)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRF IR: IR_CellInserted\n");
|
||||
nsresult rv = AddFrame(aReflowState.reflowState, (nsIFrame*)aInsertedFrame);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || nsnull==tableFrame)
|
||||
return rv;
|
||||
|
||||
#if 0
|
||||
// do a pass-1 layout of the cell
|
||||
if (PR_TRUE==tableFrame->RequiresPass1Layout())
|
||||
{
|
||||
rv = InitialReflow(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
aInsertedFrame, PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
// set row state
|
||||
GetMinRowSpan(tableFrame);
|
||||
FixMinCellHeight(tableFrame);
|
||||
|
||||
// set table state
|
||||
tableFrame->InvalidateCellMap();
|
||||
tableFrame->InvalidateColumnCache();
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowFrame::IR_DidAppendCell(nsTableCellFrame *aRowFrame)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
// since we know we're doing an append here, we can optimize
|
||||
NS_METHOD nsTableRowFrame::IR_CellAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableCellFrame* aAppendedFrame)
|
||||
{
|
||||
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRF IR: IR_CellInserted\n");
|
||||
nsresult rv = AddFrame(aReflowState.reflowState, (nsIFrame*)aAppendedFrame);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || nsnull==tableFrame)
|
||||
return rv;
|
||||
|
||||
tableFrame->AddCellToTable(aAppendedFrame, GetRowIndex());
|
||||
// do a pass-1 layout of the cell
|
||||
if (PR_TRUE==tableFrame->RequiresPass1Layout())
|
||||
{
|
||||
rv = InitialReflow(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
aAppendedFrame, PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
// set row state
|
||||
GetMinRowSpan(tableFrame);
|
||||
FixMinCellHeight(tableFrame);
|
||||
|
||||
// set table state
|
||||
|
||||
tableFrame->InvalidateCellMap();
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
return rv;
|
||||
|
||||
|
||||
#if 0
|
||||
nsresult rv=NS_OK;
|
||||
// hook aAppendedFrame into the child list
|
||||
nsIFrame *lastChild = mFrames.FirstChild();
|
||||
nsIFrame *nextChild = lastChild;
|
||||
nsIFrame *lastRow = nsnull;
|
||||
while (nsnull!=nextChild)
|
||||
{
|
||||
// remember the last child that is really a cell
|
||||
const nsStyleDisplay *childDisplay;
|
||||
nextChild->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay)
|
||||
lastRow = nextChild;
|
||||
lastChild = nextChild;
|
||||
nextChild->GetNextSibling(nextChild);
|
||||
}
|
||||
if (nsnull==lastChild)
|
||||
mFirstChild = aAppendedFrame;
|
||||
else
|
||||
lastChild->SetNextSibling(aAppendedFrame);
|
||||
|
||||
aReflowState.tableFrame->InvalidateFirstPassCache();
|
||||
// the table will see that it's cached info is bogus and rebuild the cell map,
|
||||
// and do a reflow
|
||||
|
||||
|
||||
// find the col index of the new cell
|
||||
|
||||
// account for the new cell
|
||||
nsresult rv = DidAppendCell((nsTableCellFrame*)aAppendedFrame);
|
||||
|
||||
// need to increment the row index of all subsequent rows
|
||||
|
||||
|
||||
return rv;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowFrame::IR_CellRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableCellFrame* aDeletedFrame)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("\nRow IR: IR_RowRemoved\n");
|
||||
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || nsnull == tableFrame)
|
||||
return rv;
|
||||
|
||||
PRInt32 colIndex;
|
||||
aDeletedFrame->GetColIndex(colIndex);
|
||||
tableFrame->RemoveCellFromTable(aDeletedFrame, GetRowIndex());
|
||||
rv = mFrames.DestroyFrame(aPresContext, (nsIFrame*)aDeletedFrame);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
ResetMaxChildHeight();
|
||||
|
||||
// set row state
|
||||
GetMinRowSpan(tableFrame);
|
||||
FixMinCellHeight(tableFrame);
|
||||
|
||||
// set table state
|
||||
tableFrame->InvalidateCellMap();
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
#if 0
|
||||
nsresult rv = mFrames.DestroyFrame(aPresContext, (nsIFrame*)aDeletedFrame);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
ResetMaxChildHeight();
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || nsnull==tableFrame)
|
||||
return rv;
|
||||
#endif
|
||||
|
||||
// if any column widths have to change due to this, rebalance column widths
|
||||
//XXX need to calculate this, but for now just do it
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowFrame::IR_StyleChanged(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
|
|
|
@ -44,6 +44,20 @@ public:
|
|||
nsIStyleContext* aContext,
|
||||
nsIFrame* aPrevInFlow);
|
||||
|
||||
NS_IMETHOD AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList);
|
||||
NS_IMETHOD InsertFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList);
|
||||
NS_IMETHOD RemoveFrame(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
/** Initialization of data */
|
||||
NS_IMETHOD InitChildren();
|
||||
|
||||
|
@ -166,32 +180,15 @@ protected:
|
|||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD IR_CellInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableCellFrame * aInsertedFrame,
|
||||
PRBool aReplace);
|
||||
|
||||
NS_IMETHOD IR_CellAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableCellFrame * aAppendedFrame);
|
||||
|
||||
NS_IMETHOD IR_DidAppendCell(nsTableCellFrame *aRowFrame);
|
||||
|
||||
NS_IMETHOD IR_CellRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableCellFrame * aDeletedFrame);
|
||||
|
||||
NS_IMETHOD IR_StyleChanged(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
nsresult AddTableDirtyReflowCommand(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIFrame* aTableFrame);
|
||||
|
||||
// row-specific methods
|
||||
|
||||
void GetMinRowSpan(nsTableFrame *aTableFrame);
|
||||
|
@ -224,7 +221,8 @@ protected:
|
|||
NS_IMETHOD ResizeReflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
nsReflowStatus& aStatus,
|
||||
PRBool aDirtyOnly = PR_FALSE);
|
||||
|
||||
/**
|
||||
* Called for the initial reflow. Creates each table cell frame, and
|
||||
|
|
|
@ -424,6 +424,7 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC
|
|||
}
|
||||
}
|
||||
|
||||
// Reflow the row frame
|
||||
if (doReflowChild) {
|
||||
nsSize kidAvailSize(aReflowState.availSize);
|
||||
if (0>=kidAvailSize.height)
|
||||
|
@ -435,15 +436,22 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC
|
|||
// it wants. We'll deal with splitting later after we've computed the row
|
||||
// heights, taking into account cells with row spans...
|
||||
kidAvailSize.height = NS_UNCONSTRAINEDSIZE;
|
||||
nsReflowReason reason = aReason;
|
||||
if (aDirtyOnly) {
|
||||
if (frameState & NS_FRAME_FIRST_REFLOW) {
|
||||
// Newly inserted frame
|
||||
aReason = eReflowReason_Initial;
|
||||
reason = eReflowReason_Initial;
|
||||
}
|
||||
}
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState, kidFrame,
|
||||
kidAvailSize, aReason);
|
||||
kidAvailSize, reason);
|
||||
|
||||
// If this isn't the first row frame, then we can't be at the top of
|
||||
// the page anymore...
|
||||
if (kidFrame != GetFirstFrame()) {
|
||||
kidReflowState.isTopOfPage = PR_FALSE;
|
||||
}
|
||||
|
||||
if (aReflowState.tableFrame->RowGroupsShouldBeConstrained()) {
|
||||
// Only applies to the tree widget.
|
||||
const nsStyleDisplay *rowDisplay;
|
||||
|
@ -454,19 +462,14 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC
|
|||
}
|
||||
}
|
||||
|
||||
if (kidFrame != GetFirstFrame()) {
|
||||
// If this isn't the first row frame, then we can't be at the top of
|
||||
// the page anymore...
|
||||
kidReflowState.isTopOfPage = PR_FALSE;
|
||||
}
|
||||
|
||||
if ((PR_TRUE==gsDebug) || (PR_TRUE==gsDebugIR))
|
||||
printf("%p RG reflowing child %p with avail width = %d, reason = %d\n",
|
||||
this, kidFrame, kidAvailSize.width, aReason);
|
||||
this, kidFrame, kidAvailSize.width, reason);
|
||||
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, aStatus);
|
||||
if (gsDebug) printf("%p RG child %p returned desired width = %d\n",
|
||||
this, kidFrame, desiredSize.width);
|
||||
|
||||
// Place the child
|
||||
nsRect kidRect (0, aReflowState.y, desiredSize.width, desiredSize.height);
|
||||
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect, aDesiredSize.maxElementSize,
|
||||
kidMaxElementSize);
|
||||
|
@ -507,6 +510,13 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC
|
|||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Adjust the running y-offset so we know where the next row should
|
||||
// be placed
|
||||
nsSize kidSize;
|
||||
|
||||
kidFrame->GetSize(kidSize);
|
||||
aReflowState.y += kidSize.height;
|
||||
}
|
||||
|
||||
if (PR_FALSE==aDoSiblings)
|
||||
|
@ -1251,13 +1261,11 @@ nsTableRowGroupFrame::RemoveFrame(nsIPresContext& aPresContext,
|
|||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
nsresult rv;
|
||||
const nsStyleDisplay *display;
|
||||
aOldFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display));
|
||||
|
||||
// Remove the frame and destroy it
|
||||
rv = mFrames.DestroyFrame(aPresContext, aOldFrame);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (mFrames.DestroyFrame(aPresContext, aOldFrame)) {
|
||||
if ((NS_STYLE_DISPLAY_TABLE_ROW == display->mDisplay) ||
|
||||
(NS_STYLE_DISPLAY_TABLE_ROW_GROUP == display->mDisplay)) {
|
||||
// Get the table frame
|
||||
|
@ -1279,7 +1287,7 @@ nsTableRowGroupFrame::RemoveFrame(nsIPresContext& aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
|
@ -1299,17 +1307,17 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
|||
switch (type)
|
||||
{
|
||||
case nsIReflowCommand::ReflowDirty:
|
||||
// Reflow the dirty child frames
|
||||
// Reflow the dirty child frames. Typically this is newly added frames.
|
||||
// XXX What we really should do is do a pass-1 reflow of newly added
|
||||
// frames (only if necessary--because the table isn't fixed layout), then
|
||||
// frames (only if necessary, i.e., the table isn't fixed layout), then
|
||||
// see if column widtsh changed and decide whether to do the pass-2 reflow
|
||||
// of just the dirty rows or have the table rebalance column widths and
|
||||
// do a pass-2 reflow of all rows
|
||||
rv = ReflowMappedChildren(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
nsnull, aReflowState.reflowState.reason, PR_TRUE, PR_TRUE);
|
||||
|
||||
// If any column widths have to change due to this, rebalance column widths
|
||||
//XXX need to calculate this, but for now just do it
|
||||
// If any column widths have to change due to this, rebalance column widths.
|
||||
// XXX need to calculate this, but for now just do it
|
||||
aReflowState.tableFrame->InvalidateColumnWidths();
|
||||
break;
|
||||
|
||||
|
|
|
@ -121,6 +121,151 @@ nsTableRowFrame::Init(nsIPresContext& aPresContext,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// Helper function. It marks the table frame as dirty and generates
|
||||
// a reflow command
|
||||
nsresult
|
||||
nsTableRowFrame::AddTableDirtyReflowCommand(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIFrame* aTableFrame)
|
||||
{
|
||||
nsFrameState frameState;
|
||||
nsIFrame* tableParentFrame;
|
||||
nsIReflowCommand* reflowCmd;
|
||||
nsresult rv;
|
||||
|
||||
// Mark the table frame as dirty
|
||||
aTableFrame->GetFrameState(&frameState);
|
||||
frameState |= NS_FRAME_IS_DIRTY;
|
||||
aTableFrame->SetFrameState(frameState);
|
||||
|
||||
// Target the reflow comamnd at its parent frame
|
||||
aTableFrame->GetParent(&tableParentFrame);
|
||||
rv = NS_NewHTMLReflowCommand(&reflowCmd, tableParentFrame,
|
||||
nsIReflowCommand::ReflowDirty);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Add the reflow command
|
||||
rv = aPresShell.AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableRowFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
// Append the frames
|
||||
mFrames.AppendFrames(nsnull, aFrameList);
|
||||
|
||||
// Add the new cell frames to the table
|
||||
nsTableFrame *tableFrame = nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
for (nsIFrame* childFrame = aFrameList; childFrame; childFrame->GetNextSibling(&childFrame)) {
|
||||
const nsStyleDisplay *display;
|
||||
childFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display));
|
||||
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == display->mDisplay) {
|
||||
// Add the cell to the cell map
|
||||
PRInt32 colIndex = tableFrame->AddCellToTable((nsTableCellFrame*)childFrame,
|
||||
GetRowIndex());
|
||||
|
||||
// Initialize the cell frame and give it its column index
|
||||
((nsTableCellFrame*)childFrame)->InitCellFrame(colIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// Reflow the new frames. They're already marked dirty, so generate a reflow
|
||||
// command that tells us to reflow our dirty child frames
|
||||
nsIReflowCommand* reflowCmd;
|
||||
|
||||
if (NS_SUCCEEDED(NS_NewHTMLReflowCommand(&reflowCmd, this,
|
||||
nsIReflowCommand::ReflowDirty))) {
|
||||
aPresShell.AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableRowFrame::InsertFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
// Get the table frame
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
|
||||
// Insert the frames
|
||||
mFrames.InsertFrames(nsnull, aPrevFrame, aFrameList);
|
||||
|
||||
// We need to rebuild the cell map, because currently we can't insert
|
||||
// new frames except at the end (append)
|
||||
tableFrame->InvalidateCellMap();
|
||||
|
||||
// We should try and avoid doing a pass1 reflow on all the cells and just
|
||||
// do it for the newly added frames, but we need to add these frames to the
|
||||
// cell map before we reflow them
|
||||
tableFrame->InvalidateFirstPassCache();
|
||||
|
||||
// Because the number of columns may have changed invalidate the column
|
||||
// cache. Note that this has the side effect of recomputing the column
|
||||
// widths, so we don't need to call InvalidateColumnWidths()
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
// Generate a reflow command so we reflow the table itself. This will
|
||||
// do a pass-1 reflow of all the rows including any rows we just added
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableRowFrame::RemoveFrame(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
// Get the table frame
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
|
||||
#if 0
|
||||
// XXX Currently we can't incrementally remove cells from the cell map
|
||||
PRInt32 colIndex;
|
||||
aDeletedFrame->GetColIndex(colIndex);
|
||||
tableFrame->RemoveCellFromTable(aOldFrame, GetRowIndex());
|
||||
|
||||
// Remove the frame and destroy it
|
||||
mFrames.DestroyFrame(aPresContext, (nsIFrame*)aOldFrame);
|
||||
|
||||
// XXX Reflow the row
|
||||
|
||||
#else
|
||||
// Remove the frame and destroy it
|
||||
mFrames.DestroyFrame(aPresContext, aOldFrame);
|
||||
|
||||
// We need to rebuild the cell map, because currently we can't incrementally
|
||||
// remove rows
|
||||
tableFrame->InvalidateCellMap();
|
||||
|
||||
// Because the number of columns may have changed invalidate the column
|
||||
// cache. Note that this has the side effect of recomputing the column
|
||||
// widths, so we don't need to call InvalidateColumnWidths()
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
// Because we haven't added any new frames we don't need to do a pass1
|
||||
// reflow. Just generate a reflow command so we reflow the table itself
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableRowFrame::InitChildren()
|
||||
{
|
||||
|
@ -550,12 +695,14 @@ void nsTableRowFrame::PlaceChild(nsIPresContext& aPresContext,
|
|||
|
||||
/**
|
||||
* Called for a resize reflow. Typically because the column widths have
|
||||
* changed. Reflows all the existing table cell frames
|
||||
* changed. Reflows all the existing table cell frames unless aDirtyOnly
|
||||
* is PR_TRUE in which case only reflow the dirty frames
|
||||
*/
|
||||
NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
nsReflowStatus& aStatus,
|
||||
PRBool aDirtyOnly)
|
||||
{
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
if (nsnull == mFrames.FirstChild()) {
|
||||
|
@ -592,177 +739,215 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
|||
// Reflow each of our existing cell frames
|
||||
nsIFrame* kidFrame = iter.First();
|
||||
while (nsnull != kidFrame) {
|
||||
const nsStyleDisplay *kidDisplay;
|
||||
kidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)kidDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay) {
|
||||
PRInt32 cellColIndex;
|
||||
((nsTableCellFrame *)kidFrame)->GetColIndex(cellColIndex);
|
||||
cellColSpan = aReflowState.tableFrame->GetEffectiveColSpan(cellColIndex,
|
||||
((nsTableCellFrame *)kidFrame));
|
||||
nsMargin kidMargin;
|
||||
aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame,kidMargin);
|
||||
if (kidMargin.top > maxCellTopMargin)
|
||||
maxCellTopMargin = kidMargin.top;
|
||||
if (kidMargin.bottom > maxCellBottomMargin)
|
||||
maxCellBottomMargin = kidMargin.bottom;
|
||||
|
||||
// Compute the x-origin for the child, taking into account straddlers (cells from prior
|
||||
// rows with rowspans > 1)
|
||||
// if this cell is not immediately adjacent to the previous cell, factor in missing col info
|
||||
if (iter.IsLeftToRight()) {
|
||||
if (prevColIndex != (cellColIndex - 1)) {
|
||||
for (PRInt32 colIndex = prevColIndex + 1; cellColIndex > colIndex; colIndex++) {
|
||||
aReflowState.x += aReflowState.tableFrame->GetColumnWidth(colIndex);
|
||||
if (aReflowState.tableFrame->GetNumCellsOriginatingIn(colIndex) > 0) {
|
||||
aReflowState.x += cellSpacingX;
|
||||
// Get the frame state bits
|
||||
nsFrameState frameState;
|
||||
kidFrame->GetFrameState(&frameState);
|
||||
|
||||
// See if we should only reflow the dirty child frames
|
||||
PRBool doReflowChild = PR_TRUE;
|
||||
if (aDirtyOnly) {
|
||||
if ((frameState & NS_FRAME_IS_DIRTY) == 0) {
|
||||
doReflowChild = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Reflow the child frame
|
||||
if (doReflowChild) {
|
||||
const nsStyleDisplay *kidDisplay;
|
||||
kidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)kidDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay) {
|
||||
PRInt32 cellColIndex;
|
||||
((nsTableCellFrame *)kidFrame)->GetColIndex(cellColIndex);
|
||||
cellColSpan = aReflowState.tableFrame->GetEffectiveColSpan(cellColIndex,
|
||||
((nsTableCellFrame *)kidFrame));
|
||||
nsMargin kidMargin;
|
||||
aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame,kidMargin);
|
||||
if (kidMargin.top > maxCellTopMargin)
|
||||
maxCellTopMargin = kidMargin.top;
|
||||
if (kidMargin.bottom > maxCellBottomMargin)
|
||||
maxCellBottomMargin = kidMargin.bottom;
|
||||
|
||||
// Compute the x-origin for the child, taking into account straddlers (cells from prior
|
||||
// rows with rowspans > 1)
|
||||
// if this cell is not immediately adjacent to the previous cell, factor in missing col info
|
||||
if (iter.IsLeftToRight()) {
|
||||
if (prevColIndex != (cellColIndex - 1)) {
|
||||
for (PRInt32 colIndex = prevColIndex + 1; cellColIndex > colIndex; colIndex++) {
|
||||
aReflowState.x += aReflowState.tableFrame->GetColumnWidth(colIndex);
|
||||
if (aReflowState.tableFrame->GetNumCellsOriginatingIn(colIndex) > 0) {
|
||||
aReflowState.x += cellSpacingX;
|
||||
}
|
||||
if (PR_TRUE==gsDebug)
|
||||
printf(" Row: in loop, aReflowState.x set to %d from cellSpacing %d and col width %d\n",
|
||||
aReflowState.x, cellSpacingX, aReflowState.tableFrame->GetColumnWidth(colIndex));
|
||||
}
|
||||
if (PR_TRUE==gsDebug)
|
||||
printf(" Row: in loop, aReflowState.x set to %d from cellSpacing %d and col width %d\n",
|
||||
aReflowState.x, cellSpacingX, aReflowState.tableFrame->GetColumnWidth(colIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (prevColIndex != cellColIndex + cellColSpan) {
|
||||
PRInt32 lastCol = cellColIndex + cellColSpan - 1;
|
||||
for (PRInt32 colIndex = prevColIndex - 1; colIndex > lastCol; colIndex--) {
|
||||
aReflowState.x += aReflowState.tableFrame->GetColumnWidth(colIndex);
|
||||
if (aReflowState.tableFrame->GetNumCellsOriginatingIn(colIndex) > 0) {
|
||||
aReflowState.x += cellSpacingX;
|
||||
else {
|
||||
if (prevColIndex != cellColIndex + cellColSpan) {
|
||||
PRInt32 lastCol = cellColIndex + cellColSpan - 1;
|
||||
for (PRInt32 colIndex = prevColIndex - 1; colIndex > lastCol; colIndex--) {
|
||||
aReflowState.x += aReflowState.tableFrame->GetColumnWidth(colIndex);
|
||||
if (aReflowState.tableFrame->GetNumCellsOriginatingIn(colIndex) > 0) {
|
||||
aReflowState.x += cellSpacingX;
|
||||
}
|
||||
if (PR_TRUE==gsDebug)
|
||||
printf(" Row: in loop, aReflowState.x set to %d from cellSpacing %d and col width %d\n",
|
||||
aReflowState.x, cellSpacingX, aReflowState.tableFrame->GetColumnWidth(colIndex));
|
||||
}
|
||||
if (PR_TRUE==gsDebug)
|
||||
printf(" Row: in loop, aReflowState.x set to %d from cellSpacing %d and col width %d\n",
|
||||
aReflowState.x, cellSpacingX, aReflowState.tableFrame->GetColumnWidth(colIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aReflowState.x += cellSpacingX;
|
||||
if (PR_TRUE==gsDebug) printf(" Row: past loop, aReflowState.x set to %d\n", aReflowState.x);
|
||||
|
||||
// at this point, we know the column widths.
|
||||
// so we get the avail width from the known column widths
|
||||
nscoord availWidth = 0;
|
||||
for (PRInt32 numColSpan=0; numColSpan<cellColSpan; numColSpan++) {
|
||||
availWidth += aReflowState.tableFrame->GetColumnWidth(cellColIndex+numColSpan);
|
||||
if ((numColSpan != 0) && (aReflowState.tableFrame->GetNumCellsOriginatingIn(cellColIndex + numColSpan) > 0)) {
|
||||
availWidth += cellSpacingX;
|
||||
|
||||
aReflowState.x += cellSpacingX;
|
||||
if (PR_TRUE==gsDebug) printf(" Row: past loop, aReflowState.x set to %d\n", aReflowState.x);
|
||||
|
||||
// at this point, we know the column widths.
|
||||
// so we get the avail width from the known column widths
|
||||
nscoord availWidth = 0;
|
||||
for (PRInt32 numColSpan=0; numColSpan<cellColSpan; numColSpan++) {
|
||||
availWidth += aReflowState.tableFrame->GetColumnWidth(cellColIndex+numColSpan);
|
||||
if ((numColSpan != 0) && (aReflowState.tableFrame->GetNumCellsOriginatingIn(cellColIndex + numColSpan) > 0)) {
|
||||
availWidth += cellSpacingX;
|
||||
}
|
||||
if (PR_TRUE==gsDebug) {
|
||||
printf(" Row: in loop, availWidth set to %d from colIndex %d width %d and cellSpacing\n",
|
||||
availWidth, cellColIndex, aReflowState.tableFrame->GetColumnWidth(cellColIndex+numColSpan));
|
||||
}
|
||||
}
|
||||
if (PR_TRUE==gsDebug) {
|
||||
printf(" Row: in loop, availWidth set to %d from colIndex %d width %d and cellSpacing\n",
|
||||
availWidth, cellColIndex, aReflowState.tableFrame->GetColumnWidth(cellColIndex+numColSpan));
|
||||
}
|
||||
}
|
||||
if (PR_TRUE==gsDebug) printf(" Row: availWidth for this cell is %d\n", availWidth);
|
||||
// remember the rightmost (ltr) or leftmost (rtl) column this cell spans into
|
||||
prevColIndex = (iter.IsLeftToRight()) ? cellColIndex + (cellColSpan - 1) : cellColIndex;
|
||||
nsHTMLReflowMetrics desiredSize(pKidMaxElementSize);
|
||||
if (PR_TRUE==gsDebug) printf(" Row: availWidth for this cell is %d\n", availWidth);
|
||||
// remember the rightmost (ltr) or leftmost (rtl) column this cell spans into
|
||||
prevColIndex = (iter.IsLeftToRight()) ? cellColIndex + (cellColSpan - 1) : cellColIndex;
|
||||
nsHTMLReflowMetrics desiredSize(pKidMaxElementSize);
|
||||
|
||||
// If the available width is the same as last time we reflowed the cell,
|
||||
// then just use the previous desired size and max element size.
|
||||
// if we need the max-element-size we don't need to reflow.
|
||||
// we just grab it from the cell frame which remembers it (see the else clause below).
|
||||
// Note: we can't do that optimization if our height is constrained or the
|
||||
// cell frame has a next-in-flow
|
||||
nsIFrame* kidNextInFlow;
|
||||
kidFrame->GetNextInFlow(&kidNextInFlow);
|
||||
if ((aReflowState.reflowState.availableHeight != NS_UNCONSTRAINEDSIZE) ||
|
||||
(availWidth != ((nsTableCellFrame *)kidFrame)->GetPriorAvailWidth()) ||
|
||||
(nsnull != kidNextInFlow))
|
||||
{
|
||||
// Reflow the cell to fit the available height
|
||||
nsSize kidAvailSize(availWidth, aReflowState.reflowState.availableHeight);
|
||||
nsSize kidMaxElementSize(0,0);
|
||||
|
||||
// If the available width is the same as last time we reflowed the cell,
|
||||
// then just use the previous desired size and max element size.
|
||||
// if we need the max-element-size we don't need to reflow.
|
||||
// we just grab it from the cell frame which remembers it (see the else clause below).
|
||||
// Note: we can't do that optimization if our height is constrained or the
|
||||
// cell frame has a next-in-flow
|
||||
nsIFrame* kidNextInFlow;
|
||||
kidFrame->GetNextInFlow(&kidNextInFlow);
|
||||
if ((aReflowState.reflowState.availableHeight != NS_UNCONSTRAINEDSIZE) ||
|
||||
(availWidth != ((nsTableCellFrame *)kidFrame)->GetPriorAvailWidth()) ||
|
||||
(nsnull != kidNextInFlow))
|
||||
{
|
||||
// Reflow the cell to fit the available height
|
||||
nsSize kidAvailSize(availWidth, aReflowState.reflowState.availableHeight);
|
||||
// If it's a dirty frame, then check whether it's the initial reflow
|
||||
nsReflowReason reason = eReflowReason_Resize;
|
||||
if (aDirtyOnly) {
|
||||
if (frameState & NS_FRAME_FIRST_REFLOW) {
|
||||
// Newly inserted frame
|
||||
reason = eReflowReason_Initial;
|
||||
|
||||
// Reflow the child
|
||||
nsHTMLReflowState kidReflowState(aPresContext,
|
||||
aReflowState.reflowState, kidFrame,
|
||||
kidAvailSize,
|
||||
eReflowReason_Resize);
|
||||
if (gsDebug) printf ("Row %p RR: avail=%d\n", this, availWidth);
|
||||
nsReflowStatus status;
|
||||
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status);
|
||||
if (gsDebug) printf ("Row %p RR: desired=%d\n", this, desiredSize.width);
|
||||
// Use an unconstrained width so we can get the child's maximum
|
||||
// width
|
||||
// XXX What about fixed layout tables?
|
||||
kidAvailSize.SizeTo(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
|
||||
desiredSize.maxElementSize=&kidMaxElementSize;
|
||||
}
|
||||
}
|
||||
|
||||
// Reflow the child
|
||||
nsHTMLReflowState kidReflowState(aPresContext,
|
||||
aReflowState.reflowState, kidFrame,
|
||||
kidAvailSize,
|
||||
reason);
|
||||
if (gsDebug) printf ("Row %p RR: avail=%d\n", this, availWidth);
|
||||
nsReflowStatus status;
|
||||
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status);
|
||||
if (gsDebug) printf ("Row %p RR: desired=%d\n", this, desiredSize.width);
|
||||
#ifdef NS_DEBUG
|
||||
if (desiredSize.width > availWidth)
|
||||
{
|
||||
printf("WARNING: cell returned desired width %d given avail width %d\n",
|
||||
desiredSize.width, availWidth);
|
||||
}
|
||||
if (desiredSize.width > availWidth)
|
||||
{
|
||||
printf("WARNING: cell returned desired width %d given avail width %d\n",
|
||||
desiredSize.width, availWidth);
|
||||
}
|
||||
#endif
|
||||
// If any of the cells are not complete, then we're not complete
|
||||
if (NS_FRAME_IS_NOT_COMPLETE(status)) {
|
||||
aStatus = NS_FRAME_NOT_COMPLETE;
|
||||
}
|
||||
|
||||
if (gsDebug)
|
||||
{
|
||||
if (nsnull!=pKidMaxElementSize)
|
||||
printf("Row: reflow of cell returned result = %s with desired=%d,%d, min = %d,%d\n",
|
||||
NS_FRAME_IS_COMPLETE(status)?"complete":"NOT complete",
|
||||
desiredSize.width, desiredSize.height,
|
||||
pKidMaxElementSize->width, pKidMaxElementSize->height);
|
||||
else
|
||||
printf("Row: reflow of cell returned result = %s with desired=%d,%d, min = nsnull\n",
|
||||
NS_FRAME_IS_COMPLETE(status)?"complete":"NOT complete",
|
||||
desiredSize.width, desiredSize.height);
|
||||
if (eReflowReason_Initial == reason) {
|
||||
// Save the pass1 reflow information
|
||||
((nsTableCellFrame *)kidFrame)->SetPass1DesiredSize(desiredSize);
|
||||
((nsTableCellFrame *)kidFrame)->SetPass1MaxElementSize(kidMaxElementSize);
|
||||
}
|
||||
|
||||
// If any of the cells are not complete, then we're not complete
|
||||
if (NS_FRAME_IS_NOT_COMPLETE(status)) {
|
||||
aStatus = NS_FRAME_NOT_COMPLETE;
|
||||
}
|
||||
|
||||
if (gsDebug)
|
||||
{
|
||||
if (nsnull!=pKidMaxElementSize)
|
||||
printf("Row: reflow of cell returned result = %s with desired=%d,%d, min = %d,%d\n",
|
||||
NS_FRAME_IS_COMPLETE(status)?"complete":"NOT complete",
|
||||
desiredSize.width, desiredSize.height,
|
||||
pKidMaxElementSize->width, pKidMaxElementSize->height);
|
||||
else
|
||||
printf("Row: reflow of cell returned result = %s with desired=%d,%d, min = nsnull\n",
|
||||
NS_FRAME_IS_COMPLETE(status)?"complete":"NOT complete",
|
||||
desiredSize.width, desiredSize.height);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nsSize priorSize = ((nsTableCellFrame *)kidFrame)->GetDesiredSize();
|
||||
desiredSize.width = priorSize.width;
|
||||
desiredSize.height = priorSize.height;
|
||||
if (nsnull != pKidMaxElementSize)
|
||||
*pKidMaxElementSize = ((nsTableCellFrame *)kidFrame)->GetPass1MaxElementSize();
|
||||
}
|
||||
|
||||
// Place the child after taking into account its margin and attributes
|
||||
nscoord specifiedHeight = 0;
|
||||
nscoord cellHeight = desiredSize.height;
|
||||
nsIStyleContextPtr kidSC;
|
||||
kidFrame->GetStyleContext(kidSC.AssignPtr());
|
||||
const nsStylePosition* kidPosition = (const nsStylePosition*)
|
||||
kidSC->GetStyleData(eStyleStruct_Position);
|
||||
switch (kidPosition->mHeight.GetUnit()) {
|
||||
case eStyleUnit_Coord:
|
||||
specifiedHeight = kidPosition->mHeight.GetCoordValue();
|
||||
break;
|
||||
|
||||
case eStyleUnit_Inherit:
|
||||
// XXX for now, do nothing
|
||||
default:
|
||||
case eStyleUnit_Auto:
|
||||
break;
|
||||
}
|
||||
if (specifiedHeight>cellHeight)
|
||||
cellHeight = specifiedHeight;
|
||||
|
||||
nscoord cellWidth = desiredSize.width;
|
||||
// begin special Nav4 compatibility code
|
||||
if (0==cellWidth)
|
||||
{
|
||||
cellWidth = availWidth;
|
||||
}
|
||||
// end special Nav4 compatibility code
|
||||
|
||||
// Place the child
|
||||
nsRect kidRect (aReflowState.x, kidMargin.top, cellWidth, cellHeight);
|
||||
|
||||
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect, aDesiredSize.maxElementSize,
|
||||
pKidMaxElementSize);
|
||||
|
||||
if (PR_TRUE==gsDebug) printf("Row: past PlaceChild, aReflowState.x set to %d\n", aReflowState.x);
|
||||
}
|
||||
else
|
||||
{
|
||||
nsSize priorSize = ((nsTableCellFrame *)kidFrame)->GetDesiredSize();
|
||||
desiredSize.width = priorSize.width;
|
||||
desiredSize.height = priorSize.height;
|
||||
if (nsnull != pKidMaxElementSize)
|
||||
*pKidMaxElementSize = ((nsTableCellFrame *)kidFrame)->GetPass1MaxElementSize();
|
||||
{// it's an unknown frame type, give it a generic reflow and ignore the results
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState,
|
||||
kidFrame,
|
||||
nsSize(0,0), eReflowReason_Resize);
|
||||
nsHTMLReflowMetrics desiredSize(nsnull);
|
||||
if (PR_TRUE==gsDebug) printf("\nRow: Resize Reflow of unknown frame %p of type %d with reason=%d\n",
|
||||
kidFrame, kidDisplay->mDisplay, eReflowReason_Resize);
|
||||
nsReflowStatus status;
|
||||
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status);
|
||||
}
|
||||
|
||||
// Place the child after taking into account its margin and attributes
|
||||
nscoord specifiedHeight = 0;
|
||||
nscoord cellHeight = desiredSize.height;
|
||||
nsIStyleContextPtr kidSC;
|
||||
kidFrame->GetStyleContext(kidSC.AssignPtr());
|
||||
const nsStylePosition* kidPosition = (const nsStylePosition*)
|
||||
kidSC->GetStyleData(eStyleStruct_Position);
|
||||
switch (kidPosition->mHeight.GetUnit()) {
|
||||
case eStyleUnit_Coord:
|
||||
specifiedHeight = kidPosition->mHeight.GetCoordValue();
|
||||
break;
|
||||
|
||||
case eStyleUnit_Inherit:
|
||||
// XXX for now, do nothing
|
||||
default:
|
||||
case eStyleUnit_Auto:
|
||||
break;
|
||||
}
|
||||
if (specifiedHeight>cellHeight)
|
||||
cellHeight = specifiedHeight;
|
||||
|
||||
nscoord cellWidth = desiredSize.width;
|
||||
// begin special Nav4 compatibility code
|
||||
if (0==cellWidth)
|
||||
{
|
||||
cellWidth = availWidth;
|
||||
}
|
||||
// end special Nav4 compatibility code
|
||||
|
||||
// Place the child
|
||||
nsRect kidRect (aReflowState.x, kidMargin.top, cellWidth, cellHeight);
|
||||
|
||||
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect, aDesiredSize.maxElementSize,
|
||||
pKidMaxElementSize);
|
||||
|
||||
if (PR_TRUE==gsDebug) printf("Row: past PlaceChild, aReflowState.x set to %d\n", aReflowState.x);
|
||||
}
|
||||
else
|
||||
{// it's an unknown frame type, give it a generic reflow and ignore the results
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState,
|
||||
kidFrame,
|
||||
nsSize(0,0), eReflowReason_Resize);
|
||||
nsHTMLReflowMetrics desiredSize(nsnull);
|
||||
if (PR_TRUE==gsDebug) printf("\nRow: Resize Reflow of unknown frame %p of type %d with reason=%d\n",
|
||||
kidFrame, kidDisplay->mDisplay, eReflowReason_Resize);
|
||||
nsReflowStatus status;
|
||||
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status);
|
||||
}
|
||||
|
||||
kidFrame = iter.Next(); // Get the next child
|
||||
|
@ -1067,52 +1252,21 @@ NS_METHOD nsTableRowFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
|||
if (PR_TRUE==gsDebugIR) printf("TRF IR: IncrementalReflow_TargetIsMe with type=%d\n", type);
|
||||
switch (type)
|
||||
{
|
||||
case nsIReflowCommand::FrameInserted :
|
||||
NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame");
|
||||
NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay");
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_CellInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
(nsTableCellFrame *)objectFrame, PR_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = AddFrame(aReflowState.reflowState, objectFrame);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::FrameAppended :
|
||||
NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame");
|
||||
NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay");
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_CellAppended(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
(nsTableCellFrame *)objectFrame);
|
||||
}
|
||||
else
|
||||
{ // no optimization to be done for Unknown frame types, so just reuse the Inserted method
|
||||
rv = AddFrame(aReflowState.reflowState, objectFrame);
|
||||
}
|
||||
break;
|
||||
case nsIReflowCommand::ReflowDirty:
|
||||
{
|
||||
// Reflow the dirty child frames. Typically this is newly added frames.
|
||||
// XXX What we really should do is do a pass-1 reflow of newly added
|
||||
// frames (only if necessary, i.e., the table isn't fixed layout), then
|
||||
// see if column widtsh changed and decide whether to do the pass-2 reflow
|
||||
// of just the dirty rows or have the table rebalance column widths and
|
||||
// do a pass-2 reflow of all rows
|
||||
rv = ResizeReflow(aPresContext, aDesiredSize, aReflowState, aStatus, PR_TRUE);
|
||||
|
||||
/*
|
||||
case nsIReflowCommand::FrameReplaced :
|
||||
|
||||
*/
|
||||
|
||||
case nsIReflowCommand::FrameRemoved :
|
||||
NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame");
|
||||
NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay");
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_CellRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
(nsTableCellFrame *)objectFrame);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = mFrames.DestroyFrame(aPresContext, objectFrame);
|
||||
}
|
||||
// If any column widths have to change due to this, rebalance column widths.
|
||||
// XXX need to calculate this, but for now just do it
|
||||
aReflowState.tableFrame->InvalidateColumnWidths();
|
||||
break;
|
||||
}
|
||||
|
||||
case nsIReflowCommand::StyleChanged :
|
||||
rv = IR_StyleChanged(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
|
@ -1123,192 +1277,16 @@ NS_METHOD nsTableRowFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
|||
rv = NS_ERROR_ILLEGAL_VALUE;
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::PullupReflow:
|
||||
case nsIReflowCommand::PushReflow:
|
||||
case nsIReflowCommand::CheckPullupReflow :
|
||||
case nsIReflowCommand::UserDefined :
|
||||
default:
|
||||
NS_NOTYETIMPLEMENTED("unimplemented reflow command type");
|
||||
NS_NOTYETIMPLEMENTED("unexpected reflow command type");
|
||||
rv = NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (PR_TRUE==gsDebugIR) printf("TRF IR: reflow command not implemented.\n");
|
||||
if (PR_TRUE==gsDebugIR) printf("TRF IR: unexpected reflow command not implemented.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowFrame::IR_CellInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableCellFrame * aInsertedFrame,
|
||||
PRBool aReplace)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRF IR: IR_CellInserted\n");
|
||||
nsresult rv = AddFrame(aReflowState.reflowState, (nsIFrame*)aInsertedFrame);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || nsnull==tableFrame)
|
||||
return rv;
|
||||
|
||||
#if 0
|
||||
// do a pass-1 layout of the cell
|
||||
if (PR_TRUE==tableFrame->RequiresPass1Layout())
|
||||
{
|
||||
rv = InitialReflow(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
aInsertedFrame, PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
// set row state
|
||||
GetMinRowSpan(tableFrame);
|
||||
FixMinCellHeight(tableFrame);
|
||||
|
||||
// set table state
|
||||
tableFrame->InvalidateCellMap();
|
||||
tableFrame->InvalidateColumnCache();
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowFrame::IR_DidAppendCell(nsTableCellFrame *aRowFrame)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
// since we know we're doing an append here, we can optimize
|
||||
NS_METHOD nsTableRowFrame::IR_CellAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableCellFrame* aAppendedFrame)
|
||||
{
|
||||
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRF IR: IR_CellInserted\n");
|
||||
nsresult rv = AddFrame(aReflowState.reflowState, (nsIFrame*)aAppendedFrame);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || nsnull==tableFrame)
|
||||
return rv;
|
||||
|
||||
tableFrame->AddCellToTable(aAppendedFrame, GetRowIndex());
|
||||
// do a pass-1 layout of the cell
|
||||
if (PR_TRUE==tableFrame->RequiresPass1Layout())
|
||||
{
|
||||
rv = InitialReflow(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
aAppendedFrame, PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
// set row state
|
||||
GetMinRowSpan(tableFrame);
|
||||
FixMinCellHeight(tableFrame);
|
||||
|
||||
// set table state
|
||||
|
||||
tableFrame->InvalidateCellMap();
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
return rv;
|
||||
|
||||
|
||||
#if 0
|
||||
nsresult rv=NS_OK;
|
||||
// hook aAppendedFrame into the child list
|
||||
nsIFrame *lastChild = mFrames.FirstChild();
|
||||
nsIFrame *nextChild = lastChild;
|
||||
nsIFrame *lastRow = nsnull;
|
||||
while (nsnull!=nextChild)
|
||||
{
|
||||
// remember the last child that is really a cell
|
||||
const nsStyleDisplay *childDisplay;
|
||||
nextChild->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay)
|
||||
lastRow = nextChild;
|
||||
lastChild = nextChild;
|
||||
nextChild->GetNextSibling(nextChild);
|
||||
}
|
||||
if (nsnull==lastChild)
|
||||
mFirstChild = aAppendedFrame;
|
||||
else
|
||||
lastChild->SetNextSibling(aAppendedFrame);
|
||||
|
||||
aReflowState.tableFrame->InvalidateFirstPassCache();
|
||||
// the table will see that it's cached info is bogus and rebuild the cell map,
|
||||
// and do a reflow
|
||||
|
||||
|
||||
// find the col index of the new cell
|
||||
|
||||
// account for the new cell
|
||||
nsresult rv = DidAppendCell((nsTableCellFrame*)aAppendedFrame);
|
||||
|
||||
// need to increment the row index of all subsequent rows
|
||||
|
||||
|
||||
return rv;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowFrame::IR_CellRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableCellFrame* aDeletedFrame)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("\nRow IR: IR_RowRemoved\n");
|
||||
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || nsnull == tableFrame)
|
||||
return rv;
|
||||
|
||||
PRInt32 colIndex;
|
||||
aDeletedFrame->GetColIndex(colIndex);
|
||||
tableFrame->RemoveCellFromTable(aDeletedFrame, GetRowIndex());
|
||||
rv = mFrames.DestroyFrame(aPresContext, (nsIFrame*)aDeletedFrame);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
ResetMaxChildHeight();
|
||||
|
||||
// set row state
|
||||
GetMinRowSpan(tableFrame);
|
||||
FixMinCellHeight(tableFrame);
|
||||
|
||||
// set table state
|
||||
tableFrame->InvalidateCellMap();
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
#if 0
|
||||
nsresult rv = mFrames.DestroyFrame(aPresContext, (nsIFrame*)aDeletedFrame);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
ResetMaxChildHeight();
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || nsnull==tableFrame)
|
||||
return rv;
|
||||
#endif
|
||||
|
||||
// if any column widths have to change due to this, rebalance column widths
|
||||
//XXX need to calculate this, but for now just do it
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowFrame::IR_StyleChanged(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
|
|
|
@ -44,6 +44,20 @@ public:
|
|||
nsIStyleContext* aContext,
|
||||
nsIFrame* aPrevInFlow);
|
||||
|
||||
NS_IMETHOD AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList);
|
||||
NS_IMETHOD InsertFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList);
|
||||
NS_IMETHOD RemoveFrame(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
/** Initialization of data */
|
||||
NS_IMETHOD InitChildren();
|
||||
|
||||
|
@ -166,32 +180,15 @@ protected:
|
|||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD IR_CellInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableCellFrame * aInsertedFrame,
|
||||
PRBool aReplace);
|
||||
|
||||
NS_IMETHOD IR_CellAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableCellFrame * aAppendedFrame);
|
||||
|
||||
NS_IMETHOD IR_DidAppendCell(nsTableCellFrame *aRowFrame);
|
||||
|
||||
NS_IMETHOD IR_CellRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableCellFrame * aDeletedFrame);
|
||||
|
||||
NS_IMETHOD IR_StyleChanged(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
nsresult AddTableDirtyReflowCommand(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIFrame* aTableFrame);
|
||||
|
||||
// row-specific methods
|
||||
|
||||
void GetMinRowSpan(nsTableFrame *aTableFrame);
|
||||
|
@ -224,7 +221,8 @@ protected:
|
|||
NS_IMETHOD ResizeReflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
nsReflowStatus& aStatus,
|
||||
PRBool aDirtyOnly = PR_FALSE);
|
||||
|
||||
/**
|
||||
* Called for the initial reflow. Creates each table cell frame, and
|
||||
|
|
|
@ -424,6 +424,7 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC
|
|||
}
|
||||
}
|
||||
|
||||
// Reflow the row frame
|
||||
if (doReflowChild) {
|
||||
nsSize kidAvailSize(aReflowState.availSize);
|
||||
if (0>=kidAvailSize.height)
|
||||
|
@ -435,15 +436,22 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC
|
|||
// it wants. We'll deal with splitting later after we've computed the row
|
||||
// heights, taking into account cells with row spans...
|
||||
kidAvailSize.height = NS_UNCONSTRAINEDSIZE;
|
||||
nsReflowReason reason = aReason;
|
||||
if (aDirtyOnly) {
|
||||
if (frameState & NS_FRAME_FIRST_REFLOW) {
|
||||
// Newly inserted frame
|
||||
aReason = eReflowReason_Initial;
|
||||
reason = eReflowReason_Initial;
|
||||
}
|
||||
}
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState, kidFrame,
|
||||
kidAvailSize, aReason);
|
||||
kidAvailSize, reason);
|
||||
|
||||
// If this isn't the first row frame, then we can't be at the top of
|
||||
// the page anymore...
|
||||
if (kidFrame != GetFirstFrame()) {
|
||||
kidReflowState.isTopOfPage = PR_FALSE;
|
||||
}
|
||||
|
||||
if (aReflowState.tableFrame->RowGroupsShouldBeConstrained()) {
|
||||
// Only applies to the tree widget.
|
||||
const nsStyleDisplay *rowDisplay;
|
||||
|
@ -454,19 +462,14 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC
|
|||
}
|
||||
}
|
||||
|
||||
if (kidFrame != GetFirstFrame()) {
|
||||
// If this isn't the first row frame, then we can't be at the top of
|
||||
// the page anymore...
|
||||
kidReflowState.isTopOfPage = PR_FALSE;
|
||||
}
|
||||
|
||||
if ((PR_TRUE==gsDebug) || (PR_TRUE==gsDebugIR))
|
||||
printf("%p RG reflowing child %p with avail width = %d, reason = %d\n",
|
||||
this, kidFrame, kidAvailSize.width, aReason);
|
||||
this, kidFrame, kidAvailSize.width, reason);
|
||||
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, aStatus);
|
||||
if (gsDebug) printf("%p RG child %p returned desired width = %d\n",
|
||||
this, kidFrame, desiredSize.width);
|
||||
|
||||
// Place the child
|
||||
nsRect kidRect (0, aReflowState.y, desiredSize.width, desiredSize.height);
|
||||
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect, aDesiredSize.maxElementSize,
|
||||
kidMaxElementSize);
|
||||
|
@ -507,6 +510,13 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC
|
|||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Adjust the running y-offset so we know where the next row should
|
||||
// be placed
|
||||
nsSize kidSize;
|
||||
|
||||
kidFrame->GetSize(kidSize);
|
||||
aReflowState.y += kidSize.height;
|
||||
}
|
||||
|
||||
if (PR_FALSE==aDoSiblings)
|
||||
|
@ -1251,13 +1261,11 @@ nsTableRowGroupFrame::RemoveFrame(nsIPresContext& aPresContext,
|
|||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
nsresult rv;
|
||||
const nsStyleDisplay *display;
|
||||
aOldFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display));
|
||||
|
||||
// Remove the frame and destroy it
|
||||
rv = mFrames.DestroyFrame(aPresContext, aOldFrame);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (mFrames.DestroyFrame(aPresContext, aOldFrame)) {
|
||||
if ((NS_STYLE_DISPLAY_TABLE_ROW == display->mDisplay) ||
|
||||
(NS_STYLE_DISPLAY_TABLE_ROW_GROUP == display->mDisplay)) {
|
||||
// Get the table frame
|
||||
|
@ -1279,7 +1287,7 @@ nsTableRowGroupFrame::RemoveFrame(nsIPresContext& aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
|
@ -1299,17 +1307,17 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
|||
switch (type)
|
||||
{
|
||||
case nsIReflowCommand::ReflowDirty:
|
||||
// Reflow the dirty child frames
|
||||
// Reflow the dirty child frames. Typically this is newly added frames.
|
||||
// XXX What we really should do is do a pass-1 reflow of newly added
|
||||
// frames (only if necessary--because the table isn't fixed layout), then
|
||||
// frames (only if necessary, i.e., the table isn't fixed layout), then
|
||||
// see if column widtsh changed and decide whether to do the pass-2 reflow
|
||||
// of just the dirty rows or have the table rebalance column widths and
|
||||
// do a pass-2 reflow of all rows
|
||||
rv = ReflowMappedChildren(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
nsnull, aReflowState.reflowState.reason, PR_TRUE, PR_TRUE);
|
||||
|
||||
// If any column widths have to change due to this, rebalance column widths
|
||||
//XXX need to calculate this, but for now just do it
|
||||
// If any column widths have to change due to this, rebalance column widths.
|
||||
// XXX need to calculate this, but for now just do it
|
||||
aReflowState.tableFrame->InvalidateColumnWidths();
|
||||
break;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче