Title: [122747] trunk
Revision
122747
Author
t...@chromium.org
Date
2012-07-16 12:09:57 -0700 (Mon, 16 Jul 2012)

Log Message

Position grid items by row/column index
https://bugs.webkit.org/show_bug.cgi?id=91293

Reviewed by Ojan Vafai.

Source/WebCore:

Do some initial grid positioning. Only handle the simple case where tracks are
fixed values and don't properly size the grid items. This gives us something to
work with and starts implementing the "Grid Track Sizing Algorithm":
http://dev.w3.org/csswg/css3-grid-layout/#grid-track-sizing-algorithm0

Test: fast/css-grid-layout/place-cell-by-index.html

* rendering/RenderGrid.cpp:
(RenderGrid::GridTrack): Data structure for holding the track size. UsedBreadth matches the terminology
used in the spec.
(WebCore::RenderGrid::layoutBlock): Pull in some boiler plate code and put the
grid specific code in layoutGridItems.
(WebCore::RenderGrid::computedUsedBreadthOfGridTracks): Implement part of the grid track sizing algorithm.
(WebCore::RenderGrid::layoutGridItems): Compute the size of grid tracks, layout and position children.
(WebCore::RenderGrid::findChildLogicalPosition): Map track sizes to the actual position of the child.
* rendering/RenderGrid.h:
* rendering/style/RenderStyle.h: Just return a copy of Length rather than a reference to Length. This seems
more consistent with other getters that return a Length.

LayoutTests:

Add a test for grid layout in each writing mode direction.  The height in vertical writing mode is incorrect for now.

* fast/css-grid-layout/containing-block-grids-expected.html: Scope <p> around text only.
* fast/css-grid-layout/containing-block-grids.html: Fix missing closing </div>.
* fast/css-grid-layout/place-cell-by-index-expected.txt: Added.
* fast/css-grid-layout/place-cell-by-index.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (122746 => 122747)


--- trunk/LayoutTests/ChangeLog	2012-07-16 19:06:00 UTC (rev 122746)
+++ trunk/LayoutTests/ChangeLog	2012-07-16 19:09:57 UTC (rev 122747)
@@ -1,3 +1,17 @@
+2012-07-16  Tony Chang  <t...@chromium.org>
+
+        Position grid items by row/column index
+        https://bugs.webkit.org/show_bug.cgi?id=91293
+
+        Reviewed by Ojan Vafai.
+
+        Add a test for grid layout in each writing mode direction.  The height in vertical writing mode is incorrect for now.
+
+        * fast/css-grid-layout/containing-block-grids-expected.html: Scope <p> around text only.
+        * fast/css-grid-layout/containing-block-grids.html: Fix missing closing </div>.
+        * fast/css-grid-layout/place-cell-by-index-expected.txt: Added.
+        * fast/css-grid-layout/place-cell-by-index.html: Added.
+
 2012-07-16  Mike West  <mk...@chromium.org>
 
         Invalid `script-nonce` directives should block script execution.

Modified: trunk/LayoutTests/fast/css-grid-layout/containing-block-grids-expected.html (122746 => 122747)


--- trunk/LayoutTests/fast/css-grid-layout/containing-block-grids-expected.html	2012-07-16 19:06:00 UTC (rev 122746)
+++ trunk/LayoutTests/fast/css-grid-layout/containing-block-grids-expected.html	2012-07-16 19:09:57 UTC (rev 122747)
@@ -6,8 +6,7 @@
     </style>
 </head>
 <body>
-<p>Grids can act as containing blocks for positioned content.
+<p>Grids can act as containing blocks for positioned content.</p>
 <div style="width: 100px; height: 200px; background-color: green;"></div>
-</p>
 </body>
 </html>

Modified: trunk/LayoutTests/fast/css-grid-layout/containing-block-grids.html (122746 => 122747)


--- trunk/LayoutTests/fast/css-grid-layout/containing-block-grids.html	2012-07-16 19:06:00 UTC (rev 122746)
+++ trunk/LayoutTests/fast/css-grid-layout/containing-block-grids.html	2012-07-16 19:09:57 UTC (rev 122747)
@@ -12,9 +12,8 @@
     </style>
 </head>
 <body>
