Bug 1489295 Part 3 - Implement column-span:all for <button>. r=dbaron
authorTing-Yu Lin <tlin@mozilla.com>
Fri, 22 Mar 2019 02:50:34 +0000
changeset 465754 804b15f4d2299995b7c212ddc50c54ac8bd1f58f
parent 465753 d53a78255fdb06dc17d7944b9ae6cf05aeeb8c38
child 465755 989c26cee55799444632810744affc2f8228252b
push id81222
push useraethanyc@gmail.com
push dateFri, 22 Mar 2019 18:46:31 +0000
treeherderautoland@989c26cee557 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs1489295, 1535200
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1489295 Part 3 - Implement column-span:all for <button>. r=dbaron We need to pull outerFrame one level up to the outer scope because it's needed when calling FinishBuildingColumns(). The patch is very similar to implementing column-span:all for <fieldset> in bug 1535200. Differential Revision: https://phabricator.services.mozilla.com/D24396
layout/base/nsCSSFrameConstructor.cpp
testing/web-platform/meta/css/css-multicol/multicol-span-all-button-001.html.ini
testing/web-platform/meta/css/css-multicol/multicol-span-all-button-002.html.ini
testing/web-platform/meta/css/css-multicol/multicol-span-all-button-003.html.ini
testing/web-platform/tests/css/css-multicol/multicol-span-all-button-001-ref.html
testing/web-platform/tests/css/css-multicol/multicol-span-all-button-001.html
testing/web-platform/tests/css/css-multicol/multicol-span-all-button-002-ref.html
testing/web-platform/tests/css/css-multicol/multicol-span-all-button-002.html
testing/web-platform/tests/css/css-multicol/multicol-span-all-button-003-ref.html
testing/web-platform/tests/css/css-multicol/multicol-span-all-button-003.html
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -3677,26 +3677,26 @@ void nsCSSFrameConstructor::ConstructFra
     // primary frame).
     primaryFrame = frameToAddToList;
 
     // If we need to create a block formatting context to wrap our
     // kids, do it now.
     nsIFrame* maybeAbsoluteContainingBlockStyleFrame = primaryFrame;
     nsIFrame* maybeAbsoluteContainingBlock = newFrame;
     nsIFrame* possiblyLeafFrame = newFrame;
+    nsContainerFrame* outerFrame = nullptr;
     if (bits & FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS) {
       RefPtr<ComputedStyle> outerStyle =
           mPresShell->StyleSet()->ResolveInheritingAnonymousBoxStyle(
               data->mAnonBoxPseudo, computedStyle);
 #ifdef DEBUG
       nsContainerFrame* containerFrame = do_QueryFrame(newFrame);
       MOZ_ASSERT(containerFrame);
 #endif
       nsContainerFrame* container = static_cast<nsContainerFrame*>(newFrame);
-      nsContainerFrame* outerFrame;
       nsContainerFrame* innerFrame;
       if (bits & FCDATA_ALLOW_GRID_FLEX_COLUMN) {
         switch (display->mDisplay) {
           case StyleDisplay::Flex:
           case StyleDisplay::InlineFlex:
             outerFrame = NS_NewFlexContainerFrame(mPresShell, outerStyle);
             InitAndRestoreFrame(aState, content, container, outerFrame);
             innerFrame = outerFrame;
@@ -3704,18 +3704,24 @@ void nsCSSFrameConstructor::ConstructFra
           case StyleDisplay::Grid:
           case StyleDisplay::InlineGrid:
             outerFrame = NS_NewGridContainerFrame(mPresShell, outerStyle);
             InitAndRestoreFrame(aState, content, container, outerFrame);
             innerFrame = outerFrame;
             break;
           default: {
             innerFrame = NS_NewBlockFormattingContext(mPresShell, outerStyle);
-            outerFrame = InitAndWrapInColumnSetFrameIfNeeded(
-                aState, content, container, innerFrame, outerStyle);
+            if (outerStyle->StyleColumn()->IsColumnContainerStyle()) {
+              outerFrame = BeginBuildingColumns(aState, content, container,
+                                                innerFrame, outerStyle);
+            } else {
+              // No need to create column container. Initialize innerFrame.
+              InitAndRestoreFrame(aState, content, container, innerFrame);
+              outerFrame = innerFrame;
+            }
             break;
           }
         }
       } else {
         innerFrame = NS_NewBlockFormattingContext(mPresShell, outerStyle);
         InitAndRestoreFrame(aState, content, container, innerFrame);
         outerFrame = innerFrame;
       }
@@ -3815,20 +3821,44 @@ void nsCSSFrameConstructor::ConstructFra
         if (childItems.NotEmpty()) {
           // an error must have occurred, delete unprocessed frames
           childItems.DestroyFrames();
         }
 
         childItems = newItems;
       }
 
