Bug 695222 - Implement column-fill part of CSS3 multicol spec. r=roc,dbaron
authorScott Johnson <sjohnson@mozilla.com>
Sun, 25 Dec 2011 23:25:59 -0600
changeset 83358 93b804e5f3f5
parent 83357 9f29daaecbcc
child 83359 902a4ec5c870
push id21754
push userbmo@edmorley.co.uk
push date2011-12-27 01:57 +0000
Treeherderresults
reviewersroc, dbaron
bugs695222
milestone12.0a1
Bug 695222 - Implement column-fill part of CSS3 multicol spec. r=roc,dbaron
dom/interfaces/css/nsIDOMCSS2Properties.idl
layout/base/nsStyleConsts.h
layout/generic/crashtests/399412-1.html
layout/generic/crashtests/673770.html
layout/generic/crashtests/crashtests.list
layout/generic/nsColumnSetFrame.cpp
layout/reftests/bugs/368020-1-ref.html
layout/reftests/bugs/368020-1.html
layout/reftests/bugs/379349-2-ref.xhtml
layout/reftests/bugs/379349-2a.xhtml
layout/reftests/bugs/379349-2b.xhtml
layout/reftests/bugs/563584-9c.html
layout/reftests/bugs/563584-9d.html
layout/reftests/columns/ahem.css
layout/reftests/columns/columnfill-auto-ref.html
layout/reftests/columns/columnfill-auto.html
layout/reftests/columns/columnfill-balance-ref.html
layout/reftests/columns/columnfill-balance.html
layout/reftests/columns/columnfill-change-ref.html
layout/reftests/columns/columnfill-change.html
layout/reftests/columns/reftest.list
layout/reftests/pagination/abspos-overflow-01-cols.xhtml
layout/reftests/pagination/border-breaking-000-cols.xhtml
layout/reftests/pagination/border-breaking-001-cols.ref.xhtml
layout/reftests/pagination/border-breaking-001-cols.xhtml
layout/reftests/pagination/border-breaking-002-cols.ref.xhtml
layout/reftests/pagination/border-breaking-002-cols.xhtml
layout/reftests/pagination/border-breaking-003-cols.xhtml
layout/reftests/pagination/content-inserted-002.ref.xhtml
layout/reftests/pagination/content-inserted-002.xhtml
layout/reftests/pagination/content-inserted-003.xhtml
layout/reftests/pagination/content-inserted-004.xhtml
layout/reftests/pagination/content-inserted-005.xhtml
layout/reftests/pagination/content-inserted-006.xhtml
layout/reftests/pagination/content-inserted-007.xhtml
layout/reftests/pagination/content-inserted-009.xhtml
layout/style/nsCSSKeywordList.h
layout/style/nsCSSPropList.h
layout/style/nsCSSProps.cpp
layout/style/nsCSSProps.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsComputedDOMStyle.h
layout/style/nsRuleNode.cpp
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/style/test/property_database.js
--- a/dom/interfaces/css/nsIDOMCSS2Properties.idl
+++ b/dom/interfaces/css/nsIDOMCSS2Properties.idl
@@ -46,17 +46,17 @@
  * The nsIDOMCSS2Properties interface is a datatype for additional
  * reflection of data already provided in nsIDOMCSSStyleDeclaration in
  * the Document Object Model.
  *
  * For more information on this interface please see
  * http://www.w3.org/TR/DOM-Level-2-Style
  */
 
