Bug 764567: Implement column-fill part of CSS3 multicol spec, now with regression fixes [r=roc].

This commit is contained in:
Scott Johnson 2012-07-31 11:21:19 -05:00
parent a211114c42
commit 79055c4778
46 changed files with 452 additions and 147 deletions

View File

@ -14,7 +14,7 @@
* http://www.w3.org/TR/DOM-Level-2-Style
*/
[builtinclass, scriptable, uuid(492673d6-039b-4d94-a598-dbf82abc174f)]
[builtinclass, scriptable, uuid(243898eb-0e13-416d-9a2e-33af084985ed)]
interface nsIDOMCSS2Properties : nsISupports
{
attribute DOMString background;
@ -498,6 +498,9 @@ interface nsIDOMCSS2Properties : nsISupports
attribute DOMString MozColumnWidth;
// raises(DOMException) on setting
attribute DOMString MozColumnFill;
// raises(DOMException) on setting
attribute DOMString MozColumnGap;
// raises(DOMException) on setting

View File

@ -806,6 +806,9 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) {
#define NS_STYLE_COLUMN_COUNT_AUTO 0
#define NS_STYLE_COLUMN_COUNT_UNLIMITED (-1)
#define NS_STYLE_COLUMN_FILL_AUTO 0
#define NS_STYLE_COLUMN_FILL_BALANCE 1
// See nsStyleUIReset
#define NS_STYLE_IME_MODE_AUTO 0
#define NS_STYLE_IME_MODE_NORMAL 1

View File

@ -17,6 +17,7 @@ body {
width: 300px;
-moz-column-width: 50px;
-moz-column-gap: 1px;
-moz-column-fill: auto;
}
</style>

View File

@ -13,7 +13,7 @@
}
</script>
</head>
<body style="-moz-column-width: 1px;" onload="boom();">
<body style="-moz-column-width: 1px; -moz-column-fill: auto;" onload="boom();">
<hr size="100" color="blue"><div style="position: absolute;"></div><div id="x" style="height: 5px;"></div>
</body>
</html>

View File

@ -375,7 +375,7 @@ load text-overflow-bug666751-2.html
asserts(0-1) load text-overflow-bug670564.xhtml
load text-overflow-bug671796.xhtml
load 667025.html
asserts(14) asserts-if(Android,8) load 673770.html # bug 569193 and bug 459597
asserts-if(Android,8) load 673770.html # bug 569193 and bug 459597
load 679933-1.html
load 682649-1.html
load 683702-1.xhtml

View File