-<p>Grids can act as containing blocks for positioned content.
-<div class="relative-positioned-grid" style="display: -webkit-grid"><div style="background-color: green; left: 0; top: 0"></div>
-<div class="relative-positioned-inline-grid" style="display: -webkit-inline-grid"><div style="background-color:green; left: 0; top: 0"></div>
-</p>
+<p>Grids can act as containing blocks for positioned content.</p>
+<div class="relative-positioned-grid" style="display: -webkit-grid"><div style="background-color: green; left: 0; top: 0"></div></div>
+<div class="relative-positioned-inline-grid" style="display: -webkit-inline-grid"><div style="background-color:green; left: 0; top: 0"></div></div>
 </body>
 </html>

Added: trunk/LayoutTests/fast/css-grid-layout/place-cell-by-index-expected.txt (0 => 122747)


--- trunk/LayoutTests/fast/css-grid-layout/place-cell-by-index-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css-grid-layout/place-cell-by-index-expected.txt	2012-07-16 19:09:57 UTC (rev 122747)
@@ -0,0 +1,22 @@
+Test some simple grid layouts by positioning grid items by index.
+
+PASS
+PASS
+FAIL:
+Expected 110 for height, but got 15. 
+
+<div class="grid" style="-webkit-writing-mode: vertical-rl; margin-bottom: 60px;" data-expected-width="50" data-expected-height="110">
+    <div id="a" data-offset-x="40" data-offset-y="0"></div>
+    <div id="b" data-offset-x="40" data-offset-y="50"></div>
+    <div id="c" data-offset-x="20" data-offset-y="0"></div>
+    <div id="d" data-offset-x="20" data-offset-y="50"></div>
+</div>
+FAIL:
+Expected 110 for height, but got 15. 
+
+<div class="grid" style="-webkit-writing-mode: vertical-lr; margin-bottom: 60px;" data-expected-width="50" data-expected-height="110">
+    <div id="a" data-offset-x="0" data-offset-y="0"></div>
+    <div id="b" data-offset-x="0" data-offset-y="50"></div>
+    <div id="c" data-offset-x="20" data-offset-y="0"></div>
+    <div id="d" data-offset-x="20" data-offset-y="50"></div>
+</div>

Added: trunk/LayoutTests/fast/css-grid-layout/place-cell-by-index.html (0 => 122747)


