[CSS Grid Layout] Relayout whenever Box Alignment properties change
authorjfernandez@igalia.com <jfernandez@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 17 Sep 2015 09:13:35 +0000 (09:13 +0000)
committerjfernandez@igalia.com <jfernandez@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 17 Sep 2015 09:13:35 +0000 (09:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=148070

Reviewed by Darin Adler.

Source/WebCore:

We were Reattaching the styles to the RenderTree whenever Content Alignment
properties (align-items and justify-items) changed their values, since the
Self Alignment properties depend on such values to resolve 'auto' values
during layout.

This patch removes such restriction, since we resolve the auto values
whenever we access the alignment properties. The only thing we need to
do is to mark a grid item for layout whenever the Default Alignment
properties change from/to stretch, since it implies a resize of the grid
items using 'auto' values for the Self Alignment properties.

Tests: fast/css-grid-layout/relayout-align-items-changed.html
       fast/css-grid-layout/relayout-align-self-changed.html
       fast/css-grid-layout/relayout-justify-items-changed.html
       fast/css-grid-layout/relayout-justify-self-changed.html
       fast/repaint/align-items-change.html
       fast/repaint/align-items-overflow-change.html
       fast/repaint/align-self-change.html
       fast/repaint/align-self-overflow-change.html
       fast/repaint/justify-items-change.html
       fast/repaint/justify-items-legacy-change.html
       fast/repaint/justify-items-overflow-change.html
       fast/repaint/justify-self-change.html
       fast/repaint/justify-self-overflow-change.html

* rendering/RenderGrid.cpp:
(WebCore::defaultAlignmentIsStretch):
(WebCore::RenderGrid::styleDidChange):
* rendering/RenderGrid.h:
* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::resolveAlignmentOverflow):
(WebCore::RenderStyle::changeRequiresLayout):
* style/StyleResolveTree.cpp:
(WebCore::Style::determineChange): Deleted.

LayoutTests:

Tests to verify we force a layout of grid container or grid items, as appropriated,
whenever Box Alignment properties change their value.

This patch also adds some repaint tests, so we can ensure we generate the correct
repaint rects as well.

* fast/css-grid-layout/relayout-align-items-changed-expected.txt: Added.
* fast/css-grid-layout/relayout-align-items-changed.html: Added.
* fast/css-grid-layout/relayout-align-self-changed-expected.txt: Added.
* fast/css-grid-layout/relayout-align-self-changed.html: Added.
* fast/css-grid-layout/relayout-justify-items-changed-expected.txt: Added.
* fast/css-grid-layout/relayout-justify-items-changed.html: Added.
* fast/css-grid-layout/relayout-justify-self-changed-expected.txt: Added.
* fast/css-grid-layout/relayout-justify-self-changed.html: Added.
* fast/repaint/align-items-change-expected.txt: Added.
* fast/repaint/align-items-change.html: Added.
* fast/repaint/align-items-overflow-change-expected.txt: Added.
* fast/repaint/align-items-overflow-change.html: Added.
* fast/repaint/align-self-change-expected.txt: Added.
* fast/repaint/align-self-change.html: Added.
* fast/repaint/align-self-overflow-change-expected.txt: Added.
* fast/repaint/align-self-overflow-change.html: Added.
* fast/repaint/justify-items-change-expected.txt: Added.
* fast/repaint/justify-items-change.html: Added.
* fast/repaint/justify-items-legacy-change-expected.txt: Added.
* fast/repaint/justify-items-legacy-change.html: Added.
* fast/repaint/justify-items-overflow-change-expected.txt: Added.
* fast/repaint/justify-items-overflow-change.html: Added.
* fast/repaint/justify-self-change-expected.txt: Added.
* fast/repaint/justify-self-change.html: Added.
* fast/repaint/justify-self-overflow-change-expected.txt: Added.
* fast/repaint/justify-self-overflow-change.html: Added.

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

