Remove overflow: scroll handling in block flow layout methods
[WebKit.git] / Source / WebCore / rendering / RenderGrid.cpp
index 883e1710b0102b96be8de24925aaabc783893ad7..dcb1861a9e21565010b8089c46b69b0c1c9547b7 100644 (file)
  */
 
 #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,10 +54,122 @@ RenderGrid::~RenderGrid()
 {
 }
 
-void RenderGrid::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight)
+void RenderGrid::layoutBlock(bool relayoutChildren, LayoutUnit)
+{
+    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();
+
+    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()
 {
-    // For now just call the base class.
-    RenderBlock::layoutBlock(relayoutChildren, pageLogicalHeight);
+    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