Patch by Julien Chaffraix <jchaffraix@webkit.org> on 2011-07-07
Reviewed by David Hyatt.

Partial layout when a flex-box has visibility: collapse
https://bugs.webkit.org/show_bug.cgi?id=63776

Source/WebCore:

Tests: fast/flexbox/crash-button-input-autofocus.html
       fast/flexbox/crash-button-keygen.html
       fast/flexbox/crash-button-relayout.html

The issue is that FlexBoxIterator would skip any child if it has visibility: collapsed.
However if one of the child is anonymous, it may wrap some other child that would be skipped.
Now FlexBoxIterator is called during the layout phase and thus some nodes would not relayouted
as expected.

* rendering/RenderDeprecatedFlexibleBox.cpp:
(WebCore::FlexBoxIterator::next): When iterating, don't skip anonymous content as there may
be real content hiding below.

LayoutTests:

Those tests checks some variation of the same underlying issue.

* fast/flexbox/crash-button-input-autofocus-expected.txt: Added.
* fast/flexbox/crash-button-input-autofocus.html: Added.
* fast/flexbox/crash-button-keygen-expected.txt: Added.
* fast/flexbox/crash-button-keygen.html: Added.
* fast/flexbox/crash-button-relayout-expected.txt: Added.
* fast/flexbox/crash-button-relayout.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@90568 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 7843ab1..f3e401a 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,19 @@
+2011-07-07  Julien Chaffraix  <jchaffraix@webkit.org>
+
+        Reviewed by David Hyatt.
+
+        Partial layout when a flex-box has visibility: collapse
+        https://bugs.webkit.org/show_bug.cgi?id=63776
+
+        Those tests checks some variation of the same underlying issue.
+
+        * fast/flexbox/crash-button-input-autofocus-expected.txt: Added.
+        * fast/flexbox/crash-button-input-autofocus.html: Added.
+        * fast/flexbox/crash-button-keygen-expected.txt: Added.
+        * fast/flexbox/crash-button-keygen.html: Added.
+        * fast/flexbox/crash-button-relayout-expected.txt: Added.
+        * fast/flexbox/crash-button-relayout.html: Added.
+
 2011-07-07  Vsevolod Vlasov  <vsevik@chromium.org>
 
         Web Inspector: URL links in styles open new tab instead of showing resources panel.
