new reflow/layout code for outer table to handle captions and margins. better % height handling.

row groups and rows don't include external cellspacing in there dimensions. r=troy.
This commit is contained in:
karnaze%netscape.com 2000-04-28 21:05:31 +00:00
Родитель d70ba8d8b0
Коммит 65511dc8d6
32 изменённых файлов: 2911 добавлений и 2077 удалений

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

@ -2287,8 +2287,9 @@ StyleContextImpl::RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse)
nsCompatibility quirkMode = eCompatibility_Standard;
aPresContext->GetCompatibilityMode(&quirkMode);
if (eCompatibility_NavQuirks == quirkMode) {
if ((mDisplay.mDisplay == NS_STYLE_DISPLAY_TABLE) ||
(mDisplay.mDisplay == NS_STYLE_DISPLAY_TABLE_CAPTION)) {
if (((mDisplay.mDisplay == NS_STYLE_DISPLAY_TABLE) ||
(mDisplay.mDisplay == NS_STYLE_DISPLAY_TABLE_CAPTION)) &&
(nsnull == mPseudoTag)) {
StyleContextImpl* holdParent = mParent;
mParent = nsnull; // cut off all inheritance. this really blows

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

@ -360,9 +360,6 @@ struct nsPseudoFrames {
// the frame type of the most descendant pseudo frame, no AddRef
nsIAtom* mLowestType;
// col groups are handled specially so if there is both a pseudo
// row group and col group, content order needs to be preserved
PRBool mColGroupBeforeRowGroup;
nsPseudoFrames();
nsPseudoFrames& operator=(const nsPseudoFrames& aOther);
@ -389,8 +386,7 @@ nsPseudoFrameData::Reset()
nsPseudoFrames::nsPseudoFrames()
: mTableOuter(), mTableInner(), mRowGroup(), mColGroup(),
mRow(), mCellOuter(), mCellInner(), mLowestType(nsnull),
mColGroupBeforeRowGroup(PR_FALSE)
mRow(), mCellOuter(), mCellInner(), mLowestType(nsnull)
{}
nsPseudoFrames& nsPseudoFrames::operator=(const nsPseudoFrames& aOther)
@ -403,7 +399,6 @@ nsPseudoFrames& nsPseudoFrames::operator=(const nsPseudoFrames& aOther)
mCellOuter = aOther.mCellOuter;
mCellInner = aOther.mCellInner;
mLowestType = aOther.mLowestType;
mColGroupBeforeRowGroup = aOther.mColGroupBeforeRowGroup;
return *this;
}
@ -422,7 +417,6 @@ nsPseudoFrames::Reset(nsPseudoFrames* aSave)
mCellOuter.Reset();
mCellInner.Reset();
mLowestType = nsnull;
mColGroupBeforeRowGroup = PR_FALSE;
}
// -----------------------------------------------------------
@ -699,15 +693,24 @@ nsMathMLmtableCreator::CreateTableCellInnerFrame(nsIFrame** aNewFrame)
// -----------------------------------------------------------
// return the child list that aFrame belongs on. does not ADDREF
nsIAtom* GetChildListFor(const nsIFrame* aFrame)
PRBool GetCaptionAdjustedParent(nsIFrame* aParentFrame,
const nsIFrame* aChildFrame,
nsIFrame** aAdjParentFrame)
{
nsIAtom* childList = nsnull;
nsCOMPtr<nsIAtom> frameType;
aFrame->GetFrameType(getter_AddRefs(frameType));
if (nsLayoutAtoms::tableCaptionFrame == frameType.get()) {
childList = nsLayoutAtoms::captionList;
*aAdjParentFrame = aParentFrame;
PRBool haveCaption = PR_FALSE;
nsCOMPtr<nsIAtom> childFrameType;
aChildFrame->GetFrameType(getter_AddRefs(childFrameType));
if (nsLayoutAtoms::tableCaptionFrame == childFrameType.get()) {
haveCaption = PR_TRUE;
nsCOMPtr<nsIAtom> parentFrameType;
aParentFrame->GetFrameType(getter_AddRefs(parentFrameType));
if (nsLayoutAtoms::tableFrame == parentFrameType.get()) {
aParentFrame->GetParent(aAdjParentFrame);
}
}
return childList;
return haveCaption;
}
nsCSSFrameConstructor::nsCSSFrameConstructor(void)
@ -1803,7 +1806,8 @@ nsCSSFrameConstructor::CreatePseudoTableFrame(nsIPresShell* aPresShel
parentFrame->GetStyleContext(getter_AddRefs(parentStyle));
parentFrame->GetContent(getter_AddRefs(parentContent));
aPresContext->ResolvePseudoStyleContextFor(parentContent, nsHTMLAtoms::tableOuterPseudo,
// create the SC for the inner table which will be the parent of the outer table's SC
aPresContext->ResolvePseudoStyleContextFor(parentContent, nsHTMLAtoms::tablePseudo,
parentStyle, PR_FALSE,
getter_AddRefs(childStyle));
@ -1910,15 +1914,13 @@ nsCSSFrameConstructor::CreatePseudoColGroupFrame(nsIPresShell* aPresS
parentFrame, childStyle.get(), aTableCreator,
PR_TRUE, items, pseudo.mFrame, pseudoParent);
if (NS_FAILED(rv)) return rv;
((nsTableColGroupFrame*)pseudo.mFrame)->SetType(eColGroupAnonymousCol);
// set pseudo data for the parent
if (aState.mPseudoFrames.mTableInner.mFrame) {
aState.mPseudoFrames.mTableInner.mChildList.AddChild(pseudo.mFrame);
}
if (!aState.mPseudoFrames.mRowGroup.mFrame) {
aState.mPseudoFrames.mColGroupBeforeRowGroup = PR_TRUE;
}
return rv;
}
@ -2322,6 +2324,17 @@ nsCSSFrameConstructor::GetParentFrame(nsIPresShell* aPresShell,
}
void
FixUpOuterTableFloat(nsIStyleContext* aOuterSC,
nsIStyleContext* aInnerSC)
{
nsStyleDisplay* outerStyleDisplay = (nsStyleDisplay*)aOuterSC->GetMutableStyleData(eStyleStruct_Display);
nsStyleDisplay* innerStyleDisplay = (nsStyleDisplay*)aInnerSC->GetStyleData(eStyleStruct_Display);
if (outerStyleDisplay->mFloats != innerStyleDisplay->mFloats) {
outerStyleDisplay->mFloats = innerStyleDisplay->mFloats;
}
}
// Construct the outer, inner table frames and the children frames for the table.
nsresult
nsCSSFrameConstructor::ConstructTableFrame(nsIPresShell* aPresShell,
@ -2357,12 +2370,19 @@ nsCSSFrameConstructor::ConstructTableFrame(nsIPresShell* aPresShell,
}
}
// create the pseudo SC for the outer table as a child of the inner SC
nsCOMPtr<nsIStyleContext> outerStyleContext;
aPresContext->ResolvePseudoStyleContextFor(aContent, nsHTMLAtoms::tableOuterPseudo,
aStyleContext, PR_FALSE,
getter_AddRefs(outerStyleContext));
FixUpOuterTableFloat(outerStyleContext, aStyleContext);
// Init the table outer frame and see if we need to create a view, e.g.
// the frame is absolutely positioned
InitAndRestoreFrame(aPresContext, aState, aContent,
parentFrame, aStyleContext, nsnull, aNewOuterFrame);
parentFrame, outerStyleContext, nsnull, aNewOuterFrame);
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, aNewOuterFrame,
aStyleContext, PR_FALSE);
outerStyleContext, PR_FALSE);
// Create the inner table frame
aTableCreator.CreateTableFrame(&aNewInnerFrame);
@ -2787,34 +2807,22 @@ nsCSSFrameConstructor::MustGeneratePseudoParent(nsIPresContext* aPresContext,
return !IsOnlyWhiteSpace(aContent);
}
if ( (nsHTMLAtoms::img == aTag) ||
(nsHTMLAtoms::hr == aTag) ||
(nsHTMLAtoms::br == aTag) ||
(nsHTMLAtoms::wbr == aTag) ||
(nsHTMLAtoms::input == aTag) ||
(nsHTMLAtoms::textarea == aTag) ||
(nsHTMLAtoms::select == aTag) ||
(nsHTMLAtoms::applet == aTag) ||
(nsHTMLAtoms::embed == aTag) ||
(nsHTMLAtoms::fieldset == aTag) ||
(nsHTMLAtoms::legend == aTag) ||
(nsHTMLAtoms::object == aTag) ||
(nsHTMLAtoms::iframe == aTag) ||
(nsHTMLAtoms::spacer == aTag) ||
(nsHTMLAtoms::button == aTag) ||
(nsHTMLAtoms::label == aTag) ) {
return PR_TRUE;
// exclude tags
if ( (nsLayoutAtoms::commentTagName == aTag) ||
(nsHTMLAtoms::form == aTag) ) {
return PR_FALSE;
}
// MathML Mod - DJF
// XXX DJF - when should pseudo frames be constructed for MathML?
#ifdef MOZ_MATHML
// XXX should pseudo frames be created in this case?
if ( (nsMathMLAtoms::math == aTag) ) {
if ( (nsMathMLAtoms::math == aTag) ) {
return PR_TRUE;
}
else {
return PR_FALSE;
}
#endif
// we should check for display type as well - later
return PR_FALSE;
}
@ -4570,16 +4578,15 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsIPresShell* aPresShell,
const nsStyleDisplay* styleDisplay;
newFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) styleDisplay);
nsIFrame * areaFrame;
//NS_NewBlockFrame(shell, &areaFrame, flags);
NS_NewAreaFrame(shell, &areaFrame, flags | NS_BLOCK_SHRINK_WRAP);// | NS_BLOCK_MARGIN_ROOT);
nsIFrame * blkFrame;
NS_NewBlockFrame(shell, &blkFrame, flags);
// Resolve style and initialize the frame
nsIStyleContext* styleContext;
aPresContext->ResolvePseudoStyleContextFor(aContent, nsHTMLAtoms::fieldsetContentPseudo,
aStyleContext, PR_FALSE, &styleContext);
InitAndRestoreFrame(aPresContext, aState, aContent,
newFrame, styleContext, nsnull, areaFrame);
newFrame, styleContext, nsnull, blkFrame);
NS_RELEASE(styleContext);
@ -4589,7 +4596,7 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsIPresShell* aPresShell,
HaveSpecialBlockStyle(aPresContext, aContent, aStyleContext,
&haveFirstLetterStyle, &haveFirstLineStyle);
nsFrameConstructorSaveState floaterSaveState;
aState.PushFloaterContainingBlock(areaFrame, floaterSaveState,
aState.PushFloaterContainingBlock(blkFrame, floaterSaveState,
haveFirstLetterStyle,
haveFirstLineStyle);
@ -4602,10 +4609,10 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsIPresShell* aPresShell,
if (isPositionedContainingBlock) {
// The area frame becomes a container for child frames that are
// absolutely positioned
aState.PushAbsoluteContainingBlock(areaFrame, absoluteSaveState);
aState.PushAbsoluteContainingBlock(blkFrame, absoluteSaveState);
}
ProcessChildren(aPresShell, aPresContext, aState, aContent, areaFrame, PR_FALSE,
ProcessChildren(aPresShell, aPresContext, aState, aContent, blkFrame, PR_FALSE,
childItems, PR_TRUE);
static NS_DEFINE_IID(kLegendFrameCID, NS_LEGEND_FRAME_CID);
@ -4619,7 +4626,7 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsIPresShell* aPresShell,
nsIFrame * nxt;
legendFrame->GetNextSibling(&nxt);
previous->SetNextSibling(nxt);
areaFrame->SetNextSibling(legendFrame);
blkFrame->SetNextSibling(legendFrame);
legendFrame->SetParent(newFrame);
legendFrame->SetNextSibling(nsnull);
break;
@ -4627,7 +4634,7 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsIPresShell* aPresShell,
nsIFrame * nxt;
legendFrame->GetNextSibling(&nxt);
childItems.childList = nxt;
areaFrame->SetNextSibling(legendFrame);
blkFrame->SetNextSibling(legendFrame);
legendFrame->SetParent(newFrame);
legendFrame->SetNextSibling(nsnull);
break;
@ -4638,21 +4645,21 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsIPresShell* aPresShell,
}
// Set the scrolled frame's initial child lists
areaFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
blkFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
if (isPositionedContainingBlock && aState.mAbsoluteItems.childList) {
areaFrame->SetInitialChildList(aPresContext,
blkFrame->SetInitialChildList(aPresContext,
nsLayoutAtoms::absoluteList,
aState.mAbsoluteItems.childList);
}
if (aState.mFloatedItems.childList) {
areaFrame->SetInitialChildList(aPresContext,
blkFrame->SetInitialChildList(aPresContext,
nsLayoutAtoms::floaterList,
aState.mFloatedItems.childList);
}
// Set the scroll frame's initial child list
newFrame->SetInitialChildList(aPresContext, nsnull, areaFrame);
newFrame->SetInitialChildList(aPresContext, nsnull, blkFrame);
// our new frame retured is the top frame which is the list frame.
aNewFrame = newFrame;
@ -5154,11 +5161,11 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsIPresShell* aPresShell,
nsFrameConstructorState& aState,
nsIContent* aParent,
nsIDocument* aDocument,
nsIFrame* aParentFrame,
nsIFrame* aNewFrame,
nsFrameItems& aChildItems)
{
nsCOMPtr<nsIAnonymousContentCreator> creator(do_QueryInterface(aParentFrame));
nsCOMPtr<nsIAnonymousContentCreator> creator(do_QueryInterface(aNewFrame));
if (!creator)
return NS_OK;
@ -5182,14 +5189,8 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsIPresShell* aPresShell,
content->SetParent(aParent);
content->SetDocument(aDocument, PR_TRUE);
nsIFrame * newFrame = nsnull;
nsresult rv = creator->CreateFrameFor(aPresContext, content, &newFrame);
if (NS_SUCCEEDED(rv) && newFrame != nsnull) {
aChildItems.AddChild(newFrame);
} else {
// create the frame and attach it to our frame
ConstructFrame(aPresShell, aPresContext, aState, content, aParentFrame, aChildItems);
}
// create the frame and attach it to our frame
ConstructFrame(aPresShell, aPresContext, aState, content, aNewFrame, aChildItems);
}
return NS_OK;
@ -7515,8 +7516,16 @@ nsCSSFrameConstructor::AppendFrames(nsIPresContext* aPresContext,
}
else {
// Append the frames to the end of the parent's child list
rv = aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
GetChildListFor(aFrameList), aFrameList);
// check for a table caption which goes on an additional child list with a different parent
nsIFrame* outerTableFrame;
if (GetCaptionAdjustedParent(aParentFrame, aFrameList, &outerTableFrame)) {
rv = aFrameManager->AppendFrames(aPresContext, *aPresShell, outerTableFrame,
nsLayoutAtoms::captionList, aFrameList);
}
else {
rv = aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
nsnull, aFrameList);
}
}
NS_IF_RELEASE(parentType);
@ -8296,11 +8305,15 @@ nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext,
}
}
// check for a table caption which goes on an additional child list
nsIAtom* childList = GetChildListFor(newFrame);
rv = state.mFrameManager->InsertFrames(aPresContext, *shell,
parentFrame,
childList, prevSibling,
newFrame);
nsIFrame* outerTableFrame;
if (GetCaptionAdjustedParent(parentFrame, newFrame, &outerTableFrame)) {
rv = state.mFrameManager->AppendFrames(aPresContext, *shell, outerTableFrame,
nsLayoutAtoms::captionList, newFrame);
}
else {
rv = state.mFrameManager->InsertFrames(aPresContext, *shell, parentFrame,
nsnull, prevSibling, newFrame);
}
}
// If there are new absolutely positioned child frames, then notify
@ -8791,9 +8804,16 @@ nsCSSFrameConstructor::ContentRemoved(nsIPresContext* aPresContext,
} else {
// Notify the parent frame that it should delete the frame
nsIAtom* childList = GetChildListFor(childFrame);
rv = frameManager->RemoveFrame(aPresContext, *shell, parentFrame,
childList, childFrame);
// check for a table caption which goes on an additional child list with a different parent
nsIFrame* outerTableFrame;
if (GetCaptionAdjustedParent(parentFrame, childFrame, &outerTableFrame)) {
rv = frameManager->RemoveFrame(aPresContext, *shell, outerTableFrame,
nsLayoutAtoms::captionList, childFrame);
}
else {
rv = frameManager->RemoveFrame(aPresContext, *shell, parentFrame,
nsnull, childFrame);
}
}
}

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

