Skip to content

Commit ee295e3

Browse files
committed
Web Inspector: Show gap overlays between items in masonry axis for grid-lanes layouts
https://bugs.webkit.org/show_bug.cgi?id=304579 rdar://problem/166984079 Reviewed by Devin Rousso. For grid-lanes (masonry) layouts, the grid overlay now shows gaps between items in the masonry axis direction. Previously, only the bounding lines of the masonry axis were drawn, with no gap visualization between items. The implementation collects all grid items and their bounding boxes, groups them by their grid axis track, sorts them by position in the masonry axis, and draws gap regions between consecutive items within each track. * Source/WebCore/inspector/InspectorOverlay.cpp: (WebCore::InspectorOverlay::buildGridOverlay): Canonical link: https://commits.webkit.org/304861@main
1 parent e74894d commit ee295e3

File tree

1 file changed

+105
-0
lines changed

1 file changed

+105
-0
lines changed

Source/WebCore/inspector/InspectorOverlay.cpp

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,6 +1864,111 @@ std::optional<InspectorOverlay::Highlight::GridHighlightOverlay> InspectorOverla
18641864
}
18651865
}
18661866

1867+
// For masonry layouts, draw gaps between items in the masonry axis direction.
1868+
if (renderGrid.isMasonry()) {
1869+
auto& orderIterator = renderGrid.currentGrid().orderIterator();
1870+
1871+
struct ItemInfo {
1872+
CheckedPtr<RenderBox> item;
1873+
FloatRect bounds;
1874+
unsigned trackStart;
1875+
unsigned trackEnd;
1876+
};
1877+
1878+
Vector<ItemInfo> allItems;
1879+
for (auto* gridItem = orderIterator.first(); gridItem; gridItem = orderIterator.next()) {
1880+
if (orderIterator.shouldSkipChild(*gridItem))
1881+
continue;
1882+
1883+
auto gridArea = renderGrid.currentGrid().gridItemArea(*gridItem);
1884+
auto absoluteRect = FloatRect { gridItem->absoluteBoundingBoxRect(true) };
1885+
absoluteRect.expand(gridItem->marginBox());
1886+
1887+
auto minCorner = localPointToRootPoint(containingView, absoluteRect.minXMinYCorner());
1888+
auto maxCorner = localPointToRootPoint(containingView, absoluteRect.maxXMaxYCorner());
1889+
FloatRect rootRect { minCorner, maxCorner - minCorner };
1890+
1891+
if (renderGrid.areMasonryRows()) {
1892+
auto& columnSpan = gridArea.columns;
1893+
if (!columnSpan.isTranslatedDefinite())
1894+
continue;
1895+
allItems.append({ gridItem, rootRect, columnSpan.startLine(), columnSpan.endLine() });
1896+
} else {
1897+
auto& rowSpan = gridArea.rows;
1898+
if (!rowSpan.isTranslatedDefinite())
1899+
continue;
1900+
allItems.append({ gridItem, rootRect, rowSpan.startLine(), rowSpan.endLine() });
1901+
}
1902+
}
1903+
1904+
unsigned gridAxisTrackCount = renderGrid.areMasonryRows() ? columnWidths.size() : rowHeights.size();
1905+
1906+
for (unsigned trackIndex = 0; trackIndex < gridAxisTrackCount; ++trackIndex) {
1907+
Vector<ItemInfo*> itemsInTrack;
1908+
for (auto& itemInfo : allItems) {
1909+
if (trackIndex >= itemInfo.trackStart && trackIndex < itemInfo.trackEnd)
1910+
itemsInTrack.append(&itemInfo);
1911+
}
1912+
1913+
if (itemsInTrack.size() < 2)
1914+
continue;
1915+
1916+
if (renderGrid.areMasonryRows()) {
1917+
std::sort(itemsInTrack.begin(), itemsInTrack.end(), [](ItemInfo* a, ItemInfo* b) {
1918+
return a->bounds.y() < b->bounds.y();
1919+
});
1920+
} else {
1921+
std::sort(itemsInTrack.begin(), itemsInTrack.end(), [](ItemInfo* a, ItemInfo* b) {
1922+
return a->bounds.x() < b->bounds.x();
1923+
});
1924+
}
1925+
1926+
for (size_t i = 1; i < itemsInTrack.size(); ++i) {
1927+
auto& previousItem = *itemsInTrack[i - 1];
1928+
auto& currentItem = *itemsInTrack[i];
1929+
1930+
FloatQuad gapQuad;
1931+
if (renderGrid.areMasonryRows()) {
1932+
float gapTop = previousItem.bounds.maxY();
1933+
float gapBottom = currentItem.bounds.y();
1934+
if (gapBottom <= gapTop)
1935+
continue;
1936+
1937+
float gapLeft = std::max(previousItem.bounds.x(), currentItem.bounds.x());
1938+
float gapRight = std::min(previousItem.bounds.maxX(), currentItem.bounds.maxX());
1939+
if (gapRight <= gapLeft)
1940+
continue;
1941+
1942+
gapQuad = {
1943+
{ gapLeft, gapTop },
1944+
{ gapRight, gapTop },
1945+
{ gapRight, gapBottom },
1946+
{ gapLeft, gapBottom },
1947+
};
1948+
} else {
1949+
float gapLeft = previousItem.bounds.maxX();
1950+
float gapRight = currentItem.bounds.x();
1951+
if (gapRight <= gapLeft)
1952+
continue;
1953+
1954+
float gapTop = std::max(previousItem.bounds.y(), currentItem.bounds.y());
1955+
float gapBottom = std::min(previousItem.bounds.maxY(), currentItem.bounds.maxY());
1956+
if (gapBottom <= gapTop)
1957+
continue;
1958+
1959+
gapQuad = {
1960+
{ gapLeft, gapTop },
1961+
{ gapRight, gapTop },
1962+
{ gapRight, gapBottom },
1963+
{ gapLeft, gapBottom },
1964+
};
1965+
}
1966+
1967+
gridHighlightOverlay.gaps.append(gapQuad);
1968+
}
1969+
}
1970+
}
1971+
18671972
if (gridOverlay.config.showOrderNumbers) {
18681973
Vector<RenderBox*> gridItemsInGridOrder;
18691974
Vector<RenderBox*> gridItemsInDOMOrder;

0 commit comments

Comments
 (0)