-[builtinclass, scriptable, uuid(b477527a-a6f4-4f86-a16b-563e602e930a)]
+[builtinclass, scriptable, uuid(b4afb8f4-d9ab-44d9-9d0c-f765c47d57c2)]
 interface nsIDOMCSS2Properties : nsISupports
 {
            attribute DOMString        background;
                                         // raises(DOMException) on setting
 
            attribute DOMString        backgroundAttachment;
                                         // raises(DOMException) on setting
 
@@ -527,16 +527,19 @@ interface nsIDOMCSS2Properties : nsISupp
                                         // raises(DOMException) on setting
 
            attribute DOMString        MozColumnCount;
                                         // raises(DOMException) on setting
 
            attribute DOMString        MozColumnWidth;
                                         // raises(DOMException) on setting
 
+           attribute DOMString        MozColumnFill;
+                                        // raises(DOMException) on setting
+
            attribute DOMString        MozColumnGap;
                                         // raises(DOMException) on setting
 
            attribute DOMString        MozFloatEdge;
                                         // raises(DOMException) on setting
 
            attribute DOMString        MozFontFeatureSettings;
                                         // raises(DOMException) on setting
--- a/layout/base/nsStyleConsts.h
+++ b/layout/base/nsStyleConsts.h
@@ -787,16 +787,19 @@ static inline mozilla::css::Side operato
 #define NS_STYLE_PAGE_BREAK_AVOID               2
 #define NS_STYLE_PAGE_BREAK_LEFT                3
 #define NS_STYLE_PAGE_BREAK_RIGHT               4
 
 // See nsStyleColumn
 #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
 #define NS_STYLE_IME_MODE_ACTIVE                2
 #define NS_STYLE_IME_MODE_DISABLED              3
 #define NS_STYLE_IME_MODE_INACTIVE              4
 
 // See nsStyleGradient
--- a/layout/generic/crashtests/399412-1.html
+++ b/layout/generic/crashtests/399412-1.html
@@ -12,16 +12,17 @@
   height: 150px;
   border: 1px silver solid;
 }
 body {
   height: 60px;
   width: 300px;
   -moz-column-width: 50px;
   -moz-column-gap: 1px;
+  -moz-column-fill: auto;
 }
 </style>
 
 </head>
 
 <body onload="s=document.getElementById('s'); s.parentNode.removeChild(s);">
 
 <div class="container"><div class="overflow"></div></div>
--- a/layout/generic/crashtests/673770.html
+++ b/layout/generic/crashtests/673770.html
@@ -8,13 +8,13 @@
         document.body.style.height = "8px";
         document.documentElement.style.fontSize = "22050893469px";
         document.documentElement.offsetHeight;
         document.getElementById("x").style.counterReset = "chicken";
         document.documentElement.offsetHeight;
       }
     </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>
 
--- a/layout/generic/crashtests/crashtests.list
+++ b/layout/generic/crashtests/crashtests.list
@@ -370,15 +370,15 @@ load 660451-1.html
 load 665853.html
 load text-overflow-form-elements.html
 load text-overflow-iframe.html
 load text-overflow-bug666751-1.html
 load text-overflow-bug666751-2.html
 asserts(2) load text-overflow-bug670564.xhtml # asserts(2) for bug 436470
 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
 load 679933-1.html
 load 682649-1.html
 load 683702-1.xhtml
 load 688996-1.html
 load 688996-2.html
 load 683712.html
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -411,28 +411,32 @@ nsColumnSetFrame::ChooseColumnStrategy(c
     // Compute extra space and divide it among the columns
     nscoord extraSpace =
       NS_MAX(0, availContentWidth - (colWidth*numColumns + colGap*(numColumns - 1)));
     nscoord extraToColumns = extraSpace/numColumns;
     colWidth += extraToColumns;
     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,
+                       GetAvailableContentHeight(aReflowState));
   } 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;
   }
 
 #ifdef DEBUG_roc
   printf("*** nsColumnSetFrame::ChooseColumnStrategy: numColumns=%d, colWidth=%d, expectedWidthLeftOver=%d, colHeight=%d, colGap=%d\n",
          numColumns, colWidth, expectedWidthLeftOver, colHeight, colGap);
 #endif
   ReflowConfig config = { numColumns, colWidth, expectedWidthLeftOver, colGap, colHeight };
--- a/layout/reftests/bugs/368020-1-ref.html
+++ b/layout/reftests/bugs/368020-1-ref.html
@@ -1,16 +1,16 @@
 <!DOCTYPE HTML>
 <html>
 <head>
 <title>Testcase, bug 368020</title>
 </head>
 <body>
 
-<div style="-moz-column-count: 2; column-count: 2; height: 3.5em; background:yellow">
+<div style="-moz-column-count: 2; column-count: 2; -moz-column-fill: auto; height: 3.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);">
       <div style="padding: 8px 6px 4px 2px;">
         blah<br>
         blah<br>
         blah<br>
         blah
--- a/layout/reftests/bugs/368020-1.html
+++ b/layout/reftests/bugs/368020-1.html
@@ -1,16 +1,16 @@
 <!DOCTYPE HTML>
 <html>
 <head>
 <title>Testcase, bug 368020</title>
 </head>
 <body>
 