--- trunk/LayoutTests/fast/css-grid-layout/place-cell-by-index.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css-grid-layout/place-cell-by-index.html	2012-07-16 19:09:57 UTC (rev 122747)
@@ -0,0 +1,91 @@
+<!DOCTYPE html>
+<html>
+<script>
+if (window.testRunner) {
+    testRunner.overridePreference("WebKitCSSGridLayoutEnabled", 1);
+    testRunner.dumpAsText();
+}
+</script>
+<style>
+.grid {
+    display: -webkit-grid;
+    -webkit-grid-columns: 50px 60px;
+    -webkit-grid-rows: 20px 30px;
+    background-color: grey;
+    max-width: 110px;
+}
+
+#a {
+    background-color: blue;
+    -webkit-grid-column: 1;
+    -webkit-grid-row: 1;
+    width: 10px;
+    height: 15px;
+}
+#b {
+    background-color: green;
+    -webkit-grid-column: 2;
+    -webkit-grid-row: 1;
+    width: 10px;
+    height: 15px;
+}
+#c {
+    background-color: red;
+    -webkit-grid-column: 1;
+    -webkit-grid-row: 2;
+    width: 10px;
+    height: 15px;
+}
+#d {
+    background-color: orange;
+    -webkit-grid-column: 2;
+    -webkit-grid-row: 2;
+    width: 10px;
+    height: 15px;
+}
+</style>
+<script src=""
+<body _onload_="checkLayout('.grid')">
+
+<p>Test some simple grid layouts by positioning grid items by index.</p>
+
+<div style="position: relative">
+<div class="grid" data-expected-width="110" data-expected-height="50">
+    <div id="a" data-offset-x="0" data-offset-y="0"></div>
+    <div id="b" data-offset-x="50" data-offset-y="0"></div>
+    <div id="c" data-offset-x="0" data-offset-y="20"></div>
+    <div id="d" data-offset-x="50" data-offset-y="20"></div>
+</div>
+</div>
+
+<div style="position: relative">
+<div class="grid" style="-webkit-writing-mode: horizontal-bt" data-expected-width="110" data-expected-height="50">
+    <div id="a" data-offset-x="0" data-offset-y="35"></div>
+    <div id="b" data-offset-x="50" data-offset-y="35"></div>
+    <div id="c" data-offset-x="0" data-offset-y="15"></div>
+    <div id="d" data-offset-x="50" data-offset-y="15"></div>
+</div>
+</div>
+
+<div style="position: relative">
+<!-- FIXME: The height of the grid is wrong because we need to implement computePreferredLogicalWidths(). -->
+<div class="grid" style="-webkit-writing-mode: vertical-rl; margin-bottom: 60px;" data-expected-width="50" data-expected-height="110">
+    <div id="a" data-offset-x="40" data-offset-y="0"></div>
+    <div id="b" data-offset-x="40" data-offset-y="50"></div>
+    <div id="c" data-offset-x="20" data-offset-y="0"></div>
+    <div id="d" data-offset-x="20" data-offset-y="50"></div>
+</div>
+</div>
+
+<div style="position: relative">
+<!-- FIXME: The height of the grid is wrong because we need to implement computePreferredLogicalWidths(). -->
+<div class="grid" style="-webkit-writing-mode: vertical-lr; margin-bottom: 60px;" data-expected-width="50" data-expected-height="110">
+    <div id="a" data-offset-x="0" data-offset-y="0"></div>
+    <div id="b" data-offset-x="0" data-offset-y="50"></div>
+    <div id="c" data-offset-x="20" data-offset-y="0"></div>
+    <div id="d" data-offset-x="20" data-offset-y="50"></div>
+</div>
+</div>
+
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (122746 => 122747)


--- trunk/Source/WebCore/ChangeLog	2012-07-16 19:06:00 UTC (rev 122746)
+++ trunk/Source/WebCore/ChangeLog	2012-07-16 19:09:57 UTC (rev 122747)
@@ -1,3 +1,29 @@
+2012-07-16  Tony Chang  <t...@chromium.org>
+
+        Position grid items by row/column index
+        https://bugs.webkit.org/show_bug.cgi?id=91293
+
+        Reviewed by Ojan Vafai.
+
+        Do some initial grid positioning. Only handle the simple case where tracks are
+        fixed values and don't properly size the grid items. This gives us something to
+        work with and starts implementing the "Grid Track Sizing Algorithm":
+        http://dev.w3.org/csswg/css3-grid-layout/#grid-track-sizing-algorithm0
+
+        Test: fast/css-grid-layout/place-cell-by-index.html
+
+        * rendering/RenderGrid.cpp:
+        (RenderGrid::GridTrack): Data structure for holding the track size. UsedBreadth matches the terminology
+        used in the spec.
+        (WebCore::RenderGrid::layoutBlock): Pull in some boiler plate code and put the
+        grid specific code in layoutGridItems.
+        (WebCore::RenderGrid::computedUsedBreadthOfGridTracks): Implement part of the grid track sizing algorithm.
+        (WebCore::RenderGrid::layoutGridItems): Compute the size of grid tracks, layout and position children.
+        (WebCore::RenderGrid::findChildLogicalPosition): Map track sizes to the actual position of the child.
+        * rendering/RenderGrid.h:
+        * rendering/style/RenderStyle.h: Just return a copy of Length rather than a reference to Length. This seems
+        more consistent with other getters that return a Length.
+
 2012-07-16  Sami Kyostila  <skyos...@chromium.org>
 
         [chromium] Only apply page scale delta to root scroll layer

