Make OrderRowGroups type-safe. Bug 367706, r=bernd, sr=roc
git-svn-id: svn://10.0.0.236/trunk@227539 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
dc91e7c438
commit
f68b71bd43
@ -76,18 +76,14 @@ nsTableCellMap::nsTableCellMap(nsTableFrame& aTableFrame,
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsTableCellMap);
|
||||
|
||||
nsAutoVoidArray orderedRowGroups;
|
||||
PRUint32 numRowGroups;
|
||||
aTableFrame.OrderRowGroups(orderedRowGroups, numRowGroups);
|
||||
nsTableFrame::RowGroupArray orderedRowGroups;
|
||||
aTableFrame.OrderRowGroups(orderedRowGroups);
|
||||
|
||||
for (PRUint32 rgX = 0; rgX < numRowGroups; rgX++) {
|
||||
nsTableRowGroupFrame* rgFrame =
|
||||
nsTableFrame::GetRowGroupFrame((nsIFrame*)orderedRowGroups.ElementAt(rgX));
|
||||
if (rgFrame) {
|
||||
nsTableRowGroupFrame* prior = (0 == rgX)
|
||||
? nsnull : nsTableFrame::GetRowGroupFrame((nsIFrame*)orderedRowGroups.ElementAt(rgX - 1));
|
||||
InsertGroupCellMap(*rgFrame, prior);
|
||||
}
|
||||
nsTableRowGroupFrame* prior = nsnull;
|
||||
for (PRUint32 rgX = 0; rgX < orderedRowGroups.Length(); rgX++) {
|
||||
nsTableRowGroupFrame* rgFrame = orderedRowGroups[rgX];
|
||||
InsertGroupCellMap(*rgFrame, prior);
|
||||
prior = rgFrame;
|
||||
}
|
||||
if (aBorderCollapse) {
|
||||
mBCInfo = new BCInfo();
|
||||
@ -296,15 +292,10 @@ nsTableCellMap::GetMapFor(const nsTableRowGroupFrame* aRowGroup,
|
||||
if (aRowGroup->IsRepeatable()) {
|
||||
nsTableFrame* fifTable = NS_STATIC_CAST(nsTableFrame*, mTableFrame.GetFirstInFlow());
|
||||
|
||||
nsAutoVoidArray rowGroups;
|
||||
PRUint32 numRowGroups;
|
||||
nsTableRowGroupFrame *thead, *tfoot;
|
||||
// find the original header/footer
|
||||
fifTable->OrderRowGroups(rowGroups, numRowGroups, &thead, &tfoot);
|
||||
|
||||
const nsStyleDisplay* display = aRowGroup->GetStyleDisplay();
|
||||
nsTableRowGroupFrame* rgOrig =
|
||||
(NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == display->mDisplay) ? thead : tfoot;
|
||||
(NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == display->mDisplay) ?
|
||||
fifTable->GetTHead() : fifTable->GetTFoot();
|
||||
// find the row group cell map using the original header/footer
|
||||
if (rgOrig && rgOrig != aRowGroup) {
|
||||
return GetMapFor(rgOrig, aStartHint);
|
||||
@ -317,37 +308,36 @@ nsTableCellMap::GetMapFor(const nsTableRowGroupFrame* aRowGroup,
|
||||
void
|
||||
nsTableCellMap::Synchronize(nsTableFrame* aTableFrame)
|
||||
{
|
||||
nsAutoVoidArray orderedRowGroups;
|
||||
nsAutoVoidArray maps;
|
||||
PRUint32 numRowGroups;
|
||||
PRInt32 mapIndex;
|
||||
nsTableFrame::RowGroupArray orderedRowGroups;
|
||||
nsAutoTPtrArray<nsCellMap, 8> maps;
|
||||
|
||||
maps.Clear();
|
||||
aTableFrame->OrderRowGroups(orderedRowGroups, numRowGroups);
|
||||
if (!numRowGroups) {
|
||||
aTableFrame->OrderRowGroups(orderedRowGroups);
|
||||
if (!orderedRowGroups.Length()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// XXXbz this fails if orderedRowGroups is missing some row groups
|
||||
// (due to OOM when appending to the array, e.g. -- we leak maps in
|
||||
// that case).
|
||||
|
||||
// Scope |map| outside the loop so we can use it as a hint.
|
||||
nsCellMap* map = nsnull;
|
||||
for (PRUint32 rgX = 0; rgX < numRowGroups; rgX++) {
|
||||
nsTableRowGroupFrame* rgFrame =
|
||||
nsTableFrame::GetRowGroupFrame((nsIFrame*)orderedRowGroups.ElementAt(rgX));
|
||||
if (rgFrame) {
|
||||
map = GetMapFor(rgFrame, map);
|
||||
if (map) {
|
||||
if (!maps.AppendElement(map)) {
|
||||
delete map;
|
||||
NS_WARNING("Could not AppendElement");
|
||||
}
|
||||
for (PRUint32 rgX = 0; rgX < orderedRowGroups.Length(); rgX++) {
|
||||
nsTableRowGroupFrame* rgFrame = orderedRowGroups[rgX];
|
||||
map = GetMapFor(rgFrame, map);
|
||||
if (map) {
|
||||
if (!maps.AppendElement(map)) {
|
||||
delete map;
|
||||
NS_WARNING("Could not AppendElement");
|
||||
}
|
||||
}
|
||||
}
|
||||
mapIndex = maps.Count() - 1;
|
||||
nsCellMap* nextMap = (nsCellMap*) maps.ElementAt(mapIndex);
|
||||
|
||||
PRInt32 mapIndex = maps.Length() - 1; // Might end up -1
|
||||
nsCellMap* nextMap = maps.ElementAt(mapIndex);
|
||||
nextMap->SetNextSibling(nsnull);
|
||||
for (mapIndex-- ; mapIndex >= 0; mapIndex--) {
|
||||
nsCellMap* map = (nsCellMap*) maps.ElementAt(mapIndex);
|
||||
nsCellMap* map = maps.ElementAt(mapIndex);
|
||||
map->SetNextSibling(nextMap);
|
||||
nextMap = map;
|
||||
}
|
||||
|
||||
@ -540,14 +540,11 @@ void nsTableFrame::AdjustRowIndices(PRInt32 aRowIndex,
|
||||
{
|
||||
// Iterate over the row groups and adjust the row indices of all rows
|
||||
// whose index is >= aRowIndex.
|
||||
nsAutoVoidArray rowGroups;
|
||||
PRUint32 numRowGroups;
|
||||
OrderRowGroups(rowGroups, numRowGroups);
|
||||
RowGroupArray rowGroups;
|
||||
OrderRowGroups(rowGroups);
|
||||
|
||||
for (PRUint32 rgX = 0; rgX < numRowGroups; rgX++) {
|
||||
nsIFrame* kidFrame = (nsIFrame*)rowGroups.ElementAt(rgX);
|
||||
nsTableRowGroupFrame* rgFrame = GetRowGroupFrame(kidFrame);
|
||||
rgFrame->AdjustRowIndices(aRowIndex, aAdjustment);
|
||||
for (PRUint32 rgX = 0; rgX < rowGroups.Length(); rgX++) {
|
||||
rowGroups[rgX]->AdjustRowIndices(aRowIndex, aAdjustment);
|
||||
}
|
||||
}
|
||||
|
||||
@ -557,9 +554,8 @@ void nsTableFrame::ResetRowIndices(nsIFrame* aFirstRowGroupFrame,
|
||||
{
|
||||
// Iterate over the row groups and adjust the row indices of all rows
|
||||
// omit the rowgroups that will be inserted later
|
||||
nsAutoVoidArray rowGroups;
|
||||
PRUint32 numRowGroups;
|
||||
OrderRowGroups(rowGroups, numRowGroups, nsnull);
|
||||
RowGroupArray rowGroups;
|
||||
OrderRowGroups(rowGroups);
|
||||
|
||||
PRInt32 rowIndex = 0;
|
||||
nsTableRowGroupFrame* newRgFrame = nsnull;
|
||||
@ -570,9 +566,8 @@ void nsTableFrame::ResetRowIndices(nsIFrame* aFirstRowGroupFrame,
|
||||
omitRgFrame = nsnull;
|
||||
}
|
||||
|
||||
for (PRUint32 rgX = 0; rgX < numRowGroups; rgX++) {
|
||||
nsIFrame* kidFrame = (nsIFrame*)rowGroups.ElementAt(rgX);
|
||||
nsTableRowGroupFrame* rgFrame = GetRowGroupFrame(kidFrame);
|
||||
for (PRUint32 rgX = 0; rgX < rowGroups.Length(); rgX++) {
|
||||
nsTableRowGroupFrame* rgFrame = rowGroups[rgX];
|
||||
if (rgFrame == newRgFrame) {
|
||||
// omit the new rowgroup
|
||||
if (omitRgFrame) {
|
||||
@ -983,13 +978,12 @@ void nsTableFrame::RemoveCell(nsTableCellFrame* aCellFrame,
|
||||
PRInt32
|
||||
nsTableFrame::GetStartRowIndex(nsTableRowGroupFrame& aRowGroupFrame)
|
||||
{
|
||||
nsAutoVoidArray orderedRowGroups;
|
||||
PRUint32 numRowGroups;
|
||||
OrderRowGroups(orderedRowGroups, numRowGroups);
|
||||
RowGroupArray orderedRowGroups;
|
||||
OrderRowGroups(orderedRowGroups);
|
||||
|
||||
PRInt32 rowIndex = 0;
|
||||
for (PRUint32 rgIndex = 0; rgIndex < numRowGroups; rgIndex++) {
|
||||
nsTableRowGroupFrame* rgFrame = GetRowGroupFrame((nsIFrame*)orderedRowGroups.ElementAt(rgIndex));
|
||||
for (PRUint32 rgIndex = 0; rgIndex < orderedRowGroups.Length(); rgIndex++) {
|
||||
nsTableRowGroupFrame* rgFrame = orderedRowGroups[rgIndex];
|
||||
if (rgFrame == &aRowGroupFrame) {
|
||||
break;
|
||||
}
|
||||
@ -1177,21 +1171,21 @@ nsTableFrame::InsertRowGroups(nsIFrame* aFirstRowGroupFrame,
|
||||
#endif
|
||||
nsTableCellMap* cellMap = GetCellMap();
|
||||
if (cellMap) {
|
||||
nsAutoVoidArray orderedRowGroups;
|
||||
PRUint32 numRowGroups;
|
||||
OrderRowGroups(orderedRowGroups, numRowGroups);
|
||||
RowGroupArray orderedRowGroups;
|
||||
OrderRowGroups(orderedRowGroups);
|
||||
|
||||
nsAutoVoidArray rows;
|
||||
// Loop over the rowgroups and check if some of them are new, if they are
|
||||
// insert cellmaps in the order that is predefined by OrderRowGroups,
|
||||
PRUint32 rgIndex;
|
||||
for (rgIndex = 0; rgIndex < numRowGroups; rgIndex++) {
|
||||
for (rgIndex = 0; rgIndex < orderedRowGroups.Length(); rgIndex++) {
|
||||
nsIFrame* kidFrame = aFirstRowGroupFrame;
|
||||
while (kidFrame) {
|
||||
nsTableRowGroupFrame* rgFrame = GetRowGroupFrame(kidFrame);
|
||||
|
||||
if (GetRowGroupFrame((nsIFrame*)orderedRowGroups.ElementAt(rgIndex)) == rgFrame) {
|
||||
nsTableRowGroupFrame* priorRG = (0 == rgIndex)
|
||||
? nsnull : GetRowGroupFrame((nsIFrame*)orderedRowGroups.ElementAt(rgIndex - 1));
|
||||
if (orderedRowGroups[rgIndex] == rgFrame) {
|
||||
nsTableRowGroupFrame* priorRG =
|
||||
(0 == rgIndex) ? nsnull : orderedRowGroups[rgIndex - 1];
|
||||
// create and add the cell map for the row group
|
||||
cellMap->InsertGroupCellMap(*rgFrame, priorRG);
|
||||
|
||||
@ -1209,14 +1203,14 @@ nsTableFrame::InsertRowGroups(nsIFrame* aFirstRowGroupFrame,
|
||||
ResetRowIndices(aFirstRowGroupFrame, aLastRowGroupFrame);
|
||||
|
||||
//now that the cellmaps are reordered too insert the rows
|
||||
for (rgIndex = 0; rgIndex < numRowGroups; rgIndex++) {
|
||||
for (rgIndex = 0; rgIndex < orderedRowGroups.Length(); rgIndex++) {
|
||||
nsIFrame* kidFrame = aFirstRowGroupFrame;
|
||||
while (kidFrame) {
|
||||
nsTableRowGroupFrame* rgFrame = GetRowGroupFrame(kidFrame);
|
||||
|
||||
if (GetRowGroupFrame((nsIFrame*)orderedRowGroups.ElementAt(rgIndex)) == rgFrame) {
|
||||
nsTableRowGroupFrame* priorRG = (0 == rgIndex)
|
||||
? nsnull : GetRowGroupFrame((nsIFrame*)orderedRowGroups.ElementAt(rgIndex - 1));
|
||||
if (orderedRowGroups[rgIndex] == rgFrame) {
|
||||
nsTableRowGroupFrame* priorRG =
|
||||
(0 == rgIndex) ? nsnull : orderedRowGroups[rgIndex - 1];
|
||||
// collect the new row frames in an array and add them to the table
|
||||
PRInt32 numRows = CollectRows(kidFrame, rows);
|
||||
if (numRows > 0) {
|
||||
@ -1559,13 +1553,12 @@ ProcessRowInserted(nsTableFrame& aTableFrame,
|
||||
nscoord aNewHeight)
|
||||
{
|
||||
aTableFrame.SetRowInserted(PR_FALSE); // reset the bit that got us here
|
||||
nsAutoVoidArray rowGroups;
|
||||
PRUint32 numRowGroups;
|
||||
aTableFrame.OrderRowGroups(rowGroups, numRowGroups);
|
||||
nsTableFrame::RowGroupArray rowGroups;
|
||||
aTableFrame.OrderRowGroups(rowGroups);
|
||||
// find the row group containing the inserted row
|
||||
for (PRUint32 rgX = 0; rgX < numRowGroups; rgX++) {
|
||||
nsTableRowGroupFrame* rgFrame = (nsTableRowGroupFrame*)rowGroups.ElementAt(rgX);
|
||||
if (!rgFrame) continue; // should never happen
|
||||
for (PRUint32 rgX = 0; rgX < rowGroups.Length(); rgX++) {
|
||||
nsTableRowGroupFrame* rgFrame = rowGroups[rgX];
|
||||
NS_ASSERTION(rgFrame, "Must have rgFrame here");
|
||||
nsIFrame* childFrame = rgFrame->GetFirstChild(nsnull);
|
||||
// find the row that was inserted first
|
||||
while (childFrame) {
|
||||
@ -2070,7 +2063,7 @@ nsTableFrame::GetFirstBodyRowGroupFrame()
|
||||
// Table specific version that takes into account repeated header and footer
|
||||
// frames when continuing table frames
|
||||
void
|
||||
nsTableFrame::PushChildren(const nsAutoVoidArray& aFrames,
|
||||
nsTableFrame::PushChildren(const FrameArray& aFrames,
|
||||
PRInt32 aPushFrom)
|
||||
{
|
||||
NS_PRECONDITION(aPushFrom > 0, "pushing first child");
|
||||
@ -2079,13 +2072,16 @@ nsTableFrame::PushChildren(const nsAutoVoidArray& aFrames,
|
||||
nsFrameList frames;
|
||||
nsIFrame* lastFrame = nsnull;
|
||||
PRUint32 childX;
|
||||
nsIFrame* prevSiblingHint =
|
||||
NS_STATIC_CAST(nsIFrame*, aFrames.ElementAt(aPushFrom - 1));
|
||||
for (childX = aPushFrom; childX < aFrames.Count(); ++childX) {
|
||||
nsIFrame* f = NS_STATIC_CAST(nsIFrame*, aFrames.FastElementAt(childX));
|
||||
// Don't push repeatable frames, do push non-rowgroup frames
|
||||
if (f->GetType() != nsGkAtoms::tableRowGroupFrame ||
|
||||
!NS_STATIC_CAST(nsTableRowGroupFrame*, f)->IsRepeatable()) {
|
||||
nsIFrame* prevSiblingHint = aFrames.SafeElementAt(aPushFrom - 1);
|
||||
for (childX = aPushFrom; childX < aFrames.Length(); ++childX) {
|
||||
nsIFrame* f = aFrames[childX];
|
||||
// Don't push repeatable frames, do push non-rowgroup frames.
|
||||
// XXXbz Need to push the non-rowgroup frames, even though we don't reflow
|
||||
// them, so that we don't lose them. Of course there shouldn't be any
|
||||
// non-rowgroup frames here...
|
||||
nsTableRowGroupFrame* rgFrame = GetRowGroupFrame(f);
|
||||
NS_ASSERTION(rgFrame, "Unexpected non-row-group frame");
|
||||
if (!rgFrame || !rgFrame->IsRepeatable()) {
|
||||
mFrames.RemoveFrame(f, prevSiblingHint);
|
||||
frames.InsertFrame(nsnull, lastFrame, f);
|
||||
lastFrame = f;
|
||||
@ -2165,17 +2161,15 @@ nsTableFrame::AdjustForCollapsingRowsCols(nsHTMLReflowMetrics& aDesiredSize,
|
||||
|
||||
// collapse the rows and/or row groups as necessary
|
||||
// Get the ordered children
|
||||
nsAutoVoidArray rowGroups;
|
||||
PRUint32 numRowGroups;
|
||||
OrderRowGroups(rowGroups, numRowGroups);
|
||||
RowGroupArray rowGroups;
|
||||
OrderRowGroups(rowGroups);
|
||||
nscoord width = GetCollapsedWidth(aBorderPadding);
|
||||
nscoord rgWidth = width - 2 * GetCellSpacingX();
|
||||
nsRect overflowArea(0, 0, 0, 0);
|
||||
// Walk the list of children
|
||||
for (PRUint32 childX = 0; childX < numRowGroups; childX++) {
|
||||
nsIFrame* childFrame = (nsIFrame*)rowGroups.ElementAt(childX);
|
||||
nsTableRowGroupFrame* rgFrame = GetRowGroupFrame(childFrame);
|
||||
if (!rgFrame) continue; // skip foreign frame types
|
||||
for (PRUint32 childX = 0; childX < rowGroups.Length(); childX++) {
|
||||
nsTableRowGroupFrame* rgFrame = rowGroups[childX];
|
||||
NS_ASSERTION(rgFrame, "Must have row group frame here");
|
||||
yTotalOffset += rgFrame->CollapseRowGroupIfNecessary(yTotalOffset, rgWidth);
|
||||
ConsiderChildOverflow(overflowArea, rgFrame);
|
||||
}
|
||||
@ -2430,8 +2424,6 @@ nsTableFrame::RemoveFrame(nsIAtom* aListName,
|
||||
NS_ASSERTION(!aListName, "unexpected child list");
|
||||
nsTableRowGroupFrame* rgFrame = GetRowGroupFrame(aOldFrame);
|
||||
if (rgFrame) {
|
||||
PRInt32 startRowIndex = rgFrame->GetStartRowIndex();
|
||||
PRInt32 numRows = rgFrame->GetRowCount();
|
||||
// remove the row group from the cell map
|
||||
nsTableCellMap* cellMap = GetCellMap();
|
||||
if (cellMap) {
|
||||
@ -2635,54 +2627,43 @@ void nsTableFrame::PlaceChild(nsTableReflowState& aReflowState,
|
||||
}
|
||||
|
||||
void
|
||||
nsTableFrame::OrderRowGroups(nsVoidArray& aChildren,
|
||||
PRUint32& aNumRowGroups,
|
||||
nsTableRowGroupFrame** aHead,
|
||||
nsTableRowGroupFrame** aFoot) const
|
||||
nsTableFrame::OrderRowGroups(RowGroupArray& aChildren) const
|
||||
{
|
||||
aChildren.Clear();
|
||||
nsIFrame* head = nsnull;
|
||||
nsIFrame* foot = nsnull;
|
||||
// initialize out parameters, if present
|
||||
if (aHead) *aHead = nsnull;
|
||||
if (aFoot) *aFoot = nsnull;
|
||||
nsTableRowGroupFrame* head = nsnull;
|
||||
nsTableRowGroupFrame* foot = nsnull;
|
||||
|
||||
nsIFrame* kidFrame = mFrames.FirstChild();
|
||||
nsAutoVoidArray nonRowGroups;
|
||||
// put the tbodies first, and the non row groups last
|
||||
while (kidFrame) {
|
||||
const nsStyleDisplay* kidDisplay = kidFrame->GetStyleDisplay();
|
||||
if (IsRowGroup(kidDisplay->mDisplay)) {
|
||||
nsTableRowGroupFrame* rowGroup = GetRowGroupFrame(kidFrame);
|
||||
if (NS_LIKELY(rowGroup)) {
|
||||
switch(kidDisplay->mDisplay) {
|
||||
case NS_STYLE_DISPLAY_TABLE_HEADER_GROUP:
|
||||
if (head) { // treat additional thead like tbody
|
||||
aChildren.AppendElement(kidFrame);
|
||||
aChildren.AppendElement(rowGroup);
|
||||
}
|
||||
else {
|
||||
head = kidFrame;
|
||||
if (aHead) {
|
||||
*aHead = (nsTableRowGroupFrame*)head;
|
||||
}
|
||||
head = rowGroup;
|
||||
}
|
||||
break;
|
||||
case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP:
|
||||
if (foot) {
|
||||
aChildren.AppendElement(kidFrame);
|
||||
if (foot) { // treat additional tfoot like tbody
|
||||
aChildren.AppendElement(rowGroup);
|
||||
}
|
||||
else {
|
||||
foot = kidFrame;
|
||||
if (aFoot) {
|
||||
*aFoot = (nsTableRowGroupFrame*)foot;
|
||||
}
|
||||
foot = rowGroup;
|
||||
}
|
||||
break;
|
||||
case NS_STYLE_DISPLAY_TABLE_ROW_GROUP:
|
||||
aChildren.AppendElement(rowGroup);
|
||||
break;
|
||||
default:
|
||||
aChildren.AppendElement(kidFrame);
|
||||
NS_NOTREACHED("How did this produce an nsTableRowGroupFrame?");
|
||||
// Just ignore it
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nonRowGroups.AppendElement(kidFrame);
|
||||
}
|
||||
// Get the next sibling but skip it if it's also the next-in-flow, since
|
||||
// a next-in-flow will not be part of the current table.
|
||||
while (kidFrame) {
|
||||
@ -2692,22 +2673,145 @@ nsTableFrame::OrderRowGroups(nsVoidArray& aChildren,
|
||||
break;
|
||||
}
|
||||
}
|
||||
aNumRowGroups = aChildren.Count();
|
||||
|
||||
// put the thead first
|
||||
if (head) {
|
||||
aChildren.InsertElementAt(head, 0);
|
||||
aNumRowGroups++;
|
||||
aChildren.InsertElementAt(0, head);
|
||||
}
|
||||
|
||||
// put the tfoot after the last tbody
|
||||
if (foot) {
|
||||
aChildren.InsertElementAt(foot, aNumRowGroups);
|
||||
aNumRowGroups++;
|
||||
aChildren.AppendElement(foot);
|
||||
}
|
||||
// put the non row groups at the end
|
||||
PRInt32 numNonRowGroups = nonRowGroups.Count();
|
||||
for (PRInt32 i = 0; i < numNonRowGroups; i++) {
|
||||
aChildren.AppendElement(nonRowGroups.ElementAt(i));
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsTableFrame::OrderRowGroups(FrameArray& aChildren,
|
||||
nsTableRowGroupFrame** aHead,
|
||||
nsTableRowGroupFrame** aFoot) const
|
||||
{
|
||||
aChildren.Clear();
|
||||
// initialize out parameters
|
||||
*aHead = nsnull;
|
||||
*aFoot = nsnull;
|
||||
|
||||
FrameArray nonRowGroups;
|
||||
|
||||
nsIFrame* head = nsnull;
|
||||
nsIFrame* foot = nsnull;
|
||||
|
||||
nsIFrame* kidFrame = mFrames.FirstChild();
|
||||
while (kidFrame) {
|
||||
const nsStyleDisplay* kidDisplay = kidFrame->GetStyleDisplay();
|
||||
nsTableRowGroupFrame* rowGroup = GetRowGroupFrame(kidFrame);
|
||||
if (NS_LIKELY(rowGroup)) {
|
||||
switch(kidDisplay->mDisplay) {
|
||||
case NS_STYLE_DISPLAY_TABLE_HEADER_GROUP:
|
||||
if (head) { // treat additional thead like tbody
|
||||
aChildren.AppendElement(kidFrame);
|
||||
}
|
||||
else {
|
||||
head = kidFrame;
|
||||
*aHead = rowGroup;
|
||||
}
|
||||
break;
|
||||
case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP:
|
||||
if (foot) { // treat additional tfoot like tbody
|
||||
aChildren.AppendElement(kidFrame);
|
||||
}
|
||||
else {
|
||||
foot = kidFrame;
|
||||
*aFoot = rowGroup;
|
||||
}
|
||||
break;
|
||||
case NS_STYLE_DISPLAY_TABLE_ROW_GROUP:
|
||||
aChildren.AppendElement(kidFrame);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
NS_NOTREACHED("Non-row-group primary frame list child of an "
|
||||
"nsTableFrame? How come?");
|
||||
nonRowGroups.AppendElement(kidFrame);
|
||||
}
|
||||
|
||||
// Get the next sibling but skip it if it's also the next-in-flow, since
|
||||
// a next-in-flow will not be part of the current table.
|
||||
while (kidFrame) {
|
||||
nsIFrame* nif = kidFrame->GetNextInFlow();
|
||||
kidFrame = kidFrame->GetNextSibling();
|
||||
if (kidFrame != nif)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// put the thead first
|
||||
if (head) {
|
||||
aChildren.InsertElementAt(0, head);
|
||||
}
|
||||
|
||||
// put the tfoot after the last tbody
|
||||
if (foot) {
|
||||
aChildren.AppendElement(foot);
|
||||
}
|
||||
|
||||
PRUint32 rowGroupCount = aChildren.Length();
|
||||
aChildren.AppendElements(nonRowGroups);
|
||||
|
||||
return rowGroupCount;
|
||||
}
|
||||
|
||||
nsTableRowGroupFrame*
|
||||
nsTableFrame::GetTHead() const
|
||||
{
|
||||
nsIFrame* kidFrame = mFrames.FirstChild();
|
||||
while (kidFrame) {
|
||||
if (kidFrame->GetStyleDisplay()->mDisplay ==
|
||||
NS_STYLE_DISPLAY_TABLE_HEADER_GROUP) {
|
||||
nsTableRowGroupFrame* rg = GetRowGroupFrame(kidFrame);
|
||||
if (rg) {
|
||||
return rg;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the next sibling but skip it if it's also the next-in-flow, since
|
||||
// a next-in-flow will not be part of the current table.
|
||||
while (kidFrame) {
|
||||
nsIFrame* nif = kidFrame->GetNextInFlow();
|
||||
kidFrame = kidFrame->GetNextSibling();
|
||||
if (kidFrame != nif)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsTableRowGroupFrame*
|
||||
nsTableFrame::GetTFoot() const
|
||||
{
|
||||
nsIFrame* kidFrame = mFrames.FirstChild();
|
||||
while (kidFrame) {
|
||||
if (kidFrame->GetStyleDisplay()->mDisplay ==
|
||||
NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP) {
|
||||
nsTableRowGroupFrame* rg = GetRowGroupFrame(kidFrame);
|
||||
if (rg) {
|
||||
return rg;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the next sibling but skip it if it's also the next-in-flow, since
|
||||
// a next-in-flow will not be part of the current table.
|
||||
while (kidFrame) {
|
||||
nsIFrame* nif = kidFrame->GetNextInFlow();
|
||||
kidFrame = kidFrame->GetNextSibling();
|
||||
if (kidFrame != nif)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
@ -2742,13 +2846,12 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
||||
mBits.mResizedColumns ||
|
||||
IsGeometryDirty();
|
||||
|
||||
nsAutoVoidArray rowGroups;
|
||||
PRUint32 numRowGroups;
|
||||
FrameArray rowGroups;
|
||||
nsTableRowGroupFrame *thead, *tfoot;
|
||||
OrderRowGroups(rowGroups, numRowGroups, &thead, &tfoot);
|
||||
PRUint32 numRowGroups = OrderRowGroups(rowGroups, &thead, &tfoot);
|
||||
PRBool pageBreak = PR_FALSE;
|
||||
for (PRUint32 childX = 0; childX < numRowGroups; childX++) {
|
||||
nsIFrame* kidFrame = (nsIFrame*)rowGroups.ElementAt(childX);
|
||||
nsIFrame* kidFrame = rowGroups[childX];
|
||||
// Get the frame state bits
|
||||
// See if we should only reflow the dirty child frames
|
||||
if (reflowAllKids ||
|
||||
@ -2770,8 +2873,10 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
||||
nscoord repeatedFooterHeight = 0;
|
||||
if (isPaginated && (NS_UNCONSTRAINEDSIZE != kidAvailSize.height)) {
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == kidFrame->GetStyleDisplay()->mDisplay) { // the child is a tbody
|
||||
nsIFrame* lastChild = (nsIFrame*)rowGroups.ElementAt(numRowGroups - 1);
|
||||
nsIFrame* lastChild = rowGroups[rowGroups.Length() - 1];
|
||||
if (NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == lastChild->GetStyleDisplay()->mDisplay) { // the last child is a tfoot
|
||||
// XXXbz what if lastChild is a scrollable tfoot? Bogus!!
|
||||
// dbaron is right -- this should be using thead/tfoot!
|
||||
if (((nsTableRowGroupFrame*)lastChild)->IsRepeatable()) {
|
||||
repeatedFooterHeight = lastChild->GetSize().height;
|
||||
if (repeatedFooterHeight + cellSpacingY < kidAvailSize.height) {
|
||||
@ -2817,10 +2922,11 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
||||
|
||||
if (reorder) {
|
||||
// reorder row groups the reflow may have changed the nextinflows
|
||||
OrderRowGroups(rowGroups, numRowGroups, &thead, &tfoot);
|
||||
for (childX = 0; childX < numRowGroups; childX++) {
|
||||
if (kidFrame == (nsIFrame*)rowGroups.ElementAt(childX))
|
||||
break;
|
||||
numRowGroups = OrderRowGroups(rowGroups, &thead, &tfoot);
|
||||
childX = rowGroups.IndexOf(kidFrame);
|
||||
if (childX == RowGroupArray::NoIndex) {
|
||||
// XXXbz can this happen?
|
||||
childX = numRowGroups;
|
||||
}
|
||||
}
|
||||
// see if the rowgroup did not fit on this page might be pushed on
|
||||
@ -2830,8 +2936,8 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
||||
kidReflowState.availableHeight < desiredSize.height) {
|
||||
// if we are on top of the page place with dataloss
|
||||
if (kidReflowState.mFlags.mIsTopOfPage) {
|
||||
if (childX+1 < numRowGroups) {
|
||||
nsIFrame* nextRowGroupFrame = (nsIFrame*) rowGroups.ElementAt(childX +1);
|
||||
if (childX+1 < rowGroups.Length()) {
|
||||
nsIFrame* nextRowGroupFrame = rowGroups[childX + 1];
|
||||
if (nextRowGroupFrame) {
|
||||
PlaceChild(aReflowState, kidFrame, desiredSize);
|
||||
aStatus = NS_FRAME_NOT_COMPLETE;
|
||||
@ -2857,7 +2963,8 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
||||
// see if there is a page break after this row group or before the next one
|
||||
if (NS_FRAME_IS_COMPLETE(aStatus) && isPaginated &&
|
||||
(NS_UNCONSTRAINEDSIZE != kidReflowState.availableHeight)) {
|
||||
nsIFrame* nextKid = (childX + 1 < numRowGroups) ? (nsIFrame*)rowGroups.ElementAt(childX + 1) : nsnull;
|
||||
nsIFrame* nextKid =
|
||||
(childX + 1 < numRowGroups) ? rowGroups[childX + 1] : nsnull;
|
||||
pageBreak = PageBreakAfter(*kidFrame, nextKid);
|
||||
}
|
||||
|
||||
@ -2890,11 +2997,11 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
||||
// would have been if we had called OrderRowGroups
|
||||
// again. Note that rowGroups doesn't get used again after
|
||||
// we PushChildren below, anyway.
|
||||
rowGroups.InsertElementAt(continuingFrame, childX + 1);
|
||||
rowGroups.InsertElementAt(childX + 1, continuingFrame);
|
||||
}
|
||||
else {
|
||||
// put the nextinflow so that it will get pushed
|
||||
rowGroups.InsertElementAt(kidNextInFlow, childX + 1);
|
||||
rowGroups.InsertElementAt(childX + 1, kidNextInFlow);
|
||||
}
|
||||
// We've used up all of our available space so push the remaining
|
||||
// children to the next-in-flow
|
||||
@ -2992,10 +3099,9 @@ nsTableFrame::CalcDesiredHeight(const nsHTMLReflowState& aReflowState, nsHTMLRef
|
||||
nsMargin borderPadding = GetChildAreaOffset(&aReflowState);
|
||||
|
||||
// get the natural height based on the last child's (row group or scroll frame) rect
|
||||
nsAutoVoidArray rowGroups;
|
||||
PRUint32 numRowGroups;
|
||||
OrderRowGroups(rowGroups, numRowGroups);
|
||||
if (numRowGroups <= 0) {
|
||||
RowGroupArray rowGroups;
|
||||
OrderRowGroups(rowGroups);
|
||||
if (rowGroups.Length() == 0) {
|
||||
// tables can be used as rectangular items without content
|
||||
nscoord tableSpecifiedHeight = CalcBorderBoxHeight(aReflowState);
|
||||
if ((NS_UNCONSTRAINEDSIZE != tableSpecifiedHeight) &&
|
||||
@ -3013,11 +3119,8 @@ nsTableFrame::CalcDesiredHeight(const nsHTMLReflowState& aReflowState, nsHTMLRef
|
||||
nscoord desiredHeight = borderPadding.top + borderPadding.bottom;
|
||||
if (rowCount > 0 && colCount > 0) {
|
||||
desiredHeight += cellSpacingY;
|
||||
for (PRUint32 rgX = 0; rgX < numRowGroups; rgX++) {
|
||||
nsIFrame* rg = (nsIFrame*)rowGroups.ElementAt(rgX);
|
||||
if (rg) {
|
||||
desiredHeight += rg->GetSize().height + cellSpacingY;
|
||||
}
|
||||
for (PRUint32 rgX = 0; rgX < rowGroups.Length(); rgX++) {
|
||||
desiredHeight += rowGroups[rgX]->GetSize().height + cellSpacingY;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3043,9 +3146,8 @@ nsTableFrame::CalcDesiredHeight(const nsHTMLReflowState& aReflowState, nsHTMLRef
|
||||
static
|
||||
void ResizeCells(nsTableFrame& aTableFrame)
|
||||
{
|
||||
nsAutoVoidArray rowGroups;
|
||||
PRUint32 numRowGroups;
|
||||
aTableFrame.OrderRowGroups(rowGroups, numRowGroups);
|
||||
nsTableFrame::RowGroupArray rowGroups;
|
||||
aTableFrame.OrderRowGroups(rowGroups);
|
||||
nsHTMLReflowMetrics tableDesiredSize;
|
||||
nsRect tableRect = aTableFrame.GetRect();
|
||||
tableDesiredSize.width = tableRect.width;
|
||||
@ -3053,8 +3155,8 @@ void ResizeCells(nsTableFrame& aTableFrame)
|
||||
tableDesiredSize.mOverflowArea = nsRect(0, 0, tableRect.width,
|
||||
tableRect.height);
|
||||
|
||||
for (PRUint32 rgX = 0; (rgX < numRowGroups); rgX++) {
|
||||
nsTableRowGroupFrame* rgFrame = aTableFrame.GetRowGroupFrame((nsIFrame*)rowGroups.ElementAt(rgX));
|
||||
for (PRUint32 rgX = 0; rgX < rowGroups.Length(); rgX++) {
|
||||
nsTableRowGroupFrame* rgFrame = rowGroups[rgX];
|
||||
|
||||
nsRect rowGroupRect = rgFrame->GetRect();
|
||||
nsHTMLReflowMetrics groupDesiredSize;
|
||||
@ -3087,9 +3189,8 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
|
||||
|
||||
nsMargin borderPadding = GetChildAreaOffset(&aReflowState);
|
||||
|
||||
nsVoidArray rowGroups;
|
||||
PRUint32 numRowGroups;
|
||||
OrderRowGroups(rowGroups, numRowGroups);
|
||||
RowGroupArray rowGroups;
|
||||
OrderRowGroups(rowGroups);
|
||||
|
||||
nscoord amountUsed = 0;
|
||||
// distribute space to each pct height row whose row group doesn't have a computed
|
||||
@ -3099,12 +3200,12 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
|
||||
nscoord yOriginRG = borderPadding.top + GetCellSpacingY();
|
||||
nscoord yEndRG = yOriginRG;
|
||||
PRUint32 rgX;
|
||||
for (rgX = 0; (rgX < numRowGroups); rgX++) {
|
||||
nsTableRowGroupFrame* rgFrame = GetRowGroupFrame((nsIFrame*)rowGroups.ElementAt(rgX));
|
||||
for (rgX = 0; rgX < rowGroups.Length(); rgX++) {
|
||||
nsTableRowGroupFrame* rgFrame = rowGroups[rgX];
|
||||
nscoord amountUsedByRG = 0;
|
||||
nscoord yOriginRow = 0;
|
||||
nsRect rgRect = rgFrame->GetRect();
|
||||
if (rgFrame && !rgFrame->HasStyleHeight()) {
|
||||
if (!rgFrame->HasStyleHeight()) {
|
||||
nsTableRowFrame* rowFrame = rgFrame->GetFirstRow();
|
||||
while (rowFrame) {
|
||||
nsRect rowRect = rowFrame->GetRect();
|
||||
@ -3154,9 +3255,9 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
|
||||
// get the first row without a style height where its row group has an unconstrianed height
|
||||
nsTableRowGroupFrame* firstUnStyledRG = nsnull;
|
||||
nsTableRowFrame* firstUnStyledRow = nsnull;
|
||||
for (rgX = 0; (rgX < numRowGroups) && !firstUnStyledRG; rgX++) {
|
||||
nsTableRowGroupFrame* rgFrame = GetRowGroupFrame((nsIFrame*)rowGroups.ElementAt(rgX));
|
||||
if (rgFrame && !rgFrame->HasStyleHeight()) {
|
||||
for (rgX = 0; rgX < rowGroups.Length() && !firstUnStyledRG; rgX++) {
|
||||
nsTableRowGroupFrame* rgFrame = rowGroups[rgX];
|
||||
if (!rgFrame->HasStyleHeight()) {
|
||||
nsTableRowFrame* rowFrame = rgFrame->GetFirstRow();
|
||||
while (rowFrame) {
|
||||
if (!rowFrame->HasStyleHeight()) {
|
||||
@ -3173,9 +3274,9 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
|
||||
// accumulate the correct divisor. This will be the total of all unstyled rows inside
|
||||
// unstyled row groups, unless there are none, in which case, it will be all rows
|
||||
nscoord divisor = 0;
|
||||
for (rgX = 0; rgX < numRowGroups; rgX++) {
|
||||
nsTableRowGroupFrame* rgFrame = GetRowGroupFrame((nsIFrame*)rowGroups.ElementAt(rgX));
|
||||
if (rgFrame && (!firstUnStyledRG || !rgFrame->HasStyleHeight())) {
|
||||
for (rgX = 0; rgX < rowGroups.Length(); rgX++) {
|
||||
nsTableRowGroupFrame* rgFrame = rowGroups[rgX];
|
||||
if (!firstUnStyledRG || !rgFrame->HasStyleHeight()) {
|
||||
nsTableRowFrame* rowFrame = rgFrame->GetFirstRow();
|
||||
while (rowFrame) {
|
||||
if (!firstUnStyledRG || !rowFrame->HasStyleHeight()) {
|
||||
@ -3195,9 +3296,8 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
|
||||
pctBasis = aAmount - amountUsed;
|
||||
yOriginRG = borderPadding.top + cellSpacingY;
|
||||
yEndRG = yOriginRG;
|
||||
for (rgX = 0; rgX < numRowGroups; rgX++) {
|
||||
nsTableRowGroupFrame* rgFrame = GetRowGroupFrame((nsIFrame*)rowGroups.ElementAt(rgX));
|
||||
if (!rgFrame) continue;
|
||||
for (rgX = 0; rgX < rowGroups.Length(); rgX++) {
|
||||
nsTableRowGroupFrame* rgFrame = rowGroups[rgX];
|
||||
nscoord amountUsedByRG = 0;
|
||||
nscoord yOriginRow = 0;
|
||||
nsRect rgRect = rgFrame->GetRect();
|
||||
@ -3330,12 +3430,13 @@ nscoord nsTableFrame::GetCellSpacingY()
|
||||
nsTableFrame::GetBaseline() const
|
||||
{
|
||||
nscoord ascent = 0;
|
||||
nsAutoVoidArray orderedRowGroups;
|
||||
PRUint32 numRowGroups;
|
||||
OrderRowGroups(orderedRowGroups, numRowGroups);
|
||||
RowGroupArray orderedRowGroups;
|
||||
OrderRowGroups(orderedRowGroups);
|
||||
nsTableRowFrame* firstRow = nsnull;
|
||||
for (PRUint32 rgIndex = 0; rgIndex < numRowGroups; rgIndex++) {
|
||||
nsTableRowGroupFrame* rgFrame = GetRowGroupFrame((nsIFrame*)orderedRowGroups.ElementAt(rgIndex));
|
||||
for (PRUint32 rgIndex = 0; rgIndex < orderedRowGroups.Length(); rgIndex++) {
|
||||
// XXXbz Do we really want to just let through the scrollable
|
||||
// rowgroups and use their ascent?
|
||||
nsTableRowGroupFrame* rgFrame = orderedRowGroups[rgIndex];
|
||||
if (rgFrame->GetRowCount()) {
|
||||
firstRow = rgFrame->GetFirstRow();
|
||||
ascent = rgFrame->GetRect().y + firstRow->GetRect().y + firstRow->GetRowBaseline();
|
||||
@ -3895,7 +3996,7 @@ private:
|
||||
|
||||
nsTableFrame& mTableFrame;
|
||||
nsTableCellMap* mTableCellMap;
|
||||
nsVoidArray mRowGroups;
|
||||
nsTableFrame::RowGroupArray mRowGroups;
|
||||
nsTableRowGroupFrame* mRowGroup;
|
||||
PRInt32 mRowGroupIndex;
|
||||
PRUint32 mNumRows;
|
||||
@ -3928,8 +4029,7 @@ BCMapCellIterator::BCMapCellIterator(nsTableFrame& aTableFrame,
|
||||
mRowGroupIndex = -1;
|
||||
|
||||
// Get the ordered row groups
|
||||
PRUint32 numRowGroups;
|
||||
aTableFrame.OrderRowGroups(mRowGroups, numRowGroups);
|
||||
aTableFrame.OrderRowGroups(mRowGroups);
|
||||
|
||||
mAtEnd = PR_TRUE; // gets reset when First() is called
|
||||
}
|
||||
@ -4065,15 +4165,19 @@ BCMapCellIterator::SetNewRowGroup(PRBool aFindFirstDamagedRow)
|
||||
{
|
||||
mAtEnd = PR_TRUE;
|
||||
mRowGroupIndex++;
|
||||
PRInt32 numRowGroups = mRowGroups.Count();
|
||||
PRInt32 numRowGroups = mRowGroups.Length();
|
||||
mCellMap = nsnull;
|
||||
for (PRInt32 rgX = mRowGroupIndex; rgX < numRowGroups; rgX++) {
|
||||
nsIFrame* frame = (nsIFrame*)mRowGroups.ElementAt(mRowGroupIndex); if (!frame) ABORT1(PR_FALSE);
|
||||
mRowGroup = mTableFrame.GetRowGroupFrame(frame); if (!mRowGroup) ABORT1(PR_FALSE);
|
||||
// XXXbz do we really want the group at mRowGroupIndex? If so, what's the
|
||||
// point of this rgX loop variable, exactly? Why not just do a while
|
||||
// (mRowGroupIndex < numRowGroups) loop or something? I suspect this means
|
||||
// to be getting the rowgroup at rgX.
|
||||
mRowGroup = mRowGroups[mRowGroupIndex];
|
||||
PRInt32 rowCount = mRowGroup->GetRowCount();
|
||||
mRowGroupStart = mRowGroup->GetStartRowIndex();
|
||||
mRowGroupEnd = mRowGroupStart + rowCount - 1;
|
||||
if (rowCount > 0) {
|
||||
if (rowCount > 0) { // XXXbz and if it's not we just keep looping? What's
|
||||
// the point?
|
||||
mCellMap = mTableCellMap->GetMapFor(mRowGroup, mCellMap);
|
||||
if (!mCellMap) ABORT1(PR_FALSE);
|
||||
nsTableRowFrame* firstRow = mRowGroup->GetFirstRow();
|
||||
@ -4084,7 +4188,8 @@ BCMapCellIterator::SetNewRowGroup(PRBool aFindFirstDamagedRow)
|
||||
// find the correct first damaged row
|
||||
PRInt32 numRows = mAreaStart.y - mRowGroupStart;
|
||||
for (PRInt32 i = 0; i < numRows; i++) {
|
||||
firstRow = firstRow->GetNextRow(); if (!frame) ABORT1(PR_FALSE);
|
||||
firstRow = firstRow->GetNextRow();
|
||||
if (!firstRow) ABORT1(PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4199,8 +4304,7 @@ BCMapCellIterator::PeekBottom(BCMapCellInfo& aRefInfo,
|
||||
PRInt32 nextRgIndex = mRowGroupIndex;
|
||||
do {
|
||||
nextRgIndex++;
|
||||
nsIFrame* frame = (nsTableRowGroupFrame*)mRowGroups.ElementAt(nextRgIndex); if (!frame) ABORT0();
|
||||
rg = mTableFrame.GetRowGroupFrame(frame);
|
||||
rg = mRowGroups.SafeElementAt(nextRgIndex);
|
||||
if (rg) {
|
||||
cellMap = mTableCellMap->GetMapFor(rg, cellMap); if (!cellMap) ABORT0();
|
||||
rgRowIndex = 0;
|
||||
@ -4803,15 +4907,13 @@ nsTableFrame::ExpandBCDamageArea(nsRect& aRect) const
|
||||
if ((dStartX > 0) || (dEndX < (numCols - 1)) || (dStartY > 0) || (dEndY < (numRows - 1))) {
|
||||
nsTableCellMap* tableCellMap = GetCellMap(); if (!tableCellMap) ABORT0();
|
||||
// Get the ordered row groups
|
||||
PRUint32 numRowGroups;
|
||||
nsVoidArray rowGroups;
|
||||
OrderRowGroups(rowGroups, numRowGroups);
|
||||
RowGroupArray rowGroups;
|
||||
OrderRowGroups(rowGroups);
|
||||
|
||||
// Scope outside loop to be used as hint.
|
||||
nsCellMap* cellMap = nsnull;
|
||||
for (PRUint32 rgX = 0; rgX < numRowGroups; rgX++) {
|
||||
nsIFrame* kidFrame = (nsIFrame*)rowGroups.ElementAt(rgX);
|
||||
nsTableRowGroupFrame* rgFrame = GetRowGroupFrame(kidFrame); if (!rgFrame) ABORT0();
|
||||
for (PRUint32 rgX = 0; rgX < rowGroups.Length(); rgX++) {
|
||||
nsTableRowGroupFrame* rgFrame = rowGroups[rgX];
|
||||
PRInt32 rgStartY = rgFrame->GetStartRowIndex();
|
||||
PRInt32 rgEndY = rgStartY + rgFrame->GetRowCount() - 1;
|
||||
if (dEndY < rgStartY)
|
||||
@ -5532,7 +5634,7 @@ public:
|
||||
nsTableCellMap* tableCellMap;
|
||||
nsCellMap* cellMap;
|
||||
|
||||
nsVoidArray rowGroups;
|
||||
nsTableFrame::RowGroupArray rowGroups;
|
||||
nsTableRowGroupFrame* prevRg;
|
||||
nsTableRowGroupFrame* rg;
|
||||
PRInt32 rowGroupIndex;
|
||||
@ -5620,8 +5722,7 @@ BCMapBorderIterator::Reset(nsTableFrame& aTable,
|
||||
bcData = nsnull;
|
||||
|
||||
// Get the ordered row groups
|
||||
PRUint32 numRowGroups;
|
||||
table->OrderRowGroups(rowGroups, numRowGroups);
|
||||
table->OrderRowGroups(rowGroups);
|
||||
}
|
||||
|
||||
void
|
||||
@ -5698,10 +5799,9 @@ BCMapBorderIterator::SetNewRowGroup()
|
||||
isRepeatedHeader = PR_FALSE;
|
||||
isRepeatedFooter = PR_FALSE;
|
||||
|
||||
if (rowGroupIndex < rowGroups.Count()) {
|
||||
if (rowGroupIndex < rowGroups.Length()) {
|
||||
prevRg = rg;
|
||||
nsIFrame* frame = (nsTableRowGroupFrame*)rowGroups.ElementAt(rowGroupIndex); if (!frame) ABORT1(PR_FALSE);
|
||||
rg = table->GetRowGroupFrame(frame); if (!rg) ABORT1(PR_FALSE);
|
||||
rg = rowGroups[rowGroupIndex];
|
||||
fifRowGroupStart = ((nsTableRowGroupFrame*)rg->GetFirstInFlow())->GetStartRowIndex();
|
||||
rowGroupStart = rg->GetStartRowIndex();
|
||||
rowGroupEnd = rowGroupStart + rg->GetRowCount() - 1;
|
||||
@ -5736,25 +5836,22 @@ BCMapBorderIterator::First()
|
||||
|
||||
atEnd = PR_FALSE;
|
||||
|
||||
PRUint32 numRowGroups = rowGroups.Count();
|
||||
PRUint32 numRowGroups = rowGroups.Length();
|
||||
for (PRUint32 rgX = 0; rgX < numRowGroups; rgX++) {
|
||||
nsIFrame* frame = (nsIFrame*)rowGroups.ElementAt(rgX);
|
||||
nsTableRowGroupFrame* rowG = table->GetRowGroupFrame(frame);
|
||||
if (rowG) {
|
||||
PRInt32 start = rowG->GetStartRowIndex();
|
||||
PRInt32 end = start + rowG->GetRowCount() - 1;
|
||||
if ((startY >= start) && (startY <= end)) {
|
||||
rowGroupIndex = rgX - 1; // SetNewRowGroup increments rowGroupIndex
|
||||
if (SetNewRowGroup()) {
|
||||
while ((y < startY) && !atEnd) {
|
||||
SetNewRow();
|
||||
}
|
||||
if (!atEnd) {
|
||||
SetNewData(startY, startX);
|
||||
}
|
||||
nsTableRowGroupFrame* rowG = rowGroups[rgX];
|
||||
PRInt32 start = rowG->GetStartRowIndex();
|
||||
PRInt32 end = start + rowG->GetRowCount() - 1;
|
||||
if ((startY >= start) && (startY <= end)) {
|
||||
rowGroupIndex = rgX - 1; // SetNewRowGroup increments rowGroupIndex
|
||||
if (SetNewRowGroup()) {
|
||||
while ((y < startY) && !atEnd) {
|
||||
SetNewRow();
|
||||
}
|
||||
if (!atEnd) {
|
||||
SetNewData(startY, startX);
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
atEnd = PR_TRUE;
|
||||
@ -6031,9 +6128,8 @@ nsTableFrame::PaintBCBorders(nsIRenderingContext& aRenderingContext,
|
||||
PRUint32 startRowIndex, endRowIndex, startColIndex, endColIndex;
|
||||
startRowIndex = endRowIndex = startColIndex = endColIndex = 0;
|
||||
|
||||
nsAutoVoidArray rowGroups;
|
||||
PRUint32 numRowGroups;
|
||||
OrderRowGroups(rowGroups, numRowGroups);
|
||||
RowGroupArray rowGroups;
|
||||
OrderRowGroups(rowGroups);
|
||||
PRBool done = PR_FALSE;
|
||||
PRBool haveIntersect = PR_FALSE;
|
||||
nsTableRowGroupFrame* inFlowRG = nsnull;
|
||||
@ -6041,10 +6137,10 @@ nsTableFrame::PaintBCBorders(nsIRenderingContext& aRenderingContext,
|
||||
// find startRowIndex, endRowIndex, startRowY
|
||||
nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1);
|
||||
PRInt32 rowY = startRowY;
|
||||
for (PRUint32 rgX = 0; (rgX < numRowGroups) && !done; rgX++) {
|
||||
nsIFrame* kidFrame = (nsIFrame*)rowGroups.ElementAt(rgX);
|
||||
nsTableRowGroupFrame* rgFrame = GetRowGroupFrame(kidFrame); if (!rgFrame) ABORT0();
|
||||
for (nsTableRowFrame* rowFrame = rgFrame->GetFirstRow(); rowFrame; rowFrame = rowFrame->GetNextRow()) {
|
||||
for (PRUint32 rgX = 0; rgX < rowGroups.Length() && !done; rgX++) {
|
||||
nsTableRowGroupFrame* rgFrame = rowGroups[rgX];
|
||||
for (nsTableRowFrame* rowFrame = rgFrame->GetFirstRow(); rowFrame;
|
||||
rowFrame = rowFrame->GetNextRow()) {
|
||||
// conservatively estimate the half border widths outside the row
|
||||
nscoord topBorderHalf = (GetPrevInFlow()) ? 0 : nsPresContext::CSSPixelsToAppUnits(rowFrame->GetTopBCBorderWidth() + 1);
|
||||
nscoord bottomBorderHalf = (GetNextInFlow()) ? 0 : nsPresContext::CSSPixelsToAppUnits(rowFrame->GetBottomBCBorderWidth() + 1);
|
||||
|
||||
@ -558,16 +558,43 @@ protected:
|
||||
* frame at aPushFrom to the end of the array. The frames are put on our overflow
|
||||
* list or moved directly to our next-in-flow if one exists.
|
||||
*/
|
||||
void PushChildren(const nsAutoVoidArray& aFrames, PRInt32 aPushFrom);
|
||||
typedef nsAutoTPtrArray<nsIFrame, 8> FrameArray;
|
||||
void PushChildren(const FrameArray& aFrames, PRInt32 aPushFrom);
|
||||
|
||||
public:
|
||||
// put the children frames in the display order (e.g. thead before tbody before tfoot)
|
||||
// and put the non row group frames at the end. Also return the number of row group frames.
|
||||
void OrderRowGroups(nsVoidArray& aChildren,
|
||||
PRUint32& aNumRowGroups,
|
||||
nsTableRowGroupFrame** aHead = nsnull,
|
||||
nsTableRowGroupFrame** aFoot = nsnull) const;
|
||||
// put the children frames in the display order (e.g. thead before tbodies
|
||||
// before tfoot). This will handle calling GetRowGroupFrame() on the
|
||||
// children, and not append nulls, so the array is guaranteed to contain
|
||||
// nsTableRowGroupFrames. If there are multiple theads or tfoots, all but
|
||||
// the first one are treated as tbodies instead.
|
||||
typedef nsAutoTPtrArray<nsTableRowGroupFrame, 8> RowGroupArray;
|
||||
void OrderRowGroups(RowGroupArray& aChildren) const;
|
||||
|
||||
// Return the thead, if any
|
||||
nsTableRowGroupFrame* GetTHead() const;
|
||||
|
||||
// Return the tfoot, if any
|
||||
nsTableRowGroupFrame* GetTFoot() const;
|
||||
|
||||
protected:
|
||||
// As above, but does NOT actually call GetRowGroupFrame() on the kids, so
|
||||
// returns an array of nsIFrames. This is to be used when you really want
|
||||
// the flowable kids of the table, not the rowgroups. This outputs the thead
|
||||
// and tfoot if they happen to be rowgroups. All the child nsIFrames of the
|
||||
// table that return null if you call GetRowGroupFrame() on them will appear
|
||||
// at the end of the array, after the tfoot, if any.
|
||||
//
|
||||
// aHead and aFoot must not be null.
|
||||
//
|
||||
// @return the number of frames in aChildren which return non-null if you
|
||||
// call GetRowGroupFrame() on them.
|
||||
//
|
||||
// XXXbz why do we really care about the non-rowgroup kids?
|
||||
PRUint32 OrderRowGroups(FrameArray& aChildren,
|
||||
nsTableRowGroupFrame** aHead,
|
||||
nsTableRowGroupFrame** aFoot) const;
|
||||
|
||||
public:
|
||||
// Returns PR_TRUE if there are any cells above the row at
|
||||
// aRowIndex and spanning into the row at aRowIndex, the number of
|
||||
// effective columns limits the search up to that column
|
||||
|
||||
@ -352,19 +352,16 @@ TableBackgroundPainter::PaintTable(nsTableFrame* aTableFrame,
|
||||
{
|
||||
NS_PRECONDITION(aTableFrame, "null table frame");
|
||||
|
||||
nsVoidArray rowGroups;
|
||||
PRUint32 numRowGroups;
|
||||
aTableFrame->OrderRowGroups(rowGroups, numRowGroups);
|
||||
nsTableFrame::RowGroupArray rowGroups;
|
||||
aTableFrame->OrderRowGroups(rowGroups);
|
||||
|
||||
if (numRowGroups < 1) { //degenerate case
|
||||
PaintTableFrame(aTableFrame,nsnull, nsnull, nsnull);
|
||||
if (rowGroups.Length() < 1) { //degenerate case
|
||||
PaintTableFrame(aTableFrame, nsnull, nsnull, nsnull);
|
||||
/* No cells; nothing else to paint */
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PaintTableFrame(aTableFrame,
|
||||
aTableFrame->GetRowGroupFrame(NS_STATIC_CAST(nsIFrame*, rowGroups.ElementAt(0))),
|
||||
aTableFrame->GetRowGroupFrame(NS_STATIC_CAST(nsIFrame*, rowGroups.ElementAt(numRowGroups - 1))),
|
||||
PaintTableFrame(aTableFrame, rowGroups[0], rowGroups[rowGroups.Length() - 1],
|
||||
aDeflate);
|
||||
|
||||
/*Set up column background/border data*/
|
||||
@ -438,8 +435,8 @@ TableBackgroundPainter::PaintTable(nsTableFrame* aTableFrame,
|
||||
}
|
||||
}
|
||||
|
||||
for (PRUint32 i = 0; i < numRowGroups; i++) {
|
||||
nsTableRowGroupFrame* rg = nsTableFrame::GetRowGroupFrame(NS_STATIC_CAST(nsIFrame*, rowGroups.ElementAt(i)));
|
||||
for (PRUint32 i = 0; i < rowGroups.Length(); i++) {
|
||||
nsTableRowGroupFrame* rg = rowGroups[i];
|
||||
mRowGroup.SetFrame(rg);
|
||||
// Need to compute the right rect via GetOffsetTo, since the row
|
||||
// group may not be a child of the table.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user