-<div style="-moz-column-count: 2; column-count: 2; height: 3.5em; background:yellow">
+<div style="-moz-column-count: 2; column-count: 2;  -moz-column-fill: auto; height: 3.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;">
       <div>
         blah<br>
         blah<br>
         blah<br>
         blah
--- a/layout/reftests/bugs/379349-2-ref.xhtml
+++ b/layout/reftests/bugs/379349-2-ref.xhtml
@@ -36,16 +36,17 @@
       width: 200pt;
       border-bottom: 4px solid blue;
     }
     body {
       height: 2.5in;
       width: 300pt;
       -moz-column-width: 100pt;
       -moz-column-gap: 0;
+      -moz-column-fill: auto;
       border: solid gray;
       position: relative;
     }
   </style>
  </head>
  <body>
   <div class="overflow">
   </div>
--- a/layout/reftests/bugs/379349-2a.xhtml
+++ b/layout/reftests/bugs/379349-2a.xhtml
@@ -43,16 +43,17 @@
       height: 800%;
       border-bottom-color: blue;
     }
     body {
       height: 2.5in;
       width: 300pt;
       -moz-column-width: 100pt;
       -moz-column-gap: 0;
+      -moz-column-fill: auto;
       border: solid gray;
     }
   </style>
  </head>
  <body>
   <div class="container no1">
     <div class="overflow">
     </div>
--- a/layout/reftests/bugs/379349-2b.xhtml
+++ b/layout/reftests/bugs/379349-2b.xhtml
@@ -43,16 +43,17 @@
       height: 800%;
       border-bottom-color: blue;
     }
     body {
       height: 2.5in;
       width: 300pt;
       -moz-column-width: 100pt;
       -moz-column-gap: 0;
+      -moz-column-fill: auto;
       border: solid gray;
     }
   </style>
  </head>
  <body onload="document.getElementById('tester1').style.height = '9in';
                document.getElementById('tester1').offsetHeight;
                document.getElementById('tester2').style.height = '29in';
                document.getElementById('tester2').offsetHeight;
--- a/layout/reftests/bugs/563584-9c.html
+++ b/layout/reftests/bugs/563584-9c.html
@@ -1,11 +1,11 @@
 <!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>
 <div style="float: left;">
   <div style="display: inline-block; vertical-align: top; height: 150px; width: 200px; background: aqua"></div>
 </div>
 <div style="float: left;">
   <div style="display: inline-block; vertical-align: top; height: 150px; width: 200px; background: fuchsia"></div>
--- a/layout/reftests/bugs/563584-9d.html
+++ b/layout/reftests/bugs/563584-9d.html
@@ -1,11 +1,11 @@
 <!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>
 <div>&nbsp;</div>
 <div style="float: left;">
   <div style="display: inline-block; vertical-align: top; height: 150px; width: 200px; background: aqua"></div>
 </div>
 <div>&nbsp;</div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/columns/ahem.css