Modified: trunk/Source/WebCore/rendering/RenderGrid.cpp (122746 => 122747)


--- trunk/Source/WebCore/rendering/RenderGrid.cpp	2012-07-16 19:06:00 UTC (rev 122746)
+++ trunk/Source/WebCore/rendering/RenderGrid.cpp	2012-07-16 19:09:57 UTC (rev 122747)
@@ -24,11 +24,25 @@
  */
 
 #include "config.h"
-
 #include "RenderGrid.h"
 
+#include "LayoutRepainter.h"
+#include "NotImplemented.h"
+#include "RenderLayer.h"
+#include "RenderView.h"
+
 namespace WebCore {
 
+class RenderGrid::GridTrack {
+public:
+    GridTrack()
+        : m_usedBreadth(0)
+    {
+    }
+
+    LayoutUnit m_usedBreadth;
+};
+
 RenderGrid::RenderGrid(Node* node)
     : RenderBlock(node)
 {
@@ -40,12 +54,131 @@
 {
 }
 
-void RenderGrid::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight)
+void RenderGrid::layoutBlock(bool relayoutChildren, LayoutUnit)
 {
-    // For now just call the base class.
-    RenderBlock::layoutBlock(relayoutChildren, pageLogicalHeight);
+    ASSERT(needsLayout());
+
+    if (!relayoutChildren && simplifiedLayout())
+        return;
+
+    // FIXME: Much of this method is boiler plate that matches RenderBox::layoutBlock and Render*FlexibleBox::layoutBlock.
+    // It would be nice to refactor some of the duplicate code.
+    LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
+    LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
+
+    if (inRenderFlowThread()) {
+        // Regions changing widths can force us to relayout our children.
+        if (logicalWidthChangedInRegions())
+            relayoutChildren = true;
+    }
+    computeInitialRegionRangeForBlock();
+
+    LayoutSize previousSize = size();
+
+    setLogicalHeight(0);
+    computeLogicalWidth();
+
+    m_overflow.clear();
+
+    if (scrollsOverflow()) {
+        if (style()->overflowX() == OSCROLL)
+            layer()->setHasHorizontalScrollbar(true);
+        if (style()->overflowY() == OSCROLL)
+            layer()->setHasVerticalScrollbar(true);
+    }
+
+    layoutGridItems();
+
+    LayoutUnit oldClientAfterEdge = clientLogicalBottom();
+    computeLogicalHeight();
+
+    if (size() != previousSize)
+        relayoutChildren = true;
+
+    layoutPositionedObjects(relayoutChildren || isRoot());
+
+    computeRegionRangeForBlock();
+
+    computeOverflow(oldClientAfterEdge);
+    statePusher.pop();
+
+    updateLayerTransform();
+
+    // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
+    // we overflow or not.
+    if (hasOverflowClip())
+        layer()->updateScrollInfoAfterLayout();
+
+    repainter.repaintAfterLayout();
+
+    setNeedsLayout(false);
 }
 
+void RenderGrid::computedUsedBreadthOfGridTracks(TrackSizingDirection direction, Vector<GridTrack>& tracks)
+{
+    const Vector<Length>& trackStyles = (direction == ForColumns) ? style()->gridColumns() : style()->gridRows();
+    for (size_t i = 0; i < trackStyles.size(); ++i) {
+        GridTrack track;
+        if (trackStyles[i].isFixed())
+            track.m_usedBreadth = trackStyles[i].getFloatValue();
+        else
+            notImplemented();
+
+        tracks.append(track);
+    }
+}
+
+void RenderGrid::layoutGridItems()
+{
+    Vector<GridTrack> columnTracks, rowTracks;
+    computedUsedBreadthOfGridTracks(ForColumns, columnTracks);
+    // FIXME: The logical width of Grid Columns from the prior step is used in
+    // the formatting of Grid items in content-sized Grid Rows to determine
+    // their required height. We will probably need to pass columns through.
+    computedUsedBreadthOfGridTracks(ForRows, rowTracks);
+
+    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
+        LayoutPoint childPosition = findChildLogicalPosition(child, columnTracks, rowTracks);
+        // 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.
+        child->layoutIfNeeded();
+
+        // FIXME: Handle border & padding on the grid element.
+        child->setLogicalLocation(childPosition);
+    }
+
+    // FIXME: Handle border & padding on the grid element.
+    for (size_t i = 0; i < rowTracks.size(); ++i)
+        setLogicalHeight(logicalHeight() + rowTracks[i].m_usedBreadth);
+}
+
+LayoutPoint RenderGrid::findChildLogicalPosition(RenderBox* child, const Vector<GridTrack>& columnTracks, const Vector<GridTrack>& rowTracks)
+{
+    Length column = child->style()->gridItemColumn();
+    Length row = child->style()->gridItemRow();
+
+    // FIXME: What does a non-positive integer mean for a column/row?
+    if (!column.isPositive() || !row.isPositive())
+        return LayoutPoint();
+
+    // FIXME: Handle other values for grid-{row,column} like ranges or line names.
+    if (!column.isFixed() || !row.isFixed())
+        return LayoutPoint();
+
+    size_t columnTrack = static_cast<size_t>(column.intValue()) - 1;
+    size_t rowTrack = static_cast<size_t>(row.intValue()) - 1;
+
+    LayoutPoint offset;
+    for (size_t i = 0; i < columnTrack && i < columnTracks.size(); ++i)
+        offset.setX(offset.x() + columnTracks[i].m_usedBreadth);
+    for (size_t i = 0; i < rowTrack && i < rowTracks.size(); ++i)
+        offset.setY(offset.y() + rowTracks[i].m_usedBreadth);
+
+    // FIXME: Handle margins on the grid item.
+    return offset;
+}
+
 const char* RenderGrid::renderName() const
 {
     if (isFloating())

Modified: trunk/Source/WebCore/rendering/RenderGrid.h (122746 => 122747)


--- trunk/Source/WebCore/rendering/RenderGrid.h	2012-07-16 19:06:00 UTC (rev 122746)
+++ trunk/Source/WebCore/rendering/RenderGrid.h	2012-07-16 19:09:57 UTC (rev 122747)
@@ -40,6 +40,14 @@
     virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) OVERRIDE;
 
     virtual bool avoidsFloats() const OVERRIDE { return true; }