-      // Set the frame's initial child list
-      // Note that MathML depends on this being called even if
-      // childItems is empty!
-      newFrameAsContainer->SetInitialChildList(kPrincipalList, childItems);
+      if (!StaticPrefs::layout_css_column_span_enabled() ||
+          !(bits & FCDATA_ALLOW_GRID_FLEX_COLUMN) ||
+          !MayNeedToCreateColumnSpanSiblings(newFrameAsContainer, childItems)) {
+        // Set the frame's initial child list. Note that MathML depends on this
+        // being called even if childItems is empty!
+        newFrameAsContainer->SetInitialChildList(kPrincipalList, childItems);
+      } else {
+        // Extract any initial non-column-span kids, and put them in inner
+        // frame's child list.
+        nsFrameList initialNonColumnSpanKids =
+            childItems.Split([](nsIFrame* f) { return f->IsColumnSpan(); });
+        newFrameAsContainer->SetInitialChildList(kPrincipalList,
+                                                 initialNonColumnSpanKids);
+
+        if (childItems.NotEmpty()) {
+          nsFrameList columnSpanSiblings = CreateColumnSpanSiblings(
+              aState, newFrameAsContainer, childItems,
+              // Column content should never be a absolute/fixed positioned
+              // containing block. Pass nullptr as aPositionedFrame.
+              nullptr);
+
+          MOZ_ASSERT(outerFrame,
+                     "outerFrame should be non-null if multi-column container "
+                     "is created.");
+          FinishBuildingColumns(aState, outerFrame, newFrameAsContainer,
+                                columnSpanSiblings);
+        }
+      }
 
       if (bits & FCDATA_MAY_NEED_BULLET) {
         nsBlockFrame* block = do_QueryFrame(newFrameAsContainer);
         MOZ_ASSERT(block,
                    "FCDATA_MAY_NEED_BULLET should not be set on "
                    "non-block type!");
         CreateBulletFrameForListItemIfNeeded(block);
       }
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-multicol/multicol-span-all-button-001.html.ini
@@ -0,0 +1,2 @@
+[multicol-span-all-button-001.html]
+  prefs: [layout.css.column-span.enabled:true]
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-multicol/multicol-span-all-button-002.html.ini
@@ -0,0 +1,2 @@
+[multicol-span-all-button-002.html]
+  prefs: [layout.css.column-span.enabled:true]
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-multicol/multicol-span-all-button-003.html.ini
@@ -0,0 +1,2 @@
+[multicol-span-all-button-003.html]
+  prefs: [layout.css.column-span.enabled:true]
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-multicol/multicol-span-all-button-001-ref.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+  <meta charset="utf-8">
+  <title>CSS Multi-column Layout Test: Test a multi-column container on button works with a column-span:all child</title>
+  <link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
+  <link rel="author" title="Mozilla" href="http://www.mozilla.org/">
+
+  <style>
+  button {
+    width: 400px;
+  }
+  .inner {
+    column-count: 3;
+    column-rule: 6px solid;
+  }
+  h3 {
+    column-span: all;
+    outline: 1px solid blue;
+  }
+  </style>
+
+  <button>
+    <div class="inner">
+      <div>block1</div><div>block2</div>
+      <h3>spanner</h3>
+      <div>block3</div><div>block4</div>
+    </div>
+  </button>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-multicol/multicol-span-all-button-001.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+  <meta charset="utf-8">
+  <title>CSS Multi-column Layout Test: Test a multi-column container on button works with a column-span:all child</title>
+  <link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
+  <link rel="author" title="Mozilla" href="http://www.mozilla.org/">
+  <link rel="help" href="https://drafts.csswg.org/css-multicol-1/#column-span">
+  <link rel="match" href="multicol-span-all-button-001-ref.html">
+  <meta name="assert" content="This test checks the page is rendered correctly for a multi-column container on button with a column-span:all child.">
+
+  <style>
+  button {
+    column-count: 3;
+    column-rule: 6px solid;
+    width: 400px;
+  }
+  h3 {
+    column-span: all;
+    outline: 1px solid blue;
+  }
+  </style>
+
+  <button>
+    <div>block1</div><div>block2</div>
+    <h3>spanner</h3>
+    <div>block3</div><div>block4</div>
+  </button>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-multicol/multicol-span-all-button-002-ref.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+  <meta charset="utf-8">
+  <title>CSS Multi-column Layout Test: Test a overflow:hidden and position:absolute multi-column container on button works with a column-span:all child and position:absolute boxes</title>
+  <link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
+  <link rel="author" title="Mozilla" href="http://www.mozilla.org/">
+
+  <style>
+  button {
+    width: 400px;
+    padding: 1em;
+    overflow: hidden;
+    position: absolute;
+  }
+  .inner {
+    column-count: 3;
+    column-rule: 6px solid;
+  }
+  h3 {
+    column-span: all;
+    outline: 1px solid blue;
+  }
+  a {
+    position: absolute;
+    width: 1em;
+    height: 1em;
+    background-color: blue;
+  }
+  </style>
+
+  <button>
+    <div class="inner">
+      <div>block1</div><div>block2</div><a></a>
+      <h3>spanner<a></a></h3>
+      <div>block3</div><div>block4</div><a></a>
+    </div>
+  </button>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-multicol/multicol-span-all-button-002.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+  <meta charset="utf-8">
+  <title>CSS Multi-column Layout Test: Test a overflow:hidden and position:absolute multi-column container on button works with a column-span:all child and position:absolute boxes</title>
+  <link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
+  <link rel="author" title="Mozilla" href="http://www.mozilla.org/">
+  <link rel="help" href="https://drafts.csswg.org/css-multicol-1/#column-span">
+  <link rel="match" href="multicol-span-all-button-002-ref.html">
+  <meta name="assert" content="This test checks the page is rendered correctly for a overflow:hidden and position:absolute button multi-column container with a column-span:all child and position:absolute boxes.">
+
+  <style>
+  button {
+    column-count: 3;
+    column-rule: 6px solid;
+    width: 400px;
+    padding: 1em;
+    overflow: hidden;
+    position: absolute;
+  }
+  h3 {
+    column-span: all;
+    outline: 1px solid blue;
+  }
+  a {
+    position: absolute;
+    width: 1em;
+    height: 1em;
+    background-color: blue;
+  }
+  </style>
+
+  <button>
+    <div>block1</div><div>block2</div><a></a>
+    <h3>spanner<a></a></h3>
+    <div>block3</div><div>block4</div><a></a>
+  </button>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-multicol/multicol-span-all-button-003-ref.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+  <meta charset="utf-8">
+  <title>CSS Multi-column Layout Test: Test a overflow:hidden and position:absolute multi-column container on button works with a column-span:all child and position:fixed boxes</title>
+  <link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
+  <link rel="author" title="Mozilla" href="http://www.mozilla.org/">
+
+  <style>
+  button {
+    width: 400px;
+    padding: 1em;
+    overflow: hidden;
+    position: absolute;
+  }
+  .inner {
+    column-count: 3;
+    column-rule: 6px solid;
+  }
+  h3 {
+    column-span: all;
+    outline: 1px solid blue;
+  }
+  a {
+    position: fixed;
+    width: 1em;
+    height: 1em;
+    background-color: blue;
+  }
+  </style>
+
+  <button>
+    <div class="inner">
+      <div>block1</div><div>block2</div><a></a>
+      <h3>spanner<a></a></h3>
+      <div>block3</div><div>block4</div><a></a>
+    </div>
+  </button>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-multicol/multicol-span-all-button-003.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+  <meta charset="utf-8">
+  <title>CSS Multi-column Layout Test: Test a overflow:hidden and position:absolute multi-column container on button works with a column-span:all child and position:fixed boxes</title>
+  <link rel="author" title="Ting-Yu Lin" href="tlin@mozilla.com">
+  <link rel="author" title="Mozilla" href="http://www.mozilla.org/">
+  <link rel="help" href="https://drafts.csswg.org/css-multicol-1/#column-span">
+  <link rel="match" href="multicol-span-all-button-003-ref.html">
+  <meta name="assert" content="This test checks the page is rendered correctly for a overflow:hidden and position:absolute button multi-column container with a column-span:all child and position:absolute boxes.">
+
+  <style>
+  button {
+    column-count: 3;
+    column-rule: 6px solid;
+    width: 400px;
+    padding: 1em;
+    overflow: hidden;
+    position: absolute;
+  }
+  h3 {
+    column-span: all;
+    outline: 1px solid blue;
+  }
+  a {
+    position: fixed;
+    width: 1em;
+    height: 1em;
+    background-color: blue;
+  }
+  </style>
+
+  <button>
+    <div>block1</div><div>block2</div><a></a>
+    <h3>spanner<a></a></h3>
+    <div>block3</div><div>block4</div><a></a>
+  </button>
+</html>