@ -110,8 +110,13 @@ protected:
// The maximum "content height" of all columns that overflowed
// their available height
nscoord mMaxOverflowingHeight;
// Whether or not we should revert back to 'auto' setting for column-fill.
// This happens if we overflow our columns such that we no longer have
// enough room to keep balancing.
bool mShouldRevertToAuto;
void Reset() {
mMaxHeight = mSumHeight = mLastHeight = mMaxOverflowingHeight = 0;
mShouldRevertToAuto = false;
}
};
@ -325,6 +330,8 @@ nsColumnSetFrame::ChooseColumnStrategy(const nsHTMLReflowState& aReflowState)
nscoord colHeight = GetAvailableContentHeight(aReflowState);
if (aReflowState.ComputedHeight() != NS_INTRINSICSIZE) {
colHeight = aReflowState.ComputedHeight();
} else if (aReflowState.mComputedMaxHeight != NS_INTRINSICSIZE) {
colHeight = aReflowState.mComputedMaxHeight;
}
nscoord colGap = GetColumnGap(this, colStyle);
@ -394,17 +401,19 @@ nsColumnSetFrame::ChooseColumnStrategy(const nsHTMLReflowState& aReflowState)
expectedWidthLeftOver = extraSpace - (extraToColumns*numColumns);
}
// NOTE that the non-balancing behavior for non-auto computed height
// is not in the CSS3 columns draft as of 18 January 2001
if (aReflowState.ComputedHeight() == NS_INTRINSICSIZE) {
// If column-fill is set to 'balance', then we want to balance the columns.
if (colStyle->mColumnFill == NS_STYLE_COLUMN_FILL_BALANCE) {
// Balancing!
if (numColumns <= 0) {
// Hmm, auto column count, column width or available width is unknown,
// and balancing is required. Let's just use one column then.
numColumns = 1;
}
colHeight = NS_MIN(mLastBalanceHeight, GetAvailableContentHeight(aReflowState));
colHeight = NS_MIN(mLastBalanceHeight,
colHeight);
} else {
// This is the case when the column-fill property is set to 'auto'.
// No balancing, so don't limit the column count
numColumns = PR_INT32_MAX;
}
@ -734,20 +743,37 @@ nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
reflowNext = true;
kidNextInFlow->RemoveStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
}
if ((contentBottom > aReflowState.mComputedMaxHeight ||
contentBottom > aReflowState.ComputedHeight()) &&
aConfig.mBalanceColCount < PR_INT32_MAX) {
// We overflowed vertically, but have not exceeded the number
// of columns. If we're balancing, then we should try reverting
// to auto instead.
aColData.mShouldRevertToAuto = true;
}
if (columnCount >= aConfig.mBalanceColCount) {
// No more columns allowed here. Stop.
aStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
kidNextInFlow->AddStateBits(NS_FRAME_IS_DIRTY);
// Move any of our leftover columns to our overflow list. Our
// next-in-flow will eventually pick them up.
const nsFrameList& continuationColumns = mFrames.RemoveFramesAfter(child);
if (continuationColumns.NotEmpty()) {
SetOverflowFrames(PresContext(), continuationColumns);
if (contentBottom >= aReflowState.availableHeight) {
// No more columns allowed here. Stop.
aStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
kidNextInFlow->AddStateBits(NS_FRAME_IS_DIRTY);
// Move any of our leftover columns to our overflow list. Our
// next-in-flow will eventually pick them up.
const nsFrameList& continuationColumns = mFrames.RemoveFramesAfter(child);
if (continuationColumns.NotEmpty()) {
SetOverflowFrames(PresContext(), continuationColumns);
}
child = nsnull;
break;
} else if (contentBottom > aReflowState.mComputedMaxHeight ||
contentBottom > aReflowState.ComputedHeight()) {
aColData.mShouldRevertToAuto = true;
} else {
// The number of columns required is too high.
allFit = false;
}
child = nullptr;
break;
}
}
@ -917,154 +943,172 @@ nsColumnSetFrame::Reflow(nsPresContext* aPresContext,
bool unboundedLastColumn = isBalancing && !nextInFlow;
nsCollapsingMargin carriedOutBottomMargin;
ColumnBalanceData colData;
bool feasible = ReflowChildren(aDesiredSize, aReflowState,
aStatus, config, unboundedLastColumn, &carriedOutBottomMargin, colData);
colData.mShouldRevertToAuto = false;
if (isBalancing && !aPresContext->HasPendingInterrupt()) {
nscoord availableContentHeight = GetAvailableContentHeight(aReflowState);
// Termination of the algorithm below is guaranteed because
// knownFeasibleHeight - knownInfeasibleHeight decreases in every
// iteration.
nscoord knownFeasibleHeight = NS_INTRINSICSIZE;
nscoord knownInfeasibleHeight = 0;
// We set this flag when we detect that we may contain a frame
// that can break anywhere (thus foiling the linear decrease-by-one
// search)
bool maybeContinuousBreakingDetected = false;
// This loop exists in order to try balancing initially. If the balancing
// overflows, then we want to revert to column-fill: auto.
while (!aPresContext->HasPendingInterrupt()) {
nscoord lastKnownFeasibleHeight = knownFeasibleHeight;
// Our loop invariant is: colData.mShouldRevertToAuto is true if and only
// if we've reflowed our children, and during the most recent reflow of
// children, we were balancing and we overflowed in the block direction.
do {
if (colData.mShouldRevertToAuto) {
config = ChooseColumnStrategy(aReflowState);
isBalancing = false;
config.mBalanceColCount = PR_INT32_MAX;
}
// Record what we learned from the last reflow
if (feasible) {
// maxHeight is feasible. Also, mLastBalanceHeight is feasible.
knownFeasibleHeight = NS_MIN(knownFeasibleHeight, colData.mMaxHeight);
knownFeasibleHeight = NS_MIN(knownFeasibleHeight, mLastBalanceHeight);
bool feasible = ReflowChildren(aDesiredSize, aReflowState,
aStatus, config, unboundedLastColumn, &carriedOutBottomMargin, colData);
// Furthermore, no height less than the height of the last
// column can ever be feasible. (We might be able to reduce the
// height of a non-last column by moving content to a later column,
// but we can't do that with the last column.)
if (mFrames.GetLength() == config.mBalanceColCount) {
if (isBalancing && !aPresContext->HasPendingInterrupt()) {
nscoord availableContentHeight = GetAvailableContentHeight(aReflowState);
// Termination of the algorithm below is guaranteed because
// knownFeasibleHeight - knownInfeasibleHeight decreases in every
// iteration.
nscoord knownFeasibleHeight = NS_INTRINSICSIZE;
nscoord knownInfeasibleHeight = 0;
// We set this flag when we detect that we may contain a frame
// that can break anywhere (thus foiling the linear decrease-by-one
// search)
bool maybeContinuousBreakingDetected = false;
while (!aPresContext->HasPendingInterrupt()) {
nscoord lastKnownFeasibleHeight = knownFeasibleHeight;
// Record what we learned from the last reflow
if (feasible) {
// maxHeight is feasible. Also, mLastBalanceHeight is feasible.
knownFeasibleHeight = NS_MIN(knownFeasibleHeight, colData.mMaxHeight);
knownFeasibleHeight = NS_MIN(knownFeasibleHeight, mLastBalanceHeight);
// Furthermore, no height less than the height of the last
// column can ever be feasible. (We might be able to reduce the
// height of a non-last column by moving content to a later column,
// but we can't do that with the last column.)
if (mFrames.GetLength() == config.mBalanceColCount) {
knownInfeasibleHeight = NS_MAX(knownInfeasibleHeight,
colData.mLastHeight - 1);
}
} else {
knownInfeasibleHeight = NS_MAX(knownInfeasibleHeight, mLastBalanceHeight);
// If a column didn't fit in its available height, then its current
// height must be the minimum height for unbreakable content in
// the column, and therefore no smaller height can be feasible.
knownInfeasibleHeight = NS_MAX(knownInfeasibleHeight,
colData.mLastHeight - 1);
}
} else {
knownInfeasibleHeight = NS_MAX(knownInfeasibleHeight, mLastBalanceHeight);
// If a column didn't fit in its available height, then its current
// height must be the minimum height for unbreakable content in
// the column, and therefore no smaller height can be feasible.
knownInfeasibleHeight = NS_MAX(knownInfeasibleHeight,
colData.mMaxOverflowingHeight - 1);
colData.mMaxOverflowingHeight - 1);
if (unboundedLastColumn) {
// The last column is unbounded, so all content got reflowed, so the
// mColMaxHeight is feasible.
knownFeasibleHeight = NS_MIN(knownFeasibleHeight,
colData.mMaxHeight);
if (unboundedLastColumn) {
// The last column is unbounded, so all content got reflowed, so the
// mColMaxHeight is feasible.
knownFeasibleHeight = NS_MIN(knownFeasibleHeight,
colData.mMaxHeight);
}
}
}
#ifdef DEBUG_roc
printf("*** nsColumnSetFrame::Reflow balancing knownInfeasible=%d knownFeasible=%d\n",
knownInfeasibleHeight, knownFeasibleHeight);
printf("*** nsColumnSetFrame::Reflow balancing knownInfeasible=%d knownFeasible=%d\n",
knownInfeasibleHeight, knownFeasibleHeight);
#endif
if (knownInfeasibleHeight >= knownFeasibleHeight - 1) {
// knownFeasibleHeight is where we want to be
break;
}
if (knownInfeasibleHeight >= availableContentHeight) {
break;
}
if (knownInfeasibleHeight >= knownFeasibleHeight - 1) {
// knownFeasibleHeight is where we want to be
break;
if (lastKnownFeasibleHeight - knownFeasibleHeight == 1) {
// We decreased the feasible height by one twip only. This could
// indicate that there is a continuously breakable child frame
// that we are crawling through.
maybeContinuousBreakingDetected = true;
}
}
if (knownInfeasibleHeight >= availableContentHeight) {
break;
}
nscoord nextGuess = (knownFeasibleHeight + knownInfeasibleHeight)/2;
// The constant of 600 twips is arbitrary. It's about two line-heights.
if (knownFeasibleHeight - nextGuess < 600 &&
!maybeContinuousBreakingDetected) {
// We're close to our target, so just try shrinking just the
// minimum amount that will cause one of our columns to break
// differently.
nextGuess = knownFeasibleHeight - 1;
} else if (unboundedLastColumn) {
// Make a guess by dividing that into N columns. Add some slop
// to try to make it on the feasible side. The constant of
// 600 twips is arbitrary. It's about two line-heights.
nextGuess = colData.mSumHeight/config.mBalanceColCount + 600;
// Sanitize it
nextGuess = clamped(nextGuess, knownInfeasibleHeight + 1,
knownFeasibleHeight - 1);
} else if (knownFeasibleHeight == NS_INTRINSICSIZE) {
// This can happen when we had a next-in-flow so we didn't
// want to do an unbounded height measuring step. Let's just increase
// from the infeasible height by some reasonable amount.
nextGuess = knownInfeasibleHeight*2 + 600;
}
// Don't bother guessing more than our height constraint.
nextGuess = NS_MIN(availableContentHeight, nextGuess);
if (lastKnownFeasibleHeight - knownFeasibleHeight == 1) {
// We decreased the feasible height by one twip only. This could
// indicate that there is a continuously breakable child frame
// that we are crawling through.
maybeContinuousBreakingDetected = true;
}
nscoord nextGuess = (knownFeasibleHeight + knownInfeasibleHeight)/2;
// The constant of 600 twips is arbitrary. It's about two line-heights.
if (knownFeasibleHeight - nextGuess < 600 &&
!maybeContinuousBreakingDetected) {
// We're close to our target, so just try shrinking just the
// minimum amount that will cause one of our columns to break
// differently.
nextGuess = knownFeasibleHeight - 1;
} else if (unboundedLastColumn) {
// Make a guess by dividing that into N columns. Add some slop
// to try to make it on the feasible side. The constant of
// 600 twips is arbitrary. It's about two line-heights.
nextGuess = colData.mSumHeight/config.mBalanceColCount + 600;
// Sanitize it
nextGuess = clamped(nextGuess, knownInfeasibleHeight + 1,
knownFeasibleHeight - 1);
} else if (knownFeasibleHeight == NS_INTRINSICSIZE) {
// This can happen when we had a next-in-flow so we didn't
// want to do an unbounded height measuring step. Let's just increase
// from the infeasible height by some reasonable amount.
nextGuess = knownInfeasibleHeight*2 + 600;
}
// Don't bother guessing more than our height constraint.
nextGuess = NS_MIN(availableContentHeight, nextGuess);
#ifdef DEBUG_roc
printf("*** nsColumnSetFrame::Reflow balancing choosing next guess=%d\n", nextGuess);
printf("*** nsColumnSetFrame::Reflow balancing choosing next guess=%d\n", nextGuess);
#endif
config.mColMaxHeight = nextGuess;
unboundedLastColumn = false;
AddStateBits(NS_FRAME_IS_DIRTY);
feasible = ReflowChildren(aDesiredSize, aReflowState,
aStatus, config, false,
&carriedOutBottomMargin, colData);
}
config.mColMaxHeight = nextGuess;
if (!feasible && !aPresContext->HasPendingInterrupt()) {
// We may need to reflow one more time at the feasible height to
// get a valid layout.
bool skip = false;
if (knownInfeasibleHeight >= availableContentHeight) {
config.mColMaxHeight = availableContentHeight;
if (mLastBalanceHeight == availableContentHeight) {
skip = true;
}
} else {
config.mColMaxHeight = knownFeasibleHeight;
}
if (!skip) {
// If our height is unconstrained, make sure that the last column is
// allowed to have arbitrary height here, even though we were balancing.
// Otherwise we'd have to split, and it's not clear what we'd do with
// that.
unboundedLastColumn = false;
AddStateBits(NS_FRAME_IS_DIRTY);
ReflowChildren(aDesiredSize, aReflowState, aStatus, config,
availableContentHeight == NS_UNCONSTRAINEDSIZE,
&carriedOutBottomMargin, colData);
feasible = ReflowChildren(aDesiredSize, aReflowState,
aStatus, config, false,
&carriedOutBottomMargin, colData);
}
if (!feasible && !aPresContext->HasPendingInterrupt()) {
// We may need to reflow one more time at the feasible height to
// get a valid layout.
bool skip = false;
if (knownInfeasibleHeight >= availableContentHeight) {
config.mColMaxHeight = availableContentHeight;
if (mLastBalanceHeight == availableContentHeight) {
skip = true;
}
} else {
config.mColMaxHeight = knownFeasibleHeight;
}
if (!skip) {
// If our height is unconstrained, make sure that the last column is
// allowed to have arbitrary height here, even though we were balancing.
// Otherwise we'd have to split, and it's not clear what we'd do with
// that.
AddStateBits(NS_FRAME_IS_DIRTY);
ReflowChildren(aDesiredSize, aReflowState, aStatus, config,
availableContentHeight == NS_UNCONSTRAINEDSIZE,
&carriedOutBottomMargin, colData);
}
}
}
}
if (aPresContext->HasPendingInterrupt() &&
aReflowState.availableHeight == NS_UNCONSTRAINEDSIZE) {
// In this situation, we might be lying about our reflow status, because
// our last kid (the one that got interrupted) was incomplete. Fix that.
aStatus = NS_FRAME_COMPLETE;
}
CheckInvalidateSizeChange(aDesiredSize);
} while (colData.mShouldRevertToAuto);
// XXXjwir3: This call should be replaced with FinishWithAbsoluteFrames
// when bug 724978 is fixed and nsColumnSetFrame is a full absolute
// container.
FinishAndStoreOverflow(&aDesiredSize);
if (aPresContext->HasPendingInterrupt() &&
aReflowState.availableHeight == NS_UNCONSTRAINEDSIZE) {
// In this situation, we might be lying about our reflow status, because
// our last kid (the one that got interrupted) was incomplete. Fix that.
aStatus = NS_FRAME_COMPLETE;
}
aDesiredSize.mCarriedOutBottomMargin = carriedOutBottomMargin;
CheckInvalidateSizeChange(aDesiredSize);
// XXXjwir3: This call should be replaced with FinishWithAbsoluteFrames
// when bug 724978 is fixed and nsColumnSetFrame is a full absolute
// container.
FinishAndStoreOverflow(&aDesiredSize);
aDesiredSize.mCarriedOutBottomMargin = carriedOutBottomMargin;
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);

View File

@ -5,7 +5,7 @@
</head>
<body>
<div style="-moz-column-count: 2; column-count: 2; height: 4.5em; background:yellow">
<div style="-moz-column-count: 2; column-count: 2; -moz-column-fill: auto; height: 4.5em; background:yellow">
<div style="margin: 7px 1% 2px 2em; border: medium dotted; border-width: 2px 3px 4px 5px;">
<div style="background: url(repeatable-diagonal-gradient.png);">

View File

@ -5,7 +5,7 @@
</head>
<body>
<div style="-moz-column-count: 2; column-count: 2; height: 4.5em; background:yellow">
<div style="-moz-column-count: 2; column-count: 2; -moz-column-fill: auto; height: 4.5em; background:yellow">
<div>
<div style="background: url(repeatable-diagonal-gradient.png); background-clip: padding-box; background-clip: padding; background-origin: padding-box; background-origin: padding; margin: 7px 1% 2px 2em; border: medium dotted; border-width: 2px 3px 4px 5px; padding: 8px 6px 4px 2px;">

View File

@ -41,6 +41,7 @@
width: 300pt;
-moz-column-width: 100pt;
-moz-column-gap: 0;
-moz-column-fill: auto;
border: solid gray;
position: relative;
}

View File

@ -48,6 +48,7 @@
width: 300pt;
-moz-column-width: 100pt;
-moz-column-gap: 0;
-moz-column-fill: auto;
border: solid gray;
}
</style>

