Support proper <percent> / calc() resolution for grid items
authorjchaffraix@webkit.org <jchaffraix@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 28 Nov 2012 02:16:36 +0000 (02:16 +0000)
committerjchaffraix@webkit.org <jchaffraix@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 28 Nov 2012 02:16:36 +0000 (02:16 +0000)
https://bugs.webkit.org/show_bug.cgi?id=102968

Reviewed by Ojan Vafai.

Source/WebCore:

This change introduces a mechanism similar to logical height / width override
but for containing block. This is required as we don't have a renderer for the
grid area but any <percent> or calc() size should be resolved against the grid
area size (which is sized after the grid tracks).

Tests: fast/css-grid-layout/calc-resolution-grid-item.html
       fast/css-grid-layout/percent-resolution-grid-item.html
       fast/css-grid-layout/percent-grid-item-in-percent-grid-track.html
       fast/css-grid-layout/percent-grid-item-in-percent-grid-track-in-percent-grid.html

* rendering/RenderBox.cpp:
(WebCore::RenderBox::willBeDestroyed):
Remove any containing block size override.

(WebCore::RenderBox::overrideContainingBlockContentLogicalWidth):
(WebCore::RenderBox::overrideContainingBlockContentLogicalHeight):
(WebCore::RenderBox::hasOverrideContainingBlockLogicalWidth):
(WebCore::RenderBox::hasOverrideContainingBlockLogicalHeight):
(WebCore::RenderBox::setOverrideContainingBlockContentLogicalWidth):
(WebCore::RenderBox::setOverrideContainingBlockContentLogicalHeight):
(WebCore::RenderBox::clearContainingBlockOverrideSize):
Containing block override size functions.

(WebCore::RenderBox::containingBlockLogicalWidthForContent):
Updated the function to check for any override logical width.

(WebCore::RenderBox::containingBlockLogicalHeightForContent):
New function, similar to RenderBox::containingBlockLogicalWidthForContent.

(WebCore::RenderBox::perpendicularContainingBlockLogicalHeight):
(WebCore::RenderBox::computePercentageLogicalHeight):
Updated these function to return overrideContainingBlockContentLogicalHeight as needed.

(WebCore::RenderBox::computeReplacedLogicalHeightUsing):
(WebCore::RenderBox::availableLogicalHeightUsing):
Updated these functions to use the new containingBlockLogicalHeightForContent instead
of availableLogicalHeight.

* rendering/RenderBox.h:
Added the previous new functions.

* rendering/RenderGrid.cpp:
(WebCore::RenderGrid::layoutGridItems):
Updated to override the containing block size so that we properly size our grid items.

LayoutTests:

* fast/css-grid-layout/calc-resolution-grid-item-expected.txt: Added.
* fast/css-grid-layout/calc-resolution-grid-item.html: Added.
* fast/css-grid-layout/percent-resolution-grid-item-expected.txt: Added.
* fast/css-grid-layout/percent-resolution-grid-item.html: Added.
Test that checks that our override containing block's logical width / height logic
works as expected.