@@ -0,0 +1,4 @@
+@font-face {
+  font-family: "Ahem";
+  src: url(../fonts/Ahem.ttf);
+}
new file mode 100644
--- /dev/null
+++ b/layout/reftests/columns/columnfill-auto-ref.html
@@ -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>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/columns/columnfill-auto.html
@@ -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>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/columns/columnfill-balance-ref.html
@@ -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: 100px;
+        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>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/columns/columnfill-balance.html
@@ -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: 100px;
+                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>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/columns/columnfill-change-ref.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<html>
+  <head>
+    <title>Bug 695222: Test for change of column-fill property REFERENCE</title>
+    <link rel="stylesheet" type="text/css" href="ahem.css" />
+    <style>
+      .columns {
+        -moz-column-count: 3;
+        -moz-column-gap: 0px;
+        -moz-column-fill: balance;
+        height: 120px;
+        font-family: ahem;
+        font-size: 12pt;
+        line-height: 1.1;
+      }
+    </style>
+  </head>
+  <body>
+    <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=695222">Mozilla Bug 695222</a>
+    <div id="test" style="display: block;">
+      <div id="columnsElement" class="columns">
+              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>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/columns/columnfill-change.html
@@ -0,0 +1,35 @@
+<!doctype html>
+<html class="reftest-wait">
+  <head>
+    <link rel="stylesheet" type="text/css" href="ahem.css" />
+    <title>Bug 695222: Test for change of column-fill property</title>
+    <style>
+      .columns {
+        -moz-column-count: 3;
+        -moz-column-gap: 0px;
+        -moz-column-fill: auto;
+        height: 120px;
+        font-family: ahem;
+        font-size: 12pt;
+        line-height: 1.1;
+      }
+    </style>
+    <script type="text/javascript">
+      function disableWait() {
+        document.documentElement.removeAttribute('class');
+      }
+      function main() {
+        document.getElementById('columnsElement').style.MozColumnFill = 'balance';
+        setTimeout(disableWait, 500);
+      }
+    </script>
+  </head>
+  <body onload="main();">
+    <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=695222">Mozilla Bug 695222</a>
+    <div id="test" style="display: block;">
+      <div id="columnsElement" class="columns">
+              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>
--- a/layout/reftests/columns/reftest.list
+++ b/layout/reftests/columns/reftest.list
@@ -11,12 +11,15 @@
 == column-balancing-overflow-003.html column-balancing-overflow-003.ref.html
 == column-balancing-overflow-004.html column-balancing-overflow-004.ref.html
 == column-balancing-overflow-005.html column-balancing-overflow-005.ref.html
 == column-balancing-000.html column-balancing-000.ref.html
 == column-balancing-001.html column-balancing-000.ref.html
 == 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
+HTTP(..) == columnfill-change.html columnfill-change-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
--- a/layout/reftests/pagination/abspos-overflow-01-cols.xhtml
+++ b/layout/reftests/pagination/abspos-overflow-01-cols.xhtml
@@ -29,16 +29,17 @@
       background: white;
       width: 100pt;
     }
     #colset {
       width: 300pt;
       height: 2in;
       -moz-column-count: 3;
       -moz-column-gap: 0;
+      -moz-column-fill: auto;
       border: silver 2pt;
       border-style: none solid;
     }
     #redline {
       width: 303pt;
       border-top: 4px solid red;
       margin-top: -1in;
       position: relative;
--- a/layout/reftests/pagination/border-breaking-000-cols.xhtml
+++ b/layout/reftests/pagination/border-breaking-000-cols.xhtml
@@ -20,16 +20,17 @@
       height: 200px;
     }
 
     body {
       height: 200px;
       width: 300px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
+      -moz-column-fill: auto;
       border: solid silver;
       border-style: none solid;
     }
   </style>
  </head>
  <body>
   <div class="container">
     <div class="box">
--- a/layout/reftests/pagination/border-breaking-001-cols.ref.xhtml
+++ b/layout/reftests/pagination/border-breaking-001-cols.ref.xhtml
@@ -15,16 +15,17 @@
       height: 500px;
     }
 
     .body {
       height: 200px;
       width: 300px;
       -moz-column-width: 100px;
       -moz-column-gap: 0;
+      -moz-column-fill: auto;
       border: solid silver;
       border-style: none solid;
       background: yellow;
     }
   </style>
  </head>
  <body>
   <div class="body">
--- a/layout/reftests/pagination/border-breaking-001-cols.xhtml
+++ b/layout/reftests/pagination/border-breaking-001-cols.xhtml
@@ -44,16 +44,17 @@
       height: 100px;
     }
 
     body {
       height: 200px;
       width: 300px;
       -moz-column-width: 100px;
       -moz-column-gap: 0;
+      -moz-column-fill: auto;
       border: solid silver;
       border-style: none solid;
     }
   </style>
  </head>
  <body>
   <div class="abs">
     <div class="container">
--- a/layout/reftests/pagination/border-breaking-002-cols.ref.xhtml
+++ b/layout/reftests/pagination/border-breaking-002-cols.ref.xhtml
@@ -11,16 +11,17 @@
       border-top: solid 10px aqua;
     }
 
     .multicol {
       height: 200px;
       width: 300px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
+      -moz-column-fill: auto;
       border: solid silver;
     }
   </style>
  </head>
  <body>
   There must be a continuous 10px line at the top
   of the gray box, the left half blue and the right
   half aqua.