View File

@ -48,6 +48,7 @@
width: 300pt;
-moz-column-width: 100pt;
-moz-column-gap: 0;
-moz-column-fill: auto;
border: solid gray;
}
</style>

View File

@ -1,6 +1,6 @@
<!DOCTYPE HTML>
<title>Test for pushing of floats to next column when float breaking in columns is disabled</title>
<body style="-moz-column-width: 200px; margin: 0; -moz-column-gap: 0; height: 200px;">
<body style="-moz-column-width: 200px; -moz-column-fill: auto; margin: 0; -moz-column-gap: 0; height: 200px;">
<div style="float: left;">
<div style="display: inline-block; vertical-align: top; height: 150px; width: 200px; background: yellow"></div>
</div>

View File

@ -1,6 +1,6 @@
<!DOCTYPE HTML>
<title>Test for pushing of floats to next column when float breaking in columns is disabled</title>
<body style="-moz-column-width: 200px; margin: 0; -moz-column-gap: 0; height: 200px;">
<body style="-moz-column-width: 200px; margin: 0; -moz-column-fill: auto; -moz-column-gap: 0; height: 200px;">
<div style="float: left;">
<div style="display: inline-block; vertical-align: top; height: 150px; width: 200px; background: yellow"></div>
</div>

View File

@ -0,0 +1,4 @@
@font-face {
font-family: "Ahem";
src: url(../fonts/Ahem.ttf);
}