+
+private:
+    class GridTrack;
+    enum TrackSizingDirection { ForColumns, ForRows };
+    void computedUsedBreadthOfGridTracks(TrackSizingDirection, Vector<GridTrack>&);
+    void layoutGridItems();
+
+    LayoutPoint findChildLogicalPosition(RenderBox*, const Vector<GridTrack>& columnTracks, const Vector<GridTrack>& rowTracks);
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/style/RenderStyle.h (122746 => 122747)


--- trunk/Source/WebCore/rendering/style/RenderStyle.h	2012-07-16 19:06:00 UTC (rev 122746)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.h	2012-07-16 19:09:57 UTC (rev 122747)
@@ -814,8 +814,8 @@
     const Vector<Length>& gridColumns() const { return rareNonInheritedData->m_grid->m_gridColumns; }
     const Vector<Length>& gridRows() const { return rareNonInheritedData->m_grid->m_gridRows; }
 
-    const Length& gridItemColumn() const { return rareNonInheritedData->m_gridItem->m_gridColumn; }
-    const Length& gridItemRow() const { return rareNonInheritedData->m_gridItem->m_gridRow; }
+    Length gridItemColumn() const { return rareNonInheritedData->m_gridItem->m_gridColumn; }
+    Length gridItemRow() const { return rareNonInheritedData->m_gridItem->m_gridRow; }
 
     const ShadowData* boxShadow() const { return rareNonInheritedData->m_boxShadow.get(); }
     void getBoxShadowExtent(LayoutUnit& top, LayoutUnit& right, LayoutUnit& bottom, LayoutUnit& left) const { getShadowExtent(boxShadow(), top, right, bottom, left); }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to