* fast/css-grid-layout/percent-grid-item-in-percent-grid-track-expected.txt: Added.
* fast/css-grid-layout/percent-grid-item-in-percent-grid-track.html: Added.
* fast/css-grid-layout/percent-grid-item-in-percent-grid-track-in-percent-grid.html: Added.
* fast/css-grid-layout/percent-grid-item-in-percent-grid-track-in-percent-grid-expected.txt: Added.
Those test cases covers the cases of percentage sized grid items with percentage sized grid tracks
inside a fixed or percentage sized grid element. They don't pass yet as we don't support percentage
sized grid tracks (see bug 103335).

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@135965 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/css-grid-layout/calc-resolution-grid-item-expected.txt [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/calc-resolution-grid-item.html [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-expected.txt [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-in-percent-grid-expected.txt [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-in-percent-grid.html [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track.html [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/percent-resolution-grid-item-expected.txt [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/percent-resolution-grid-item.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderBox.cpp
Source/WebCore/rendering/RenderBox.h
Source/WebCore/rendering/RenderGrid.cpp

index 75c9f2a..53128bb 100644 (file)
@@ -1,3 +1,25 @@
+2012-11-27  Julien Chaffraix  <jchaffraix@webkit.org>
+
+        Support proper <percent> / calc() resolution for grid items
+        https://bugs.webkit.org/show_bug.cgi?id=102968
+
+        Reviewed by Ojan Vafai.
+
+        * fast/css-grid-layout/calc-resolution-grid-item-expected.txt: Added.
+        * fast/css-grid-layout/calc-resolution-grid-item.html: Added.
+        * fast/css-grid-layout/percent-resolution-grid-item-expected.txt: Added.
+        * fast/css-grid-layout/percent-resolution-grid-item.html: Added.
+        Test that checks that our override containing block's logical width / height logic
+        works as expected.
+
+        * fast/css-grid-layout/percent-grid-item-in-percent-grid-track-expected.txt: Added.
+        * fast/css-grid-layout/percent-grid-item-in-percent-grid-track.html: Added.
+        * fast/css-grid-layout/percent-grid-item-in-percent-grid-track-in-percent-grid.html: Added.
+        * fast/css-grid-layout/percent-grid-item-in-percent-grid-track-in-percent-grid-expected.txt: Added.
+        Those test cases covers the cases of percentage sized grid items with percentage sized grid tracks
+        inside a fixed or percentage sized grid element. They don't pass yet as we don't support percentage
+        sized grid tracks (see bug 103335).
+
 2012-11-27  Yael Aharon  <yael.aharon@intel.com>
 
         Unreviewed gardening. Add more tests that started failing after http://trac.webkit.org/changeset/135935
diff --git a/LayoutTests/fast/css-grid-layout/calc-resolution-grid-item-expected.txt b/LayoutTests/fast/css-grid-layout/calc-resolution-grid-item-expected.txt
new file mode 100644 (file)
index 0000000..ed8fdb1
--- /dev/null
@@ -0,0 +1,6 @@
+Test that resolving calc lengths on grid items works properly on a fixed grid with different writing modes.
+
+PASS
+PASS
+PASS
+PASS
diff --git a/LayoutTests/fast/css-grid-layout/calc-resolution-grid-item.html b/LayoutTests/fast/css-grid-layout/calc-resolution-grid-item.html
new file mode 100644 (file)
index 0000000..6ce0427
--- /dev/null
@@ -0,0 +1,93 @@
+<!DOCTYPE html>
+<html>
+<script>
+if (window.testRunner)
+    testRunner.overridePreference("WebKitCSSGridLayoutEnabled", 1);
+</script>
+<style>
+.grid {
+    display: -webkit-grid;
+    background-color: grey;
+    -webkit-grid-columns: 100px 300px;
+    -webkit-grid-rows: 50px 150px;
+    height: 200px;
+    width: 400px;
+}
+
+#a {
+    background-color: blue;
+    -webkit-grid-column: 1;
+    -webkit-grid-row: 1;
+}
+
+#b {
+    background-color: lime;
+    -webkit-grid-column: 2;
+    -webkit-grid-row: 1;
+}
+
+#c {
+    background-color: purple;
+    -webkit-grid-column: 1;
+    -webkit-grid-row: 2;
+}
+
+#d {
+    background-color: orange;
+    -webkit-grid-column: 2;
+    -webkit-grid-row: 2;
+}
+
+.calcWidth {
+    width: -webkit-calc(80% + 20%);
+    height: 15px;
+}
+
+.calcHeight {
+    width: 15px;
+    height: -webkit-calc(80% + 20px);
+}
+
+.calcHeightAndWidth {
+    width: -webkit-calc(80% + 20px);
+    height: -webkit-calc(70% + 30%);
+}
+
+.verticalRL {
+    -webkit-writing-mode: vertical-rl;
+}
+</style>
+<script src="../../resources/check-layout.js"></script>
+<body onload="checkLayout('.grid')">
+
+<p>Test that resolving calc lengths on grid items works properly on a fixed grid with different writing modes.</p>
+
+<div class="grid">
+    <div id="a" class="calcWidth" data-expected-width="100" data-expected-height="15"></div>
+    <div id="b" class="calcHeight" data-expected-width="15" data-expected-height="60"></div>
+    <div id="c" class="calcHeightAndWidth" data-expected-width="100" data-expected-height="150"></div>
+    <div id="d" class="calcHeightAndWidth" data-expected-width="260" data-expected-height="150"></div>
+</div>
+
+<div class="grid verticalRL">
+    <div id="a" class="calcWidth" data-expected-width="50" data-expected-height="15"></div>
+    <div id="b" class="calcHeight" data-expected-width="15" data-expected-height="260"></div>
+    <div id="c" class="calcHeightAndWidth" data-expected-width="140" data-expected-height="100"></div>
+    <div id="d" class="calcHeightAndWidth" data-expected-width="140" data-expected-height="300"></div>
+</div>
+
+<div class="grid">
+    <div id="a" class="calcWidth verticalRL" data-expected-width="100" data-expected-height="15"></div>
+    <div id="b" class="calcHeight verticalRL" data-expected-width="15" data-expected-height="60"></div>
+    <div id="c" class="calcHeightAndWidth verticalRL" data-expected-width="100" data-expected-height="150"></div>
+    <div id="d" class="calcHeightAndWidth verticalRL" data-expected-width="260" data-expected-height="150"></div>
+</div>
+
+<div class="grid">
+    <div id="a" class="calcWidth verticalRL" data-expected-width="100" data-expected-height="15"></div>
+    <div id="b" class="calcHeight" data-expected-width="15" data-expected-height="60"></div>
+    <div id="c" class="calcHeightAndWidth verticalRL" data-expected-width="100" data-expected-height="150"></div>
+    <div id="d" class="calcHeightAndWidth" data-expected-width="260" data-expected-height="150"></div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-expected.txt b/LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-expected.txt
new file mode 100644 (file)
index 0000000..9553708
--- /dev/null
@@ -0,0 +1,58 @@
+Test that percentage sized grid items inside percentage sized grid tracks get properly sized.
+
+FAIL:
+Expected 160 for width, but got 0. 
+Expected 90 for height, but got 0. 
+Expected 80 for width, but got 0. 
+Expected 105 for height, but got 0. 
+Expected 240 for width, but got 0. 
+Expected 210 for height, but got 0. 
+
+<div class="grid" data-expected-width="400" data-expected-height="300">
+    <div id="a" data-expected-width="160" data-expected-height="15"></div>
+    <div id="b" data-expected-width="15" data-expected-height="90"></div>
+    <div id="c" data-expected-width="80" data-expected-height="105"></div>
+    <div id="d" data-expected-width="240" data-expected-height="210"></div>
+</div>
+FAIL:
+Expected 160 for width, but got 0. 
+Expected 90 for height, but got 0. 
+Expected 80 for width, but got 0. 
+Expected 105 for height, but got 0. 
+Expected 240 for width, but got 0. 
+Expected 210 for height, but got 0. 
+
+<div class="grid" style="-webkit-writing-mode: horizontal-bt" data-expected-width="400" data-expected-height="300">
+    <div id="a" data-expected-width="160" data-expected-height="15"></div>
+    <div id="b" data-expected-width="15" data-expected-height="90"></div>
+    <div id="c" data-expected-width="80" data-expected-height="105"></div>
+    <div id="d" data-expected-width="240" data-expected-height="210"></div>
+</div>
+FAIL:
+Expected 120 for width, but got 0. 
+Expected 180 for height, but got 0. 
+Expected 140 for width, but got 0. 
+Expected 60 for height, but got 0. 
+Expected 280 for width, but got 0. 
+Expected 180 for height, but got 0. 
+
+<div class="grid" style="-webkit-writing-mode: vertical-rl;" data-expected-width="400" data-expected-height="300">
+    <div id="a" data-expected-width="120" data-expected-height="15"></div>
+    <div id="b" data-expected-width="15" data-expected-height="180"></div>
+    <div id="c" data-expected-width="140" data-expected-height="60"></div>
+    <div id="d" data-expected-width="280" data-expected-height="180"></div>
+</div>
+FAIL:
+Expected 120 for width, but got 0. 
+Expected 180 for height, but got 0. 
+Expected 140 for width, but got 0. 
+Expected 60 for height, but got 0. 
+Expected 280 for width, but got 0. 
+Expected 180 for height, but got 0. 
+
+<div class="grid" style="-webkit-writing-mode: vertical-lr;" data-expected-width="400" data-expected-height="300">
+    <div id="a" data-expected-width="120" data-expected-height="15"></div>
+    <div id="b" data-expected-width="15" data-expected-height="180"></div>
+    <div id="c" data-expected-width="140" data-expected-height="60"></div>
+    <div id="d" data-expected-width="280" data-expected-height="180"></div>
+</div>
diff --git a/LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-in-percent-grid-expected.txt b/LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-in-percent-grid-expected.txt
new file mode 100644 (file)
index 0000000..a7271dc
--- /dev/null
@@ -0,0 +1,66 @@
+Test that percentage sized grid items inside percentage sized grid tracks inside a percentage size grid get properly sized.
+
+FAIL:
+Expected 160 for width, but got 0. 
+Expected 90 for height, but got 0. 
+Expected 80 for width, but got 0. 
+Expected 105 for height, but got 0. 
+Expected 240 for width, but got 0. 
+Expected 210 for height, but got 0. 
+
+<div class="container">
+<div class="grid" data-expected-width="400" data-expected-height="300">
+    <div id="a" data-expected-width="160" data-expected-height="15"></div>
+    <div id="b" data-expected-width="15" data-expected-height="90"></div>
+    <div id="c" data-expected-width="80" data-expected-height="105"></div>
+    <div id="d" data-expected-width="240" data-expected-height="210"></div>
+</div>
+</div>
+FAIL:
+Expected 160 for width, but got 0. 
+Expected 90 for height, but got 0. 
+Expected 80 for width, but got 0. 
+Expected 105 for height, but got 0. 
+Expected 240 for width, but got 0. 
+Expected 210 for height, but got 0. 
+
+<div class="container">
+<div class="grid" style="-webkit-writing-mode: horizontal-bt" data-expected-width="400" data-expected-height="300">
+    <div id="a" data-expected-width="160" data-expected-height="15"></div>
+    <div id="b" data-expected-width="15" data-expected-height="90"></div>
+    <div id="c" data-expected-width="80" data-expected-height="105"></div>
+    <div id="d" data-expected-width="240" data-expected-height="210"></div>
+</div>
+</div>
+FAIL:
+Expected 120 for width, but got 0. 
+Expected 180 for height, but got 0. 
+Expected 140 for width, but got 0. 
+Expected 60 for height, but got 0. 
+Expected 280 for width, but got 0. 
+Expected 180 for height, but got 0. 
+
+<div class="container">
+<div class="grid" style="-webkit-writing-mode: vertical-rl;" data-expected-width="400" data-expected-height="300">
+    <div id="a" data-expected-width="120" data-expected-height="15"></div>
+    <div id="b" data-expected-width="15" data-expected-height="180"></div>
+    <div id="c" data-expected-width="140" data-expected-height="60"></div>
+    <div id="d" data-expected-width="280" data-expected-height="180"></div>
+</div>
+</div>
+FAIL:
+Expected 120 for width, but got 0. 
+Expected 180 for height, but got 0. 
+Expected 140 for width, but got 0. 
+Expected 60 for height, but got 0. 
+Expected 280 for width, but got 0. 
+Expected 180 for height, but got 0. 
+
+<div class="container">
+<div class="grid" style="-webkit-writing-mode: vertical-lr;" data-expected-width="400" data-expected-height="300">
+    <div id="a" data-expected-width="120" data-expected-height="15"></div>
+    <div id="b" data-expected-width="15" data-expected-height="180"></div>
+    <div id="c" data-expected-width="140" data-expected-height="60"></div>
+    <div id="d" data-expected-width="280" data-expected-height="180"></div>
+</div>
+</div>
diff --git a/LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-in-percent-grid.html b/LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-in-percent-grid.html
new file mode 100644 (file)
index 0000000..8df42cf
--- /dev/null
@@ -0,0 +1,94 @@
+<!DOCTYPE html>
+<html>
+<script>
+if (window.testRunner)
+    testRunner.overridePreference("WebKitCSSGridLayoutEnabled", 1);
+</script>
+<style>
+.container {
+    position: relative;
+    width: 500px;
+    height: 600px;
+}
+
+.grid {
+    display: -webkit-grid;
+    -webkit-grid-columns: 40% 60%;
+    -webkit-grid-rows: 30% 70%;
+    background-color: grey;
+    width: 80%;
+    height: 50%;
+}
+
+#a {
+    background-color: blue;
+    -webkit-grid-column: 1;
+    -webkit-grid-row: 1;
+    width: 100%;
+    height: 15px;
+}
+#b {
+    background-color: green;
+    -webkit-grid-column: 2;
+    -webkit-grid-row: 1;
+    width: 15px;
+    height: 100%;
+}
+#c {
+    background-color: red;
+    -webkit-grid-column: 1;
+    -webkit-grid-row: 2;
+    width: 50%;
+    height: 50%;
+}
+#d {
+    background-color: orange;
+    -webkit-grid-column: 2;
+    -webkit-grid-row: 2;
+    width: -webkit-calc(100%);
+    height: -webkit-calc(100%);
+}
+</style>
+<script src="../../resources/check-layout.js"></script>
+<body onload="checkLayout('.grid')">
+
+<p>Test that percentage sized grid items inside percentage sized grid tracks inside a percentage size grid get properly sized.</p>
+
+<div class="container">
+<div class="grid" data-expected-width="400" data-expected-height="300">
+    <div id="a" data-expected-width="160" data-expected-height="15"></div>
+    <div id="b" data-expected-width="15" data-expected-height="90"></div>
+    <div id="c" data-expected-width="80" data-expected-height="105"></div>
+    <div id="d" data-expected-width="240" data-expected-height="210"></div>
+</div>
+</div>
+
+<div class="container">
+<div class="grid" style="-webkit-writing-mode: horizontal-bt" data-expected-width="400" data-expected-height="300">
+    <div id="a" data-expected-width="160" data-expected-height="15"></div>
+    <div id="b" data-expected-width="15" data-expected-height="90"></div>
+    <div id="c" data-expected-width="80" data-expected-height="105"></div>
+    <div id="d" data-expected-width="240" data-expected-height="210"></div>
+</div>
+</div>
+
+<div class="container">
+<div class="grid" style="-webkit-writing-mode: vertical-rl;" data-expected-width="400" data-expected-height="300">
+    <div id="a" data-expected-width="120" data-expected-height="15"></div>
+    <div id="b" data-expected-width="15" data-expected-height="180"></div>
+    <div id="c" data-expected-width="140" data-expected-height="60"></div>
+    <div id="d" data-expected-width="280" data-expected-height="180"></div>
+</div>
+</div>
+
+<div class="container">
+<div class="grid" style="-webkit-writing-mode: vertical-lr;" data-expected-width="400" data-expected-height="300">
+    <div id="a" data-expected-width="120" data-expected-height="15"></div>
+    <div id="b" data-expected-width="15" data-expected-height="180"></div>
+    <div id="c" data-expected-width="140" data-expected-height="60"></div>
+    <div id="d" data-expected-width="280" data-expected-height="180"></div>
+</div>
+</div>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track.html b/LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track.html
new file mode 100644 (file)
index 0000000..77dff2f
--- /dev/null
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<html>
+<script>
+if (window.testRunner)
+    testRunner.overridePreference("WebKitCSSGridLayoutEnabled", 1);
+</script>
+<style>
+.grid {
+    display: -webkit-grid;
+    -webkit-grid-columns: 40% 60%;
+    -webkit-grid-rows: 30% 70%;
+    background-color: grey;
+    width: 400px;
+    height: 300px;
+}
+
+#a {
+    background-color: blue;
+    -webkit-grid-column: 1;
+    -webkit-grid-row: 1;
+    width: 100%;
+    height: 15px;
+}
+#b {
+    background-color: green;
+    -webkit-grid-column: 2;
+    -webkit-grid-row: 1;
+    width: 15px;
+    height: 100%;
+}
+#c {
+    background-color: red;
+    -webkit-grid-column: 1;
+    -webkit-grid-row: 2;
+    width: 50%;
+    height: 50%;
+}
+#d {
+    background-color: orange;
+    -webkit-grid-column: 2;
+    -webkit-grid-row: 2;
+    width: -webkit-calc(100%);
+    height: -webkit-calc(100%);
+}
+</style>
+<script src="../../resources/check-layout.js"></script>
+<body onload="checkLayout('.grid')">
+
+<p>Test that percentage sized grid items inside percentage sized grid tracks get properly sized.</p>
+
+<div style="position: relative">
+<div class="grid" data-expected-width="400" data-expected-height="300">
+    <div id="a" data-expected-width="160" data-expected-height="15"></div>
+    <div id="b" data-expected-width="15" data-expected-height="90"></div>
+    <div id="c" data-expected-width="80" data-expected-height="105"></div>
+    <div id="d" data-expected-width="240" data-expected-height="210"></div>
+</div>
+</div>
+
+<div style="position: relative">
+<div class="grid" style="-webkit-writing-mode: horizontal-bt" data-expected-width="400" data-expected-height="300">
+    <div id="a" data-expected-width="160" data-expected-height="15"></div>
+    <div id="b" data-expected-width="15" data-expected-height="90"></div>
+    <div id="c" data-expected-width="80" data-expected-height="105"></div>
+    <div id="d" data-expected-width="240" data-expected-height="210"></div>
+</div>
+</div>
+
+<div style="position: relative">
+<div class="grid" style="-webkit-writing-mode: vertical-rl;" data-expected-width="400" data-expected-height="300">
+    <div id="a" data-expected-width="120" data-expected-height="15"></div>
+    <div id="b" data-expected-width="15" data-expected-height="180"></div>
+    <div id="c" data-expected-width="140" data-expected-height="60"></div>
+    <div id="d" data-expected-width="280" data-expected-height="180"></div>
+</div>
+</div>
+
+<div style="position: relative">
+<div class="grid" style="-webkit-writing-mode: vertical-lr;" data-expected-width="400" data-expected-height="300">
+    <div id="a" data-expected-width="120" data-expected-height="15"></div>
+    <div id="b" data-expected-width="15" data-expected-height="180"></div>
+    <div id="c" data-expected-width="140" data-expected-height="60"></div>
+    <div id="d" data-expected-width="280" data-expected-height="180"></div>
+</div>
+</div>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/css-grid-layout/percent-resolution-grid-item-expected.txt b/LayoutTests/fast/css-grid-layout/percent-resolution-grid-item-expected.txt
new file mode 100644 (file)
index 0000000..0b435f5
--- /dev/null
@@ -0,0 +1,6 @@
+Test that resolving percent lengths on grid items works properly on a fixed grid with different writing modes.
+
+PASS
+PASS
+PASS
+PASS
diff --git a/LayoutTests/fast/css-grid-layout/percent-resolution-grid-item.html b/LayoutTests/fast/css-grid-layout/percent-resolution-grid-item.html
new file mode 100644 (file)
index 0000000..97e1e59
--- /dev/null
@@ -0,0 +1,93 @@
+<!DOCTYPE html>
+<html>
+<script>
+if (window.testRunner)
+    testRunner.overridePreference("WebKitCSSGridLayoutEnabled", 1);
+</script>
+<style>
+.grid {
+    display: -webkit-grid;
+    background-color: grey;
+    -webkit-grid-columns: 100px 300px;
+    -webkit-grid-rows: 50px 150px;
+    height: 200px;
+    width: 400px;
+}
+
+#a {
+    background-color: blue;
+    -webkit-grid-column: 1;
+    -webkit-grid-row: 1;
+}
+
+#b {
+    background-color: lime;
+    -webkit-grid-column: 2;
+    -webkit-grid-row: 1;
+}
+
+#c {
+    background-color: purple;
+    -webkit-grid-column: 1;
+    -webkit-grid-row: 2;
+}
+
+#d {
+    background-color: orange;
+    -webkit-grid-column: 2;
+    -webkit-grid-row: 2;
+}
+
+.percentWidth {
+    width: 100%;
+    height: 15px;
+}
+
+.percentHeight {
+    width: 15px;
+    height: 100%;
+}
+
+.percentHeightAndWidth {
+    width: 100%;
+    height: 100%;
+}
+
+.verticalRL {
+    -webkit-writing-mode: vertical-rl;
+}
+</style>
+<script src="../../resources/check-layout.js"></script>
+<body onload="checkLayout('.grid')">
+
+<p>Test that resolving percent lengths on grid items works properly on a fixed grid with different writing modes.</p>
+
+<div class="grid">
+    <div id="a" class="percentWidth" data-expected-width="100" data-expected-height="15"></div>
+    <div id="b" class="percentHeight" data-expected-width="15" data-expected-height="50"></div>
+    <div id="c" class="percentHeightAndWidth" data-expected-width="100" data-expected-height="150"></div>
+    <div id="d" class="percentHeightAndWidth" data-expected-width="300" data-expected-height="150"></div>
+</div>
+
+<div class="grid verticalRL">
+    <div id="a" class="percentWidth" data-expected-width="50" data-expected-height="15"></div>
+    <div id="b" class="percentHeight" data-expected-width="15" data-expected-height="300"></div>
+    <div id="c" class="percentHeightAndWidth" data-expected-width="150" data-expected-height="100"></div>
+    <div id="d" class="percentHeightAndWidth" data-expected-width="150" data-expected-height="300"></div>
+</div>
+
+<div class="grid">
+    <div id="a" class="percentWidth verticalRL" data-expected-width="100" data-expected-height="15"></div>
+    <div id="b" class="percentHeight verticalRL" data-expected-width="15" data-expected-height="50"></div>
+    <div id="c" class="percentHeightAndWidth verticalRL" data-expected-width="100" data-expected-height="150"></div>
+    <div id="d" class="percentHeightAndWidth verticalRL" data-expected-width="300" data-expected-height="150"></div>
+</div>
+
+<div class="grid">
+    <div id="a" class="percentWidth verticalRL" data-expected-width="100" data-expected-height="15"></div>
+    <div id="b" class="percentHeight" data-expected-width="15" data-expected-height="50"></div>
+    <div id="c" class="percentHeightAndWidth verticalRL" data-expected-width="100" data-expected-height="150"></div>
+    <div id="d" class="percentHeightAndWidth" data-expected-width="300" data-expected-height="150"></div>
+</div>
+</body>
+</html>
index 1b72b96..b80a2e2 100644 (file)
@@ -1,3 +1,55 @@
+2012-11-27  Julien Chaffraix  <jchaffraix@webkit.org>
+
+        Support proper <percent> / calc() resolution for grid items
+        https://bugs.webkit.org/show_bug.cgi?id=102968
+
+        Reviewed by Ojan Vafai.
+
+        This change introduces a mechanism similar to logical height / width override
+        but for containing block. This is required as we don't have a renderer for the
+        grid area but any <percent> or calc() size should be resolved against the grid
+        area size (which is sized after the grid tracks).
+
+        Tests: fast/css-grid-layout/calc-resolution-grid-item.html
+               fast/css-grid-layout/percent-resolution-grid-item.html
+               fast/css-grid-layout/percent-grid-item-in-percent-grid-track.html
+               fast/css-grid-layout/percent-grid-item-in-percent-grid-track-in-percent-grid.html
+
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::willBeDestroyed):
+        Remove any containing block size override.
+
+        (WebCore::RenderBox::overrideContainingBlockContentLogicalWidth):
+        (WebCore::RenderBox::overrideContainingBlockContentLogicalHeight):
+        (WebCore::RenderBox::hasOverrideContainingBlockLogicalWidth):
+        (WebCore::RenderBox::hasOverrideContainingBlockLogicalHeight):
+        (WebCore::RenderBox::setOverrideContainingBlockContentLogicalWidth):
+        (WebCore::RenderBox::setOverrideContainingBlockContentLogicalHeight):
+        (WebCore::RenderBox::clearContainingBlockOverrideSize):
+        Containing block override size functions.
+
+        (WebCore::RenderBox::containingBlockLogicalWidthForContent):
+        Updated the function to check for any override logical width.
+
+        (WebCore::RenderBox::containingBlockLogicalHeightForContent):
+        New function, similar to RenderBox::containingBlockLogicalWidthForContent.
+
+        (WebCore::RenderBox::perpendicularContainingBlockLogicalHeight):
+        (WebCore::RenderBox::computePercentageLogicalHeight):
+        Updated these function to return overrideContainingBlockContentLogicalHeight as needed.
+
+        (WebCore::RenderBox::computeReplacedLogicalHeightUsing):
+        (WebCore::RenderBox::availableLogicalHeightUsing):
+        Updated these functions to use the new containingBlockLogicalHeightForContent instead
+        of availableLogicalHeight.
+
+        * rendering/RenderBox.h:
+        Added the previous new functions.
+
+        * rendering/RenderGrid.cpp:
+        (WebCore::RenderGrid::layoutGridItems):
+        Updated to override the containing block size so that we properly size our grid items.
+
 2012-11-27  Kent Tamura  <tkent@chromium.org>
 
         Fix build errors by r135955.