View File

@ -0,0 +1,32 @@
<html>
<head>
<link rel="stylesheet" type="text/css" href="ahem.css" />
<style>
td.text {
width: 200px;
text-align: left;
font-family: ahem;
font-size: 12pt;
line-height: 1.1;
}
table {
width: 100%;
font-family: ahem;
font-size: 12pt;
line-height: 1.1;
}
</style>
</head>
<body>
<table cellpadding=0 cellspacing=0>
<tr>
<td class="text" valign="top">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat libero vel diam.</td>
<td class="text" valign="top">Pellentesque pulvinar commodo lacus. Sed fringilla. Sed lectus. Praesent laoreet orci</td>
<td valign="top" class="text">vitae nisi. Duis venenatis tristique massa. Sed commodo diam at mauris.</td>
</tr>
</table>
</body>

View File

@ -0,0 +1,19 @@
<html>
<head>
<link rel="stylesheet" type="text/css" href="ahem.css" />
</head>
<body>
<div style="width: 100%">
<div style="-moz-column-width: 200px;
-moz-column-gap: 0px;
-moz-column-fill: auto;
height: 120px;
font-family: ahem;
font-size: 12pt;
line-height: 1.1;">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat libero vel diam. Pellentesque pulvinar commodo lacus. Sed fringilla. Sed lectus. Praesent laoreet orci vitae nisi. Duis venenatis tristique massa. Sed commodo diam at mauris.
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,33 @@
<html>
<head>
<link rel="stylesheet" type="text/css" href="ahem.css" />
<style>
td {
width: 200px;
font-family: ahem;
}
table {
width: 100%;
height: 150px;
padding-bottom: 0;
margin-bottom: 0;
font-family: ahem;
}
</style>
</head>
<body>
<table cellpadding=0 cellspacing=0>
<tr>
<td valign="top">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat libero vel diam.
</td>
<td valign="top">Pellentesque pulvinar commodo lacus. Sed fringilla. Sed lectus. Praesent laoreet orci
</td>
<td valign="top">vitae nisi. Duis venenatis tristique massa. Sed commodo diam at mauris.
</td>
</tr>
</table>
</body>
</html>