--- a/layout/reftests/pagination/border-breaking-002-cols.xhtml
+++ b/layout/reftests/pagination/border-breaking-002-cols.xhtml
@@ -12,16 +12,17 @@
       border-bottom: solid 10px aqua;
     }
 
     .multicol {
       height: 200px;
       width: 300px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
+      -moz-column-fill: auto;
       border: solid silver;
     }
   </style>
  </head>
  <body>
   There must be a continuous 10px line at the top
   of the gray box, the left half blue and the right
   half aqua.
--- a/layout/reftests/pagination/border-breaking-003-cols.xhtml
+++ b/layout/reftests/pagination/border-breaking-003-cols.xhtml
@@ -15,16 +15,17 @@
       border-bottom: 10px solid aqua;
     }
 
     .multicol {
       height: 200px;
       width: 300px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
+      -moz-column-fill: auto;
       border: solid silver;
     }
   </style>
  </head>
  <body>
   There must be two continuous 10px lines at the top
   of the gray box, the top one blue and the bottom one
   aqua.
--- a/layout/reftests/pagination/content-inserted-002.ref.xhtml
+++ b/layout/reftests/pagination/content-inserted-002.ref.xhtml
@@ -8,16 +8,17 @@
       font-size: 16px;
     }
 
     #colset {
       height: 200px;
       width: 450px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
+      -moz-column-fill: auto;
       border: 3px solid silver;
     }
 
     #mark {
       border-bottom: 4px solid blue;
     }
 
     #shift {
--- a/layout/reftests/pagination/content-inserted-002.xhtml
+++ b/layout/reftests/pagination/content-inserted-002.xhtml
@@ -8,16 +8,17 @@
       font-size: 16px;
     }
 
     #colset {
       height: 200px;
       width: 450px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
+      -moz-column-fill: auto;
       border: 3px solid silver;
     }
 
     #x {
       height: 500px;
     }
 
     #x:after {
--- a/layout/reftests/pagination/content-inserted-003.xhtml
+++ b/layout/reftests/pagination/content-inserted-003.xhtml
@@ -8,16 +8,17 @@
       font-size: 16px;
     }
 
     #colset {
       height: 200px;
       width: 450px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
+      -moz-column-fill: auto;
       border: 3px solid silver;
     }
 
     #x {
       height: 500px;
     }
 
     #x:after {
--- a/layout/reftests/pagination/content-inserted-004.xhtml
+++ b/layout/reftests/pagination/content-inserted-004.xhtml
@@ -8,16 +8,17 @@
       font-size: 16px;
     }
 
     #colset {
       height: 200px;
       width: 450px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
+      -moz-column-fill: auto;
       border: 3px solid silver;
     }
 
     #x {
       height: 500px;
     }
 
     #x:before {
--- a/layout/reftests/pagination/content-inserted-005.xhtml
+++ b/layout/reftests/pagination/content-inserted-005.xhtml
@@ -8,16 +8,17 @@
       font-size: 16px;
     }
 
     #colset {
       height: 200px;
       width: 450px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
+      -moz-column-fill: auto;
       border: 3px solid silver;
     }
 
     #x {
       border-bottom: 4px solid blue;
     }
 
     #x:before {
--- a/layout/reftests/pagination/content-inserted-006.xhtml
+++ b/layout/reftests/pagination/content-inserted-006.xhtml
@@ -8,16 +8,17 @@
       font-size: 16px;
     }
 
     #colset {
       height: 200px;
       width: 450px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
+      -moz-column-fill: auto;
       border: 3px solid silver;
     }
 
     #x {
       height: 500px;
     }
 
     #x:after {
--- a/layout/reftests/pagination/content-inserted-007.xhtml
+++ b/layout/reftests/pagination/content-inserted-007.xhtml
@@ -8,16 +8,17 @@
       font-size: 16px;
     }
 
     #colset {
       height: 200px;
       width: 450px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
+      -moz-column-fill: auto;
       border: 3px solid silver;
     }
 
     #x {
       height: 500px;
     }
 
     #x:before {
--- a/layout/reftests/pagination/content-inserted-009.xhtml
+++ b/layout/reftests/pagination/content-inserted-009.xhtml
@@ -8,16 +8,17 @@
       font-size: 16px;
     }
 
     #colset {
       height: 200px;
       width: 450px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
+      -moz-column-fill: auto;
       border: 3px solid silver;
     }
 
     #shift {
       height: 201px;
       border-bottom: 2px solid blue;
     }
     #overflow {
