Changeset 289698 in webkit
- Timestamp:
- Feb 12, 2022 11:25:51 AM (5 months ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 11 edited
-
ChangeLog (modified) (1 diff)
-
inspector/InspectorInstrumentation.cpp (modified) (2 diffs)
-
inspector/InspectorInstrumentation.h (modified) (4 diffs)
-
inspector/InspectorOverlay.cpp (modified) (8 diffs)
-
inspector/InspectorOverlay.h (modified) (4 diffs)
-
inspector/agents/InspectorDOMAgent.cpp (modified) (5 diffs)
-
inspector/agents/InspectorDOMAgent.h (modified) (4 diffs)
-
platform/LayoutUnit.h (modified) (1 diff)
-
rendering/RenderBox.h (modified) (1 diff)
-
rendering/RenderFlexibleBox.cpp (modified) (1 diff)
-
rendering/RenderFlexibleBox.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r289697 r289698 1 2022-02-12 Patrick Angle <pangle@apple.com> 2 3 Web Inspector: [Flexbox] Show item bounds, gaps, and free space in flex overlays 4 https://bugs.webkit.org/show_bug.cgi?id=236410 5 6 Reviewed by Devin Rousso. 7 8 * inspector/InspectorInstrumentation.cpp: 9 (WebCore::InspectorInstrumentation::flexibleBoxRendererBeganLayoutImpl): 10 (WebCore::InspectorInstrumentation::flexibleBoxRendererWrappedToNextLineImpl): 11 (WebCore::InspectorInstrumentation::instrumentingAgents): 12 * inspector/InspectorInstrumentation.h: 13 (WebCore::InspectorInstrumentation::flexibleBoxRendererBeganLayout): 14 (WebCore::InspectorInstrumentation::flexibleBoxRendererWrappedToNextLine): 15 * inspector/agents/InspectorDOMAgent.cpp: 16 (WebCore::InspectorDOMAgent::willDestroyFrontendAndBackend): 17 (WebCore::InspectorDOMAgent::reset): 18 (WebCore::InspectorDOMAgent::flexibleBoxRendererBeganLayout): 19 (WebCore::InspectorDOMAgent::flexibleBoxRendererWrappedToNextLine): 20 (WebCore::InspectorDOMAgent::flexibleBoxRendererCachedItemsAtStartOfLine): 21 * inspector/agents/InspectorDOMAgent.h: 22 - Add instrumentation points specifically for flexbox renderers to keep track of which items start a new line 23 inside flex containers. The start of the first line is not recorded because it will always be zero. 24 25 (WebCore::InspectorDOMAgent::didCreateFrontendAndBackend): 26 - Force a layout of the document to ensure that our collection of flexbox line starts is correctly populated 27 when attaching an inspector, since without an inspector this information is not kept beyond layout. 28 29 * inspector/InspectorOverlay.cpp: 30 (WebCore::drawLayoutPattern): 31 - Generalize `drawLayoutHatching` to support different line styles in order to support the new stippling fill. 32 - In order to support "flipping" the pattern we now use a rectangle encompassing the provided quad as the edges 33 we follow for filling the pattern (the existing clipping ensures that the final product is still within the 34 quad). This also resolves an issue that could occur in transformed containers (non-rectangular) where the 35 spacing was inconsistent at different rotations/perspectives. 36 37 (WebCore::drawLayoutStippling): 38 - A new dot-pattern effect similar to hatching, but using small dots to fill the space instead. 39 40 (WebCore::drawLayoutHatching): 41 - Updated to use the new generic `drawLayoutPattern` helper. 42 43 (WebCore::InspectorOverlay::drawFlexOverlay): 44 (WebCore::InspectorOverlay::buildFlexOverlay): 45 - Handle iterating through the flex children to show their bounds as well as the spacing/gaps between them. 46 Almost all this work is done in relative terms, like leading/trailing/cross-axis/main-axis to make it easier to 47 reason about what should happen for different writing modes, text direction, flex direction, and flex wrapping. 48 To accomplish this coordinates of children are read through special `corrected*` helper functions that take in 49 to account the determined direction, main-axis reversal, and cross axis-reversal from all of the relevant 50 properties. This means there are only 8 (2^3) actual permutations of flex layout (since the layout inside each 51 individual child is irrelevant here). Throughout we are working with flex children frames that are relative to 52 their parent, which saves us from having to deal with transforms until after we have constructed most of our 53 overlay representation, only needing to be passed through `childQuadToRootQuad` before being added to the 54 appropriate part of the highlight object. 55 56 * inspector/InspectorOverlay.h: 57 (WebCore::InspectorOverlay::Highlight::FlexHighlightOverlay::encode const): 58 (WebCore::InspectorOverlay::Highlight::FlexHighlightOverlay::decode): 59 60 * rendering/RenderBox.h: 61 (WebCore::RenderBox::marginBox const): 62 - Add a way to get the entire margin box instead of its individual components. 63 64 * rendering/RenderFlexibleBox.cpp: 65 (WebCore::RenderFlexibleBox::layoutFlexItems): 66 * rendering/RenderFlexibleBox.h: 67 - Make getting the computed inter-item and inter-line gap public so we can use them in the overlay. 68 - Add instrumentation calls to keep track of the indexes of items that start a new line during layout when an 69 Inspector is attached. 70 71 * platform/LayoutUnit.h: 72 (WebCore::operator!=): 73 1 74 2022-02-12 Jer Noble <jer.noble@apple.com> 2 75 -
trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp
r288623 r289698 579 579 } 580 580 581 void InspectorInstrumentation::flexibleBoxRendererBeganLayoutImpl(InstrumentingAgents& instrumentingAgents, const RenderObject& renderer) 582 { 583 if (auto* domAgent = instrumentingAgents.persistentDOMAgent()) 584 domAgent->flexibleBoxRendererBeganLayout(renderer); 585 } 586 587 void InspectorInstrumentation::flexibleBoxRendererWrappedToNextLineImpl(InstrumentingAgents& instrumentingAgents, const RenderObject& renderer, size_t lineStartItemIndex) 588 { 589 if (auto* domAgent = instrumentingAgents.persistentDOMAgent()) 590 domAgent->flexibleBoxRendererWrappedToNextLine(renderer, lineStartItemIndex); 591 } 592 581 593 void InspectorInstrumentation::willSendRequestImpl(InstrumentingAgents& instrumentingAgents, ResourceLoaderIdentifier identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse, const CachedResource* cachedResource) 582 594 { … … 1273 1285 } 1274 1286 1275 InstrumentingAgents* InspectorInstrumentation::instrumentingAgents( RenderObject& renderer)1287 InstrumentingAgents* InspectorInstrumentation::instrumentingAgents(const RenderObject& renderer) 1276 1288 { 1277 1289 return instrumentingAgents(renderer.frame()); -
trunk/Source/WebCore/inspector/InspectorInstrumentation.h
r288623 r289698 192 192 static void applyEmulatedMedia(Frame&, String&); 193 193 194 static void flexibleBoxRendererBeganLayout(const RenderObject&); 195 static void flexibleBoxRendererWrappedToNextLine(const RenderObject&, size_t lineStartItemIndex); 196 194 197 static void willSendRequest(Frame*, ResourceLoaderIdentifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, const CachedResource*); 195 198 static void didLoadResourceFromMemoryCache(Page&, DocumentLoader*, CachedResource*); … … 411 414 static void applyEmulatedMediaImpl(InstrumentingAgents&, String&); 412 415 416 static void flexibleBoxRendererBeganLayoutImpl(InstrumentingAgents&, const RenderObject&); 417 static void flexibleBoxRendererWrappedToNextLineImpl(InstrumentingAgents&, const RenderObject&, size_t lineStartItemIndex); 418 413 419 static void willSendRequestImpl(InstrumentingAgents&, ResourceLoaderIdentifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, const CachedResource*); 414 420 static void willSendRequestOfTypeImpl(InstrumentingAgents&, ResourceLoaderIdentifier, DocumentLoader*, ResourceRequest&, LoadType); … … 524 530 static InstrumentingAgents* instrumentingAgents(Document&); 525 531 static InstrumentingAgents* instrumentingAgents(Document*); 526 static InstrumentingAgents* instrumentingAgents( RenderObject&);532 static InstrumentingAgents* instrumentingAgents(const RenderObject&); 527 533 static InstrumentingAgents* instrumentingAgents(WorkerOrWorkletGlobalScope*); 528 534 }; … … 1041 1047 } 1042 1048 1049 inline void InspectorInstrumentation::flexibleBoxRendererBeganLayout(const RenderObject& renderer) 1050 { 1051 FAST_RETURN_IF_NO_FRONTENDS(void()); 1052 if (auto* agents = instrumentingAgents(renderer)) 1053 flexibleBoxRendererBeganLayoutImpl(*agents, renderer); 1054 } 1055 1056 inline void InspectorInstrumentation::flexibleBoxRendererWrappedToNextLine(const RenderObject& renderer, size_t lineStartItemIndex) 1057 { 1058 FAST_RETURN_IF_NO_FRONTENDS(void()); 1059 if (auto* agents = instrumentingAgents(renderer)) 1060 flexibleBoxRendererWrappedToNextLineImpl(*agents, renderer, lineStartItemIndex); 1061 } 1062 1043 1063 inline void InspectorInstrumentation::willSendRequest(Frame* frame, ResourceLoaderIdentifier identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse, const CachedResource* cachedResource) 1044 1064 { -
trunk/Source/WebCore/inspector/InspectorOverlay.cpp
r289416 r289698 52 52 #include "GridPositionsResolver.h" 53 53 #include "InspectorClient.h" 54 #include "InspectorController.h" 55 #include "InspectorDOMAgent.h" 54 56 #include "IntPoint.h" 55 57 #include "IntRect.h" … … 58 60 #include "NodeList.h" 59 61 #include "NodeRenderStyle.h" 62 #include "OrderIterator.h" 60 63 #include "Page.h" 61 64 #include "PseudoElement.h" … … 69 72 #include "StyleGridData.h" 70 73 #include "StyleResolver.h" 74 #include "TextDirection.h" 71 75 #include <wtf/MathExtras.h> 72 76 #include <wtf/text/StringBuilder.h> … … 95 99 static constexpr UChar thinSpace = 0x2009; 96 100 static constexpr UChar emSpace = 0x2003; 101 102 enum class Flip : bool { No, Yes }; 97 103 98 104 static void truncateWithEllipsis(String& string, size_t length) … … 1221 1227 } 1222 1228 1223 static void drawLayout Hatching(GraphicsContext& context, FloatQuad quad)1229 static void drawLayoutPattern(GraphicsContext& context, const FloatQuad& quad, int hatchSpacing, Flip flip) 1224 1230 { 1225 1231 GraphicsContextStateSaver saver(context); 1226 1232 context.clipPath(quadToPath(quad)); 1233 1234 Path hatchPath; 1235 1236 auto boundingBox = quad.enclosingBoundingBox(); 1237 1238 auto correctedLineForPoints = [&](const FloatPoint& start, const FloatPoint& end) { 1239 return (flip == Flip::Yes) ? FloatLine(end, start) : FloatLine(start, end); 1240 }; 1241 1242 auto topSide = correctedLineForPoints(boundingBox.minXMinYCorner(), boundingBox.maxXMinYCorner()); 1243 auto leftSide = correctedLineForPoints(boundingBox.minXMinYCorner(), boundingBox.minXMaxYCorner()); 1244 1245 // The opposite axis' length is used to determine how far to draw a hatch line in both dimensions, which keeps the lines at a 45deg angle. 1246 if (topSide.length() > leftSide.length()) { 1247 auto bottomSide = correctedLineForPoints(boundingBox.minXMaxYCorner(), boundingBox.maxXMaxYCorner()); 1248 // Move across the relative top of the area, starting left of `0, 0` to ensure that the tail of the previous hatch line is drawn while scrolling. 1249 for (float x = -leftSide.length(); x < topSide.length(); x += hatchSpacing) { 1250 hatchPath.moveTo(topSide.pointAtAbsoluteDistance(x)); 1251 hatchPath.addLineTo(bottomSide.pointAtAbsoluteDistance(x + leftSide.length())); 1252 } 1253 } else { 1254 auto rightSide = correctedLineForPoints(boundingBox.maxXMinYCorner(), boundingBox.maxXMaxYCorner()); 1255 // Move down the relative left side of the area, starting above `0, 0` to ensure that the tail of the previous hatch line is drawn while scrolling. 1256 for (float y = -topSide.length(); y < leftSide.length(); y += hatchSpacing) { 1257 hatchPath.moveTo(leftSide.pointAtAbsoluteDistance(y)); 1258 hatchPath.addLineTo(rightSide.pointAtAbsoluteDistance(y + topSide.length())); 1259 } 1260 } 1261 1262 context.strokePath(hatchPath); 1263 } 1264 1265 static void drawLayoutStippling(GraphicsContext& context, const FloatQuad& quad, float density) 1266 { 1267 GraphicsContextStateSaver saver(context); 1268 context.setStrokeThickness(1); 1269 context.setStrokeStyle(StrokeStyle::DashedStroke); 1270 context.setLineDash({ 1, density }, 1); 1271 1272 drawLayoutPattern(context, quad, density, Flip::No); 1273 } 1274 1275 static void drawLayoutHatching(GraphicsContext& context, const FloatQuad& quad, Flip flip = Flip::No) 1276 { 1277 GraphicsContextStateSaver saver(context); 1227 1278 context.setStrokeThickness(0.5); 1228 1279 context.setStrokeStyle(StrokeStyle::DashedStroke); 1229 1280 context.setLineDash({ 2, 2 }, 2); 1230 1231 constexpr auto hatchSpacing = 12; 1232 Path hatchPath; 1233 1234 FloatLine topSide = { quad.p1(), quad.p2() }; 1235 FloatLine leftSide = { quad.p1(), quad.p4() }; 1236 1237 // The opposite axis' length is used to determine how far to draw a hatch line in both dimensions, which keeps the lines at a 45deg angle. 1238 if (topSide.length() > leftSide.length()) { 1239 FloatLine bottomSide = { quad.p4(), quad.p3() }; 1240 // Move across the relative top of the quad, starting left of `0, 0` to ensure that the tail of the previous hatch line is drawn while scrolling. 1241 for (float x = -leftSide.length(); x < topSide.length(); x += hatchSpacing) { 1242 hatchPath.moveTo(topSide.pointAtAbsoluteDistance(x)); 1243 hatchPath.addLineTo(bottomSide.pointAtAbsoluteDistance(x + leftSide.length())); 1244 } 1245 } else { 1246 FloatLine rightSide = { quad.p2(), quad.p3() }; 1247 // Move down the relative left side of the quad, starting above `0, 0` to ensure that the tail of the previous hatch line is drawn while scrolling. 1248 for (float y = -topSide.length(); y < leftSide.length(); y += hatchSpacing) { 1249 hatchPath.moveTo(leftSide.pointAtAbsoluteDistance(y)); 1250 hatchPath.addLineTo(rightSide.pointAtAbsoluteDistance(y + topSide.length())); 1251 } 1252 } 1253 1254 context.strokePath(hatchPath); 1281 1282 constexpr auto defaultLayoutHatchSpacing = 12; 1283 drawLayoutPattern(context, quad, defaultLayoutHatchSpacing, flip); 1255 1284 } 1256 1285 … … 1994 2023 context.setStrokeColor(flexHighlightOverlay.color); 1995 2024 context.strokePath(quadToPath(flexHighlightOverlay.containerBounds)); 2025 2026 for (const auto& bounds : flexHighlightOverlay.itemBounds) 2027 context.strokePath(quadToPath(bounds)); 2028 2029 for (const auto& mainAxisGap : flexHighlightOverlay.mainAxisGaps) { 2030 context.strokePath(quadToPath(mainAxisGap)); 2031 drawLayoutHatching(context, mainAxisGap); 2032 } 2033 2034 { 2035 GraphicsContextStateSaver mainAxisSpaceContextSaver(context); 2036 context.setAlpha(0.5); 2037 2038 constexpr auto mainAxisSpaceDensity = 3; 2039 for (auto mainAxisSpaceBetweenItemAndGap : flexHighlightOverlay.mainAxisSpaceBetweenItemsAndGaps) 2040 drawLayoutStippling(context, mainAxisSpaceBetweenItemAndGap, mainAxisSpaceDensity); 2041 } 2042 2043 for (const auto& crossAxisGap : flexHighlightOverlay.crossAxisGaps) { 2044 context.strokePath(quadToPath(crossAxisGap)); 2045 drawLayoutHatching(context, crossAxisGap, Flip::Yes); 2046 } 2047 2048 context.setAlpha(0.7); 2049 constexpr auto spaceBetweenItemsAndCrossAxisSpaceStipplingDensity = 6; 2050 for (const auto& crossAxisSpaceBetweenItemAndGap : flexHighlightOverlay.spaceBetweenItemsAndCrossAxisSpace) 2051 drawLayoutStippling(context, crossAxisSpaceBetweenItemAndGap, spaceBetweenItemsAndCrossAxisSpaceStipplingDensity); 1996 2052 } 1997 2053 … … 2017 2073 auto& renderFlex = *downcast<RenderFlexibleBox>(renderer); 2018 2074 2075 auto itemsAtStartOfLine = m_page.inspectorController().ensureDOMAgent().flexibleBoxRendererCachedItemsAtStartOfLine(renderFlex); 2076 2019 2077 Frame* containingFrame = node->document().frame(); 2020 2078 if (!containingFrame) … … 2022 2080 FrameView* containingView = containingFrame->view(); 2023 2081 2024 auto localQuadToRootQuad = [&](const FloatQuad& quad) -> FloatQuad { 2025 return { 2082 auto computedStyle = node->computedStyle(); 2083 if (!computedStyle) 2084 return { }; 2085 2086 auto wasRowDirection = !computedStyle->isColumnFlexDirection(); 2087 auto isFlippedBlocksWritingMode = computedStyle->isFlippedBlocksWritingMode(); 2088 auto isRightToLeftDirection = computedStyle->direction() == TextDirection::RTL; 2089 2090 auto isRowDirection = wasRowDirection ^ !computedStyle->isHorizontalWritingMode(); 2091 auto isMainAxisDirectionReversed = computedStyle->isReverseFlexDirection() ^ (wasRowDirection ? isRightToLeftDirection : isFlippedBlocksWritingMode); 2092 auto isCrossAxisDirectionReversed = (computedStyle->flexWrap() == FlexWrap::Reverse) ^ (wasRowDirection ? isFlippedBlocksWritingMode : isRightToLeftDirection); 2093 2094 auto localQuadToRootQuad = [&](const FloatQuad& quad) { 2095 return FloatQuad( 2026 2096 localPointToRootPoint(containingView, quad.p1()), 2027 2097 localPointToRootPoint(containingView, quad.p2()), 2028 2098 localPointToRootPoint(containingView, quad.p3()), 2029 2099 localPointToRootPoint(containingView, quad.p4()) 2030 }; 2100 ); 2101 }; 2102 2103 auto childQuadToRootQuad = [&](const FloatQuad& quad) { 2104 return FloatQuad( 2105 localPointToRootPoint(containingView, renderFlex.localToContainerPoint(quad.p1(), nullptr)), 2106 localPointToRootPoint(containingView, renderFlex.localToContainerPoint(quad.p2(), nullptr)), 2107 localPointToRootPoint(containingView, renderFlex.localToContainerPoint(quad.p3(), nullptr)), 2108 localPointToRootPoint(containingView, renderFlex.localToContainerPoint(quad.p4(), nullptr)) 2109 ); 2110 }; 2111 2112 auto correctedMainAxisLeadingEdge = [&](const LayoutRect& rect) { 2113 if (isRowDirection) 2114 return isMainAxisDirectionReversed ? rect.maxX() : rect.x(); 2115 return isMainAxisDirectionReversed ? rect.maxY() : rect.y(); 2116 }; 2117 2118 auto correctedMainAxisTrailingEdge = [&](const LayoutRect& rect) { 2119 if (isRowDirection) 2120 return isMainAxisDirectionReversed ? rect.x() : rect.maxX(); 2121 return isMainAxisDirectionReversed ? rect.y() : rect.maxY(); 2122 }; 2123 2124 auto correctedCrossAxisLeadingEdge = [&](const LayoutRect& rect) { 2125 if (isRowDirection) 2126 return isCrossAxisDirectionReversed ? rect.maxY() : rect.y(); 2127 return isCrossAxisDirectionReversed ? rect.maxX() : rect.x(); 2128 }; 2129 2130 auto correctedCrossAxisTrailingEdge = [&](const LayoutRect& rect) { 2131 if (isRowDirection) 2132 return isCrossAxisDirectionReversed ? rect.y() : rect.maxY(); 2133 return isCrossAxisDirectionReversed ? rect.x() : rect.maxX(); 2134 }; 2135 2136 auto correctedCrossAxisMin = [&](float a, float b) { 2137 return isCrossAxisDirectionReversed ? std::fmax(a, b) : std::fmin(a, b); 2138 }; 2139 2140 auto correctedCrossAxisMax = [&](float a, float b) { 2141 return isCrossAxisDirectionReversed ? std::fmin(a, b) : std::fmax(a, b); 2142 }; 2143 2144 auto correctedPoint = [&](float mainAxisLocation, float crossAxisLocation) { 2145 return isRowDirection ? FloatPoint(mainAxisLocation, crossAxisLocation) : FloatPoint(crossAxisLocation, mainAxisLocation); 2146 }; 2147 2148 auto populateHighlightForGapOrSpace = [&](float fromMainAxisEdge, float toMainAxisEdge, float fromCrossAxisEdge, float toCrossAxisEdge, Vector<FloatQuad>& gapsSet) { 2149 gapsSet.append(childQuadToRootQuad({ 2150 correctedPoint(fromMainAxisEdge, fromCrossAxisEdge), 2151 correctedPoint(toMainAxisEdge, fromCrossAxisEdge), 2152 correctedPoint(toMainAxisEdge, toCrossAxisEdge), 2153 correctedPoint(fromMainAxisEdge, toCrossAxisEdge), 2154 })); 2031 2155 }; 2032 2156 2033 2157 InspectorOverlay::Highlight::FlexHighlightOverlay flexHighlightOverlay; 2034 2158 flexHighlightOverlay.color = flexOverlay.config.flexColor; 2035 flexHighlightOverlay.containerBounds = localQuadToRootQuad({ renderFlex.absoluteContentQuad() }); 2159 flexHighlightOverlay.containerBounds = localQuadToRootQuad(renderFlex.absoluteContentQuad()); 2160 2161 float computedMainAxisGap = renderFlex.computeGap(RenderFlexibleBox::GapType::BetweenItems).toFloat(); 2162 float computedCrossAxisGap = renderFlex.computeGap(RenderFlexibleBox::GapType::BetweenLines).toFloat(); 2163 2164 // For reasoning about the edges of the flex container, use the untransformed content rect moved to the origin of the 2165 // inner top-left corner of padding, which is the same relative coordinate space that each item's `frameRect()` will be in. 2166 auto containerRect = renderFlex.absoluteContentBox(); 2167 containerRect.setLocation({ renderFlex.paddingLeft() + renderFlex.borderLeft(), renderFlex.paddingTop() + renderFlex.borderTop() }); 2168 2169 float containerMainAxisLeadingEdge = correctedMainAxisLeadingEdge(containerRect); 2170 float containerMainAxisTrailingEdge = correctedMainAxisTrailingEdge(containerRect); 2171 2172 Vector<LayoutRect> currentLineChildrenRects; 2173 float currentLineCrossAxisLeadingEdge = isCrossAxisDirectionReversed ? 0.0f : std::numeric_limits<float>::max(); 2174 float currentLineCrossAxisTrailingEdge = isCrossAxisDirectionReversed ? std::numeric_limits<float>::max() : 0.0f; 2175 float previousLineCrossAxisTrailingEdge = correctedCrossAxisLeadingEdge(containerRect); 2176 2177 size_t currentChildIndex = 0; 2178 auto childOrderIterator = renderFlex.orderIterator(); 2179 for (RenderBox* renderChild = childOrderIterator.first(); renderChild; renderChild = childOrderIterator.next()) { 2180 if (childOrderIterator.shouldSkipChild(*renderChild)) 2181 continue; 2182 2183 // Build bounds for each child and collect children on the same logical line. 2184 { 2185 auto childRect = renderChild->frameRect(); 2186 renderFlex.flipForWritingMode(childRect); 2187 childRect.expand(renderChild->marginBox()); 2188 flexHighlightOverlay.itemBounds.append(childQuadToRootQuad({ childRect })); 2189 2190 currentLineCrossAxisLeadingEdge = correctedCrossAxisMin(currentLineCrossAxisLeadingEdge, correctedCrossAxisLeadingEdge(childRect)); 2191 currentLineCrossAxisTrailingEdge = correctedCrossAxisMax(currentLineCrossAxisTrailingEdge, correctedCrossAxisTrailingEdge(childRect)); 2192 2193 currentLineChildrenRects.append(WTFMove(childRect)); 2194 ++currentChildIndex; 2195 } 2196 2197 // The remaining work can only be done once we have collected all of the children on the current line. 2198 if (!itemsAtStartOfLine.contains(currentChildIndex)) 2199 continue; 2200 2201 float previousChildMainAxisTrailingEdge = correctedMainAxisLeadingEdge(containerRect); 2202 for (const auto& childRect : currentLineChildrenRects) { 2203 auto childMainAxisLeadingEdge = correctedMainAxisLeadingEdge(childRect); 2204 auto childMainAxisTrailingEdge = correctedMainAxisTrailingEdge(childRect); 2205 auto childCrossAxisLeadingEdge = correctedCrossAxisLeadingEdge(childRect); 2206 auto childCrossAxisTrailingEdge = correctedCrossAxisTrailingEdge(childRect); 2207 2208 // Build bounds for space between the current item and the cross-axis space. 2209 if (std::fabs(childCrossAxisLeadingEdge - currentLineCrossAxisLeadingEdge) > 1) 2210 populateHighlightForGapOrSpace(childMainAxisLeadingEdge, childMainAxisTrailingEdge, currentLineCrossAxisLeadingEdge, childCrossAxisLeadingEdge, flexHighlightOverlay.spaceBetweenItemsAndCrossAxisSpace); 2211 if (std::fabs(childCrossAxisTrailingEdge - currentLineCrossAxisTrailingEdge) > 1) 2212 populateHighlightForGapOrSpace(childMainAxisLeadingEdge, childMainAxisTrailingEdge, currentLineCrossAxisTrailingEdge, childCrossAxisTrailingEdge, flexHighlightOverlay.spaceBetweenItemsAndCrossAxisSpace); 2213 2214 // Build bounds for gaps and space between the current item and previous item (or container edge). 2215 if (computedMainAxisGap && previousChildMainAxisTrailingEdge != correctedMainAxisLeadingEdge(containerRect)) { 2216 // Regardless of flipped axises, we need to do the below calculations from left to right or top to bottom. 2217 float startEdge = std::fmin(previousChildMainAxisTrailingEdge, childMainAxisLeadingEdge); 2218 float endEdge = std::fmax(previousChildMainAxisTrailingEdge, childMainAxisLeadingEdge); 2219 2220 float spaceBetweenEdgeAndGap = (endEdge - startEdge - computedMainAxisGap) / 2; 2221 2222 populateHighlightForGapOrSpace(startEdge, startEdge + spaceBetweenEdgeAndGap, currentLineCrossAxisLeadingEdge, currentLineCrossAxisTrailingEdge, flexHighlightOverlay.mainAxisSpaceBetweenItemsAndGaps); 2223 populateHighlightForGapOrSpace(startEdge + spaceBetweenEdgeAndGap, endEdge - spaceBetweenEdgeAndGap, currentLineCrossAxisLeadingEdge, currentLineCrossAxisTrailingEdge, flexHighlightOverlay.mainAxisGaps); 2224 populateHighlightForGapOrSpace(endEdge - spaceBetweenEdgeAndGap, endEdge, currentLineCrossAxisLeadingEdge, currentLineCrossAxisTrailingEdge, flexHighlightOverlay.mainAxisSpaceBetweenItemsAndGaps); 2225 } else 2226 populateHighlightForGapOrSpace(previousChildMainAxisTrailingEdge, childMainAxisLeadingEdge, currentLineCrossAxisLeadingEdge, currentLineCrossAxisTrailingEdge, flexHighlightOverlay.mainAxisSpaceBetweenItemsAndGaps); 2227 2228 previousChildMainAxisTrailingEdge = childMainAxisTrailingEdge; 2229 } 2230 populateHighlightForGapOrSpace(previousChildMainAxisTrailingEdge, containerMainAxisTrailingEdge, currentLineCrossAxisLeadingEdge, currentLineCrossAxisTrailingEdge, flexHighlightOverlay.mainAxisSpaceBetweenItemsAndGaps); 2231 2232 // Build gaps between the current line and the previous line. 2233 if (computedCrossAxisGap && previousLineCrossAxisTrailingEdge != correctedCrossAxisLeadingEdge(containerRect)) { 2234 // Regardless of flipped axises, we need to do the below calculations from left to right or top to bottom. 2235 float startEdge = std::fmin(previousLineCrossAxisTrailingEdge, currentLineCrossAxisLeadingEdge); 2236 float endEdge = std::fmax(previousLineCrossAxisTrailingEdge, currentLineCrossAxisLeadingEdge); 2237 2238 float spaceBetweenEdgeAndGap = (endEdge - startEdge - computedCrossAxisGap) / 2; 2239 2240 populateHighlightForGapOrSpace(containerMainAxisLeadingEdge, containerMainAxisTrailingEdge, startEdge + spaceBetweenEdgeAndGap, endEdge - spaceBetweenEdgeAndGap, flexHighlightOverlay.crossAxisGaps); 2241 } 2242 2243 previousLineCrossAxisTrailingEdge = currentLineCrossAxisTrailingEdge; 2244 2245 currentLineChildrenRects.clear(); 2246 currentLineCrossAxisLeadingEdge = isCrossAxisDirectionReversed ? 0.0f : std::numeric_limits<float>::max(); 2247 currentLineCrossAxisTrailingEdge = isCrossAxisDirectionReversed ? std::numeric_limits<float>::max() : 0.0f; 2248 } 2036 2249 2037 2250 return { flexHighlightOverlay }; -
trunk/Source/WebCore/inspector/InspectorOverlay.h
r289416 r289698 40 40 #include <wtf/RefPtr.h> 41 41 #include <wtf/Vector.h> 42 #include <wtf/WeakHashMap.h> 42 43 #include <wtf/WeakPtr.h> 43 44 #include <wtf/text/WTFString.h> … … 147 148 Color color; 148 149 FloatQuad containerBounds; 150 Vector<FloatQuad> itemBounds; 151 Vector<FloatQuad> mainAxisGaps; 152 Vector<FloatQuad> mainAxisSpaceBetweenItemsAndGaps; 153 Vector<FloatQuad> spaceBetweenItemsAndCrossAxisSpace; 154 Vector<FloatQuad> crossAxisGaps; 149 155 150 156 #if PLATFORM(IOS_FAMILY) … … 304 310 encoder << color; 305 311 encoder << containerBounds; 312 encoder << itemBounds; 313 encoder << mainAxisGaps; 314 encoder << mainAxisSpaceBetweenItemsAndGaps; 315 encoder << spaceBetweenItemsAndCrossAxisSpace; 316 encoder << crossAxisGaps; 306 317 } 307 318 … … 312 323 return { }; 313 324 if (!decoder.decode(flexHighlightOverlay.containerBounds)) 325 return { }; 326 if (!decoder.decode(flexHighlightOverlay.itemBounds)) 327 return { }; 328 if (!decoder.decode(flexHighlightOverlay.mainAxisGaps)) 329 return { }; 330 if (!decoder.decode(flexHighlightOverlay.mainAxisSpaceBetweenItemsAndGaps)) 331 return { }; 332 if (!decoder.decode(flexHighlightOverlay.spaceBetweenItemsAndCrossAxisSpace)) 333 return { }; 334 if (!decoder.decode(flexHighlightOverlay.crossAxisGaps)) 314 335 return { }; 315 336 return { flexHighlightOverlay }; -
trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp
r289416 r289698 96 96 #include "PseudoElement.h" 97 97 #include "RenderGrid.h" 98 #include "RenderObject.h" 98 99 #include "RenderStyle.h" 99 100 #include "RenderStyleConstants.h" … … 308 309 m_document = m_inspectedPage.mainFrame().document(); 309 310 311 // Force a layout so that we can collect additional information from the layout process. 312 if (m_document) 313 m_document->updateLayout(); 314 310 315 #if ENABLE(VIDEO) 311 316 if (m_document) … … 330 335 331 336 m_overlay->clearAllGridOverlays(); 337 m_overlay->clearAllFlexOverlays(); 332 338 333 339 m_instrumentingAgents.setPersistentDOMAgent(nullptr); … … 357 363 m_revalidateStyleAttrTask->reset(); 358 364 m_document = nullptr; 365 m_flexibleBoxRendererCachedItemsAtStartOfLine.clear(); 359 366 360 367 m_destroyedDetachedNodeIdentifiers.clear(); … … 2791 2798 } 2792 2799 2800 void InspectorDOMAgent::flexibleBoxRendererBeganLayout(const RenderObject& renderer) 2801 { 2802 m_flexibleBoxRendererCachedItemsAtStartOfLine.remove(renderer); 2803 } 2804 2805 void InspectorDOMAgent::flexibleBoxRendererWrappedToNextLine(const RenderObject& renderer, size_t lineStartItemIndex) 2806 { 2807 m_flexibleBoxRendererCachedItemsAtStartOfLine.ensure(renderer, [] { 2808 return Vector<size_t>(); 2809 }).iterator->value.append(lineStartItemIndex); 2810 } 2811 2812 Vector<size_t> InspectorDOMAgent::flexibleBoxRendererCachedItemsAtStartOfLine(const RenderObject& renderer) 2813 { 2814 return m_flexibleBoxRendererCachedItemsAtStartOfLine.get(renderer); 2815 } 2816 2793 2817 RefPtr<JSC::Breakpoint> InspectorDOMAgent::breakpointForEventListener(EventTarget& target, const AtomString& eventType, EventListener& listener, bool capture) 2794 2818 { -
trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.h
r289416 r289698 73 73 class Page; 74 74 class PseudoElement; 75 class RenderObject; 75 76 class RevalidateStyleAttributeTask; 76 77 class ShadowRoot; … … 183 184 bool isEventListenerDisabled(EventTarget&, const AtomString& eventType, EventListener&, bool capture); 184 185 void eventDidResetAfterDispatch(const Event&); 186 void flexibleBoxRendererBeganLayout(const RenderObject&); 187 void flexibleBoxRendererWrappedToNextLine(const RenderObject&, size_t lineStartItemIndex); 185 188 186 189 // Callbacks that don't directly correspond to an instrumentation entry point. … … 206 209 InspectorHistory* history() { return m_history.get(); } 207 210 Vector<Document*> documents(); 211 Vector<size_t> flexibleBoxRendererCachedItemsAtStartOfLine(const RenderObject&); 208 212 void reset(); 209 213 … … 270 274 std::unique_ptr<InspectorHistory> m_history; 271 275 std::unique_ptr<DOMEditor> m_domEditor; 276 WeakHashMap<RenderObject, Vector<size_t>> m_flexibleBoxRendererCachedItemsAtStartOfLine; 272 277 273 278 Vector<Inspector::Protocol::DOM::NodeId> m_destroyedDetachedNodeIdentifiers; -
trunk/Source/WebCore/platform/LayoutUnit.h
r283287 r289698 379 379 } 380 380 381 inline bool operator!=(const float a, const LayoutUnit& b) 382 { 383 return LayoutUnit(a) != b; 384 } 385 381 386 inline bool operator!=(const LayoutUnit& a, float b) 382 387 { -
trunk/Source/WebCore/rendering/RenderBox.h
r289606 r289698 263 263 void setScrollPosition(const ScrollPosition&, const ScrollPositionChangeOptions&); 264 264 265 const LayoutBoxExtent& marginBox() const { return m_marginBox; } 265 266 LayoutUnit marginTop() const override { return m_marginBox.top(); } 266 267 LayoutUnit marginBottom() const override { return m_marginBox.bottom(); } -
trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp
r288492 r289698 1154 1154 size_t nextIndex = 0; 1155 1155 size_t numLines = 0; 1156 InspectorInstrumentation::flexibleBoxRendererBeganLayout(*this); 1156 1157 while (flexAlgorithm.computeNextFlexLine(nextIndex, lineItems, sumFlexBaseSize, totalFlexGrow, totalFlexShrink, totalWeightedFlexShrink, sumHypotheticalMainSize)) { 1157 1158 ++numLines; 1159 InspectorInstrumentation::flexibleBoxRendererWrappedToNextLine(*this, nextIndex); 1160 1158 1161 LayoutUnit containerMainInnerSize = mainAxisContentExtent(sumHypotheticalMainSize); 1159 1162 // availableFreeSpace is the initial amount of free space in this flexbox. -
trunk/Source/WebCore/rendering/RenderFlexibleBox.h
r287976 r289698 87 87 // be laid out again. 88 88 bool setStaticPositionForPositionedLayout(const RenderBox&); 89 90 enum class GapType { BetweenLines, BetweenItems }; 91 LayoutUnit computeGap(GapType) const; 89 92 90 93 protected: … … 206 209 void resetHasDefiniteHeight() { m_hasDefiniteHeight = SizeDefiniteness::Unknown; } 207 210 208 enum class GapType { BetweenLines, BetweenItems };209 LayoutUnit computeGap(GapType) const;210 211 211 // This is used to cache the preferred size for orthogonal flow children so we 212 212 // don't have to relayout to get it … … 223 223 // sizing of children. 224 224 HashSet<const RenderBox*> m_relaidOutChildren; 225 225 226 226 mutable OrderIterator m_orderIterator { *this }; 227 227 int m_numberOfInFlowChildrenOnFirstLine { -1 };
Note: See TracChangeset
for help on using the changeset viewer.