View File

@ -0,0 +1,16 @@
<html>
<head>
<link rel="stylesheet" type="text/css" href="ahem.css" />
</head>
<body>
<div style="-moz-column-width: 200px;
-moz-column-gap: 0px;
-moz-column-fill: balance;
height: 150px;
margin-bottom: 0;
padding-bottom: 0;
font-family: ahem;">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat libero vel diam. Pellentesque pulvinar commodo lacus. Sed fringilla. Sed lectus. Praesent laoreet orci vitae nisi. Duis venenatis tristique massa. Sed commodo diam at mauris.
</div>
</body>
</html>

View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
div.container {
width:54em;
background-color: gray;
}
div.multicolumn {
height: 5em;
overflow: visible;
column-width:15em;
column-gap: 2em;
column-rule: 4px solid green;
column-fill: auto;
-moz-column-width:15em;
-moz-column-gap: 2em;
-moz-column-rule: 4px solid green;
-moz-column-fill: auto;
padding: 5px;
}
p {
margin: 0;
padding: 0
}
</style>
</head>
<body>
<div class="container">
<div class="multicolumn">
<p>Ab cde fgh i jkl. Mnopqr stu vw xyz. A bcdef g hij klm nopqrstuv wxy z. Abc de fghi jklmno. Pqrstu vwx yz. Abc def ghi jkl.M nop qrst uv wx yz. Ab cde fgh i jkl. Mnopqr stu vw xyz. A bcdef g hij klm nopqrstuv wxy z. Abc de fghi jklmno. Pqrstu vwx yz. Abc def ghi jkl.M nop qrst uv wx yz. Ab cde fgh i jkl. Mnopqr stu vw xyz. A bcdef g hij klm nopqrstuv wxy z. Abc de fghi jklmno. Pqrstu vwx yz. Abc def ghi jkl.M nop qrst uv wx yz. Ab cde fgh i jkl. Mnopqr stu vw xyz. A bcdef g hij klm nopqrstuv wxy z. Abc de fghi jklmno. Pqrstu vwx yz. Abc def ghi jkl.M nop qrst uv wx yz. Ab cde fgh i jkl. Mnopqr stu vw xyz. A bcdef g hij klm nopqrstuv wxy z. Abc de fghi jklmno. Pqrstu vwx yz. Abc def ghi jkl.M nop qrst uv wx yz. Ab cde fgh i jkl. Mnopqr stu vw xyz. A bcdef g hij klm nopqrstuv wxy z. Abc de fghi jklmno. Pqrstu vwx yz. Abc def ghi jkl.M nop qrst uv wx yz. Ab cde fgh i jkl. Mnopqr stu vw xyz. A bcdef g hij klm nopqrstuv wxy z. Abc de fghi jklmno. Pqrstu vwx yz. Abc def ghi jkl.M nop qrst uv wx yz. </p>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
div.container {
width:54em;
background-color: gray;
}
div.multicolumn {
height: 5em;
overflow: visible;
column-width:15em;
column-gap: 2em;
column-rule: 4px solid green;
column-fill: balance;
-moz-column-width:15em;
-moz-column-gap: 2em;
-moz-column-rule: 4px solid green;
-moz-column-fill: balance;
padding: 5px;
}
p {
margin: 0;
padding: 0
}
</style>
</head>
<body>
<div class="container">
<div class="multicolumn">
<p>Ab cde fgh i jkl. Mnopqr stu vw xyz. A bcdef g hij klm nopqrstuv wxy z. Abc de fghi jklmno. Pqrstu vwx yz. Abc def ghi jkl.M nop qrst uv wx yz. Ab cde fgh i jkl. Mnopqr stu vw xyz. A bcdef g hij klm nopqrstuv wxy z. Abc de fghi jklmno. Pqrstu vwx yz. Abc def ghi jkl.M nop qrst uv wx yz. Ab cde fgh i jkl. Mnopqr stu vw xyz. A bcdef g hij klm nopqrstuv wxy z. Abc de fghi jklmno. Pqrstu vwx yz. Abc def ghi jkl.M nop qrst uv wx yz. Ab cde fgh i jkl. Mnopqr stu vw xyz. A bcdef g hij klm nopqrstuv wxy z. Abc de fghi jklmno. Pqrstu vwx yz. Abc def ghi jkl.M nop qrst uv wx yz. Ab cde fgh i jkl. Mnopqr stu vw xyz. A bcdef g hij klm nopqrstuv wxy z. Abc de fghi jklmno. Pqrstu vwx yz. Abc def ghi jkl.M nop qrst uv wx yz. Ab cde fgh i jkl. Mnopqr stu vw xyz. A bcdef g hij klm nopqrstuv wxy z. Abc de fghi jklmno. Pqrstu vwx yz. Abc def ghi jkl.M nop qrst uv wx yz. Ab cde fgh i jkl. Mnopqr stu vw xyz. A bcdef g hij klm nopqrstuv wxy z. Abc de fghi jklmno. Pqrstu vwx yz. Abc def ghi jkl.M nop qrst uv wx yz. </p>
</div>
</div>
</body>
</html>