--- a/layout/style/nsCSSKeywordList.h
+++ b/layout/style/nsCSSKeywordList.h
@@ -193,16 +193,17 @@ CSS_KEY(all-scroll, all_scroll)
 CSS_KEY(alternate, alternate)
 CSS_KEY(always, always)
 CSS_KEY(appworkspace, appworkspace)
 CSS_KEY(armenian, armenian)
 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)
 CSS_KEY(block, block)
 CSS_KEY(block-axis, block_axis)
 CSS_KEY(bold, bold)
 CSS_KEY(bolder, bolder)
 CSS_KEY(border-box, border_box)
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -1296,16 +1296,25 @@ CSS_PROP_COLUMN(
         // Need to reject 0 in addition to negatives.  If we accept 0, we
         // need to change NS_STYLE_COLUMN_COUNT_AUTO to something else.
         CSS_PROPERTY_VALUE_AT_LEAST_ONE,
     VARIANT_AHI,
     nsnull,
     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,
     CSS_PROP_DOMPROP_PREFIXED(ColumnWidth),
     CSS_PROPERTY_PARSE_VALUE |
         CSS_PROPERTY_VALUE_NONNEGATIVE,
     VARIANT_AHL | VARIANT_CALC,
     nsnull,
     offsetof(nsStyleColumn, mColumnWidth),
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -1468,16 +1468,22 @@ const PRInt32 nsCSSProps::kTextRendering
 
 const PRInt32 nsCSSProps::kColorInterpolationKTable[] = {
   eCSSKeyword_auto, NS_STYLE_COLOR_INTERPOLATION_AUTO,
   eCSSKeyword_srgb, NS_STYLE_COLOR_INTERPOLATION_SRGB,
   eCSSKeyword_linearrgb, NS_STYLE_COLOR_INTERPOLATION_LINEARRGB,
   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)
 {
   PRInt32 index = 0;
   while (eCSSKeyword_UNKNOWN != nsCSSKeyword(aTable[index])) {
     if (aKeyword == nsCSSKeyword(aTable[index])) {
       aResult = aTable[index+1];
       return true;
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -355,16 +355,17 @@ public:
   static const PRInt32 kFillRuleKTable[];
   static const PRInt32 kImageRenderingKTable[];
   static const PRInt32 kShapeRenderingKTable[];
   static const PRInt32 kStrokeLinecapKTable[];
   static const PRInt32 kStrokeLinejoinKTable[];
   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[];
   static const PRInt32 kCaptionSideKTable[];
   static const PRInt32 kClearKTable[];
   static const PRInt32 kColorKTable[];
   static const PRInt32 kContentKTable[];
   static const PRInt32 kCursorKTable[];
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -737,16 +737,26 @@ nsComputedDOMStyle::DoGetColumnGap()
   } else {
     SetValueToCoord(val, GetStyleColumn()->mColumnGap, true);
   }
 
   return val;
 }
 
 nsIDOMCSSValue*
+nsComputedDOMStyle::DoGetColumnFill()
+{
+  nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
+  val->SetIdent(
+    nsCSSProps::ValueToKeywordEnum(GetStyleColumn()->mColumnFill,
+                                   nsCSSProps::kColumnFillKTable));
+  return val;
+}
+
+nsIDOMCSSValue*
 nsComputedDOMStyle::DoGetColumnRuleWidth()
 {
   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
   val->SetAppUnits(GetStyleColumn()->GetComputedColumnRuleWidth());
   return val;
 }
 
 nsIDOMCSSValue*
@@ -4611,16 +4621,17 @@ nsComputedDOMStyle::GetQueryableProperty
     COMPUTED_STYLE_MAP_ENTRY(box_align,                     BoxAlign),
     COMPUTED_STYLE_MAP_ENTRY(box_direction,                 BoxDirection),
     COMPUTED_STYLE_MAP_ENTRY(box_flex,                      BoxFlex),
     COMPUTED_STYLE_MAP_ENTRY(box_ordinal_group,             BoxOrdinalGroup),
     COMPUTED_STYLE_MAP_ENTRY(box_orient,                    BoxOrient),
     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),
     COMPUTED_STYLE_MAP_ENTRY(_moz_column_rule_style,        ColumnRuleStyle),
     COMPUTED_STYLE_MAP_ENTRY(_moz_column_rule_width,        ColumnRuleWidth),
     COMPUTED_STYLE_MAP_ENTRY(_moz_column_width,             ColumnWidth),
     COMPUTED_STYLE_MAP_ENTRY(float_edge,                    FloatEdge),
     COMPUTED_STYLE_MAP_ENTRY(font_feature_settings,         MozFontFeatureSettings),
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -366,16 +366,17 @@ private:
   nsIDOMCSSValue* DoGetIMEMode();
   nsIDOMCSSValue* DoGetUserFocus();
   nsIDOMCSSValue* DoGetUserInput();
   nsIDOMCSSValue* DoGetUserModify();
   nsIDOMCSSValue* DoGetUserSelect();
 
   /* Column properties */
   nsIDOMCSSValue* DoGetColumnCount();
+  nsIDOMCSSValue* DoGetColumnFill();
   nsIDOMCSSValue* DoGetColumnWidth();
   nsIDOMCSSValue* DoGetColumnGap();
   nsIDOMCSSValue* DoGetColumnRuleWidth();
   nsIDOMCSSValue* DoGetColumnRuleStyle();
   nsIDOMCSSValue* DoGetColumnRuleColor();
 
   /* CSS Transitions */
   nsIDOMCSSValue* DoGetTransitionProperty();
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -6585,16 +6585,23 @@ nsRuleNode::ComputeColumnData(void* aSta
            eCSSUnit_Enumerated == colorValue.GetUnit()) {
     column->mColumnRuleColorIsForeground = true;
   }
   else if (SetColor(colorValue, 0, mPresContext, aContext,
                     column->mColumnRuleColor, canStoreInRuleTree)) {
     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)
 }
 
 static void
 SetSVGPaint(const nsCSSValue& aValue, const nsStyleSVGPaint& parentPaint,
             nsPresContext* aPresContext, nsStyleContext *aContext,
             nsStyleSVGPaint& aResult, nsStyleSVGPaintType aInitialPaintType,
             bool& aCanStoreInRuleTree)
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -787,16 +787,17 @@ nsChangeHint nsStyleXUL::MaxDifference()
 // nsStyleColumn
 //
 nsStyleColumn::nsStyleColumn(nsPresContext* aPresContext)
 {
   MOZ_COUNT_CTOR(nsStyleColumn);
   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;
   mColumnRuleColor = NS_RGB(0, 0, 0);
   mColumnRuleColorIsForeground = true;
 
   mTwipsPerPixel = aPresContext->AppUnitsPerDevPixel();
 }