diff --git a/LayoutTests/fast/flexbox/crash-button-input-autofocus-expected.txt b/LayoutTests/fast/flexbox/crash-button-input-autofocus-expected.txt
new file mode 100644
index 0000000..2276350
--- /dev/null
+++ b/LayoutTests/fast/flexbox/crash-button-input-autofocus-expected.txt
@@ -0,0 +1,3 @@
+Test for bug 63776: Partial layout when a flex-box has visibility: collapse
+
+This test PASSES if it does not CRASH.
diff --git a/LayoutTests/fast/flexbox/crash-button-input-autofocus.html b/LayoutTests/fast/flexbox/crash-button-input-autofocus.html
new file mode 100755
index 0000000..4763ff3
--- /dev/null
+++ b/LayoutTests/fast/flexbox/crash-button-input-autofocus.html
@@ -0,0 +1,14 @@
+<html>
+<body>
+<p style="visibility: collapse;"><button><input autofocus><input id="test"></input></button></p>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+document.body.offsetTop;
+document.getElementById('test').parentNode.removeChild(document.getElementById('test'));
+document.body.offsetTop;
+</script>
+<p>Test for bug <a href="https://bugs.webkit.org/show_bug.cgi?id=63776">63776</a>: Partial layout when a flex-box has visibility: collapse</p>
+<p>This test PASSES if it does not CRASH.</p>
+</body>
+</html>
diff --git a/LayoutTests/fast/flexbox/crash-button-keygen-expected.txt b/LayoutTests/fast/flexbox/crash-button-keygen-expected.txt
new file mode 100644
index 0000000..2276350
--- /dev/null
+++ b/LayoutTests/fast/flexbox/crash-button-keygen-expected.txt
@@ -0,0 +1,3 @@
+Test for bug 63776: Partial layout when a flex-box has visibility: collapse
+
+This test PASSES if it does not CRASH.
diff --git a/LayoutTests/fast/flexbox/crash-button-keygen.html b/LayoutTests/fast/flexbox/crash-button-keygen.html
new file mode 100755
index 0000000..7cf441e
--- /dev/null
+++ b/LayoutTests/fast/flexbox/crash-button-keygen.html
@@ -0,0 +1,14 @@
+<html>
+<body>
+<p style="visibility: collapse;"><button><keygen autofocus><input id="test"></keygen></button></p>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+document.body.offsetTop;
+document.getElementById('test').parentNode.removeChild(document.getElementById('test'));
+document.body.offsetTop;
+</script>
+<p>Test for bug <a href="https://bugs.webkit.org/show_bug.cgi?id=63776">63776</a>: Partial layout when a flex-box has visibility: collapse</p>
+<p>This test PASSES if it does not CRASH.</p>
+</body>
+</html>
diff --git a/LayoutTests/fast/flexbox/crash-button-relayout-expected.txt b/LayoutTests/fast/flexbox/crash-button-relayout-expected.txt
new file mode 100644
index 0000000..2276350
--- /dev/null
+++ b/LayoutTests/fast/flexbox/crash-button-relayout-expected.txt
@@ -0,0 +1,3 @@
+Test for bug 63776: Partial layout when a flex-box has visibility: collapse
+
+This test PASSES if it does not CRASH.
diff --git a/LayoutTests/fast/flexbox/crash-button-relayout.html b/LayoutTests/fast/flexbox/crash-button-relayout.html
new file mode 100755
index 0000000..49a6d2a
--- /dev/null
+++ b/LayoutTests/fast/flexbox/crash-button-relayout.html
@@ -0,0 +1,14 @@
+<html>
+<body>
+<p style="visibility: collapse;"><button><input><script>document.getElementsByTagName('input')[0].offsetTop;</script><input id="test"></input></button></p>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+document.body.offsetTop;
+document.getElementById('test').parentNode.removeChild(document.getElementById('test'));
+document.body.offsetTop;
+</script>
+<p>Test for bug <a href="https://bugs.webkit.org/show_bug.cgi?id=63776">63776</a>: Partial layout when a flex-box has visibility: collapse</p>
+<p>This test PASSES if it does not CRASH.</p>
+</body>
+</html>
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index cf07355..76a41fc 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,23 @@
+2011-07-07  Julien Chaffraix  <jchaffraix@webkit.org>
+
+        Reviewed by David Hyatt.
+
+        Partial layout when a flex-box has visibility: collapse
+        https://bugs.webkit.org/show_bug.cgi?id=63776
+
+        Tests: fast/flexbox/crash-button-input-autofocus.html
+               fast/flexbox/crash-button-keygen.html
+               fast/flexbox/crash-button-relayout.html
+
+        The issue is that FlexBoxIterator would skip any child if it has visibility: collapsed.
+        However if one of the child is anonymous, it may wrap some other child that would be skipped.
+        Now FlexBoxIterator is called during the layout phase and thus some nodes would not relayouted
+        as expected.
+
+        * rendering/RenderDeprecatedFlexibleBox.cpp:
+        (WebCore::FlexBoxIterator::next): When iterating, don't skip anonymous content as there may
+        be real content hiding below.
+
 2011-07-07  Vsevolod Vlasov  <vsevik@chromium.org>
 
         Web Inspector: URL links in styles open new tab instead of showing resources panel.
diff --git a/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp b/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp
index 00a2cab..473a665 100644
--- a/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp
+++ b/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp
@@ -89,8 +89,8 @@
                 m_currentChild = m_forward ? m_currentChild->nextSiblingBox() : m_currentChild->previousSiblingBox();
             if (m_currentChild && m_currentChild->style()->boxOrdinalGroup() > m_lastOrdinal)
                 m_lastOrdinal = m_currentChild->style()->boxOrdinalGroup();
-        } while (!m_currentChild || m_currentChild->style()->boxOrdinalGroup() != m_currentOrdinal
-                 || m_currentChild->style()->visibility() == COLLAPSE);
+        } while (!m_currentChild || (!m_currentChild->isAnonymous()
+                 && (m_currentChild->style()->boxOrdinalGroup() != m_currentOrdinal || m_currentChild->style()->visibility() == COLLAPSE)));
         return m_currentChild;
     }