LCOV - code coverage report
Current view: directory - layout/tables - nsTableRowFrame.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 648 0 0.0 %
Date: 2012-06-02 Functions: 55 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      26                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : #include "nsTableRowFrame.h"
      38                 : #include "nsTableRowGroupFrame.h"
      39                 : #include "nsIPresShell.h"
      40                 : #include "nsPresContext.h"
      41                 : #include "nsStyleContext.h"
      42                 : #include "nsStyleConsts.h"
      43                 : #include "nsGkAtoms.h"
      44                 : #include "nsIContent.h"
      45                 : #include "nsTableFrame.h"
      46                 : #include "nsTableCellFrame.h"
      47                 : #include "nsCSSRendering.h"
      48                 : #include "nsHTMLParts.h"
      49                 : #include "nsTableColGroupFrame.h"
      50                 : #include "nsTableColFrame.h"
      51                 : #include "nsCOMPtr.h"
      52                 : #include "nsDisplayList.h"
      53                 : 
      54                 : using namespace mozilla;
      55                 : 
      56                 : struct nsTableCellReflowState : public nsHTMLReflowState
      57               0 : {
      58               0 :   nsTableCellReflowState(nsPresContext*           aPresContext,
      59                 :                          const nsHTMLReflowState& aParentReflowState,
      60                 :                          nsIFrame*                aFrame,
      61                 :                          const nsSize&            aAvailableSpace,
      62                 :                          bool                     aInit = true)
      63                 :     : nsHTMLReflowState(aPresContext, aParentReflowState, aFrame,
      64               0 :                         aAvailableSpace, -1, -1, aInit)
      65                 :   {
      66               0 :   }
      67                 : 
      68                 :   void FixUp(const nsSize& aAvailSpace);
      69                 : };
      70                 : 
      71               0 : void nsTableCellReflowState::FixUp(const nsSize& aAvailSpace)
      72                 : {
      73                 :   // fix the mComputed values during a pass 2 reflow since the cell can be a percentage base
      74               0 :   NS_WARN_IF_FALSE(NS_UNCONSTRAINEDSIZE != aAvailSpace.width,
      75                 :                    "have unconstrained width; this should only result from "
      76                 :                    "very large sizes, not attempts at intrinsic width "
      77                 :                    "calculation");
      78               0 :   if (NS_UNCONSTRAINEDSIZE != ComputedWidth()) {
      79                 :     nscoord computedWidth =
      80               0 :       aAvailSpace.width - mComputedBorderPadding.LeftRight();
      81               0 :     computedWidth = NS_MAX(0, computedWidth);
      82               0 :     SetComputedWidth(computedWidth);
      83                 :   }
      84               0 :   if (NS_UNCONSTRAINEDSIZE != ComputedHeight() &&
      85                 :       NS_UNCONSTRAINEDSIZE != aAvailSpace.height) {
      86                 :     nscoord computedHeight =
      87               0 :       aAvailSpace.height - mComputedBorderPadding.TopBottom();
      88               0 :     computedHeight = NS_MAX(0, computedHeight);
      89               0 :     SetComputedHeight(computedHeight);
      90                 :   }
      91               0 : }
      92                 : 
      93                 : void
      94               0 : nsTableRowFrame::InitChildReflowState(nsPresContext&         aPresContext,
      95                 :                                       const nsSize&           aAvailSize,
      96                 :                                       bool                    aBorderCollapse,
      97                 :                                       nsTableCellReflowState& aReflowState)
      98                 : {
      99               0 :   nsMargin collapseBorder;
     100               0 :   nsMargin* pCollapseBorder = nsnull;
     101               0 :   if (aBorderCollapse) {
     102                 :     // we only reflow cells, so don't need to check frame type
     103               0 :     nsBCTableCellFrame* bcCellFrame = (nsBCTableCellFrame*)aReflowState.frame;
     104               0 :     if (bcCellFrame) {
     105               0 :       pCollapseBorder = bcCellFrame->GetBorderWidth(collapseBorder);
     106                 :     }
     107                 :   }
     108               0 :   aReflowState.Init(&aPresContext, -1, -1, pCollapseBorder);
     109               0 :   aReflowState.FixUp(aAvailSize);
     110               0 : }
     111                 : 
     112                 : void 
     113               0 : nsTableRowFrame::SetFixedHeight(nscoord aValue)
     114                 : {
     115               0 :   nscoord height = NS_MAX(0, aValue);
     116               0 :   if (HasFixedHeight()) {
     117               0 :     if (height > mStyleFixedHeight) {
     118               0 :       mStyleFixedHeight = height;
     119                 :     }
     120                 :   }
     121                 :   else {
     122               0 :     mStyleFixedHeight = height;
     123               0 :     if (height > 0) {
     124               0 :       SetHasFixedHeight(true);
     125                 :     }
     126                 :   }
     127               0 : }
     128                 : 
     129                 : void 
     130               0 : nsTableRowFrame::SetPctHeight(float  aPctValue,
     131                 :                               bool aForce)
     132                 : {
     133               0 :   nscoord height = NS_MAX(0, NSToCoordRound(aPctValue * 100.0f));
     134               0 :   if (HasPctHeight()) {
     135               0 :     if ((height > mStylePctHeight) || aForce) {
     136               0 :       mStylePctHeight = height;
     137                 :     }
     138                 :   }
     139                 :   else {
     140               0 :     mStylePctHeight = height;
     141               0 :     if (height > 0) {
     142               0 :       SetHasPctHeight(true);
     143                 :     }
     144                 :   }
     145               0 : }
     146                 : 
     147                 : /* ----------- nsTableRowFrame ---------- */
     148                 : 
     149               0 : NS_QUERYFRAME_HEAD(nsTableRowFrame)
     150               0 :   NS_QUERYFRAME_ENTRY(nsTableRowFrame)
     151               0 : NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
     152                 : 
     153               0 : nsTableRowFrame::nsTableRowFrame(nsStyleContext* aContext)
     154               0 :   : nsContainerFrame(aContext)
     155                 : {
     156               0 :   mBits.mRowIndex = mBits.mFirstInserted = 0;
     157               0 :   ResetHeight(0);
     158               0 : }
     159                 : 
     160               0 : nsTableRowFrame::~nsTableRowFrame()
     161                 : {
     162               0 : }
     163                 : 
     164                 : NS_IMETHODIMP
     165               0 : nsTableRowFrame::Init(nsIContent*      aContent,
     166                 :                       nsIFrame*        aParent,
     167                 :                       nsIFrame*        aPrevInFlow)
     168                 : {
     169                 :   nsresult  rv;
     170                 : 
     171                 :   // Let the base class do its initialization
     172               0 :   rv = nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
     173                 : 
     174               0 :   NS_ASSERTION(NS_STYLE_DISPLAY_TABLE_ROW == GetStyleDisplay()->mDisplay,
     175                 :                "wrong display on table row frame");
     176                 : 
     177               0 :   if (aPrevInFlow) {
     178                 :     // Set the row index
     179               0 :     nsTableRowFrame* rowFrame = (nsTableRowFrame*)aPrevInFlow;
     180                 :     
     181               0 :     SetRowIndex(rowFrame->GetRowIndex());
     182                 :   }
     183                 : 
     184               0 :   return rv;
     185                 : }
     186                 : 
     187                 : /* virtual */ void
     188               0 : nsTableRowFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
     189                 : {
     190               0 :   if (!aOldStyleContext) //avoid this on init
     191               0 :     return;
     192                 :      
     193               0 :   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
     194               0 :   if (tableFrame->IsBorderCollapse() &&
     195               0 :       tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
     196               0 :     nsIntRect damageArea(0, GetRowIndex(), tableFrame->GetColCount(), 1);
     197               0 :     tableFrame->AddBCDamageArea(damageArea);
     198                 :   }
     199                 : }
     200                 : 
     201                 : NS_IMETHODIMP
     202               0 : nsTableRowFrame::AppendFrames(ChildListID     aListID,
     203                 :                               nsFrameList&    aFrameList)
     204                 : {
     205               0 :   NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
     206                 : 
     207               0 :   const nsFrameList::Slice& newCells = mFrames.AppendFrames(nsnull, aFrameList);
     208                 : 
     209                 :   // Add the new cell frames to the table
     210               0 :   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
     211               0 :   for (nsFrameList::Enumerator e(newCells) ; !e.AtEnd(); e.Next()) {
     212               0 :     nsIFrame *childFrame = e.get();
     213               0 :     NS_ASSERTION(IS_TABLE_CELL(childFrame->GetType()),"Not a table cell frame/pseudo frame construction failure");
     214               0 :     tableFrame->AppendCell(static_cast<nsTableCellFrame&>(*childFrame), GetRowIndex());
     215                 :   }
     216                 : 
     217               0 :   PresContext()->PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
     218               0 :                                                NS_FRAME_HAS_DIRTY_CHILDREN);
     219               0 :   tableFrame->SetGeometryDirty();
     220                 : 
     221               0 :   return NS_OK;
     222                 : }
     223                 : 
     224                 : 
     225                 : NS_IMETHODIMP
     226               0 : nsTableRowFrame::InsertFrames(ChildListID     aListID,
     227                 :                               nsIFrame*       aPrevFrame,
     228                 :                               nsFrameList&    aFrameList)
     229                 : {
     230               0 :   NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
     231               0 :   NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
     232                 :                "inserting after sibling frame with different parent");
     233                 :   //Insert Frames in the frame list
     234               0 :   const nsFrameList::Slice& newCells = mFrames.InsertFrames(nsnull, aPrevFrame, aFrameList);
     235                 : 
     236                 :   // Get the table frame
     237               0 :   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
     238               0 :   nsIAtom* cellFrameType = tableFrame->IsBorderCollapse() ? nsGkAtoms::bcTableCellFrame : nsGkAtoms::tableCellFrame;
     239               0 :   nsTableCellFrame* prevCellFrame = (nsTableCellFrame *)nsTableFrame::GetFrameAtOrBefore(this, aPrevFrame, cellFrameType);
     240               0 :   nsTArray<nsTableCellFrame*> cellChildren;
     241               0 :   for (nsFrameList::Enumerator e(newCells); !e.AtEnd(); e.Next()) {
     242               0 :     nsIFrame *childFrame = e.get();
     243               0 :     NS_ASSERTION(IS_TABLE_CELL(childFrame->GetType()),"Not a table cell frame/pseudo frame construction failure");
     244               0 :     cellChildren.AppendElement(static_cast<nsTableCellFrame*>(childFrame));
     245                 :   }
     246                 :   // insert the cells into the cell map
     247               0 :   PRInt32 colIndex = -1;
     248               0 :   if (prevCellFrame) {
     249               0 :     prevCellFrame->GetColIndex(colIndex);
     250                 :   }
     251               0 :   tableFrame->InsertCells(cellChildren, GetRowIndex(), colIndex);
     252                 :   
     253               0 :   PresContext()->PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
     254               0 :                                                NS_FRAME_HAS_DIRTY_CHILDREN);
     255               0 :   tableFrame->SetGeometryDirty();
     256                 : 
     257               0 :   return NS_OK;
     258                 : }
     259                 : 
     260                 : NS_IMETHODIMP
     261               0 : nsTableRowFrame::RemoveFrame(ChildListID     aListID,
     262                 :                              nsIFrame*       aOldFrame)
     263                 : {
     264               0 :   NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
     265                 : 
     266               0 :   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
     267               0 :   nsTableCellFrame *cellFrame = do_QueryFrame(aOldFrame);
     268               0 :   if (cellFrame) {
     269                 :     PRInt32 colIndex;
     270               0 :     cellFrame->GetColIndex(colIndex);
     271                 :     // remove the cell from the cell map
     272               0 :     tableFrame->RemoveCell(cellFrame, GetRowIndex());
     273                 : 
     274                 :     // Remove the frame and destroy it
     275               0 :     mFrames.DestroyFrame(aOldFrame);
     276                 : 
     277               0 :     PresContext()->PresShell()->
     278                 :       FrameNeedsReflow(this, nsIPresShell::eTreeChange,
     279               0 :                        NS_FRAME_HAS_DIRTY_CHILDREN);
     280               0 :     tableFrame->SetGeometryDirty();
     281                 :   }
     282                 :   else {
     283               0 :     NS_ERROR("unexpected frame type");
     284               0 :     return NS_ERROR_INVALID_ARG;
     285                 :   }
     286                 : 
     287               0 :   return NS_OK;
     288                 : }
     289                 : 
     290                 : /* virtual */ nsMargin
     291               0 : nsTableRowFrame::GetUsedMargin() const
     292                 : {
     293               0 :   return nsMargin(0,0,0,0);
     294                 : }
     295                 : 
     296                 : /* virtual */ nsMargin
     297               0 : nsTableRowFrame::GetUsedBorder() const
     298                 : {
     299               0 :   return nsMargin(0,0,0,0);
     300                 : }
     301                 : 
     302                 : /* virtual */ nsMargin
     303               0 : nsTableRowFrame::GetUsedPadding() const
     304                 : {
     305               0 :   return nsMargin(0,0,0,0);
     306                 : }
     307                 : 
     308                 : nscoord 
     309               0 : GetHeightOfRowsSpannedBelowFirst(nsTableCellFrame& aTableCellFrame,
     310                 :                                  nsTableFrame&     aTableFrame)
     311                 : {
     312               0 :   nscoord height = 0;
     313               0 :   nscoord cellSpacingY = aTableFrame.GetCellSpacingY();
     314               0 :   PRInt32 rowSpan = aTableFrame.GetEffectiveRowSpan(aTableCellFrame);
     315                 :   // add in height of rows spanned beyond the 1st one
     316               0 :   nsIFrame* nextRow = aTableCellFrame.GetParent()->GetNextSibling();
     317               0 :   for (PRInt32 rowX = 1; ((rowX < rowSpan) && nextRow);) {
     318               0 :     if (nsGkAtoms::tableRowFrame == nextRow->GetType()) {
     319               0 :       height += nextRow->GetSize().height;
     320               0 :       rowX++;
     321                 :     }
     322               0 :     height += cellSpacingY;
     323               0 :     nextRow = nextRow->GetNextSibling();
     324                 :   }
     325               0 :   return height;
     326                 : }
     327                 : 
     328                 : nsTableCellFrame*  
     329               0 : nsTableRowFrame::GetFirstCell() 
     330                 : {
     331               0 :   nsIFrame* childFrame = mFrames.FirstChild();
     332               0 :   while (childFrame) {
     333               0 :     nsTableCellFrame *cellFrame = do_QueryFrame(childFrame);
     334               0 :     if (cellFrame) {
     335               0 :       return cellFrame;
     336                 :     }
     337               0 :     childFrame = childFrame->GetNextSibling();
     338                 :   }
     339               0 :   return nsnull;
     340                 : }
     341                 : 
     342                 : /**
     343                 :  * Post-reflow hook. This is where the table row does its post-processing
     344                 :  */
     345                 : void
     346               0 : nsTableRowFrame::DidResize()
     347                 : {
     348                 :   // Resize and re-align the cell frames based on our row height
     349               0 :   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
     350               0 :   nsTableIterator iter(*this);
     351               0 :   nsIFrame* childFrame = iter.First();
     352                 :   
     353               0 :   nsHTMLReflowMetrics desiredSize;
     354               0 :   desiredSize.width = mRect.width;
     355               0 :   desiredSize.height = mRect.height;
     356               0 :   desiredSize.SetOverflowAreasToDesiredBounds();
     357                 : 
     358               0 :   while (childFrame) {
     359               0 :     nsTableCellFrame *cellFrame = do_QueryFrame(childFrame);
     360               0 :     if (cellFrame) {
     361               0 :       nscoord cellHeight = mRect.height + GetHeightOfRowsSpannedBelowFirst(*cellFrame, *tableFrame);
     362                 : 
     363                 :       // resize the cell's height
     364               0 :       nsRect cellRect = cellFrame->GetRect();
     365               0 :       nsRect cellVisualOverflow = cellFrame->GetVisualOverflowRect();
     366               0 :       if (cellRect.height != cellHeight)
     367                 :       {
     368               0 :         cellFrame->SetSize(nsSize(cellRect.width, cellHeight));
     369                 :         nsTableFrame::InvalidateFrame(cellFrame, cellRect,
     370                 :                                       cellVisualOverflow,
     371               0 :                                       false);
     372                 :       }
     373                 : 
     374                 :       // realign cell content based on the new height.  We might be able to
     375                 :       // skip this if the height didn't change... maybe.  Hard to tell.
     376               0 :       cellFrame->VerticallyAlignChild(mMaxCellAscent);
     377                 :       
     378                 :       // Always store the overflow, even if the height didn't change, since
     379                 :       // we'll lose part of our overflow area otherwise.
     380               0 :       ConsiderChildOverflow(desiredSize.mOverflowAreas, cellFrame);
     381                 : 
     382                 :       // Note that if the cell's *content* needs to change in response
     383                 :       // to this height, it will get a special height reflow.
     384                 :     }
     385                 :     // Get the next child
     386               0 :     childFrame = iter.Next();
     387                 :   }
     388               0 :   FinishAndStoreOverflow(&desiredSize);
     389               0 :   if (HasView()) {
     390                 :     nsContainerFrame::SyncFrameViewAfterReflow(PresContext(), this, GetView(),
     391               0 :                                                desiredSize.VisualOverflow(), 0);
     392                 :   }
     393                 :   // Let our base class do the usual work
     394               0 : }
     395                 : 
     396                 : // returns max-ascent amongst all cells that have 'vertical-align: baseline'
     397                 : // *including* cells with rowspans
     398               0 : nscoord nsTableRowFrame::GetMaxCellAscent() const
     399                 : {
     400               0 :   return mMaxCellAscent;
     401                 : }
     402                 : 
     403               0 : nscoord nsTableRowFrame::GetRowBaseline()
     404                 : {
     405               0 :   if(mMaxCellAscent)
     406               0 :     return mMaxCellAscent;
     407                 : 
     408                 :   // If we don't have a baseline on any of the cells we go for the lowest 
     409                 :   // content edge of the inner block frames. 
     410                 :   // Every table cell has a cell frame with its border and padding. Inside
     411                 :   // the cell is a block frame. The cell is as high as the tallest cell in
     412                 :   // the parent row. As a consequence the block frame might not touch both
     413                 :   // the top and the bottom padding of it parent cell frame at the same time.
     414                 :   // 
     415                 :   // bbbbbbbbbbbbbbbbbb             cell border:  b
     416                 :   // bppppppppppppppppb             cell padding: p
     417                 :   // bpxxxxxxxxxxxxxxpb             inner block:  x
     418                 :   // bpx            xpb
     419                 :   // bpx            xpb
     420                 :   // bpx            xpb
     421                 :   // bpxxxxxxxxxxxxxxpb  base line
     422                 :   // bp              pb
     423                 :   // bp              pb
     424                 :   // bppppppppppppppppb
     425                 :   // bbbbbbbbbbbbbbbbbb
     426                 : 
     427               0 :   nsTableIterator iter(*this);
     428               0 :   nsIFrame* childFrame = iter.First();
     429               0 :   nscoord ascent = 0;
     430               0 :    while (childFrame) {
     431               0 :     if (IS_TABLE_CELL(childFrame->GetType())) {
     432               0 :       nsIFrame* firstKid = childFrame->GetFirstPrincipalChild();
     433               0 :       ascent = NS_MAX(ascent, firstKid->GetRect().YMost());
     434                 :     }
     435                 :     // Get the next child
     436               0 :     childFrame = iter.Next();
     437                 :   }
     438               0 :   return ascent;
     439                 : }
     440                 : nscoord
     441               0 : nsTableRowFrame::GetHeight(nscoord aPctBasis) const
     442                 : {
     443               0 :   nscoord height = 0;
     444               0 :   if ((aPctBasis > 0) && HasPctHeight()) {
     445               0 :     height = NSToCoordRound(GetPctHeight() * (float)aPctBasis);
     446                 :   }
     447               0 :   if (HasFixedHeight()) {
     448               0 :     height = NS_MAX(height, GetFixedHeight());
     449                 :   }
     450               0 :   return NS_MAX(height, GetContentHeight());
     451                 : }
     452                 : 
     453                 : void 
     454               0 : nsTableRowFrame::ResetHeight(nscoord aFixedHeight)
     455                 : {
     456               0 :   SetHasFixedHeight(false);
     457               0 :   SetHasPctHeight(false);
     458               0 :   SetFixedHeight(0);
     459               0 :   SetPctHeight(0);
     460               0 :   SetContentHeight(0);
     461                 : 
     462               0 :   if (aFixedHeight > 0) {
     463               0 :     SetFixedHeight(aFixedHeight);
     464                 :   }
     465                 : 
     466               0 :   mMaxCellAscent = 0;
     467               0 :   mMaxCellDescent = 0;
     468               0 : }
     469                 : 
     470                 : void
     471               0 : nsTableRowFrame::UpdateHeight(nscoord           aHeight,
     472                 :                               nscoord           aAscent,
     473                 :                               nscoord           aDescent,
     474                 :                               nsTableFrame*     aTableFrame,
     475                 :                               nsTableCellFrame* aCellFrame)
     476                 : {
     477               0 :   if (!aTableFrame || !aCellFrame) {
     478               0 :     NS_ASSERTION(false , "invalid call");
     479               0 :     return;
     480                 :   }
     481                 : 
     482               0 :   if (aHeight != NS_UNCONSTRAINEDSIZE) {
     483               0 :     if (!(aCellFrame->HasVerticalAlignBaseline())) { // only the cell's height matters
     484               0 :       if (GetHeight() < aHeight) {
     485               0 :         PRInt32 rowSpan = aTableFrame->GetEffectiveRowSpan(*aCellFrame);
     486               0 :         if (rowSpan == 1) {
     487               0 :           SetContentHeight(aHeight);
     488                 :         }
     489                 :       }
     490                 :     }
     491                 :     else { // the alignment on the baseline can change the height
     492               0 :       NS_ASSERTION((aAscent != NS_UNCONSTRAINEDSIZE) && (aDescent != NS_UNCONSTRAINEDSIZE), "invalid call");
     493                 :       // see if this is a long ascender
     494               0 :       if (mMaxCellAscent < aAscent) {
     495               0 :         mMaxCellAscent = aAscent;
     496                 :       }
     497                 :       // see if this is a long descender and without rowspan
     498               0 :       if (mMaxCellDescent < aDescent) {
     499               0 :         PRInt32 rowSpan = aTableFrame->GetEffectiveRowSpan(*aCellFrame);
     500               0 :         if (rowSpan == 1) {
     501               0 :           mMaxCellDescent = aDescent;
     502                 :         }
     503                 :       }
     504                 :       // keep the tallest height in sync
     505               0 :       if (GetHeight() < mMaxCellAscent + mMaxCellDescent) {
     506               0 :         SetContentHeight(mMaxCellAscent + mMaxCellDescent);
     507                 :       }
     508                 :     }
     509                 :   }
     510                 : }
     511                 : 
     512                 : nscoord
     513               0 : nsTableRowFrame::CalcHeight(const nsHTMLReflowState& aReflowState)
     514                 : {
     515               0 :   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
     516               0 :   nscoord computedHeight = (NS_UNCONSTRAINEDSIZE == aReflowState.ComputedHeight())
     517               0 :                             ? 0 : aReflowState.ComputedHeight();
     518               0 :   ResetHeight(computedHeight);
     519                 : 
     520               0 :   const nsStylePosition* position = GetStylePosition();
     521               0 :   if (eStyleUnit_Coord == position->mHeight.GetUnit()) {
     522               0 :     SetFixedHeight(position->mHeight.GetCoordValue());
     523                 :   }
     524               0 :   else if (eStyleUnit_Percent == position->mHeight.GetUnit()) {
     525               0 :     SetPctHeight(position->mHeight.GetPercentValue());
     526                 :   }
     527                 :   // calc() is treated like 'auto' on table rows.
     528                 : 
     529               0 :   for (nsIFrame* kidFrame = mFrames.FirstChild(); kidFrame;
     530                 :        kidFrame = kidFrame->GetNextSibling()) {
     531               0 :     nsTableCellFrame *cellFrame = do_QueryFrame(kidFrame);
     532               0 :     if (cellFrame) {
     533               0 :       nsSize desSize = cellFrame->GetDesiredSize();
     534               0 :       if ((NS_UNCONSTRAINEDSIZE == aReflowState.availableHeight) && !GetPrevInFlow()) {
     535               0 :         CalculateCellActualHeight(cellFrame, desSize.height);
     536                 :       }
     537                 :       // height may have changed, adjust descent to absorb any excess difference
     538                 :       nscoord ascent;
     539               0 :        if (!kidFrame->GetFirstPrincipalChild()->GetFirstPrincipalChild())
     540               0 :          ascent = desSize.height;
     541                 :        else
     542               0 :          ascent = cellFrame->GetCellBaseline();
     543               0 :       nscoord descent = desSize.height - ascent;
     544               0 :       UpdateHeight(desSize.height, ascent, descent, tableFrame, cellFrame);
     545                 :     }
     546                 :   }
     547               0 :   return GetHeight();
     548                 : }
     549                 : 
     550                 : /**
     551                 :  * We need a custom display item for table row backgrounds. This is only used
     552                 :  * when the table row is the root of a stacking context (e.g., has 'opacity').
     553                 :  * Table row backgrounds can extend beyond the row frame bounds, when
     554                 :  * the row contains row-spanning cells.
     555                 :  */
     556                 : class nsDisplayTableRowBackground : public nsDisplayTableItem {
     557                 : public:
     558               0 :   nsDisplayTableRowBackground(nsDisplayListBuilder* aBuilder,
     559                 :                               nsTableRowFrame* aFrame) :
     560               0 :     nsDisplayTableItem(aBuilder, aFrame) {
     561               0 :     MOZ_COUNT_CTOR(nsDisplayTableRowBackground);
     562               0 :   }
     563                 : #ifdef NS_BUILD_REFCNT_LOGGING
     564               0 :   virtual ~nsDisplayTableRowBackground() {
     565               0 :     MOZ_COUNT_DTOR(nsDisplayTableRowBackground);
     566               0 :   }
     567                 : #endif
     568                 : 
     569                 :   virtual void Paint(nsDisplayListBuilder* aBuilder,
     570                 :                      nsRenderingContext* aCtx);
     571               0 :   NS_DISPLAY_DECL_NAME("TableRowBackground", TYPE_TABLE_ROW_BACKGROUND)
     572                 : };
     573                 : 
     574                 : void
     575               0 : nsDisplayTableRowBackground::Paint(nsDisplayListBuilder* aBuilder,
     576                 :                                    nsRenderingContext* aCtx)
     577                 : {
     578               0 :   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(mFrame);
     579                 :   TableBackgroundPainter painter(tableFrame,
     580                 :                                  TableBackgroundPainter::eOrigin_TableRow,
     581                 :                                  mFrame->PresContext(), *aCtx,
     582               0 :                                  mVisibleRect, ToReferenceFrame(),
     583               0 :                                  aBuilder->GetBackgroundPaintFlags());
     584               0 :   painter.PaintRow(static_cast<nsTableRowFrame*>(mFrame));
     585               0 : }
     586                 : 
     587                 : NS_IMETHODIMP
     588               0 : nsTableRowFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
     589                 :                                   const nsRect&           aDirtyRect,
     590                 :                                   const nsDisplayListSet& aLists)
     591                 : {
     592               0 :   nsDisplayTableItem* item = nsnull;
     593               0 :   if (IsVisibleInSelection(aBuilder)) {
     594               0 :     bool isRoot = aBuilder->IsAtRootOfPseudoStackingContext();
     595               0 :     if (isRoot) {
     596                 :       // This background is created regardless of whether this frame is
     597                 :       // visible or not. Visibility decisions are delegated to the
     598                 :       // table background painter.
     599                 :       // We would use nsDisplayGeneric for this rare case except that we
     600                 :       // need the background to be larger than the row frame in some
     601                 :       // cases.
     602               0 :       item = new (aBuilder) nsDisplayTableRowBackground(aBuilder, this);
     603               0 :       nsresult rv = aLists.BorderBackground()->AppendNewToTop(item);
     604               0 :       NS_ENSURE_SUCCESS(rv, rv);
     605                 :     }
     606                 :   }
     607               0 :   return nsTableFrame::DisplayGenericTablePart(aBuilder, this, aDirtyRect, aLists, item);
     608                 : }
     609                 : 
     610                 : PRIntn
     611               0 : nsTableRowFrame::GetSkipSides() const
     612                 : {
     613               0 :   PRIntn skip = 0;
     614               0 :   if (nsnull != GetPrevInFlow()) {
     615               0 :     skip |= 1 << NS_SIDE_TOP;
     616                 :   }
     617               0 :   if (nsnull != GetNextInFlow()) {
     618               0 :     skip |= 1 << NS_SIDE_BOTTOM;
     619                 :   }
     620               0 :   return skip;
     621                 : }
     622                 : 
     623                 : // Calculate the cell's actual height given its pass2  height.
     624                 : // Takes into account the specified height (in the style).
     625                 : // Modifies the desired height that is passed in.
     626                 : nsresult
     627               0 : nsTableRowFrame::CalculateCellActualHeight(nsTableCellFrame* aCellFrame,
     628                 :                                            nscoord&          aDesiredHeight)
     629                 : {
     630               0 :   nscoord specifiedHeight = 0;
     631                 :   
     632                 :   // Get the height specified in the style information
     633               0 :   const nsStylePosition* position = aCellFrame->GetStylePosition();
     634                 : 
     635               0 :   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
     636               0 :   PRInt32 rowSpan = tableFrame->GetEffectiveRowSpan(*aCellFrame);
     637                 :   
     638               0 :   switch (position->mHeight.GetUnit()) {
     639                 :     case eStyleUnit_Coord:
     640               0 :       specifiedHeight = position->mHeight.GetCoordValue();
     641               0 :       if (1 == rowSpan) 
     642               0 :         SetFixedHeight(specifiedHeight);
     643               0 :       break;
     644                 :     case eStyleUnit_Percent: {
     645               0 :       if (1 == rowSpan) 
     646               0 :         SetPctHeight(position->mHeight.GetPercentValue());
     647                 :       // pct heights are handled when all of the cells are finished, so don't set specifiedHeight 
     648               0 :       break;
     649                 :     }
     650                 :     case eStyleUnit_Auto:
     651                 :     default: // includes calc(), which we treat like 'auto'
     652               0 :       break;
     653                 :   }
     654                 : 
     655                 :   // If the specified height is greater than the desired height, then use the specified height
     656               0 :   if (specifiedHeight > aDesiredHeight)
     657               0 :     aDesiredHeight = specifiedHeight;
     658                 : 
     659               0 :   return NS_OK;
     660                 : }
     661                 : 
     662                 : // Calculates the available width for the table cell based on the known
     663                 : // column widths taking into account column spans and column spacing
     664                 : static nscoord
     665               0 : CalcAvailWidth(nsTableFrame&     aTableFrame,
     666                 :                nsTableCellFrame& aCellFrame,
     667                 :                nscoord           aCellSpacingX)
     668                 : {
     669               0 :   nscoord cellAvailWidth = 0;
     670                 :   PRInt32 colIndex;
     671               0 :   aCellFrame.GetColIndex(colIndex);
     672               0 :   PRInt32 colspan = aTableFrame.GetEffectiveColSpan(aCellFrame);
     673               0 :   NS_ASSERTION(colspan > 0, "effective colspan should be positive");
     674                 : 
     675               0 :   for (PRInt32 spanX = 0; spanX < colspan; spanX++) {
     676               0 :     cellAvailWidth += aTableFrame.GetColumnWidth(colIndex + spanX);
     677               0 :     if (spanX > 0 &&
     678               0 :         aTableFrame.ColumnHasCellSpacingBefore(colIndex + spanX)) {
     679               0 :       cellAvailWidth += aCellSpacingX;
     680                 :     }
     681                 :   }
     682               0 :   return cellAvailWidth;
     683                 : }
     684                 : 
     685                 : nscoord
     686               0 : GetSpaceBetween(PRInt32       aPrevColIndex,
     687                 :                 PRInt32       aColIndex,
     688                 :                 PRInt32       aColSpan,
     689                 :                 nsTableFrame& aTableFrame,
     690                 :                 nscoord       aCellSpacingX,
     691                 :                 bool          aIsLeftToRight,
     692                 :                 bool          aCheckVisibility)
     693                 : {
     694               0 :   nscoord space = 0;
     695                 :   PRInt32 colX;
     696               0 :   if (aIsLeftToRight) {
     697               0 :     for (colX = aPrevColIndex + 1; aColIndex > colX; colX++) {
     698               0 :       bool isCollapsed = false;
     699               0 :       if (!aCheckVisibility) {
     700               0 :         space += aTableFrame.GetColumnWidth(colX);
     701                 :       }
     702                 :       else {
     703               0 :         nsTableColFrame* colFrame = aTableFrame.GetColFrame(colX);
     704               0 :         const nsStyleVisibility* colVis = colFrame->GetStyleVisibility();
     705               0 :         bool collapseCol = (NS_STYLE_VISIBILITY_COLLAPSE == colVis->mVisible);
     706               0 :         nsIFrame* cgFrame = colFrame->GetParent();
     707               0 :         const nsStyleVisibility* groupVis = cgFrame->GetStyleVisibility();
     708                 :         bool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE ==
     709               0 :                                 groupVis->mVisible);
     710               0 :         isCollapsed = collapseCol || collapseGroup;
     711               0 :         if (!isCollapsed)
     712               0 :           space += aTableFrame.GetColumnWidth(colX);
     713                 :       }
     714               0 :       if (!isCollapsed && aTableFrame.ColumnHasCellSpacingBefore(colX)) {
     715               0 :         space += aCellSpacingX;
     716                 :       }
     717                 :     }
     718                 :   } 
     719                 :   else {
     720               0 :     PRInt32 lastCol = aColIndex + aColSpan - 1;
     721               0 :     for (colX = aPrevColIndex - 1; colX > lastCol; colX--) {
     722               0 :       bool isCollapsed = false;
     723               0 :       if (!aCheckVisibility) {
     724               0 :         space += aTableFrame.GetColumnWidth(colX);
     725                 :       }
     726                 :       else {
     727               0 :         nsTableColFrame* colFrame = aTableFrame.GetColFrame(colX);
     728               0 :         const nsStyleVisibility* colVis = colFrame->GetStyleVisibility();
     729               0 :         bool collapseCol = (NS_STYLE_VISIBILITY_COLLAPSE == colVis->mVisible);
     730               0 :         nsIFrame* cgFrame = colFrame->GetParent();
     731               0 :         const nsStyleVisibility* groupVis = cgFrame->GetStyleVisibility();
     732                 :         bool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE ==
     733               0 :                                 groupVis->mVisible);
     734               0 :         isCollapsed = collapseCol || collapseGroup;
     735               0 :         if (!isCollapsed)
     736               0 :           space += aTableFrame.GetColumnWidth(colX);
     737                 :       }
     738               0 :       if (!isCollapsed && aTableFrame.ColumnHasCellSpacingBefore(colX)) {
     739               0 :         space += aCellSpacingX;
     740                 :       }
     741                 :     }
     742                 :   }
     743               0 :   return space;
     744                 : }
     745                 : 
     746                 : // subtract the heights of aRow's prev in flows from the unpaginated height
     747                 : static
     748               0 : nscoord CalcHeightFromUnpaginatedHeight(nsPresContext*   aPresContext,
     749                 :                                         nsTableRowFrame& aRow)
     750                 : {
     751               0 :   nscoord height = 0;
     752                 :   nsTableRowFrame* firstInFlow =
     753               0 :     static_cast<nsTableRowFrame*>(aRow.GetFirstInFlow());
     754               0 :   if (firstInFlow->HasUnpaginatedHeight()) {
     755               0 :     height = firstInFlow->GetUnpaginatedHeight(aPresContext);
     756               0 :     for (nsIFrame* prevInFlow = aRow.GetPrevInFlow(); prevInFlow;
     757                 :          prevInFlow = prevInFlow->GetPrevInFlow()) {
     758               0 :       height -= prevInFlow->GetSize().height;
     759                 :     }
     760                 :   }
     761               0 :   return NS_MAX(height, 0);
     762                 : }
     763                 : 
     764                 : nsresult
     765               0 : nsTableRowFrame::ReflowChildren(nsPresContext*          aPresContext,
     766                 :                                 nsHTMLReflowMetrics&     aDesiredSize,
     767                 :                                 const nsHTMLReflowState& aReflowState,
     768                 :                                 nsTableFrame&            aTableFrame,
     769                 :                                 nsReflowStatus&          aStatus)
     770                 : {
     771               0 :   aStatus = NS_FRAME_COMPLETE;
     772                 : 
     773                 :   // XXXldb Should we be checking constrained height instead?
     774               0 :   const bool isPaginated = aPresContext->IsPaginated();
     775               0 :   const bool borderCollapse = aTableFrame.IsBorderCollapse();
     776               0 :   nsresult rv = NS_OK;
     777               0 :   nscoord cellSpacingX = aTableFrame.GetCellSpacingX();
     778               0 :   PRInt32 cellColSpan = 1;  // must be defined here so it's set properly for non-cell kids
     779                 :   
     780               0 :   nsTableIterator iter(*this);
     781                 :   // remember the col index of the previous cell to handle rowspans into this row
     782               0 :   PRInt32 firstPrevColIndex = (iter.IsLeftToRight()) ? -1 : aTableFrame.GetColCount();
     783               0 :   PRInt32 prevColIndex  = firstPrevColIndex;
     784               0 :   nscoord x = 0; // running total of children x offset
     785                 : 
     786                 :   // This computes the max of all cell heights
     787               0 :   nscoord cellMaxHeight = 0;
     788                 : 
     789                 :   // Reflow each of our existing cell frames
     790               0 :   for (nsIFrame* kidFrame = iter.First(); kidFrame; kidFrame = iter.Next()) {
     791               0 :     nsTableCellFrame *cellFrame = do_QueryFrame(kidFrame);
     792               0 :     if (!cellFrame) {
     793                 :       // XXXldb nsCSSFrameConstructor needs to enforce this!
     794               0 :       NS_NOTREACHED("yikes, a non-row child");
     795                 : 
     796                 :       // it's an unknown frame type, give it a generic reflow and ignore the results
     797                 :       nsTableCellReflowState kidReflowState(aPresContext, aReflowState,
     798               0 :                                             kidFrame, nsSize(0,0), false);
     799               0 :       InitChildReflowState(*aPresContext, nsSize(0,0), false, kidReflowState);
     800               0 :       nsHTMLReflowMetrics desiredSize;
     801                 :       nsReflowStatus  status;
     802               0 :       ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, 0, 0, 0, status);
     803               0 :       kidFrame->DidReflow(aPresContext, nsnull, NS_FRAME_REFLOW_FINISHED);
     804                 : 
     805               0 :       continue;
     806                 :     }
     807                 : 
     808                 :     // See if we should only reflow the dirty child frames
     809               0 :     bool doReflowChild = true;
     810               0 :     if (!aReflowState.ShouldReflowAllKids() &&
     811               0 :         !aTableFrame.IsGeometryDirty() &&
     812               0 :         !NS_SUBTREE_DIRTY(kidFrame)) {
     813               0 :       if (!aReflowState.mFlags.mSpecialHeightReflow)
     814               0 :         doReflowChild = false;
     815                 :     }
     816               0 :     else if ((NS_UNCONSTRAINEDSIZE != aReflowState.availableHeight)) {
     817                 :       // We don't reflow a rowspan >1 cell here with a constrained height. 
     818                 :       // That happens in nsTableRowGroupFrame::SplitSpanningCells.
     819               0 :       if (aTableFrame.GetEffectiveRowSpan(*cellFrame) > 1) {
     820               0 :         doReflowChild = false;
     821                 :       }
     822                 :     }
     823               0 :     if (aReflowState.mFlags.mSpecialHeightReflow) {
     824               0 :       if (!isPaginated && !(cellFrame->GetStateBits() &
     825               0 :                             NS_FRAME_CONTAINS_RELATIVE_HEIGHT)) {
     826               0 :         continue;
     827                 :       }
     828                 :     }
     829                 : 
     830                 :     PRInt32 cellColIndex;
     831               0 :     cellFrame->GetColIndex(cellColIndex);
     832               0 :     cellColSpan = aTableFrame.GetEffectiveColSpan(*cellFrame);
     833                 : 
     834                 :     // If the adjacent cell is in a prior row (because of a rowspan) add in the space
     835               0 :     if ((iter.IsLeftToRight() && (prevColIndex != (cellColIndex - 1))) ||
     836               0 :         (!iter.IsLeftToRight() && (prevColIndex != cellColIndex + cellColSpan))) {
     837                 :       x += GetSpaceBetween(prevColIndex, cellColIndex, cellColSpan, aTableFrame, 
     838               0 :                            cellSpacingX, iter.IsLeftToRight(), false);
     839                 :     }
     840                 : 
     841                 :     // remember the rightmost (ltr) or leftmost (rtl) column this cell spans into
     842               0 :     prevColIndex = (iter.IsLeftToRight()) ? cellColIndex + (cellColSpan - 1) : cellColIndex;
     843                 : 
     844                 :     // Reflow the child frame
     845               0 :     nsRect kidRect = kidFrame->GetRect();
     846               0 :     nsRect kidVisualOverflow = kidFrame->GetVisualOverflowRect();
     847                 :     bool firstReflow =
     848               0 :       (kidFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
     849                 : 
     850               0 :     if (doReflowChild) {
     851                 :       // Calculate the available width for the table cell using the known column widths
     852                 :       nscoord availCellWidth =
     853               0 :         CalcAvailWidth(aTableFrame, *cellFrame, cellSpacingX);
     854                 : 
     855               0 :       nsHTMLReflowMetrics desiredSize;
     856                 : 
     857                 :       // If the avail width is not the same as last time we reflowed the cell or
     858                 :       // the cell wants to be bigger than what was available last time or
     859                 :       // it is a style change reflow or we are printing, then we must reflow the
     860                 :       // cell. Otherwise we can skip the reflow.
     861                 :       // XXXldb Why is this condition distinct from doReflowChild above?
     862               0 :       nsSize cellDesiredSize = cellFrame->GetDesiredSize();
     863               0 :       if ((availCellWidth != cellFrame->GetPriorAvailWidth())       ||
     864               0 :           (cellDesiredSize.width > cellFrame->GetPriorAvailWidth()) ||
     865               0 :           (GetStateBits() & NS_FRAME_IS_DIRTY)                      ||
     866                 :           isPaginated                                               ||
     867               0 :           NS_SUBTREE_DIRTY(cellFrame)                               ||
     868                 :           // See if it needs a special reflow, or if it had one that we need to undo.
     869               0 :           (cellFrame->GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_HEIGHT) ||
     870               0 :           HasPctHeight()) {
     871                 :         // Reflow the cell to fit the available width, height
     872                 :         // XXX The old IR_ChildIsDirty code used availCellWidth here.
     873               0 :         nsSize  kidAvailSize(availCellWidth, aReflowState.availableHeight);
     874                 : 
     875                 :         // Reflow the child
     876                 :         nsTableCellReflowState kidReflowState(aPresContext, aReflowState, 
     877               0 :                                               kidFrame, kidAvailSize, false);
     878                 :         InitChildReflowState(*aPresContext, kidAvailSize, borderCollapse,
     879               0 :                              kidReflowState);
     880                 : 
     881                 :         nsReflowStatus status;
     882                 :         rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState,
     883               0 :                          x, 0, NS_FRAME_INVALIDATE_ON_MOVE, status);
     884                 : 
     885                 :         // allow the table to determine if/how the table needs to be rebalanced
     886                 :         // If any of the cells are not complete, then we're not complete
     887               0 :         if (NS_FRAME_IS_NOT_COMPLETE(status)) {
     888               0 :           aStatus = NS_FRAME_NOT_COMPLETE;
     889                 :         }
     890                 :       }
     891                 :       else {
     892               0 :         if (x != kidRect.x) {
     893               0 :           kidFrame->InvalidateFrameSubtree();
     894                 :         }
     895                 :         
     896               0 :         desiredSize.width = cellDesiredSize.width;
     897               0 :         desiredSize.height = cellDesiredSize.height;
     898               0 :         desiredSize.mOverflowAreas = cellFrame->GetOverflowAreas();
     899                 : 
     900                 :         // if we are in a floated table, our position is not yet established, so we cannot reposition our views
     901                 :         // the containing block will do this for us after positioning the table
     902               0 :         if (!aTableFrame.GetStyleDisplay()->IsFloating()) {
     903                 :           // Because we may have moved the frame we need to make sure any views are
     904                 :           // positioned properly. We have to do this, because any one of our parent
     905                 :           // frames could have moved and we have no way of knowing...
     906               0 :           nsTableFrame::RePositionViews(kidFrame);
     907                 :         }
     908                 :       }
     909                 :       
     910               0 :       if (NS_UNCONSTRAINEDSIZE == aReflowState.availableHeight) {
     911               0 :         if (!GetPrevInFlow()) {
     912                 :           // Calculate the cell's actual height given its pass2 height. This
     913                 :           // function takes into account the specified height (in the style)
     914               0 :           CalculateCellActualHeight(cellFrame, desiredSize.height);
     915                 :         }
     916                 :         // height may have changed, adjust descent to absorb any excess difference
     917                 :         nscoord ascent;
     918               0 :         if (!kidFrame->GetFirstPrincipalChild()->GetFirstPrincipalChild())
     919               0 :           ascent = desiredSize.height;
     920                 :         else
     921               0 :           ascent = ((nsTableCellFrame *)kidFrame)->GetCellBaseline();
     922               0 :         nscoord descent = desiredSize.height - ascent;
     923               0 :         UpdateHeight(desiredSize.height, ascent, descent, &aTableFrame, cellFrame);
     924                 :       }
     925                 :       else {
     926               0 :         cellMaxHeight = NS_MAX(cellMaxHeight, desiredSize.height);
     927               0 :         PRInt32 rowSpan = aTableFrame.GetEffectiveRowSpan((nsTableCellFrame&)*kidFrame);
     928               0 :         if (1 == rowSpan) {
     929               0 :           SetContentHeight(cellMaxHeight);
     930                 :         }
     931                 :       }
     932                 : 
     933                 :       // Place the child
     934               0 :       desiredSize.width = availCellWidth;
     935                 : 
     936               0 :       FinishReflowChild(kidFrame, aPresContext, nsnull, desiredSize, x, 0, 0);
     937                 : 
     938                 :       nsTableFrame::InvalidateFrame(kidFrame, kidRect, kidVisualOverflow,
     939               0 :                                     firstReflow);
     940                 :       
     941               0 :       x += desiredSize.width;  
     942                 :     }
     943                 :     else {
     944               0 :       if (kidRect.x != x) {
     945                 :         // Invalidate the old position
     946               0 :         kidFrame->InvalidateFrameSubtree();
     947                 :         // move to the new position
     948               0 :         kidFrame->SetPosition(nsPoint(x, kidRect.y));
     949               0 :         nsTableFrame::RePositionViews(kidFrame);
     950                 :         // invalidate the new position
     951               0 :         kidFrame->InvalidateFrameSubtree();
     952                 :       }
     953                 :       // we need to account for the cell's width even if it isn't reflowed
     954               0 :       x += kidRect.width;
     955                 : 
     956               0 :       if (kidFrame->GetNextInFlow()) {
     957               0 :         aStatus = NS_FRAME_NOT_COMPLETE;
     958                 :       }
     959                 :     }
     960               0 :     ConsiderChildOverflow(aDesiredSize.mOverflowAreas, kidFrame);
     961               0 :     x += cellSpacingX;
     962                 :   }
     963                 : 
     964                 :   // just set our width to what was available. The table will calculate the width and not use our value.
     965               0 :   aDesiredSize.width = aReflowState.availableWidth;
     966                 : 
     967               0 :   if (aReflowState.mFlags.mSpecialHeightReflow) {
     968               0 :     aDesiredSize.height = mRect.height;
     969                 :   }
     970               0 :   else if (NS_UNCONSTRAINEDSIZE == aReflowState.availableHeight) {
     971               0 :     aDesiredSize.height = CalcHeight(aReflowState);
     972               0 :     if (GetPrevInFlow()) {
     973               0 :       nscoord height = CalcHeightFromUnpaginatedHeight(aPresContext, *this);
     974               0 :       aDesiredSize.height = NS_MAX(aDesiredSize.height, height);
     975                 :     }
     976                 :     else {
     977               0 :       if (isPaginated && HasStyleHeight()) {
     978                 :         // set the unpaginated height so next in flows can try to honor it
     979               0 :         SetHasUnpaginatedHeight(true);
     980               0 :         SetUnpaginatedHeight(aPresContext, aDesiredSize.height);
     981                 :       }
     982               0 :       if (isPaginated && HasUnpaginatedHeight()) {
     983               0 :         aDesiredSize.height = NS_MAX(aDesiredSize.height, GetUnpaginatedHeight(aPresContext));
     984                 :       }
     985                 :     }
     986                 :   }
     987                 :   else { // constrained height, paginated
     988                 :     // Compute the height we should have from style (subtracting the
     989                 :     // height from our prev-in-flows from the style height)
     990               0 :     nscoord styleHeight = CalcHeightFromUnpaginatedHeight(aPresContext, *this);
     991               0 :     if (styleHeight > aReflowState.availableHeight) {
     992               0 :       styleHeight = aReflowState.availableHeight;
     993               0 :       NS_FRAME_SET_INCOMPLETE(aStatus);
     994                 :     }
     995               0 :     aDesiredSize.height = NS_MAX(cellMaxHeight, styleHeight);
     996                 :   }
     997               0 :   aDesiredSize.UnionOverflowAreasWithDesiredBounds();
     998               0 :   FinishAndStoreOverflow(&aDesiredSize);
     999               0 :   return rv;
    1000                 : }
    1001                 : 
    1002                 : /** Layout the entire row.
    1003                 :   * This method stacks cells horizontally according to HTML 4.0 rules.
    1004                 :   */
    1005                 : NS_METHOD
    1006               0 : nsTableRowFrame::Reflow(nsPresContext*          aPresContext,
    1007                 :                         nsHTMLReflowMetrics&     aDesiredSize,
    1008                 :                         const nsHTMLReflowState& aReflowState,
    1009                 :                         nsReflowStatus&          aStatus)
    1010                 : {
    1011               0 :   DO_GLOBAL_REFLOW_COUNT("nsTableRowFrame");
    1012               0 :   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
    1013               0 :   nsresult rv = NS_OK;
    1014                 : 
    1015               0 :   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
    1016               0 :   const nsStyleVisibility* rowVis = GetStyleVisibility();
    1017               0 :   bool collapseRow = (NS_STYLE_VISIBILITY_COLLAPSE == rowVis->mVisible);
    1018               0 :   if (collapseRow) {
    1019               0 :     tableFrame->SetNeedToCollapse(true);
    1020                 :   }
    1021                 : 
    1022                 :   // see if a special height reflow needs to occur due to having a pct height
    1023               0 :   nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState);
    1024                 : 
    1025                 :   // See if we have a cell with specified/pct height
    1026               0 :   InitHasCellWithStyleHeight(tableFrame);
    1027                 : 
    1028                 :   rv = ReflowChildren(aPresContext, aDesiredSize, aReflowState, *tableFrame,
    1029               0 :                       aStatus);
    1030                 : 
    1031                 :   // just set our width to what was available. The table will calculate the width and not use our value.
    1032               0 :   aDesiredSize.width = aReflowState.availableWidth;
    1033                 : 
    1034                 :   // If our parent is in initial reflow, it'll handle invalidating our
    1035                 :   // entire overflow rect.
    1036               0 :   if (!(GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
    1037               0 :     CheckInvalidateSizeChange(aDesiredSize);
    1038                 :   }
    1039                 : 
    1040               0 :   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
    1041               0 :   return rv;
    1042                 : }
    1043                 : 
    1044                 : /**
    1045                 :  * This function is called by the row group frame's SplitRowGroup() code when
    1046                 :  * pushing a row frame that has cell frames that span into it. The cell frame
    1047                 :  * should be reflowed with the specified height
    1048                 :  */
    1049                 : nscoord 
    1050               0 : nsTableRowFrame::ReflowCellFrame(nsPresContext*          aPresContext,
    1051                 :                                  const nsHTMLReflowState& aReflowState,
    1052                 :                                  bool                     aIsTopOfPage,
    1053                 :                                  nsTableCellFrame*        aCellFrame,
    1054                 :                                  nscoord                  aAvailableHeight,
    1055                 :                                  nsReflowStatus&          aStatus)
    1056                 : {
    1057                 :   // Reflow the cell frame with the specified height. Use the existing width
    1058               0 :   nsRect cellRect = aCellFrame->GetRect();
    1059               0 :   nsRect cellVisualOverflow = aCellFrame->GetVisualOverflowRect();
    1060                 :   
    1061               0 :   nsSize availSize(cellRect.width, aAvailableHeight);
    1062               0 :   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
    1063               0 :   bool borderCollapse = tableFrame->IsBorderCollapse();
    1064                 :   nsTableCellReflowState cellReflowState(aPresContext, aReflowState,
    1065               0 :                                          aCellFrame, availSize, false);
    1066               0 :   InitChildReflowState(*aPresContext, availSize, borderCollapse, cellReflowState);
    1067               0 :   cellReflowState.mFlags.mIsTopOfPage = aIsTopOfPage;
    1068                 : 
    1069               0 :   nsHTMLReflowMetrics desiredSize;
    1070                 : 
    1071                 :   ReflowChild(aCellFrame, aPresContext, desiredSize, cellReflowState,
    1072               0 :               0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
    1073               0 :   bool fullyComplete = NS_FRAME_IS_COMPLETE(aStatus) && !NS_FRAME_IS_TRUNCATED(aStatus);
    1074               0 :   if (fullyComplete) {
    1075               0 :     desiredSize.height = aAvailableHeight;
    1076                 :   }
    1077               0 :   aCellFrame->SetSize(nsSize(cellRect.width, desiredSize.height));
    1078                 : 
    1079                 :   // Note: VerticallyAlignChild can affect the overflow rect.
    1080                 :   // XXX What happens if this cell has 'vertical-align: baseline' ?
    1081                 :   // XXX Why is it assumed that the cell's ascent hasn't changed ?
    1082               0 :   if (fullyComplete) {
    1083               0 :     aCellFrame->VerticallyAlignChild(mMaxCellAscent);
    1084                 :   }
    1085                 :   
    1086                 :   nsTableFrame::InvalidateFrame(aCellFrame, cellRect,
    1087                 :                                 cellVisualOverflow,
    1088               0 :                                 (aCellFrame->GetStateBits() &
    1089               0 :                                    NS_FRAME_FIRST_REFLOW) != 0);
    1090                 :   
    1091               0 :   aCellFrame->DidReflow(aPresContext, nsnull, NS_FRAME_REFLOW_FINISHED);
    1092                 : 
    1093               0 :   return desiredSize.height;
    1094                 : }
    1095                 : 
    1096                 : nscoord
    1097               0 : nsTableRowFrame::CollapseRowIfNecessary(nscoord aRowOffset,
    1098                 :                                         nscoord aWidth,
    1099                 :                                         bool    aCollapseGroup,
    1100                 :                                         bool& aDidCollapse)
    1101                 : {
    1102               0 :   const nsStyleVisibility* rowVis = GetStyleVisibility();
    1103               0 :   bool collapseRow = (NS_STYLE_VISIBILITY_COLLAPSE == rowVis->mVisible);
    1104                 :   nsTableFrame* tableFrame = static_cast<nsTableFrame*>(
    1105               0 :     nsTableFrame::GetTableFrame(this)->GetFirstInFlow());
    1106               0 :   if (collapseRow) {
    1107               0 :     tableFrame->SetNeedToCollapse(true);
    1108                 :   }
    1109                 : 
    1110               0 :   if (aRowOffset != 0) {
    1111                 :     // We're moving, so invalidate our old position
    1112               0 :     InvalidateFrameSubtree();
    1113                 :   }
    1114                 :   
    1115               0 :   nsRect rowRect = GetRect();
    1116               0 :   nsRect oldRect = rowRect;
    1117               0 :   nsRect oldVisualOverflow = GetVisualOverflowRect();
    1118                 :   
    1119               0 :   rowRect.y -= aRowOffset;
    1120               0 :   rowRect.width  = aWidth;
    1121               0 :   nsOverflowAreas overflow;
    1122               0 :   nscoord shift = 0;
    1123               0 :   nscoord cellSpacingX = tableFrame->GetCellSpacingX();
    1124               0 :   nscoord cellSpacingY = tableFrame->GetCellSpacingY();
    1125                 : 
    1126               0 :   if (aCollapseGroup || collapseRow) {
    1127               0 :     nsTableCellFrame* cellFrame = GetFirstCell();
    1128               0 :     aDidCollapse = true;
    1129               0 :     shift = rowRect.height + cellSpacingY;
    1130               0 :     while (cellFrame) {
    1131               0 :       nsRect cRect = cellFrame->GetRect();
    1132                 :       // If aRowOffset != 0, there's no point in invalidating the cells, since
    1133                 :       // we've already invalidated our overflow area.  Note that we _do_ still
    1134                 :       // need to invalidate if our row is not moving, because the cell might
    1135                 :       // span out of this row, so invalidating our row rect won't do enough.
    1136               0 :       if (aRowOffset == 0) {
    1137               0 :         Invalidate(cRect);
    1138                 :       }
    1139               0 :       cRect.height = 0;
    1140               0 :       cellFrame->SetRect(cRect);
    1141               0 :       cellFrame = cellFrame->GetNextCell();
    1142                 :     }
    1143               0 :     rowRect.height = 0;
    1144                 :   }
    1145                 :   else { // row is not collapsed
    1146               0 :     nsTableIterator iter(*this);
    1147                 :     // remember the col index of the previous cell to handle rowspans into this
    1148                 :     // row
    1149               0 :     PRInt32 firstPrevColIndex = (iter.IsLeftToRight()) ? -1 :
    1150               0 :                                 tableFrame->GetColCount();
    1151               0 :     PRInt32 prevColIndex  = firstPrevColIndex;
    1152               0 :     nscoord x = 0; // running total of children x offset
    1153                 : 
    1154               0 :     PRInt32 colIncrement = iter.IsLeftToRight() ? 1 : -1;
    1155                 : 
    1156                 :     //nscoord x = cellSpacingX;
    1157                 : 
    1158               0 :     nsIFrame* kidFrame = iter.First();
    1159               0 :     while (kidFrame) {
    1160               0 :       nsTableCellFrame *cellFrame = do_QueryFrame(kidFrame);
    1161               0 :       if (cellFrame) {
    1162                 :         PRInt32 cellColIndex;
    1163               0 :         cellFrame->GetColIndex(cellColIndex);
    1164               0 :         PRInt32 cellColSpan = tableFrame->GetEffectiveColSpan(*cellFrame);
    1165                 : 
    1166                 :         // If the adjacent cell is in a prior row (because of a rowspan) add in
    1167                 :         // the space
    1168               0 :         if ((iter.IsLeftToRight() && (prevColIndex != (cellColIndex - 1))) ||
    1169               0 :             (!iter.IsLeftToRight() &&
    1170                 :              (prevColIndex != cellColIndex + cellColSpan))) {
    1171                 :           x += GetSpaceBetween(prevColIndex, cellColIndex, cellColSpan,
    1172               0 :                                *tableFrame, cellSpacingX, iter.IsLeftToRight(),
    1173               0 :                                true);
    1174                 :         }
    1175               0 :         nsRect cRect(x, 0, 0, rowRect.height);
    1176                 : 
    1177                 :         // remember the rightmost (ltr) or leftmost (rtl) column this cell
    1178                 :         // spans into
    1179               0 :         prevColIndex = (iter.IsLeftToRight()) ?
    1180               0 :                        cellColIndex + (cellColSpan - 1) : cellColIndex;
    1181               0 :         PRInt32 startIndex = (iter.IsLeftToRight()) ?
    1182               0 :                              cellColIndex : cellColIndex + (cellColSpan - 1);
    1183               0 :         PRInt32 actualColSpan = cellColSpan;
    1184               0 :         bool isVisible = false;
    1185               0 :         for (PRInt32 colX = startIndex; actualColSpan > 0;
    1186                 :              colX += colIncrement, actualColSpan--) {
    1187                 : 
    1188               0 :           nsTableColFrame* colFrame = tableFrame->GetColFrame(colX);
    1189               0 :           const nsStyleVisibility* colVis = colFrame->GetStyleVisibility();
    1190                 :           bool collapseCol = (NS_STYLE_VISIBILITY_COLLAPSE ==
    1191               0 :                                 colVis->mVisible);
    1192               0 :           nsIFrame* cgFrame = colFrame->GetParent();
    1193               0 :           const nsStyleVisibility* groupVis = cgFrame->GetStyleVisibility();
    1194                 :           bool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE ==
    1195               0 :                                   groupVis->mVisible);
    1196               0 :           bool isCollapsed = collapseCol || collapseGroup;
    1197               0 :           if (!isCollapsed) {
    1198               0 :             cRect.width += tableFrame->GetColumnWidth(colX);
    1199               0 :             isVisible = true;
    1200               0 :             if ((actualColSpan > 1)) {
    1201                 :               nsTableColFrame* nextColFrame =
    1202               0 :                 tableFrame->GetColFrame(colX + colIncrement);
    1203                 :               const nsStyleVisibility* nextColVis =
    1204               0 :               nextColFrame->GetStyleVisibility();
    1205               0 :               if ( (NS_STYLE_VISIBILITY_COLLAPSE != nextColVis->mVisible) &&
    1206               0 :                   tableFrame->ColumnHasCellSpacingBefore(colX + colIncrement)) {
    1207               0 :                 cRect.width += cellSpacingX;
    1208                 :               }
    1209                 :             }
    1210                 :           }
    1211                 :         }
    1212               0 :         x += cRect.width;
    1213               0 :         if (isVisible)
    1214               0 :           x += cellSpacingX;
    1215               0 :         PRInt32 actualRowSpan = tableFrame->GetEffectiveRowSpan(*cellFrame);
    1216               0 :         nsTableRowFrame* rowFrame = GetNextRow();
    1217               0 :         for (actualRowSpan--; actualRowSpan > 0 && rowFrame; actualRowSpan--) {
    1218               0 :           const nsStyleVisibility* nextRowVis = rowFrame->GetStyleVisibility();
    1219                 :           bool collapseNextRow = (NS_STYLE_VISIBILITY_COLLAPSE ==
    1220               0 :                                     nextRowVis->mVisible);
    1221               0 :           if (!collapseNextRow) {
    1222               0 :             nsRect nextRect = rowFrame->GetRect();
    1223               0 :             cRect.height += nextRect.height + cellSpacingY;
    1224                 :           }
    1225               0 :           rowFrame = rowFrame->GetNextRow();
    1226                 :         }
    1227                 : 
    1228               0 :         nsRect oldCellRect = cellFrame->GetRect();
    1229               0 :         nsRect oldCellVisualOverflow = cellFrame->GetVisualOverflowRect();
    1230                 : 
    1231               0 :         if (aRowOffset == 0 && cRect.TopLeft() != oldCellRect.TopLeft()) {
    1232                 :           // We're moving the cell.  Invalidate the old overflow area
    1233               0 :           cellFrame->InvalidateFrameSubtree();
    1234                 :         }
    1235                 :         
    1236               0 :         cellFrame->SetRect(cRect);
    1237                 : 
    1238                 :         // XXXbz This looks completely bogus in the cases when we didn't
    1239                 :         // collapse the cell!
    1240               0 :         nsRect cellBounds(0, 0, cRect.width, cRect.height);
    1241               0 :         nsOverflowAreas cellOverflow(cellBounds, cellBounds);
    1242                 :         cellFrame->FinishAndStoreOverflow(cellOverflow,
    1243               0 :                                           nsSize(cRect.width, cRect.height));
    1244               0 :         nsTableFrame::RePositionViews(cellFrame);
    1245               0 :         ConsiderChildOverflow(overflow, cellFrame);
    1246                 :                 
    1247               0 :         if (aRowOffset == 0) {
    1248                 :           nsTableFrame::InvalidateFrame(cellFrame, oldCellRect,
    1249                 :                                         oldCellVisualOverflow,
    1250               0 :                                         false);
    1251                 :         }
    1252                 :       }
    1253               0 :       kidFrame = iter.Next(); // Get the next child
    1254                 :     }
    1255                 :   }
    1256                 : 
    1257               0 :   SetRect(rowRect);
    1258               0 :   overflow.UnionAllWith(nsRect(0,0,rowRect.width, rowRect.height));
    1259               0 :   FinishAndStoreOverflow(overflow, nsSize(rowRect.width, rowRect.height));
    1260                 : 
    1261               0 :   nsTableFrame::RePositionViews(this);
    1262               0 :   nsTableFrame::InvalidateFrame(this, oldRect, oldVisualOverflow, false);
    1263               0 :   return shift;
    1264                 : }
    1265                 : 
    1266                 : /*
    1267                 :  * The following method is called by the row group frame's SplitRowGroup()
    1268                 :  * when it creates a continuing cell frame and wants to insert it into the
    1269                 :  * row's child list.
    1270                 :  */
    1271                 : void 
    1272               0 : nsTableRowFrame::InsertCellFrame(nsTableCellFrame* aFrame,
    1273                 :                                  PRInt32           aColIndex)
    1274                 : {
    1275                 :   // Find the cell frame where col index < aColIndex
    1276               0 :   nsTableCellFrame* priorCell = nsnull;
    1277               0 :   for (nsIFrame* child = mFrames.FirstChild(); child;
    1278                 :        child = child->GetNextSibling()) {
    1279               0 :     nsTableCellFrame *cellFrame = do_QueryFrame(child);
    1280               0 :     if (cellFrame) {
    1281                 :       PRInt32 colIndex;
    1282               0 :       cellFrame->GetColIndex(colIndex);
    1283               0 :       if (colIndex < aColIndex) {
    1284               0 :         priorCell = cellFrame;
    1285                 :       }
    1286               0 :       else break;
    1287                 :     }
    1288                 :   }
    1289               0 :   mFrames.InsertFrame(this, priorCell, aFrame);
    1290               0 : }
    1291                 : 
    1292                 : nsIAtom*
    1293               0 : nsTableRowFrame::GetType() const
    1294                 : {
    1295               0 :   return nsGkAtoms::tableRowFrame;
    1296                 : }
    1297                 : 
    1298                 : nsTableRowFrame*  
    1299               0 : nsTableRowFrame::GetNextRow() const
    1300                 : {
    1301               0 :   nsIFrame* childFrame = GetNextSibling();
    1302               0 :   while (childFrame) {
    1303               0 :     nsTableRowFrame *rowFrame = do_QueryFrame(childFrame);
    1304               0 :     if (rowFrame) {
    1305               0 :           NS_ASSERTION(NS_STYLE_DISPLAY_TABLE_ROW == childFrame->GetStyleDisplay()->mDisplay, "wrong display type on rowframe");
    1306               0 :       return rowFrame;
    1307                 :     }
    1308               0 :     childFrame = childFrame->GetNextSibling();
    1309                 :   }
    1310               0 :   return nsnull;
    1311                 : }
    1312                 : 
    1313               0 : NS_DECLARE_FRAME_PROPERTY(RowUnpaginatedHeightProperty, nsnull)
    1314                 : 
    1315                 : void 
    1316               0 : nsTableRowFrame::SetUnpaginatedHeight(nsPresContext* aPresContext,
    1317                 :                                       nscoord        aValue)
    1318                 : {
    1319               0 :   NS_ASSERTION(!GetPrevInFlow(), "program error");
    1320                 :   // Get the property
    1321                 :   aPresContext->PropertyTable()->
    1322               0 :     Set(this, RowUnpaginatedHeightProperty(), NS_INT32_TO_PTR(aValue));
    1323               0 : }
    1324                 : 
    1325                 : nscoord
    1326               0 : nsTableRowFrame::GetUnpaginatedHeight(nsPresContext* aPresContext)
    1327                 : {
    1328               0 :   FrameProperties props = GetFirstInFlow()->Properties();
    1329               0 :   return NS_PTR_TO_INT32(props.Get(RowUnpaginatedHeightProperty()));
    1330                 : }
    1331                 : 
    1332               0 : void nsTableRowFrame::SetContinuousBCBorderWidth(PRUint8     aForSide,
    1333                 :                                                  BCPixelSize aPixelValue)
    1334                 : {
    1335               0 :   switch (aForSide) {
    1336                 :     case NS_SIDE_RIGHT:
    1337               0 :       mRightContBorderWidth = aPixelValue;
    1338               0 :       return;
    1339                 :     case NS_SIDE_TOP:
    1340               0 :       mTopContBorderWidth = aPixelValue;
    1341               0 :       return;
    1342                 :     case NS_SIDE_LEFT:
    1343               0 :       mLeftContBorderWidth = aPixelValue;
    1344               0 :       return;
    1345                 :     default:
    1346               0 :       NS_ERROR("invalid NS_SIDE arg");
    1347                 :   }
    1348                 : }
    1349                 : 
    1350                 : /**
    1351                 :  * Sets the NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT bit to indicate whether
    1352                 :  * this row has any cells that have non-auto-height.  (Row-spanning
    1353                 :  * cells are ignored.)
    1354                 :  */
    1355               0 : void nsTableRowFrame::InitHasCellWithStyleHeight(nsTableFrame* aTableFrame)
    1356                 : {
    1357               0 :   nsTableIterator iter(*this);
    1358                 : 
    1359               0 :   for (nsIFrame* kidFrame = iter.First(); kidFrame; kidFrame = iter.Next()) {
    1360               0 :     nsTableCellFrame *cellFrame = do_QueryFrame(kidFrame);
    1361               0 :     if (!cellFrame) {
    1362               0 :       NS_NOTREACHED("Table row has a non-cell child.");
    1363               0 :       continue;
    1364                 :     }
    1365                 :     // Ignore row-spanning cells
    1366               0 :     const nsStyleCoord &cellHeight = cellFrame->GetStylePosition()->mHeight;
    1367               0 :     if (aTableFrame->GetEffectiveRowSpan(*cellFrame) == 1 &&
    1368               0 :         cellHeight.GetUnit() != eStyleUnit_Auto &&
    1369               0 :         !cellHeight.IsCalcUnit() /* calc() treated like 'auto' */) {
    1370               0 :       AddStateBits(NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT);
    1371               0 :       return;
    1372                 :     }
    1373                 :   }
    1374               0 :   RemoveStateBits(NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT);
    1375                 : }
    1376                 : 
    1377                 : /* ----- global methods ----- */
    1378                 : 
    1379                 : nsIFrame* 
    1380               0 : NS_NewTableRowFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
    1381                 : {
    1382               0 :   return new (aPresShell) nsTableRowFrame(aContext);
    1383                 : }
    1384                 : 
    1385               0 : NS_IMPL_FRAMEARENA_HELPERS(nsTableRowFrame)
    1386                 : 
    1387                 : #ifdef DEBUG
    1388                 : NS_IMETHODIMP
    1389               0 : nsTableRowFrame::GetFrameName(nsAString& aResult) const
    1390                 : {
    1391               0 :   return MakeFrameName(NS_LITERAL_STRING("TableRow"), aResult);
    1392                 : }
    1393                 : #endif

Generated by: LCOV version 1.7