index 89f4d12..44f3de1 100644 (file)
@@ -68,6 +68,10 @@ typedef WTF::HashMap<const RenderBox*, LayoutUnit> OverrideSizeMap;
 static OverrideSizeMap* gOverrideHeightMap = 0;
 static OverrideSizeMap* gOverrideWidthMap = 0;
 
+// Used by grid elements to properly size their grid items.
+static OverrideSizeMap* gOverrideContainingBlockLogicalHeightMap = 0;
+static OverrideSizeMap* gOverrideContainingBlockLogicalWidthMap = 0;
+
 bool RenderBox::s_hadOverflowClip = false;
 
 RenderBox::RenderBox(Node* node)
@@ -133,6 +137,7 @@ void RenderBox::clearRenderBoxRegionInfo()
 void RenderBox::willBeDestroyed()
 {
     clearOverrideSize();
+    clearContainingBlockOverrideSize();
 
     RenderBlock::removePercentHeightDescendantIfNeeded(this);
 
@@ -738,6 +743,50 @@ LayoutUnit RenderBox::overrideLogicalContentHeight() const
     return gOverrideHeightMap->get(this);
 }
 
+LayoutUnit RenderBox::overrideContainingBlockContentLogicalWidth() const
+{
+    ASSERT(hasOverrideContainingBlockLogicalWidth());
+    return gOverrideContainingBlockLogicalWidthMap->get(this);
+}
+
+LayoutUnit RenderBox::overrideContainingBlockContentLogicalHeight() const
+{
+    ASSERT(hasOverrideContainingBlockLogicalHeight());
+    return gOverrideContainingBlockLogicalHeightMap->get(this);
+}
+
+bool RenderBox::hasOverrideContainingBlockLogicalWidth() const
+{
+    return gOverrideContainingBlockLogicalWidthMap && gOverrideContainingBlockLogicalWidthMap->contains(this);
+}
+
+bool RenderBox::hasOverrideContainingBlockLogicalHeight() const
+{
+    return gOverrideContainingBlockLogicalHeightMap && gOverrideContainingBlockLogicalHeightMap->contains(this);
+}
+
+void RenderBox::setOverrideContainingBlockContentLogicalWidth(LayoutUnit logicalWidth)
+{
+    if (!gOverrideContainingBlockLogicalWidthMap)
+        gOverrideContainingBlockLogicalWidthMap = new OverrideSizeMap;
+    gOverrideContainingBlockLogicalWidthMap->set(this, logicalWidth);
+}
+
+void RenderBox::setOverrideContainingBlockContentLogicalHeight(LayoutUnit logicalHeight)
+{
+    if (!gOverrideContainingBlockLogicalHeightMap)
+        gOverrideContainingBlockLogicalHeightMap = new OverrideSizeMap;
+    gOverrideContainingBlockLogicalHeightMap->set(this, logicalHeight);
+}
+
+void RenderBox::clearContainingBlockOverrideSize()
+{
+    if (gOverrideContainingBlockLogicalWidthMap)
+        gOverrideContainingBlockLogicalWidthMap->remove(this);
+    if (gOverrideContainingBlockLogicalHeightMap)
+        gOverrideContainingBlockLogicalHeightMap->remove(this);
+}
+
 LayoutUnit RenderBox::adjustBorderBoxLogicalWidthForBoxSizing(LayoutUnit width) const
 {
     LayoutUnit bordersPlusPadding = borderAndPaddingLogicalWidth();
@@ -1251,10 +1300,22 @@ LayoutUnit RenderBox::shrinkLogicalWidthToAvoidFloats(LayoutUnit childMarginStar
 
 LayoutUnit RenderBox::containingBlockLogicalWidthForContent() const
 {
+    if (hasOverrideContainingBlockLogicalWidth())
+        return overrideContainingBlockContentLogicalWidth();
+
     RenderBlock* cb = containingBlock();
     return cb->availableLogicalWidth();
 }
 
+LayoutUnit RenderBox::containingBlockLogicalHeightForContent() const
+{
+    if (hasOverrideContainingBlockLogicalHeight())
+        return overrideContainingBlockContentLogicalHeight();
+
+    RenderBlock* cb = containingBlock();
+    return cb->availableLogicalHeight();
+}
+
 LayoutUnit RenderBox::containingBlockLogicalWidthForContentInRegion(RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage) const
 {
     if (!region)
@@ -1262,6 +1323,8 @@ LayoutUnit RenderBox::containingBlockLogicalWidthForContentInRegion(RenderRegion
 
     RenderBlock* cb = containingBlock();
     RenderRegion* containingBlockRegion = cb->clampToStartAndEndRegions(region);
+    // FIXME: It's unclear if a region's content should use the containing block's override logical width.
+    // If it should, the following line should call containingBlockLogicalWidthForContent.
     LayoutUnit result = cb->availableLogicalWidth();
     RenderBoxRegionInfo* boxInfo = cb->renderBoxRegionInfo(containingBlockRegion, offsetFromLogicalTopOfFirstPage - logicalTop());
     if (!boxInfo)
@@ -1285,6 +1348,9 @@ LayoutUnit RenderBox::containingBlockAvailableLineWidthInRegion(RenderRegion* re
 
 LayoutUnit RenderBox::perpendicularContainingBlockLogicalHeight() const
 {
+    if (hasOverrideContainingBlockLogicalHeight())
+        return overrideContainingBlockContentLogicalHeight();
+
     RenderBlock* cb = containingBlock();
     if (cb->hasOverrideHeight())
         return cb->overrideLogicalContentHeight();
@@ -2217,6 +2283,8 @@ LayoutUnit RenderBox::computePercentageLogicalHeight(const Length& height) const
 
     if (isHorizontalWritingMode() != cb->isHorizontalWritingMode())
         availableHeight = containingBlockChild->containingBlockLogicalWidthForContent();
+    else if (hasOverrideContainingBlockLogicalHeight())
+        availableHeight = overrideContainingBlockContentLogicalHeight();
     else if (cb->isTableCell()) {
         if (!skippedAutoHeightContainingBlock) {
             // Table cells violate what the CSS spec says to do with heights. Basically we
@@ -2363,7 +2431,7 @@ LayoutUnit RenderBox::computeReplacedLogicalHeightUsing(SizeType sizeType, Lengt
             if (isOutOfFlowPositioned())
                 availableHeight = containingBlockLogicalHeightForPositioned(toRenderBoxModelObject(cb));
             else {
-                availableHeight =  toRenderBox(cb)->availableLogicalHeight();
+                availableHeight = containingBlockLogicalHeightForContent();
                 // It is necessary to use the border-box to match WinIE's broken
                 // box model.  This is essential for sizing inside
                 // table cells using percentage heights.
@@ -2431,7 +2499,7 @@ LayoutUnit RenderBox::availableLogicalHeightUsing(const Length& h) const
     }
 
     // FIXME: This is wrong if the containingBlock has a perpendicular writing mode.
-    return containingBlock()->availableLogicalHeight();
+    return containingBlockLogicalHeightForContent();
 }
 
 void RenderBox::computeBlockDirectionMargins(const RenderBlock* containingBlock, LayoutUnit& marginBefore, LayoutUnit& marginAfter) const
index 156b729..c1de3e7 100644 (file)
@@ -305,6 +305,14 @@ public:
     void clearOverrideLogicalContentHeight();
     void clearOverrideLogicalContentWidth();
 
+    LayoutUnit overrideContainingBlockContentLogicalWidth() const;
+    LayoutUnit overrideContainingBlockContentLogicalHeight() const;
+    bool hasOverrideContainingBlockLogicalWidth() const;
+    bool hasOverrideContainingBlockLogicalHeight() const;
+    void setOverrideContainingBlockContentLogicalWidth(LayoutUnit);
+    void setOverrideContainingBlockContentLogicalHeight(LayoutUnit);
+    void clearContainingBlockOverrideSize();
+
     virtual LayoutSize offsetFromContainer(RenderObject*, const LayoutPoint&, bool* offsetDependsOnPoint = 0) const;
     
     LayoutUnit adjustBorderBoxLogicalWidthForBoxSizing(LayoutUnit width) const;
@@ -368,6 +376,8 @@ public:
     virtual void repaintDuringLayoutIfMoved(const LayoutRect&);
 
     virtual LayoutUnit containingBlockLogicalWidthForContent() const;
+    LayoutUnit containingBlockLogicalHeightForContent() const;
+
     LayoutUnit containingBlockLogicalWidthForContentInRegion(RenderRegion*, LayoutUnit offsetFromLogicalTopOfFirstPage) const;
     LayoutUnit containingBlockAvailableLineWidthInRegion(RenderRegion*, LayoutUnit offsetFromLogicalTopOfFirstPage) const;
     LayoutUnit perpendicularContainingBlockLogicalHeight() const;
index e520581..492a83f 100644 (file)
@@ -161,6 +161,15 @@ void RenderGrid::layoutGridItems()
 
     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
         LayoutPoint childPosition = findChildLogicalPosition(child, columnTracks, rowTracks);
+
+        size_t columnTrack = resolveGridPosition(child->style()->gridItemColumn());
+        size_t rowTrack = resolveGridPosition(child->style()->gridItemRow());
+
+        // Because the grid area cannot be styled, we don't need to adjust
+        // the grid breadth to account for 'box-sizing'.
+        child->setOverrideContainingBlockContentLogicalWidth(columnTracks[columnTrack].m_usedBreadth);
+        child->setOverrideContainingBlockContentLogicalHeight(rowTracks[rowTrack].m_usedBreadth);
+
         // FIXME: Grid items should stretch to fill their cells. Once we
         // implement grid-{column,row}-align, we can also shrink to fit. For
         // now, just size as if we were a regular child.