WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch v1.3 (reupload for EWS)
bug-236410-20220211094118.patch (text/plain), 38.05 KB, created by
Patrick Angle
on 2022-02-11 09:41:19 PST
(
hide
)
Description:
Patch v1.3 (reupload for EWS)
Filename:
MIME Type:
Creator:
Patrick Angle
Created:
2022-02-11 09:41:19 PST
Size:
38.05 KB
patch
obsolete
>Subversion Revision: 289499 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index fc62511aed9febbd897fb3b6126098595e0d5aa6..d822db70595392b75d5aac81beb1acd16c9b5179 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,76 @@ >+2022-02-10 Patrick Angle <pangle@apple.com> >+ >+ Web Inspector: [Flexbox] Show item bounds, gaps, and free space in flex overlays >+ https://bugs.webkit.org/show_bug.cgi?id=236410 >+ >+ Reviewed by Devin Rousso. >+ >+ * inspector/InspectorInstrumentation.cpp: >+ (WebCore::InspectorInstrumentation::flexibleBoxRendererBeganLayoutImpl): >+ (WebCore::InspectorInstrumentation::flexibleBoxRendererWrappedToNextLineImpl): >+ (WebCore::InspectorInstrumentation::instrumentingAgents): >+ * inspector/InspectorInstrumentation.h: >+ (WebCore::InspectorInstrumentation::flexibleBoxRendererBeganLayout): >+ (WebCore::InspectorInstrumentation::flexibleBoxRendererWrappedToNextLine): >+ * inspector/agents/InspectorDOMAgent.cpp: >+ (WebCore::InspectorDOMAgent::willDestroyFrontendAndBackend): >+ (WebCore::InspectorDOMAgent::reset): >+ (WebCore::InspectorDOMAgent::flexibleBoxRendererBeganLayout): >+ (WebCore::InspectorDOMAgent::flexibleBoxRendererWrappedToNextLine): >+ (WebCore::InspectorDOMAgent::flexibleBoxRendererCachedItemsAtStartOfLine): >+ * inspector/agents/InspectorDOMAgent.h: >+ - Add instrumentation points specifically for flexbox renderers to keep track of which items start a new line >+ inside flex containers. The start of the first line is not recorded because it will always be zero. >+ >+ (WebCore::InspectorDOMAgent::didCreateFrontendAndBackend): >+ - Force a layout of the document to ensure that our collection of flexbox line starts is correctly populated >+ when attaching an inspector, since without an inspector this information is not kept beyond layout. >+ >+ * inspector/InspectorOverlay.cpp: >+ (WebCore::drawLayoutPattern): >+ - Generalize `drawLayoutHatching` to support different line styles in order to support the new stippling fill. >+ - In order to support "flipping" the pattern we now use a rectangle encompassing the provided quad as the edges >+ we follow for filling the pattern (the existing clipping ensures that the final product is still within the >+ quad). This also resolves an issue that could occur in transformed containers (non-rectangular) where the >+ spacing was inconsistent at different rotations/perspectives. >+ >+ (WebCore::drawLayoutStippling): >+ - A new dot-pattern effect similar to hatching, but using small dots to fill the space instead. >+ >+ (WebCore::drawLayoutHatching): >+ - Updated to use the new generic `drawLayoutPattern` helper. >+ >+ (WebCore::InspectorOverlay::drawFlexOverlay): >+ (WebCore::InspectorOverlay::buildFlexOverlay): >+ - Handle iterating through the flex children to show their bounds as well as the spacing/gaps between them. >+ Almost all this work is done in relative terms, like leading/trailing/cross-axis/main-axis to make it easier to >+ reason about what should happen for different writing modes, text direction, flex direction, and flex wrapping. >+ To accomplish this coordinates of children are read through special `corrected*` helper functions that take in >+ to account the determined direction, main-axis reversal, and cross axis-reversal from all of the relevant >+ properties. This means there are only 8 (2^3) actual permutations of flex layout (since the layout inside each >+ individual child is irrelevant here). Throughout we are working with flex children frames that are relative to >+ their parent, which saves us from having to deal with transforms until after we have constructed most of our >+ overlay representation, only needing to be passed through `childQuadToRootQuad` before being added to the >+ appropriate part of the highlight object. >+ >+ * inspector/InspectorOverlay.h: >+ (WebCore::InspectorOverlay::Highlight::FlexHighlightOverlay::encode const): >+ (WebCore::InspectorOverlay::Highlight::FlexHighlightOverlay::decode): >+ >+ * rendering/RenderBox.h: >+ (WebCore::RenderBox::marginBox const): >+ - Add a way to get the entire margin box instead of its individual components. >+ >+ * rendering/RenderFlexibleBox.cpp: >+ (WebCore::RenderFlexibleBox::layoutFlexItems): >+ * rendering/RenderFlexibleBox.h: >+ - Make getting the computed inter-item and inter-line gap public so we can use them in the overlay. >+ - Add instrumentation calls to keep track of the indexes of items that start a new line during layout when an >+ Inspector is attached. >+ >+ * platform/LayoutUnit.h: >+ (WebCore::operator!=): >+ > 2022-02-09 Alan Bujtas <zalan@apple.com> > > [LFC][IFC] Vertical writing mode with RTL text content has incorrect advances >diff --git a/Source/WebCore/inspector/InspectorInstrumentation.cpp b/Source/WebCore/inspector/InspectorInstrumentation.cpp >index fa92adcea9ef8572e2aa853a2072cc645fac10fd..f96f40cf38395152ec33c48c7a0c4723dfa0c573 100644 >--- a/Source/WebCore/inspector/InspectorInstrumentation.cpp >+++ b/Source/WebCore/inspector/InspectorInstrumentation.cpp >@@ -578,6 +578,18 @@ void InspectorInstrumentation::applyEmulatedMediaImpl(InstrumentingAgents& instr > pageAgent->applyEmulatedMedia(media); > } > >+void InspectorInstrumentation::flexibleBoxRendererBeganLayoutImpl(InstrumentingAgents& instrumentingAgents, const RenderObject& renderer) >+{ >+ if (auto* domAgent = instrumentingAgents.persistentDOMAgent()) >+ domAgent->flexibleBoxRendererBeganLayout(renderer); >+} >+ >+void InspectorInstrumentation::flexibleBoxRendererWrappedToNextLineImpl(InstrumentingAgents& instrumentingAgents, const RenderObject& renderer, size_t lineStartItemIndex) >+{ >+ if (auto* domAgent = instrumentingAgents.persistentDOMAgent()) >+ domAgent->flexibleBoxRendererWrappedToNextLine(renderer, lineStartItemIndex); >+} >+ > void InspectorInstrumentation::willSendRequestImpl(InstrumentingAgents& instrumentingAgents, ResourceLoaderIdentifier identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse, const CachedResource* cachedResource) > { > if (auto* networkAgent = instrumentingAgents.enabledNetworkAgent()) >@@ -1272,7 +1284,7 @@ void InspectorInstrumentation::unregisterInstrumentingAgents(InstrumentingAgents > } > } > >-InstrumentingAgents* InspectorInstrumentation::instrumentingAgents(RenderObject& renderer) >+InstrumentingAgents* InspectorInstrumentation::instrumentingAgents(const RenderObject& renderer) > { > return instrumentingAgents(renderer.frame()); > } >diff --git a/Source/WebCore/inspector/InspectorInstrumentation.h b/Source/WebCore/inspector/InspectorInstrumentation.h >index 777a7ed4c082bd24ef719956e2a653744e0755f3..b61f6a0dcab296bbacbc125caac03586e9c197f0 100644 >--- a/Source/WebCore/inspector/InspectorInstrumentation.h >+++ b/Source/WebCore/inspector/InspectorInstrumentation.h >@@ -191,6 +191,9 @@ public: > static void applyUserAgentOverride(Frame&, String&); > static void applyEmulatedMedia(Frame&, String&); > >+ static void flexibleBoxRendererBeganLayout(const RenderObject&); >+ static void flexibleBoxRendererWrappedToNextLine(const RenderObject&, size_t lineStartItemIndex); >+ > static void willSendRequest(Frame*, ResourceLoaderIdentifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, const CachedResource*); > static void didLoadResourceFromMemoryCache(Page&, DocumentLoader*, CachedResource*); > static void didReceiveResourceResponse(Frame&, ResourceLoaderIdentifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*); >@@ -410,6 +413,9 @@ private: > static void applyUserAgentOverrideImpl(InstrumentingAgents&, String&); > static void applyEmulatedMediaImpl(InstrumentingAgents&, String&); > >+ static void flexibleBoxRendererBeganLayoutImpl(InstrumentingAgents&, const RenderObject&); >+ static void flexibleBoxRendererWrappedToNextLineImpl(InstrumentingAgents&, const RenderObject&, size_t lineStartItemIndex); >+ > static void willSendRequestImpl(InstrumentingAgents&, ResourceLoaderIdentifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, const CachedResource*); > static void willSendRequestOfTypeImpl(InstrumentingAgents&, ResourceLoaderIdentifier, DocumentLoader*, ResourceRequest&, LoadType); > static void markResourceAsCachedImpl(InstrumentingAgents&, ResourceLoaderIdentifier); >@@ -523,7 +529,7 @@ private: > static InstrumentingAgents* instrumentingAgents(ScriptExecutionContext&); > static InstrumentingAgents* instrumentingAgents(Document&); > static InstrumentingAgents* instrumentingAgents(Document*); >- static InstrumentingAgents* instrumentingAgents(RenderObject&); >+ static InstrumentingAgents* instrumentingAgents(const RenderObject&); > static InstrumentingAgents* instrumentingAgents(WorkerOrWorkletGlobalScope*); > }; > >@@ -1040,6 +1046,20 @@ inline void InspectorInstrumentation::applyEmulatedMedia(Frame& frame, String& m > applyEmulatedMediaImpl(*agents, media); > } > >+inline void InspectorInstrumentation::flexibleBoxRendererBeganLayout(const RenderObject& renderer) >+{ >+ FAST_RETURN_IF_NO_FRONTENDS(void()); >+ if (auto* agents = instrumentingAgents(renderer)) >+ flexibleBoxRendererBeganLayoutImpl(*agents, renderer); >+} >+ >+inline void InspectorInstrumentation::flexibleBoxRendererWrappedToNextLine(const RenderObject& renderer, size_t lineStartItemIndex) >+{ >+ FAST_RETURN_IF_NO_FRONTENDS(void()); >+ if (auto* agents = instrumentingAgents(renderer)) >+ flexibleBoxRendererWrappedToNextLineImpl(*agents, renderer, lineStartItemIndex); >+} >+ > inline void InspectorInstrumentation::willSendRequest(Frame* frame, ResourceLoaderIdentifier identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse, const CachedResource* cachedResource) > { > FAST_RETURN_IF_NO_FRONTENDS(void()); >diff --git a/Source/WebCore/inspector/InspectorOverlay.cpp b/Source/WebCore/inspector/InspectorOverlay.cpp >index 25cafcbfa58ff54262b0eb5f720b66f075e3598b..e32e82f3cf756c9e9111bce800bffc27e5d92344 100644 >--- a/Source/WebCore/inspector/InspectorOverlay.cpp >+++ b/Source/WebCore/inspector/InspectorOverlay.cpp >@@ -51,12 +51,15 @@ > #include "GridArea.h" > #include "GridPositionsResolver.h" > #include "InspectorClient.h" >+#include "InspectorController.h" >+#include "InspectorDOMAgent.h" > #include "IntPoint.h" > #include "IntRect.h" > #include "IntSize.h" > #include "Node.h" > #include "NodeList.h" > #include "NodeRenderStyle.h" >+#include "OrderIterator.h" > #include "Page.h" > #include "PseudoElement.h" > #include "RenderBox.h" >@@ -68,6 +71,7 @@ > #include "Settings.h" > #include "StyleGridData.h" > #include "StyleResolver.h" >+#include "TextDirection.h" > #include <wtf/MathExtras.h> > #include <wtf/text/StringBuilder.h> > >@@ -95,6 +99,8 @@ static constexpr UChar multiplicationSign = 0x00D7; > static constexpr UChar thinSpace = 0x2009; > static constexpr UChar emSpace = 0x2003; > >+enum class Flip : bool { No, Yes }; >+ > static void truncateWithEllipsis(String& string, size_t length) > { > if (string.length() > length) { >@@ -1220,40 +1226,63 @@ Path InspectorOverlay::drawElementTitle(GraphicsContext& context, Node& node, co > return path; > } > >-static void drawLayoutHatching(GraphicsContext& context, FloatQuad quad) >+static void drawLayoutPattern(GraphicsContext& context, const FloatQuad& quad, int hatchSpacing, Flip flip) > { > GraphicsContextStateSaver saver(context); > context.clipPath(quadToPath(quad)); >- context.setStrokeThickness(0.5); >- context.setStrokeStyle(StrokeStyle::DashedStroke); >- context.setLineDash({ 2, 2 }, 2); >- >- constexpr auto hatchSpacing = 12; >+ > Path hatchPath; >- >- FloatLine topSide = { quad.p1(), quad.p2() }; >- FloatLine leftSide = { quad.p1(), quad.p4() }; >- >+ >+ auto boundingBox = quad.enclosingBoundingBox(); >+ >+ auto correctedLineForPoints = [&](const FloatPoint& start, const FloatPoint& end) { >+ return (flip == Flip::Yes) ? FloatLine(end, start) : FloatLine(start, end); >+ }; >+ >+ auto topSide = correctedLineForPoints(boundingBox.minXMinYCorner(), boundingBox.maxXMinYCorner()); >+ auto leftSide = correctedLineForPoints(boundingBox.minXMinYCorner(), boundingBox.minXMaxYCorner()); >+ > // 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. > if (topSide.length() > leftSide.length()) { >- FloatLine bottomSide = { quad.p4(), quad.p3() }; >- // 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. >+ auto bottomSide = correctedLineForPoints(boundingBox.minXMaxYCorner(), boundingBox.maxXMaxYCorner()); >+ // 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. > for (float x = -leftSide.length(); x < topSide.length(); x += hatchSpacing) { > hatchPath.moveTo(topSide.pointAtAbsoluteDistance(x)); > hatchPath.addLineTo(bottomSide.pointAtAbsoluteDistance(x + leftSide.length())); > } > } else { >- FloatLine rightSide = { quad.p2(), quad.p3() }; >- // 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. >+ auto rightSide = correctedLineForPoints(boundingBox.maxXMinYCorner(), boundingBox.maxXMaxYCorner()); >+ // 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. > for (float y = -topSide.length(); y < leftSide.length(); y += hatchSpacing) { > hatchPath.moveTo(leftSide.pointAtAbsoluteDistance(y)); > hatchPath.addLineTo(rightSide.pointAtAbsoluteDistance(y + topSide.length())); > } > } >- >+ > context.strokePath(hatchPath); > } > >+static void drawLayoutStippling(GraphicsContext& context, const FloatQuad& quad, float density) >+{ >+ GraphicsContextStateSaver saver(context); >+ context.setStrokeThickness(1); >+ context.setStrokeStyle(StrokeStyle::DashedStroke); >+ context.setLineDash({ 1, density }, 1); >+ >+ drawLayoutPattern(context, quad, density, Flip::No); >+} >+ >+static void drawLayoutHatching(GraphicsContext& context, const FloatQuad& quad, Flip flip = Flip::No) >+{ >+ GraphicsContextStateSaver saver(context); >+ context.setStrokeThickness(0.5); >+ context.setStrokeStyle(StrokeStyle::DashedStroke); >+ context.setLineDash({ 2, 2 }, 2); >+ >+ constexpr auto defaultLayoutHatchSpacing = 12; >+ drawLayoutPattern(context, quad, defaultLayoutHatchSpacing, flip); >+} >+ > static FontCascade fontForLayoutLabel() > { > FontCascadeDescription fontDescription; >@@ -1993,6 +2022,33 @@ void InspectorOverlay::drawFlexOverlay(GraphicsContext& context, const Inspector > context.setStrokeThickness(1); > context.setStrokeColor(flexHighlightOverlay.color); > context.strokePath(quadToPath(flexHighlightOverlay.containerBounds)); >+ >+ for (const auto& bounds : flexHighlightOverlay.itemBounds) >+ context.strokePath(quadToPath(bounds)); >+ >+ for (const auto& mainAxisGap : flexHighlightOverlay.mainAxisGaps) { >+ context.strokePath(quadToPath(mainAxisGap)); >+ drawLayoutHatching(context, mainAxisGap); >+ } >+ >+ { >+ GraphicsContextStateSaver mainAxisSpaceContextSaver(context); >+ context.setAlpha(0.5); >+ >+ constexpr auto mainAxisSpaceDensity = 3; >+ for (auto mainAxisSpaceBetweenItemAndGap : flexHighlightOverlay.mainAxisSpaceBetweenItemsAndGaps) >+ drawLayoutStippling(context, mainAxisSpaceBetweenItemAndGap, mainAxisSpaceDensity); >+ } >+ >+ for (const auto& crossAxisGap : flexHighlightOverlay.crossAxisGaps) { >+ context.strokePath(quadToPath(crossAxisGap)); >+ drawLayoutHatching(context, crossAxisGap, Flip::Yes); >+ } >+ >+ context.setAlpha(0.7); >+ constexpr auto spaceBetweenItemsAndCrossAxisSpaceStipplingDensity = 6; >+ for (const auto& crossAxisSpaceBetweenItemAndGap : flexHighlightOverlay.spaceBetweenItemsAndCrossAxisSpace) >+ drawLayoutStippling(context, crossAxisSpaceBetweenItemAndGap, spaceBetweenItemsAndCrossAxisSpaceStipplingDensity); > } > > std::optional<InspectorOverlay::Highlight::FlexHighlightOverlay> InspectorOverlay::buildFlexOverlay(const InspectorOverlay::Flex& flexOverlay) >@@ -2016,23 +2072,180 @@ std::optional<InspectorOverlay::Highlight::FlexHighlightOverlay> InspectorOverla > > auto& renderFlex = *downcast<RenderFlexibleBox>(renderer); > >+ auto itemsAtStartOfLine = m_page.inspectorController().ensureDOMAgent().flexibleBoxRendererCachedItemsAtStartOfLine(renderFlex); >+ > Frame* containingFrame = node->document().frame(); > if (!containingFrame) > return { }; > FrameView* containingView = containingFrame->view(); > >- auto localQuadToRootQuad = [&](const FloatQuad& quad) -> FloatQuad { >- return { >+ auto computedStyle = node->computedStyle(); >+ if (!computedStyle) >+ return { }; >+ >+ auto wasRowDirection = !computedStyle->isColumnFlexDirection(); >+ auto isFlippedBlocksWritingMode = computedStyle->isFlippedBlocksWritingMode(); >+ auto isRightToLeftDirection = computedStyle->direction() == TextDirection::RTL; >+ >+ auto isRowDirection = wasRowDirection ^ !computedStyle->isHorizontalWritingMode(); >+ auto isMainAxisDirectionReversed = computedStyle->isReverseFlexDirection() ^ (wasRowDirection ? isRightToLeftDirection : isFlippedBlocksWritingMode); >+ auto isCrossAxisDirectionReversed = (computedStyle->flexWrap() == FlexWrap::Reverse) ^ (wasRowDirection ? isFlippedBlocksWritingMode : isRightToLeftDirection); >+ >+ auto localQuadToRootQuad = [&](const FloatQuad& quad) { >+ return FloatQuad( > localPointToRootPoint(containingView, quad.p1()), > localPointToRootPoint(containingView, quad.p2()), > localPointToRootPoint(containingView, quad.p3()), > localPointToRootPoint(containingView, quad.p4()) >- }; >+ ); >+ }; >+ >+ auto childQuadToRootQuad = [&](const FloatQuad& quad) { >+ return FloatQuad( >+ localPointToRootPoint(containingView, renderFlex.localToContainerPoint(quad.p1(), nullptr)), >+ localPointToRootPoint(containingView, renderFlex.localToContainerPoint(quad.p2(), nullptr)), >+ localPointToRootPoint(containingView, renderFlex.localToContainerPoint(quad.p3(), nullptr)), >+ localPointToRootPoint(containingView, renderFlex.localToContainerPoint(quad.p4(), nullptr)) >+ ); >+ }; >+ >+ auto correctedMainAxisLeadingEdge = [&](const LayoutRect& rect) { >+ if (isRowDirection) >+ return isMainAxisDirectionReversed ? rect.maxX() : rect.x(); >+ return isMainAxisDirectionReversed ? rect.maxY() : rect.y(); >+ }; >+ >+ auto correctedMainAxisTrailingEdge = [&](const LayoutRect& rect) { >+ if (isRowDirection) >+ return isMainAxisDirectionReversed ? rect.x() : rect.maxX(); >+ return isMainAxisDirectionReversed ? rect.y() : rect.maxY(); >+ }; >+ >+ auto correctedCrossAxisLeadingEdge = [&](const LayoutRect& rect) { >+ if (isRowDirection) >+ return isCrossAxisDirectionReversed ? rect.maxY() : rect.y(); >+ return isCrossAxisDirectionReversed ? rect.maxX() : rect.x(); >+ }; >+ >+ auto correctedCrossAxisTrailingEdge = [&](const LayoutRect& rect) { >+ if (isRowDirection) >+ return isCrossAxisDirectionReversed ? rect.y() : rect.maxY(); >+ return isCrossAxisDirectionReversed ? rect.x() : rect.maxX(); >+ }; >+ >+ auto correctedCrossAxisMin = [&](float a, float b) { >+ return isCrossAxisDirectionReversed ? std::fmax(a, b) : std::fmin(a, b); >+ }; >+ >+ auto correctedCrossAxisMax = [&](float a, float b) { >+ return isCrossAxisDirectionReversed ? std::fmin(a, b) : std::fmax(a, b); >+ }; >+ >+ auto correctedPoint = [&](float mainAxisLocation, float crossAxisLocation) { >+ return isRowDirection ? FloatPoint(mainAxisLocation, crossAxisLocation) : FloatPoint(crossAxisLocation, mainAxisLocation); >+ }; >+ >+ auto populateHighlightForGapOrSpace = [&](float fromMainAxisEdge, float toMainAxisEdge, float fromCrossAxisEdge, float toCrossAxisEdge, Vector<FloatQuad>& gapsSet) { >+ gapsSet.append(childQuadToRootQuad({ >+ correctedPoint(fromMainAxisEdge, fromCrossAxisEdge), >+ correctedPoint(toMainAxisEdge, fromCrossAxisEdge), >+ correctedPoint(toMainAxisEdge, toCrossAxisEdge), >+ correctedPoint(fromMainAxisEdge, toCrossAxisEdge), >+ })); > }; > > InspectorOverlay::Highlight::FlexHighlightOverlay flexHighlightOverlay; > flexHighlightOverlay.color = flexOverlay.config.flexColor; >- flexHighlightOverlay.containerBounds = localQuadToRootQuad({ renderFlex.absoluteContentQuad() }); >+ flexHighlightOverlay.containerBounds = localQuadToRootQuad(renderFlex.absoluteContentQuad()); >+ >+ float computedMainAxisGap = renderFlex.computeGap(RenderFlexibleBox::GapType::BetweenItems).toFloat(); >+ float computedCrossAxisGap = renderFlex.computeGap(RenderFlexibleBox::GapType::BetweenLines).toFloat(); >+ >+ // For reasoning about the edges of the flex container, use the untransformed content rect moved to the origin of the >+ // inner top-left corner of padding, which is the same relative coordinate space that each item's `frameRect()` will be in. >+ auto containerRect = renderFlex.absoluteContentBox(); >+ containerRect.setLocation({ renderFlex.paddingLeft() + renderFlex.borderLeft(), renderFlex.paddingTop() + renderFlex.borderTop() }); >+ >+ float containerMainAxisLeadingEdge = correctedMainAxisLeadingEdge(containerRect); >+ float containerMainAxisTrailingEdge = correctedMainAxisTrailingEdge(containerRect); >+ >+ Vector<LayoutRect> currentLineChildrenRects; >+ float currentLineCrossAxisLeadingEdge = isCrossAxisDirectionReversed ? 0.0f : std::numeric_limits<float>::max(); >+ float currentLineCrossAxisTrailingEdge = isCrossAxisDirectionReversed ? std::numeric_limits<float>::max() : 0.0f; >+ float previousLineCrossAxisTrailingEdge = correctedCrossAxisLeadingEdge(containerRect); >+ >+ size_t currentChildIndex = 0; >+ auto childOrderIterator = renderFlex.orderIterator(); >+ for (RenderBox* renderChild = childOrderIterator.first(); renderChild; renderChild = childOrderIterator.next()) { >+ if (childOrderIterator.shouldSkipChild(*renderChild)) >+ continue; >+ >+ // Build bounds for each child and collect children on the same logical line. >+ { >+ auto childRect = renderChild->frameRect(); >+ renderFlex.flipForWritingMode(childRect); >+ childRect.expand(renderChild->marginBox()); >+ flexHighlightOverlay.itemBounds.append(childQuadToRootQuad({ childRect })); >+ >+ currentLineCrossAxisLeadingEdge = correctedCrossAxisMin(currentLineCrossAxisLeadingEdge, correctedCrossAxisLeadingEdge(childRect)); >+ currentLineCrossAxisTrailingEdge = correctedCrossAxisMax(currentLineCrossAxisTrailingEdge, correctedCrossAxisTrailingEdge(childRect)); >+ >+ currentLineChildrenRects.append(WTFMove(childRect)); >+ ++currentChildIndex; >+ } >+ >+ // The remaining work can only be done once we have collected all of the children on the current line. >+ if (!itemsAtStartOfLine.contains(currentChildIndex)) >+ continue; >+ >+ float previousChildMainAxisTrailingEdge = correctedMainAxisLeadingEdge(containerRect); >+ for (const auto& childRect : currentLineChildrenRects) { >+ auto childMainAxisLeadingEdge = correctedMainAxisLeadingEdge(childRect); >+ auto childMainAxisTrailingEdge = correctedMainAxisTrailingEdge(childRect); >+ auto childCrossAxisLeadingEdge = correctedCrossAxisLeadingEdge(childRect); >+ auto childCrossAxisTrailingEdge = correctedCrossAxisTrailingEdge(childRect); >+ >+ // Build bounds for space between the current item and the cross-axis space. >+ if (std::fabs(childCrossAxisLeadingEdge - currentLineCrossAxisLeadingEdge) > 1) >+ populateHighlightForGapOrSpace(childMainAxisLeadingEdge, childMainAxisTrailingEdge, currentLineCrossAxisLeadingEdge, childCrossAxisLeadingEdge, flexHighlightOverlay.spaceBetweenItemsAndCrossAxisSpace); >+ if (std::fabs(childCrossAxisTrailingEdge - currentLineCrossAxisTrailingEdge) > 1) >+ populateHighlightForGapOrSpace(childMainAxisLeadingEdge, childMainAxisTrailingEdge, currentLineCrossAxisTrailingEdge, childCrossAxisTrailingEdge, flexHighlightOverlay.spaceBetweenItemsAndCrossAxisSpace); >+ >+ // Build bounds for gaps and space between the current item and previous item (or container edge). >+ if (computedMainAxisGap && previousChildMainAxisTrailingEdge != correctedMainAxisLeadingEdge(containerRect)) { >+ // Regardless of flipped axises, we need to do the below calculations from left to right or top to bottom. >+ float startEdge = std::fmin(previousChildMainAxisTrailingEdge, childMainAxisLeadingEdge); >+ float endEdge = std::fmax(previousChildMainAxisTrailingEdge, childMainAxisLeadingEdge); >+ >+ float spaceBetweenEdgeAndGap = (endEdge - startEdge - computedMainAxisGap) / 2; >+ >+ populateHighlightForGapOrSpace(startEdge, startEdge + spaceBetweenEdgeAndGap, currentLineCrossAxisLeadingEdge, currentLineCrossAxisTrailingEdge, flexHighlightOverlay.mainAxisSpaceBetweenItemsAndGaps); >+ populateHighlightForGapOrSpace(startEdge + spaceBetweenEdgeAndGap, endEdge - spaceBetweenEdgeAndGap, currentLineCrossAxisLeadingEdge, currentLineCrossAxisTrailingEdge, flexHighlightOverlay.mainAxisGaps); >+ populateHighlightForGapOrSpace(endEdge - spaceBetweenEdgeAndGap, endEdge, currentLineCrossAxisLeadingEdge, currentLineCrossAxisTrailingEdge, flexHighlightOverlay.mainAxisSpaceBetweenItemsAndGaps); >+ } else >+ populateHighlightForGapOrSpace(previousChildMainAxisTrailingEdge, childMainAxisLeadingEdge, currentLineCrossAxisLeadingEdge, currentLineCrossAxisTrailingEdge, flexHighlightOverlay.mainAxisSpaceBetweenItemsAndGaps); >+ >+ previousChildMainAxisTrailingEdge = childMainAxisTrailingEdge; >+ } >+ populateHighlightForGapOrSpace(previousChildMainAxisTrailingEdge, containerMainAxisTrailingEdge, currentLineCrossAxisLeadingEdge, currentLineCrossAxisTrailingEdge, flexHighlightOverlay.mainAxisSpaceBetweenItemsAndGaps); >+ >+ // Build gaps between the current line and the previous line. >+ if (computedCrossAxisGap && previousLineCrossAxisTrailingEdge != correctedCrossAxisLeadingEdge(containerRect)) { >+ // Regardless of flipped axises, we need to do the below calculations from left to right or top to bottom. >+ float startEdge = std::fmin(previousLineCrossAxisTrailingEdge, currentLineCrossAxisLeadingEdge); >+ float endEdge = std::fmax(previousLineCrossAxisTrailingEdge, currentLineCrossAxisLeadingEdge); >+ >+ float spaceBetweenEdgeAndGap = (endEdge - startEdge - computedCrossAxisGap) / 2; >+ >+ populateHighlightForGapOrSpace(containerMainAxisLeadingEdge, containerMainAxisTrailingEdge, startEdge + spaceBetweenEdgeAndGap, endEdge - spaceBetweenEdgeAndGap, flexHighlightOverlay.crossAxisGaps); >+ } >+ >+ previousLineCrossAxisTrailingEdge = currentLineCrossAxisTrailingEdge; >+ >+ currentLineChildrenRects.clear(); >+ currentLineCrossAxisLeadingEdge = isCrossAxisDirectionReversed ? 0.0f : std::numeric_limits<float>::max(); >+ currentLineCrossAxisTrailingEdge = isCrossAxisDirectionReversed ? std::numeric_limits<float>::max() : 0.0f; >+ } > > return { flexHighlightOverlay }; > } >diff --git a/Source/WebCore/inspector/InspectorOverlay.h b/Source/WebCore/inspector/InspectorOverlay.h >index ce8974443da7a1152284825a332ae63fd313e7a6..52953a183f0cce1134b375c7478f1303cd4bae70 100644 >--- a/Source/WebCore/inspector/InspectorOverlay.h >+++ b/Source/WebCore/inspector/InspectorOverlay.h >@@ -39,6 +39,7 @@ > #include <wtf/MonotonicTime.h> > #include <wtf/RefPtr.h> > #include <wtf/Vector.h> >+#include <wtf/WeakHashMap.h> > #include <wtf/WeakPtr.h> > #include <wtf/text/WTFString.h> > >@@ -146,6 +147,11 @@ public: > > Color color; > FloatQuad containerBounds; >+ Vector<FloatQuad> itemBounds; >+ Vector<FloatQuad> mainAxisGaps; >+ Vector<FloatQuad> mainAxisSpaceBetweenItemsAndGaps; >+ Vector<FloatQuad> spaceBetweenItemsAndCrossAxisSpace; >+ Vector<FloatQuad> crossAxisGaps; > > #if PLATFORM(IOS_FAMILY) > template<class Encoder> void encode(Encoder&) const; >@@ -303,6 +309,11 @@ template<class Encoder> void InspectorOverlay::Highlight::FlexHighlightOverlay:: > { > encoder << color; > encoder << containerBounds; >+ encoder << itemBounds; >+ encoder << mainAxisGaps; >+ encoder << mainAxisSpaceBetweenItemsAndGaps; >+ encoder << spaceBetweenItemsAndCrossAxisSpace; >+ encoder << crossAxisGaps; > } > > template<class Decoder> std::optional<InspectorOverlay::Highlight::FlexHighlightOverlay> InspectorOverlay::Highlight::FlexHighlightOverlay::decode(Decoder& decoder) >@@ -312,6 +323,16 @@ template<class Decoder> std::optional<InspectorOverlay::Highlight::FlexHighlight > return { }; > if (!decoder.decode(flexHighlightOverlay.containerBounds)) > return { }; >+ if (!decoder.decode(flexHighlightOverlay.itemBounds)) >+ return { }; >+ if (!decoder.decode(flexHighlightOverlay.mainAxisGaps)) >+ return { }; >+ if (!decoder.decode(flexHighlightOverlay.mainAxisSpaceBetweenItemsAndGaps)) >+ return { }; >+ if (!decoder.decode(flexHighlightOverlay.spaceBetweenItemsAndCrossAxisSpace)) >+ return { }; >+ if (!decoder.decode(flexHighlightOverlay.crossAxisGaps)) >+ return { }; > return { flexHighlightOverlay }; > } > >diff --git a/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp b/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp >index 0affc974e0e4a1764a4821b3994066c751919025..4735111adac014387125bc5f17c842e1d4d946f8 100644 >--- a/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp >+++ b/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp >@@ -95,6 +95,7 @@ > #include "Pasteboard.h" > #include "PseudoElement.h" > #include "RenderGrid.h" >+#include "RenderObject.h" > #include "RenderStyle.h" > #include "RenderStyleConstants.h" > #include "ScriptController.h" >@@ -307,6 +308,10 @@ void InspectorDOMAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, > m_instrumentingAgents.setPersistentDOMAgent(this); > m_document = m_inspectedPage.mainFrame().document(); > >+ // Force a layout so that we can collect additional information from the layout process. >+ if (m_document) >+ m_document->updateLayout(); >+ > #if ENABLE(VIDEO) > if (m_document) > addEventListenersToNode(*m_document); >@@ -329,6 +334,7 @@ void InspectorDOMAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReaso > hideHighlight(); > > m_overlay->clearAllGridOverlays(); >+ m_overlay->clearAllFlexOverlays(); > > m_instrumentingAgents.setPersistentDOMAgent(nullptr); > m_documentRequested = false; >@@ -356,6 +362,7 @@ void InspectorDOMAgent::reset() > if (m_revalidateStyleAttrTask) > m_revalidateStyleAttrTask->reset(); > m_document = nullptr; >+ m_flexibleBoxRendererCachedItemsAtStartOfLine.clear(); > > m_destroyedDetachedNodeIdentifiers.clear(); > m_destroyedAttachedNodeIdentifiers.clear(); >@@ -2790,6 +2797,23 @@ void InspectorDOMAgent::eventDidResetAfterDispatch(const Event& event) > m_dispatchedEvents.remove(&event); > } > >+void InspectorDOMAgent::flexibleBoxRendererBeganLayout(const RenderObject& renderer) >+{ >+ m_flexibleBoxRendererCachedItemsAtStartOfLine.remove(renderer); >+} >+ >+void InspectorDOMAgent::flexibleBoxRendererWrappedToNextLine(const RenderObject& renderer, size_t lineStartItemIndex) >+{ >+ m_flexibleBoxRendererCachedItemsAtStartOfLine.ensure(renderer, [] { >+ return Vector<size_t>(); >+ }).iterator->value.append(lineStartItemIndex); >+} >+ >+Vector<size_t> InspectorDOMAgent::flexibleBoxRendererCachedItemsAtStartOfLine(const RenderObject& renderer) >+{ >+ return m_flexibleBoxRendererCachedItemsAtStartOfLine.get(renderer); >+} >+ > RefPtr<JSC::Breakpoint> InspectorDOMAgent::breakpointForEventListener(EventTarget& target, const AtomString& eventType, EventListener& listener, bool capture) > { > for (auto& inspectorEventListener : m_eventListenerEntries.values()) { >diff --git a/Source/WebCore/inspector/agents/InspectorDOMAgent.h b/Source/WebCore/inspector/agents/InspectorDOMAgent.h >index c7e3c67601c58a0e23148985d2772d54f179ef8c..fd56c2afd7749f1b145cfe8cf0b5ad4fa653b8a9 100644 >--- a/Source/WebCore/inspector/agents/InspectorDOMAgent.h >+++ b/Source/WebCore/inspector/agents/InspectorDOMAgent.h >@@ -72,6 +72,7 @@ class HitTestResult; > class Node; > class Page; > class PseudoElement; >+class RenderObject; > class RevalidateStyleAttributeTask; > class ShadowRoot; > >@@ -182,6 +183,8 @@ public: > void willRemoveEventListener(EventTarget&, const AtomString& eventType, EventListener&, bool capture); > bool isEventListenerDisabled(EventTarget&, const AtomString& eventType, EventListener&, bool capture); > void eventDidResetAfterDispatch(const Event&); >+ void flexibleBoxRendererBeganLayout(const RenderObject&); >+ void flexibleBoxRendererWrappedToNextLine(const RenderObject&, size_t lineStartItemIndex); > > // Callbacks that don't directly correspond to an instrumentation entry point. > void setDocument(Document*); >@@ -205,6 +208,7 @@ public: > > InspectorHistory* history() { return m_history.get(); } > Vector<Document*> documents(); >+ Vector<size_t> flexibleBoxRendererCachedItemsAtStartOfLine(const RenderObject&); > void reset(); > > Node* assertNode(Inspector::Protocol::ErrorString&, Inspector::Protocol::DOM::NodeId); >@@ -269,6 +273,7 @@ private: > std::unique_ptr<InspectorOverlay::Highlight::Config> m_inspectModeHighlightConfig; > std::unique_ptr<InspectorHistory> m_history; > std::unique_ptr<DOMEditor> m_domEditor; >+ WeakHashMap<RenderObject, Vector<size_t>> m_flexibleBoxRendererCachedItemsAtStartOfLine; > > Vector<Inspector::Protocol::DOM::NodeId> m_destroyedDetachedNodeIdentifiers; > Vector<std::pair<Inspector::Protocol::DOM::NodeId, Inspector::Protocol::DOM::NodeId>> m_destroyedAttachedNodeIdentifiers; >diff --git a/Source/WebCore/platform/LayoutUnit.h b/Source/WebCore/platform/LayoutUnit.h >index 0c5240c49132c6be6e647be18eb2bcb4bd36490b..bc63b20d0591465f8a7363df3ce8fd9d75897e64 100644 >--- a/Source/WebCore/platform/LayoutUnit.h >+++ b/Source/WebCore/platform/LayoutUnit.h >@@ -378,6 +378,11 @@ inline bool operator!=(const LayoutUnit& a, const LayoutUnit& b) > return a.rawValue() != b.rawValue(); > } > >+inline bool operator!=(const float a, const LayoutUnit& b) >+{ >+ return LayoutUnit(a) != b; >+} >+ > inline bool operator!=(const LayoutUnit& a, float b) > { > return a != LayoutUnit(b); >diff --git a/Source/WebCore/rendering/RenderBox.h b/Source/WebCore/rendering/RenderBox.h >index 209c390da4379e1d7d47c1142c8a81a929f97934..9f2fd1e3ac641fddbc8fd79cf366aa88ee1d762f 100644 >--- a/Source/WebCore/rendering/RenderBox.h >+++ b/Source/WebCore/rendering/RenderBox.h >@@ -261,6 +261,7 @@ public: > virtual void setScrollTop(int, const ScrollPositionChangeOptions&); > void setScrollPosition(const ScrollPosition&, const ScrollPositionChangeOptions&); > >+ const LayoutBoxExtent& marginBox() const { return m_marginBox; } > LayoutUnit marginTop() const override { return m_marginBox.top(); } > LayoutUnit marginBottom() const override { return m_marginBox.bottom(); } > LayoutUnit marginLeft() const override { return m_marginBox.left(); } >diff --git a/Source/WebCore/rendering/RenderFlexibleBox.cpp b/Source/WebCore/rendering/RenderFlexibleBox.cpp >index a942f321980d58de0c3eb74da84a5be9ea26134f..a5b7c45e36e3e6539d8d1717e057ca4e5d7414c1 100644 >--- a/Source/WebCore/rendering/RenderFlexibleBox.cpp >+++ b/Source/WebCore/rendering/RenderFlexibleBox.cpp >@@ -1153,8 +1153,11 @@ void RenderFlexibleBox::layoutFlexItems(bool relayoutChildren) > Vector<FlexItem> lineItems; > size_t nextIndex = 0; > size_t numLines = 0; >+ InspectorInstrumentation::flexibleBoxRendererBeganLayout(*this); > while (flexAlgorithm.computeNextFlexLine(nextIndex, lineItems, sumFlexBaseSize, totalFlexGrow, totalFlexShrink, totalWeightedFlexShrink, sumHypotheticalMainSize)) { > ++numLines; >+ InspectorInstrumentation::flexibleBoxRendererWrappedToNextLine(*this, nextIndex); >+ > LayoutUnit containerMainInnerSize = mainAxisContentExtent(sumHypotheticalMainSize); > // availableFreeSpace is the initial amount of free space in this flexbox. > // remainingFreeSpace starts out at the same value but as we place and lay >diff --git a/Source/WebCore/rendering/RenderFlexibleBox.h b/Source/WebCore/rendering/RenderFlexibleBox.h >index cf1e0210d4a96e68e7118fdffae0a0a1e9ee8958..4b5552b1895d50e0dce192307967a3d41d7efece 100644 >--- a/Source/WebCore/rendering/RenderFlexibleBox.h >+++ b/Source/WebCore/rendering/RenderFlexibleBox.h >@@ -87,6 +87,9 @@ public: > // be laid out again. > bool setStaticPositionForPositionedLayout(const RenderBox&); > >+ enum class GapType { BetweenLines, BetweenItems }; >+ LayoutUnit computeGap(GapType) const; >+ > protected: > void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const override; > >@@ -205,9 +208,6 @@ private: > > void resetHasDefiniteHeight() { m_hasDefiniteHeight = SizeDefiniteness::Unknown; } > >- enum class GapType { BetweenLines, BetweenItems }; >- LayoutUnit computeGap(GapType) const; >- > // This is used to cache the preferred size for orthogonal flow children so we > // don't have to relayout to get it > HashMap<const RenderBox*, LayoutUnit> m_intrinsicSizeAlongMainAxis; >@@ -222,7 +222,7 @@ private: > // the first layout likely did not use the correct value for percentage > // sizing of children. > HashSet<const RenderBox*> m_relaidOutChildren; >- >+ > mutable OrderIterator m_orderIterator { *this }; > int m_numberOfInFlowChildrenOnFirstLine { -1 }; >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 236410
:
451451
|
451452
|
451593
|
451595
|
451631
| 451712