32 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/css-grid-layout/relayout-align-items-changed-expected.txt [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/relayout-align-items-changed.html [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/relayout-align-self-changed-expected.txt [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/relayout-align-self-changed.html [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/relayout-justify-items-changed-expected.txt [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/relayout-justify-items-changed.html [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/relayout-justify-self-changed-expected.txt [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/relayout-justify-self-changed.html [new file with mode: 0644]
LayoutTests/fast/repaint/align-items-change-expected.txt [new file with mode: 0644]
LayoutTests/fast/repaint/align-items-change.html [new file with mode: 0644]
LayoutTests/fast/repaint/align-items-overflow-change-expected.txt [new file with mode: 0644]
LayoutTests/fast/repaint/align-items-overflow-change.html [new file with mode: 0644]
LayoutTests/fast/repaint/align-self-change-expected.txt [new file with mode: 0644]
LayoutTests/fast/repaint/align-self-change.html [new file with mode: 0644]
LayoutTests/fast/repaint/align-self-overflow-change-expected.txt [new file with mode: 0644]
LayoutTests/fast/repaint/align-self-overflow-change.html [new file with mode: 0644]
LayoutTests/fast/repaint/justify-items-change-expected.txt [new file with mode: 0644]
LayoutTests/fast/repaint/justify-items-change.html [new file with mode: 0644]
LayoutTests/fast/repaint/justify-items-legacy-change-expected.txt [new file with mode: 0644]
LayoutTests/fast/repaint/justify-items-legacy-change.html [new file with mode: 0644]
LayoutTests/fast/repaint/justify-items-overflow-change-expected.txt [new file with mode: 0644]
LayoutTests/fast/repaint/justify-items-overflow-change.html [new file with mode: 0644]
LayoutTests/fast/repaint/justify-self-change-expected.txt [new file with mode: 0644]
LayoutTests/fast/repaint/justify-self-change.html [new file with mode: 0644]
LayoutTests/fast/repaint/justify-self-overflow-change-expected.txt [new file with mode: 0644]
LayoutTests/fast/repaint/justify-self-overflow-change.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderGrid.cpp
Source/WebCore/rendering/RenderGrid.h
Source/WebCore/rendering/style/RenderStyle.cpp
Source/WebCore/style/StyleResolveTree.cpp

index fbed258..eb1dd45 100644 (file)
@@ -1,3 +1,43 @@
+2015-09-17  Javier Fernandez  <jfernandez@igalia.com>
+
+        [CSS Grid Layout] Relayout whenever Box Alignment properties change
+        https://bugs.webkit.org/show_bug.cgi?id=148070
+
+        Reviewed by Darin Adler.
+
+        Tests to verify we force a layout of grid container or grid items, as appropriated,
+        whenever Box Alignment properties change their value.
+
+        This patch also adds some repaint tests, so we can ensure we generate the correct
+        repaint rects as well.
+
+        * fast/css-grid-layout/relayout-align-items-changed-expected.txt: Added.
+        * fast/css-grid-layout/relayout-align-items-changed.html: Added.
+        * fast/css-grid-layout/relayout-align-self-changed-expected.txt: Added.
+        * fast/css-grid-layout/relayout-align-self-changed.html: Added.
+        * fast/css-grid-layout/relayout-justify-items-changed-expected.txt: Added.
+        * fast/css-grid-layout/relayout-justify-items-changed.html: Added.
+        * fast/css-grid-layout/relayout-justify-self-changed-expected.txt: Added.
+        * fast/css-grid-layout/relayout-justify-self-changed.html: Added.
+        * fast/repaint/align-items-change-expected.txt: Added.
+        * fast/repaint/align-items-change.html: Added.
+        * fast/repaint/align-items-overflow-change-expected.txt: Added.
+        * fast/repaint/align-items-overflow-change.html: Added.
+        * fast/repaint/align-self-change-expected.txt: Added.
+        * fast/repaint/align-self-change.html: Added.
+        * fast/repaint/align-self-overflow-change-expected.txt: Added.
+        * fast/repaint/align-self-overflow-change.html: Added.
+        * fast/repaint/justify-items-change-expected.txt: Added.
+        * fast/repaint/justify-items-change.html: Added.
+        * fast/repaint/justify-items-legacy-change-expected.txt: Added.
+        * fast/repaint/justify-items-legacy-change.html: Added.
+        * fast/repaint/justify-items-overflow-change-expected.txt: Added.
+        * fast/repaint/justify-items-overflow-change.html: Added.
+        * fast/repaint/justify-self-change-expected.txt: Added.
+        * fast/repaint/justify-self-change.html: Added.
+        * fast/repaint/justify-self-overflow-change-expected.txt: Added.
+        * fast/repaint/justify-self-overflow-change.html: Added.
+
 2015-09-16  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         printing does not use minimum page zoom factor
diff --git a/LayoutTests/fast/css-grid-layout/relayout-align-items-changed-expected.txt b/LayoutTests/fast/css-grid-layout/relayout-align-items-changed-expected.txt
new file mode 100644 (file)
index 0000000..6ca05ed
--- /dev/null
@@ -0,0 +1,8 @@
+Tests how a align-items style change requires a relayout of the grid and previously stretched items.
+
+The grid bellow had initially 'align-items: end' and was changed to 'stretch'.
+
+PASS
+The grid bellow was initially stretched and it has now 'align-items: center'.
+
+PASS
diff --git a/LayoutTests/fast/css-grid-layout/relayout-align-items-changed.html b/LayoutTests/fast/css-grid-layout/relayout-align-items-changed.html
new file mode 100644 (file)
index 0000000..de9ab53
--- /dev/null
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<link href="resources/grid.css" rel="stylesheet">
+<style>
+.grid {
+  -webkit-grid: 100px 100px / 150px;
+  position: relative;
+}
+#fromStretch { align-items: stretch; }
+#toStretch { align-items: end; }
+</style>
+<script src="../../resources/check-layout.js"></script>
+<p>Tests how a align-items style change requires a relayout of the grid and previously stretched items.</p>
+<p>The grid bellow had initially 'align-items: end' and was changed to 'stretch'.</p>
+<div id="toStretch" class="grid">
+    <div style="width: 50px;" class="firstRowFirstColumn" data-expected-height="150" data-offset-y="0">
+        <div style="height: 50px"></div>
+    </div>
+    <div style="width: 50px;" class="firstRowSecondColumn" data-expected-height="150" data-offset-y="0">
+        <div style="height: 100px"></div>
+    </div>
+</div>
+<p>The grid bellow was initially stretched and it has now 'align-items: center'.</p>
+<div id="fromStretch" class="grid">
+    <div style="width: 50px;" class="firstRowFirstColumn" data-expected-height="50" data-offset-y="50">
+        <div style="height: 50px"></div>
+    </div>
+    <div style="width: 50px;" class="firstRowSecondColumn" data-expected-height="100" data-offset-y="25">
+        <div style="height: 100px"></div>
+    </div>
+</div>
+<script>
+document.body.offsetLeft;
+document.getElementById("toStretch").style.alignItems = "stretch";
+document.getElementById("fromStretch").style.alignItems = "center";
+checkLayout(".grid");
+</script>
diff --git a/LayoutTests/fast/css-grid-layout/relayout-align-self-changed-expected.txt b/LayoutTests/fast/css-grid-layout/relayout-align-self-changed-expected.txt
new file mode 100644 (file)
index 0000000..a28b8e2
--- /dev/null
@@ -0,0 +1,8 @@
+Tests how a align-self style change requires a relayout of the grid and previously stretched items.
+
+The grid bellow had initially 'align-self: end' and was changed to 'stretch'.
+
+PASS
+The grid bellow was initially stretched and it has now 'align-self: center'.
+
+PASS
diff --git a/LayoutTests/fast/css-grid-layout/relayout-align-self-changed.html b/LayoutTests/fast/css-grid-layout/relayout-align-self-changed.html
new file mode 100644 (file)
index 0000000..571061e
--- /dev/null
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<link href="resources/grid.css" rel="stylesheet">
+<style>
+.grid {
+  -webkit-grid: 100px 100px / 150px;
+  width: 200px;
+  position: relative;
+}
+.toStretch { align-self: end; }
+.fromStretch { align-self: stretch; }
+</style>
+<script src="../../resources/check-layout.js"></script>
+<p>Tests how a align-self style change requires a relayout of the grid and previously stretched items.</p>
+<p>The grid bellow had initially 'align-self: end' and was changed to 'stretch'.</p>
+<div class="grid">
+    <div style="width: 50px;" class="toStretch firstRowFirstColumn" data-expected-height="150" data-offset-y="0">
+        <div style="height: 50px"></div>
+    </div>
+    <div style="width: 50px;" class="toStretch firstRowSecondColumn" data-expected-height="150" data-offset-y="0">
+        <div style="height: 100px"></div>
+    </div>
+</div>
+<p>The grid bellow was initially stretched and it has now 'align-self: center'.</p>
+<div class="grid">
+    <div style="width: 50px;" class="fromStretch firstRowFirstColumn" data-expected-height="50" data-offset-y="50">
+        <div style="height: 50px"></div>
+    </div>
+    <div style="width: 50px;" class="fromStretch firstRowSecondColumn" data-expected-height="100" data-offset-y="25">
+        <div style="height: 100px"></div>
+    </div>
+</div>
+<script>
+document.body.offsetLeft;
+document.getElementsByClassName('toStretch')[0].style.alignSelf = 'stretch';
+document.getElementsByClassName('toStretch')[1].style.alignSelf = 'stretch';
+document.getElementsByClassName('fromStretch')[0].style.alignSelf = 'center';
+document.getElementsByClassName('fromStretch')[1].style.alignSelf = 'center';
+checkLayout(".grid");
+</script>
diff --git a/LayoutTests/fast/css-grid-layout/relayout-justify-items-changed-expected.txt b/LayoutTests/fast/css-grid-layout/relayout-justify-items-changed-expected.txt
new file mode 100644 (file)
index 0000000..40a0e2e
--- /dev/null
@@ -0,0 +1,8 @@
+Tests how a justify-items style change requires a relayout of the grid and previously stretched items.
+
+The grid bellow had initially 'justify-items: end' and was changed to 'stretch'.
+
+PASS
+The grid bellow was initially stretched and it has now 'justify-items: center'.
+
+PASS
diff --git a/LayoutTests/fast/css-grid-layout/relayout-justify-items-changed.html b/LayoutTests/fast/css-grid-layout/relayout-justify-items-changed.html
new file mode 100644 (file)
index 0000000..9832884
--- /dev/null
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<link href="resources/grid.css" rel="stylesheet">
+<style>
+.grid {
+  -webkit-grid: 150px / 100px 100px;
+  width: 150px;
+  position: relative;
+}
+#fromStretch { justify-items: stretch; }
+#toStretch { justify-items: end; }
+</style>
+<script src="../../resources/check-layout.js"></script>
+<p>Tests how a justify-items style change requires a relayout of the grid and previously stretched items.</p>
+<p>The grid bellow had initially 'justify-items: end' and was changed to 'stretch'.</p>
+<div id="toStretch" class="grid">
+    <div style="height: 50px;" class="firstRowFirstColumn" data-expected-width="150" data-offset-x="0">
+        <div style="width: 50px;"></div>
+    </div>
+    <div style="height: 50px;" class="secondRowFirstColumn" data-expected-width="150" data-offset-x="0">
+        <div style="width: 100px;"></div>
+    </div>
+</div>
+<p>The grid bellow was initially stretched and it has now 'justify-items: center'.</p>
+<div id="fromStretch" class="grid">
+    <div style="height: 50px;" class="firstRowFirstColumn" data-expected-width="50" data-offset-x="50">
+        <div style="width: 50px;"></div>
+    </div>
+    <div style="height: 50px;" class="secondRowFirstColumn" data-expected-width="100" data-offset-x="25">
+        <div style="width: 100px;"></div>
+    </div>
+</div>
+<script>
+document.body.offsetLeft;
+document.getElementById("toStretch").style.justifyItems = "stretch";
+document.getElementById("fromStretch").style.justifyItems = "center";
+checkLayout(".grid");
+</script>
diff --git a/LayoutTests/fast/css-grid-layout/relayout-justify-self-changed-expected.txt b/LayoutTests/fast/css-grid-layout/relayout-justify-self-changed-expected.txt
new file mode 100644 (file)
index 0000000..549130b
--- /dev/null
@@ -0,0 +1,8 @@
+Tests how a justify-self style change requires a relayout of the grid and previously stretched items.
+
+The grid bellow had initially 'justify-self: end' and was changed to 'stretch'.
+
+PASS
+The grid bellow was initially stretched and it has now 'justify-self: center'.
+
+PASS
diff --git a/LayoutTests/fast/css-grid-layout/relayout-justify-self-changed.html b/LayoutTests/fast/css-grid-layout/relayout-justify-self-changed.html
new file mode 100644 (file)
index 0000000..8920c18
--- /dev/null
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<link href="resources/grid.css" rel="stylesheet">
+<style>
+.grid {
+  -webkit-grid: 150px / 100px 100px;
+  width: 150px;
+  position: relative;
+}
+.fromStretch { justify-self: stretch; }
+.toStretch { justify-self: end; }
+</style>
+<script src="../../resources/check-layout.js"></script>
+<p>Tests how a justify-self style change requires a relayout of the grid and previously stretched items.</p>
+<p>The grid bellow had initially 'justify-self: end' and was changed to 'stretch'.</p>
+<div class="grid">
+    <div style="height: 50px;" class="toStretch firstRowFirstColumn" data-expected-width="150" data-offset-x="0">
+        <div style="width: 50px;"></div>
+    </div>
+    <div style="height: 50px;" class="toStretch secondRowFirstColumn" data-expected-width="150" data-offset-x="0">
+        <div style="width: 100px;"></div>
+    </div>
+</div>
+<p>The grid bellow was initially stretched and it has now 'justify-self: center'.</p>
+<div class="grid">
+    <div style="height: 50px;" class="fromStretch firstRowFirstColumn" data-expected-width="50" data-offset-x="50">
+        <div style="width: 50px;"></div>
+    </div>
+    <div style="height: 50px;" class="fromStretch secondRowFirstColumn" data-expected-width="100" data-offset-x="25">
+        <div style="width: 100px;"></div>
+    </div>
+</div>
+<script>
+document.body.offsetLeft;
+document.getElementsByClassName('toStretch')[0].style.justifySelf = 'stretch';
+document.getElementsByClassName('toStretch')[1].style.justifySelf = 'stretch';
+document.getElementsByClassName('fromStretch')[0].style.justifySelf = 'center';
+document.getElementsByClassName('fromStretch')[1].style.justifySelf = 'center';
+checkLayout(".grid");
+</script>
diff --git a/LayoutTests/fast/repaint/align-items-change-expected.txt b/LayoutTests/fast/repaint/align-items-change-expected.txt
new file mode 100644 (file)
index 0000000..750a424
--- /dev/null
@@ -0,0 +1,10 @@
+Tests invalidation on align-items style change. Passes if there is no red.
+
+(repaint rects
+  (rect 0 52 100 300)
+  (rect 0 51 100 1)
+  (rect 100 52 100 300)
+  (rect 100 51 100 1)
+  (rect 0 52 200 300)
+)
+
diff --git a/LayoutTests/fast/repaint/align-items-change.html b/LayoutTests/fast/repaint/align-items-change.html
new file mode 100644 (file)
index 0000000..0fffb18
--- /dev/null
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<script src="resources/text-based-repaint.js"></script>
+<script>
+function repaintTest() {
+  document.getElementById('container').style.alignItems = 'stretch';
+}
+onload = runRepaintTest;
+</script>
+<style>
+body {
+  margin: 0;
+}
+#container {
+  display: flex;
+  align-items: flex-start;
+  width: 200px;
+  height: 300px;
+  background-color: red;
+}
+.item {
+  background-color: green;
+  border: solid thin blue;
+  width: 100px;
+}
+</style>
+<p style="height: 20px">Tests invalidation on align-items style change. Passes if there is no red.</p>
+<div id="container">
+  <div class="item">
+    <div style="height: 100px"></div>
+  </div>
+  <div class="item">
+    <div style="height: 150px"></div>
+  </div>
+</div>
diff --git a/LayoutTests/fast/repaint/align-items-overflow-change-expected.txt b/LayoutTests/fast/repaint/align-items-overflow-change-expected.txt
new file mode 100644 (file)
index 0000000..d7a397c
--- /dev/null
@@ -0,0 +1,8 @@
+Tests invalidation on align-items style change (just overflow). Passes if there is no red.
+
+(repaint rects
+  (rect 0 2 200 350)
+  (rect 0 52 200 300)
+  (rect 0 2 800 14)
+)
+
diff --git a/LayoutTests/fast/repaint/align-items-overflow-change.html b/LayoutTests/fast/repaint/align-items-overflow-change.html
new file mode 100644 (file)
index 0000000..4947e02
--- /dev/null
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML>
+<script src="resources/text-based-repaint.js"></script>
+<script>
+function repaintTest() {
+  document.getElementById('container').style.alignItems = 'end safe';
+}
+onload = runRepaintTest;
+</script>
+<style>
+body {
+  margin: 0;
+}
+#container {
+  display: -webkit-grid;
+  -webkit-grid: 200px / 150px 150px;
+  align-items: end true;
+  width: 200px;
+  height: 300px;
+  background-color: red;
+}
+.item1 {
+  -webkit-grid-row: 1;
+  -webkit-grid-column: 1;
+  background-color: green;
+}
+.item2 {
+  -webkit-grid-row: 2;
+  -webkit-grid-column: 1;
+  background-color: green;
+}
+</style>
+<p style="height: 20px">Tests invalidation on align-items style change (just overflow). Passes if there is no red.</p>
+<div id="container">
+    <div class="item1">
+        <div style="height: 200px"></div>
+    </div>
+    <div class="item2">
+        <div style="height: 100px"></div>
+    </div>
+</div>
diff --git a/LayoutTests/fast/repaint/align-self-change-expected.txt b/LayoutTests/fast/repaint/align-self-change-expected.txt
new file mode 100644 (file)
index 0000000..edf5bde
--- /dev/null
@@ -0,0 +1,9 @@
+Tests invalidation on align-self style change. Passes if there is no red.
+
+(repaint rects
+  (rect 0 302 100 300)
+  (rect 0 302 100 50)
+  (rect 0 52 100 300)
+  (rect 100 52 100 300)
+)
+
diff --git a/LayoutTests/fast/repaint/align-self-change.html b/LayoutTests/fast/repaint/align-self-change.html
new file mode 100644 (file)
index 0000000..ba79f6d
--- /dev/null
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML>
+<script src="resources/text-based-repaint.js"></script>
+<script>
+function repaintTest() {
+  document.getElementsByClassName('item1')[0].style.alignSelf = 'stretch';
+  document.getElementsByClassName('item2')[0].style.alignSelf = 'stretch';
+}
+onload = runRepaintTest;
+</script>
+<style>
+body {
+  margin: 0;
+}
+#container {
+  display: -webkit-grid;
+  -webkit-grid: 100px 100px / 300px;
+  width: 200px;
+  height: 300px;
+  background-color: red;
+}
+.item1 {
+  -webkit-grid-row: 1;
+  -webkit-grid-column: 1;
+  align-self: end;
+  background-color: green;
+}
+.item2 {
+  -webkit-grid-row: 1;
+  -webkit-grid-column: 2;
+  align-self: start;
+  background-color: green;
+}
+</style>
+<p style="height: 20px">Tests invalidation on align-self style change. Passes if there is no red.</p>
+<div id="container">
+  <div class="item1">
+    <div style="height: 50px"></div>
+  </div>
+  <div class="item2">
+    <div style="height: 50px"></div>
+  </div>
+</div>
diff --git a/LayoutTests/fast/repaint/align-self-overflow-change-expected.txt b/LayoutTests/fast/repaint/align-self-overflow-change-expected.txt
new file mode 100644 (file)
index 0000000..7d6ddaa
--- /dev/null
@@ -0,0 +1,11 @@
+Tests invalidation on align-self style change (just overflow). Passes if there is no red.
+
+(repaint rects
+  (rect 0 2 200 200)
+  (rect 0 2 200 200)
+  (rect 0 52 200 200)
+  (rect 0 252 200 100)
+  (rect 0 2 200 50)
+  (rect 0 2 800 14)
+)
+
diff --git a/LayoutTests/fast/repaint/align-self-overflow-change.html b/LayoutTests/fast/repaint/align-self-overflow-change.html
new file mode 100644 (file)
index 0000000..331dbcb
--- /dev/null
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<script src="resources/text-based-repaint.js"></script>
+<script>
+function repaintTest() {
+  document.getElementsByClassName('item1')[0].style.alignSelf = 'end safe';
+  document.getElementsByClassName('item2')[0].style.alignSelf = 'end safe';
+}
+onload = runRepaintTest;
+</script>
+<style>
+body {
+  margin: 0;
+}
+#container {
+  display: -webkit-grid;
+  -webkit-grid: 200px / 150px 150px;
+  width: 200px;
+  height: 300px;
+  background-color: red;
+}
+.item1 {
+  -webkit-grid-row: 1;
+  -webkit-grid-column: 1;
+  align-self: end true;
+  background-color: green;
+}
+.item2 {
+  -webkit-grid-row: 2;
+  -webkit-grid-column: 1;
+  align-self: end true;
+  background-color: green;
+</style>
+<p style="height: 20px">Tests invalidation on align-self style change (just overflow). Passes if there is no red.</p>
+<div id="container">
+  <div class="item1">
+    <div style="height: 200px"></div>
+  </div>
+  <div class="item2">
+    <div style="height: 100px"></div>
+  </div>
+</div>
diff --git a/LayoutTests/fast/repaint/justify-items-change-expected.txt b/LayoutTests/fast/repaint/justify-items-change-expected.txt
new file mode 100644 (file)
index 0000000..418e417
--- /dev/null
@@ -0,0 +1,7 @@
+Tests invalidation on justify-items style change. Passes if there is no red.
+
+(repaint rects
+  (rect 200 52 150 300)
+  (rect 0 52 200 300)
+)
+
diff --git a/LayoutTests/fast/repaint/justify-items-change.html b/LayoutTests/fast/repaint/justify-items-change.html
new file mode 100644 (file)
index 0000000..6b1bff2
--- /dev/null
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<script src="resources/text-based-repaint.js"></script>
+<script>
+function repaintTest() {
+  document.getElementById('container').style.justifyItems = 'stretch';
+}
+onload = runRepaintTest;
+</script>
+<style>
+body {
+  margin: 0;
+}
+#container {
+  display: -webkit-grid;
+  -webkit-grid: 200px / 300px;
+  justify-items: end;
+  width: 200px;
+  height: 300px;
+  background-color: red;
+}
+.item {
+  -webkit-grid-row: 1;
+  -webkit-grid-column: 1;
+  background-color: green;
+}
+</style>
+<p style="height: 20px">Tests invalidation on justify-items style change. Passes if there is no red.</p>
+<div id="container">
+  <div class="item">
+    <div style="width: 50px; height: 50px"></div>
+  </div>
+</div>
diff --git a/LayoutTests/fast/repaint/justify-items-legacy-change-expected.txt b/LayoutTests/fast/repaint/justify-items-legacy-change-expected.txt
new file mode 100644 (file)
index 0000000..fa2b44f
--- /dev/null
@@ -0,0 +1,6 @@
+Tests invalidation on justify-items style change (legacy value). Passes if green bars are centerd inside their red container.
+
+(repaint rects
+  (rect 0 52 300 400)
+)
+
diff --git a/LayoutTests/fast/repaint/justify-items-legacy-change.html b/LayoutTests/fast/repaint/justify-items-legacy-change.html
new file mode 100644 (file)
index 0000000..0cb2c16
--- /dev/null
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML>
+<script src="resources/text-based-repaint.js"></script>
+<script>
+function repaintTest() {
+  document.getElementById('parentContainer').style.justifyItems = 'legacy center';
+}
+onload = runRepaintTest;
+</script>
+<style>
+body {
+  margin: 0;
+}
+#parentContainer {
+  justify-items: center;
+  background-color: orange;
+  width: 300px;
+  height: 400px;
+}
+
+#container {
+  display: -webkit-grid;
+  -webkit-grid: 100px 100px / 150px 150px;
+  width: 200px;
+  height: 300px;
+  background-color: red;
+}
+.item1 {
+  -webkit-grid-row: 1;
+  -webkit-grid-column: 1;
+  background-color: green;
+  border: solid thin blue;
+  width: 50px;
+}
+.item2 {
+  -webkit-grid-row: 1;
+  -webkit-grid-column: 2;
+  background-color: green;
+  border: solid thin blue;
+  width: 50px;
+</style>
+<p style="height: 20px">Tests invalidation on justify-items style change (legacy value). Passes if green bars are centerd inside their red container.</p>
+<div id="parentContainer">
+    <div id="container">
+        <div class="item1">
+            <div style="height: 50px"></div>
+        </div>
+        <div class="item2">
+            <div style="height: 50px"></div>
+        </div>
+    </div>
+</div>
diff --git a/LayoutTests/fast/repaint/justify-items-overflow-change-expected.txt b/LayoutTests/fast/repaint/justify-items-overflow-change-expected.txt
new file mode 100644 (file)
index 0000000..96654c6
--- /dev/null
@@ -0,0 +1,9 @@
+Tests invalidation on justify-items style change. Passes if there is no red.
+
+(repaint rects
+  (rect -60 52 260 300)
+  (rect 0 52 200 300)
+  (rect -60 16 60 336)
+  (rect -60 0 60 352)
+)
+
diff --git a/LayoutTests/fast/repaint/justify-items-overflow-change.html b/LayoutTests/fast/repaint/justify-items-overflow-change.html
new file mode 100644 (file)
index 0000000..7dabcea
--- /dev/null
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<script src="resources/text-based-repaint.js"></script>
+<script>
+function repaintTest() {
+  document.getElementById('container').style.justifyItems = 'end safe';
+}
+onload = runRepaintTest;
+</script>
+<style>
+body {
+  margin: 0;
+}
+#container {
+  display: -webkit-grid;
+  -webkit-grid: 100px 100px / 300px;
+  justify-items: end true;
+  width: 200px;
+  height: 300px;
+  background-color: red;
+}
+.item1 {
+  -webkit-grid-row: 1;
+  -webkit-grid-column: 1;
+  background-color: green;
+  width: 160px;
+}
+.item2 {
+  -webkit-grid-row: 1;
+  -webkit-grid-column: 2;
+  background-color: green;
+  width: 50px;
+</style>
+<p style="height: 20px">Tests invalidation on justify-items style change. Passes if there is no red.</p>
+<div id="container">
+  <div class="item1">
+    <div style="height: 50px"></div>
+  </div>
+  <div class="item2">
+    <div style="height: 50px"></div>
+  </div>
+</div>
diff --git a/LayoutTests/fast/repaint/justify-self-change-expected.txt b/LayoutTests/fast/repaint/justify-self-change-expected.txt
new file mode 100644 (file)
index 0000000..36df845
--- /dev/null
@@ -0,0 +1,13 @@
+Tests invalidation on justify-self style change. Passes if there is no red.
+
+(repaint rects
+  (rect 24 52 52 300)
+  (rect 24 52 100 300)
+  (rect 24 52 52 300)
+  (rect 0 52 100 300)
+  (rect 124 52 52 300)
+  (rect 124 52 100 300)
+  (rect 124 52 52 300)
+  (rect 100 52 100 300)
+)
+
diff --git a/LayoutTests/fast/repaint/justify-self-change.html b/LayoutTests/fast/repaint/justify-self-change.html
new file mode 100644 (file)
index 0000000..be1ab8d
--- /dev/null
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<script src="resources/text-based-repaint.js"></script>
+<script>
+function repaintTest() {
+  document.getElementsByClassName('item1')[0].style.justifySelf = 'stretch';
+  document.getElementsByClassName('item2')[0].style.justifySelf = 'stretch';
+}
+onload = runRepaintTest;
+</script>
+<style>
+body {
+  margin: 0;
+}
+#container {
+  display: -webkit-grid;
+  -webkit-grid: 100px 100px / 300px;
+  justify-items: center;
+  width: 200px;
+  background-color: red;
+}
+.item1 {
+  -webkit-grid-row: 1;
+  -webkit-grid-column: 1;
+  background-color: green;
+  border: solid thin blue;
+}
+.item2 {
+  -webkit-grid-row: 1;
+  -webkit-grid-column: 2;
+  background-color: green;
+  border: solid thin blue;
+</style>
+<p style="height: 20px">Tests invalidation on justify-self style change. Passes if there is no red.</p>
+<div id="container">
+  <div class="item1">
+    <div style="width: 50px; height: 150px"></div>
+  </div>
+  <div class="item2">
+    <div style="width: 50px; height: 100px"></div>
+  </div>
+</div>
diff --git a/LayoutTests/fast/repaint/justify-self-overflow-change-expected.txt b/LayoutTests/fast/repaint/justify-self-overflow-change-expected.txt
new file mode 100644 (file)
index 0000000..2833ed4
--- /dev/null
@@ -0,0 +1,12 @@
+Tests invalidation on justify-self style change. Passes if there is no red.
+
+(repaint rects
+  (rect -50 52 150 300)
+  (rect -50 52 150 300)
+  (rect 0 52 150 300)
+  (rect 150 52 50 300)
+  (rect -50 52 50 300)
+  (rect -50 16 50 336)
+  (rect -50 0 50 352)
+)
+
diff --git a/LayoutTests/fast/repaint/justify-self-overflow-change.html b/LayoutTests/fast/repaint/justify-self-overflow-change.html
new file mode 100644 (file)
index 0000000..c4792ea
--- /dev/null
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<script src="resources/text-based-repaint.js"></script>
+<script>
+function repaintTest() {
+  document.getElementsByClassName('item1')[0].style.justifySelf = 'end safe';
+  document.getElementsByClassName('item2')[0].style.justifySelf = 'end safe';
+}
+onload = runRepaintTest;
+</script>
+<style>
+body {
+  margin: 0;
+}
+#container {
+  display: -webkit-grid;
+  -webkit-grid: 100px 100px / 300px;
+  width: 200px;
+  height: 300px;
+  background-color: red;
+}
+.item1 {
+  -webkit-grid-row: 1;
+  -webkit-grid-column: 1;
+  justify-self: end true;
+  background-color: green;
+  width: 150px;
+}
+.item2 {
+  -webkit-grid-row: 1;
+  -webkit-grid-column: 2;
+  background-color: green;
+  justify-self: end true;
+  width: 50px;
+</style>
+<p style="height: 20px">Tests invalidation on justify-self style change. Passes if there is no red.</p>
+<div id="container">
+  <div class="item1">
+    <div style="height: 150px"></div>
+  </div>
+  <div class="item2">
+    <div style="height: 100px"></div>
+  </div>
+</div>
index 953e8a9..cb8b46b 100644 (file)
@@ -1,3 +1,45 @@
+2015-09-17  Javier Fernandez  <jfernandez@igalia.com>
+
+        [CSS Grid Layout] Relayout whenever Box Alignment properties change
+        https://bugs.webkit.org/show_bug.cgi?id=148070
+
+        Reviewed by Darin Adler.
+
+        We were Reattaching the styles to the RenderTree whenever Content Alignment
+        properties (align-items and justify-items) changed their values, since the
+        Self Alignment properties depend on such values to resolve 'auto' values
+        during layout.
+
+        This patch removes such restriction, since we resolve the auto values
+        whenever we access the alignment properties. The only thing we need to
+        do is to mark a grid item for layout whenever the Default Alignment
+        properties change from/to stretch, since it implies a resize of the grid
+        items using 'auto' values for the Self Alignment properties.
+
+        Tests: fast/css-grid-layout/relayout-align-items-changed.html
+               fast/css-grid-layout/relayout-align-self-changed.html
+               fast/css-grid-layout/relayout-justify-items-changed.html
+               fast/css-grid-layout/relayout-justify-self-changed.html
+               fast/repaint/align-items-change.html
+               fast/repaint/align-items-overflow-change.html
+               fast/repaint/align-self-change.html
+               fast/repaint/align-self-overflow-change.html
+               fast/repaint/justify-items-change.html
+               fast/repaint/justify-items-legacy-change.html
+               fast/repaint/justify-items-overflow-change.html
+               fast/repaint/justify-self-change.html
+               fast/repaint/justify-self-overflow-change.html
+
+        * rendering/RenderGrid.cpp:
+        (WebCore::defaultAlignmentIsStretch):
+        (WebCore::RenderGrid::styleDidChange):
+        * rendering/RenderGrid.h:
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::resolveAlignmentOverflow):
+        (WebCore::RenderStyle::changeRequiresLayout):
+        * style/StyleResolveTree.cpp:
+        (WebCore::Style::determineChange): Deleted.
+
 2015-09-16  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         printing does not use minimum page zoom factor
index 9a82464..ebe3c6a 100644 (file)
@@ -242,6 +242,53 @@ RenderGrid::~RenderGrid()
 {
 }
 
+static inline bool defaultAlignmentIsStretch(ItemPosition position)
+{
+    return position == ItemPositionStretch || position == ItemPositionAuto;
+}
+
+static inline bool defaultAlignmentChangedToStretchInRowAxis(const RenderStyle& oldStyle, const RenderStyle& newStyle)
+{
+    return !defaultAlignmentIsStretch(oldStyle.justifyItemsPosition()) && defaultAlignmentIsStretch(newStyle.justifyItemsPosition());
+}
+
+static inline bool defaultAlignmentChangedFromStretchInColumnAxis(const RenderStyle& oldStyle, const RenderStyle& newStyle)
+{
+    return defaultAlignmentIsStretch(oldStyle.alignItemsPosition()) && !defaultAlignmentIsStretch(newStyle.alignItemsPosition());
+}
+
+static inline bool selfAlignmentChangedToStretchInRowAxis(const RenderStyle& oldStyle, const RenderStyle& newStyle, const RenderStyle& childStyle)
+{
+    return RenderStyle::resolveJustification(oldStyle, childStyle, ItemPositionStretch) != ItemPositionStretch
+        && RenderStyle::resolveJustification(newStyle, childStyle, ItemPositionStretch) == ItemPositionStretch;
+}
+
+static inline bool selfAlignmentChangedFromStretchInColumnAxis(const RenderStyle& oldStyle, const RenderStyle& newStyle, const RenderStyle& childStyle)
+{
+    return RenderStyle::resolveAlignment(oldStyle, childStyle, ItemPositionStretch) == ItemPositionStretch
+        && RenderStyle::resolveAlignment(newStyle, childStyle, ItemPositionStretch) != ItemPositionStretch;
+}
+
+void RenderGrid::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+    RenderBlock::styleDidChange(diff, oldStyle);
+    if (!oldStyle || diff != StyleDifferenceLayout)
+        return;
+
+    const RenderStyle& newStyle = style();
+    if (defaultAlignmentChangedToStretchInRowAxis(*oldStyle, newStyle) || defaultAlignmentChangedFromStretchInColumnAxis(*oldStyle, newStyle)) {
+        // Grid items that were not previously stretched in row-axis need to be relayed out so we can compute new available space.
+        // Grid items that were previously stretching in column-axis need to be relayed out so we can compute new available space.
+        // This is only necessary for stretching since other alignment values don't change the size of the box.
+        for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
+            if (child->isOutOfFlowPositioned())
+                continue;
+            if (selfAlignmentChangedToStretchInRowAxis(*oldStyle, newStyle, child->style()) || selfAlignmentChangedFromStretchInColumnAxis(*oldStyle, newStyle, child->style()))
+                child->setChildNeedsLayout(MarkOnlyThis);
+        }
+    }
+}
+
 void RenderGrid::layoutBlock(bool relayoutChildren, LayoutUnit)
 {
     ASSERT(needsLayout());
index 2b405b5..99206c7 100644 (file)
@@ -49,6 +49,7 @@ public:
 
     Element& element() const { return downcast<Element>(nodeForNonAnonymous()); }
 
+    virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;
     virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) override;
 
     virtual bool avoidsFloats() const override { return true; }