View File

@ -16,9 +16,12 @@
== column-balancing-002.html column-balancing-002.ref.html
== column-balancing-003.html column-balancing-000.ref.html
== column-balancing-004.html column-balancing-004.ref.html
HTTP(..) == columnfill-balance.html columnfill-balance-ref.html
HTTP(..) == columnfill-auto.html columnfill-auto-ref.html
== columnrule-basic.html columnrule-basic-ref.html
== columnrule-complex.html columnrule-complex-ref.html
!= columnrule-linestyles.html columnrule-linestyles-notref.html
== columnrule-padding.html columnrule-padding-ref.html
== columnfill-overflow.html columnfill-overflow-ref.html
== margin-collapsing-bug616722-1.html margin-collapsing-bug616722-1-ref.html
== margin-collapsing-bug616722-2.html margin-collapsing-bug616722-2-ref.html

View File

@ -34,6 +34,7 @@
height: 2in;
-moz-column-count: 3;
-moz-column-gap: 0;
-moz-column-fill: auto;
border: silver 2pt;
border-style: none solid;
}

View File

@ -25,6 +25,7 @@
width: 300px;
-moz-column-width: 150px;
-moz-column-gap: 0;
-moz-column-fill: auto;
border: solid silver;
border-style: none solid;
}

View File

