include the border width for border collapsed tables as required by CSS 2.1. We implemented before what CSS 2.0 required and it was ugly, so the spec changed. r=fantasai sr=roc, bug 155955

This commit is contained in:
Bernd 2009-02-08 17:46:42 +01:00
parent 3ba502a047
commit acce04933d
20 changed files with 149 additions and 74 deletions

View File

@ -2,7 +2,6 @@
<html>
<style>
table {
margin: 1px;
border: .1mm solid black;
border-collapse: collapse;
}

View File

@ -41,7 +41,7 @@
(1px of border outside width)
*/
div { width: 57px; height: 19px; margin: 38px 117px 80px 120px; }
div { width: 57px; height: 19px; margin: 40px 118px 86px 123px; }
div.color { background-color: aqua; }
div.imagetl, div.imagebr {

View File

@ -41,7 +41,7 @@
(1px of border outside width)
*/
div { width: 171px; height: 97px; margin: 0px 60px 2px 63px; }
div { width: 171px; height: 97px; margin: 2px 61px 8px 66px; }
div.color { background-color: aqua; }
div.imagetl, div.imagebr {

View File

@ -41,7 +41,7 @@
(1px of border outside width)
*/
div { width: 57px; height: 97px; margin: 0px 117px 2px 120px; }
div { width: 57px; height: 97px; margin: 2px 121px 8px 123px; }
div.color { background-color: aqua; }
div.imagetl, div.imagebr {

View File

@ -41,15 +41,15 @@
(1px of border outside width)
*/
div { width: 287px; height: 97px; margin: 0px 3px 2px 4px; }
div { width: 291px; height: 103px; margin: 0px 3px 2px 4px; }
div.color { background-color: aqua; }
div.imagetl, div.imagebr {
background-image: url(repeatable-diagonal-gradient-with-ticks.png);
}
div.imagetl { background-position: 0 0; }
div.imagebr { background-position: 287px 97px; }
div.imagetl { background-position: 3px 2px; }
div.imagebr { background-position: 290px 99px; }
</style>
</head>

View File

@ -41,7 +41,7 @@
(1px of border outside width)
*/
div { width: 287px; height: 57px; margin: 19px 3px 42px 4px; }
div { width: 287px; height: 57px; margin: 21px 4px 48px 7px; }
div.color { background-color: aqua; }
div.imagetl, div.imagebr {

View File

@ -41,7 +41,7 @@
(1px of border outside width)
*/
div { width: 287px; height: 19px; margin: 38px 3px 80px 4px; }
div { width: 287px; height: 19px; margin: 40px 4px 86px 7px; }
div.color { background-color: aqua; }
div.imagetl, div.imagebr {

View File

@ -39,7 +39,7 @@
(1px of border outside width)
*/
div { width: 57px; height: 19px; margin: 38px 117px 80px 120px; }
div { width: 57px; height: 19px; margin: 40px 118px 86px 123px; }
div.color { background-color: aqua; }
div.imagetl, div.imagebr {

View File

@ -39,7 +39,7 @@
(1px of border outside width)
*/
div { width: 171px; height: 97px; margin: 0px 60px 2px 63px; }
div { width: 171px; height: 97px; margin: 2px 61px 8px 66px; }
div.color { background-color: aqua; }
div.imagetl, div.imagebr {

View File

@ -39,7 +39,7 @@
(1px of border outside width)
*/
div { width: 57px; height: 97px; margin: 0px 117px 2px 120px; }
div { width: 57px; height: 97px; margin: 2px 121px 8px 123px; }
div.color { background-color: aqua; }
div.imagetl, div.imagebr {

View File

@ -39,15 +39,15 @@
(1px of border outside width)
*/
div { width: 287px; height: 97px; margin: 0px 3px 2px 4px; }
div { width: 291px; height: 103px; margin: 0px 3px 2px 4px; }
div.color { background-color: aqua; }
div.imagetl, div.imagebr {
background-image: url(repeatable-diagonal-gradient-with-ticks.png);
}
div.imagetl { background-position: 0 0; }
div.imagebr { background-position: 287px 97px; }
div.imagetl { background-position: 3px 2px;}
div.imagebr { background-position: 290px 99px;}
</style>
</head>

View File

@ -39,7 +39,7 @@
(1px of border outside width)
*/
div { width: 287px; height: 57px; margin: 19px 3px 42px 4px; }
div { width: 287px; height: 57px; margin: 21px 4px 48px 7px; }
div.color { background-color: aqua; }
div.imagetl, div.imagebr {

View File

@ -39,7 +39,7 @@
(1px of border outside width)
*/
div { width: 287px; height: 19px; margin: 38px 3px 80px 4px; }
div { width: 287px; height: 19px; margin: 40px 4px 86px 7px; }
div.color { background-color: aqua; }
div.imagetl, div.imagebr {

View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<style>
td {width: 100px; text-align:center}
div {position:absolute; border:green 4px solid}
</style>
</head>
<body>
<div>
<table style="border-collapse:collapse;">
<tr><td style="border:solid 4px orange; height:30px">cell 1</td></tr>
</table>
</div>
</body>
</html>

View File

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<style>
td {width: 100px; text-align:center}
div {position:absolute; border:green 4px solid}
</style>
</head>
<body>
<!-- the height for table cells includes the border -->
<div>
<table cellspacing="0">
<tr><td style="border:solid 4px orange; height:34px">cell 1</td></tr>
</table>
</div>
</body>
</html>

View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<style>
td {width: 100px; text-align:center}
caption {border:solid 4px green}
</style>
</head>
<body>
<table style="border-collapse:collapse;"><caption>caption</caption>
<tr><td style="border:solid 4px orange; height:30px">cell 1</td></tr>
</table>
</body>
</html>

View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<style>
td {width: 100px; text-align:center}
caption {border:solid 4px green}
</style>
</head>
<body>
<table cellspacing="0" cellpadding="0"><caption>caption</caption>
<tr>
<td style="border:solid 4px orange; width:102px; height:34px">cell 1</td>
</tr>
</table>
</body>
</html>

View File

@ -18,3 +18,5 @@
== bc_dyn_table1.html bc_dyn_table1_ref.html
== bc_dyn_table2.html bc_dyn_table2_ref.html
== bc_dyn_table3.html bc_dyn_table3_ref.html
== bc_borderoffset1.html bc_borderoffset1_ref.html
== bc_borderoffset2.html bc_borderoffset2_ref.html

View File

@ -145,13 +145,17 @@ struct nsTableReflowState {
struct BCPropertyData
{
BCPropertyData() { mDamageArea.x = mDamageArea.y = mDamageArea.width = mDamageArea.height =
mTopBorderWidth = mRightBorderWidth = mBottomBorderWidth = mLeftBorderWidth = 0; }
BCPropertyData() { mDamageArea.x = mDamageArea.y = mDamageArea.width =
mDamageArea.height = mTopBorderWidth = mRightBorderWidth =
mBottomBorderWidth = mLeftBorderWidth =
mLeftCellBorderWidth = mRightCellBorderWidth = 0; }
nsRect mDamageArea;
BCPixelSize mTopBorderWidth;
BCPixelSize mRightBorderWidth;
BCPixelSize mBottomBorderWidth;
BCPixelSize mLeftBorderWidth;
BCPixelSize mLeftCellBorderWidth;
BCPixelSize mRightCellBorderWidth;
};
NS_IMETHODIMP
@ -2550,10 +2554,10 @@ nsTableFrame::GetOuterBCBorder() const
BCPropertyData* propData =
(BCPropertyData*)nsTableFrame::GetProperty((nsIFrame*)this, nsGkAtoms::tableBCProperty, PR_FALSE);
if (propData) {
border.top += BC_BORDER_TOP_HALF_COORD(p2t, propData->mTopBorderWidth);
border.right += BC_BORDER_RIGHT_HALF_COORD(p2t, propData->mRightBorderWidth);
border.bottom += BC_BORDER_BOTTOM_HALF_COORD(p2t, propData->mBottomBorderWidth);
border.left += BC_BORDER_LEFT_HALF_COORD(p2t, propData->mLeftBorderWidth);
border.top = BC_BORDER_TOP_HALF_COORD(p2t, propData->mTopBorderWidth);
border.right = BC_BORDER_RIGHT_HALF_COORD(p2t, propData->mRightBorderWidth);
border.bottom = BC_BORDER_BOTTOM_HALF_COORD(p2t, propData->mBottomBorderWidth);
border.left = BC_BORDER_LEFT_HALF_COORD(p2t, propData->mLeftBorderWidth);
}
return border;
}
@ -2561,21 +2565,28 @@ nsTableFrame::GetOuterBCBorder() const
nsMargin
nsTableFrame::GetIncludedOuterBCBorder() const
{
if (eCompatibility_NavQuirks == PresContext()->CompatibilityMode()) {
return GetOuterBCBorder();
}
if (NeedToCalcBCBorders())
const_cast<nsTableFrame*>(this)->CalcBCBorders();
nsMargin border(0, 0, 0, 0);
PRInt32 p2t = nsPresContext::AppUnitsPerCSSPixel();
BCPropertyData* propData =
(BCPropertyData*)nsTableFrame::GetProperty((nsIFrame*)this,
nsGkAtoms::tableBCProperty,
PR_FALSE);
if (propData) {
border.top += BC_BORDER_TOP_HALF_COORD(p2t, propData->mTopBorderWidth);
border.right += BC_BORDER_RIGHT_HALF_COORD(p2t, propData->mRightCellBorderWidth);
border.bottom += BC_BORDER_BOTTOM_HALF_COORD(p2t, propData->mBottomBorderWidth);
border.left += BC_BORDER_LEFT_HALF_COORD(p2t, propData->mLeftCellBorderWidth);
}
return border;
}
nsMargin
nsTableFrame::GetExcludedOuterBCBorder() const
{
if (eCompatibility_NavQuirks != PresContext()->CompatibilityMode()) {
return GetOuterBCBorder();
}
nsMargin border(0, 0, 0, 0);
return border;
return GetOuterBCBorder() - GetIncludedOuterBCBorder();
}
static
void GetSeparateModelBorderPadding(const nsHTMLReflowState* aReflowState,
@ -2597,34 +2608,7 @@ nsTableFrame::GetChildAreaOffset(const nsHTMLReflowState* aReflowState) const
{
nsMargin offset(0,0,0,0);
if (IsBorderCollapse()) {
nsPresContext* presContext = PresContext();
if (eCompatibility_NavQuirks == presContext->CompatibilityMode()) {
nsTableFrame* firstInFlow = (nsTableFrame*)GetFirstInFlow(); if (!firstInFlow) ABORT1(offset);
PRInt32 p2t = nsPresContext::AppUnitsPerCSSPixel();
BCPropertyData* propData =
(BCPropertyData*)nsTableFrame::GetProperty((nsIFrame*)firstInFlow, nsGkAtoms::tableBCProperty, PR_FALSE);
if (!propData) ABORT1(offset);
offset.top += BC_BORDER_TOP_HALF_COORD(p2t, propData->mTopBorderWidth);
offset.right += BC_BORDER_RIGHT_HALF_COORD(p2t, propData->mRightBorderWidth);
offset.bottom += BC_BORDER_BOTTOM_HALF_COORD(p2t, propData->mBottomBorderWidth);
offset.left += BC_BORDER_LEFT_HALF_COORD(p2t, propData->mLeftBorderWidth);
}
}
else {
GetSeparateModelBorderPadding(aReflowState, *mStyleContext, offset);
}
return offset;
}
nsMargin
nsTableFrame::GetContentAreaOffset(const nsHTMLReflowState* aReflowState) const
{
nsMargin offset(0,0,0,0);
if (IsBorderCollapse()) {
// LDB: This used to unconditionally include the inner half as well,
// but that's pretty clearly wrong per the CSS2.1 spec.
offset = GetOuterBCBorder();
offset = GetIncludedOuterBCBorder();
}
else {
GetSeparateModelBorderPadding(aReflowState, *mStyleContext, offset);
@ -3702,7 +3686,7 @@ nsTableFrame::CalcBorderBoxHeight(const nsHTMLReflowState& aState)
{
nscoord height = aState.ComputedHeight();
if (NS_AUTOHEIGHT != height) {
nsMargin borderPadding = GetContentAreaOffset(&aState);
nsMargin borderPadding = GetChildAreaOffset(&aState);
height += borderPadding.top + borderPadding.bottom;
}
height = PR_MAX(0, height);
@ -5498,6 +5482,15 @@ nsTableFrame::CalcBCBorders()
tableCellMap->SetBCBorderCorner(eTopLeft, *info.cellMap, iter.mRowGroupStart, rowX,
0, tlCorner.ownerSide, tlCorner.subWidth, tlCorner.bevel);
bottomCorners[0].Set(NS_SIDE_TOP, currentBorder); // bottom left
// update the left/right first cell border
if (0 == rowX) {
if (tableIsLTR) {
propData->mLeftCellBorderWidth = currentBorder.width;
}
else {
propData->mRightCellBorderWidth = currentBorder.width;
}
}
// update lastVerBordersBorder and see if a new segment starts
startSeg = SetBorder(currentBorder, lastVerBorders[0]);
// store the border segment in the cell map
@ -5554,6 +5547,15 @@ nsTableFrame::CalcBCBorders()
// store the border segment in the cell map and update cellBorders
tableCellMap->SetBCBorderEdge(NS_SIDE_RIGHT, *info.cellMap, iter.mRowGroupStart, rowX,
cellEndColIndex, 1, currentBorder.owner, currentBorder.width, startSeg);
// update the left/right first cell border
if (0 == rowX) {
if (tableIsLTR) {
propData->mRightCellBorderWidth = currentBorder.width;
}
else {
propData->mLeftCellBorderWidth = currentBorder.width;
}
}
// update the affected borders of the cell, col, and table
if (info.cell) {
info.cell->SetBorderWidth(secondSide, PR_MAX(currentBorder.width, info.cell->GetBorderWidth(secondSide)));

View File

@ -213,9 +213,6 @@ public:
// Get the offset from the border box to the area where the row groups fit
nsMargin GetChildAreaOffset(const nsHTMLReflowState* aReflowState) const;
// Get the offset from the border box to the area where the content fits
nsMargin GetContentAreaOffset(const nsHTMLReflowState* aReflowState) const;
/** helper method to find the table parent of any table frame object */
static nsTableFrame* GetTableFrame(nsIFrame* aSourceFrame);
@ -284,26 +281,26 @@ public:
const nsRect& aDirtyRect,
nsPoint aPt);
// Get the outer half (i.e., the part outside the height and width of
// the table) of the largest segment (?) of border-collapsed border on
// the table on each side, or 0 for non border-collapsed tables.
/** Get the outer half (i.e., the part outside the height and width of
* the table) of the largest segment (?) of border-collapsed border on
* the table on each side, or 0 for non border-collapsed tables.
*/
nsMargin GetOuterBCBorder() const;
// Same as above, but only if it's included from the border-box width
// of the table (nonzero only in quirks mode).
/** Same as above, but only if it's included from the border-box width
* of the table.
*/
nsMargin GetIncludedOuterBCBorder() const;
// Same as above, but only if it's excluded from the border-box width
// of the table (nonzero only in standards mode). This is the area
// that leaks out into the margin (or potentially past it, if there is
// no margin).
/** Same as above, but only if it's excluded from the border-box width
* of the table. This is the area that leaks out into the margin
* (or potentially past it, if there is no margin).
*/
nsMargin GetExcludedOuterBCBorder() const;
/** Get width of table + colgroup + col collapse: elements that
* continue along the length of the whole left side.
* see nsTablePainter about continuous borders
* @param aPixelsToTwips - conversion factor
* @param aGetInner - get only inner half of border width
*/
nscoord GetContinuousLeftBCBorderWidth() const;
friend class nsDelayedCalcBCBorders;