index dc7189b..c9fe3bc 100644 (file)
@@ -196,7 +196,7 @@ ItemPosition RenderStyle::resolveAlignment(const RenderStyle& parentStyle, const
 
 OverflowAlignment RenderStyle::resolveAlignmentOverflow(const RenderStyle& parentStyle, const RenderStyle& childStyle)
 {
-    return resolveJustificationData(parentStyle, childStyle, ItemPositionStretch).overflow();
+    return resolveAlignmentData(parentStyle, childStyle, ItemPositionStretch).overflow();
 }
 
 ItemPosition RenderStyle::resolveJustification(const RenderStyle& parentStyle, const RenderStyle& childStyle, ItemPosition resolvedAutoPositionForRenderer)
@@ -524,7 +524,9 @@ bool RenderStyle::changeRequiresLayout(const RenderStyle& other, unsigned& chang
             || rareNonInheritedData->m_alignContent != other.rareNonInheritedData->m_alignContent
             || rareNonInheritedData->m_alignItems != other.rareNonInheritedData->m_alignItems
             || rareNonInheritedData->m_alignSelf != other.rareNonInheritedData->m_alignSelf
-            || rareNonInheritedData->m_justifyContent != other.rareNonInheritedData->m_justifyContent)
+            || rareNonInheritedData->m_justifyContent != other.rareNonInheritedData->m_justifyContent
+            || rareNonInheritedData->m_justifyItems != other.rareNonInheritedData->m_justifyItems
+            || rareNonInheritedData->m_justifySelf != other.rareNonInheritedData->m_justifySelf)
             return true;
 
         if (!rareNonInheritedData->reflectionDataEquivalent(*other.rareNonInheritedData.get()))
index 453a7b5..39b6d29 100644 (file)
@@ -97,8 +97,6 @@ Change determineChange(const RenderStyle& s1, const RenderStyle& s2)
     // a separate render region object.
     if (s1.hasFlowFrom() && (s1.specifiesColumns() != s2.specifiesColumns()))
         return Detach;
-    if (s1.alignItems() != s2.alignItems())
-        return Detach;
 
     if (s1 != s2) {
         if (s1.inheritedNotEqual(&s2))