зеркало из https://github.com/mozilla/gecko-dev.git
more content decoupling
support work for style optimizations fixed a bug in table columns -- the attribute repeat defaults to 1, not 0
This commit is contained in:
Родитель
a56ae43131
Коммит
7b6c525170
|
@ -40,7 +40,7 @@ nsTableCol::nsTableCol(nsIAtom* aTag)
|
|||
: nsTableContent(aTag),
|
||||
mColGroup(0),
|
||||
mColIndex(0),
|
||||
mRepeat(0)
|
||||
mRepeat(1)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ nsTableCol::nsTableCol()
|
|||
: nsTableContent(NS_NewAtom(nsTablePart::kColTagString)),
|
||||
mColGroup(0),
|
||||
mColIndex(0),
|
||||
mRepeat(0)
|
||||
mRepeat(1)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ nsTableCol::nsTableCol (PRBool aImplicit)
|
|||
: nsTableContent(NS_NewAtom(nsTablePart::kColTagString)),
|
||||
mColGroup(0),
|
||||
mColIndex(0),
|
||||
mRepeat(0)
|
||||
mRepeat(1)
|
||||
{
|
||||
mImplicit = aImplicit;
|
||||
Init();
|
||||
|
|
|
@ -35,6 +35,8 @@ static const PRBool gsDebug = PR_FALSE;
|
|||
static const PRBool gsNoisyRefs = PR_FALSE;
|
||||
#endif
|
||||
|
||||
static NS_DEFINE_IID(kITableContentIID, NS_ITABLECONTENT_IID);
|
||||
|
||||
|
||||
nsTableColGroup::nsTableColGroup(nsIAtom* aTag, int aSpan)
|
||||
: nsTableContent(aTag),
|
||||
|
@ -251,18 +253,24 @@ nsTableColGroup::RemoveChildAt (PRInt32 aIndex, PRBool aNotify)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/** support method to determine if the param aContent is a TableRow object */
|
||||
/** support method to determine if the param aContent is an nsTableCol object */
|
||||
PRBool nsTableColGroup::IsCol(nsIContent * aContent) const
|
||||
{
|
||||
NS_ASSERTION(nsnull!=aContent, "bad arg");
|
||||
PRBool result = PR_FALSE;
|
||||
if (nsnull!=aContent)
|
||||
{
|
||||
// is aContent a col?
|
||||
nsTableContent *tableContent = (nsTableContent *)aContent;
|
||||
const int contentType = tableContent->GetType();
|
||||
if (contentType == nsITableContent::kTableColType)
|
||||
result = PR_TRUE;
|
||||
nsITableContent *tableContentInterface = nsnull;
|
||||
nsresult rv = aContent->QueryInterface(kITableContentIID,
|
||||
(void **)&tableContentInterface); // tableContentInterface: REFCNT++
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
const int contentType = tableContentInterface->GetType();
|
||||
NS_RELEASE(tableContentInterface);
|
||||
if (contentType == nsITableContent::kTableColType)
|
||||
result = PR_TRUE;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
*/
|
||||
#include "nsTableColGroupFrame.h"
|
||||
#include "nsTableColFrame.h"
|
||||
#include "nsITableContent.h"
|
||||
#include "nsIReflowCommand.h"
|
||||
#include "nsIStyleContext.h"
|
||||
#include "nsStyleConsts.h"
|
||||
|
@ -28,6 +29,8 @@
|
|||
NS_DEF_PTR(nsIContent);
|
||||
NS_DEF_PTR(nsIStyleContext);
|
||||
|
||||
static NS_DEFINE_IID(kITableContentIID, NS_ITABLECONTENT_IID);
|
||||
|
||||
static PRBool gsDebug = PR_FALSE;
|
||||
|
||||
|
||||
|
@ -51,7 +54,9 @@ NS_METHOD nsTableColGroupFrame::Paint(nsIPresContext& aPresContext,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// TODO: content changed notifications
|
||||
// TODO: incremental reflow
|
||||
// today, we just throw away the column frames and start over every time
|
||||
// this is dumb, we should be able to maintain column frames and adjust incrementally
|
||||
NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
|
||||
nsReflowMetrics& aDesiredSize,
|
||||
const nsReflowState& aReflowState,
|
||||
|
@ -59,20 +64,35 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
|
|||
{
|
||||
NS_ASSERTION(nsnull!=mContent, "bad state -- null content for frame");
|
||||
|
||||
if (nsnull == mFirstChild)
|
||||
{ // if we don't have any children, create them
|
||||
nsIFrame* kidFrame = nsnull;
|
||||
nsIFrame* prevKidFrame;
|
||||
|
||||
LastChild(prevKidFrame); // XXX remember this...
|
||||
PRInt32 kidIndex = 0;
|
||||
for (PRInt32 colIndex = 0; ;colIndex++) // colIndex is used to set the column frames' index field
|
||||
{
|
||||
nsIContentPtr kid = mContent->ChildAt(kidIndex); // kid: REFCNT++
|
||||
if (kid.IsNull()) {
|
||||
break;
|
||||
}
|
||||
// for every content child that (is a column thingy and does not already have a frame)
|
||||
// create a frame and adjust it's style
|
||||
nsIFrame* kidFrame = nsnull;
|
||||
nsIFrame* prevKidFrame;
|
||||
|
||||
LastChild(prevKidFrame); // XXX remember this...
|
||||
PRInt32 kidIndex = 0; // index of the content child we are currently working on
|
||||
PRInt32 colIndex = 0; // number of content children that are columns, normally same as kidIndex
|
||||
for (;;)
|
||||
{
|
||||
// get the next content child, breaking if there is none
|
||||
nsIContentPtr kid = mContent->ChildAt(kidIndex); // kid: REFCNT++
|
||||
if (kid.IsNull()) {
|
||||
break;
|
||||
}
|
||||
|
||||
// verify that we're dealing with table content. If so, we know it's a column
|
||||
nsITableContent *tableContentInterface = nsnull;
|
||||
nsresult rv = kid->QueryInterface(kITableContentIID,
|
||||
(void **)&tableContentInterface); // tableContentInterface: REFCNT++
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
kidIndex++;
|
||||
continue;
|
||||
}
|
||||
NS_RELEASE(tableContentInterface); // tableContentInterface: REFCNT--
|
||||
|
||||
if (mChildCount<=colIndex)
|
||||
{
|
||||
// Resolve style
|
||||
nsIStyleContextPtr kidSC =
|
||||
aPresContext.ResolveStyleContextFor(kid, this, PR_TRUE);
|
||||
|
@ -82,8 +102,7 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
|
|||
// Create a child frame
|
||||
nsIContentDelegate* kidDel = nsnull;
|
||||
kidDel = kid->GetDelegate(&aPresContext);
|
||||
nsresult rv = kidDel->CreateFrame(&aPresContext, kid, this, kidSC,
|
||||
kidFrame);
|
||||
rv = kidDel->CreateFrame(&aPresContext, kid, this, kidSC, kidFrame);
|
||||
NS_RELEASE(kidDel);
|
||||
|
||||
// give the child frame a chance to reflow, even though we know it'll have 0 size
|
||||
|
@ -107,10 +126,10 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
|
|||
}
|
||||
prevKidFrame = kidFrame;
|
||||
mChildCount++;
|
||||
kidIndex++;
|
||||
SetStyleContextForFirstPass(&aPresContext, colIndex);
|
||||
}
|
||||
// now that I have all my COL children, adjust their style
|
||||
SetStyleContextForFirstPass(&aPresContext);
|
||||
colIndex++; // if this wasn't a column, we would not have gotten this far
|
||||
kidIndex++;
|
||||
}
|
||||
aDesiredSize.width=0;
|
||||
aDesiredSize.height=0;
|
||||
|
@ -124,7 +143,8 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
|
|||
}
|
||||
|
||||
// Subclass hook for style post processing
|
||||
NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPresContext)
|
||||
NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPresContext,
|
||||
PRInt32 aColIndex)
|
||||
{
|
||||
// get the table frame
|
||||
nsIFrame* tableFrame=nsnull;
|
||||
|
@ -150,30 +170,30 @@ NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPre
|
|||
PRInt32 colIndex=0;
|
||||
nsIFrame *colFrame=nsnull;
|
||||
nsIStyleContextPtr colStyleContext;
|
||||
for (; colIndex<numCols; colIndex++)
|
||||
ChildAt(aColIndex, colFrame);
|
||||
if (nsnull!=colFrame)
|
||||
{
|
||||
ChildAt(colIndex, colFrame);
|
||||
if (nsnull==colFrame)
|
||||
break; // the attribute value specified was greater than the actual number of columns
|
||||
nsStylePosition * colPosition=nsnull;
|
||||
colFrame->GetStyleContext(aPresContext, colStyleContext.AssignRef());
|
||||
colPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position);
|
||||
nsStyleCoord width (1, eStyleUnit_Proportional);
|
||||
colPosition->mWidth = width;
|
||||
colStyleContext->RecalcAutomaticData(aPresContext);
|
||||
}
|
||||
// if there are more columns, there width is set to "minimum"
|
||||
PRInt32 numChildFrames;
|
||||
ChildCount(numChildFrames);
|
||||
for (; colIndex<numChildFrames; colIndex++)
|
||||
{
|
||||
ChildAt(colIndex, colFrame);
|
||||
NS_ASSERTION(nsnull!=colFrame, "bad column frame");
|
||||
nsStylePosition * colPosition=nsnull;
|
||||
colFrame->GetStyleContext(aPresContext, colStyleContext.AssignRef());
|
||||
colPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position);
|
||||
colPosition->mWidth.SetCoordValue(0);
|
||||
colStyleContext->RecalcAutomaticData(aPresContext);
|
||||
|
||||
// if there are more columns, there width is set to "minimum"
|
||||
PRInt32 numChildFrames;
|
||||
ChildCount(numChildFrames);
|
||||
for (; aColIndex<numChildFrames-1; colIndex++)
|
||||
{
|
||||
ChildAt(colIndex, colFrame);
|
||||
if (nsnull==colFrame)
|
||||
break;
|
||||
nsStylePosition * colPosition=nsnull;
|
||||
colFrame->GetStyleContext(aPresContext, colStyleContext.AssignRef());
|
||||
colPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position);
|
||||
colPosition->mWidth.SetCoordValue(0);
|
||||
colStyleContext->RecalcAutomaticData(aPresContext);
|
||||
}
|
||||
}
|
||||
|
||||
mStyleContext->RecalcAutomaticData(aPresContext);
|
||||
|
@ -188,30 +208,28 @@ NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPre
|
|||
*/
|
||||
int nsTableColGroupFrame::GetColumnCount ()
|
||||
{
|
||||
if (0 == mColCount)
|
||||
mColCount=0;
|
||||
int count;
|
||||
ChildCount (count);
|
||||
if (0 < count)
|
||||
{
|
||||
int count;
|
||||
ChildCount (count);
|
||||
if (0 < count)
|
||||
nsIFrame * child = nsnull;
|
||||
ChildAt(0, child);
|
||||
NS_ASSERTION(nsnull!=child, "bad child");
|
||||
while (nsnull!=child)
|
||||
{
|
||||
nsIFrame * child = nsnull;
|
||||
ChildAt(0, child);
|
||||
NS_ASSERTION(nsnull!=child, "bad child");
|
||||
while (nsnull!=child)
|
||||
{
|
||||
nsTableColFrame *col = (nsTableColFrame *)child;
|
||||
col->SetColumnIndex (mStartColIndex + mColCount);
|
||||
mColCount += col->GetRepeat ();
|
||||
child->GetNextSibling(child);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const nsStyleTable *tableStyle;
|
||||
GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
|
||||
mColCount = tableStyle->mSpan;
|
||||
nsTableColFrame *col = (nsTableColFrame *)child;
|
||||
col->SetColumnIndex (mStartColIndex + mColCount);
|
||||
mColCount += col->GetRepeat ();
|
||||
child->GetNextSibling(child);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const nsStyleTable *tableStyle;
|
||||
GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
|
||||
mColCount = tableStyle->mSpan;
|
||||
}
|
||||
return mColCount;
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,8 @@ protected:
|
|||
* Since we need to know the full column structure before the COLS attribute
|
||||
* can be interpreted, we can't just use DidSetStyleContext
|
||||
*/
|
||||
NS_METHOD SetStyleContextForFirstPass(nsIPresContext* aPresContext);
|
||||
NS_METHOD SetStyleContextForFirstPass(nsIPresContext* aPresContext,
|
||||
PRInt32 aColIndex);
|
||||
|
||||
|
||||
PRInt32 mColCount;
|
||||
|
|
|
@ -574,9 +574,9 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext,
|
|||
// need to find the generic way to stamp out this content, and ::AppendChildTo it
|
||||
// this might be ok. no matter what my mcontent is, I know it needs a colgroup as a kid?
|
||||
|
||||
lastColGroup = new nsTableColGroup (PR_TRUE);
|
||||
// XXX: how do I know whether AppendChildTo should notify or not?
|
||||
mContent->AppendChildTo(lastColGroup, PR_FALSE); // was AppendColGroup
|
||||
lastColGroup = new nsTableColGroup (PR_TRUE); // create an implicit colgroup
|
||||
// XXX: instead of Append, maybe this should be insertAt(0)?
|
||||
mContent->AppendChildTo(lastColGroup, PR_FALSE); // add the implicit colgroup to my content
|
||||
NS_ADDREF(lastColGroup); // ADDREF a: lastColGroup++
|
||||
// Resolve style for the child
|
||||
nsIStyleContext* colGroupStyleContext =
|
||||
|
@ -616,9 +616,10 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext,
|
|||
|
||||
PRInt32 excessColumns = GetColCount() - actualColumns;
|
||||
for ( ; excessColumns > 0; excessColumns--)
|
||||
{//QQQ
|
||||
{ //QQQ
|
||||
// need to find the generic way to stamp out this content, and ::AppendChildTo it
|
||||
nsTableCol *col = new nsTableCol(PR_TRUE);
|
||||
NS_ADDREF(col);
|
||||
lastColGroup->AppendChildTo (col, PR_FALSE);
|
||||
}
|
||||
NS_RELEASE(lastColGroup); // ADDREF: lastColGroup--
|
||||
|
@ -626,6 +627,103 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
/** sum the columns represented by all nsTableColGroup objects
|
||||
* if the cell map says there are more columns than this,
|
||||
* add extra implicit columns to the content tree.
|
||||
*/
|
||||
void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex,
|
||||
nsIPresContext* aPresContext,
|
||||
nsReflowMetrics& aDesiredSize,
|
||||
const nsReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
|
||||
if (nsnull!=mCellMap)
|
||||
return; // we already have a cell map so this makes no sense
|
||||
|
||||
PRInt32 actualColumns = 0;
|
||||
nsTableColGroupFrame *lastColGroupFrame = nsnull;
|
||||
nsIFrame * firstRowGroupFrame=nsnull;
|
||||
nsIFrame * prevSibFrame=nsnull;
|
||||
nsIFrame * childFrame=mFirstChild;
|
||||
while (nsnull!=childFrame)
|
||||
{
|
||||
const nsStyleDisplay *childDisplay;
|
||||
childFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
|
||||
{
|
||||
PRInt32 numCols = ((nsTableColGroupFrame*)childFrame)->GetColumnCount();
|
||||
actualColumns += numCols;
|
||||
lastColGroupFrame = (nsTableColGroupFrame *)childFrame;
|
||||
if (actualColumns > aColIndex)
|
||||
break; // we gave enough col frames at this point
|
||||
}
|
||||
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay ||
|
||||
NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == childDisplay->mDisplay ||
|
||||
NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == childDisplay->mDisplay )
|
||||
{
|
||||
firstRowGroupFrame = childFrame;
|
||||
break;
|
||||
}
|
||||
prevSibFrame = childFrame;
|
||||
childFrame->GetNextSibling(childFrame);
|
||||
}
|
||||
if (actualColumns <= aColIndex)
|
||||
{
|
||||
nsTableColGroup *lastColGroup=nsnull;
|
||||
if (nsnull==lastColGroupFrame)
|
||||
{
|
||||
lastColGroup = new nsTableColGroup (PR_TRUE); // create an implicit colgroup
|
||||
mContent->AppendChildTo(lastColGroup, PR_FALSE); // add the implicit colgroup to my content
|
||||
NS_ADDREF(lastColGroup); // ADDREF a: lastColGroup++
|
||||
// Resolve style for the child
|
||||
nsIStyleContext* colGroupStyleContext =
|
||||
aPresContext->ResolveStyleContextFor(lastColGroup, this, PR_TRUE); // kidStyleContext: REFCNT++
|
||||
nsIContentDelegate* kidDel = nsnull;
|
||||
kidDel = lastColGroup->GetDelegate(aPresContext); // kidDel: REFCNT++
|
||||
nsresult rv = kidDel->CreateFrame(aPresContext, lastColGroup, this,
|
||||
colGroupStyleContext, (nsIFrame *&)lastColGroupFrame);
|
||||
NS_RELEASE(kidDel); // kidDel: REFCNT--
|
||||
NS_RELEASE(colGroupStyleContext); // kidStyleContenxt: REFCNT--
|
||||
|
||||
// hook lastColGroupFrame into child list
|
||||
if (nsnull==firstRowGroupFrame)
|
||||
{ // make lastColGroupFrame the last frame
|
||||
nsIFrame *lastChild=nsnull;
|
||||
LastChild(lastChild);
|
||||
lastChild->SetNextSibling(lastColGroupFrame);
|
||||
}
|
||||
else
|
||||
{ // insert lastColGroupFrame before the first row group frame
|
||||
if (nsnull!=prevSibFrame)
|
||||
{ // lastColGroupFrame is inserted between prevSibFrame and lastColGroupFrame
|
||||
prevSibFrame->SetNextSibling(lastColGroupFrame);
|
||||
}
|
||||
else
|
||||
{ // lastColGroupFrame is inserted as the first child of this table
|
||||
mFirstChild = lastColGroupFrame;
|
||||
}
|
||||
lastColGroupFrame->SetNextSibling(firstRowGroupFrame);
|
||||
}
|
||||
mChildCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastColGroupFrame->GetContent((nsIContent *&)lastColGroup); // ADDREF b: lastColGroup++
|
||||
}
|
||||
|
||||
PRInt32 excessColumns = aColIndex - actualColumns;
|
||||
for ( ; excessColumns >= 0; excessColumns--)
|
||||
{
|
||||
nsTableCol *col = new nsTableCol(PR_TRUE);
|
||||
NS_ADDREF(col);
|
||||
lastColGroup->AppendChildTo(col, PR_FALSE);
|
||||
}
|
||||
NS_RELEASE(lastColGroup); // ADDREF: lastColGroup--
|
||||
lastColGroupFrame->Reflow(*aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
}
|
||||
}
|
||||
|
||||
/** Get the cell map for this table frame. It is not always mCellMap.
|
||||
* Only the firstInFlow has a legit cell map
|
||||
*/
|
||||
|
@ -1442,6 +1540,7 @@ nsReflowStatus nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext,
|
|||
nscoord bottomInset = borderPadding.bottom;
|
||||
nscoord leftInset = borderPadding.left;
|
||||
nsReflowReason reflowReason = aReflowState.reason;
|
||||
nsIContent * prevKid; // do NOT hold a reference for this temp pointer!
|
||||
|
||||
/* assumes that Table's children are in the following order:
|
||||
* Captions
|
||||
|
@ -1457,6 +1556,14 @@ nsReflowStatus nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext,
|
|||
break;
|
||||
}
|
||||
|
||||
if (kid==prevKid)
|
||||
{ // we just saw this kid, but in it's processing someone inserted something in front of it
|
||||
// (probably a colgroup). So don't process it twice.
|
||||
kidIndex++;
|
||||
continue;
|
||||
}
|
||||
prevKid = kid;
|
||||
|
||||
mLastContentIsComplete = PR_TRUE;
|
||||
|
||||
// Resolve style
|
||||
|
|
|
@ -199,7 +199,16 @@ public:
|
|||
/** return the value of the COLS attribute, adjusted for the
|
||||
* actual number of columns in the table
|
||||
*/
|
||||
PRInt32 GetEffectiveCOLSAttribute();
|
||||
PRInt32 GetEffectiveCOLSAttribute();
|
||||
|
||||
/** verify that there are at least aColIndex column frames created.
|
||||
* if not, create the needed col frames
|
||||
*/
|
||||
virtual void EnsureColumnFrameAt(PRInt32 aColIndex,
|
||||
nsIPresContext* aPresContext,
|
||||
nsReflowMetrics& aDesiredSize,
|
||||
const nsReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -41,9 +41,11 @@ static NS_DEFINE_IID(kITableContentIID, NS_ITABLECONTENT_IID);
|
|||
#ifdef NS_DEBUG
|
||||
static PRBool gsDebug = PR_FALSE;
|
||||
static PRBool gsNoisyRefs = PR_FALSE;
|
||||
static PRBool gsDebugWarnings = PR_TRUE;
|
||||
#else
|
||||
static const PRBool gsDebug = PR_FALSE;
|
||||
static const PRBool gsNoisyRefs = PR_FALSE;
|
||||
static const PRBool gsDebugWarnings = PR_FALSE;
|
||||
#endif
|
||||
|
||||
const char *nsTablePart::kCaptionTagString="CAPTION";
|
||||
|
@ -174,9 +176,11 @@ nsTablePart::AppendChildTo (nsIContent * aContent, PRBool aNotify)
|
|||
nsresult rv = aContent->QueryInterface(kITableContentIID,
|
||||
(void **)&tableContentInterface); // tableContentInterface: REFCNT++
|
||||
if (NS_FAILED(rv))
|
||||
{ // create an implicit cell and return the result of adding it to the table
|
||||
NS_ASSERTION(PR_FALSE, "non-table content insertion not implemented");
|
||||
return NS_ERROR_FAILURE;
|
||||
{ // hold onto the non-table content, but do nothing with it
|
||||
if (PR_TRUE==gsDebugWarnings)
|
||||
printf ("non-table content inserted into table.");
|
||||
rv = nsHTMLContainer::AppendChildTo(aContent, aNotify);
|
||||
return rv;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -389,20 +393,31 @@ PRBool nsTablePart::AppendRowGroup (nsTableRowGroup *aContent)
|
|||
nsIAtom * tBodyTag = NS_NewAtom(kRowGroupBodyTagString); // tBodyTag: REFCNT++
|
||||
for (childIndex = 0; childIndex < childCount; childIndex++)
|
||||
{
|
||||
nsTableContent *tableChild = (nsTableContent *)ChildAt(childIndex); // tableChild: REFCNT++
|
||||
nsITableContent *tableContentInterface = nsnull;
|
||||
nsIContent * child = ChildAt(childIndex); // tableChild: REFCNT++
|
||||
nsresult rv = child->QueryInterface(kITableContentIID,
|
||||
(void **)&tableContentInterface); // tableContentInterface: REFCNT++
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
NS_RELEASE(child); // tableChild: REFCNT-- (a)
|
||||
continue;
|
||||
}
|
||||
nsTableContent *tableChild = (nsTableContent *)tableContentInterface;
|
||||
const int tableChildType = tableChild->GetType();
|
||||
// if we've found caption or colgroup, then just skip it and keep going
|
||||
if ((tableChildType == nsITableContent::kTableCaptionType) ||
|
||||
(tableChildType == nsITableContent::kTableColGroupType))
|
||||
{
|
||||
NS_RELEASE(tableChild); // tableChild: REFCNT-- (a)
|
||||
NS_RELEASE(child); // tableChild: REFCNT-- (b)
|
||||
NS_RELEASE(tableContentInterface); // tableContentInterface: REFCNT--
|
||||
continue;
|
||||
}
|
||||
// if we've found a row group, our action depends on what kind of row group
|
||||
else if (tableChildType == nsITableContent::kTableRowGroupType)
|
||||
{
|
||||
nsIAtom * tableChildTag = tableChild->GetTag();
|
||||
NS_RELEASE(tableChild); // tableChild: REFCNT-- (b)
|
||||
NS_RELEASE(child); // tableChild: REFCNT-- (c)
|
||||
NS_RELEASE(tableContentInterface); // tableContentInterface: REFCNT--
|
||||
// if aContent is a header and the current child is a header, keep going
|
||||
if (tHeadTag==rowGroupTag && tHeadTag==tableChildTag)
|
||||
{
|
||||
|
@ -434,7 +449,8 @@ PRBool nsTablePart::AppendRowGroup (nsTableRowGroup *aContent)
|
|||
// otherwise we're already at the right spot, so stop
|
||||
else
|
||||
{
|
||||
NS_RELEASE(tableChild); // tableChild: REFCNT-- (c)
|
||||
NS_RELEASE(child); // tableChild: REFCNT-- (d)
|
||||
NS_RELEASE(tableContentInterface); // tableContentInterface: REFCNT--
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -465,9 +481,18 @@ PRBool nsTablePart::AppendColGroup(nsTableColGroup *aContent)
|
|||
int childCount = ChildCount ();
|
||||
for (childIndex = 0; childIndex < childCount; childIndex++)
|
||||
{
|
||||
nsTableContent *tableChild = (nsTableContent *)ChildAt(childIndex); // tableChild: REFCNT++
|
||||
const int tableChildType = tableChild->GetType();
|
||||
NS_RELEASE(tableChild); // tableChild: REFCNT--
|
||||
nsIContent *child = ChildAt(childIndex); // child: REFCNT++
|
||||
nsITableContent *tableContentInterface = nsnull;
|
||||
nsresult rv = child->QueryInterface(kITableContentIID,
|
||||
(void **)&tableContentInterface); // tableContentInterface: REFCNT++
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
NS_RELEASE(child);
|
||||
continue;
|
||||
}
|
||||
const int tableChildType = tableContentInterface->GetType();
|
||||
NS_RELEASE(child); // tableChild: REFCNT--
|
||||
NS_RELEASE(tableContentInterface);
|
||||
if (!((tableChildType == nsITableContent::kTableCaptionType) ||
|
||||
(tableChildType == nsITableContent::kTableColGroupType)))
|
||||
break;
|
||||
|
@ -513,13 +538,22 @@ PRBool nsTablePart::AppendColumn(nsTableCol *aContent)
|
|||
int index = ChildCount ();
|
||||
while ((0 < index) && (PR_FALSE==foundColGroup))
|
||||
{
|
||||
nsIContent *child = ChildAt (--index); // child: REFCNT++
|
||||
if (nsnull != child)
|
||||
nsITableContent *tableContentInterface = nsnull;
|
||||
nsIContent *child = ChildAt (--index); // child: REFCNT++
|
||||
nsresult rv = child->QueryInterface(kITableContentIID,
|
||||
(void **)&tableContentInterface); // tableContentInterface: REFCNT++
|
||||
NS_RELEASE(child); // tableChild: REFCNT-- (a)
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
group = (nsTableColGroup *)child;
|
||||
foundColGroup = (PRBool)
|
||||
(group->GetType()==nsITableContent::kTableColGroupType);
|
||||
NS_RELEASE(child); // child: REFCNT--
|
||||
continue;
|
||||
}
|
||||
|
||||
group = (nsTableColGroup *)tableContentInterface;
|
||||
foundColGroup = (PRBool)
|
||||
(group->GetType()==nsITableContent::kTableColGroupType);
|
||||
if (PR_FALSE==foundColGroup)
|
||||
{ // release all the table contents that are not a col group
|
||||
NS_RELEASE(tableContentInterface); // tableContentInterface: REFCNT-- (a)
|
||||
}
|
||||
}
|
||||
PRBool groupIsImplicit = PR_FALSE;
|
||||
|
@ -537,6 +571,7 @@ PRBool nsTablePart::AppendColumn(nsTableCol *aContent)
|
|||
if (NS_OK==rv)
|
||||
rv = group->AppendChildTo (aContent, PR_FALSE);
|
||||
|
||||
NS_IF_RELEASE(group); // tableContentInterface: REFCNT-- (b)
|
||||
return (PRBool)(NS_OK==rv);
|
||||
}
|
||||
|
||||
|
@ -553,9 +588,17 @@ PRBool nsTablePart::AppendCaption(nsTableCaption *aContent)
|
|||
int childCount = ChildCount ();
|
||||
for (childIndex = 0; childIndex < childCount; childIndex++)
|
||||
{
|
||||
nsTableContent *tableChild = (nsTableContent *)ChildAt(childIndex);
|
||||
const int tableChildType = tableChild->GetType();
|
||||
NS_RELEASE(tableChild);
|
||||
nsITableContent *tableContentInterface = nsnull;
|
||||
nsIContent *child = ChildAt (childIndex); // child: REFCNT++
|
||||
nsresult rv = child->QueryInterface(kITableContentIID,
|
||||
(void **)&tableContentInterface); // tableContentInterface: REFCNT++
|
||||
NS_RELEASE(child); // tableChild: REFCNT-- (a)
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const int tableChildType = tableContentInterface->GetType();
|
||||
NS_RELEASE(tableContentInterface);
|
||||
if (tableChildType != nsITableContent::kTableCaptionType)
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -20,10 +20,12 @@
|
|||
#include "nsIPresContext.h"
|
||||
#include "nsIStyleContext.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsIHTMLAttributes.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIContentDelegate.h"
|
||||
#include "nsHTMLTagContent.h"
|
||||
#include "nsTableFrame.h"
|
||||
#include "nsTableColFrame.h"
|
||||
#include "nsTableCellFrame.h"
|
||||
#include "nsIView.h"
|
||||
#include "nsIPtr.h"
|
||||
|
@ -500,6 +502,7 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
|
|||
// Place our children, one at a time, until we are out of children
|
||||
nsSize kidMaxElementSize;
|
||||
PRInt32 kidIndex = 0;
|
||||
PRInt32 colIndex = -1;
|
||||
nsIFrame* prevKidFrame = nsnull;
|
||||
nscoord maxTopMargin = 0;
|
||||
nscoord maxBottomMargin = 0;
|
||||
|
@ -513,6 +516,21 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
|
|||
break; // no more content
|
||||
}
|
||||
|
||||
// what column does this cell span to?
|
||||
nsHTMLValue value;
|
||||
((nsHTMLTagContent *)cell)->GetAttribute(nsHTMLAtoms::align, value);
|
||||
if (value.GetUnit() == eHTMLUnit_Integer)
|
||||
colIndex += value.GetIntValue();
|
||||
else
|
||||
colIndex += 1;
|
||||
|
||||
// create column frames if necessary
|
||||
nsReflowStatus status;
|
||||
aState.tableFrame->EnsureColumnFrameAt(colIndex,
|
||||
&aPresContext,
|
||||
aDesiredSize,
|
||||
aState.reflowState,
|
||||
status);
|
||||
// Create a child frame -- always an nsTableCell frame
|
||||
nsIStyleContext* kidSC = aPresContext.ResolveStyleContextFor(cell, this, PR_TRUE);
|
||||
nsIContentDelegate* kidDel = cell->GetDelegate(&aPresContext);
|
||||
|
@ -569,8 +587,6 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
|
|||
nsReflowMetrics kidSize(&kidMaxElementSize);
|
||||
nsReflowState kidReflowState(kidFrame, aState.reflowState, kidAvailSize,
|
||||
eReflowReason_Initial);
|
||||
nsReflowStatus status;
|
||||
|
||||
kidFrame->WillReflow(aPresContext);
|
||||
if (gsDebug) printf ("%p InitR: avail=%d\n", this, kidAvailSize.width);
|
||||
status = ReflowChild(kidFrame, &aPresContext, kidSize, kidReflowState);
|
||||
|
|
|
@ -40,7 +40,6 @@ static const PRBool gsDebug = PR_FALSE;
|
|||
static const PRBool gsNoisyRefs = PR_FALSE;
|
||||
#endif
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kITableContentIID, NS_ITABLECONTENT_IID);
|
||||
|
||||
// nsTableContent checks aTag
|
||||
|
@ -294,10 +293,13 @@ PRBool nsTableRowGroup::IsRow(nsIContent * aContent) const
|
|||
nsresult rv = aContent->QueryInterface(kITableContentIID,
|
||||
(void **)&tableContentInterface); // tableContentInterface: REFCNT++
|
||||
|
||||
const int contentType = tableContentInterface->GetType();
|
||||
NS_RELEASE(tableContentInterface);
|
||||
if (contentType == nsITableContent::kTableRowType)
|
||||
result = PR_TRUE;
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
const int contentType = tableContentInterface->GetType();
|
||||
NS_RELEASE(tableContentInterface);
|
||||
if (contentType == nsITableContent::kTableRowType)
|
||||
result = PR_TRUE;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -312,11 +314,13 @@ PRBool nsTableRowGroup::IsTableCell(nsIContent * aContent) const
|
|||
nsITableContent *tableContentInterface = nsnull;
|
||||
nsresult rv = aContent->QueryInterface(kITableContentIID,
|
||||
(void **)&tableContentInterface); // tableContentInterface: REFCNT++
|
||||
|
||||
const int contentType = tableContentInterface->GetType();
|
||||
NS_RELEASE(tableContentInterface);
|
||||
if (contentType == nsITableContent::kTableCellType)
|
||||
result = PR_TRUE;
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
const int contentType = tableContentInterface->GetType();
|
||||
NS_RELEASE(tableContentInterface);
|
||||
if (contentType == nsITableContent::kTableCellType)
|
||||
result = PR_TRUE;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
*/
|
||||
#include "nsTableColGroupFrame.h"
|
||||
#include "nsTableColFrame.h"
|
||||
#include "nsITableContent.h"
|
||||
#include "nsIReflowCommand.h"
|
||||
#include "nsIStyleContext.h"
|
||||
#include "nsStyleConsts.h"
|
||||
|
@ -28,6 +29,8 @@
|
|||
NS_DEF_PTR(nsIContent);
|
||||
NS_DEF_PTR(nsIStyleContext);
|
||||
|
||||
static NS_DEFINE_IID(kITableContentIID, NS_ITABLECONTENT_IID);
|
||||
|
||||
static PRBool gsDebug = PR_FALSE;
|
||||
|
||||
|
||||
|
@ -51,7 +54,9 @@ NS_METHOD nsTableColGroupFrame::Paint(nsIPresContext& aPresContext,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// TODO: content changed notifications
|
||||
// TODO: incremental reflow
|
||||
// today, we just throw away the column frames and start over every time
|
||||
// this is dumb, we should be able to maintain column frames and adjust incrementally
|
||||
NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
|
||||
nsReflowMetrics& aDesiredSize,
|
||||
const nsReflowState& aReflowState,
|
||||
|
@ -59,20 +64,35 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
|
|||
{
|
||||
NS_ASSERTION(nsnull!=mContent, "bad state -- null content for frame");
|
||||
|
||||
if (nsnull == mFirstChild)
|
||||
{ // if we don't have any children, create them
|
||||
nsIFrame* kidFrame = nsnull;
|
||||
nsIFrame* prevKidFrame;
|
||||
|
||||
LastChild(prevKidFrame); // XXX remember this...
|
||||
PRInt32 kidIndex = 0;
|
||||
for (PRInt32 colIndex = 0; ;colIndex++) // colIndex is used to set the column frames' index field
|
||||
{
|
||||
nsIContentPtr kid = mContent->ChildAt(kidIndex); // kid: REFCNT++
|
||||
if (kid.IsNull()) {
|
||||
break;
|
||||
}
|
||||
// for every content child that (is a column thingy and does not already have a frame)
|
||||
// create a frame and adjust it's style
|
||||
nsIFrame* kidFrame = nsnull;
|
||||
nsIFrame* prevKidFrame;
|
||||
|
||||
LastChild(prevKidFrame); // XXX remember this...
|
||||
PRInt32 kidIndex = 0; // index of the content child we are currently working on
|
||||
PRInt32 colIndex = 0; // number of content children that are columns, normally same as kidIndex
|
||||
for (;;)
|
||||
{
|
||||
// get the next content child, breaking if there is none
|
||||
nsIContentPtr kid = mContent->ChildAt(kidIndex); // kid: REFCNT++
|
||||
if (kid.IsNull()) {
|
||||
break;
|
||||
}
|
||||
|
||||
// verify that we're dealing with table content. If so, we know it's a column
|
||||
nsITableContent *tableContentInterface = nsnull;
|
||||
nsresult rv = kid->QueryInterface(kITableContentIID,
|
||||
(void **)&tableContentInterface); // tableContentInterface: REFCNT++
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
kidIndex++;
|
||||
continue;
|
||||
}
|
||||
NS_RELEASE(tableContentInterface); // tableContentInterface: REFCNT--
|
||||
|
||||
if (mChildCount<=colIndex)
|
||||
{
|
||||
// Resolve style
|
||||
nsIStyleContextPtr kidSC =
|
||||
aPresContext.ResolveStyleContextFor(kid, this, PR_TRUE);
|
||||
|
@ -82,8 +102,7 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
|
|||
// Create a child frame
|
||||
nsIContentDelegate* kidDel = nsnull;
|
||||
kidDel = kid->GetDelegate(&aPresContext);
|
||||
nsresult rv = kidDel->CreateFrame(&aPresContext, kid, this, kidSC,
|
||||
kidFrame);
|
||||
rv = kidDel->CreateFrame(&aPresContext, kid, this, kidSC, kidFrame);
|
||||
NS_RELEASE(kidDel);
|
||||
|
||||
// give the child frame a chance to reflow, even though we know it'll have 0 size
|
||||
|
@ -107,10 +126,10 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
|
|||
}
|
||||
prevKidFrame = kidFrame;
|
||||
mChildCount++;
|
||||
kidIndex++;
|
||||
SetStyleContextForFirstPass(&aPresContext, colIndex);
|
||||
}
|
||||
// now that I have all my COL children, adjust their style
|
||||
SetStyleContextForFirstPass(&aPresContext);
|
||||
colIndex++; // if this wasn't a column, we would not have gotten this far
|
||||
kidIndex++;
|
||||
}
|
||||
aDesiredSize.width=0;
|
||||
aDesiredSize.height=0;
|
||||
|
@ -124,7 +143,8 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
|
|||
}
|
||||
|
||||
// Subclass hook for style post processing
|
||||
NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPresContext)
|
||||
NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPresContext,
|
||||
PRInt32 aColIndex)
|
||||
{
|
||||
// get the table frame
|
||||
nsIFrame* tableFrame=nsnull;
|
||||
|
@ -150,30 +170,30 @@ NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPre
|
|||
PRInt32 colIndex=0;
|
||||
nsIFrame *colFrame=nsnull;
|
||||
nsIStyleContextPtr colStyleContext;
|
||||
for (; colIndex<numCols; colIndex++)
|
||||
ChildAt(aColIndex, colFrame);
|
||||
if (nsnull!=colFrame)
|
||||
{
|
||||
ChildAt(colIndex, colFrame);
|
||||
if (nsnull==colFrame)
|
||||
break; // the attribute value specified was greater than the actual number of columns
|
||||
nsStylePosition * colPosition=nsnull;
|
||||
colFrame->GetStyleContext(aPresContext, colStyleContext.AssignRef());
|
||||
colPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position);
|
||||
nsStyleCoord width (1, eStyleUnit_Proportional);
|
||||
colPosition->mWidth = width;
|
||||
colStyleContext->RecalcAutomaticData(aPresContext);
|
||||
}
|
||||
// if there are more columns, there width is set to "minimum"
|
||||
PRInt32 numChildFrames;
|
||||
ChildCount(numChildFrames);
|
||||
for (; colIndex<numChildFrames; colIndex++)
|
||||
{
|
||||
ChildAt(colIndex, colFrame);
|
||||
NS_ASSERTION(nsnull!=colFrame, "bad column frame");
|
||||
nsStylePosition * colPosition=nsnull;
|
||||
colFrame->GetStyleContext(aPresContext, colStyleContext.AssignRef());
|
||||
colPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position);
|
||||
colPosition->mWidth.SetCoordValue(0);
|
||||
colStyleContext->RecalcAutomaticData(aPresContext);
|
||||
|
||||
// if there are more columns, there width is set to "minimum"
|
||||
PRInt32 numChildFrames;
|
||||
ChildCount(numChildFrames);
|
||||
for (; aColIndex<numChildFrames-1; colIndex++)
|
||||
{
|
||||
ChildAt(colIndex, colFrame);
|
||||
if (nsnull==colFrame)
|
||||
break;
|
||||
nsStylePosition * colPosition=nsnull;
|
||||
colFrame->GetStyleContext(aPresContext, colStyleContext.AssignRef());
|
||||
colPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position);
|
||||
colPosition->mWidth.SetCoordValue(0);
|
||||
colStyleContext->RecalcAutomaticData(aPresContext);
|
||||
}
|
||||
}
|
||||
|
||||
mStyleContext->RecalcAutomaticData(aPresContext);
|
||||
|
@ -188,30 +208,28 @@ NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPre
|
|||
*/
|
||||
int nsTableColGroupFrame::GetColumnCount ()
|
||||
{
|
||||
if (0 == mColCount)
|
||||
mColCount=0;
|
||||
int count;
|
||||
ChildCount (count);
|
||||
if (0 < count)
|
||||
{
|
||||
int count;
|
||||
ChildCount (count);
|
||||
if (0 < count)
|
||||
nsIFrame * child = nsnull;
|
||||
ChildAt(0, child);
|
||||
NS_ASSERTION(nsnull!=child, "bad child");
|
||||
while (nsnull!=child)
|
||||
{
|
||||
nsIFrame * child = nsnull;
|
||||
ChildAt(0, child);
|
||||
NS_ASSERTION(nsnull!=child, "bad child");
|
||||
while (nsnull!=child)
|
||||
{
|
||||
nsTableColFrame *col = (nsTableColFrame *)child;
|
||||
col->SetColumnIndex (mStartColIndex + mColCount);
|
||||
mColCount += col->GetRepeat ();
|
||||
child->GetNextSibling(child);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const nsStyleTable *tableStyle;
|
||||
GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
|
||||
mColCount = tableStyle->mSpan;
|
||||
nsTableColFrame *col = (nsTableColFrame *)child;
|
||||
col->SetColumnIndex (mStartColIndex + mColCount);
|
||||
mColCount += col->GetRepeat ();
|
||||
child->GetNextSibling(child);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const nsStyleTable *tableStyle;
|
||||
GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
|
||||
mColCount = tableStyle->mSpan;
|
||||
}
|
||||
return mColCount;
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,8 @@ protected:
|
|||
* Since we need to know the full column structure before the COLS attribute
|
||||
* can be interpreted, we can't just use DidSetStyleContext
|
||||
*/
|
||||
NS_METHOD SetStyleContextForFirstPass(nsIPresContext* aPresContext);
|
||||
NS_METHOD SetStyleContextForFirstPass(nsIPresContext* aPresContext,
|
||||
PRInt32 aColIndex);
|
||||
|
||||
|
||||
PRInt32 mColCount;
|
||||
|
|
|
@ -574,9 +574,9 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext,
|
|||
// need to find the generic way to stamp out this content, and ::AppendChildTo it
|
||||
// this might be ok. no matter what my mcontent is, I know it needs a colgroup as a kid?
|
||||
|
||||
lastColGroup = new nsTableColGroup (PR_TRUE);
|
||||
// XXX: how do I know whether AppendChildTo should notify or not?
|
||||
mContent->AppendChildTo(lastColGroup, PR_FALSE); // was AppendColGroup
|
||||
lastColGroup = new nsTableColGroup (PR_TRUE); // create an implicit colgroup
|
||||
// XXX: instead of Append, maybe this should be insertAt(0)?
|
||||
mContent->AppendChildTo(lastColGroup, PR_FALSE); // add the implicit colgroup to my content
|
||||
NS_ADDREF(lastColGroup); // ADDREF a: lastColGroup++
|
||||
// Resolve style for the child
|
||||
nsIStyleContext* colGroupStyleContext =
|
||||
|
@ -616,9 +616,10 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext,
|
|||
|
||||
PRInt32 excessColumns = GetColCount() - actualColumns;
|
||||
for ( ; excessColumns > 0; excessColumns--)
|
||||
{//QQQ
|
||||
{ //QQQ
|
||||
// need to find the generic way to stamp out this content, and ::AppendChildTo it
|
||||
nsTableCol *col = new nsTableCol(PR_TRUE);
|
||||
NS_ADDREF(col);
|
||||
lastColGroup->AppendChildTo (col, PR_FALSE);
|
||||
}
|
||||
NS_RELEASE(lastColGroup); // ADDREF: lastColGroup--
|
||||
|
@ -626,6 +627,103 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
/** sum the columns represented by all nsTableColGroup objects
|
||||
* if the cell map says there are more columns than this,
|
||||
* add extra implicit columns to the content tree.
|
||||
*/
|
||||
void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex,
|
||||
nsIPresContext* aPresContext,
|
||||
nsReflowMetrics& aDesiredSize,
|
||||
const nsReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
|
||||
if (nsnull!=mCellMap)
|
||||
return; // we already have a cell map so this makes no sense
|
||||
|
||||
PRInt32 actualColumns = 0;
|
||||
nsTableColGroupFrame *lastColGroupFrame = nsnull;
|
||||
nsIFrame * firstRowGroupFrame=nsnull;
|
||||
nsIFrame * prevSibFrame=nsnull;
|
||||
nsIFrame * childFrame=mFirstChild;
|
||||
while (nsnull!=childFrame)
|
||||
{
|
||||
const nsStyleDisplay *childDisplay;
|
||||
childFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
|
||||
{
|
||||
PRInt32 numCols = ((nsTableColGroupFrame*)childFrame)->GetColumnCount();
|
||||
actualColumns += numCols;
|
||||
lastColGroupFrame = (nsTableColGroupFrame *)childFrame;
|
||||
if (actualColumns > aColIndex)
|
||||
break; // we gave enough col frames at this point
|
||||
}
|
||||
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay ||
|
||||
NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == childDisplay->mDisplay ||
|
||||
NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == childDisplay->mDisplay )
|
||||
{
|
||||
firstRowGroupFrame = childFrame;
|
||||
break;
|
||||
}
|
||||
prevSibFrame = childFrame;
|
||||
childFrame->GetNextSibling(childFrame);
|
||||
}
|
||||
if (actualColumns <= aColIndex)
|
||||
{
|
||||
nsTableColGroup *lastColGroup=nsnull;
|
||||
if (nsnull==lastColGroupFrame)
|
||||
{
|
||||
lastColGroup = new nsTableColGroup (PR_TRUE); // create an implicit colgroup
|
||||
mContent->AppendChildTo(lastColGroup, PR_FALSE); // add the implicit colgroup to my content
|
||||
NS_ADDREF(lastColGroup); // ADDREF a: lastColGroup++
|
||||
// Resolve style for the child
|
||||
nsIStyleContext* colGroupStyleContext =
|
||||
aPresContext->ResolveStyleContextFor(lastColGroup, this, PR_TRUE); // kidStyleContext: REFCNT++
|
||||
nsIContentDelegate* kidDel = nsnull;
|
||||
kidDel = lastColGroup->GetDelegate(aPresContext); // kidDel: REFCNT++
|
||||
nsresult rv = kidDel->CreateFrame(aPresContext, lastColGroup, this,
|
||||
colGroupStyleContext, (nsIFrame *&)lastColGroupFrame);
|
||||
NS_RELEASE(kidDel); // kidDel: REFCNT--
|
||||
NS_RELEASE(colGroupStyleContext); // kidStyleContenxt: REFCNT--
|
||||
|
||||
// hook lastColGroupFrame into child list
|
||||
if (nsnull==firstRowGroupFrame)
|
||||
{ // make lastColGroupFrame the last frame
|
||||
nsIFrame *lastChild=nsnull;
|
||||
LastChild(lastChild);
|
||||
lastChild->SetNextSibling(lastColGroupFrame);
|
||||
}
|
||||
else
|
||||
{ // insert lastColGroupFrame before the first row group frame
|
||||
if (nsnull!=prevSibFrame)
|
||||
{ // lastColGroupFrame is inserted between prevSibFrame and lastColGroupFrame
|
||||
prevSibFrame->SetNextSibling(lastColGroupFrame);
|
||||
}
|
||||
else
|
||||
{ // lastColGroupFrame is inserted as the first child of this table
|
||||
mFirstChild = lastColGroupFrame;
|
||||
}
|
||||
lastColGroupFrame->SetNextSibling(firstRowGroupFrame);
|
||||
}
|
||||
mChildCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastColGroupFrame->GetContent((nsIContent *&)lastColGroup); // ADDREF b: lastColGroup++
|
||||
}
|
||||
|
||||
PRInt32 excessColumns = aColIndex - actualColumns;
|
||||
for ( ; excessColumns >= 0; excessColumns--)
|
||||
{
|
||||
nsTableCol *col = new nsTableCol(PR_TRUE);
|
||||
NS_ADDREF(col);
|
||||
lastColGroup->AppendChildTo(col, PR_FALSE);
|
||||
}
|
||||
NS_RELEASE(lastColGroup); // ADDREF: lastColGroup--
|
||||
lastColGroupFrame->Reflow(*aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
}
|
||||
}
|
||||
|
||||
/** Get the cell map for this table frame. It is not always mCellMap.
|
||||
* Only the firstInFlow has a legit cell map
|
||||
*/
|
||||
|
@ -1442,6 +1540,7 @@ nsReflowStatus nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext,
|
|||
nscoord bottomInset = borderPadding.bottom;
|
||||
nscoord leftInset = borderPadding.left;
|
||||
nsReflowReason reflowReason = aReflowState.reason;
|
||||
nsIContent * prevKid; // do NOT hold a reference for this temp pointer!
|
||||
|
||||
/* assumes that Table's children are in the following order:
|
||||
* Captions
|
||||
|
@ -1457,6 +1556,14 @@ nsReflowStatus nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext,
|
|||
break;
|
||||
}
|
||||
|
||||
if (kid==prevKid)
|
||||
{ // we just saw this kid, but in it's processing someone inserted something in front of it
|
||||
// (probably a colgroup). So don't process it twice.
|
||||
kidIndex++;
|
||||
continue;
|
||||
}
|
||||
prevKid = kid;
|
||||
|
||||
mLastContentIsComplete = PR_TRUE;
|
||||
|
||||
// Resolve style
|
||||
|
|
|
@ -199,7 +199,16 @@ public:
|
|||
/** return the value of the COLS attribute, adjusted for the
|
||||
* actual number of columns in the table
|
||||
*/
|
||||
PRInt32 GetEffectiveCOLSAttribute();
|
||||
PRInt32 GetEffectiveCOLSAttribute();
|
||||
|
||||
/** verify that there are at least aColIndex column frames created.
|
||||
* if not, create the needed col frames
|
||||
*/
|
||||
virtual void EnsureColumnFrameAt(PRInt32 aColIndex,
|
||||
nsIPresContext* aPresContext,
|
||||
nsReflowMetrics& aDesiredSize,
|
||||
const nsReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -20,10 +20,12 @@
|
|||
#include "nsIPresContext.h"
|
||||
#include "nsIStyleContext.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsIHTMLAttributes.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIContentDelegate.h"
|
||||
#include "nsHTMLTagContent.h"
|
||||
#include "nsTableFrame.h"
|
||||
#include "nsTableColFrame.h"
|
||||
#include "nsTableCellFrame.h"
|
||||
#include "nsIView.h"
|
||||
#include "nsIPtr.h"
|
||||
|
@ -500,6 +502,7 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
|
|||
// Place our children, one at a time, until we are out of children
|
||||
nsSize kidMaxElementSize;
|
||||
PRInt32 kidIndex = 0;
|
||||
PRInt32 colIndex = -1;
|
||||
nsIFrame* prevKidFrame = nsnull;
|
||||
nscoord maxTopMargin = 0;
|
||||
nscoord maxBottomMargin = 0;
|
||||
|
@ -513,6 +516,21 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
|
|||
break; // no more content
|
||||
}
|
||||
|
||||
// what column does this cell span to?
|
||||
nsHTMLValue value;
|
||||
((nsHTMLTagContent *)cell)->GetAttribute(nsHTMLAtoms::align, value);
|
||||
if (value.GetUnit() == eHTMLUnit_Integer)
|
||||
colIndex += value.GetIntValue();
|
||||
else
|
||||
colIndex += 1;
|
||||
|
||||
// create column frames if necessary
|
||||
nsReflowStatus status;
|
||||
aState.tableFrame->EnsureColumnFrameAt(colIndex,
|
||||
&aPresContext,
|
||||
aDesiredSize,
|
||||
aState.reflowState,
|
||||
status);
|
||||
// Create a child frame -- always an nsTableCell frame
|
||||
nsIStyleContext* kidSC = aPresContext.ResolveStyleContextFor(cell, this, PR_TRUE);
|
||||
nsIContentDelegate* kidDel = cell->GetDelegate(&aPresContext);
|
||||
|
@ -569,8 +587,6 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
|
|||
nsReflowMetrics kidSize(&kidMaxElementSize);
|
||||
nsReflowState kidReflowState(kidFrame, aState.reflowState, kidAvailSize,
|
||||
eReflowReason_Initial);
|
||||
nsReflowStatus status;
|
||||
|
||||
kidFrame->WillReflow(aPresContext);
|
||||
if (gsDebug) printf ("%p InitR: avail=%d\n", this, kidAvailSize.width);
|
||||
status = ReflowChild(kidFrame, &aPresContext, kidSize, kidReflowState);
|
||||
|
|
Загрузка…
Ссылка в новой задаче