зеркало из https://github.com/mozilla/pjs.git
support for right-to-left direction
This commit is contained in:
Родитель
aa8cbffd9b
Коммит
cea85eaf3b
|
@ -2962,6 +2962,7 @@ NS_METHOD nsTableFrame::AdjustForCollapsingCols(nsIPresContext& aPresContext,
|
|||
{
|
||||
// determine which col groups and cols are collapsed
|
||||
nsIFrame* childFrame = mColGroups.FirstChild();
|
||||
PRInt32 colX = 0;
|
||||
while (nsnull != childFrame) {
|
||||
const nsStyleDisplay* groupDisplay;
|
||||
GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)groupDisplay));
|
||||
|
@ -2969,7 +2970,6 @@ NS_METHOD nsTableFrame::AdjustForCollapsingCols(nsIPresContext& aPresContext,
|
|||
|
||||
nsTableColFrame* colFrame = nsnull;
|
||||
childFrame->FirstChild(nsnull, (nsIFrame**)&colFrame);
|
||||
PRInt32 colX = 0;
|
||||
while (nsnull != colFrame) {
|
||||
const nsStyleDisplay *colDisplay;
|
||||
colFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)colDisplay));
|
||||
|
@ -2988,18 +2988,22 @@ NS_METHOD nsTableFrame::AdjustForCollapsingCols(nsIPresContext& aPresContext,
|
|||
return NS_OK; // no collapsed cols, we're done
|
||||
}
|
||||
|
||||
PRInt32 numCols = colX;
|
||||
|
||||
// collapse the cols and/or col groups
|
||||
PRInt32 numRows = mCellMap->GetRowCount();
|
||||
nsIFrame* groupFrame = mColGroups.FirstChild();
|
||||
nsTableIterator groupIter(mColGroups, PR_TRUE);
|
||||
nsIFrame* groupFrame = groupIter.First();
|
||||
nscoord cellSpacingX = GetCellSpacingX();
|
||||
nscoord xOffset = 0;
|
||||
PRInt32 colX = 0;
|
||||
colX = (groupIter.IsLeftToRight()) ? 0 : numCols - 1;
|
||||
PRInt32 direction = (groupIter.IsLeftToRight()) ? 1 : -1;
|
||||
while (nsnull != groupFrame) {
|
||||
const nsStyleDisplay* groupDisplay;
|
||||
groupFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)groupDisplay));
|
||||
PRBool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE == groupDisplay->mVisible);
|
||||
nsIFrame* colFrame;
|
||||
groupFrame->FirstChild(nsnull, &colFrame);
|
||||
nsTableIterator colIter(*groupFrame, PR_TRUE);
|
||||
nsIFrame* colFrame = colIter.First();
|
||||
while (nsnull != colFrame) {
|
||||
const nsStyleDisplay* colDisplay;
|
||||
colFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)colDisplay));
|
||||
|
@ -3007,14 +3011,15 @@ NS_METHOD nsTableFrame::AdjustForCollapsingCols(nsIPresContext& aPresContext,
|
|||
PRBool collapseCol = (NS_STYLE_VISIBILITY_COLLAPSE == colDisplay->mVisible);
|
||||
PRInt32 colSpan = ((nsTableColFrame*)colFrame)->GetSpan();
|
||||
for (PRInt32 spanX = 0; spanX < colSpan; spanX++) {
|
||||
PRInt32 colWidth = GetColumnWidth(colX+spanX);
|
||||
PRInt32 col2X = colX + (direction * spanX);
|
||||
PRInt32 colWidth = GetColumnWidth(col2X);
|
||||
if (collapseGroup || collapseCol) {
|
||||
xOffset += colWidth + cellSpacingX;
|
||||
}
|
||||
nsTableCellFrame* lastCell = nsnull;
|
||||
nsTableCellFrame* cellFrame = nsnull;
|
||||
for (PRInt32 rowX = 0; rowX < numRows; rowX++) {
|
||||
CellData* cellData = mCellMap->GetCellAt(rowX, colX+spanX);
|
||||
CellData* cellData = mCellMap->GetCellAt(rowX, col2X);
|
||||
nsRect cellRect;
|
||||
if (cellData) {
|
||||
cellFrame = cellData->mCell;
|
||||
|
@ -3042,11 +3047,11 @@ NS_METHOD nsTableFrame::AdjustForCollapsingCols(nsIPresContext& aPresContext,
|
|||
lastCell = cellFrame;
|
||||
}
|
||||
}
|
||||
colX += colSpan;
|
||||
colX += direction * colSpan;
|
||||
}
|
||||
colFrame->GetNextSibling(&colFrame);
|
||||
colFrame = colIter.Next();
|
||||
} // inner while
|
||||
groupFrame->GetNextSibling(&groupFrame);
|
||||
groupFrame = groupIter.Next();
|
||||
} // outer while
|
||||
|
||||
aWidth -= xOffset;
|
||||
|
@ -5295,3 +5300,104 @@ nsTableFrame::IsFinalPass(const nsReflowState& aState)
|
|||
return (NS_UNCONSTRAINEDSIZE != aState.availableWidth) ||
|
||||
(NS_UNCONSTRAINEDSIZE != aState.availableHeight);
|
||||
}
|
||||
|
||||
// nsTableIterator
|
||||
nsTableIterator::nsTableIterator(nsIFrame& aSource,
|
||||
PRBool aUseDirection)
|
||||
{
|
||||
nsIFrame* firstChild;
|
||||
aSource.FirstChild(nsnull, &firstChild);
|
||||
Init(firstChild, aUseDirection);
|
||||
}
|
||||
|
||||
nsTableIterator::nsTableIterator(nsFrameList& aSource,
|
||||
PRBool aUseDirection)
|
||||
{
|
||||
nsIFrame* firstChild = aSource.FirstChild();
|
||||
Init(firstChild, aUseDirection);
|
||||
}
|
||||
|
||||
void nsTableIterator::Init(nsIFrame* aFirstChild,
|
||||
PRBool aUseDirection)
|
||||
{
|
||||
mFirstListChild = aFirstChild;
|
||||
mFirstChild = aFirstChild;
|
||||
mCurrentChild = nsnull;
|
||||
mLeftToRight = PR_TRUE;
|
||||
mCount = -1;
|
||||
|
||||
if (!mFirstChild) {
|
||||
return;
|
||||
}
|
||||
if (aUseDirection) {
|
||||
nsTableFrame* table = nsnull;
|
||||
nsresult rv = nsTableFrame::GetTableFrame(mFirstChild, table);
|
||||
if (NS_SUCCEEDED(rv) && (table != nsnull)) {
|
||||
const nsStyleDisplay* display;
|
||||
table->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display);
|
||||
mLeftToRight = (NS_STYLE_DIRECTION_LTR == display->mDirection);
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(PR_FALSE, "source of table iterator is not part of a table");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!mLeftToRight) {
|
||||
mCount = 0;
|
||||
nsIFrame* nextChild;
|
||||
mFirstChild->GetNextSibling(&nextChild);
|
||||
while (nsnull != nextChild) {
|
||||
mCount++;
|
||||
mFirstChild = nextChild;
|
||||
nextChild->GetNextSibling(&nextChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsIFrame* nsTableIterator::First()
|
||||
{
|
||||
mCurrentChild = mFirstChild;
|
||||
return mCurrentChild;
|
||||
}
|
||||
|
||||
nsIFrame* nsTableIterator::Next()
|
||||
{
|
||||
if (!mCurrentChild) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (mLeftToRight) {
|
||||
mCurrentChild->GetNextSibling(&mCurrentChild);
|
||||
return mCurrentChild;
|
||||
}
|
||||
else {
|
||||
nsIFrame* targetChild = mCurrentChild;
|
||||
mCurrentChild = nsnull;
|
||||
nsIFrame* child = mFirstListChild;
|
||||
while (child && (child != targetChild)) {
|
||||
mCurrentChild = child;
|
||||
child->GetNextSibling(&child);
|
||||
}
|
||||
return mCurrentChild;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool nsTableIterator::IsLeftToRight()
|
||||
{
|
||||
return mLeftToRight;
|
||||
}
|
||||
|
||||
PRInt32 nsTableIterator::Count()
|
||||
{
|
||||
if (-1 == mCount) {
|
||||
mCount = 0;
|
||||
nsIFrame* child = mFirstListChild;
|
||||
while (nsnull != child) {
|
||||
mCount++;
|
||||
child->GetNextSibling(&child);
|
||||
}
|
||||
}
|
||||
return mCount;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -844,6 +844,28 @@ inline PRBool nsTableFrame::IsRowGroup(PRInt32 aDisplayType) const
|
|||
(NS_STYLE_DISPLAY_TABLE_ROW_GROUP == aDisplayType));
|
||||
}
|
||||
|
||||
class nsTableIterator
|
||||
{
|
||||
public:
|
||||
nsTableIterator(nsIFrame& aSource,
|
||||
PRBool aUseDirection);
|
||||
nsTableIterator(nsFrameList& aSource,
|
||||
PRBool aUseDirection);
|
||||
nsIFrame* First();
|
||||
nsIFrame* Next();
|
||||
PRBool IsLeftToRight();
|
||||
PRInt32 Count();
|
||||
|
||||
protected:
|
||||
void Init(nsIFrame* aFirstChild,
|
||||
PRBool aUseDirection);
|
||||
PRBool mLeftToRight;
|
||||
nsIFrame* mFirstListChild;
|
||||
nsIFrame* mFirstChild;
|
||||
nsIFrame* mCurrentChild;
|
||||
PRInt32 mCount;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ static const PRBool gsDebug = PR_FALSE;
|
|||
static const PRBool gsDebugIR = PR_FALSE;
|
||||
#endif
|
||||
|
||||
|
||||
/* ----------- RowReflowState ---------- */
|
||||
|
||||
struct RowReflowState {
|
||||
|
@ -192,7 +193,8 @@ nsTableRowFrame::DidResize(nsIPresContext& aPresContext,
|
|||
// Resize and re-align the cell frames based on our row height
|
||||
nscoord cellHeight = mRect.height - mCellMaxTopMargin - mCellMaxBottomMargin;
|
||||
if (gsDebug) printf("Row DidReflow: cellHeight=%d\n", cellHeight);
|
||||
nsIFrame *cellFrame = mFrames.FirstChild();
|
||||
nsTableIterator iter(*this, PR_TRUE);
|
||||
nsIFrame* cellFrame = iter.First();
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
const nsStyleTable* tableStyle;
|
||||
|
@ -249,7 +251,7 @@ nsTableRowFrame::DidResize(nsIPresContext& aPresContext,
|
|||
}
|
||||
}
|
||||
// Get the next cell
|
||||
cellFrame->GetNextSibling(&cellFrame);
|
||||
cellFrame = iter.Next();
|
||||
}
|
||||
|
||||
// Let our base class do the usual work
|
||||
|
@ -484,22 +486,6 @@ void nsTableRowFrame::PlaceChild(nsIPresContext& aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
nsIFrame * nsTableRowFrame::GetNextChildForDirection(PRUint8 aDir, nsIFrame *aCurrentChild)
|
||||
{
|
||||
NS_ASSERTION(nsnull!=aCurrentChild, "bad arg");
|
||||
|
||||
nsIFrame *result=nsnull;
|
||||
aCurrentChild->GetNextSibling(&result);
|
||||
return result;
|
||||
}
|
||||
|
||||
nsIFrame * nsTableRowFrame::GetFirstChildForDirection(PRUint8 aDir)
|
||||
{
|
||||
nsIFrame *result=nsnull;
|
||||
result = mFrames.FirstChild();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called for a resize reflow. Typically because the column widths have
|
||||
* changed. Reflows all the existing table cell frames
|
||||
|
@ -510,12 +496,16 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
|||
nsReflowStatus& aStatus)
|
||||
{
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
if (nsnull == mFrames.FirstChild())
|
||||
if (nsnull == mFrames.FirstChild()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool isPass2Reflow = (aReflowState.reflowState.availableWidth == NS_UNCONSTRAINEDSIZE)
|
||||
? PR_FALSE : PR_TRUE;
|
||||
nsTableIterator iter(*this, isPass2Reflow);
|
||||
|
||||
nsresult rv=NS_OK;
|
||||
nsSize kidMaxElementSize;
|
||||
PRInt32 prevColIndex = -1; // remember the col index of the previous cell to handle rowspans into this row
|
||||
nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ?
|
||||
&kidMaxElementSize : nsnull;
|
||||
nscoord maxCellTopMargin = 0;
|
||||
|
@ -523,17 +513,25 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
|||
nscoord cellSpacingX = aReflowState.tableFrame->GetCellSpacingX();
|
||||
PRInt32 cellColSpan=1; // must be defined here so it's set properly for non-cell kids
|
||||
if (PR_TRUE==gsDebug) printf("Row %p: Resize Reflow\n", this);
|
||||
|
||||
PRInt32 prevColIndex; // remember the col index of the previous cell to handle rowspans into this row
|
||||
PRBool firstTime = PR_TRUE;
|
||||
|
||||
// Reflow each of our existing cell frames
|
||||
const nsStyleDisplay *rowDisplay;
|
||||
GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)rowDisplay);
|
||||
nsIFrame* kidFrame=GetFirstChildForDirection(rowDisplay->mDirection);
|
||||
while (nsnull != kidFrame)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay) {
|
||||
PRInt32 cellColIndex;
|
||||
((nsTableCellFrame *)kidFrame)->GetColIndex(cellColIndex);
|
||||
cellColSpan = aReflowState.tableFrame->GetEffectiveColSpan(cellColIndex,
|
||||
((nsTableCellFrame *)kidFrame));
|
||||
if (firstTime) { // set the prevColIndex
|
||||
prevColIndex = (iter.IsLeftToRight()) ? -1 : cellColIndex + cellColSpan;
|
||||
firstTime = PR_FALSE;
|
||||
}
|
||||
|
||||
nsMargin kidMargin;
|
||||
aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame,kidMargin);
|
||||
if (kidMargin.top > maxCellTopMargin)
|
||||
|
@ -543,28 +541,36 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
|||
|
||||
// Compute the x-origin for the child, taking into account straddlers (cells from prior
|
||||
// rows with rowspans > 1)
|
||||
PRInt32 cellColIndex;
|
||||
((nsTableCellFrame *)kidFrame)->GetColIndex(cellColIndex);
|
||||
if (prevColIndex != (cellColIndex-1))
|
||||
{ // if this cell is not immediately adjacent to the previous cell, factor in missing col info
|
||||
for (PRInt32 colIndex=prevColIndex+1; colIndex<cellColIndex; colIndex++)
|
||||
{
|
||||
aReflowState.x += aReflowState.tableFrame->GetColumnWidth(colIndex);
|
||||
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 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);
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (prevColIndex != cellColIndex + cellColSpan) {
|
||||
PRInt32 lastCol = cellColIndex + cellColSpan - 1;
|
||||
for (PRInt32 colIndex = prevColIndex - 1; colIndex > lastCol; colIndex--) {
|
||||
aReflowState.x += aReflowState.tableFrame->GetColumnWidth(colIndex);
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
PRInt32 baseColIndex;
|
||||
((nsTableCellFrame *)kidFrame)->GetColIndex(baseColIndex);
|
||||
cellColSpan = aReflowState.tableFrame->GetEffectiveColSpan(baseColIndex,
|
||||
((nsTableCellFrame *)kidFrame));
|
||||
nscoord availWidth = 0;
|
||||
for (PRInt32 numColSpan=0; numColSpan<cellColSpan; numColSpan++)
|
||||
{
|
||||
|
@ -578,8 +584,8 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
|||
availWidth, cellColIndex, aReflowState.tableFrame->GetColumnWidth(cellColIndex+numColSpan));
|
||||
}
|
||||
if (PR_TRUE==gsDebug) printf(" Row: availWidth for this cell is %d\n", availWidth);
|
||||
|
||||
prevColIndex = cellColIndex + (cellColSpan-1); // remember the rightmost column this cell spans into
|
||||
// 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,
|
||||
|
@ -689,8 +695,7 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
|||
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status);
|
||||
}
|
||||
|
||||
// Get the next child
|
||||
kidFrame = GetNextChildForDirection(rowDisplay->mDirection, kidFrame);
|
||||
kidFrame = iter.Next(); // Get the next child
|
||||
// if this was the last child, and it had a colspan>1, add in the cellSpacing for the colspan
|
||||
// if the last kid wasn't a colspan, then we still have the colspan of the last real cell
|
||||
if ((nsnull==kidFrame) && (cellColSpan>1))
|
||||
|
@ -1543,3 +1548,6 @@ nsTableRowFrame::GetFrameName(nsString& aResult) const
|
|||
{
|
||||
return MakeFrameName("TableRow", aResult);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -217,9 +217,6 @@ protected:
|
|||
nscoord ComputeCellAvailWidth(const RowReflowState& aState,
|
||||
nsIFrame* aKidFrame) const;
|
||||
|
||||
nsIFrame * GetFirstChildForDirection(PRUint8 aDir);
|
||||
nsIFrame * GetNextChildForDirection(PRUint8 aDir, nsIFrame *aCurrentChild);
|
||||
|
||||
/**
|
||||
* Called for a resize reflow. Typically because the column widths have
|
||||
* changed. Reflows all the existing table cell frames
|
||||
|
@ -249,7 +246,7 @@ private:
|
|||
PRBool mInitializedChildren; // PR_TRUE if child cells have been initialized
|
||||
// (for now, that means "added to the table", and
|
||||
// is NOT the same as having nsIFrame::Init() called.)
|
||||
|
||||
|
||||
};
|
||||
|
||||
inline PRInt32 nsTableRowFrame::GetRowIndex() const
|
||||
|
|
|
@ -2962,6 +2962,7 @@ NS_METHOD nsTableFrame::AdjustForCollapsingCols(nsIPresContext& aPresContext,
|
|||
{
|
||||
// determine which col groups and cols are collapsed
|
||||
nsIFrame* childFrame = mColGroups.FirstChild();
|
||||
PRInt32 colX = 0;
|
||||
while (nsnull != childFrame) {
|
||||
const nsStyleDisplay* groupDisplay;
|
||||
GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)groupDisplay));
|
||||
|
@ -2969,7 +2970,6 @@ NS_METHOD nsTableFrame::AdjustForCollapsingCols(nsIPresContext& aPresContext,
|
|||
|
||||
nsTableColFrame* colFrame = nsnull;
|
||||
childFrame->FirstChild(nsnull, (nsIFrame**)&colFrame);
|
||||
PRInt32 colX = 0;
|
||||
while (nsnull != colFrame) {
|
||||
const nsStyleDisplay *colDisplay;
|
||||
colFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)colDisplay));
|
||||
|
@ -2988,18 +2988,22 @@ NS_METHOD nsTableFrame::AdjustForCollapsingCols(nsIPresContext& aPresContext,
|
|||
return NS_OK; // no collapsed cols, we're done
|
||||
}
|
||||
|
||||
PRInt32 numCols = colX;
|
||||
|
||||
// collapse the cols and/or col groups
|
||||
PRInt32 numRows = mCellMap->GetRowCount();
|
||||
nsIFrame* groupFrame = mColGroups.FirstChild();
|
||||
nsTableIterator groupIter(mColGroups, PR_TRUE);
|
||||
nsIFrame* groupFrame = groupIter.First();
|
||||
nscoord cellSpacingX = GetCellSpacingX();
|
||||
nscoord xOffset = 0;
|
||||
PRInt32 colX = 0;
|
||||
colX = (groupIter.IsLeftToRight()) ? 0 : numCols - 1;
|
||||
PRInt32 direction = (groupIter.IsLeftToRight()) ? 1 : -1;
|
||||
while (nsnull != groupFrame) {
|
||||
const nsStyleDisplay* groupDisplay;
|
||||
groupFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)groupDisplay));
|
||||
PRBool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE == groupDisplay->mVisible);
|
||||
nsIFrame* colFrame;
|
||||
groupFrame->FirstChild(nsnull, &colFrame);
|
||||
nsTableIterator colIter(*groupFrame, PR_TRUE);
|
||||
nsIFrame* colFrame = colIter.First();
|
||||
while (nsnull != colFrame) {
|
||||
const nsStyleDisplay* colDisplay;
|
||||
colFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)colDisplay));
|
||||
|
@ -3007,14 +3011,15 @@ NS_METHOD nsTableFrame::AdjustForCollapsingCols(nsIPresContext& aPresContext,
|
|||
PRBool collapseCol = (NS_STYLE_VISIBILITY_COLLAPSE == colDisplay->mVisible);
|
||||
PRInt32 colSpan = ((nsTableColFrame*)colFrame)->GetSpan();
|
||||
for (PRInt32 spanX = 0; spanX < colSpan; spanX++) {
|
||||
PRInt32 colWidth = GetColumnWidth(colX+spanX);
|
||||
PRInt32 col2X = colX + (direction * spanX);
|
||||
PRInt32 colWidth = GetColumnWidth(col2X);
|
||||
if (collapseGroup || collapseCol) {
|
||||
xOffset += colWidth + cellSpacingX;
|
||||
}
|
||||
nsTableCellFrame* lastCell = nsnull;
|
||||
nsTableCellFrame* cellFrame = nsnull;
|
||||
for (PRInt32 rowX = 0; rowX < numRows; rowX++) {
|
||||
CellData* cellData = mCellMap->GetCellAt(rowX, colX+spanX);
|
||||
CellData* cellData = mCellMap->GetCellAt(rowX, col2X);
|
||||
nsRect cellRect;
|
||||
if (cellData) {
|
||||
cellFrame = cellData->mCell;
|
||||
|
@ -3042,11 +3047,11 @@ NS_METHOD nsTableFrame::AdjustForCollapsingCols(nsIPresContext& aPresContext,
|
|||
lastCell = cellFrame;
|
||||
}
|
||||
}
|
||||
colX += colSpan;
|
||||
colX += direction * colSpan;
|
||||
}
|
||||
colFrame->GetNextSibling(&colFrame);
|
||||
colFrame = colIter.Next();
|
||||
} // inner while
|
||||
groupFrame->GetNextSibling(&groupFrame);
|
||||
groupFrame = groupIter.Next();
|
||||
} // outer while
|
||||
|
||||
aWidth -= xOffset;
|
||||
|
@ -5295,3 +5300,104 @@ nsTableFrame::IsFinalPass(const nsReflowState& aState)
|
|||
return (NS_UNCONSTRAINEDSIZE != aState.availableWidth) ||
|
||||
(NS_UNCONSTRAINEDSIZE != aState.availableHeight);
|
||||
}
|
||||
|
||||
// nsTableIterator
|
||||
nsTableIterator::nsTableIterator(nsIFrame& aSource,
|
||||
PRBool aUseDirection)
|
||||
{
|
||||
nsIFrame* firstChild;
|
||||
aSource.FirstChild(nsnull, &firstChild);
|
||||
Init(firstChild, aUseDirection);
|
||||
}
|
||||
|
||||
nsTableIterator::nsTableIterator(nsFrameList& aSource,
|
||||
PRBool aUseDirection)
|
||||
{
|
||||
nsIFrame* firstChild = aSource.FirstChild();
|
||||
Init(firstChild, aUseDirection);
|
||||
}
|
||||
|
||||
void nsTableIterator::Init(nsIFrame* aFirstChild,
|
||||
PRBool aUseDirection)
|
||||
{
|
||||
mFirstListChild = aFirstChild;
|
||||
mFirstChild = aFirstChild;
|
||||
mCurrentChild = nsnull;
|
||||
mLeftToRight = PR_TRUE;
|
||||
mCount = -1;
|
||||
|
||||
if (!mFirstChild) {
|
||||
return;
|
||||
}
|
||||
if (aUseDirection) {
|
||||
nsTableFrame* table = nsnull;
|
||||
nsresult rv = nsTableFrame::GetTableFrame(mFirstChild, table);
|
||||
if (NS_SUCCEEDED(rv) && (table != nsnull)) {
|
||||
const nsStyleDisplay* display;
|
||||
table->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display);
|
||||
mLeftToRight = (NS_STYLE_DIRECTION_LTR == display->mDirection);
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(PR_FALSE, "source of table iterator is not part of a table");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!mLeftToRight) {
|
||||
mCount = 0;
|
||||
nsIFrame* nextChild;
|
||||
mFirstChild->GetNextSibling(&nextChild);
|
||||
while (nsnull != nextChild) {
|
||||
mCount++;
|
||||
mFirstChild = nextChild;
|
||||
nextChild->GetNextSibling(&nextChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsIFrame* nsTableIterator::First()
|
||||
{
|
||||
mCurrentChild = mFirstChild;
|
||||
return mCurrentChild;
|
||||
}
|
||||
|
||||
nsIFrame* nsTableIterator::Next()
|
||||
{
|
||||
if (!mCurrentChild) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (mLeftToRight) {
|
||||
mCurrentChild->GetNextSibling(&mCurrentChild);
|
||||
return mCurrentChild;
|
||||
}
|
||||
else {
|
||||
nsIFrame* targetChild = mCurrentChild;
|
||||
mCurrentChild = nsnull;
|
||||
nsIFrame* child = mFirstListChild;
|
||||
while (child && (child != targetChild)) {
|
||||
mCurrentChild = child;
|
||||
child->GetNextSibling(&child);
|
||||
}
|
||||
return mCurrentChild;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool nsTableIterator::IsLeftToRight()
|
||||
{
|
||||
return mLeftToRight;
|
||||
}
|
||||
|
||||
PRInt32 nsTableIterator::Count()
|
||||
{
|
||||
if (-1 == mCount) {
|
||||
mCount = 0;
|
||||
nsIFrame* child = mFirstListChild;
|
||||
while (nsnull != child) {
|
||||
mCount++;
|
||||
child->GetNextSibling(&child);
|
||||
}
|
||||
}
|
||||
return mCount;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -844,6 +844,28 @@ inline PRBool nsTableFrame::IsRowGroup(PRInt32 aDisplayType) const
|
|||
(NS_STYLE_DISPLAY_TABLE_ROW_GROUP == aDisplayType));
|
||||
}
|
||||
|
||||
class nsTableIterator
|
||||
{
|
||||
public:
|
||||
nsTableIterator(nsIFrame& aSource,
|
||||
PRBool aUseDirection);
|
||||
nsTableIterator(nsFrameList& aSource,
|
||||
PRBool aUseDirection);
|
||||
nsIFrame* First();
|
||||
nsIFrame* Next();
|
||||
PRBool IsLeftToRight();
|
||||
PRInt32 Count();
|
||||
|
||||
protected:
|
||||
void Init(nsIFrame* aFirstChild,
|
||||
PRBool aUseDirection);
|
||||
PRBool mLeftToRight;
|
||||
nsIFrame* mFirstListChild;
|
||||
nsIFrame* mFirstChild;
|
||||
nsIFrame* mCurrentChild;
|
||||
PRInt32 mCount;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ static const PRBool gsDebug = PR_FALSE;
|
|||
static const PRBool gsDebugIR = PR_FALSE;
|
||||
#endif
|
||||
|
||||
|
||||
/* ----------- RowReflowState ---------- */
|
||||
|
||||
struct RowReflowState {
|
||||
|
@ -192,7 +193,8 @@ nsTableRowFrame::DidResize(nsIPresContext& aPresContext,
|
|||
// Resize and re-align the cell frames based on our row height
|
||||
nscoord cellHeight = mRect.height - mCellMaxTopMargin - mCellMaxBottomMargin;
|
||||
if (gsDebug) printf("Row DidReflow: cellHeight=%d\n", cellHeight);
|
||||
nsIFrame *cellFrame = mFrames.FirstChild();
|
||||
nsTableIterator iter(*this, PR_TRUE);
|
||||
nsIFrame* cellFrame = iter.First();
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
const nsStyleTable* tableStyle;
|
||||
|
@ -249,7 +251,7 @@ nsTableRowFrame::DidResize(nsIPresContext& aPresContext,
|
|||
}
|
||||
}
|
||||
// Get the next cell
|
||||
cellFrame->GetNextSibling(&cellFrame);
|
||||
cellFrame = iter.Next();
|
||||
}
|
||||
|
||||
// Let our base class do the usual work
|
||||
|
@ -484,22 +486,6 @@ void nsTableRowFrame::PlaceChild(nsIPresContext& aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
nsIFrame * nsTableRowFrame::GetNextChildForDirection(PRUint8 aDir, nsIFrame *aCurrentChild)
|
||||
{
|
||||
NS_ASSERTION(nsnull!=aCurrentChild, "bad arg");
|
||||
|
||||
nsIFrame *result=nsnull;
|
||||
aCurrentChild->GetNextSibling(&result);
|
||||
return result;
|
||||
}
|
||||
|
||||
nsIFrame * nsTableRowFrame::GetFirstChildForDirection(PRUint8 aDir)
|
||||
{
|
||||
nsIFrame *result=nsnull;
|
||||
result = mFrames.FirstChild();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called for a resize reflow. Typically because the column widths have
|
||||
* changed. Reflows all the existing table cell frames
|
||||
|
@ -510,12 +496,16 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
|||
nsReflowStatus& aStatus)
|
||||
{
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
if (nsnull == mFrames.FirstChild())
|
||||
if (nsnull == mFrames.FirstChild()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool isPass2Reflow = (aReflowState.reflowState.availableWidth == NS_UNCONSTRAINEDSIZE)
|
||||
? PR_FALSE : PR_TRUE;
|
||||
nsTableIterator iter(*this, isPass2Reflow);
|
||||
|
||||
nsresult rv=NS_OK;
|
||||
nsSize kidMaxElementSize;
|
||||
PRInt32 prevColIndex = -1; // remember the col index of the previous cell to handle rowspans into this row
|
||||
nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ?
|
||||
&kidMaxElementSize : nsnull;
|
||||
nscoord maxCellTopMargin = 0;
|
||||
|
@ -523,17 +513,25 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
|||
nscoord cellSpacingX = aReflowState.tableFrame->GetCellSpacingX();
|
||||
PRInt32 cellColSpan=1; // must be defined here so it's set properly for non-cell kids
|
||||
if (PR_TRUE==gsDebug) printf("Row %p: Resize Reflow\n", this);
|
||||
|
||||
PRInt32 prevColIndex; // remember the col index of the previous cell to handle rowspans into this row
|
||||
PRBool firstTime = PR_TRUE;
|
||||
|
||||
// Reflow each of our existing cell frames
|
||||
const nsStyleDisplay *rowDisplay;
|
||||
GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)rowDisplay);
|
||||
nsIFrame* kidFrame=GetFirstChildForDirection(rowDisplay->mDirection);
|
||||
while (nsnull != kidFrame)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay) {
|
||||
PRInt32 cellColIndex;
|
||||
((nsTableCellFrame *)kidFrame)->GetColIndex(cellColIndex);
|
||||
cellColSpan = aReflowState.tableFrame->GetEffectiveColSpan(cellColIndex,
|
||||
((nsTableCellFrame *)kidFrame));
|
||||
if (firstTime) { // set the prevColIndex
|
||||
prevColIndex = (iter.IsLeftToRight()) ? -1 : cellColIndex + cellColSpan;
|
||||
firstTime = PR_FALSE;
|
||||
}
|
||||
|
||||
nsMargin kidMargin;
|
||||
aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame,kidMargin);
|
||||
if (kidMargin.top > maxCellTopMargin)
|
||||
|
@ -543,28 +541,36 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
|||
|
||||
// Compute the x-origin for the child, taking into account straddlers (cells from prior
|
||||
// rows with rowspans > 1)
|
||||
PRInt32 cellColIndex;
|
||||
((nsTableCellFrame *)kidFrame)->GetColIndex(cellColIndex);
|
||||
if (prevColIndex != (cellColIndex-1))
|
||||
{ // if this cell is not immediately adjacent to the previous cell, factor in missing col info
|
||||
for (PRInt32 colIndex=prevColIndex+1; colIndex<cellColIndex; colIndex++)
|
||||
{
|
||||
aReflowState.x += aReflowState.tableFrame->GetColumnWidth(colIndex);
|
||||
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 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);
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (prevColIndex != cellColIndex + cellColSpan) {
|
||||
PRInt32 lastCol = cellColIndex + cellColSpan - 1;
|
||||
for (PRInt32 colIndex = prevColIndex - 1; colIndex > lastCol; colIndex--) {
|
||||
aReflowState.x += aReflowState.tableFrame->GetColumnWidth(colIndex);
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
PRInt32 baseColIndex;
|
||||
((nsTableCellFrame *)kidFrame)->GetColIndex(baseColIndex);
|
||||
cellColSpan = aReflowState.tableFrame->GetEffectiveColSpan(baseColIndex,
|
||||
((nsTableCellFrame *)kidFrame));
|
||||
nscoord availWidth = 0;
|
||||
for (PRInt32 numColSpan=0; numColSpan<cellColSpan; numColSpan++)
|
||||
{
|
||||
|
@ -578,8 +584,8 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
|||
availWidth, cellColIndex, aReflowState.tableFrame->GetColumnWidth(cellColIndex+numColSpan));
|
||||
}
|
||||
if (PR_TRUE==gsDebug) printf(" Row: availWidth for this cell is %d\n", availWidth);
|
||||
|
||||
prevColIndex = cellColIndex + (cellColSpan-1); // remember the rightmost column this cell spans into
|
||||
// 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,
|
||||
|
@ -689,8 +695,7 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
|||
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status);
|
||||
}
|
||||
|
||||
// Get the next child
|
||||
kidFrame = GetNextChildForDirection(rowDisplay->mDirection, kidFrame);
|
||||
kidFrame = iter.Next(); // Get the next child
|
||||
// if this was the last child, and it had a colspan>1, add in the cellSpacing for the colspan
|
||||
// if the last kid wasn't a colspan, then we still have the colspan of the last real cell
|
||||
if ((nsnull==kidFrame) && (cellColSpan>1))
|
||||
|
@ -1543,3 +1548,6 @@ nsTableRowFrame::GetFrameName(nsString& aResult) const
|
|||
{
|
||||
return MakeFrameName("TableRow", aResult);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -217,9 +217,6 @@ protected:
|
|||
nscoord ComputeCellAvailWidth(const RowReflowState& aState,
|
||||
nsIFrame* aKidFrame) const;
|
||||
|
||||
nsIFrame * GetFirstChildForDirection(PRUint8 aDir);
|
||||
nsIFrame * GetNextChildForDirection(PRUint8 aDir, nsIFrame *aCurrentChild);
|
||||
|
||||
/**
|
||||
* Called for a resize reflow. Typically because the column widths have
|
||||
* changed. Reflows all the existing table cell frames
|
||||
|
@ -249,7 +246,7 @@ private:
|
|||
PRBool mInitializedChildren; // PR_TRUE if child cells have been initialized
|
||||
// (for now, that means "added to the table", and
|
||||
// is NOT the same as having nsIFrame::Init() called.)
|
||||
|
||||
|
||||
};
|
||||
|
||||
inline PRInt32 nsTableRowFrame::GetRowIndex() const
|
||||
|
|
Загрузка…
Ссылка в новой задаче