bug 22246 - row/col span changes on cell alter cell map and reflow table. r=kmcclusk

This commit is contained in:
karnaze%netscape.com 2000-01-04 05:31:56 +00:00
Родитель 527c7e0748
Коммит 5397ffd020
12 изменённых файлов: 352 добавлений и 50 удалений

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

@ -364,7 +364,7 @@ PRBool nsCellMap::CellsSpanInOrOut(PRInt32 aStartRowIndex,
}
void nsCellMap::InsertCells(nsVoidArray& aCellFrames,
PRInt32 aRowIndex,
PRInt32 aRowIndex,
PRInt32 aColIndexBefore)
{
if (aCellFrames.Count() == 0) return;
@ -419,7 +419,6 @@ void nsCellMap::InsertCells(nsVoidArray& aCellFrames,
else {
ExpandWithCells(aCellFrames, aRowIndex, startColIndex, rowSpan);
}
}
PRBool
@ -537,9 +536,11 @@ void nsCellMap::ExpandWithCells(nsVoidArray& aCellFrames,
for (PRInt32 rowX = aRowIndex; rowX <= endRowIndex; rowX++) {
nsVoidArray* row = (nsVoidArray *)mRows.ElementAt(rowX);
PRInt32 numCols = row->Count();
for (PRInt32 colX = aColIndex + totalColSpan; colX < numCols; colX++) {
PRInt32 colX;
for (colX = aColIndex + totalColSpan; colX < numCols; colX++) {
CellData* data = (CellData*) row->ElementAt(colX);
if (data) {
// increase the origin and span counts beyond the spanned cols
if (data->mOrigCell) {
// a cell that gets moved needs adjustment as well as it new orignating col
data->mOrigCell->SetColIndex(colX);
@ -550,21 +551,24 @@ void nsCellMap::ExpandWithCells(nsVoidArray& aCellFrames,
nsColInfo* colInfo = (nsColInfo *)mCols.ElementAt(colX);
colInfo->mNumCellsSpan++;
}
}
data = (CellData*) row->ElementAt(colX - totalColSpan);
if (data) {
if (data->mOrigCell) {
// the old originating col of a moved cell needs adjustment
nsColInfo* colInfo = (nsColInfo *)mCols.ElementAt(colX - totalColSpan);
colInfo->mNumCellsOrig--;
}
else if (data->mColSpanData) {
nsColInfo* colInfo = (nsColInfo *)mCols.ElementAt(colX);
colInfo->mNumCellsSpan--;
}
// decrease the origin and span counts within the spanned cols
PRInt32 colX2 = colX - totalColSpan;
//if (colX2 < aColIndex + totalColSpan) {
nsColInfo* colInfo2 = (nsColInfo *)mCols.ElementAt(colX2);
if (data->mOrigCell) {
// the old originating col of a moved cell needs adjustment
colInfo2->mNumCellsOrig--;
}
else if (data->mColSpanData) {
colInfo2->mNumCellsSpan--;
}
//}
}
}
}
// remove any unused cols
RemoveUnusedCols(mCols.Count());
}
void nsCellMap::ShrinkWithoutRows(PRInt32 aStartRowIndex,
@ -611,16 +615,50 @@ void nsCellMap::ShrinkWithoutRows(PRInt32 aStartRowIndex,
}
}
PRInt32 nsCellMap::GetColSpan(PRInt32 aRowIndex,
PRInt32 aColIndex)
{
PRInt32 colSpan = 1;
nsVoidArray* row = (nsVoidArray *)(mRows.ElementAt(aRowIndex));
PRInt32 colCount = mCols.Count();
for (PRInt32 colX = aColIndex + 1; colX < colCount; colX++) {
CellData* data = (CellData *)(row->ElementAt(colX));
if (data && data->mColSpanData) {
colSpan++;
}
else break;
}
return colSpan;
}
PRInt32 nsCellMap::GetRowSpan(PRInt32 aRowIndex,
PRInt32 aColIndex)
{
PRInt32 rowSpan = 1;
PRInt32 rowCount = mRows.Count();
for (PRInt32 rowX = aRowIndex + 1; rowX < rowCount; rowX++) {
nsVoidArray* row = (nsVoidArray *)(mRows.ElementAt(rowX));
CellData* data = (CellData *)(row->ElementAt(aColIndex));
if (data && data->mRowSpanData) {
rowSpan++;
}
else break;
}
return rowSpan;
}
void nsCellMap::ShrinkWithoutCell(nsTableCellFrame& aCellFrame,
PRInt32 aRowIndex,
PRInt32 aColIndex)
{
PRInt32 rowSpan = aCellFrame.GetRowSpan();
PRInt32 colSpan = aCellFrame.GetColSpan();
PRInt32 colX, rowX;
// get the rowspan and colspan from the cell map since the content may have changed
PRInt32 rowSpan = GetRowSpan(aRowIndex, aColIndex);
PRInt32 colSpan = GetColSpan(aRowIndex, aColIndex);
PRInt32 endRowIndex = aRowIndex + rowSpan - 1;
PRInt32 endColIndex = aColIndex + colSpan - 1;
PRInt32 colX;
// adjust the col counts due to the deleted cell before removing it
for (colX = aColIndex; colX <= endColIndex; colX++) {
nsColInfo* colInfo = (nsColInfo *)mCols.ElementAt(colX);
@ -633,10 +671,9 @@ void nsCellMap::ShrinkWithoutCell(nsTableCellFrame& aCellFrame,
}
// remove the deleted cell and cellData entries for it
PRInt32 rowX;
for (rowX = aRowIndex; rowX <= endRowIndex; rowX++) {
nsVoidArray* row = (nsVoidArray *)mRows.ElementAt(rowX);
for (colX = aColIndex; colX <= endColIndex; colX++) {
for (colX = endColIndex; colX >= aColIndex; colX--) {
row->RemoveElementAt(colX);
}
// put back null entries in the row to make it the right size
@ -871,7 +908,7 @@ void nsCellMap::RebuildConsideringCells(nsVoidArray* aCellFrames,
}
void nsCellMap::RemoveCell(nsTableCellFrame* aCellFrame,
PRInt32 aRowIndex)
PRInt32 aRowIndex)
{
PRInt32 numRows = mRows.Count();
if ((aRowIndex < 0) || (aRowIndex >= numRows)) {
@ -889,9 +926,9 @@ void nsCellMap::RemoveCell(nsTableCellFrame* aCellFrame,
}
}
PRInt32 rowSpan = aCellFrame->GetRowSpan();
PRInt32 rowSpan = GetRowSpan(aRowIndex, startColIndex);
PRInt32 endRowIndex = aRowIndex + rowSpan - 1;
PRInt32 endColIndex = startColIndex + aCellFrame->GetColSpan() - 1;
PRInt32 endColIndex = startColIndex + GetColSpan(aRowIndex, startColIndex) - 1;
// record whether removing the cells is going to cause complications due
// to existing row spans, col spans or table sizing.
PRBool spansCauseRebuild = PR_FALSE;
@ -962,7 +999,8 @@ void nsCellMap::Dump() const
// check the validity of the cell map
nsVoidArray* rowAbove = (nsVoidArray *)mRows.ElementAt(rowIndex - 1);
CellData* cdAbove = (CellData *)rowAbove->ElementAt(colIndex);
if ((cdAbove->mOrigCell != cell) && (cdAbove->mRowSpanData->mOrigCell != cell)) {
if ((cdAbove->mOrigCell != cell) && (cdAbove->mRowSpanData) &&
(cdAbove->mRowSpanData->mOrigCell != cell)) {
NS_ASSERTION(PR_FALSE, "bad row span data");
}
printf("R ");
@ -971,7 +1009,8 @@ void nsCellMap::Dump() const
cell = cd->mColSpanData->mOrigCell;
// check the validity of the cell map
CellData* cdBefore = (CellData *)row->ElementAt(colIndex - 1);
if ((cdBefore->mOrigCell != cell) && (cdBefore->mColSpanData->mOrigCell != cell)) {
if ((cdBefore->mOrigCell != cell) && (cdBefore->mColSpanData) &&
(cdBefore->mColSpanData->mOrigCell != cell)) {
NS_ASSERTION(PR_FALSE, "bad col span data");
}
printf("C ");

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

@ -183,6 +183,13 @@ protected:
PRBool CreateEmptyRow(PRInt32 aRowIndex,
PRInt32 aNumCols);
PRInt32 GetColSpan(PRInt32 aRowIndex,
PRInt32 aColIndex);
PRInt32 GetRowSpan(PRInt32 aRowIndex,
PRInt32 aColIndex);
/** an array containing col array. It can be larger than mRowCount due to
* row spans extending beyond the table */
nsVoidArray mRows;

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

@ -51,6 +51,13 @@ NS_DEF_PTR(nsIStyleContext);
static NS_DEFINE_IID(kIHTMLTableCellElementIID, NS_IHTMLTABLECELLELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLTableCellElementIID, NS_IDOMHTMLTABLECELLELEMENT_IID);
nsTableCellFrame::nsTableCellFrame()
{
mColIndex = 0;
mPriorAvailWidth = 0;
mBorderEdges = nsnull;
}
nsTableCellFrame::~nsTableCellFrame()
{
delete mBorderEdges;
@ -80,6 +87,22 @@ nsTableCellFrame::Init(nsIPresContext* aPresContext,
return rv;
}
NS_IMETHODIMP
nsTableCellFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aHint)
{
// let the table frame decide what to do
nsTableFrame* tableFrame = nsnull;
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame);
if ((NS_SUCCEEDED(rv)) && (tableFrame)) {
tableFrame->AttributeChangedFor(aPresContext, this, aChild, aAttribute);
}
return NS_OK;
}
void nsTableCellFrame::SetPass1MaxElementSize(const nsSize& aMaxElementSize)
{
mPass1MaxElementSize.height = aMaxElementSize.height;
@ -144,6 +167,7 @@ void nsTableCellFrame::InitCellFrame(PRInt32 aColIndex)
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame)) {
SetColIndex(aColIndex);
if (NS_STYLE_BORDER_COLLAPSE == tableFrame->GetBorderCollapseStyle()) {
if (mBorderEdges) delete mBorderEdges; // this could be non null during a reinitialization
mBorderEdges = new nsBorderEdges;
mBorderEdges->mOutsideEdge=PR_FALSE;

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

@ -57,6 +57,7 @@ public:
// default constructor supplied by the compiler
nsTableCellFrame();
~nsTableCellFrame();
NS_IMETHOD Init(nsIPresContext* aPresContext,
@ -65,6 +66,12 @@ public:
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aHint);
// table cells contain an area frame which does most of the work, and
// so these functions should never be called. They assert and return
// NS_ERROR_NOT_IMPLEMENTED

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

@ -247,6 +247,39 @@ nsTableFrame::Destroy(nsIPresContext* aPresContext)
return nsHTMLContainerFrame::Destroy(aPresContext);
}
// Helper function. It marks the table frame as dirty and generates
// a reflow command
nsresult
nsTableFrame::AddTableDirtyReflowCommand(nsIPresContext* aPresContext,
nsIFrame* aTableFrame)
{
nsFrameState frameState;
nsIFrame* tableParentFrame;
nsIReflowCommand* reflowCmd;
nsresult rv;
nsIPresShell* presShell;
aPresContext->GetShell(&presShell);
// 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 = presShell->AppendReflowCommand(reflowCmd);
NS_RELEASE(reflowCmd);
}
NS_RELEASE(presShell);
return rv;
}
// XXX this needs to be cleaned up so that the frame constructor breaks out col group
// frames into a separate child list.
NS_IMETHODIMP
@ -315,6 +348,37 @@ nsTableFrame::SetInitialChildList(nsIPresContext* aPresContext,
}
void nsTableFrame::AttributeChangedFor(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIContent* aContent,
nsIAtom* aAttribute)
{
nsIAtom* frameType;
aFrame->GetFrameType(&frameType);
if (nsLayoutAtoms::tableCellFrame == frameType) {
if ((nsHTMLAtoms::rowspan == aAttribute) ||
(nsHTMLAtoms::colspan == aAttribute)) {
nsCellMap* cellMap = GetCellMap();
if (cellMap) {
// for now just remove the cell from the map and reinsert it
nsTableCellFrame* cellFrame = (nsTableCellFrame*)aFrame;
PRInt32 rowIndex, colIndex;
cellFrame->GetRowIndex(rowIndex);
cellFrame->GetColIndex(colIndex);
RemoveCell(*aPresContext, cellFrame, rowIndex);
nsVoidArray cells;
cells.AppendElement(cellFrame);
InsertCells(*aPresContext, cells, rowIndex, colIndex - 1);
// invalidate the column widths and generate a reflow command
InvalidateColumnWidths();
AddTableDirtyReflowCommand(aPresContext, this);
}
}
}
NS_IF_RELEASE(frameType);
}
/* ****** CellMap methods ******* */
/* counts columns in column groups */

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

@ -106,6 +106,16 @@ public:
nsIFrame* aPrevInFlow);
static nsresult AddTableDirtyReflowCommand(nsIPresContext* aPresContext,
nsIFrame* aTableFrame);
/*
* Notification that aAttribute has changed for content inside a table (cell, row, etc)
*/
void AttributeChangedFor(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIContent* aContent,
nsIAtom* aAttribute);
/** @see nsIFrame::Destroy */
NS_IMETHOD Destroy(nsIPresContext* aPresContext);

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

@ -364,7 +364,7 @@ PRBool nsCellMap::CellsSpanInOrOut(PRInt32 aStartRowIndex,
}
void nsCellMap::InsertCells(nsVoidArray& aCellFrames,
PRInt32 aRowIndex,
PRInt32 aRowIndex,
PRInt32 aColIndexBefore)
{
if (aCellFrames.Count() == 0) return;
@ -419,7 +419,6 @@ void nsCellMap::InsertCells(nsVoidArray& aCellFrames,
else {
ExpandWithCells(aCellFrames, aRowIndex, startColIndex, rowSpan);
}
}
PRBool
@ -537,9 +536,11 @@ void nsCellMap::ExpandWithCells(nsVoidArray& aCellFrames,
for (PRInt32 rowX = aRowIndex; rowX <= endRowIndex; rowX++) {
nsVoidArray* row = (nsVoidArray *)mRows.ElementAt(rowX);
PRInt32 numCols = row->Count();
for (PRInt32 colX = aColIndex + totalColSpan; colX < numCols; colX++) {
PRInt32 colX;
for (colX = aColIndex + totalColSpan; colX < numCols; colX++) {
CellData* data = (CellData*) row->ElementAt(colX);
if (data) {
// increase the origin and span counts beyond the spanned cols
if (data->mOrigCell) {
// a cell that gets moved needs adjustment as well as it new orignating col
data->mOrigCell->SetColIndex(colX);
@ -550,21 +551,24 @@ void nsCellMap::ExpandWithCells(nsVoidArray& aCellFrames,
nsColInfo* colInfo = (nsColInfo *)mCols.ElementAt(colX);
colInfo->mNumCellsSpan++;
}
}
data = (CellData*) row->ElementAt(colX - totalColSpan);
if (data) {
if (data->mOrigCell) {
// the old originating col of a moved cell needs adjustment
nsColInfo* colInfo = (nsColInfo *)mCols.ElementAt(colX - totalColSpan);
colInfo->mNumCellsOrig--;
}
else if (data->mColSpanData) {
nsColInfo* colInfo = (nsColInfo *)mCols.ElementAt(colX);
colInfo->mNumCellsSpan--;
}
// decrease the origin and span counts within the spanned cols
PRInt32 colX2 = colX - totalColSpan;
//if (colX2 < aColIndex + totalColSpan) {
nsColInfo* colInfo2 = (nsColInfo *)mCols.ElementAt(colX2);
if (data->mOrigCell) {
// the old originating col of a moved cell needs adjustment
colInfo2->mNumCellsOrig--;
}
else if (data->mColSpanData) {
colInfo2->mNumCellsSpan--;
}
//}
}
}
}
// remove any unused cols
RemoveUnusedCols(mCols.Count());
}
void nsCellMap::ShrinkWithoutRows(PRInt32 aStartRowIndex,
@ -611,16 +615,50 @@ void nsCellMap::ShrinkWithoutRows(PRInt32 aStartRowIndex,
}
}
PRInt32 nsCellMap::GetColSpan(PRInt32 aRowIndex,
PRInt32 aColIndex)
{
PRInt32 colSpan = 1;
nsVoidArray* row = (nsVoidArray *)(mRows.ElementAt(aRowIndex));
PRInt32 colCount = mCols.Count();
for (PRInt32 colX = aColIndex + 1; colX < colCount; colX++) {
CellData* data = (CellData *)(row->ElementAt(colX));
if (data && data->mColSpanData) {
colSpan++;
}
else break;
}
return colSpan;
}
PRInt32 nsCellMap::GetRowSpan(PRInt32 aRowIndex,
PRInt32 aColIndex)
{
PRInt32 rowSpan = 1;
PRInt32 rowCount = mRows.Count();
for (PRInt32 rowX = aRowIndex + 1; rowX < rowCount; rowX++) {
nsVoidArray* row = (nsVoidArray *)(mRows.ElementAt(rowX));
CellData* data = (CellData *)(row->ElementAt(aColIndex));
if (data && data->mRowSpanData) {
rowSpan++;
}
else break;
}
return rowSpan;
}
void nsCellMap::ShrinkWithoutCell(nsTableCellFrame& aCellFrame,
PRInt32 aRowIndex,
PRInt32 aColIndex)
{
PRInt32 rowSpan = aCellFrame.GetRowSpan();
PRInt32 colSpan = aCellFrame.GetColSpan();
PRInt32 colX, rowX;
// get the rowspan and colspan from the cell map since the content may have changed
PRInt32 rowSpan = GetRowSpan(aRowIndex, aColIndex);
PRInt32 colSpan = GetColSpan(aRowIndex, aColIndex);
PRInt32 endRowIndex = aRowIndex + rowSpan - 1;
PRInt32 endColIndex = aColIndex + colSpan - 1;
PRInt32 colX;
// adjust the col counts due to the deleted cell before removing it
for (colX = aColIndex; colX <= endColIndex; colX++) {
nsColInfo* colInfo = (nsColInfo *)mCols.ElementAt(colX);
@ -633,10 +671,9 @@ void nsCellMap::ShrinkWithoutCell(nsTableCellFrame& aCellFrame,
}
// remove the deleted cell and cellData entries for it
PRInt32 rowX;
for (rowX = aRowIndex; rowX <= endRowIndex; rowX++) {
nsVoidArray* row = (nsVoidArray *)mRows.ElementAt(rowX);
for (colX = aColIndex; colX <= endColIndex; colX++) {
for (colX = endColIndex; colX >= aColIndex; colX--) {
row->RemoveElementAt(colX);
}
// put back null entries in the row to make it the right size
@ -871,7 +908,7 @@ void nsCellMap::RebuildConsideringCells(nsVoidArray* aCellFrames,
}
void nsCellMap::RemoveCell(nsTableCellFrame* aCellFrame,
PRInt32 aRowIndex)
PRInt32 aRowIndex)
{
PRInt32 numRows = mRows.Count();
if ((aRowIndex < 0) || (aRowIndex >= numRows)) {
@ -889,9 +926,9 @@ void nsCellMap::RemoveCell(nsTableCellFrame* aCellFrame,
}
}
PRInt32 rowSpan = aCellFrame->GetRowSpan();
PRInt32 rowSpan = GetRowSpan(aRowIndex, startColIndex);
PRInt32 endRowIndex = aRowIndex + rowSpan - 1;
PRInt32 endColIndex = startColIndex + aCellFrame->GetColSpan() - 1;
PRInt32 endColIndex = startColIndex + GetColSpan(aRowIndex, startColIndex) - 1;
// record whether removing the cells is going to cause complications due
// to existing row spans, col spans or table sizing.
PRBool spansCauseRebuild = PR_FALSE;
@ -962,7 +999,8 @@ void nsCellMap::Dump() const
// check the validity of the cell map
nsVoidArray* rowAbove = (nsVoidArray *)mRows.ElementAt(rowIndex - 1);
CellData* cdAbove = (CellData *)rowAbove->ElementAt(colIndex);
if ((cdAbove->mOrigCell != cell) && (cdAbove->mRowSpanData->mOrigCell != cell)) {
if ((cdAbove->mOrigCell != cell) && (cdAbove->mRowSpanData) &&
(cdAbove->mRowSpanData->mOrigCell != cell)) {
NS_ASSERTION(PR_FALSE, "bad row span data");
}
printf("R ");
@ -971,7 +1009,8 @@ void nsCellMap::Dump() const
cell = cd->mColSpanData->mOrigCell;
// check the validity of the cell map
CellData* cdBefore = (CellData *)row->ElementAt(colIndex - 1);
if ((cdBefore->mOrigCell != cell) && (cdBefore->mColSpanData->mOrigCell != cell)) {
if ((cdBefore->mOrigCell != cell) && (cdBefore->mColSpanData) &&
(cdBefore->mColSpanData->mOrigCell != cell)) {
NS_ASSERTION(PR_FALSE, "bad col span data");
}
printf("C ");

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

@ -183,6 +183,13 @@ protected:
PRBool CreateEmptyRow(PRInt32 aRowIndex,
PRInt32 aNumCols);
PRInt32 GetColSpan(PRInt32 aRowIndex,
PRInt32 aColIndex);
PRInt32 GetRowSpan(PRInt32 aRowIndex,
PRInt32 aColIndex);
/** an array containing col array. It can be larger than mRowCount due to
* row spans extending beyond the table */
nsVoidArray mRows;

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

@ -51,6 +51,13 @@ NS_DEF_PTR(nsIStyleContext);
static NS_DEFINE_IID(kIHTMLTableCellElementIID, NS_IHTMLTABLECELLELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLTableCellElementIID, NS_IDOMHTMLTABLECELLELEMENT_IID);
nsTableCellFrame::nsTableCellFrame()
{
mColIndex = 0;
mPriorAvailWidth = 0;
mBorderEdges = nsnull;
}
nsTableCellFrame::~nsTableCellFrame()
{
delete mBorderEdges;
@ -80,6 +87,22 @@ nsTableCellFrame::Init(nsIPresContext* aPresContext,
return rv;
}
NS_IMETHODIMP
nsTableCellFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aHint)
{
// let the table frame decide what to do
nsTableFrame* tableFrame = nsnull;
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame);
if ((NS_SUCCEEDED(rv)) && (tableFrame)) {
tableFrame->AttributeChangedFor(aPresContext, this, aChild, aAttribute);
}
return NS_OK;
}
void nsTableCellFrame::SetPass1MaxElementSize(const nsSize& aMaxElementSize)
{
mPass1MaxElementSize.height = aMaxElementSize.height;
@ -144,6 +167,7 @@ void nsTableCellFrame::InitCellFrame(PRInt32 aColIndex)
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame)) {
SetColIndex(aColIndex);
if (NS_STYLE_BORDER_COLLAPSE == tableFrame->GetBorderCollapseStyle()) {
if (mBorderEdges) delete mBorderEdges; // this could be non null during a reinitialization
mBorderEdges = new nsBorderEdges;
mBorderEdges->mOutsideEdge=PR_FALSE;

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

@ -57,6 +57,7 @@ public:
// default constructor supplied by the compiler
nsTableCellFrame();
~nsTableCellFrame();
NS_IMETHOD Init(nsIPresContext* aPresContext,
@ -65,6 +66,12 @@ public:
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aHint);
// table cells contain an area frame which does most of the work, and
// so these functions should never be called. They assert and return
// NS_ERROR_NOT_IMPLEMENTED

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

@ -247,6 +247,39 @@ nsTableFrame::Destroy(nsIPresContext* aPresContext)
return nsHTMLContainerFrame::Destroy(aPresContext);
}
// Helper function. It marks the table frame as dirty and generates
// a reflow command
nsresult
nsTableFrame::AddTableDirtyReflowCommand(nsIPresContext* aPresContext,
nsIFrame* aTableFrame)
{
nsFrameState frameState;
nsIFrame* tableParentFrame;
nsIReflowCommand* reflowCmd;
nsresult rv;
nsIPresShell* presShell;
aPresContext->GetShell(&presShell);
// 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 = presShell->AppendReflowCommand(reflowCmd);
NS_RELEASE(reflowCmd);
}
NS_RELEASE(presShell);
return rv;
}
// XXX this needs to be cleaned up so that the frame constructor breaks out col group
// frames into a separate child list.
NS_IMETHODIMP
@ -315,6 +348,37 @@ nsTableFrame::SetInitialChildList(nsIPresContext* aPresContext,
}
void nsTableFrame::AttributeChangedFor(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIContent* aContent,
nsIAtom* aAttribute)
{
nsIAtom* frameType;
aFrame->GetFrameType(&frameType);
if (nsLayoutAtoms::tableCellFrame == frameType) {
if ((nsHTMLAtoms::rowspan == aAttribute) ||
(nsHTMLAtoms::colspan == aAttribute)) {
nsCellMap* cellMap = GetCellMap();
if (cellMap) {
// for now just remove the cell from the map and reinsert it
nsTableCellFrame* cellFrame = (nsTableCellFrame*)aFrame;
PRInt32 rowIndex, colIndex;
cellFrame->GetRowIndex(rowIndex);
cellFrame->GetColIndex(colIndex);
RemoveCell(*aPresContext, cellFrame, rowIndex);
nsVoidArray cells;
cells.AppendElement(cellFrame);
InsertCells(*aPresContext, cells, rowIndex, colIndex - 1);
// invalidate the column widths and generate a reflow command
InvalidateColumnWidths();
AddTableDirtyReflowCommand(aPresContext, this);
}
}
}
NS_IF_RELEASE(frameType);
}
/* ****** CellMap methods ******* */
/* counts columns in column groups */

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

@ -106,6 +106,16 @@ public:
nsIFrame* aPrevInFlow);
static nsresult AddTableDirtyReflowCommand(nsIPresContext* aPresContext,
nsIFrame* aTableFrame);
/*
* Notification that aAttribute has changed for content inside a table (cell, row, etc)
*/
void AttributeChangedFor(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIContent* aContent,
nsIAtom* aAttribute);
/** @see nsIFrame::Destroy */
NS_IMETHOD Destroy(nsIPresContext* aPresContext);