@ -305,9 +305,14 @@ struct nsHTMLReflowState {
static nsCSSFrameType DetermineFrameType(nsIFrame* aFrame);
void ComputeContainingBlockRectangle(const nsHTMLReflowState* aContainingBlockRS,
nscoord& aContainingBlockWidth,
nscoord& aContainingBlockHeight);
void ComputeContainingBlockRectangle(nsIPresContext* aPresContext,
const nsHTMLReflowState* aContainingBlockRS,
nscoord& aContainingBlockWidth,
nscoord& aContainingBlockHeight);
void CalculateBlockSideMargins(const nsHTMLReflowState* aContainingBlockRS,
nscoord aComputedWidth);
protected:
// This method initializes various data members. It is automatically
@ -343,9 +348,6 @@ protected:
nscoord aContainingBlockWidth,
nscoord aContainingBlockHeight);
void CalculateBlockSideMargins(const nsHTMLReflowState* aContainingBlockRS,
nscoord aComputedWidth);
void ComputeHorizontalValue(nscoord aContainingBlockWidth,
nsStyleUnit aUnit,
const nsStyleCoord& aCoord,

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

@ -2287,8 +2287,9 @@ StyleContextImpl::RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse)
nsCompatibility quirkMode = eCompatibility_Standard;
aPresContext->GetCompatibilityMode(&quirkMode);
if (eCompatibility_NavQuirks == quirkMode) {
if ((mDisplay.mDisplay == NS_STYLE_DISPLAY_TABLE) ||
(mDisplay.mDisplay == NS_STYLE_DISPLAY_TABLE_CAPTION)) {
if (((mDisplay.mDisplay == NS_STYLE_DISPLAY_TABLE) ||
(mDisplay.mDisplay == NS_STYLE_DISPLAY_TABLE_CAPTION)) &&
(nsnull == mPseudoTag)) {
StyleContextImpl* holdParent = mParent;
mParent = nsnull; // cut off all inheritance. this really blows

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

@ -421,7 +421,8 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
(NS_AUTOOFFSET == kidReflowState.mComputedOffsets.top)) {
if (-1 == aContainingBlockWidth) {
// Get the containing block width/height
kidReflowState.ComputeContainingBlockRectangle(&aReflowState,
kidReflowState.ComputeContainingBlockRectangle(aPresContext,
&aReflowState,
aContainingBlockWidth,
aContainingBlockHeight);
}

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

@ -1261,12 +1261,90 @@ IsInitialContainingBlock(nsIFrame* aFrame)
return result;
}
nscoord
GetVerticalMarginBorderPadding(const nsHTMLReflowState* aReflowState)
{
nscoord result = 0;
if (!aReflowState) return result;
// zero auto margins
nsMargin margin = aReflowState->mComputedMargin;
if (NS_AUTOMARGIN == margin.top)
margin.top = 0;
if (NS_AUTOMARGIN == margin.bottom)
margin.bottom = 0;
result += margin.top + margin.bottom;
result += aReflowState->mComputedBorderPadding.top +
aReflowState->mComputedBorderPadding.bottom;
return result;
}
/* Get the height based on the viewport of the containing block specified
* in aReflowState when the containing block has mComputedHeight == NS_AUTOHEIGHT
* and it is the body.
*/
nscoord
CalcQuirkContainingBlockHeight(const nsHTMLReflowState& aReflowState)
{
nsHTMLReflowState* firstBlockRS = nsnull; // a candidate for body frame
nsHTMLReflowState* firstAreaRS = nsnull; // a candidate for html frame
nscoord result = 0;
const nsHTMLReflowState* rs = &aReflowState;
for (; rs; rs = (nsHTMLReflowState *)(rs->parentReflowState)) {
nsCOMPtr<nsIAtom> frameType;
rs->frame->GetFrameType(getter_AddRefs(frameType));
// if the ancestor is auto height then skip it and continue up if it
// is the first block/area frame and possibly the body/html
if (nsLayoutAtoms::blockFrame == frameType.get()) {
if (!firstBlockRS) {
firstBlockRS = (nsHTMLReflowState*)rs;
if (NS_AUTOHEIGHT == rs->mComputedHeight) continue;
}
else break;
}
else if (nsLayoutAtoms::areaFrame == frameType.get()) {
if (!firstAreaRS) {
firstAreaRS = (nsHTMLReflowState*)rs;
if (NS_AUTOHEIGHT == rs->mComputedHeight) continue;
}
else break;
}
else if (nsLayoutAtoms::canvasFrame != frameType.get()) {
break;
}
// the ancestor has a computed height, it is the percent base
result = rs->mComputedHeight;
// if we got to the canvas frame, then subtract out
// margin/border/padding for the BODY and HTML elements
if (nsLayoutAtoms::canvasFrame == frameType.get()) {
result -= GetVerticalMarginBorderPadding(firstBlockRS);
result -= GetVerticalMarginBorderPadding(firstAreaRS);
}
// if we got to the html frame, then subtract out
// margin/border/padding for the BODY element
else if (nsLayoutAtoms::areaFrame == frameType.get()) {
// make sure it is the body
nsCOMPtr<nsIAtom> fType;
rs->parentReflowState->frame->GetFrameType(getter_AddRefs(fType));
if (nsLayoutAtoms::canvasFrame == fType.get()) {
result -= GetVerticalMarginBorderPadding(firstBlockRS);
}
}
break;
}
return result;
}
// Called by InitConstraints() to compute the containing block rectangle for
// the element. Handles the special logic for absolutely positioned elements
void
nsHTMLReflowState::ComputeContainingBlockRectangle(const nsHTMLReflowState* aContainingBlockRS,
nscoord& aContainingBlockWidth,
nscoord& aContainingBlockHeight)
nsHTMLReflowState::ComputeContainingBlockRectangle(nsIPresContext* aPresContext,
const nsHTMLReflowState* aContainingBlockRS,
nscoord& aContainingBlockWidth,
nscoord& aContainingBlockHeight)
{
// Unless the element is absolutely positioned, the containing block is
// formed by the content edge of the nearest block-level ancestor
@ -1339,6 +1417,19 @@ nsHTMLReflowState::ComputeContainingBlockRectangle(const nsHTMLReflowState* aCon
if (NS_UNCONSTRAINEDSIZE == availableWidth) {
aContainingBlockWidth = NS_UNCONSTRAINEDSIZE;
}
// a table in quirks mode gets a containing block based on the viewport (less
// body margins, border, padding) if the table is a child of the body.
if (NS_AUTOHEIGHT == aContainingBlockHeight) {
nsCOMPtr<nsIAtom> fType;
frame->GetFrameType(getter_AddRefs(fType));
if (nsLayoutAtoms::tableFrame == fType.get()) {
nsCompatibility mode;
aPresContext->GetCompatibilityMode(&mode);
if (eCompatibility_NavQuirks == mode) {
aContainingBlockHeight = CalcQuirkContainingBlockHeight(*aContainingBlockRS);
}
}
}
}
}
@ -1370,7 +1461,8 @@ nsHTMLReflowState::InitConstraints(nsIPresContext* aPresContext,
// If we weren't given a containing block width and height, then
// compute one
if (aContainingBlockWidth == -1) {
ComputeContainingBlockRectangle(cbrs, aContainingBlockWidth, aContainingBlockHeight);
ComputeContainingBlockRectangle(aPresContext, cbrs, aContainingBlockWidth,
aContainingBlockHeight);
}
// See if the element is relatively positioned
@ -1517,10 +1609,9 @@ nsHTMLReflowState::InitConstraints(nsIPresContext* aPresContext,
mComputedWidth = NS_UNCONSTRAINEDSIZE;
} else if (NS_STYLE_DISPLAY_TABLE == mStyleDisplay->mDisplay) {
// It's a table. The CSS spec says the computed width should be
// 0 so set it to 0. The table code will just chose whatever width
// it wants
mComputedWidth = 0;
// It's an outer table because an inner table is not positioned
// shrink wrap its width since the outer table is anonymous
mComputedWidth = NS_SHRINKWRAPWIDTH;
} else {
// The CSS2 spec says the computed width should be 0; however, that's
@ -1704,9 +1795,24 @@ nsHTMLReflowState::ComputeBlockBoxData(nsIPresContext* aPresContext,
}
} else {
mComputedWidth = availableWidth - mComputedMargin.left -
mComputedMargin.right - mComputedBorderPadding.left -
mComputedBorderPadding.right;
// tables act like replaced elements regarding mComputedWidth
nsCOMPtr<nsIAtom> fType;
frame->GetFrameType(getter_AddRefs(fType));
if (nsLayoutAtoms::tableOuterFrame == fType.get()) {
mComputedWidth = NS_SHRINKWRAPWIDTH;
} else if (nsLayoutAtoms::tableFrame == fType.get()) {
mComputedWidth = NS_SHRINKWRAPWIDTH;
if (eStyleUnit_Auto == mStyleSpacing->mMargin.GetLeftUnit()) {
mComputedMargin.left = NS_AUTOMARGIN;
}
if (eStyleUnit_Auto == mStyleSpacing->mMargin.GetRightUnit()) {
mComputedMargin.right = NS_AUTOMARGIN;
}
} else {
mComputedWidth = availableWidth - mComputedMargin.left -
mComputedMargin.right - mComputedBorderPadding.left -
mComputedBorderPadding.right;
}
// Take into account any min and max values
if (mComputedWidth > mComputedMaxWidth) {

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

@ -305,9 +305,14 @@ struct nsHTMLReflowState {
static nsCSSFrameType DetermineFrameType(nsIFrame* aFrame);
void ComputeContainingBlockRectangle(const nsHTMLReflowState* aContainingBlockRS,
nscoord& aContainingBlockWidth,
nscoord& aContainingBlockHeight);
void ComputeContainingBlockRectangle(nsIPresContext* aPresContext,
const nsHTMLReflowState* aContainingBlockRS,
nscoord& aContainingBlockWidth,
nscoord& aContainingBlockHeight);
void CalculateBlockSideMargins(const nsHTMLReflowState* aContainingBlockRS,
nscoord aComputedWidth);
protected:
// This method initializes various data members. It is automatically
@ -343,9 +348,6 @@ protected:
nscoord aContainingBlockWidth,
nscoord aContainingBlockHeight);
void CalculateBlockSideMargins(const nsHTMLReflowState* aContainingBlockRS,
nscoord aComputedWidth);
void ComputeHorizontalValue(nscoord aContainingBlockWidth,
nsStyleUnit aUnit,
const nsStyleCoord& aCoord,

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

@ -421,7 +421,8 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
(NS_AUTOOFFSET == kidReflowState.mComputedOffsets.top)) {
if (-1 == aContainingBlockWidth) {
// Get the containing block width/height
kidReflowState.ComputeContainingBlockRectangle(&aReflowState,
kidReflowState.ComputeContainingBlockRectangle(aPresContext,
&aReflowState,
aContainingBlockWidth,
aContainingBlockHeight);
}

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

@ -1261,12 +1261,90 @@ IsInitialContainingBlock(nsIFrame* aFrame)
return result;
}
nscoord
GetVerticalMarginBorderPadding(const nsHTMLReflowState* aReflowState)
{
nscoord result = 0;
if (!aReflowState) return result;
// zero auto margins
nsMargin margin = aReflowState->mComputedMargin;
if (NS_AUTOMARGIN == margin.top)
margin.top = 0;
if (NS_AUTOMARGIN == margin.bottom)
margin.bottom = 0;
result += margin.top + margin.bottom;
result += aReflowState->mComputedBorderPadding.top +
aReflowState->mComputedBorderPadding.bottom;
return result;
}
/* Get the height based on the viewport of the containing block specified
* in aReflowState when the containing block has mComputedHeight == NS_AUTOHEIGHT
* and it is the body.
*/
nscoord
CalcQuirkContainingBlockHeight(const nsHTMLReflowState& aReflowState)
{
nsHTMLReflowState* firstBlockRS = nsnull; // a candidate for body frame
nsHTMLReflowState* firstAreaRS = nsnull; // a candidate for html frame
nscoord result = 0;
const nsHTMLReflowState* rs = &aReflowState;
for (; rs; rs = (nsHTMLReflowState *)(rs->parentReflowState)) {
nsCOMPtr<nsIAtom> frameType;
rs->frame->GetFrameType(getter_AddRefs(frameType));
// if the ancestor is auto height then skip it and continue up if it
// is the first block/area frame and possibly the body/html
if (nsLayoutAtoms::blockFrame == frameType.get()) {
if (!firstBlockRS) {
firstBlockRS = (nsHTMLReflowState*)rs;
if (NS_AUTOHEIGHT == rs->mComputedHeight) continue;
}
else break;
}
else if (nsLayoutAtoms::areaFrame == frameType.get()) {
if (!firstAreaRS) {
firstAreaRS = (nsHTMLReflowState*)rs;
if (NS_AUTOHEIGHT == rs->mComputedHeight) continue;
}
else break;
}
else if (nsLayoutAtoms::canvasFrame != frameType.get()) {
break;
}
// the ancestor has a computed height, it is the percent base
result = rs->mComputedHeight;
// if we got to the canvas frame, then subtract out
// margin/border/padding for the BODY and HTML elements
if (nsLayoutAtoms::canvasFrame == frameType.get()) {
result -= GetVerticalMarginBorderPadding(firstBlockRS);
result -= GetVerticalMarginBorderPadding(firstAreaRS);
}
// if we got to the html frame, then subtract out
// margin/border/padding for the BODY element
else if (nsLayoutAtoms::areaFrame == frameType.get()) {
// make sure it is the body
nsCOMPtr<nsIAtom> fType;
rs->parentReflowState->frame->GetFrameType(getter_AddRefs(fType));
if (nsLayoutAtoms::canvasFrame == fType.get()) {
result -= GetVerticalMarginBorderPadding(firstBlockRS);
}
}
break;
}
return result;
}
// Called by InitConstraints() to compute the containing block rectangle for
// the element. Handles the special logic for absolutely positioned elements
void
nsHTMLReflowState::ComputeContainingBlockRectangle(const nsHTMLReflowState* aContainingBlockRS,
nscoord& aContainingBlockWidth,
nscoord& aContainingBlockHeight)
nsHTMLReflowState::ComputeContainingBlockRectangle(nsIPresContext* aPresContext,
const nsHTMLReflowState* aContainingBlockRS,
nscoord& aContainingBlockWidth,
nscoord& aContainingBlockHeight)
{
// Unless the element is absolutely positioned, the containing block is
// formed by the content edge of the nearest block-level ancestor
@ -1339,6 +1417,19 @@ nsHTMLReflowState::ComputeContainingBlockRectangle(const nsHTMLReflowState* aCon
if (NS_UNCONSTRAINEDSIZE == availableWidth) {
aContainingBlockWidth = NS_UNCONSTRAINEDSIZE;
}
// a table in quirks mode gets a containing block based on the viewport (less
// body margins, border, padding) if the table is a child of the body.
if (NS_AUTOHEIGHT == aContainingBlockHeight) {
nsCOMPtr<nsIAtom> fType;
frame->GetFrameType(getter_AddRefs(fType));
if (nsLayoutAtoms::tableFrame == fType.get()) {
nsCompatibility mode;
aPresContext->GetCompatibilityMode(&mode);
if (eCompatibility_NavQuirks == mode) {
aContainingBlockHeight = CalcQuirkContainingBlockHeight(*aContainingBlockRS);
}
}
}
}
}
@ -1370,7 +1461,8 @@ nsHTMLReflowState::InitConstraints(nsIPresContext* aPresContext,
// If we weren't given a containing block width and height, then
// compute one
if (aContainingBlockWidth == -1) {
ComputeContainingBlockRectangle(cbrs, aContainingBlockWidth, aContainingBlockHeight);
ComputeContainingBlockRectangle(aPresContext, cbrs, aContainingBlockWidth,
aContainingBlockHeight);
}
// See if the element is relatively positioned
@ -1517,10 +1609,9 @@ nsHTMLReflowState::InitConstraints(nsIPresContext* aPresContext,
mComputedWidth = NS_UNCONSTRAINEDSIZE;
} else if (NS_STYLE_DISPLAY_TABLE == mStyleDisplay->mDisplay) {
// It's a table. The CSS spec says the computed width should be
// 0 so set it to 0. The table code will just chose whatever width
// it wants
mComputedWidth = 0;
// It's an outer table because an inner table is not positioned
// shrink wrap its width since the outer table is anonymous
mComputedWidth = NS_SHRINKWRAPWIDTH;
} else {
// The CSS2 spec says the computed width should be 0; however, that's
@ -1704,9 +1795,24 @@ nsHTMLReflowState::ComputeBlockBoxData(nsIPresContext* aPresContext,
}
} else {
mComputedWidth = availableWidth - mComputedMargin.left -
mComputedMargin.right - mComputedBorderPadding.left -
mComputedBorderPadding.right;
// tables act like replaced elements regarding mComputedWidth
nsCOMPtr<nsIAtom> fType;
frame->GetFrameType(getter_AddRefs(fType));
if (nsLayoutAtoms::tableOuterFrame == fType.get()) {
mComputedWidth = NS_SHRINKWRAPWIDTH;
} else if (nsLayoutAtoms::tableFrame == fType.get()) {
mComputedWidth = NS_SHRINKWRAPWIDTH;
if (eStyleUnit_Auto == mStyleSpacing->mMargin.GetLeftUnit()) {
mComputedMargin.left = NS_AUTOMARGIN;
}
if (eStyleUnit_Auto == mStyleSpacing->mMargin.GetRightUnit()) {
mComputedMargin.right = NS_AUTOMARGIN;
}
} else {
mComputedWidth = availableWidth - mComputedMargin.left -
mComputedMargin.right - mComputedBorderPadding.left -
mComputedBorderPadding.right;
}
// Take into account any min and max values
if (mComputedWidth > mComputedMaxWidth) {

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

@ -179,6 +179,7 @@ th {
caption {
text-align: center;
display: table-caption;
box-sizing: border-box;
}
tr {
display: table-row;
@ -1084,6 +1085,35 @@ option[disabled] {
background-color:rgb(204,204,204) !important;
}
select option[disabled] {
color:rgb(153,153,153);
background-color:rgb(204,204,204);
}
select[size] option[-moz-option-selected] {
color:white;
background-color:rgb(51,51,102);
}
select[size] option[-moz-option-selected-focus] {
color:white;
background-color:rgb(51,51,102);
}
select[size][disabled] option[-moz-option-selected] {
color:rgb(153,153,153);
background-color:rgb(204,204,204);
}
select[size="1"] option[-moz-option-selected] {
color:white;
background-color:rgb(51,51,102);
}
select[size="1"] option[disabled][-moz-option-selected] {
color:rgb(153,153,153);
background-color:rgb(204,204,204);
}
optgroup {
font-family: sans-serif;
font-size: small;
@ -1290,14 +1320,22 @@ sourcetext { /* XXX should not be in HTML namespace */
:table {
display: table;
border-style: inherit;
border-color: inherit;
margin-top: inherit;
margin-bottom: inherit;
background: inherit;
border-spacing: 2px;
border-collapse: separate;
margin-top: 0;
margin-bottom: 0;
box-sizing: border-box;
}
:table-outer {
display: table;
margin: 0px;
border: 0px;
padding: 0px;
float: inherit;
position: inherit;
}
:table-cell {
display: table-cell;
}
@ -1310,10 +1348,6 @@ sourcetext { /* XXX should not be in HTML namespace */
display: table-column-group;
}
:table-outer {
display: table;
}
:table-row {
display: table-row;
}

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

@ -360,9 +360,6 @@ struct nsPseudoFrames {
// the frame type of the most descendant pseudo frame, no AddRef
nsIAtom* mLowestType;
// col groups are handled specially so if there is both a pseudo
// row group and col group, content order needs to be preserved
PRBool mColGroupBeforeRowGroup;
nsPseudoFrames();
nsPseudoFrames& operator=(const nsPseudoFrames& aOther);
@ -389,8 +386,7 @@ nsPseudoFrameData::Reset()
nsPseudoFrames::nsPseudoFrames()
: mTableOuter(), mTableInner(), mRowGroup(), mColGroup(),
mRow(), mCellOuter(), mCellInner(), mLowestType(nsnull),
mColGroupBeforeRowGroup(PR_FALSE)
mRow(), mCellOuter(), mCellInner(), mLowestType(nsnull)
{}
nsPseudoFrames& nsPseudoFrames::operator=(const nsPseudoFrames& aOther)
@ -403,7 +399,6 @@ nsPseudoFrames& nsPseudoFrames::operator=(const nsPseudoFrames& aOther)
mCellOuter = aOther.mCellOuter;
mCellInner = aOther.mCellInner;
mLowestType = aOther.mLowestType;
mColGroupBeforeRowGroup = aOther.mColGroupBeforeRowGroup;
return *this;
}
@ -422,7 +417,6 @@ nsPseudoFrames::Reset(nsPseudoFrames* aSave)
mCellOuter.Reset();
mCellInner.Reset();
mLowestType = nsnull;
mColGroupBeforeRowGroup = PR_FALSE;
}
// -----------------------------------------------------------
@ -699,15 +693,24 @@ nsMathMLmtableCreator::CreateTableCellInnerFrame(nsIFrame** aNewFrame)
// -----------------------------------------------------------
// return the child list that aFrame belongs on. does not ADDREF
nsIAtom* GetChildListFor(const nsIFrame* aFrame)
PRBool GetCaptionAdjustedParent(nsIFrame* aParentFrame,
const nsIFrame* aChildFrame,
nsIFrame** aAdjParentFrame)
{
nsIAtom* childList = nsnull;
nsCOMPtr<nsIAtom> frameType;
aFrame->GetFrameType(getter_AddRefs(frameType));
if (nsLayoutAtoms::tableCaptionFrame == frameType.get()) {
childList = nsLayoutAtoms::captionList;
*aAdjParentFrame = aParentFrame;
PRBool haveCaption = PR_FALSE;
nsCOMPtr<nsIAtom> childFrameType;
aChildFrame->GetFrameType(getter_AddRefs(childFrameType));
if (nsLayoutAtoms::tableCaptionFrame == childFrameType.get()) {
haveCaption = PR_TRUE;
nsCOMPtr<nsIAtom> parentFrameType;
aParentFrame->GetFrameType(getter_AddRefs(parentFrameType));
if (nsLayoutAtoms::tableFrame == parentFrameType.get()) {
aParentFrame->GetParent(aAdjParentFrame);
}
}
return childList;
return haveCaption;
}
nsCSSFrameConstructor::nsCSSFrameConstructor(void)
@ -1803,7 +1806,8 @@ nsCSSFrameConstructor::CreatePseudoTableFrame(nsIPresShell* aPresShel
parentFrame->GetStyleContext(getter_AddRefs(parentStyle));
parentFrame->GetContent(getter_AddRefs(parentContent));
aPresContext->ResolvePseudoStyleContextFor(parentContent, nsHTMLAtoms::tableOuterPseudo,
// create the SC for the inner table which will be the parent of the outer table's SC
aPresContext->ResolvePseudoStyleContextFor(parentContent, nsHTMLAtoms::tablePseudo,
parentStyle, PR_FALSE,
getter_AddRefs(childStyle));
@ -1910,15 +1914,13 @@ nsCSSFrameConstructor::CreatePseudoColGroupFrame(nsIPresShell* aPresS
parentFrame, childStyle.get(), aTableCreator,
PR_TRUE, items, pseudo.mFrame, pseudoParent);
if (NS_FAILED(rv)) return rv;
((nsTableColGroupFrame*)pseudo.mFrame)->SetType(eColGroupAnonymousCol);
// set pseudo data for the parent
if (aState.mPseudoFrames.mTableInner.mFrame) {
aState.mPseudoFrames.mTableInner.mChildList.AddChild(pseudo.mFrame);
}
if (!aState.mPseudoFrames.mRowGroup.mFrame) {
aState.mPseudoFrames.mColGroupBeforeRowGroup = PR_TRUE;
}
return rv;
}
@ -2322,6 +2324,17 @@ nsCSSFrameConstructor::GetParentFrame(nsIPresShell* aPresShell,
}
void
FixUpOuterTableFloat(nsIStyleContext* aOuterSC,
nsIStyleContext* aInnerSC)
{
nsStyleDisplay* outerStyleDisplay = (nsStyleDisplay*)aOuterSC->GetMutableStyleData(eStyleStruct_Display);
nsStyleDisplay* innerStyleDisplay = (nsStyleDisplay*)aInnerSC->GetStyleData(eStyleStruct_Display);
if (outerStyleDisplay->mFloats != innerStyleDisplay->mFloats) {
outerStyleDisplay->mFloats = innerStyleDisplay->mFloats;
}
}
// Construct the outer, inner table frames and the children frames for the table.
nsresult
nsCSSFrameConstructor::ConstructTableFrame(nsIPresShell* aPresShell,
@ -2357,12 +2370,19 @@ nsCSSFrameConstructor::ConstructTableFrame(nsIPresShell* aPresShell,
}
}
// create the pseudo SC for the outer table as a child of the inner SC
nsCOMPtr<nsIStyleContext> outerStyleContext;
aPresContext->ResolvePseudoStyleContextFor(aContent, nsHTMLAtoms::tableOuterPseudo,
aStyleContext, PR_FALSE,
getter_AddRefs(outerStyleContext));
FixUpOuterTableFloat(outerStyleContext, aStyleContext);
// Init the table outer frame and see if we need to create a view, e.g.
// the frame is absolutely positioned
InitAndRestoreFrame(aPresContext, aState, aContent,
parentFrame, aStyleContext, nsnull, aNewOuterFrame);
parentFrame, outerStyleContext, nsnull, aNewOuterFrame);
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, aNewOuterFrame,
aStyleContext, PR_FALSE);
outerStyleContext, PR_FALSE);
// Create the inner table frame
aTableCreator.CreateTableFrame(&aNewInnerFrame);
@ -2787,34 +2807,22 @@ nsCSSFrameConstructor::MustGeneratePseudoParent(nsIPresContext* aPresContext,
return !IsOnlyWhiteSpace(aContent);
}
if ( (nsHTMLAtoms::img == aTag) ||
(nsHTMLAtoms::hr == aTag) ||
(nsHTMLAtoms::br == aTag) ||
(nsHTMLAtoms::wbr == aTag) ||
(nsHTMLAtoms::input == aTag) ||
(nsHTMLAtoms::textarea == aTag) ||
(nsHTMLAtoms::select == aTag) ||
(nsHTMLAtoms::applet == aTag) ||
(nsHTMLAtoms::embed == aTag) ||
(nsHTMLAtoms::fieldset == aTag) ||
(nsHTMLAtoms::legend == aTag) ||
(nsHTMLAtoms::object == aTag) ||
(nsHTMLAtoms::iframe == aTag) ||
(nsHTMLAtoms::spacer == aTag) ||
(nsHTMLAtoms::button == aTag) ||
(nsHTMLAtoms::label == aTag) ) {
return PR_TRUE;
// exclude tags
if ( (nsLayoutAtoms::commentTagName == aTag) ||
(nsHTMLAtoms::form == aTag) ) {
return PR_FALSE;
}
// MathML Mod - DJF
// XXX DJF - when should pseudo frames be constructed for MathML?
#ifdef MOZ_MATHML
// XXX should pseudo frames be created in this case?
if ( (nsMathMLAtoms::math == aTag) ) {
if ( (nsMathMLAtoms::math == aTag) ) {
return PR_TRUE;
}
else {
return PR_FALSE;
}
#endif
// we should check for display type as well - later
return PR_FALSE;
}
@ -4570,16 +4578,15 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsIPresShell* aPresShell,
const nsStyleDisplay* styleDisplay;
newFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) styleDisplay);
nsIFrame * areaFrame;
//NS_NewBlockFrame(shell, &areaFrame, flags);
NS_NewAreaFrame(shell, &areaFrame, flags | NS_BLOCK_SHRINK_WRAP);// | NS_BLOCK_MARGIN_ROOT);
nsIFrame * blkFrame;
NS_NewBlockFrame(shell, &blkFrame, flags);
// Resolve style and initialize the frame
nsIStyleContext* styleContext;
aPresContext->ResolvePseudoStyleContextFor(aContent, nsHTMLAtoms::fieldsetContentPseudo,
aStyleContext, PR_FALSE, &styleContext);
InitAndRestoreFrame(aPresContext, aState, aContent,
newFrame, styleContext, nsnull, areaFrame);
newFrame, styleContext, nsnull, blkFrame);
NS_RELEASE(styleContext);
@ -4589,7 +4596,7 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsIPresShell* aPresShell,
HaveSpecialBlockStyle(aPresContext, aContent, aStyleContext,
&haveFirstLetterStyle, &haveFirstLineStyle);
nsFrameConstructorSaveState floaterSaveState;
aState.PushFloaterContainingBlock(areaFrame, floaterSaveState,
aState.PushFloaterContainingBlock(blkFrame, floaterSaveState,
haveFirstLetterStyle,
haveFirstLineStyle);
@ -4602,10 +4609,10 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsIPresShell* aPresShell,
if (isPositionedContainingBlock) {
// The area frame becomes a container for child frames that are
// absolutely positioned
aState.PushAbsoluteContainingBlock(areaFrame, absoluteSaveState);
aState.PushAbsoluteContainingBlock(blkFrame, absoluteSaveState);
}
ProcessChildren(aPresShell, aPresContext, aState, aContent, areaFrame, PR_FALSE,
ProcessChildren(aPresShell, aPresContext, aState, aContent, blkFrame, PR_FALSE,
childItems, PR_TRUE);
static NS_DEFINE_IID(kLegendFrameCID, NS_LEGEND_FRAME_CID);
@ -4619,7 +4626,7 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsIPresShell* aPresShell,
nsIFrame * nxt;
legendFrame->GetNextSibling(&nxt);
previous->SetNextSibling(nxt);
areaFrame->SetNextSibling(legendFrame);
blkFrame->SetNextSibling(legendFrame);
legendFrame->SetParent(newFrame);
legendFrame->SetNextSibling(nsnull);
break;
@ -4627,7 +4634,7 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsIPresShell* aPresShell,
nsIFrame * nxt;
legendFrame->GetNextSibling(&nxt);
childItems.childList = nxt;
areaFrame->SetNextSibling(legendFrame);
blkFrame->SetNextSibling(legendFrame);
legendFrame->SetParent(newFrame);
legendFrame->SetNextSibling(nsnull);
break;
@ -4638,21 +4645,21 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsIPresShell* aPresShell,
}
// Set the scrolled frame's initial child lists
areaFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
blkFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
if (isPositionedContainingBlock && aState.mAbsoluteItems.childList) {
areaFrame->SetInitialChildList(aPresContext,
blkFrame->SetInitialChildList(aPresContext,
nsLayoutAtoms::absoluteList,
aState.mAbsoluteItems.childList);
}
if (aState.mFloatedItems.childList) {
areaFrame->SetInitialChildList(aPresContext,
blkFrame->SetInitialChildList(aPresContext,
nsLayoutAtoms::floaterList,
aState.mFloatedItems.childList);
}
// Set the scroll frame's initial child list
newFrame->SetInitialChildList(aPresContext, nsnull, areaFrame);
newFrame->SetInitialChildList(aPresContext, nsnull, blkFrame);
// our new frame retured is the top frame which is the list frame.
aNewFrame = newFrame;
@ -5154,11 +5161,11 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsIPresShell* aPresShell,
nsFrameConstructorState& aState,
nsIContent* aParent,
nsIDocument* aDocument,
nsIFrame* aParentFrame,
nsIFrame* aNewFrame,
nsFrameItems& aChildItems)
{
nsCOMPtr<nsIAnonymousContentCreator> creator(do_QueryInterface(aParentFrame));
nsCOMPtr<nsIAnonymousContentCreator> creator(do_QueryInterface(aNewFrame));
if (!creator)
return NS_OK;
@ -5182,14 +5189,8 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsIPresShell* aPresShell,
content->SetParent(aParent);
content->SetDocument(aDocument, PR_TRUE);
nsIFrame * newFrame = nsnull;
nsresult rv = creator->CreateFrameFor(aPresContext, content, &newFrame);
if (NS_SUCCEEDED(rv) && newFrame != nsnull) {
aChildItems.AddChild(newFrame);
} else {
// create the frame and attach it to our frame
ConstructFrame(aPresShell, aPresContext, aState, content, aParentFrame, aChildItems);
}
// create the frame and attach it to our frame
ConstructFrame(aPresShell, aPresContext, aState, content, aNewFrame, aChildItems);
}
return NS_OK;
@ -7515,8 +7516,16 @@ nsCSSFrameConstructor::AppendFrames(nsIPresContext* aPresContext,
}
else {
// Append the frames to the end of the parent's child list
rv = aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
GetChildListFor(aFrameList), aFrameList);
// check for a table caption which goes on an additional child list with a different parent
nsIFrame* outerTableFrame;
if (GetCaptionAdjustedParent(aParentFrame, aFrameList, &outerTableFrame)) {
rv = aFrameManager->AppendFrames(aPresContext, *aPresShell, outerTableFrame,
nsLayoutAtoms::captionList, aFrameList);
}
else {
rv = aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
nsnull, aFrameList);
}
}
NS_IF_RELEASE(parentType);
@ -8296,11 +8305,15 @@ nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext,
}
}
// check for a table caption which goes on an additional child list
nsIAtom* childList = GetChildListFor(newFrame);
rv = state.mFrameManager->InsertFrames(aPresContext, *shell,
parentFrame,
childList, prevSibling,
newFrame);
nsIFrame* outerTableFrame;
if (GetCaptionAdjustedParent(parentFrame, newFrame, &outerTableFrame)) {
rv = state.mFrameManager->AppendFrames(aPresContext, *shell, outerTableFrame,
nsLayoutAtoms::captionList, newFrame);
}
else {
rv = state.mFrameManager->InsertFrames(aPresContext, *shell, parentFrame,
nsnull, prevSibling, newFrame);
}
}
// If there are new absolutely positioned child frames, then notify
@ -8791,9 +8804,16 @@ nsCSSFrameConstructor::ContentRemoved(nsIPresContext* aPresContext,
} else {
// Notify the parent frame that it should delete the frame
nsIAtom* childList = GetChildListFor(childFrame);
rv = frameManager->RemoveFrame(aPresContext, *shell, parentFrame,
childList, childFrame);
// check for a table caption which goes on an additional child list with a different parent
nsIFrame* outerTableFrame;
if (GetCaptionAdjustedParent(parentFrame, childFrame, &outerTableFrame)) {
rv = frameManager->RemoveFrame(aPresContext, *shell, outerTableFrame,
nsLayoutAtoms::captionList, childFrame);
}
else {
rv = frameManager->RemoveFrame(aPresContext, *shell, parentFrame,
nsnull, childFrame);
}
}
}

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

@ -855,8 +855,8 @@ void nsCellMap::InsertCells(nsTableCellMap& aMap,
PRInt32 startColIndex;
for (startColIndex = aColIndexBefore + 1; startColIndex < numCols; startColIndex++) {
CellData* data = GetMapCellAt(aMap, aRowIndex, startColIndex, PR_TRUE);
if (data && data->IsOrig()) {
break; // we found the col index
if (!data || data->IsOrig()) { // stop unless it is a span
break;
}
}
@ -904,19 +904,20 @@ void
nsCellMap::ExpandWithRows(nsIPresContext* aPresContext,
nsTableCellMap& aMap,
nsVoidArray& aRowFrames,
PRInt32 aStartRowIndex)
PRInt32 aStartRowIndexIn)
{
PRInt32 startRowIndex = (aStartRowIndexIn >= 0) ? aStartRowIndexIn : 0;
PRInt32 numNewRows = aRowFrames.Count();
PRInt32 endRowIndex = aStartRowIndex + numNewRows - 1;
PRInt32 endRowIndex = startRowIndex + numNewRows - 1;
// create the new rows first
if (!Grow(aMap, numNewRows, aStartRowIndex)) {
if (!Grow(aMap, numNewRows, startRowIndex)) {
return;
}
mRowCount += numNewRows;
PRInt32 newRowIndex = 0;
for (PRInt32 rowX = aStartRowIndex; rowX <= endRowIndex; rowX++) {
for (PRInt32 rowX = startRowIndex; rowX <= endRowIndex; rowX++) {
nsTableRowFrame* rFrame = (nsTableRowFrame *)aRowFrames.ElementAt(newRowIndex);
// append cells
nsIFrame* cFrame = nsnull;

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

@ -135,6 +135,16 @@ struct InnerTableReflowState {
}
};
const nsHTMLReflowState*
GetGrandParentReflowState(const nsHTMLReflowState& aInnerRS)
{
const nsHTMLReflowState* rs = nsnull;
if (aInnerRS.parentReflowState) {
rs = aInnerRS.parentReflowState->parentReflowState;
}
return rs;
}
NS_IMETHODIMP
nsTableFrame::GetFrameType(nsIAtom** aType) const
@ -1461,37 +1471,30 @@ nsTableFrame::SetColumnDimensions(nsIPresContext* aPresContext,
{
nscoord colHeight = aHeight -= aBorderPadding.top + aBorderPadding.bottom;
nscoord cellSpacingX = GetCellSpacingX();
nscoord halfCellSpacingX = NSToCoordRound(((float)cellSpacingX) / (float)2);
nsIFrame* colGroupFrame = mColGroups.FirstChild();
PRInt32 colX = 0;
nsPoint colGroupOrigin(aBorderPadding.left, aBorderPadding.top);
nsPoint colGroupOrigin(aBorderPadding.left + cellSpacingX, aBorderPadding.top);
PRInt32 numCols = GetColCount();
while (nsnull != colGroupFrame) {
nscoord colGroupWidth = 0;
nsIFrame* colFrame = nsnull;
colGroupFrame->FirstChild(aPresContext, nsnull, &colFrame);
nsPoint colOrigin(0, 0);
nsPoint colOrigin(0,0);
while (nsnull != colFrame) {
const nsStyleDisplay* colDisplay;
colFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)colDisplay));
if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay) {
NS_ASSERTION(colX < numCols, "invalid number of columns");
nscoord colWidth = mColumnWidths[colX];
if (numCols == 1) {
colWidth += cellSpacingX + cellSpacingX;
}
else if ((0 == colX) || (numCols - 1 == colX)) {
colWidth += cellSpacingX + halfCellSpacingX;
}
else if (GetNumCellsOriginatingInCol(colX) > 0) {
colWidth += cellSpacingX;
}
colGroupWidth += colWidth;
nsRect colRect(colOrigin.x, colOrigin.y, colWidth, colHeight);
colFrame->SetRect(aPresContext, colRect);
colOrigin.x += colWidth;
colOrigin.x += colWidth + cellSpacingX;
colGroupWidth += colWidth;
if (numCols - 1 != colX) {
colGroupWidth += cellSpacingX;
}
colX++;
}
colFrame->GetNextSibling(&colFrame);
@ -1604,9 +1607,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
aDesiredSize.maxElementSize = nsnull;
}
rv = ResizeReflowPass2(aPresContext, aDesiredSize, reflowState, aStatus);
if (NS_FAILED(rv)) {
return rv;
}
if (NS_FAILED(rv)) return rv;
aDesiredSize.width = PR_MIN(aDesiredSize.width, pass1Width);
@ -1704,7 +1705,7 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext,
NS_ASSERTION(nsnull==mPrevInFlow, "illegal call, cannot call pass 1 on a continuing frame.");
NS_ASSERTION(nsnull != mContent, "null content");
nsresult rv=NS_OK;
nsresult rv = NS_OK;
// set out params
aStatus = NS_FRAME_COMPLETE;
@ -1713,23 +1714,22 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext,
nsSize kidMaxSize(0,0);
nsHTMLReflowMetrics kidSize(&kidMaxSize);
nscoord y = 0;
nscoord cellSpacingY = GetCellSpacingY();
// Compute the insets (sum of border and padding)
// XXX: since this is pass1 reflow and where we place the rowgroup frames is irrelevant, insets are probably a waste
if (IsAutoLayout(&aReflowState))
{
if (IsAutoLayout(&aReflowState)) {
nsIFrame* kidFrame = aStartingFrame;
if (nsnull==kidFrame)
kidFrame=mFrames.FirstChild();
for ( ; nsnull != kidFrame; kidFrame->GetNextSibling(&kidFrame))
{
kidFrame = mFrames.FirstChild();
for ( ; nsnull != kidFrame; kidFrame->GetNextSibling(&kidFrame)) {
const nsStyleDisplay *childDisplay;
kidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
if ((NS_STYLE_DISPLAY_TABLE_HEADER_GROUP != childDisplay->mDisplay) &&
(NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP != childDisplay->mDisplay) &&
(NS_STYLE_DISPLAY_TABLE_ROW_GROUP != childDisplay->mDisplay) )
{ // it's an unknown frame type, give it a generic reflow and ignore the results
(NS_STYLE_DISPLAY_TABLE_ROW_GROUP != childDisplay->mDisplay) ) {
// it's an unknown frame type, give it a generic reflow and ignore the results
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
availSize, aReason);
// rv intentionally not set here
@ -1738,7 +1738,7 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext,
continue;
}
// Get the row group's border padding
// Get the table's border padding
nsMargin borderPadding;
GetTableBorderForRowGroup(GetRowGroupFrameFor(kidFrame, childDisplay), borderPadding);
const nsStyleSpacing* tableSpacing;
@ -1746,6 +1746,11 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext,
nsMargin padding;
tableSpacing->GetPadding(padding);
borderPadding += padding;
y += cellSpacingY;
if (kidFrame == mFrames.FirstChild()) {
y += borderPadding.top;
}
// Reflow the child
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
@ -1754,12 +1759,12 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext,
// isTopOfPage reflow state flag, because we're dealing with an unconstrained
// height and it isn't an issue...
ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, borderPadding.left,
borderPadding.top + y, 0, aStatus);
y, 0, aStatus);
// Place the child since some of its content fit in us.
FinishReflowChild(kidFrame, aPresContext, kidSize, borderPadding.left,
borderPadding.top + y, 0);
if (NS_UNCONSTRAINEDSIZE==kidSize.height)
if (NS_UNCONSTRAINEDSIZE == kidSize.height)
// XXX This is very suspicious. Why would a row group frame want
// such a large height?
y = NS_UNCONSTRAINEDSIZE;
@ -1777,16 +1782,14 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext,
// up all of our available space (or needs us to split).
break;
}
if (PR_FALSE==aDoSiblingFrames)
if (!aDoSiblingFrames)
break;
}
// if required, give the colgroups their initial reflows
if (PR_TRUE==aDoSiblingFrames)
{
if (aDoSiblingFrames) {
kidFrame=mColGroups.FirstChild();
for ( ; nsnull != kidFrame; kidFrame->GetNextSibling(&kidFrame))
{
for ( ; nsnull != kidFrame; kidFrame->GetNextSibling(&kidFrame)) {
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
availSize, aReason);
ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, 0, 0, 0, aStatus);
@ -1946,6 +1949,7 @@ NS_METHOD nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresContext,
borderPadding += aReflowState.mComputedPadding;
InnerTableReflowState state(aPresContext, aReflowState, borderPadding);
state.y = borderPadding.top; // XXX this should be set in the constructor, but incremental code is affected.
// now that we've computed the column width information, reflow all children
#ifdef NS_DEBUG
@ -1958,7 +1962,7 @@ NS_METHOD nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresContext,
// Reflow the existing frames
if (mFrames.NotEmpty()) {
ComputePercentBasisForRows(aReflowState);
ComputePercentBasisForRows(aPresContext, aReflowState);
rv = ReflowMappedChildren(aPresContext, aDesiredSize, state, aStatus);
}
@ -1973,7 +1977,7 @@ NS_METHOD nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresContext,
// Return our size and our status
aDesiredSize.width = ComputeDesiredWidth(aReflowState);
nscoord defaultHeight = state.y + borderPadding.top + borderPadding.bottom;
nscoord defaultHeight = state.y + GetCellSpacingY() + borderPadding.bottom;
aDesiredSize.height = ComputeDesiredHeight(aPresContext, aReflowState, defaultHeight);
AdjustForCollapsingRows(aPresContext, aDesiredSize.height);
@ -1994,16 +1998,15 @@ NS_METHOD nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresContext,
}
void nsTableFrame::ComputePercentBasisForRows(const nsHTMLReflowState& aReflowState)
void nsTableFrame::ComputePercentBasisForRows(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState)
{
nscoord height = CalcBorderBoxHeight(aReflowState, PR_TRUE);
nscoord height = CalcBorderBoxHeight(aPresContext, aReflowState);
if ((height > 0) && (height != NS_UNCONSTRAINEDSIZE)) {
// exclude our border and padding
nsMargin borderPadding = aReflowState.mComputedBorderPadding;
height -= borderPadding.top + borderPadding.bottom;
// exclude cell spacing for all rows
height -= (1 + GetRowCount()) * GetCellSpacingY();
height = PR_MAX(0, height);
}
else {
@ -2786,10 +2789,9 @@ nscoord nsTableFrame::ComputeDesiredWidth(const nsHTMLReflowState& aReflowState)
nscoord desiredWidth = aReflowState.availableWidth;
// this is the biggest hack in the world. But there's no other rational way to handle nested percent tables
const nsStylePosition* position;
PRBool isNested=IsNested(aReflowState, position);
if((eReflowReason_Initial==aReflowState.reason) &&
(PR_TRUE==isNested) && (eStyleUnit_Percent==position->mWidth.GetUnit()))
{
PRBool isNested = IsNested(aReflowState, position);
if ((eReflowReason_Initial==aReflowState.reason) &&
(isNested) && (eStyleUnit_Percent == position->mWidth.GetUnit())) {
nsITableLayoutStrategy* tableLayoutStrategy = mTableLayoutStrategy;
if (mPrevInFlow) {
// Get the table layout strategy from the first-in-flow
@ -2823,36 +2825,30 @@ void nsTableFrame::PlaceChild(nsIPresContext* aPresContext,
aReflowState.availSize.height -= aDesiredSize.height;
}
// If this is a footer row group, remember it
const nsStyleDisplay *childDisplay;
aKidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
// We only allow a single footer frame, and the footer frame must occur before
// any body section row groups
if ((NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == childDisplay->mDisplay) &&
!aReflowState.footerFrame && !aReflowState.firstBodySection)
{
!aReflowState.footerFrame && !aReflowState.firstBodySection) {
aReflowState.footerFrame = aKidFrame;
}
else if (aReflowState.footerFrame)
{
// Place the row group frame
nsSize footerSize;
else if (aReflowState.footerFrame) {
// put the non footer where the footer was
nsPoint origin;
aKidFrame->GetOrigin(origin);
aReflowState.footerFrame->GetSize(footerSize);
origin.y -= footerSize.height;
aKidFrame->MoveTo(aPresContext, origin.x, origin.y);
// Move the footer below the body row group frame
aReflowState.footerFrame->GetOrigin(origin);
origin.y += aDesiredSize.height;
aKidFrame->MoveTo(aPresContext, origin.x, origin.y);
// put the footer below the non footer
nsSize size;
aReflowState.footerFrame->GetSize(size);
origin.y = aReflowState.y - size.height;
aReflowState.footerFrame->MoveTo(aPresContext, origin.x, origin.y);
}
//XXX: this should call into layout strategy to get the width field
if (nsnull != aMaxElementSize)
{
if (nsnull != aMaxElementSize) {
const nsStyleSpacing* tableSpacing;
GetStyleData(eStyleStruct_Spacing , ((const nsStyleStruct *&)tableSpacing));
nsMargin borderPadding;
@ -2865,6 +2861,39 @@ void nsTableFrame::PlaceChild(nsIPresContext* aPresContext,
}
}
void
nsTableFrame::GetSectionInfo(nsFrameList& aKidFrames,
PRBool& aHaveTHead,
PRBool& aHaveTBody,
PRBool& aHaveTFoot,
PRBool& aTHeadBeforeTFoot)
{
aHaveTHead = aHaveTBody = aHaveTFoot = PR_FALSE;
aTHeadBeforeTFoot = PR_TRUE;
nsIFrame* kidFrame = aKidFrames.FirstChild();
while (kidFrame) {
const nsStyleDisplay* kidDisplay;
kidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)kidDisplay));
if (IsRowGroup(kidDisplay->mDisplay)) {
switch(kidDisplay->mDisplay) {
case NS_STYLE_DISPLAY_TABLE_HEADER_GROUP:
aHaveTHead = PR_TRUE;
break;
case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP:
aHaveTFoot = PR_TRUE;
if (!aHaveTHead) {
aTHeadBeforeTFoot = PR_FALSE;
}
break;
default:
aHaveTBody = PR_TRUE;
}
}
kidFrame->GetNextSibling(&kidFrame);
}
}
/**
* Reflow the frames we've already created
*
@ -2873,22 +2902,21 @@ void nsTableFrame::PlaceChild(nsIPresContext* aPresContext,
* @return true if we successfully reflowed all the mapped children and false
* otherwise, e.g. we pushed children to the next in flow
*/
NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus)
nsReflowStatus& aStatus)
{
NS_PRECONDITION(mFrames.NotEmpty(), "no children");
PRInt32 childCount = 0;
nsIFrame* prevKidFrame = nsnull;
nsSize kidMaxElementSize(0,0);
nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ? &kidMaxElementSize : nsnull;
nsresult rv = NS_OK;
nscoord cellSpacingY = GetCellSpacingY();
nsReflowReason reason;
if (!IsAutoLayout(&aReflowState.reflowState))
{
if (!IsAutoLayout(&aReflowState.reflowState)) {
reason = aReflowState.reflowState.reason;
if (eReflowReason_Incremental==reason) {
reason = eReflowReason_Resize;
@ -2898,22 +2926,26 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
}
}
}
else
else {
reason = eReflowReason_Resize;
}
// determine what section elements are present
PRBool haveTHead, haveTBody, haveTFoot, tHeadBeforeTFoot;
GetSectionInfo(mFrames, haveTHead, haveTBody, haveTFoot, tHeadBeforeTFoot);
// this never passes reflows down to colgroups
for (nsIFrame* kidFrame = mFrames.FirstChild(); nsnull != kidFrame; )
{
nsIFrame* kidFrame = mFrames.FirstChild();
while (kidFrame) {
nsSize kidAvailSize(aReflowState.availSize);
nsHTMLReflowMetrics desiredSize(pKidMaxElementSize);
desiredSize.width=desiredSize.height=desiredSize.ascent=desiredSize.descent=0;
desiredSize.width = desiredSize.height = desiredSize.ascent = desiredSize.descent = 0;
const nsStyleDisplay *childDisplay;
const nsStyleDisplay* childDisplay;
kidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
{
if (IsRowGroup(childDisplay->mDisplay)) {
// Keep track of the first body section row group
if (nsnull == aReflowState.firstBodySection) {
if (!aReflowState.firstBodySection) {
if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay) {
aReflowState.firstBodySection = kidFrame;
}
@ -2934,12 +2966,13 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
kidReflowState.isTopOfPage = PR_FALSE;
}
aReflowState.y += cellSpacingY;
nscoord x = borderPadding.left;
nscoord y = borderPadding.top + aReflowState.y;
nscoord y = aReflowState.y;
if (RowGroupsShouldBeConstrained()) {
// Only applies to the tree widget.
nscoord tableSpecifiedHeight = CalcBorderBoxHeight(aReflowState.reflowState, PR_TRUE);
nscoord tableSpecifiedHeight = CalcBorderBoxHeight(aPresContext, aReflowState.reflowState);
if ((tableSpecifiedHeight != NS_UNCONSTRAINEDSIZE)) {
kidReflowState.availableHeight = tableSpecifiedHeight - y;
if (kidReflowState.availableHeight < 0)
@ -2961,11 +2994,10 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
}
// Place the child
if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
{
if (IsRowGroup(childDisplay->mDisplay)) {
// we don't want to adjust the maxElementSize if this is an initial reflow
// it was set by the TableLayoutStrategy and shouldn't be changed.
nsSize *requestedMaxElementSize = nsnull;
nsSize* requestedMaxElementSize = nsnull;
if (eReflowReason_Initial != aReflowState.reflowState.reason)
requestedMaxElementSize = aDesiredSize.maxElementSize;
PlaceChild(aPresContext, aReflowState, kidFrame, desiredSize,
@ -2973,7 +3005,6 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
} else {
kidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
}
childCount++;
// Remember where we just were in case we end up pushing children
prevKidFrame = kidFrame;
@ -3014,23 +3045,20 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
break;
}
}
else
{// it's an unknown frame type, give it a generic reflow and ignore the results
nsHTMLReflowState kidReflowState(aPresContext,
aReflowState.reflowState, kidFrame,
nsSize(0,0), eReflowReason_Resize);
nsHTMLReflowMetrics unusedDesiredSize(nsnull);
nsReflowStatus status;
ReflowChild(kidFrame, aPresContext, unusedDesiredSize, kidReflowState,
0, 0, 0, status);
kidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
else {// it's an unknown frame type, give it a generic reflow and ignore the results
nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState, kidFrame,
nsSize(0,0), eReflowReason_Resize);
nsHTMLReflowMetrics unusedDesiredSize(nsnull);
nsReflowStatus status;
ReflowChild(kidFrame, aPresContext, unusedDesiredSize, kidReflowState,
0, 0, 0, status);
kidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
}
// Get the next child
kidFrame->GetNextSibling(&kidFrame);
}
// Update the child count
return rv;
}
@ -3287,90 +3315,18 @@ void nsTableFrame::SetTableWidth(nsIPresContext* aPresContext,
SetRect(aPresContext, tableSize);
}
// XXX percentage based margin/border/padding
nscoord GetVerticalMarginBorderPadding(nsIFrame* aFrame,
const nsIID& aIID)
nscoord
GetVertMarginBorderPadding(const nsHTMLReflowState* aReflowState)
{
nscoord result = 0;
if (!aFrame) {
return result;
}
nsCOMPtr<nsIContent> iContent;
nsresult rv = aFrame->GetContent(getter_AddRefs(iContent));
if (NS_SUCCEEDED(rv)) {
nsIHTMLContent* htmlContent = nsnull;
rv = iContent->QueryInterface(aIID, (void **)&htmlContent);
if (htmlContent && NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIStyleContext> styleContext;
aFrame->GetStyleContext(getter_AddRefs(styleContext));
const nsStyleSpacing* spacing =
(const nsStyleSpacing*)styleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin margin(0,0,0,0);
if (spacing->GetMargin(margin)) {
result += margin.top + margin.bottom;
}
if (spacing->GetBorderPadding(margin)) {
result += margin.top + margin.bottom;
}
NS_RELEASE(htmlContent);
}
}
return result;
}
if (!aReflowState) return result;
/* Get the height of the nearest ancestor of this table which has a height other than
* auto, except when there is an ancestor which is a table and that table does not have
* a coord height. It can be the case that the nearest such ancestor is a scroll frame
* or viewport frame; this provides backwards compatibility with Nav4.X and IE.
*/
nscoord nsTableFrame::GetEffectiveContainerHeight(const nsHTMLReflowState& aReflowState)
{
nsIFrame* lastArea = nsnull;
nsIFrame* lastBlock = nsnull;
nsIAtom* frameType = nsnull;
nscoord result = -1;
const nsHTMLReflowState* rs = &aReflowState;
nsMargin margin = aReflowState->mComputedMargin;
nsTableOuterFrame::ZeroAutoMargin(margin);
result += margin.top + margin.bottom;
result += aReflowState->mComputedBorderPadding.top +
aReflowState->mComputedBorderPadding.bottom;
while (rs) {
const nsStyleDisplay* display;
rs->frame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)display);
if (NS_STYLE_DISPLAY_TABLE == display->mDisplay) {
const nsStylePosition* position;
rs->frame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)position);
nsStyleUnit unit = position->mHeight.GetUnit();
if ((eStyleUnit_Null == unit) || (eStyleUnit_Auto == unit)) {
result = 0;
break;
}
}
if (NS_AUTOHEIGHT != rs->mComputedHeight) {
result = rs->mComputedHeight;
// if we get to the scroll frame or viewport frame, then subtract out
// margin/border/padding for the HTML and BODY elements
rs->frame->GetFrameType(&frameType);
if ((nsLayoutAtoms::viewportFrame == frameType) ||
(nsLayoutAtoms::scrollFrame == frameType)) {
result -= GetVerticalMarginBorderPadding(lastArea, kIHTMLElementIID);
result -= GetVerticalMarginBorderPadding(lastBlock, kIBodyElementIID);
}
NS_IF_RELEASE(frameType);
break;
}
// keep track of the area and block frame on the way up because they could
// be the HTML and BODY elements
rs->frame->GetFrameType(&frameType);
if (nsLayoutAtoms::areaFrame == frameType) {
lastArea = rs->frame;
}
else if (nsLayoutAtoms::blockFrame == frameType) {
lastBlock = rs->frame;
}
NS_IF_RELEASE(frameType);
// XXX: evil cast!
rs = (nsHTMLReflowState *)(rs->parentReflowState);
}
NS_ASSERTION(-1 != result, "bad state: no constrained height in reflow chain");
return result;
}
@ -3405,34 +3361,33 @@ void nsTableFrame::DistributeSpaceToCells(nsIPresContext* aPresContext,
void nsTableFrame::DistributeSpaceToRows(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsIFrame* aRowGroupFrame,
const nscoord& aSumOfRowHeights,
const nscoord& aExcess,
const nsStyleTable* aTableStyle,
nscoord aSumOfRowHeights,
nscoord aExcess,
nscoord& aExcessForRowGroup,
nscoord& aRowGroupYPos)
{
// the rows in rowGroupFrame need to be expanded by rowHeightDelta[i]
// and the rowgroup itself needs to be expanded by SUM(row height deltas)
nscoord cellSpacingY = GetCellSpacingY();
nsTableRowGroupFrame* rowGroupFrame = (nsTableRowGroupFrame*)aRowGroupFrame;
nsIFrame * rowFrame = rowGroupFrame->GetFirstFrame();
nscoord y = 0;
while (nsnull!=rowFrame)
{
nsIFrame* rowFrame = rowGroupFrame->GetFirstFrame();
nscoord y = cellSpacingY;
while (rowFrame) {
const nsStyleDisplay *rowDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)rowDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == rowDisplay->mDisplay) {
DistributeSpaceToRows(aPresContext, aReflowState, rowFrame, aSumOfRowHeights,
aExcess, aTableStyle, aExcessForRowGroup, y);
aExcess, aExcessForRowGroup, y);
}
else if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay)
{ // the row needs to be expanded by the proportion this row contributed to the original height
else if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay) {
// the row needs to be expanded by the proportion this row contributed to the original height
nsRect rowRect;
rowFrame->GetRect(rowRect);
float percent = ((float)(rowRect.height)) / ((float)(aSumOfRowHeights));
nscoord excessForRow = NSToCoordRound((float)aExcess*percent);
float percent = ((float)(rowRect.height)) / (float)aSumOfRowHeights;
nscoord excessForRow = NSToCoordRound((float)aExcess * percent);
if (rowGroupFrame->RowsDesireExcessSpace()) {
nsRect newRowRect(rowRect.x, y, rowRect.width, excessForRow+rowRect.height);
nsRect newRowRect(rowRect.x, y, rowRect.width, excessForRow + rowRect.height);
rowFrame->SetRect(aPresContext, newRowRect);
if ((NS_STYLE_BORDER_COLLAPSE == GetBorderCollapseStyle()) && mBorderCollapser) {
PRInt32 rowIndex = ((nsTableRowFrame*)rowFrame)->GetRowIndex();
@ -3440,13 +3395,13 @@ void nsTableFrame::DistributeSpaceToRows(nsIPresContext* aPresContext,
mBorderCollapser->SetBorderEdgeLength(NS_SIDE_RIGHT, rowIndex, newRowRect.height);
}
// better if this were part of an overloaded row::SetRect
y += excessForRow+rowRect.height;
y += excessForRow + rowRect.height;
}
y += cellSpacingY;
aExcessForRowGroup += excessForRow;
}
else
{
else { // XXX why
nsRect rowRect;
rowFrame->GetRect(rowRect);
y += rowRect.height;
@ -3458,11 +3413,14 @@ void nsTableFrame::DistributeSpaceToRows(nsIPresContext* aPresContext,
nsRect rowGroupRect;
aRowGroupFrame->GetRect(rowGroupRect);
if (rowGroupFrame->RowGroupDesiresExcessSpace()) {
nsRect newRowGroupRect(rowGroupRect.x, aRowGroupYPos, rowGroupRect.width, aExcessForRowGroup+rowGroupRect.height);
nsRect newRowGroupRect(rowGroupRect.x, aRowGroupYPos, rowGroupRect.width,
aExcessForRowGroup + rowGroupRect.height);
aRowGroupFrame->SetRect(aPresContext, newRowGroupRect);
aRowGroupYPos += aExcessForRowGroup + rowGroupRect.height;
}
else aRowGroupYPos += rowGroupRect.height;
else {
aRowGroupYPos += rowGroupRect.height;
}
DistributeSpaceToCells(aPresContext, aReflowState, aRowGroupFrame);
}
@ -3478,7 +3436,7 @@ nscoord nsTableFrame::ComputeDesiredHeight(nsIPresContext* aPresContext
}
nscoord result = aDefaultHeight;
nscoord tableSpecifiedHeight = CalcBorderBoxHeight(aReflowState, PR_TRUE);
nscoord tableSpecifiedHeight = CalcBorderBoxHeight(aPresContext, aReflowState);
if ((tableSpecifiedHeight > 0) && (tableSpecifiedHeight != NS_UNCONSTRAINEDSIZE)) {
if (tableSpecifiedHeight > aDefaultHeight) {
result = tableSpecifiedHeight;
@ -3517,7 +3475,7 @@ nscoord nsTableFrame::ComputeDesiredHeight(nsIPresContext* aPresContext
const nsStyleTable* tableStyle;
GetStyleData(eStyleStruct_Table, (const nsStyleStruct *&)tableStyle);
DistributeSpaceToRows(aPresContext, aReflowState, childFrame, sumOfRowHeights,
excess, tableStyle, excessForGroup, rowGroupYPos);
excess, excessForGroup, rowGroupYPos);
// Make sure child views are properly positioned
nsIView* view;
@ -3923,29 +3881,6 @@ nsTableFrame::GetPadding(const nsSize& aBasis,
return padding;
}
NS_METHOD nsTableFrame::GetCellMarginData(nsTableCellFrame* aKidFrame, nsMargin& aMargin)
{
nsresult result = NS_ERROR_NOT_INITIALIZED;
if (aKidFrame) {
nscoord spacingX = GetCellSpacingX();
nscoord spacingY = GetCellSpacingY();
PRInt32 rowIndex, colIndex;
aKidFrame->GetRowIndex(rowIndex);
aKidFrame->GetColIndex(colIndex);
// left/top margins only apply if the cell is a left/top border cell
// there used to be more complicated logic (rev 3.326) dealing with rowspans
// but failure to produce reasonable tests cases does not justify it.
aMargin.left = (0 == colIndex) ? spacingX : 0;
aMargin.top = (0 == rowIndex) ? spacingY : 0;
aMargin.right = spacingX;
aMargin.bottom = spacingY;
result = NS_OK;
}
return result;
}
//XXX: ok, this looks dumb now. but in a very short time this will get filled in
void nsTableFrame::GetTableBorder(nsMargin &aBorder)
{
@ -4109,19 +4044,18 @@ NS_METHOD nsTableFrame::GetTableFrame(nsIFrame *aSourceFrame, nsTableFrame *& aT
/* helper method for determining if this is a nested table or not */
// aReflowState must be the reflow state for this inner table frame, should have an assertion here for that
PRBool nsTableFrame::IsNested(const nsHTMLReflowState& aReflowState, const nsStylePosition *& aPosition) const
PRBool
nsTableFrame::IsNested(const nsHTMLReflowState& aReflowState,
const nsStylePosition*& aPosition) const
{
aPosition = nsnull;
PRBool result = PR_FALSE;
// Walk up the reflow state chain until we find a cell or the root
const nsHTMLReflowState* rs = aReflowState.parentReflowState; // this is for the outer frame
if (rs)
rs = rs->parentReflowState; // and this is the parent of the outer frame
while (nsnull != rs)
{
const nsStyleDisplay *display;
rs->frame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)display);
if (NS_STYLE_DISPLAY_TABLE==display->mDisplay)
{
const nsHTMLReflowState* rs = GetGrandParentReflowState(aReflowState);
while (rs) {
nsCOMPtr<nsIAtom> frameType;
rs->frame->GetFrameType(getter_AddRefs(frameType));
if (nsLayoutAtoms::tableFrame == frameType.get()) {
result = PR_TRUE;
rs->frame->GetStyleData(eStyleStruct_Position, ((const nsStyleStruct *&)aPosition));
break;
@ -4180,39 +4114,15 @@ nscoord nsTableFrame::CalcBorderBoxWidth(const nsHTMLReflowState& aState)
return width;
}
nscoord nsTableFrame::CalcBorderBoxHeight(const nsHTMLReflowState& aState,
PRBool aDoNavHack)
nscoord nsTableFrame::CalcBorderBoxHeight(nsIPresContext* aPresContext,
const nsHTMLReflowState& aState)
{
nscoord height = aState.mComputedHeight;
PRBool isAutoHeight = PR_FALSE;
PRBool isPercentHack = PR_FALSE;
if (eStyleUnit_Auto == aState.mStylePosition->mHeight.GetUnit()) {
isAutoHeight = PR_TRUE;
}
else if (((0 == height) || (NS_UNCONSTRAINEDSIZE == height)) &&
aDoNavHack && (eStyleUnit_Percent == aState.mStylePosition->mHeight.GetUnit())) {
nsIAtom* frameType;
aState.frame->GetFrameType(&frameType);
if (nsLayoutAtoms::tableFrame == frameType) {
float percent = aState.mStylePosition->mHeight.GetPercentValue();
nscoord parentHeight = ((nsTableFrame*)aState.frame)->GetEffectiveContainerHeight(aState);
if ((NS_UNCONSTRAINEDSIZE != parentHeight) && (0 != parentHeight)) {
// css box-sizing not supported for this Nav hack
height = NSToCoordRound((float)parentHeight * percent);
isPercentHack = PR_TRUE;
}
}
NS_IF_RELEASE(frameType);
}
height = PR_MAX(height, 0);
if ((height != NS_UNCONSTRAINEDSIZE) && !isAutoHeight && !isPercentHack) {
nsMargin borderPadding(0,0,0,0);
aState.mStyleSpacing->GetBorderPadding(borderPadding);
if (NS_AUTOHEIGHT != height) {
nsMargin borderPadding = aState.mComputedBorderPadding;
height += borderPadding.top + borderPadding.bottom;
}
height = PR_MAX(0, height);
return height;
}

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

@ -147,8 +147,8 @@ public:
// calculate the height of aFrame including its border and padding given
// its reflow state.
nscoord CalcBorderBoxHeight(const nsHTMLReflowState& aReflowState,
PRBool aDoNavHacks);
nscoord CalcBorderBoxHeight(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState);
// Return the closest sibling of aPriorChildFrame (including aPriroChildFrame)
// of type aChildType.
@ -292,10 +292,6 @@ public:
/** helper to get the cell padding style value */
virtual nscoord GetCellPadding();
// Get cell margin information
NS_IMETHOD GetCellMarginData(nsTableCellFrame* aKidFrame, nsMargin& aMargin);
/** return the row span of a cell, taking into account row span magic at the bottom
* of a table. The row span equals the number of rows spanned by aCell starting at
* aStartRowIndex, and can be smaller if aStartRowIndex is greater than the row
@ -450,7 +446,8 @@ protected:
* If not nested, undefined.
* @return PR_TRUE if this table is nested inside another table.
*/
PRBool IsNested(const nsHTMLReflowState& aReflowState, const nsStylePosition *& aPosition) const;
PRBool IsNested(const nsHTMLReflowState& aReflowState,
const nsStylePosition*& aPosition) const;
// Sets the starting column index for aColGroupFrame and the siblings frames that
// follow
@ -576,17 +573,16 @@ protected:
/** The following two functions are helpers for ComputeDesiredHeight
*/
void DistributeSpaceToCells(nsIPresContext* aPresContext,
void DistributeSpaceToCells(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsIFrame* aRowGroupFrame);
void DistributeSpaceToRows(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsIFrame* aRowGroupFrame, const nscoord& aSumOfRowHeights,
const nscoord& aExcess, const nsStyleTable* aTableStyle,
nscoord& aExcessForRowGroup,
nscoord& aRowGroupYPos);
nscoord GetEffectiveContainerHeight(const nsHTMLReflowState& aReflowState);
nsIFrame* aRowGroupFrame);
void DistributeSpaceToRows(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsIFrame* aRowGroupFrame,
nscoord aSumOfRowHeights,
nscoord aExcess,
nscoord& aExcessForRowGroup,
nscoord& aRowGroupYPos);
void PlaceChild(nsIPresContext* aPresContext,
InnerTableReflowState& aReflowState,
@ -653,6 +649,11 @@ protected:
nsIFrame* aFromChild,
nsIFrame* aPrevSibling);
void GetSectionInfo(nsFrameList& aKidFrames,
PRBool& aHaveTHead,
PRBool& aHaveTBody,
PRBool& aHaveTFoot,
PRBool& aTHeadBeforeTFoot);
public:
// Returns PR_TRUE if there are any cells above the row at
// aRowIndex and spanning into the row at aRowIndex
@ -811,7 +812,8 @@ public: /* ----- Cell Map public methods ----- */
// compute the height of the table to be used as the basis for
// percentage height cells
void ComputePercentBasisForRows(const nsHTMLReflowState& aReflowState);
void ComputePercentBasisForRows(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState);
nscoord GetPercentBasisForRows();

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -27,7 +27,6 @@
#include "nsBlockFrame.h"
#include "nsITableLayout.h"
struct OuterTableReflowState;
struct nsStyleTable;
class nsTableCaptionFrame : public nsBlockFrame
@ -74,6 +73,8 @@ public:
NS_IMETHOD Destroy(nsIPresContext* aPresContext);
NS_IMETHOD IsPercentageBase(PRBool& aBase) const;
NS_IMETHOD AdjustZeroWidth();
/** @see nsIFrame::SetInitialChildList */
@ -158,6 +159,11 @@ public:
/** @see nsITableFrame::GetTableSize */
NS_IMETHOD GetTableSize(PRInt32& aRowCount, PRInt32& aColCount);
static void PositionView(nsIPresContext* aPresContext,
nsIFrame* aFrame);
static void ZeroAutoMargin(nsMargin& aMargin);
protected:
@ -197,61 +203,59 @@ protected:
virtual void DeleteChildsNextInFlow(nsIPresContext* aPresContext, nsIFrame* aChild);
// begin Incremental Reflow methods
/** prepare aReflowState for an incremental reflow */
NS_IMETHOD RecoverState(OuterTableReflowState& aReflowState, nsIFrame* aKidFrame);
/** process an incremental reflow command */
NS_IMETHOD IncrementalReflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
OuterTableReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD IncrementalReflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** process an incremental reflow command targeted at a child of this frame. */
NS_IMETHOD IR_TargetIsChild(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
OuterTableReflowState& aReflowState,
nsReflowStatus& aStatus,
nsIFrame * aNextFrame);
NS_IMETHOD IR_TargetIsChild(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus,
nsIFrame * aNextFrame);
/** process an incremental reflow command targeted at the table inner frame. */
NS_IMETHOD IR_TargetIsInnerTableFrame(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
OuterTableReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD IR_TargetIsInnerTableFrame(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** process an incremental reflow command targeted at the caption. */
NS_IMETHOD IR_TargetIsCaptionFrame(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
OuterTableReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD IR_TargetIsCaptionFrame(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** process an incremental reflow command targeted at this frame.
* many incremental reflows that are targeted at this outer frame
* are actually handled by the inner frame. The logic to decide this
* is here.
*/
NS_IMETHOD IR_TargetIsMe(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
OuterTableReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD IR_TargetIsMe(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** pass along the incremental reflow command to the inner table. */
NS_IMETHOD IR_InnerTableReflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
OuterTableReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD IR_InnerTableReflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** handle incremental reflow notification that a caption was inserted. */
NS_IMETHOD IR_CaptionInserted(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
OuterTableReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD IR_CaptionInserted(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** handle incremental reflow notification that we have dirty child frames */
NS_IMETHOD IR_ReflowDirty(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
OuterTableReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD IR_ReflowDirty(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** handle incremental reflow notification that the caption style was changed
* such that it is now left|right instead of top|bottom, or vice versa.
@ -259,25 +263,93 @@ protected:
PRBool IR_CaptionChangedAxis(const nsStyleTable* aOldStyle,
const nsStyleTable* aNewStyle) const;
/** set the size and the location of both the inner table frame and the caption. */
NS_IMETHOD SizeAndPlaceChildren(nsIPresContext* aPresContext,
const nsSize& aInnerSize,
const nsSize& aCaptionSize,
OuterTableReflowState& aReflowState,
const nsMargin& aCaptionMargin);
// end Incremental Reflow methods
// end Incremental Reflow methods
// The following function at least lets the tree widget work
// inside boxes. It repairs the reflow state after it's been
// screwed up by the nsHTMLReflowState code.
// When the reflow state is constructed, mComputedWidth and mComputedHeight get set
// to the table's styled width and height. Flex from XUL boxes can make the styled #s
// inaccurate, which means that mComputedWidth and mComputedHeight from the parent
// reflow state should be used instead.
// The following function will patch the reflow state so that trees behave properly inside boxes.
// This might work for tables as well, but not until regression tests can be run to make sure,
NS_IMETHOD FixBadReflowState(const nsHTMLReflowState& aParentReflowState,
nsHTMLReflowState& aChildReflowState) { return NS_OK; };
nsSize GetMaxElementSize(const nsMargin& aInnerMargin,
const nsMargin& aInnerPadding,
const nsMargin& aCaptionMargin);
nscoord GetMaxWidth(PRUint8 aCaptionSide,
const nsMargin& aInnerMargin,
const nsMargin& aCaptionMargin);
PRUint8 GetCaptionSide();
void SetDesiredSize(PRUint8 aCaptionSide,
const nsMargin& aInnerMargin,
const nsMargin& aCaptionMargin,
nscoord& aWidth,
nscoord& aHeight);
NS_IMETHOD GetCaptionOrigin(nsIPresContext* aPresContext,
PRUint32 aCaptionSide,
const nsSize& aContainBlockSize,
const nsSize& aInnerSize,
const nsMargin& aInnerMargin,
const nsSize& aCaptionSize,
nsMargin& aCaptionMargin,
nsPoint& aOrigin);
NS_IMETHOD GetInnerOrigin(nsIPresContext* aPresContext,
PRUint32 aCaptionSide,
const nsSize& aContainBlockSize,
const nsSize& aCaptionSize,
const nsMargin& aCaptionMargin,
const nsSize& aInnerSize,
nsMargin& aInnerMargin,
nsPoint& aOrigin);
nscoord GetChildAvailWidth(nsIPresContext* aPresContext,
nsIFrame* aChildFrame,
const nsHTMLReflowState& aOuterRS,
nscoord aOuterWidth,
nsMargin& aMargin,
nsMargin& aPadding);
nscoord GetCaptionAvailWidth(nsIPresContext* aPresContext,
nsIFrame* aCaptionFrame,
const nsHTMLReflowState& aReflowState,
nscoord* aInnerWidth = nsnull,
const nsMargin* aInnerMargin = nsnull);
NS_IMETHOD OuterReflowChild(nsIPresContext* aPresContext,
nsIFrame* aChildFrame,
const nsHTMLReflowState& aOuterRS,
nsHTMLReflowMetrics& aMetrics,
nscoord* aAvailWidth,
nsSize& aDesiredSize,
nsMargin& aMargin,
nsMargin& aPadding,
nsReflowReason aReflowReason,
nsReflowStatus& aStatus);
void UpdateReflowMetrics(PRUint8 aCaptionSide,
nsHTMLReflowMetrics& aMet,
const nsMargin& aInnerMargin,
const nsMargin& aInnerPadding,
const nsMargin& aCaptionPadding);
void InvalidateDamage(nsIPresContext* aPresContext,
PRUint8 aCaptionSide,
nsSize& aOuterSize,
PRBool aInnerChanged,
PRBool aCaptionChanged);
private:
/** used to keep track of this frame's children */
nsIFrame *mInnerTableFrame; // XXX this is redundant, mFrames holds the same
nsIFrame *mCaptionFrame;
nsIFrame* mInnerTableFrame; // XXX this is redundant, mFrames holds the same
nsIFrame* mCaptionFrame;
/** used to track caption max element size */
PRInt32 mMinCaptionWidth;

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

@ -244,11 +244,10 @@ nsTableRowFrame::DidResize(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState)
{
// Resize and re-align the cell frames based on our row height
nscoord cellMaxTopMargin = GetTopMargin();
nscoord cellMaxBottomMargin = GetBottomMargin();
nscoord rowCellHeight = mRect.height - cellMaxTopMargin - cellMaxBottomMargin;
nsTableFrame* tableFrame;
nsTableFrame::GetTableFrame(this, tableFrame);
if (!tableFrame) return;
nscoord cellSpacingY = tableFrame->GetCellSpacingY();
nsTableIterator iter(aPresContext, *this, eTableDIR);
nsIFrame* cellFrame = iter.First();
@ -258,7 +257,7 @@ nsTableRowFrame::DidResize(nsIPresContext* aPresContext,
cellFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)kidDisplay));
if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay) {
PRInt32 rowSpan = tableFrame->GetEffectiveRowSpan((nsTableCellFrame &)*cellFrame);
nscoord cellHeight = rowCellHeight;
nscoord cellHeight = mRect.height;
// add in height of rows spanned beyond the 1st one
nsIFrame* nextRow = nsnull;
GetNextSibling(&nextRow);
@ -271,6 +270,7 @@ nsTableRowFrame::DidResize(nsIPresContext* aPresContext,
cellHeight += rect.height;
i++;
}
cellHeight += cellSpacingY;
nextRow->GetNextSibling(&nextRow);
}
@ -365,20 +365,8 @@ NS_METHOD nsTableRowFrame::Paint(nsIPresContext* aPresContext,
return rv;
}
nscoord cellSpacingX = tableFrame->GetCellSpacingX();
nscoord halfCellSpacingY =
NSToCoordRound(((float)tableFrame->GetCellSpacingY()) / (float)2);
// every row is short by the ending cell spacing X
nsRect rect(0, 0, mRect.width + cellSpacingX, mRect.height);
// first row may have gotten too much cell spacing Y
if (tableFrame->GetRowCount() != 1) {
if (IsFirstRow(aPresContext, *tableFrame, *this)) {
rect.height -= halfCellSpacingY;
}
else {
rect.height += halfCellSpacingY;
rect.y -= halfCellSpacingY;
}
}
nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this,
aDirtyRect, rect, *color, *spacing, 0, 0);
@ -514,24 +502,6 @@ nscoord nsTableRowFrame::GetTallestChild() const
return mTallestCell;
}
nscoord nsTableRowFrame::GetTopMargin() const
{
nsTableFrame *tableFrame;
nsTableFrame::GetTableFrame((nsIFrame*)this, tableFrame);
// Only cells in the first row have a top margin
return (GetRowIndex() == 0) ? tableFrame->GetCellSpacingY() : 0;
}
nscoord nsTableRowFrame::GetBottomMargin() const
{
nsTableFrame *tableFrame;
nsTableFrame::GetTableFrame((nsIFrame*)this, tableFrame);
// All cells have the same bottom margin
return tableFrame->GetCellSpacingY();
}
/* GetMinRowSpan is needed for deviant cases where every cell in a row has a rowspan > 1.
* It sets mMinRowSpan, which is used in FixMinCellHeight and PlaceChild
*/
@ -636,14 +606,7 @@ void nsTableRowFrame::PlaceChild(nsIPresContext* aPresContext,
aReflowState.maxCellHeight = aDesiredSize.height;
// Update maxCellVertSpace
nsMargin margin;
if (aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)aKidFrame, margin) == NS_OK) {
nscoord height = aDesiredSize.height + margin.top + margin.bottom;
if (height > aReflowState.maxCellVertSpace)
aReflowState.maxCellVertSpace = height;
}
aReflowState.maxCellVertSpace = PR_MAX(aDesiredSize.height, aReflowState.maxCellVertSpace);
}
#endif
}
@ -880,7 +843,7 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
reason);
nsReflowStatus status;
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState,
aReflowState.x, GetTopMargin(), 0, status);
aReflowState.x, 0, 0, status);
#ifdef NS_DEBUG
if (desiredSize.width > availWidth)
{
@ -935,7 +898,7 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
// Place the child
PlaceChild(aPresContext, aReflowState, kidFrame, desiredSize,
aReflowState.x, GetTopMargin(),
aReflowState.x, 0,
aDesiredSize.maxElementSize, kidMaxElementSize);
}
@ -996,6 +959,7 @@ nsTableRowFrame::InitialReflow(nsIPresContext* aPresContext,
nscoord x = 0;
nsTableFrame* table = aReflowState.tableFrame;
PRBool isAutoLayout = table->IsAutoLayout(&aReflowState.reflowState);
nscoord cellSpacingX = table->GetCellSpacingX();
nsIFrame* kidFrame;
if (nsnull==aStartFrame)
@ -1003,29 +967,20 @@ nsTableRowFrame::InitialReflow(nsIPresContext* aPresContext,
else
kidFrame = aStartFrame;
for ( ; nsnull != kidFrame; kidFrame->GetNextSibling(&kidFrame))
{
for ( ; nsnull != kidFrame; kidFrame->GetNextSibling(&kidFrame)) {
const nsStyleDisplay *kidDisplay;
kidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)kidDisplay));
if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay)
{
// Get the child's margins
// Get the frame's margins
nsMargin kidMargin;
aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, kidMargin);
if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay) {
// For the initial reflow always allow the child to be as high as it
// wants. The default available width is also unconstrained so we can
// get the child's maximum width
nsSize kidAvailSize;
nsHTMLReflowMetrics kidSize(nsnull);
if (isAutoLayout)
{
if (isAutoLayout) {
kidAvailSize.SizeTo(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
kidSize.maxElementSize=&kidMaxElementSize;
}
else
{
else {
PRInt32 colIndex;
((nsTableCellFrame *)kidFrame)->GetColIndex(colIndex);
kidAvailSize.SizeTo(table->GetColumnWidth(colIndex), NS_UNCONSTRAINEDSIZE);
@ -1037,7 +992,7 @@ nsTableRowFrame::InitialReflow(nsIPresContext* aPresContext,
eReflowReason_Initial);
rv = ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState,
x + kidMargin.left, kidMargin.top, 0, aStatus);
x + cellSpacingX, 0, 0, aStatus);
// the following signals bugs in the content frames.
if (kidMaxElementSize.width > kidSize.width) {
@ -1056,10 +1011,10 @@ nsTableRowFrame::InitialReflow(nsIPresContext* aPresContext,
NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "unexpected child reflow status");
// Place the child
x += kidMargin.left;
PlaceChild(aPresContext, aReflowState, kidFrame, kidSize, x, kidMargin.top,
x += cellSpacingX;
PlaceChild(aPresContext, aReflowState, kidFrame, kidSize, x, 0,
aDesiredSize.maxElementSize, &kidMaxElementSize);
x += kidSize.width + kidMargin.right;
x += kidSize.width + cellSpacingX;
}
else
{// it's an unknown frame type, give it a generic reflow and ignore the results
@ -1108,10 +1063,6 @@ NS_METHOD nsTableRowFrame::RecoverState(nsIPresContext* aPresContext,
frame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)kidDisplay));
if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay) {
// Get the child's margins
nsMargin kidMargin;
aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)frame, kidMargin);
// Update maxCellHeight and maxVertCellSpace. When determining this we
// don't include cells that span rows
PRInt32 rowSpan = aReflowState.tableFrame->GetEffectiveRowSpan((nsTableCellFrame &)*frame);
@ -1130,10 +1081,7 @@ NS_METHOD nsTableRowFrame::RecoverState(nsIPresContext* aPresContext,
}
// Update maxCellVertHeight
nscoord vertHeight = desiredSize.height + kidMargin.top + kidMargin.bottom;
if (vertHeight > aReflowState.maxCellVertSpace) {
aReflowState.maxCellVertSpace = vertHeight;
}
aReflowState.maxCellVertSpace = PR_MAX(desiredSize.height, aReflowState.maxCellVertSpace);
}
// Recover the max element size if requested
@ -1293,7 +1241,7 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
// in a max width of NS_UNCONSTRAINEDSIZE, because the max width must match
// the width of the previous reflow...
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState,
aReflowState.x, GetTopMargin(), 0, aStatus);
aReflowState.x, 0, 0, aStatus);
// Update the cell layout data.. If the cell's maximum width changed,
// then inform the table that its maximum width needs to be recomputed
@ -1334,7 +1282,7 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
// Now place the child
PlaceChild(aPresContext, aReflowState, aNextFrame, desiredSize, aReflowState.x,
GetTopMargin(), aDesiredSize.maxElementSize, &kidMaxElementSize);
0, aDesiredSize.maxElementSize, &kidMaxElementSize);
SetMaxChildHeight(aReflowState.maxCellHeight);

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

@ -168,8 +168,6 @@ public:
/** returns the tallest child in this row (ignoring any cell with rowspans) */
nscoord GetTallestChild() const;
nscoord GetTopMargin() const;
nscoord GetBottomMargin() const;
/** returns the ordinal position of this row in its table */
virtual PRInt32 GetRowIndex() const;

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

@ -181,23 +181,7 @@ NS_METHOD nsTableRowGroupFrame::Paint(nsIPresContext* aPresContext,
if (NS_FAILED(rv) || (nsnull == tableFrame)) {
return rv;
}
nscoord halfCellSpacingY =
NSToCoordRound(((float)tableFrame->GetCellSpacingY()) / (float)2);
// every row group is short by the ending cell spacing X
nsRect rect(0, 0, mRect.width, mRect.height);
nsIFrame* firstRowGroup = nsnull;
tableFrame->FirstChild(aPresContext, nsnull, &firstRowGroup);
// first row group may have gotten too much cell spacing Y
if (tableFrame->GetRowCount() != 1) {
if (this == firstRowGroup) {
rect.height -= halfCellSpacingY;
}
else {
rect.height += halfCellSpacingY;
rect.y -= halfCellSpacingY;
}
}
nsRect rect(0,0,mRect.width, mRect.height);
nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this,
aDirtyRect, rect, *color, *spacing, 0, 0);
}
@ -335,7 +319,12 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext* aPresC
{
nsSize kidMaxElementSize;
nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ? &kidMaxElementSize : nsnull;
nsresult rv = NS_OK;
nsTableFrame* tableFrame = nsnull;
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame);
if (NS_FAILED(rv) || !tableFrame) return rv;
nscoord cellSpacingY = tableFrame->GetCellSpacingY();
if (!ContinueReflow(nsnull, aPresContext, aReflowState.y, aReflowState.availSize.height))
return rv;
@ -413,12 +402,11 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext* aPresC
/* if the table has collapsing borders, we need to reset the length of the shared vertical borders
* for the table and the cells that overlap this row
*/
if ((eReflowReason_Initial != aReflowState.reflowState.reason) && (NS_STYLE_BORDER_COLLAPSE==borderStyle))
{
if ((eReflowReason_Initial != aReflowState.reflowState.reason) &&
(NS_STYLE_BORDER_COLLAPSE==borderStyle)) {
const nsStyleDisplay *childDisplay;
kidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
{
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay) {
PRInt32 rowIndex = ((nsTableRowFrame*)kidFrame)->GetRowIndex();
aReflowState.tableFrame->SetBorderEdgeLength(NS_SIDE_LEFT,
rowIndex,
@ -446,13 +434,14 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext* aPresC
}
}
}
aReflowState.y += cellSpacingY;
} else {
// Adjust the running y-offset so we know where the next row should
// be placed
nsSize kidSize;
kidFrame->GetSize(kidSize);
aReflowState.y += kidSize.height;
aReflowState.y += kidSize.height + cellSpacingY;
}
if (PR_FALSE==aDoSiblings)
@ -555,8 +544,8 @@ AllocateSpecialHeight(nsIPresContext* aPresContext,
* Actual row heights are ultimately determined by the table, when the table
* height attribute is factored in.
*/
void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState)
{
nsTableFrame* tableFrame = nsnull;
@ -597,11 +586,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
startRowIndex = ((nsTableRowFrame*)rowFrame)->GetRowIndex();
}
// get the height of the tallest cell in the row (excluding cells that span rows)
nscoord maxCellHeight = ((nsTableRowFrame*)rowFrame)->GetTallestChild();
nscoord topMargin = ((nsTableRowFrame*)rowFrame)->GetTopMargin();
nscoord bottomMargin = ((nsTableRowFrame*)rowFrame)->GetBottomMargin();
nscoord maxRowHeight = maxCellHeight + topMargin + bottomMargin;
rowHeights[rowIndex] = maxRowHeight;
rowHeights[rowIndex] = ((nsTableRowFrame*)rowFrame)->GetTallestChild();
// See if a cell spans into the row. If so we'll have to do step 2
if (!hasRowSpanningCell) {
if (tableFrame->RowIsSpannedInto(rowIndex + startRowIndex)) {
@ -649,6 +634,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
if (rowSpan > 1) { // found a cell with rowspan > 1, determine the height
// of the rows it spans
nscoord heightOfRowsSpanned = 0;
nscoord cellSpacingOfRowsSpanned = 0;
PRInt32 spanX;
PRBool cellsOrigInSpan = PR_FALSE; // do any cells originate in the spanned rows
for (spanX = 0; spanX < rowSpan; spanX++) {
@ -658,9 +644,11 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
heightOfRowsSpanned += rowHeights[rowIndex + spanX];
cellsOrigInSpan = PR_TRUE;
}
if (0 != spanX) {
cellSpacingOfRowsSpanned += cellSpacingY;
}
}
// reduce the height by top and bottom margins
nscoord availHeightOfRowsSpanned = heightOfRowsSpanned - cellSpacingY - cellSpacingY;
nscoord availHeightOfRowsSpanned = heightOfRowsSpanned + cellSpacingOfRowsSpanned;
// see if the cell's height fits within the rows it spans. If this is
// pass 1 then use the cell's desired height and not the current height
@ -675,7 +663,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
}
if (availHeightOfRowsSpanned >= cellFrameSize.height) {
// yes the cell's height fits with the available space of the rows it
// the cell's height fits with the available space of the rows it
// spans. Set the cell frame's height
cellFrame->SizeTo(aPresContext, cellFrameSize.width, availHeightOfRowsSpanned);
// Realign cell content based on new height
@ -800,6 +788,9 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
nsSize rowSize;
rowFrame->GetSize(rowSize);
rowGroupHeight += rowSize.height;
if (0 != rowIndex) {
rowGroupHeight += cellSpacingY;
}
GetNextFrame(rowFrame, &rowFrame); // Get the next row
rowIndex++;
@ -1371,24 +1362,28 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext* aPresContext,
return rv;
}
NS_METHOD nsTableRowGroupFrame::GetHeightOfRows(nsIPresContext* aPresContext, nscoord& aResult)
NS_METHOD nsTableRowGroupFrame::GetHeightOfRows(nsIPresContext* aPresContext,
nscoord& aResult)
{
nsTableFrame* tableFrame = nsnull;
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame);
if (NS_FAILED(rv) || !tableFrame) return rv;
nscoord cellSpacingY = tableFrame->GetCellSpacingY();
// the rows in rowGroupFrame need to be expanded by rowHeightDelta[i]
// and the rowgroup itself needs to be expanded by SUM(row height deltas)
nsIFrame * rowFrame=nsnull;
nsresult rv = FirstChild(aPresContext, nsnull, &rowFrame);
while ((NS_SUCCEEDED(rv)) && (nsnull!=rowFrame))
{
const nsStyleDisplay *rowDisplay;
nsIFrame* rowFrame = nsnull;
rv = FirstChild(aPresContext, nsnull, &rowFrame);
while ((NS_SUCCEEDED(rv)) && (nsnull!=rowFrame)) {
const nsStyleDisplay* rowDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)rowDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay)
{
if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay) {
nsRect rowRect;
rowFrame->GetRect(rowRect);
aResult += rowRect.height;
}
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == rowDisplay->mDisplay)
{
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == rowDisplay->mDisplay) {
((nsTableRowGroupFrame*)rowFrame)->GetHeightOfRows(aPresContext, aResult);
}
GetNextFrame(rowFrame, &rowFrame);

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

@ -179,6 +179,7 @@ th {
caption {
text-align: center;
display: table-caption;
box-sizing: border-box;
}
tr {
display: table-row;
@ -1084,6 +1085,35 @@ option[disabled] {
background-color:rgb(204,204,204) !important;
}
select option[disabled] {
color:rgb(153,153,153);
background-color:rgb(204,204,204);
}
select[size] option[-moz-option-selected] {
color:white;
background-color:rgb(51,51,102);
}
select[size] option[-moz-option-selected-focus] {
color:white;
background-color:rgb(51,51,102);
}
select[size][disabled] option[-moz-option-selected] {
color:rgb(153,153,153);
background-color:rgb(204,204,204);
}
select[size="1"] option[-moz-option-selected] {
color:white;
background-color:rgb(51,51,102);
}
select[size="1"] option[disabled][-moz-option-selected] {
color:rgb(153,153,153);
background-color:rgb(204,204,204);
}
optgroup {
font-family: sans-serif;
font-size: small;
@ -1290,14 +1320,22 @@ sourcetext { /* XXX should not be in HTML namespace */
:table {
display: table;
border-style: inherit;
border-color: inherit;
margin-top: inherit;
margin-bottom: inherit;
background: inherit;
border-spacing: 2px;
border-collapse: separate;
margin-top: 0;
margin-bottom: 0;
box-sizing: border-box;
}
:table-outer {
display: table;
margin: 0px;
border: 0px;
padding: 0px;
float: inherit;
position: inherit;
}
:table-cell {
display: table-cell;
}
@ -1310,10 +1348,6 @@ sourcetext { /* XXX should not be in HTML namespace */
display: table-column-group;
}
:table-outer {
display: table;
}
:table-row {
display: table-row;
}

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

@ -2287,8 +2287,9 @@ StyleContextImpl::RemapStyle(nsIPresContext* aPresContext, PRBool aRecurse)
nsCompatibility quirkMode = eCompatibility_Standard;
aPresContext->GetCompatibilityMode(&quirkMode);
if (eCompatibility_NavQuirks == quirkMode) {
if ((mDisplay.mDisplay == NS_STYLE_DISPLAY_TABLE) ||
(mDisplay.mDisplay == NS_STYLE_DISPLAY_TABLE_CAPTION)) {
if (((mDisplay.mDisplay == NS_STYLE_DISPLAY_TABLE) ||
(mDisplay.mDisplay == NS_STYLE_DISPLAY_TABLE_CAPTION)) &&
(nsnull == mPseudoTag)) {
StyleContextImpl* holdParent = mParent;
mParent = nsnull; // cut off all inheritance. this really blows

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

@ -855,8 +855,8 @@ void nsCellMap::InsertCells(nsTableCellMap& aMap,
PRInt32 startColIndex;
for (startColIndex = aColIndexBefore + 1; startColIndex < numCols; startColIndex++) {
CellData* data = GetMapCellAt(aMap, aRowIndex, startColIndex, PR_TRUE);
if (data && data->IsOrig()) {
break; // we found the col index
if (!data || data->IsOrig()) { // stop unless it is a span
break;
}
}
@ -904,19 +904,20 @@ void
nsCellMap::ExpandWithRows(nsIPresContext* aPresContext,
nsTableCellMap& aMap,
nsVoidArray& aRowFrames,
PRInt32 aStartRowIndex)
PRInt32 aStartRowIndexIn)
{
PRInt32 startRowIndex = (aStartRowIndexIn >= 0) ? aStartRowIndexIn : 0;
PRInt32 numNewRows = aRowFrames.Count();
PRInt32 endRowIndex = aStartRowIndex + numNewRows - 1;
PRInt32 endRowIndex = startRowIndex + numNewRows - 1;
// create the new rows first
if (!Grow(aMap, numNewRows, aStartRowIndex)) {
if (!Grow(aMap, numNewRows, startRowIndex)) {
return;
}
mRowCount += numNewRows;
PRInt32 newRowIndex = 0;
for (PRInt32 rowX = aStartRowIndex; rowX <= endRowIndex; rowX++) {
for (PRInt32 rowX = startRowIndex; rowX <= endRowIndex; rowX++) {
nsTableRowFrame* rFrame = (nsTableRowFrame *)aRowFrames.ElementAt(newRowIndex);
// append cells
nsIFrame* cFrame = nsnull;

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

@ -135,6 +135,16 @@ struct InnerTableReflowState {
}
};
const nsHTMLReflowState*
GetGrandParentReflowState(const nsHTMLReflowState& aInnerRS)
{
const nsHTMLReflowState* rs = nsnull;
if (aInnerRS.parentReflowState) {
rs = aInnerRS.parentReflowState->parentReflowState;
}
return rs;
}
NS_IMETHODIMP
nsTableFrame::GetFrameType(nsIAtom** aType) const
@ -1461,37 +1471,30 @@ nsTableFrame::SetColumnDimensions(nsIPresContext* aPresContext,
{
nscoord colHeight = aHeight -= aBorderPadding.top + aBorderPadding.bottom;
nscoord cellSpacingX = GetCellSpacingX();
nscoord halfCellSpacingX = NSToCoordRound(((float)cellSpacingX) / (float)2);
nsIFrame* colGroupFrame = mColGroups.FirstChild();
PRInt32 colX = 0;
nsPoint colGroupOrigin(aBorderPadding.left, aBorderPadding.top);
nsPoint colGroupOrigin(aBorderPadding.left + cellSpacingX, aBorderPadding.top);
PRInt32 numCols = GetColCount();
while (nsnull != colGroupFrame) {
nscoord colGroupWidth = 0;
nsIFrame* colFrame = nsnull;
colGroupFrame->FirstChild(aPresContext, nsnull, &colFrame);
nsPoint colOrigin(0, 0);
nsPoint colOrigin(0,0);
while (nsnull != colFrame) {
const nsStyleDisplay* colDisplay;
colFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)colDisplay));
if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay) {
NS_ASSERTION(colX < numCols, "invalid number of columns");
nscoord colWidth = mColumnWidths[colX];
if (numCols == 1) {
colWidth += cellSpacingX + cellSpacingX;
}
else if ((0 == colX) || (numCols - 1 == colX)) {
colWidth += cellSpacingX + halfCellSpacingX;
}
else if (GetNumCellsOriginatingInCol(colX) > 0) {
colWidth += cellSpacingX;
}
colGroupWidth += colWidth;
nsRect colRect(colOrigin.x, colOrigin.y, colWidth, colHeight);
colFrame->SetRect(aPresContext, colRect);
colOrigin.x += colWidth;
colOrigin.x += colWidth + cellSpacingX;
colGroupWidth += colWidth;
if (numCols - 1 != colX) {
colGroupWidth += cellSpacingX;
}
colX++;
}
colFrame->GetNextSibling(&colFrame);
@ -1604,9 +1607,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
aDesiredSize.maxElementSize = nsnull;
}
rv = ResizeReflowPass2(aPresContext, aDesiredSize, reflowState, aStatus);
if (NS_FAILED(rv)) {
return rv;
}
if (NS_FAILED(rv)) return rv;
aDesiredSize.width = PR_MIN(aDesiredSize.width, pass1Width);
@ -1704,7 +1705,7 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext,
NS_ASSERTION(nsnull==mPrevInFlow, "illegal call, cannot call pass 1 on a continuing frame.");
NS_ASSERTION(nsnull != mContent, "null content");
nsresult rv=NS_OK;
nsresult rv = NS_OK;
// set out params
aStatus = NS_FRAME_COMPLETE;
@ -1713,23 +1714,22 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext,
nsSize kidMaxSize(0,0);
nsHTMLReflowMetrics kidSize(&kidMaxSize);
nscoord y = 0;
nscoord cellSpacingY = GetCellSpacingY();
// Compute the insets (sum of border and padding)
// XXX: since this is pass1 reflow and where we place the rowgroup frames is irrelevant, insets are probably a waste
if (IsAutoLayout(&aReflowState))
{
if (IsAutoLayout(&aReflowState)) {
nsIFrame* kidFrame = aStartingFrame;
if (nsnull==kidFrame)
kidFrame=mFrames.FirstChild();
for ( ; nsnull != kidFrame; kidFrame->GetNextSibling(&kidFrame))
{
kidFrame = mFrames.FirstChild();
for ( ; nsnull != kidFrame; kidFrame->GetNextSibling(&kidFrame)) {
const nsStyleDisplay *childDisplay;
kidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
if ((NS_STYLE_DISPLAY_TABLE_HEADER_GROUP != childDisplay->mDisplay) &&
(NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP != childDisplay->mDisplay) &&
(NS_STYLE_DISPLAY_TABLE_ROW_GROUP != childDisplay->mDisplay) )
{ // it's an unknown frame type, give it a generic reflow and ignore the results
(NS_STYLE_DISPLAY_TABLE_ROW_GROUP != childDisplay->mDisplay) ) {
// it's an unknown frame type, give it a generic reflow and ignore the results
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
availSize, aReason);
// rv intentionally not set here
@ -1738,7 +1738,7 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext,
continue;
}
// Get the row group's border padding
// Get the table's border padding
nsMargin borderPadding;
GetTableBorderForRowGroup(GetRowGroupFrameFor(kidFrame, childDisplay), borderPadding);
const nsStyleSpacing* tableSpacing;
@ -1746,6 +1746,11 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext,
nsMargin padding;
tableSpacing->GetPadding(padding);
borderPadding += padding;
y += cellSpacingY;
if (kidFrame == mFrames.FirstChild()) {
y += borderPadding.top;
}
// Reflow the child
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
@ -1754,12 +1759,12 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext,
// isTopOfPage reflow state flag, because we're dealing with an unconstrained
// height and it isn't an issue...
ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, borderPadding.left,
borderPadding.top + y, 0, aStatus);
y, 0, aStatus);
// Place the child since some of its content fit in us.
FinishReflowChild(kidFrame, aPresContext, kidSize, borderPadding.left,
borderPadding.top + y, 0);
if (NS_UNCONSTRAINEDSIZE==kidSize.height)
if (NS_UNCONSTRAINEDSIZE == kidSize.height)
// XXX This is very suspicious. Why would a row group frame want
// such a large height?
y = NS_UNCONSTRAINEDSIZE;
@ -1777,16 +1782,14 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext,
// up all of our available space (or needs us to split).
break;
}
if (PR_FALSE==aDoSiblingFrames)
if (!aDoSiblingFrames)
break;
}
// if required, give the colgroups their initial reflows
if (PR_TRUE==aDoSiblingFrames)
{
if (aDoSiblingFrames) {
kidFrame=mColGroups.FirstChild();
for ( ; nsnull != kidFrame; kidFrame->GetNextSibling(&kidFrame))
{
for ( ; nsnull != kidFrame; kidFrame->GetNextSibling(&kidFrame)) {
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
availSize, aReason);
ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, 0, 0, 0, aStatus);
@ -1946,6 +1949,7 @@ NS_METHOD nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresContext,
borderPadding += aReflowState.mComputedPadding;
InnerTableReflowState state(aPresContext, aReflowState, borderPadding);
state.y = borderPadding.top; // XXX this should be set in the constructor, but incremental code is affected.
// now that we've computed the column width information, reflow all children
#ifdef NS_DEBUG
@ -1958,7 +1962,7 @@ NS_METHOD nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresContext,
// Reflow the existing frames
if (mFrames.NotEmpty()) {
ComputePercentBasisForRows(aReflowState);
ComputePercentBasisForRows(aPresContext, aReflowState);
rv = ReflowMappedChildren(aPresContext, aDesiredSize, state, aStatus);
}
@ -1973,7 +1977,7 @@ NS_METHOD nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresContext,
// Return our size and our status
aDesiredSize.width = ComputeDesiredWidth(aReflowState);
nscoord defaultHeight = state.y + borderPadding.top + borderPadding.bottom;
nscoord defaultHeight = state.y + GetCellSpacingY() + borderPadding.bottom;
aDesiredSize.height = ComputeDesiredHeight(aPresContext, aReflowState, defaultHeight);
AdjustForCollapsingRows(aPresContext, aDesiredSize.height);
@ -1994,16 +1998,15 @@ NS_METHOD nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresContext,
}
void nsTableFrame::ComputePercentBasisForRows(const nsHTMLReflowState& aReflowState)
void nsTableFrame::ComputePercentBasisForRows(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState)
{
nscoord height = CalcBorderBoxHeight(aReflowState, PR_TRUE);
nscoord height = CalcBorderBoxHeight(aPresContext, aReflowState);
if ((height > 0) && (height != NS_UNCONSTRAINEDSIZE)) {
// exclude our border and padding
nsMargin borderPadding = aReflowState.mComputedBorderPadding;
height -= borderPadding.top + borderPadding.bottom;
// exclude cell spacing for all rows
height -= (1 + GetRowCount()) * GetCellSpacingY();
height = PR_MAX(0, height);
}
else {
@ -2786,10 +2789,9 @@ nscoord nsTableFrame::ComputeDesiredWidth(const nsHTMLReflowState& aReflowState)
nscoord desiredWidth = aReflowState.availableWidth;
// this is the biggest hack in the world. But there's no other rational way to handle nested percent tables
const nsStylePosition* position;
PRBool isNested=IsNested(aReflowState, position);
if((eReflowReason_Initial==aReflowState.reason) &&
(PR_TRUE==isNested) && (eStyleUnit_Percent==position->mWidth.GetUnit()))
{
PRBool isNested = IsNested(aReflowState, position);
if ((eReflowReason_Initial==aReflowState.reason) &&
(isNested) && (eStyleUnit_Percent == position->mWidth.GetUnit())) {
nsITableLayoutStrategy* tableLayoutStrategy = mTableLayoutStrategy;
if (mPrevInFlow) {
// Get the table layout strategy from the first-in-flow
@ -2823,36 +2825,30 @@ void nsTableFrame::PlaceChild(nsIPresContext* aPresContext,
aReflowState.availSize.height -= aDesiredSize.height;
}
// If this is a footer row group, remember it
const nsStyleDisplay *childDisplay;
aKidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
// We only allow a single footer frame, and the footer frame must occur before
// any body section row groups
if ((NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == childDisplay->mDisplay) &&
!aReflowState.footerFrame && !aReflowState.firstBodySection)
{
!aReflowState.footerFrame && !aReflowState.firstBodySection) {
aReflowState.footerFrame = aKidFrame;
}
else if (aReflowState.footerFrame)
{
// Place the row group frame
nsSize footerSize;
else if (aReflowState.footerFrame) {
// put the non footer where the footer was
nsPoint origin;
aKidFrame->GetOrigin(origin);
aReflowState.footerFrame->GetSize(footerSize);
origin.y -= footerSize.height;
aKidFrame->MoveTo(aPresContext, origin.x, origin.y);
// Move the footer below the body row group frame
aReflowState.footerFrame->GetOrigin(origin);
origin.y += aDesiredSize.height;
aKidFrame->MoveTo(aPresContext, origin.x, origin.y);
// put the footer below the non footer
nsSize size;
aReflowState.footerFrame->GetSize(size);
origin.y = aReflowState.y - size.height;
aReflowState.footerFrame->MoveTo(aPresContext, origin.x, origin.y);
}
//XXX: this should call into layout strategy to get the width field
if (nsnull != aMaxElementSize)
{
if (nsnull != aMaxElementSize) {
const nsStyleSpacing* tableSpacing;
GetStyleData(eStyleStruct_Spacing , ((const nsStyleStruct *&)tableSpacing));
nsMargin borderPadding;
@ -2865,6 +2861,39 @@ void nsTableFrame::PlaceChild(nsIPresContext* aPresContext,
}
}
void
nsTableFrame::GetSectionInfo(nsFrameList& aKidFrames,
PRBool& aHaveTHead,
PRBool& aHaveTBody,
PRBool& aHaveTFoot,
PRBool& aTHeadBeforeTFoot)
{
aHaveTHead = aHaveTBody = aHaveTFoot = PR_FALSE;
aTHeadBeforeTFoot = PR_TRUE;
nsIFrame* kidFrame = aKidFrames.FirstChild();
while (kidFrame) {
const nsStyleDisplay* kidDisplay;
kidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)kidDisplay));
if (IsRowGroup(kidDisplay->mDisplay)) {
switch(kidDisplay->mDisplay) {
case NS_STYLE_DISPLAY_TABLE_HEADER_GROUP:
aHaveTHead = PR_TRUE;
break;
case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP:
aHaveTFoot = PR_TRUE;
if (!aHaveTHead) {
aTHeadBeforeTFoot = PR_FALSE;
}
break;
default:
aHaveTBody = PR_TRUE;
}
}
kidFrame->GetNextSibling(&kidFrame);
}
}
/**
* Reflow the frames we've already created
*
@ -2873,22 +2902,21 @@ void nsTableFrame::PlaceChild(nsIPresContext* aPresContext,
* @return true if we successfully reflowed all the mapped children and false
* otherwise, e.g. we pushed children to the next in flow
*/
NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus)
nsReflowStatus& aStatus)
{
NS_PRECONDITION(mFrames.NotEmpty(), "no children");
PRInt32 childCount = 0;
nsIFrame* prevKidFrame = nsnull;
nsSize kidMaxElementSize(0,0);
nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ? &kidMaxElementSize : nsnull;
nsresult rv = NS_OK;
nscoord cellSpacingY = GetCellSpacingY();
nsReflowReason reason;
if (!IsAutoLayout(&aReflowState.reflowState))
{
if (!IsAutoLayout(&aReflowState.reflowState)) {
reason = aReflowState.reflowState.reason;
if (eReflowReason_Incremental==reason) {
reason = eReflowReason_Resize;
@ -2898,22 +2926,26 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
}
}
}
else
else {
reason = eReflowReason_Resize;
}
// determine what section elements are present
PRBool haveTHead, haveTBody, haveTFoot, tHeadBeforeTFoot;
GetSectionInfo(mFrames, haveTHead, haveTBody, haveTFoot, tHeadBeforeTFoot);
// this never passes reflows down to colgroups
for (nsIFrame* kidFrame = mFrames.FirstChild(); nsnull != kidFrame; )
{
nsIFrame* kidFrame = mFrames.FirstChild();
while (kidFrame) {
nsSize kidAvailSize(aReflowState.availSize);
nsHTMLReflowMetrics desiredSize(pKidMaxElementSize);
desiredSize.width=desiredSize.height=desiredSize.ascent=desiredSize.descent=0;
desiredSize.width = desiredSize.height = desiredSize.ascent = desiredSize.descent = 0;
const nsStyleDisplay *childDisplay;
const nsStyleDisplay* childDisplay;
kidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
{
if (IsRowGroup(childDisplay->mDisplay)) {
// Keep track of the first body section row group
if (nsnull == aReflowState.firstBodySection) {
if (!aReflowState.firstBodySection) {
if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay) {
aReflowState.firstBodySection = kidFrame;
}
@ -2934,12 +2966,13 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
kidReflowState.isTopOfPage = PR_FALSE;
}
aReflowState.y += cellSpacingY;
nscoord x = borderPadding.left;
nscoord y = borderPadding.top + aReflowState.y;
nscoord y = aReflowState.y;
if (RowGroupsShouldBeConstrained()) {
// Only applies to the tree widget.
nscoord tableSpecifiedHeight = CalcBorderBoxHeight(aReflowState.reflowState, PR_TRUE);
nscoord tableSpecifiedHeight = CalcBorderBoxHeight(aPresContext, aReflowState.reflowState);
if ((tableSpecifiedHeight != NS_UNCONSTRAINEDSIZE)) {
kidReflowState.availableHeight = tableSpecifiedHeight - y;
if (kidReflowState.availableHeight < 0)
@ -2961,11 +2994,10 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
}
// Place the child
if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
{
if (IsRowGroup(childDisplay->mDisplay)) {
// we don't want to adjust the maxElementSize if this is an initial reflow
// it was set by the TableLayoutStrategy and shouldn't be changed.
nsSize *requestedMaxElementSize = nsnull;
nsSize* requestedMaxElementSize = nsnull;
if (eReflowReason_Initial != aReflowState.reflowState.reason)
requestedMaxElementSize = aDesiredSize.maxElementSize;
PlaceChild(aPresContext, aReflowState, kidFrame, desiredSize,
@ -2973,7 +3005,6 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
} else {
kidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
}
childCount++;
// Remember where we just were in case we end up pushing children
prevKidFrame = kidFrame;
@ -3014,23 +3045,20 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
break;
}
}
else
{// it's an unknown frame type, give it a generic reflow and ignore the results
nsHTMLReflowState kidReflowState(aPresContext,
aReflowState.reflowState, kidFrame,
nsSize(0,0), eReflowReason_Resize);
nsHTMLReflowMetrics unusedDesiredSize(nsnull);
nsReflowStatus status;
ReflowChild(kidFrame, aPresContext, unusedDesiredSize, kidReflowState,
0, 0, 0, status);
kidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
else {// it's an unknown frame type, give it a generic reflow and ignore the results
nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState, kidFrame,
nsSize(0,0), eReflowReason_Resize);
nsHTMLReflowMetrics unusedDesiredSize(nsnull);
nsReflowStatus status;
ReflowChild(kidFrame, aPresContext, unusedDesiredSize, kidReflowState,
0, 0, 0, status);
kidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
}
// Get the next child
kidFrame->GetNextSibling(&kidFrame);
}
// Update the child count
return rv;
}
@ -3287,90 +3315,18 @@ void nsTableFrame::SetTableWidth(nsIPresContext* aPresContext,
SetRect(aPresContext, tableSize);
}
// XXX percentage based margin/border/padding
nscoord GetVerticalMarginBorderPadding(nsIFrame* aFrame,
const nsIID& aIID)
nscoord
GetVertMarginBorderPadding(const nsHTMLReflowState* aReflowState)
{
nscoord result = 0;
if (!aFrame) {
return result;
}
nsCOMPtr<nsIContent> iContent;
nsresult rv = aFrame->GetContent(getter_AddRefs(iContent));
if (NS_SUCCEEDED(rv)) {
nsIHTMLContent* htmlContent = nsnull;
rv = iContent->QueryInterface(aIID, (void **)&htmlContent);
if (htmlContent && NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIStyleContext> styleContext;
aFrame->GetStyleContext(getter_AddRefs(styleContext));
const nsStyleSpacing* spacing =
(const nsStyleSpacing*)styleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin margin(0,0,0,0);
if (spacing->GetMargin(margin)) {
result += margin.top + margin.bottom;
}
if (spacing->GetBorderPadding(margin)) {
result += margin.top + margin.bottom;
}
NS_RELEASE(htmlContent);
}
}
return result;
}
if (!aReflowState) return result;
/* Get the height of the nearest ancestor of this table which has a height other than
* auto, except when there is an ancestor which is a table and that table does not have
* a coord height. It can be the case that the nearest such ancestor is a scroll frame
* or viewport frame; this provides backwards compatibility with Nav4.X and IE.
*/
nscoord nsTableFrame::GetEffectiveContainerHeight(const nsHTMLReflowState& aReflowState)
{
nsIFrame* lastArea = nsnull;
nsIFrame* lastBlock = nsnull;
nsIAtom* frameType = nsnull;
nscoord result = -1;
const nsHTMLReflowState* rs = &aReflowState;
nsMargin margin = aReflowState->mComputedMargin;
nsTableOuterFrame::ZeroAutoMargin(margin);
result += margin.top + margin.bottom;
result += aReflowState->mComputedBorderPadding.top +
aReflowState->mComputedBorderPadding.bottom;
while (rs) {
const nsStyleDisplay* display;
rs->frame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)display);
if (NS_STYLE_DISPLAY_TABLE == display->mDisplay) {
const nsStylePosition* position;
rs->frame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)position);
nsStyleUnit unit = position->mHeight.GetUnit();
if ((eStyleUnit_Null == unit) || (eStyleUnit_Auto == unit)) {
result = 0;
break;
}
}
if (NS_AUTOHEIGHT != rs->mComputedHeight) {
result = rs->mComputedHeight;
// if we get to the scroll frame or viewport frame, then subtract out
// margin/border/padding for the HTML and BODY elements
rs->frame->GetFrameType(&frameType);
if ((nsLayoutAtoms::viewportFrame == frameType) ||
(nsLayoutAtoms::scrollFrame == frameType)) {
result -= GetVerticalMarginBorderPadding(lastArea, kIHTMLElementIID);
result -= GetVerticalMarginBorderPadding(lastBlock, kIBodyElementIID);
}
NS_IF_RELEASE(frameType);
break;
}
// keep track of the area and block frame on the way up because they could
// be the HTML and BODY elements
rs->frame->GetFrameType(&frameType);
if (nsLayoutAtoms::areaFrame == frameType) {
lastArea = rs->frame;
}
else if (nsLayoutAtoms::blockFrame == frameType) {
lastBlock = rs->frame;
}
NS_IF_RELEASE(frameType);
// XXX: evil cast!
rs = (nsHTMLReflowState *)(rs->parentReflowState);
}
NS_ASSERTION(-1 != result, "bad state: no constrained height in reflow chain");
return result;
}
@ -3405,34 +3361,33 @@ void nsTableFrame::DistributeSpaceToCells(nsIPresContext* aPresContext,
void nsTableFrame::DistributeSpaceToRows(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsIFrame* aRowGroupFrame,
const nscoord& aSumOfRowHeights,
const nscoord& aExcess,
const nsStyleTable* aTableStyle,
nscoord aSumOfRowHeights,
nscoord aExcess,
nscoord& aExcessForRowGroup,
nscoord& aRowGroupYPos)
{
// the rows in rowGroupFrame need to be expanded by rowHeightDelta[i]
// and the rowgroup itself needs to be expanded by SUM(row height deltas)
nscoord cellSpacingY = GetCellSpacingY();
nsTableRowGroupFrame* rowGroupFrame = (nsTableRowGroupFrame*)aRowGroupFrame;
nsIFrame * rowFrame = rowGroupFrame->GetFirstFrame();
nscoord y = 0;
while (nsnull!=rowFrame)
{
nsIFrame* rowFrame = rowGroupFrame->GetFirstFrame();
nscoord y = cellSpacingY;
while (rowFrame) {
const nsStyleDisplay *rowDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)rowDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == rowDisplay->mDisplay) {
DistributeSpaceToRows(aPresContext, aReflowState, rowFrame, aSumOfRowHeights,
aExcess, aTableStyle, aExcessForRowGroup, y);
aExcess, aExcessForRowGroup, y);
}
else if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay)
{ // the row needs to be expanded by the proportion this row contributed to the original height
else if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay) {
// the row needs to be expanded by the proportion this row contributed to the original height
nsRect rowRect;
rowFrame->GetRect(rowRect);
float percent = ((float)(rowRect.height)) / ((float)(aSumOfRowHeights));
nscoord excessForRow = NSToCoordRound((float)aExcess*percent);
float percent = ((float)(rowRect.height)) / (float)aSumOfRowHeights;
nscoord excessForRow = NSToCoordRound((float)aExcess * percent);
if (rowGroupFrame->RowsDesireExcessSpace()) {
nsRect newRowRect(rowRect.x, y, rowRect.width, excessForRow+rowRect.height);
nsRect newRowRect(rowRect.x, y, rowRect.width, excessForRow + rowRect.height);
rowFrame->SetRect(aPresContext, newRowRect);
if ((NS_STYLE_BORDER_COLLAPSE == GetBorderCollapseStyle()) && mBorderCollapser) {
PRInt32 rowIndex = ((nsTableRowFrame*)rowFrame)->GetRowIndex();
@ -3440,13 +3395,13 @@ void nsTableFrame::DistributeSpaceToRows(nsIPresContext* aPresContext,
mBorderCollapser->SetBorderEdgeLength(NS_SIDE_RIGHT, rowIndex, newRowRect.height);
}
// better if this were part of an overloaded row::SetRect
y += excessForRow+rowRect.height;
y += excessForRow + rowRect.height;
}
y += cellSpacingY;
aExcessForRowGroup += excessForRow;
}
else
{
else { // XXX why
nsRect rowRect;
rowFrame->GetRect(rowRect);
y += rowRect.height;
@ -3458,11 +3413,14 @@ void nsTableFrame::DistributeSpaceToRows(nsIPresContext* aPresContext,
nsRect rowGroupRect;
aRowGroupFrame->GetRect(rowGroupRect);
if (rowGroupFrame->RowGroupDesiresExcessSpace()) {
nsRect newRowGroupRect(rowGroupRect.x, aRowGroupYPos, rowGroupRect.width, aExcessForRowGroup+rowGroupRect.height);
nsRect newRowGroupRect(rowGroupRect.x, aRowGroupYPos, rowGroupRect.width,
aExcessForRowGroup + rowGroupRect.height);
aRowGroupFrame->SetRect(aPresContext, newRowGroupRect);
aRowGroupYPos += aExcessForRowGroup + rowGroupRect.height;
}
else aRowGroupYPos += rowGroupRect.height;
else {
aRowGroupYPos += rowGroupRect.height;
}
DistributeSpaceToCells(aPresContext, aReflowState, aRowGroupFrame);
}
@ -3478,7 +3436,7 @@ nscoord nsTableFrame::ComputeDesiredHeight(nsIPresContext* aPresContext
}
nscoord result = aDefaultHeight;
nscoord tableSpecifiedHeight = CalcBorderBoxHeight(aReflowState, PR_TRUE);
nscoord tableSpecifiedHeight = CalcBorderBoxHeight(aPresContext, aReflowState);
if ((tableSpecifiedHeight > 0) && (tableSpecifiedHeight != NS_UNCONSTRAINEDSIZE)) {
if (tableSpecifiedHeight > aDefaultHeight) {
result = tableSpecifiedHeight;
@ -3517,7 +3475,7 @@ nscoord nsTableFrame::ComputeDesiredHeight(nsIPresContext* aPresContext
const nsStyleTable* tableStyle;
GetStyleData(eStyleStruct_Table, (const nsStyleStruct *&)tableStyle);
DistributeSpaceToRows(aPresContext, aReflowState, childFrame, sumOfRowHeights,
excess, tableStyle, excessForGroup, rowGroupYPos);
excess, excessForGroup, rowGroupYPos);
// Make sure child views are properly positioned
nsIView* view;
@ -3923,29 +3881,6 @@ nsTableFrame::GetPadding(const nsSize& aBasis,
return padding;
}
NS_METHOD nsTableFrame::GetCellMarginData(nsTableCellFrame* aKidFrame, nsMargin& aMargin)
{
nsresult result = NS_ERROR_NOT_INITIALIZED;
if (aKidFrame) {
nscoord spacingX = GetCellSpacingX();
nscoord spacingY = GetCellSpacingY();
PRInt32 rowIndex, colIndex;
aKidFrame->GetRowIndex(rowIndex);
aKidFrame->GetColIndex(colIndex);
// left/top margins only apply if the cell is a left/top border cell
// there used to be more complicated logic (rev 3.326) dealing with rowspans
// but failure to produce reasonable tests cases does not justify it.
aMargin.left = (0 == colIndex) ? spacingX : 0;
aMargin.top = (0 == rowIndex) ? spacingY : 0;
aMargin.right = spacingX;
aMargin.bottom = spacingY;
result = NS_OK;
}
return result;
}
//XXX: ok, this looks dumb now. but in a very short time this will get filled in
void nsTableFrame::GetTableBorder(nsMargin &aBorder)
{
@ -4109,19 +4044,18 @@ NS_METHOD nsTableFrame::GetTableFrame(nsIFrame *aSourceFrame, nsTableFrame *& aT
/* helper method for determining if this is a nested table or not */
// aReflowState must be the reflow state for this inner table frame, should have an assertion here for that
PRBool nsTableFrame::IsNested(const nsHTMLReflowState& aReflowState, const nsStylePosition *& aPosition) const
PRBool
nsTableFrame::IsNested(const nsHTMLReflowState& aReflowState,
const nsStylePosition*& aPosition) const
{
aPosition = nsnull;
PRBool result = PR_FALSE;
// Walk up the reflow state chain until we find a cell or the root
const nsHTMLReflowState* rs = aReflowState.parentReflowState; // this is for the outer frame
if (rs)
rs = rs->parentReflowState; // and this is the parent of the outer frame
while (nsnull != rs)
{
const nsStyleDisplay *display;
rs->frame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)display);
if (NS_STYLE_DISPLAY_TABLE==display->mDisplay)
{
const nsHTMLReflowState* rs = GetGrandParentReflowState(aReflowState);
while (rs) {
nsCOMPtr<nsIAtom> frameType;
rs->frame->GetFrameType(getter_AddRefs(frameType));
if (nsLayoutAtoms::tableFrame == frameType.get()) {
result = PR_TRUE;
rs->frame->GetStyleData(eStyleStruct_Position, ((const nsStyleStruct *&)aPosition));
break;
@ -4180,39 +4114,15 @@ nscoord nsTableFrame::CalcBorderBoxWidth(const nsHTMLReflowState& aState)
return width;
}
nscoord nsTableFrame::CalcBorderBoxHeight(const nsHTMLReflowState& aState,
PRBool aDoNavHack)
nscoord nsTableFrame::CalcBorderBoxHeight(nsIPresContext* aPresContext,
const nsHTMLReflowState& aState)
{
nscoord height = aState.mComputedHeight;
PRBool isAutoHeight = PR_FALSE;
PRBool isPercentHack = PR_FALSE;
if (eStyleUnit_Auto == aState.mStylePosition->mHeight.GetUnit()) {
isAutoHeight = PR_TRUE;
}
else if (((0 == height) || (NS_UNCONSTRAINEDSIZE == height)) &&
aDoNavHack && (eStyleUnit_Percent == aState.mStylePosition->mHeight.GetUnit())) {
nsIAtom* frameType;
aState.frame->GetFrameType(&frameType);
if (nsLayoutAtoms::tableFrame == frameType) {
float percent = aState.mStylePosition->mHeight.GetPercentValue();
nscoord parentHeight = ((nsTableFrame*)aState.frame)->GetEffectiveContainerHeight(aState);
if ((NS_UNCONSTRAINEDSIZE != parentHeight) && (0 != parentHeight)) {
// css box-sizing not supported for this Nav hack
height = NSToCoordRound((float)parentHeight * percent);
isPercentHack = PR_TRUE;
}
}
NS_IF_RELEASE(frameType);
}
height = PR_MAX(height, 0);
if ((height != NS_UNCONSTRAINEDSIZE) && !isAutoHeight && !isPercentHack) {
nsMargin borderPadding(0,0,0,0);
aState.mStyleSpacing->GetBorderPadding(borderPadding);
if (NS_AUTOHEIGHT != height) {
nsMargin borderPadding = aState.mComputedBorderPadding;
height += borderPadding.top + borderPadding.bottom;
}
height = PR_MAX(0, height);
return height;
}

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

@ -147,8 +147,8 @@ public:
// calculate the height of aFrame including its border and padding given
// its reflow state.
nscoord CalcBorderBoxHeight(const nsHTMLReflowState& aReflowState,
PRBool aDoNavHacks);
nscoord CalcBorderBoxHeight(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState);
// Return the closest sibling of aPriorChildFrame (including aPriroChildFrame)
// of type aChildType.
@ -292,10 +292,6 @@ public:
/** helper to get the cell padding style value */
virtual nscoord GetCellPadding();
// Get cell margin information
NS_IMETHOD GetCellMarginData(nsTableCellFrame* aKidFrame, nsMargin& aMargin);
/** return the row span of a cell, taking into account row span magic at the bottom
* of a table. The row span equals the number of rows spanned by aCell starting at
* aStartRowIndex, and can be smaller if aStartRowIndex is greater than the row
@ -450,7 +446,8 @@ protected:
* If not nested, undefined.
* @return PR_TRUE if this table is nested inside another table.
*/
PRBool IsNested(const nsHTMLReflowState& aReflowState, const nsStylePosition *& aPosition) const;
PRBool IsNested(const nsHTMLReflowState& aReflowState,
const nsStylePosition*& aPosition) const;
// Sets the starting column index for aColGroupFrame and the siblings frames that
// follow
@ -576,17 +573,16 @@ protected:
/** The following two functions are helpers for ComputeDesiredHeight
*/
void DistributeSpaceToCells(nsIPresContext* aPresContext,
void DistributeSpaceToCells(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsIFrame* aRowGroupFrame);
void DistributeSpaceToRows(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsIFrame* aRowGroupFrame, const nscoord& aSumOfRowHeights,
const nscoord& aExcess, const nsStyleTable* aTableStyle,
nscoord& aExcessForRowGroup,
nscoord& aRowGroupYPos);
nscoord GetEffectiveContainerHeight(const nsHTMLReflowState& aReflowState);
nsIFrame* aRowGroupFrame);
void DistributeSpaceToRows(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsIFrame* aRowGroupFrame,
nscoord aSumOfRowHeights,
nscoord aExcess,
nscoord& aExcessForRowGroup,
nscoord& aRowGroupYPos);
void PlaceChild(nsIPresContext* aPresContext,
InnerTableReflowState& aReflowState,
@ -653,6 +649,11 @@ protected:
nsIFrame* aFromChild,
nsIFrame* aPrevSibling);
void GetSectionInfo(nsFrameList& aKidFrames,
PRBool& aHaveTHead,
PRBool& aHaveTBody,
PRBool& aHaveTFoot,
PRBool& aTHeadBeforeTFoot);
public:
// Returns PR_TRUE if there are any cells above the row at
// aRowIndex and spanning into the row at aRowIndex
@ -811,7 +812,8 @@ public: /* ----- Cell Map public methods ----- */
// compute the height of the table to be used as the basis for
// percentage height cells
void ComputePercentBasisForRows(const nsHTMLReflowState& aReflowState);
void ComputePercentBasisForRows(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState);
nscoord GetPercentBasisForRows();

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -27,7 +27,6 @@
#include "nsBlockFrame.h"
#include "nsITableLayout.h"
struct OuterTableReflowState;
struct nsStyleTable;
class nsTableCaptionFrame : public nsBlockFrame
@ -74,6 +73,8 @@ public:
NS_IMETHOD Destroy(nsIPresContext* aPresContext);
NS_IMETHOD IsPercentageBase(PRBool& aBase) const;
NS_IMETHOD AdjustZeroWidth();
/** @see nsIFrame::SetInitialChildList */
@ -158,6 +159,11 @@ public:
/** @see nsITableFrame::GetTableSize */
NS_IMETHOD GetTableSize(PRInt32& aRowCount, PRInt32& aColCount);
static void PositionView(nsIPresContext* aPresContext,
nsIFrame* aFrame);
static void ZeroAutoMargin(nsMargin& aMargin);
protected:
@ -197,61 +203,59 @@ protected:
virtual void DeleteChildsNextInFlow(nsIPresContext* aPresContext, nsIFrame* aChild);
// begin Incremental Reflow methods
/** prepare aReflowState for an incremental reflow */
NS_IMETHOD RecoverState(OuterTableReflowState& aReflowState, nsIFrame* aKidFrame);
/** process an incremental reflow command */
NS_IMETHOD IncrementalReflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
OuterTableReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD IncrementalReflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** process an incremental reflow command targeted at a child of this frame. */
NS_IMETHOD IR_TargetIsChild(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
OuterTableReflowState& aReflowState,
nsReflowStatus& aStatus,
nsIFrame * aNextFrame);
NS_IMETHOD IR_TargetIsChild(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus,
nsIFrame * aNextFrame);
/** process an incremental reflow command targeted at the table inner frame. */
NS_IMETHOD IR_TargetIsInnerTableFrame(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
OuterTableReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD IR_TargetIsInnerTableFrame(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** process an incremental reflow command targeted at the caption. */
NS_IMETHOD IR_TargetIsCaptionFrame(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
OuterTableReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD IR_TargetIsCaptionFrame(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** process an incremental reflow command targeted at this frame.
* many incremental reflows that are targeted at this outer frame
* are actually handled by the inner frame. The logic to decide this
* is here.
*/
NS_IMETHOD IR_TargetIsMe(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
OuterTableReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD IR_TargetIsMe(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** pass along the incremental reflow command to the inner table. */
NS_IMETHOD IR_InnerTableReflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
OuterTableReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD IR_InnerTableReflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** handle incremental reflow notification that a caption was inserted. */
NS_IMETHOD IR_CaptionInserted(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
OuterTableReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD IR_CaptionInserted(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** handle incremental reflow notification that we have dirty child frames */
NS_IMETHOD IR_ReflowDirty(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
OuterTableReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD IR_ReflowDirty(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** handle incremental reflow notification that the caption style was changed
* such that it is now left|right instead of top|bottom, or vice versa.
@ -259,25 +263,93 @@ protected:
PRBool IR_CaptionChangedAxis(const nsStyleTable* aOldStyle,
const nsStyleTable* aNewStyle) const;
/** set the size and the location of both the inner table frame and the caption. */
NS_IMETHOD SizeAndPlaceChildren(nsIPresContext* aPresContext,
const nsSize& aInnerSize,
const nsSize& aCaptionSize,
OuterTableReflowState& aReflowState,
const nsMargin& aCaptionMargin);
// end Incremental Reflow methods
// end Incremental Reflow methods
// The following function at least lets the tree widget work
// inside boxes. It repairs the reflow state after it's been
// screwed up by the nsHTMLReflowState code.
// When the reflow state is constructed, mComputedWidth and mComputedHeight get set
// to the table's styled width and height. Flex from XUL boxes can make the styled #s
// inaccurate, which means that mComputedWidth and mComputedHeight from the parent
// reflow state should be used instead.
// The following function will patch the reflow state so that trees behave properly inside boxes.
// This might work for tables as well, but not until regression tests can be run to make sure,
NS_IMETHOD FixBadReflowState(const nsHTMLReflowState& aParentReflowState,
nsHTMLReflowState& aChildReflowState) { return NS_OK; };
nsSize GetMaxElementSize(const nsMargin& aInnerMargin,
const nsMargin& aInnerPadding,
const nsMargin& aCaptionMargin);
nscoord GetMaxWidth(PRUint8 aCaptionSide,
const nsMargin& aInnerMargin,
const nsMargin& aCaptionMargin);
PRUint8 GetCaptionSide();
void SetDesiredSize(PRUint8 aCaptionSide,
const nsMargin& aInnerMargin,
const nsMargin& aCaptionMargin,
nscoord& aWidth,
nscoord& aHeight);
NS_IMETHOD GetCaptionOrigin(nsIPresContext* aPresContext,
PRUint32 aCaptionSide,
const nsSize& aContainBlockSize,
const nsSize& aInnerSize,
const nsMargin& aInnerMargin,
const nsSize& aCaptionSize,
nsMargin& aCaptionMargin,
nsPoint& aOrigin);
NS_IMETHOD GetInnerOrigin(nsIPresContext* aPresContext,
PRUint32 aCaptionSide,
const nsSize& aContainBlockSize,
const nsSize& aCaptionSize,
const nsMargin& aCaptionMargin,
const nsSize& aInnerSize,
nsMargin& aInnerMargin,
nsPoint& aOrigin);
nscoord GetChildAvailWidth(nsIPresContext* aPresContext,
nsIFrame* aChildFrame,
const nsHTMLReflowState& aOuterRS,
nscoord aOuterWidth,
nsMargin& aMargin,
nsMargin& aPadding);
nscoord GetCaptionAvailWidth(nsIPresContext* aPresContext,
nsIFrame* aCaptionFrame,
const nsHTMLReflowState& aReflowState,
nscoord* aInnerWidth = nsnull,
const nsMargin* aInnerMargin = nsnull);
NS_IMETHOD OuterReflowChild(nsIPresContext* aPresContext,
nsIFrame* aChildFrame,
const nsHTMLReflowState& aOuterRS,
nsHTMLReflowMetrics& aMetrics,
nscoord* aAvailWidth,
nsSize& aDesiredSize,
nsMargin& aMargin,
nsMargin& aPadding,
nsReflowReason aReflowReason,
nsReflowStatus& aStatus);
void UpdateReflowMetrics(PRUint8 aCaptionSide,
nsHTMLReflowMetrics& aMet,
const nsMargin& aInnerMargin,
const nsMargin& aInnerPadding,
const nsMargin& aCaptionPadding);
void InvalidateDamage(nsIPresContext* aPresContext,
PRUint8 aCaptionSide,
nsSize& aOuterSize,
PRBool aInnerChanged,
PRBool aCaptionChanged);
private:
/** used to keep track of this frame's children */
nsIFrame *mInnerTableFrame; // XXX this is redundant, mFrames holds the same
nsIFrame *mCaptionFrame;
nsIFrame* mInnerTableFrame; // XXX this is redundant, mFrames holds the same
nsIFrame* mCaptionFrame;
/** used to track caption max element size */
PRInt32 mMinCaptionWidth;

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

@ -244,11 +244,10 @@ nsTableRowFrame::DidResize(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState)
{
// Resize and re-align the cell frames based on our row height
nscoord cellMaxTopMargin = GetTopMargin();
nscoord cellMaxBottomMargin = GetBottomMargin();
nscoord rowCellHeight = mRect.height - cellMaxTopMargin - cellMaxBottomMargin;
nsTableFrame* tableFrame;
nsTableFrame::GetTableFrame(this, tableFrame);
if (!tableFrame) return;
nscoord cellSpacingY = tableFrame->GetCellSpacingY();
nsTableIterator iter(aPresContext, *this, eTableDIR);
nsIFrame* cellFrame = iter.First();
@ -258,7 +257,7 @@ nsTableRowFrame::DidResize(nsIPresContext* aPresContext,
cellFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)kidDisplay));
if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay) {
PRInt32 rowSpan = tableFrame->GetEffectiveRowSpan((nsTableCellFrame &)*cellFrame);
nscoord cellHeight = rowCellHeight;
nscoord cellHeight = mRect.height;
// add in height of rows spanned beyond the 1st one
nsIFrame* nextRow = nsnull;
GetNextSibling(&nextRow);
@ -271,6 +270,7 @@ nsTableRowFrame::DidResize(nsIPresContext* aPresContext,
cellHeight += rect.height;
i++;
}
cellHeight += cellSpacingY;
nextRow->GetNextSibling(&nextRow);
}
@ -365,20 +365,8 @@ NS_METHOD nsTableRowFrame::Paint(nsIPresContext* aPresContext,
return rv;
}
nscoord cellSpacingX = tableFrame->GetCellSpacingX();
nscoord halfCellSpacingY =
NSToCoordRound(((float)tableFrame->GetCellSpacingY()) / (float)2);
// every row is short by the ending cell spacing X
nsRect rect(0, 0, mRect.width + cellSpacingX, mRect.height);
// first row may have gotten too much cell spacing Y
if (tableFrame->GetRowCount() != 1) {
if (IsFirstRow(aPresContext, *tableFrame, *this)) {
rect.height -= halfCellSpacingY;
}
else {
rect.height += halfCellSpacingY;
rect.y -= halfCellSpacingY;
}
}
nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this,
aDirtyRect, rect, *color, *spacing, 0, 0);
@ -514,24 +502,6 @@ nscoord nsTableRowFrame::GetTallestChild() const
return mTallestCell;
}
nscoord nsTableRowFrame::GetTopMargin() const
{
nsTableFrame *tableFrame;
nsTableFrame::GetTableFrame((nsIFrame*)this, tableFrame);
// Only cells in the first row have a top margin
return (GetRowIndex() == 0) ? tableFrame->GetCellSpacingY() : 0;
}
nscoord nsTableRowFrame::GetBottomMargin() const
{
nsTableFrame *tableFrame;
nsTableFrame::GetTableFrame((nsIFrame*)this, tableFrame);
// All cells have the same bottom margin
return tableFrame->GetCellSpacingY();
}
/* GetMinRowSpan is needed for deviant cases where every cell in a row has a rowspan > 1.
* It sets mMinRowSpan, which is used in FixMinCellHeight and PlaceChild
*/
@ -636,14 +606,7 @@ void nsTableRowFrame::PlaceChild(nsIPresContext* aPresContext,
aReflowState.maxCellHeight = aDesiredSize.height;
// Update maxCellVertSpace
nsMargin margin;
if (aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)aKidFrame, margin) == NS_OK) {
nscoord height = aDesiredSize.height + margin.top + margin.bottom;
if (height > aReflowState.maxCellVertSpace)
aReflowState.maxCellVertSpace = height;
}
aReflowState.maxCellVertSpace = PR_MAX(aDesiredSize.height, aReflowState.maxCellVertSpace);
}
#endif
}
@ -880,7 +843,7 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
reason);
nsReflowStatus status;
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState,
aReflowState.x, GetTopMargin(), 0, status);
aReflowState.x, 0, 0, status);
#ifdef NS_DEBUG
if (desiredSize.width > availWidth)
{
@ -935,7 +898,7 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
// Place the child
PlaceChild(aPresContext, aReflowState, kidFrame, desiredSize,
aReflowState.x, GetTopMargin(),
aReflowState.x, 0,
aDesiredSize.maxElementSize, kidMaxElementSize);
}
@ -996,6 +959,7 @@ nsTableRowFrame::InitialReflow(nsIPresContext* aPresContext,
nscoord x = 0;
nsTableFrame* table = aReflowState.tableFrame;
PRBool isAutoLayout = table->IsAutoLayout(&aReflowState.reflowState);
nscoord cellSpacingX = table->GetCellSpacingX();
nsIFrame* kidFrame;
if (nsnull==aStartFrame)
@ -1003,29 +967,20 @@ nsTableRowFrame::InitialReflow(nsIPresContext* aPresContext,
else
kidFrame = aStartFrame;
for ( ; nsnull != kidFrame; kidFrame->GetNextSibling(&kidFrame))
{
for ( ; nsnull != kidFrame; kidFrame->GetNextSibling(&kidFrame)) {
const nsStyleDisplay *kidDisplay;
kidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)kidDisplay));
if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay)
{
// Get the child's margins
// Get the frame's margins
nsMargin kidMargin;
aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, kidMargin);
if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay) {
// For the initial reflow always allow the child to be as high as it
// wants. The default available width is also unconstrained so we can
// get the child's maximum width
nsSize kidAvailSize;
nsHTMLReflowMetrics kidSize(nsnull);
if (isAutoLayout)
{
if (isAutoLayout) {
kidAvailSize.SizeTo(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
kidSize.maxElementSize=&kidMaxElementSize;
}
else
{
else {
PRInt32 colIndex;
((nsTableCellFrame *)kidFrame)->GetColIndex(colIndex);
kidAvailSize.SizeTo(table->GetColumnWidth(colIndex), NS_UNCONSTRAINEDSIZE);
@ -1037,7 +992,7 @@ nsTableRowFrame::InitialReflow(nsIPresContext* aPresContext,
eReflowReason_Initial);
rv = ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState,
x + kidMargin.left, kidMargin.top, 0, aStatus);
x + cellSpacingX, 0, 0, aStatus);
// the following signals bugs in the content frames.
if (kidMaxElementSize.width > kidSize.width) {
@ -1056,10 +1011,10 @@ nsTableRowFrame::InitialReflow(nsIPresContext* aPresContext,
NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "unexpected child reflow status");
// Place the child
x += kidMargin.left;
PlaceChild(aPresContext, aReflowState, kidFrame, kidSize, x, kidMargin.top,
x += cellSpacingX;
PlaceChild(aPresContext, aReflowState, kidFrame, kidSize, x, 0,
aDesiredSize.maxElementSize, &kidMaxElementSize);
x += kidSize.width + kidMargin.right;
x += kidSize.width + cellSpacingX;
}
else
{// it's an unknown frame type, give it a generic reflow and ignore the results
@ -1108,10 +1063,6 @@ NS_METHOD nsTableRowFrame::RecoverState(nsIPresContext* aPresContext,
frame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)kidDisplay));
if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay) {
// Get the child's margins
nsMargin kidMargin;
aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)frame, kidMargin);
// Update maxCellHeight and maxVertCellSpace. When determining this we
// don't include cells that span rows
PRInt32 rowSpan = aReflowState.tableFrame->GetEffectiveRowSpan((nsTableCellFrame &)*frame);
@ -1130,10 +1081,7 @@ NS_METHOD nsTableRowFrame::RecoverState(nsIPresContext* aPresContext,
}
// Update maxCellVertHeight
nscoord vertHeight = desiredSize.height + kidMargin.top + kidMargin.bottom;
if (vertHeight > aReflowState.maxCellVertSpace) {
aReflowState.maxCellVertSpace = vertHeight;
}
aReflowState.maxCellVertSpace = PR_MAX(desiredSize.height, aReflowState.maxCellVertSpace);
}
// Recover the max element size if requested
@ -1293,7 +1241,7 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
// in a max width of NS_UNCONSTRAINEDSIZE, because the max width must match
// the width of the previous reflow...
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState,
aReflowState.x, GetTopMargin(), 0, aStatus);
aReflowState.x, 0, 0, aStatus);
// Update the cell layout data.. If the cell's maximum width changed,
// then inform the table that its maximum width needs to be recomputed
@ -1334,7 +1282,7 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
// Now place the child
PlaceChild(aPresContext, aReflowState, aNextFrame, desiredSize, aReflowState.x,
GetTopMargin(), aDesiredSize.maxElementSize, &kidMaxElementSize);
0, aDesiredSize.maxElementSize, &kidMaxElementSize);
SetMaxChildHeight(aReflowState.maxCellHeight);

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

@ -168,8 +168,6 @@ public:
/** returns the tallest child in this row (ignoring any cell with rowspans) */
nscoord GetTallestChild() const;
nscoord GetTopMargin() const;
nscoord GetBottomMargin() const;
/** returns the ordinal position of this row in its table */
virtual PRInt32 GetRowIndex() const;

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

@ -181,23 +181,7 @@ NS_METHOD nsTableRowGroupFrame::Paint(nsIPresContext* aPresContext,
if (NS_FAILED(rv) || (nsnull == tableFrame)) {
return rv;
}
nscoord halfCellSpacingY =
NSToCoordRound(((float)tableFrame->GetCellSpacingY()) / (float)2);
// every row group is short by the ending cell spacing X
nsRect rect(0, 0, mRect.width, mRect.height);
nsIFrame* firstRowGroup = nsnull;
tableFrame->FirstChild(aPresContext, nsnull, &firstRowGroup);
// first row group may have gotten too much cell spacing Y
if (tableFrame->GetRowCount() != 1) {
if (this == firstRowGroup) {
rect.height -= halfCellSpacingY;
}
else {
rect.height += halfCellSpacingY;
rect.y -= halfCellSpacingY;
}
}
nsRect rect(0,0,mRect.width, mRect.height);
nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this,
aDirtyRect, rect, *color, *spacing, 0, 0);
}
@ -335,7 +319,12 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext* aPresC
{
nsSize kidMaxElementSize;
nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ? &kidMaxElementSize : nsnull;
nsresult rv = NS_OK;
nsTableFrame* tableFrame = nsnull;
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame);
if (NS_FAILED(rv) || !tableFrame) return rv;
nscoord cellSpacingY = tableFrame->GetCellSpacingY();
if (!ContinueReflow(nsnull, aPresContext, aReflowState.y, aReflowState.availSize.height))
return rv;
@ -413,12 +402,11 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext* aPresC
/* if the table has collapsing borders, we need to reset the length of the shared vertical borders
* for the table and the cells that overlap this row
*/
if ((eReflowReason_Initial != aReflowState.reflowState.reason) && (NS_STYLE_BORDER_COLLAPSE==borderStyle))
{
if ((eReflowReason_Initial != aReflowState.reflowState.reason) &&
(NS_STYLE_BORDER_COLLAPSE==borderStyle)) {
const nsStyleDisplay *childDisplay;
kidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
{
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay) {
PRInt32 rowIndex = ((nsTableRowFrame*)kidFrame)->GetRowIndex();
aReflowState.tableFrame->SetBorderEdgeLength(NS_SIDE_LEFT,
rowIndex,
@ -446,13 +434,14 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext* aPresC
}
}
}
aReflowState.y += cellSpacingY;
} else {
// Adjust the running y-offset so we know where the next row should
// be placed
nsSize kidSize;
kidFrame->GetSize(kidSize);
aReflowState.y += kidSize.height;
aReflowState.y += kidSize.height + cellSpacingY;
}
if (PR_FALSE==aDoSiblings)
@ -555,8 +544,8 @@ AllocateSpecialHeight(nsIPresContext* aPresContext,
* Actual row heights are ultimately determined by the table, when the table
* height attribute is factored in.
*/
void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState)
{
nsTableFrame* tableFrame = nsnull;
@ -597,11 +586,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
startRowIndex = ((nsTableRowFrame*)rowFrame)->GetRowIndex();
}
// get the height of the tallest cell in the row (excluding cells that span rows)
nscoord maxCellHeight = ((nsTableRowFrame*)rowFrame)->GetTallestChild();
nscoord topMargin = ((nsTableRowFrame*)rowFrame)->GetTopMargin();
nscoord bottomMargin = ((nsTableRowFrame*)rowFrame)->GetBottomMargin();
nscoord maxRowHeight = maxCellHeight + topMargin + bottomMargin;
rowHeights[rowIndex] = maxRowHeight;
rowHeights[rowIndex] = ((nsTableRowFrame*)rowFrame)->GetTallestChild();
// See if a cell spans into the row. If so we'll have to do step 2
if (!hasRowSpanningCell) {
if (tableFrame->RowIsSpannedInto(rowIndex + startRowIndex)) {
@ -649,6 +634,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
if (rowSpan > 1) { // found a cell with rowspan > 1, determine the height
// of the rows it spans
nscoord heightOfRowsSpanned = 0;
nscoord cellSpacingOfRowsSpanned = 0;
PRInt32 spanX;
PRBool cellsOrigInSpan = PR_FALSE; // do any cells originate in the spanned rows
for (spanX = 0; spanX < rowSpan; spanX++) {
@ -658,9 +644,11 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
heightOfRowsSpanned += rowHeights[rowIndex + spanX];
cellsOrigInSpan = PR_TRUE;
}
if (0 != spanX) {
cellSpacingOfRowsSpanned += cellSpacingY;
}
}
// reduce the height by top and bottom margins
nscoord availHeightOfRowsSpanned = heightOfRowsSpanned - cellSpacingY - cellSpacingY;
nscoord availHeightOfRowsSpanned = heightOfRowsSpanned + cellSpacingOfRowsSpanned;
// see if the cell's height fits within the rows it spans. If this is
// pass 1 then use the cell's desired height and not the current height
@ -675,7 +663,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
}
if (availHeightOfRowsSpanned >= cellFrameSize.height) {
// yes the cell's height fits with the available space of the rows it
// the cell's height fits with the available space of the rows it
// spans. Set the cell frame's height
cellFrame->SizeTo(aPresContext, cellFrameSize.width, availHeightOfRowsSpanned);
// Realign cell content based on new height
@ -800,6 +788,9 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
nsSize rowSize;
rowFrame->GetSize(rowSize);
rowGroupHeight += rowSize.height;
if (0 != rowIndex) {
rowGroupHeight += cellSpacingY;
}
GetNextFrame(rowFrame, &rowFrame); // Get the next row
rowIndex++;
@ -1371,24 +1362,28 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext* aPresContext,
return rv;
}
NS_METHOD nsTableRowGroupFrame::GetHeightOfRows(nsIPresContext* aPresContext, nscoord& aResult)
NS_METHOD nsTableRowGroupFrame::GetHeightOfRows(nsIPresContext* aPresContext,
nscoord& aResult)
{
nsTableFrame* tableFrame = nsnull;
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame);
if (NS_FAILED(rv) || !tableFrame) return rv;
nscoord cellSpacingY = tableFrame->GetCellSpacingY();
// the rows in rowGroupFrame need to be expanded by rowHeightDelta[i]
// and the rowgroup itself needs to be expanded by SUM(row height deltas)
nsIFrame * rowFrame=nsnull;
nsresult rv = FirstChild(aPresContext, nsnull, &rowFrame);
while ((NS_SUCCEEDED(rv)) && (nsnull!=rowFrame))
{
const nsStyleDisplay *rowDisplay;
nsIFrame* rowFrame = nsnull;
rv = FirstChild(aPresContext, nsnull, &rowFrame);
while ((NS_SUCCEEDED(rv)) && (nsnull!=rowFrame)) {
const nsStyleDisplay* rowDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)rowDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay)
{
if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay) {
nsRect rowRect;
rowFrame->GetRect(rowRect);
aResult += rowRect.height;
}
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == rowDisplay->mDisplay)
{
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == rowDisplay->mDisplay) {
((nsTableRowGroupFrame*)rowFrame)->GetHeightOfRows(aPresContext, aResult);
}
GetNextFrame(rowFrame, &rowFrame);

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

@ -593,12 +593,6 @@ nsBoxToBlockAdaptor::Reflow(nsBoxLayoutState& aState,
printf(" reason=%s %s",reflowReasonString,ch);
#endif
nsHTMLReflowState reflowState(aPresContext, aReflowState, mFrame, nsSize(size.width, NS_INTRINSICSIZE));
reflowState.reason = reason;
if (reason != eReflowReason_Incremental)
reflowState.reflowCommand = nsnull;
if (size.height != NS_INTRINSICSIZE) {
size.height -= (border.top + border.bottom);
NS_ASSERTION(size.height >= 0,"Error top bottom border too large");
@ -609,6 +603,12 @@ nsBoxToBlockAdaptor::Reflow(nsBoxLayoutState& aState,
NS_ASSERTION(size.height >= 0,"Error left right border too large");
}
nsHTMLReflowState reflowState(aPresContext, aReflowState, mFrame, nsSize(size.width, NS_INTRINSICSIZE));
reflowState.reason = reason;
if (reason != eReflowReason_Incremental)
reflowState.reflowCommand = nsnull;
// XXX this needs to subtract out the border and padding of mFrame since it is content size
reflowState.mComputedWidth = size.width;
reflowState.mComputedHeight = size.height;
#ifdef DEBUG_REFLOW

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

@ -122,7 +122,6 @@ nsTreeOuterFrame::Reflow(nsIPresContext* aPresContext,
return Reflow(aPresContext, aDesiredSize, goodState, aStatus);
}
if (aReflowState.mComputedWidth == NS_UNCONSTRAINEDSIZE) {
NS_WARNING("Inefficient XUL: Reflowing outer tree frame with unconstrained width, try giving it a width in CSS!");
nsHTMLReflowState goodState(aReflowState);

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

@ -1632,7 +1632,13 @@ nsTreeRowGroupFrame::ReflowScrollbar(nsIPresContext* aPresContext)
nsXULAtoms::maxpos, value);
if(value != maxpos){
// mark as having dirty children to avoid generating a reflow on SetAttribute
PRBool dirtyChildren(mState & NS_FRAME_HAS_DIRTY_CHILDREN);
mState |= NS_FRAME_HAS_DIRTY_CHILDREN;
scrollbarContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::maxpos, maxpos, PR_TRUE);
if (!dirtyChildren) {
mState &= ~NS_FRAME_HAS_DIRTY_CHILDREN;
}
}
}