@ -20,6 +20,7 @@
width: 300px;
-moz-column-width: 100px;
-moz-column-gap: 0;
-moz-column-fill: auto;
border: solid silver;
border-style: none solid;
background: yellow;

View File

@ -49,6 +49,7 @@
width: 300px;
-moz-column-width: 100px;
-moz-column-gap: 0;
-moz-column-fill: auto;
border: solid silver;
border-style: none solid;
}

View File

@ -16,6 +16,7 @@
width: 300px;
-moz-column-width: 150px;
-moz-column-gap: 0;
-moz-column-fill: auto;
border: solid silver;
}
</style>

View File

@ -17,6 +17,7 @@
width: 300px;
-moz-column-width: 150px;
-moz-column-gap: 0;
-moz-column-fill: auto;
border: solid silver;
}
</style>

View File

@ -20,6 +20,7 @@
width: 300px;
-moz-column-width: 150px;
-moz-column-gap: 0;
-moz-column-fill: auto;
border: solid silver;
}
</style>

View File

@ -13,6 +13,7 @@
width: 450px;
-moz-column-width: 150px;
-moz-column-gap: 0;
-moz-column-fill: auto;
border: 3px solid silver;
}

View File

@ -13,6 +13,7 @@
width: 450px;
-moz-column-width: 150px;
-moz-column-gap: 0;
-moz-column-fill: auto;
border: 3px solid silver;
}

View File

@ -13,6 +13,7 @@
width: 450px;
-moz-column-width: 150px;
-moz-column-gap: 0;
-moz-column-fill: auto;
border: 3px solid silver;
}

View File

@ -13,6 +13,7 @@
width: 450px;
-moz-column-width: 150px;
-moz-column-gap: 0;
-moz-column-fill: auto;
border: 3px solid silver;
}

View File

@ -13,6 +13,7 @@
width: 450px;
-moz-column-width: 150px;
-moz-column-gap: 0;
-moz-column-fill: auto;
border: 3px solid silver;
}

View File

@ -13,6 +13,7 @@
width: 450px;
-moz-column-width: 150px;
-moz-column-gap: 0;
-moz-column-fill: auto;
border: 3px solid silver;
}

View File

@ -13,6 +13,7 @@
width: 450px;
-moz-column-width: 150px;
-moz-column-gap: 0;
-moz-column-fill: auto;
border: 3px solid silver;
}

View File

@ -13,6 +13,7 @@
width: 450px;
-moz-column-width: 150px;
-moz-column-gap: 0;
-moz-column-fill: auto;
border: 3px solid silver;
}

View File

@ -172,6 +172,7 @@ CSS_KEY(auto, auto)
CSS_KEY(avoid, avoid)
CSS_KEY(background, background)
CSS_KEY(backwards, backwards)
CSS_KEY(balance, balance)
CSS_KEY(baseline, baseline)
CSS_KEY(bidi-override, bidi_override)
CSS_KEY(blink, blink)

View File