@@ -818,17 +819,18 @@ nsChangeHint nsStyleColumn::CalcDifferen
       != (aOther.mColumnWidth.GetUnit() == eStyleUnit_Auto) ||
       mColumnCount != aOther.mColumnCount)
     // We force column count changes to do a reframe, because it's tricky to handle
     // some edge cases where the column count gets smaller and content overflows.
     // XXX not ideal
     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() ||
       mColumnRuleStyle != aOther.mColumnRuleStyle ||
       mColumnRuleColor != aOther.mColumnRuleColor ||
       mColumnRuleColorIsForeground != aOther.mColumnRuleColorIsForeground)
     return NS_STYLE_HINT_VISUAL;
 
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -2081,16 +2081,18 @@ struct nsStyleColumn {
   static bool ForceCompare() { return false; }
 
   PRUint32     mColumnCount; // [reset] see nsStyleConsts.h
   nsStyleCoord mColumnWidth; // [reset] coord, auto
   nsStyleCoord mColumnGap;   // [reset] coord, normal
 
   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;
 
   void SetColumnRuleWidth(nscoord aWidth) {
     mColumnRuleWidth = NS_ROUND_BORDER_TO_PIXELS(aWidth, mTwipsPerPixel);
   }
 
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -540,16 +540,24 @@ var gCSSProperties = {
 		domProp: "MozColumnCount",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		initial_values: [ "auto" ],
 		other_values: [ "1", "17" ],
 		// 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,
 		type: CSS_TYPE_LONGHAND,
 		initial_values: [ "normal", "1em", "-moz-calc(-2em + 3em)" ],
 		other_values: [ "2px", "4em",
 			"-moz-calc(2px)",
 			"-moz-calc(-2px)",