@ -1390,6 +1390,16 @@ CSS_PROP_COLUMN(
nullptr,
offsetof(nsStyleColumn, mColumnCount),
eStyleAnimType_Custom)
CSS_PROP_COLUMN(
-moz-column-fill,
_moz_column_fill,
CSS_PROP_DOMPROP_PREFIXED(ColumnFill),
CSS_PROPERTY_PARSE_VALUE,
"",
VARIANT_HK,
kColumnFillKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
CSS_PROP_COLUMN(
-moz-column-width,
_moz_column_width,

View File

@ -1595,6 +1595,12 @@ const PRInt32 nsCSSProps::kColorInterpolationKTable[] = {
eCSSKeyword_UNKNOWN, -1
};
const PRInt32 nsCSSProps::kColumnFillKTable[] = {
eCSSKeyword_auto, NS_STYLE_COLUMN_FILL_AUTO,
eCSSKeyword_balance, NS_STYLE_COLUMN_FILL_BALANCE,
eCSSKeyword_UNKNOWN, -1
};
bool
nsCSSProps::FindKeyword(nsCSSKeyword aKeyword, const PRInt32 aTable[], PRInt32& aResult)
{

View File

@ -359,6 +359,7 @@ public:
static const PRInt32 kTextAnchorKTable[];
static const PRInt32 kTextRenderingKTable[];
static const PRInt32 kColorInterpolationKTable[];
static const PRInt32 kColumnFillKTable[];
static const PRInt32 kBoxPropSourceKTable[];
static const PRInt32 kBoxShadowTypeKTable[];
static const PRInt32 kBoxSizingKTable[];

View File

@ -699,6 +699,16 @@ nsComputedDOMStyle::DoGetColumnGap()
return val;
}
nsIDOMCSSValue*
nsComputedDOMStyle::DoGetColumnFill()
{
nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
val->SetIdent(
nsCSSProps::ValueToKeywordEnum(GetStyleColumn()->mColumnFill,
nsCSSProps::kColumnFillKTable));
return val;
}
nsIDOMCSSValue*
nsComputedDOMStyle::DoGetColumnRuleWidth()
{
@ -4768,6 +4778,7 @@ nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength)
COMPUTED_STYLE_MAP_ENTRY(box_pack, BoxPack),
COMPUTED_STYLE_MAP_ENTRY(box_sizing, BoxSizing),
COMPUTED_STYLE_MAP_ENTRY(_moz_column_count, ColumnCount),
COMPUTED_STYLE_MAP_ENTRY(_moz_column_fill, ColumnFill),
COMPUTED_STYLE_MAP_ENTRY(_moz_column_gap, ColumnGap),
//// COMPUTED_STYLE_MAP_ENTRY(_moz_column_rule, ColumnRule),
COMPUTED_STYLE_MAP_ENTRY(_moz_column_rule_color, ColumnRuleColor),

View File

@ -333,6 +333,7 @@ private:
/* Column properties */
nsIDOMCSSValue* DoGetColumnCount();
nsIDOMCSSValue* DoGetColumnFill();
nsIDOMCSSValue* DoGetColumnWidth();
nsIDOMCSSValue* DoGetColumnGap();
nsIDOMCSSValue* DoGetColumnRuleWidth();

View File

@ -7097,6 +7097,13 @@ nsRuleNode::ComputeColumnData(void* aStartStruct,
column->mColumnRuleColorIsForeground = false;
}
// column-fill: enum
SetDiscrete(*aRuleData->ValueForColumnFill(),
column->mColumnFill, canStoreInRuleTree,
SETDSC_ENUMERATED, parent->mColumnFill,
NS_STYLE_COLUMN_FILL_BALANCE,
0, 0, 0, 0);
COMPUTE_END_RESET(Column, column)
}

View File

@ -774,6 +774,7 @@ nsStyleColumn::nsStyleColumn(nsPresContext* aPresContext)
mColumnCount = NS_STYLE_COLUMN_COUNT_AUTO;
mColumnWidth.SetAutoValue();
mColumnGap.SetNormalValue();
mColumnFill = NS_STYLE_COLUMN_FILL_BALANCE;
mColumnRuleWidth = (aPresContext->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM];
mColumnRuleStyle = NS_STYLE_BORDER_STYLE_NONE;
@ -805,7 +806,8 @@ nsChangeHint nsStyleColumn::CalcDifference(const nsStyleColumn& aOther) const
return NS_STYLE_HINT_FRAMECHANGE;
if (mColumnWidth != aOther.mColumnWidth ||
mColumnGap != aOther.mColumnGap)
mColumnGap != aOther.mColumnGap ||
mColumnFill != aOther.mColumnFill)
return NS_STYLE_HINT_REFLOW;
if (GetComputedColumnRuleWidth() != aOther.GetComputedColumnRuleWidth() ||

View File

@ -2098,6 +2098,8 @@ struct nsStyleColumn {
nscolor mColumnRuleColor; // [reset]
PRUint8 mColumnRuleStyle; // [reset]
PRUint8 mColumnFill; // [reset] see nsStyleConsts.h
// See https://bugzilla.mozilla.org/show_bug.cgi?id=271586#c43 for why
// this is hard to replace with 'currentColor'.
bool mColumnRuleColorIsForeground;

View File

@ -519,6 +519,14 @@ var gCSSProperties = {
// negative and zero invalid per editor's draft
invalid_values: [ "-1", "0", "3px" ]
},
"-moz-column-fill": {
domProp: "MozColumnFill",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "balance" ],
other_values: [ "auto" ],
invalid_values: [ "2px", "dotted", "5em" ]
},
"-moz-column-gap": {
domProp: "MozColumnGap",
inherited: false,