Diff
Modified: trunk/LayoutTests/ChangeLog (289415 => 289416)
--- trunk/LayoutTests/ChangeLog 2022-02-08 19:59:52 UTC (rev 289415)
+++ trunk/LayoutTests/ChangeLog 2022-02-08 20:25:39 UTC (rev 289416)
@@ -1,3 +1,17 @@
+2022-02-08 Razvan Caliman <rcali...@apple.com>
+
+ Web Inspector: [Flexbox] Add support for showing/hiding flex container overlays and basic overlay drawing
+ https://bugs.webkit.org/show_bug.cgi?id=236013
+ <rdar://87893201>
+
+ Reviewed by Patrick Angle.
+
+ * inspector/dom/showFlexOverlay-expected.txt: Added.
+ * inspector/dom/showFlexOverlay.html: Added.
+
+ * inspector/dom/showGridOverlay.html:
+ - Drive-by clean-up of out-of-context comments.
+
2022-02-08 Jon Lee <jon...@apple.com>
Unreviewed gardening.
Added: trunk/LayoutTests/inspector/dom/showFlexOverlay-expected.txt (0 => 289416)
--- trunk/LayoutTests/inspector/dom/showFlexOverlay-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/dom/showFlexOverlay-expected.txt 2022-02-08 20:25:39 UTC (rev 289416)
@@ -0,0 +1,51 @@
+Tests for the DOM.showFlexOverlay command.
+
+
+
+== Running test suite: DOM.showFlexOverlay
+-- Running test case: DOM.showFlexOverlay.ShowOneOverlay
+PASS: Should have 0 flex overlays displayed.
+Requesting to show flex overlay for first .flex-container
+PASS: Should have 1 flex overlay displayed.
+Requesting to show a different flex overlay for first .flex-container
+PASS: Should have 1 flex overlay displayed.
+Requesting to hide flex overlay
+PASS: Should have 0 flex overlays displayed.
+
+-- Running test case: DOM.showFlexOverlay.ShowTwoOverlays
+PASS: Should have 0 flex overlays displayed.
+Requesting to show first flex overlay
+PASS: Should have 1 flex overlay displayed.
+Requesting to show second flex overlay
+PASS: Should have 2 flex overlays displayed.
+Requesting to hide first flex overlay
+PASS: Should have 1 flex overlay displayed.
+Requesting to hide second flex overlay
+PASS: Should have 0 flex overlays displayed.
+
+-- Running test case: DOM.showFlexOverlay.HideAllOverlays
+PASS: Should have 0 flex overlays displayed.
+Requesting to show first flex overlay
+PASS: Should have 1 flex overlay displayed.
+Requesting to show second flex overlay
+PASS: Should have 2 flex overlays displayed.
+Requesting to hide all flex overlays.
+PASS: Should have 0 flex overlays displayed.
+Requesting to hide all flex overlays again, expecting none to be cleared. Hiding all flex overlays is idempotent and should not throw an error.
+PASS: Should have 0 flex overlays displayed.
+
+-- Running test case: DOM.showFlexOverlay.HideBeforeShowShouldError
+PASS: Should have 0 flex overlays displayed.
+Requesting to hide flex overlay for .flex-container
+PASS: Should produce an exception.
+Error: No flex overlay exists for the node, so cannot clear.
+Requesting to hide all flex overlays. Hiding all flex overlays is idempotent and should not throw an error.
+PASS: Should have 0 flex overlays displayed.
+
+-- Running test case: DOM.showFlexOverlay.ForNonexistentNodeShouldError
+PASS: Should have 0 flex overlays displayed.
+Requesting to show flex overlay for invalid nodeId -1
+PASS: Should produce an exception.
+Error: Missing node for given nodeId
+PASS: Should have 0 flex overlays displayed.
+
Added: trunk/LayoutTests/inspector/dom/showFlexOverlay.html (0 => 289416)
--- trunk/LayoutTests/inspector/dom/showFlexOverlay.html (rev 0)
+++ trunk/LayoutTests/inspector/dom/showFlexOverlay.html 2022-02-08 20:25:39 UTC (rev 289416)
@@ -0,0 +1,174 @@
+<!doctype html>
+<html>
+<head>
+<script src=""
+<script>
+function test()
+{
+ let suite = InspectorTest.createAsyncSuite("DOM.showFlexOverlay");
+
+ async function getFlexContainerNode() {
+ let doc = await WI.domManager.requestDocument();
+ let nodeId = await doc.querySelector(".flex-container");
+ return WI.domManager.nodeForId(nodeId);
+ }
+
+ async function getAllFlexContainerNodes() {
+ let doc = await WI.domManager.requestDocument();
+ let nodeIds = await doc.querySelectorAll(".flex-container");
+ return nodeIds.map((nodeId) => WI.domManager.nodeForId(nodeId));
+ }
+
+ async function FlexOverlayCount() {
+ return InspectorTest.evaluateInPage("window.internals.inspectorFlexOverlayCount()");
+ }
+
+ async function checkFlexOverlayCount(expected) {
+ let actual = await FlexOverlayCount();
+ let message;
+ switch (expected) {
+ case 1:
+ message = "Should have 1 flex overlay displayed.";
+ break;
+ default:
+ message = `Should have ${expected} flex overlays displayed.`;
+ break;
+ }
+
+ InspectorTest.expectEqual(actual, expected, message);
+ }
+
+ suite.addTestCase({
+ name: "DOM.showFlexOverlay.ShowOneOverlay",
+ description: "No error occurs when requesting to show a flex overlay.",
+ async test() {
+ await checkFlexOverlayCount(0);
+ let container = await getFlexContainerNode();
+
+ InspectorTest.log("Requesting to show flex overlay for first .flex-container");
+ await DOMAgent.showFlexOverlay(container.id, WI.Color.fromString("magenta").toProtocol());
+ await checkFlexOverlayCount(1);
+
+ // No error should occur if showing flex overlay for a node that already has one.
+ InspectorTest.log("Requesting to show a different flex overlay for first .flex-container");
+ await DOMAgent.showFlexOverlay(container.id, WI.Color.fromString("green").toProtocol());
+ await checkFlexOverlayCount(1);
+
+ // No error should occur when hiding the flex overlay.
+ InspectorTest.log("Requesting to hide flex overlay");
+ await DOMAgent.hideFlexOverlay(container.id);
+ await checkFlexOverlayCount(0);
+ }
+ });
+
+ suite.addTestCase({
+ name: "DOM.showFlexOverlay.ShowTwoOverlays",
+ description: "No error occurs when requesting to show multiple flex overlays.",
+ async test() {
+ await checkFlexOverlayCount(0);
+ let [first, second] = await getAllFlexContainerNodes();
+
+ InspectorTest.log("Requesting to show first flex overlay");
+ await DOMAgent.showFlexOverlay(first.id, WI.Color.fromString("magenta").toProtocol());
+ await checkFlexOverlayCount(1);
+
+ InspectorTest.log("Requesting to show second flex overlay");
+ await DOMAgent.showFlexOverlay(second.id, WI.Color.fromString("green").toProtocol());
+ await checkFlexOverlayCount(2);
+
+ // No error should occur when hiding the first flex overlay.
+ InspectorTest.log("Requesting to hide first flex overlay");
+ await DOMAgent.hideFlexOverlay(first.id);
+ await checkFlexOverlayCount(1);
+
+ // No error should occur when hiding the second flex overlay.
+ InspectorTest.log("Requesting to hide second flex overlay");
+ await DOMAgent.hideFlexOverlay(second.id);
+ await checkFlexOverlayCount(0);
+ }
+ });
+
+ suite.addTestCase({
+ name: "DOM.showFlexOverlay.HideAllOverlays",
+ description: "No error occurs when repeatedly requesting to hide all flex overlays.",
+ async test() {
+ await checkFlexOverlayCount(0);
+ let [first, second] = await getAllFlexContainerNodes();
+
+ InspectorTest.log("Requesting to show first flex overlay");
+ await DOMAgent.showFlexOverlay(first.id, WI.Color.fromString("magenta").toProtocol());
+ await checkFlexOverlayCount(1);
+
+ InspectorTest.log("Requesting to show second flex overlay");
+ await DOMAgent.showFlexOverlay(second.id, WI.Color.fromString("green").toProtocol());
+ await checkFlexOverlayCount(2);
+
+ // No error should occur when hiding all flex overlays.
+ InspectorTest.log("Requesting to hide all flex overlays.");
+ await DOMAgent.hideFlexOverlay();
+ await checkFlexOverlayCount(0);
+
+ // No error should occur when hiding all flex overlays.
+ InspectorTest.log("Requesting to hide all flex overlays again, expecting none to be cleared. Hiding all flex overlays is idempotent and should not throw an error.");
+ await DOMAgent.hideFlexOverlay();
+ await checkFlexOverlayCount(0);
+ }
+ });
+
+ suite.addTestCase({
+ name: "DOM.showFlexOverlay.HideBeforeShowShouldError",
+ description: "Return an error when requesting to hide a flex overlay when none is active for the node.",
+ async test() {
+ let container = await getFlexContainerNode();
+
+ await checkFlexOverlayCount(0);
+
+ InspectorTest.log("Requesting to hide flex overlay for .flex-container");
+ await InspectorTest.expectException(async () => {
+ await DOMAgent.hideFlexOverlay(container.id);
+ });
+
+ InspectorTest.log("Requesting to hide all flex overlays. Hiding all flex overlays is idempotent and should not throw an error.");
+ await DOMAgent.hideFlexOverlay();
+ await checkFlexOverlayCount(0);
+ }
+ });
+
+ suite.addTestCase({
+ name: "DOM.showFlexOverlay.ForNonexistentNodeShouldError",
+ description: "Return an error when requesting to show a flex overlay for a nonexistent node.",
+ async test() {
+ await checkFlexOverlayCount(0);
+
+ InspectorTest.log("Requesting to show flex overlay for invalid nodeId -1");
+ await InspectorTest.expectException(async () => {
+ await DOMAgent.showFlexOverlay(-1, WI.Color.fromString("magenta").toProtocol());
+ });
+
+ await checkFlexOverlayCount(0);
+ }
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+ <style>
+ body {
+ margin: 100px;
+ }
+ .flex-container {
+ display: flex;
+ padding: 10px;
+ background-color: lightgray;
+ }
+
+ </style>
+
+ <p>Tests for the DOM.showFlexOverlay command.</p>
+ <div class="flex-container"></div>
+ <br />
+ <div class="flex-container"></div>
+</body>
+</html>
Modified: trunk/LayoutTests/inspector/dom/showGridOverlay.html (289415 => 289416)
--- trunk/LayoutTests/inspector/dom/showGridOverlay.html 2022-02-08 19:59:52 UTC (rev 289415)
+++ trunk/LayoutTests/inspector/dom/showGridOverlay.html 2022-02-08 20:25:39 UTC (rev 289416)
@@ -72,7 +72,6 @@
await DOMAgent.showGridOverlay(first.id, WI.Color.fromString("magenta").toProtocol());
await checkGridOverlayCount(1);
- // No error should occur if showing grid overlay for a node that already has one.
InspectorTest.log("Requesting to show second grid overlay");
await DOMAgent.showGridOverlay(second.id, WI.Color.fromString("green").toProtocol());
await checkGridOverlayCount(2);
@@ -100,7 +99,6 @@
await DOMAgent.showGridOverlay(first.id, WI.Color.fromString("magenta").toProtocol());
await checkGridOverlayCount(1);
- // No error should occur if showing grid overlay for a node that already has one.
InspectorTest.log("Requesting to show a different grid overlay");
await DOMAgent.showGridOverlay(second.id, WI.Color.fromString("green").toProtocol());
await checkGridOverlayCount(2);
Modified: trunk/Source/_javascript_Core/ChangeLog (289415 => 289416)
--- trunk/Source/_javascript_Core/ChangeLog 2022-02-08 19:59:52 UTC (rev 289415)
+++ trunk/Source/_javascript_Core/ChangeLog 2022-02-08 20:25:39 UTC (rev 289416)
@@ -1,3 +1,15 @@
+2022-02-08 Razvan Caliman <rcali...@apple.com>
+
+ Web Inspector: [Flexbox] Add support for showing/hiding flex container overlays and basic overlay drawing
+ https://bugs.webkit.org/show_bug.cgi?id=236013
+ <rdar://87893201>
+
+ Reviewed by Patrick Angle.
+
+ Add new commands to show and hide flex overlays.
+
+ * inspector/protocol/DOM.json:
+
2022-02-07 Yusuke Suzuki <ysuz...@apple.com>
[JSC] Convert JSString's non-atomic WTF::String to atomic string while concurrent compilers / heap threads run
Modified: trunk/Source/_javascript_Core/inspector/protocol/DOM.json (289415 => 289416)
--- trunk/Source/_javascript_Core/inspector/protocol/DOM.json 2022-02-08 19:59:52 UTC (rev 289415)
+++ trunk/Source/_javascript_Core/inspector/protocol/DOM.json 2022-02-08 20:25:39 UTC (rev 289416)
@@ -526,6 +526,23 @@
]
},
{
+ "name": "showFlexOverlay",
+ "description": "Shows a flex overlay for a node that begins a 'flex' layout context. The command has no effect if <code>nodeId</code> is invalid or the associated node does not begin a 'flex' layout context. A node can only have one flex overlay at a time; subsequent calls with the same <code>nodeId</code> will override earlier calls.",
+ "targetTypes": ["page"],
+ "parameters": [
+ { "name": "nodeId", "$ref": "NodeId", "description": "The node for which a flex overlay should be shown." },
+ { "name": "flexColor", "$ref": "RGBAColor", "description": "The primary color to use for the flex overlay." }
+ ]
+ },
+ {
+ "name": "hideFlexOverlay",
+ "description": "Hides a flex overlay for a node that begins a 'flex' layout context. The command has no effect if <code>nodeId</code> is specified and invalid, or if there is not currently an overlay set for the <code>nodeId</code>.",
+ "targetTypes": ["page"],
+ "parameters": [
+ { "name": "nodeId", "$ref": "NodeId", "optional": true, "description": "The node for which a flex overlay should be hidden. If a <code>nodeId</code> is not specified, all flex overlays will be hidden." }
+ ]
+ },
+ {
"name": "pushNodeByPathToFrontend",
"description": "Requests that the node is sent to the caller given its path.",
"targetTypes": ["page"],
Modified: trunk/Source/WebCore/ChangeLog (289415 => 289416)
--- trunk/Source/WebCore/ChangeLog 2022-02-08 19:59:52 UTC (rev 289415)
+++ trunk/Source/WebCore/ChangeLog 2022-02-08 20:25:39 UTC (rev 289416)
@@ -1,3 +1,56 @@
+2022-02-08 Razvan Caliman <rcali...@apple.com>
+
+ Web Inspector: [Flexbox] Add support for showing/hiding flex container overlays and basic overlay drawing
+ https://bugs.webkit.org/show_bug.cgi?id=236013
+ <rdar://87893201>
+
+ Reviewed by Patrick Angle.
+
+ Test: inspector/dom/showFlexOverlay.html
+ - The test follows the example for checking grid overlays at inspector/dom/showGridOverlay.html
+
+ Implement backend commands to toggle the visibility of a specialized page overlay shown on top of a flex container.
+ At this stage, the overlay consists of an outline around the bounding box of the flex container.
+ Future patches will add more detail regarding flex items and gaps between them.
+
+ This patch follows closely the example for toggling the visibility of CSS Grid overlays implemented in
+ https://bugs.webkit.org/show_bug.cgi?id=221062
+
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorController::flexOverlayCount const):
+ * inspector/InspectorController.h:
+ * inspector/InspectorOverlay.cpp:
+ (WebCore::InspectorOverlay::paint):
+ (WebCore::InspectorOverlay::getHighlight):
+ (WebCore::InspectorOverlay::shouldShowOverlay const):
+ (WebCore::InspectorOverlay::removeFlexOverlayForNode):
+
+ (WebCore::InspectorOverlay::setFlexOverlayForNode):
+ (WebCore::InspectorOverlay::clearFlexOverlayForNode):
+ (WebCore::InspectorOverlay::clearAllFlexOverlays):
+ - Maintain a list of active flex overlays. A node can have only one flex overlay at a time.
+
+ (WebCore::InspectorOverlay::drawFlexOverlay):
+ (WebCore::InspectorOverlay::buildFlexOverlay):
+ * inspector/InspectorOverlay.h:
+ (WebCore::InspectorOverlay::flexOverlayCount const):
+ (WebCore::InspectorOverlay::Highlight::FlexHighlightOverlay::encode const):
+ (WebCore::InspectorOverlay::Highlight::FlexHighlightOverlay::decode):
+ - The signature of the flex overlay includes the color for the outline and a quad expressing the bounding box of the flex container.
+
+ * inspector/agents/InspectorDOMAgent.cpp:
+ (WebCore::InspectorDOMAgent::showFlexOverlay):
+ (WebCore::InspectorDOMAgent::hideFlexOverlay):
+ - Translate protocol commands into InspectorOverlay method calls.
+
+ * inspector/agents/InspectorDOMAgent.h:
+
+ * testing/Internals.cpp:
+ (WebCore::Internals::inspectorFlexOverlayCount):
+ * testing/Internals.h:
+ * testing/Internals.idl:
+ - Helper used in testing to check the number of shown flex overlays.
+
2022-02-08 Cameron McCormack <hey...@apple.com>
Make HTMLToken::beginStartTag tag an 8 bit character
Modified: trunk/Source/WebCore/inspector/InspectorController.cpp (289415 => 289416)
--- trunk/Source/WebCore/inspector/InspectorController.cpp 2022-02-08 19:59:52 UTC (rev 289415)
+++ trunk/Source/WebCore/inspector/InspectorController.cpp 2022-02-08 20:25:39 UTC (rev 289416)
@@ -369,6 +369,11 @@
return m_overlay->gridOverlayCount();
}
+unsigned InspectorController::flexOverlayCount() const
+{
+ return m_overlay->flexOverlayCount();
+}
+
unsigned InspectorController::paintRectCount() const
{
if (m_inspectorClient->overridesShowPaintRects())
Modified: trunk/Source/WebCore/inspector/InspectorController.h (289415 => 289416)
--- trunk/Source/WebCore/inspector/InspectorController.h 2022-02-08 19:59:52 UTC (rev 289415)
+++ trunk/Source/WebCore/inspector/InspectorController.h 2022-02-08 20:25:39 UTC (rev 289416)
@@ -106,6 +106,7 @@
void setIsUnderTest(bool isUnderTest) { m_isUnderTest = isUnderTest; }
WEBCORE_EXPORT void evaluateForTestInFrontend(const String& script);
WEBCORE_EXPORT unsigned gridOverlayCount() const;
+ WEBCORE_EXPORT unsigned flexOverlayCount() const;
WEBCORE_EXPORT unsigned paintRectCount() const;
InspectorClient* inspectorClient() const { return m_inspectorClient; }
Modified: trunk/Source/WebCore/inspector/InspectorOverlay.cpp (289415 => 289416)
--- trunk/Source/WebCore/inspector/InspectorOverlay.cpp 2022-02-08 19:59:52 UTC (rev 289415)
+++ trunk/Source/WebCore/inspector/InspectorOverlay.cpp 2022-02-08 20:25:39 UTC (rev 289416)
@@ -61,6 +61,7 @@
#include "PseudoElement.h"
#include "RenderBox.h"
#include "RenderBoxModelObject.h"
+#include "RenderFlexibleBox.h"
#include "RenderGrid.h"
#include "RenderInline.h"
#include "RenderObject.h"
@@ -437,6 +438,11 @@
drawGridOverlay(context, *gridHighlightOverlay);
}
+ for (const InspectorOverlay::Flex& flexOverlay : m_activeFlexOverlays) {
+ if (auto flexHighlightOverlay = buildFlexOverlay(flexOverlay))
+ drawFlexOverlay(context, *flexHighlightOverlay);
+ }
+
if (!m_paintRects.isEmpty())
drawPaintRects(context, m_paintRects);
@@ -446,7 +452,7 @@
void InspectorOverlay::getHighlight(InspectorOverlay::Highlight& highlight, InspectorOverlay::CoordinateSystem coordinateSystem)
{
- if (!m_highlightNode && !m_highlightQuad && !m_highlightNodeList && !m_activeGridOverlays.size())
+ if (!m_highlightNode && !m_highlightQuad && !m_highlightNodeList && !m_activeGridOverlays.size() && !m_activeFlexOverlays.size())
return;
highlight.type = InspectorOverlay::Highlight::Type::None;
@@ -470,6 +476,11 @@
if (auto gridHighlightOverlay = buildGridOverlay(gridOverlay, offsetBoundsByScroll))
highlight.gridHighlightOverlays.append(*gridHighlightOverlay);
}
+
+ for (const InspectorOverlay::Flex& flexOverlay : m_activeFlexOverlays) {
+ if (auto flexHighlightOverlay = buildFlexOverlay(flexOverlay))
+ highlight.flexHighlightOverlays.append(*flexHighlightOverlay);
+ }
}
void InspectorOverlay::hideHighlight()
@@ -530,7 +541,7 @@
{
// Don't show the overlay when m_showRulersDuringElementSelection is true, as it's only supposed
// to have an effect when element selection is active (e.g. a node is hovered).
- return m_highlightNode || m_highlightNodeList || m_highlightQuad || m_indicating || m_showPaintRects || m_showRulers || m_activeGridOverlays.size();
+ return m_highlightNode || m_highlightNodeList || m_highlightQuad || m_indicating || m_showPaintRects || m_showRulers || m_activeGridOverlays.size() || m_activeFlexOverlays.size();
}
void InspectorOverlay::update()
@@ -630,6 +641,45 @@
update();
}
+bool InspectorOverlay::removeFlexOverlayForNode(Node& node)
+{
+ // Try to remove `node`. Also clear any grid overlays whose WeakPtr<Node> has been cleared.
+ return m_activeFlexOverlays.removeAllMatching([&] (const InspectorOverlay::Flex& flexOverlay) {
+ return !flexOverlay.flexNode || flexOverlay.flexNode.get() == &node;
+ });
+}
+
+ErrorStringOr<void> InspectorOverlay::setFlexOverlayForNode(Node& node, const InspectorOverlay::Flex::Config& flexOverlayConfig)
+{
+ if (!is<RenderFlexibleBox>(node.renderer()))
+ return makeUnexpected("Node does not initiate a flex context");
+
+ removeFlexOverlayForNode(node);
+
+ m_activeFlexOverlays.append({ node, flexOverlayConfig });
+
+ update();
+
+ return { };
+}
+
+ErrorStringOr<void> InspectorOverlay::clearFlexOverlayForNode(Node& node)
+{
+ if (!removeFlexOverlayForNode(node))
+ return makeUnexpected("No flex overlay exists for the node, so cannot clear.");
+
+ update();
+
+ return { };
+}
+
+void InspectorOverlay::clearAllFlexOverlays()
+{
+ m_activeFlexOverlays.clear();
+
+ update();
+}
+
void InspectorOverlay::updatePaintRectsTimerFired()
{
MonotonicTime now = MonotonicTime::now();
@@ -1937,4 +1987,54 @@
return { gridHighlightOverlay };
}
+void InspectorOverlay::drawFlexOverlay(GraphicsContext& context, const InspectorOverlay::Highlight::FlexHighlightOverlay& flexHighlightOverlay)
+{
+ GraphicsContextStateSaver saver(context);
+ context.setStrokeThickness(1);
+ context.setStrokeColor(flexHighlightOverlay.color);
+ context.strokePath(quadToPath(flexHighlightOverlay.containerBounds));
+}
+
+std::optional<InspectorOverlay::Highlight::FlexHighlightOverlay> InspectorOverlay::buildFlexOverlay(const InspectorOverlay::Flex& flexOverlay)
+{
+ // If the node WeakPtr has been cleared, then the node is gone and there's nothing to draw.
+ if (!flexOverlay.flexNode) {
+ m_activeFlexOverlays.removeAllMatching([&] (const InspectorOverlay::Flex& flexOverlay) {
+ return !flexOverlay.flexNode;
+ });
+ return { };
+ }
+
+ // Always re-check because the node's renderer may have changed since being added.
+ // If renderer is no longer a flex, then remove the flex overlay for the node.
+ Node* node = flexOverlay.flexNode.get();
+ auto renderer = node->renderer();
+ if (!is<RenderFlexibleBox>(renderer)) {
+ removeFlexOverlayForNode(*node);
+ return { };
+ }
+
+ auto& renderFlex = *downcast<RenderFlexibleBox>(renderer);
+
+ Frame* containingFrame = node->document().frame();
+ if (!containingFrame)
+ return { };
+ FrameView* containingView = containingFrame->view();
+
+ auto localQuadToRootQuad = [&](const FloatQuad& quad) -> FloatQuad {
+ return {
+ localPointToRootPoint(containingView, quad.p1()),
+ localPointToRootPoint(containingView, quad.p2()),
+ localPointToRootPoint(containingView, quad.p3()),
+ localPointToRootPoint(containingView, quad.p4())
+ };
+ };
+
+ InspectorOverlay::Highlight::FlexHighlightOverlay flexHighlightOverlay;
+ flexHighlightOverlay.color = flexOverlay.config.flexColor;
+ flexHighlightOverlay.containerBounds = localQuadToRootQuad({ renderFlex.absoluteContentQuad() });
+
+ return { flexHighlightOverlay };
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/inspector/InspectorOverlay.h (289415 => 289416)
--- trunk/Source/WebCore/inspector/InspectorOverlay.h 2022-02-08 19:59:52 UTC (rev 289415)
+++ trunk/Source/WebCore/inspector/InspectorOverlay.h 2022-02-08 20:25:39 UTC (rev 289416)
@@ -141,6 +141,18 @@
#endif
};
+ struct FlexHighlightOverlay {
+ WTF_MAKE_STRUCT_FAST_ALLOCATED;
+
+ Color color;
+ FloatQuad containerBounds;
+
+#if PLATFORM(IOS_FAMILY)
+ template<class Encoder> void encode(Encoder&) const;
+ template<class Decoder> static std::optional<InspectorOverlay::Highlight::FlexHighlightOverlay> decode(Decoder&);
+#endif
+ };
+
void setDataFromConfig(const Config& config)
{
contentColor = config.content;
@@ -160,6 +172,7 @@
Type type {Type::Node};
Vector<FloatQuad> quads;
Vector<GridHighlightOverlay> gridHighlightOverlays;
+ Vector<FlexHighlightOverlay> flexHighlightOverlays;
bool usePageCoordinates {true};
using Bounds = FloatRect;
@@ -183,6 +196,19 @@
Config config;
};
+ struct Flex {
+ WTF_MAKE_STRUCT_FAST_ALLOCATED;
+
+ struct Config {
+ WTF_MAKE_STRUCT_FAST_ALLOCATED;
+
+ Color flexColor;
+ };
+
+ WeakPtr<Node> flexNode;
+ Config config;
+ };
+
enum class CoordinateSystem {
View, // Adjusts for the main frame's scroll offset.
Document, // Does not adjust for the main frame's scroll offset.
@@ -207,18 +233,24 @@
Node* highlightedNode() const;
unsigned gridOverlayCount() const { return m_activeGridOverlays.size(); }
+ unsigned flexOverlayCount() const { return m_activeFlexOverlays.size(); }
void didSetSearchingForNode(bool enabled);
void setIndicating(bool indicating);
- // Multiple grid overlays can be active at the same time. These methods
+ // Multiple grid and flex overlays can be active at the same time. These methods
// will fail if the node is not a grid or if the node has been GC'd.
Inspector::ErrorStringOr<void> setGridOverlayForNode(Node&, const InspectorOverlay::Grid::Config&);
Inspector::ErrorStringOr<void> clearGridOverlayForNode(Node&);
void clearAllGridOverlays();
+ Inspector::ErrorStringOr<void> setFlexOverlayForNode(Node&, const InspectorOverlay::Flex::Config&);
+ Inspector::ErrorStringOr<void> clearFlexOverlayForNode(Node&);
+ void clearAllFlexOverlays();
+
WEBCORE_EXPORT static void drawGridOverlay(GraphicsContext&, const InspectorOverlay::Highlight::GridHighlightOverlay&);
+ WEBCORE_EXPORT static void drawFlexOverlay(GraphicsContext&, const InspectorOverlay::Highlight::FlexHighlightOverlay&);
private:
using TimeRectPair = std::pair<MonotonicTime, FloatRect>;
@@ -236,10 +268,12 @@
Path drawElementTitle(GraphicsContext&, Node&, const Highlight::Bounds&);
std::optional<InspectorOverlay::Highlight::GridHighlightOverlay> buildGridOverlay(const InspectorOverlay::Grid&, bool offsetBoundsByScroll = false);
+ std::optional<InspectorOverlay::Highlight::FlexHighlightOverlay> buildFlexOverlay(const InspectorOverlay::Flex&);
void updatePaintRectsTimerFired();
bool removeGridOverlayForNode(Node&);
+ bool removeFlexOverlayForNode(Node&);
Page& m_page;
InspectorClient* m_client;
@@ -255,6 +289,7 @@
Timer m_paintRectUpdateTimer;
Vector<InspectorOverlay::Grid> m_activeGridOverlays;
+ Vector<InspectorOverlay::Flex> m_activeFlexOverlays;
bool m_indicating { false };
bool m_showPaintRects { false };
@@ -264,6 +299,22 @@
#if PLATFORM(IOS_FAMILY)
+template<class Encoder> void InspectorOverlay::Highlight::FlexHighlightOverlay::encode(Encoder& encoder) const
+{
+ encoder << color;
+ encoder << containerBounds;
+}
+
+template<class Decoder> std::optional<InspectorOverlay::Highlight::FlexHighlightOverlay> InspectorOverlay::Highlight::FlexHighlightOverlay::decode(Decoder& decoder)
+{
+ InspectorOverlay::Highlight::FlexHighlightOverlay flexHighlightOverlay;
+ if (!decoder.decode(flexHighlightOverlay.color))
+ return { };
+ if (!decoder.decode(flexHighlightOverlay.containerBounds))
+ return { };
+ return { flexHighlightOverlay };
+}
+
template<class Encoder> void InspectorOverlay::Highlight::GridHighlightOverlay::encode(Encoder& encoder) const
{
encoder << color;
Modified: trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp (289415 => 289416)
--- trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp 2022-02-08 19:59:52 UTC (rev 289415)
+++ trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp 2022-02-08 20:25:39 UTC (rev 289416)
@@ -1542,6 +1542,41 @@
return { };
}
+Inspector::Protocol::ErrorStringOr<void> InspectorDOMAgent::showFlexOverlay(Inspector::Protocol::DOM::NodeId nodeId, Ref<JSON::Object>&& flexColor)
+{
+ Protocol::ErrorString errorString;
+ Node* node = assertNode(errorString, nodeId);
+ if (!node)
+ return makeUnexpected(errorString);
+
+ auto parsedColor = parseColor(WTFMove(flexColor));
+ if (!parsedColor)
+ return makeUnexpected("Invalid color could not be parsed.");
+
+ InspectorOverlay::Flex::Config config;
+ config.flexColor = *parsedColor;
+
+ m_overlay->setFlexOverlayForNode(*node, config);
+
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorDOMAgent::hideFlexOverlay(std::optional<Protocol::DOM::NodeId>&& nodeId)
+{
+ if (nodeId) {
+ Protocol::ErrorString errorString;
+ auto node = assertNode(errorString, *nodeId);
+ if (!node)
+ return makeUnexpected(errorString);
+
+ return m_overlay->clearFlexOverlayForNode(*node);
+ }
+
+ m_overlay->clearAllFlexOverlays();
+
+ return { };
+}
+
Protocol::ErrorStringOr<Protocol::DOM::NodeId> InspectorDOMAgent::moveTo(Protocol::DOM::NodeId nodeId, Protocol::DOM::NodeId targetNodeId, std::optional<Protocol::DOM::NodeId>&& insertBeforeNodeId)
{
Protocol::ErrorString errorString;
Modified: trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.h (289415 => 289416)
--- trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.h 2022-02-08 19:59:52 UTC (rev 289415)
+++ trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.h 2022-02-08 20:25:39 UTC (rev 289416)
@@ -149,6 +149,8 @@
Inspector::Protocol::ErrorStringOr<void> highlightFrame(const Inspector::Protocol::Network::FrameId&, RefPtr<JSON::Object>&& color, RefPtr<JSON::Object>&& outlineColor);
Inspector::Protocol::ErrorStringOr<void> showGridOverlay(Inspector::Protocol::DOM::NodeId, Ref<JSON::Object>&& gridColor, std::optional<bool>&& showLineNames, std::optional<bool>&& showLineNumbers, std::optional<bool>&& showExtendedGridLines, std::optional<bool>&& showTrackSizes, std::optional<bool>&& showAreaNames);
Inspector::Protocol::ErrorStringOr<void> hideGridOverlay(std::optional<Inspector::Protocol::DOM::NodeId>&&);
+ Inspector::Protocol::ErrorStringOr<void> showFlexOverlay(Inspector::Protocol::DOM::NodeId, Ref<JSON::Object>&& flexColor);
+ Inspector::Protocol::ErrorStringOr<void> hideFlexOverlay(std::optional<Inspector::Protocol::DOM::NodeId>&&);
Inspector::Protocol::ErrorStringOr<Inspector::Protocol::DOM::NodeId> moveTo(Inspector::Protocol::DOM::NodeId nodeId, Inspector::Protocol::DOM::NodeId targetNodeId, std::optional<Inspector::Protocol::DOM::NodeId>&& insertBeforeNodeId);
Inspector::Protocol::ErrorStringOr<void> undo();
Inspector::Protocol::ErrorStringOr<void> redo();
Modified: trunk/Source/WebCore/testing/Internals.cpp (289415 => 289416)
--- trunk/Source/WebCore/testing/Internals.cpp 2022-02-08 19:59:52 UTC (rev 289415)
+++ trunk/Source/WebCore/testing/Internals.cpp 2022-02-08 20:25:39 UTC (rev 289416)
@@ -1763,6 +1763,15 @@
return document->page()->inspectorController().gridOverlayCount();
}
+ExceptionOr<unsigned> Internals::inspectorFlexOverlayCount()
+{
+ Document* document = contextDocument();
+ if (!document || !document->page())
+ return Exception { InvalidAccessError };
+
+ return document->page()->inspectorController().flexOverlayCount();
+}
+
ExceptionOr<Ref<DOMRectList>> Internals::inspectorHighlightRects()
{
Document* document = contextDocument();
Modified: trunk/Source/WebCore/testing/Internals.h (289415 => 289416)
--- trunk/Source/WebCore/testing/Internals.h 2022-02-08 19:59:52 UTC (rev 289415)
+++ trunk/Source/WebCore/testing/Internals.h 2022-02-08 20:25:39 UTC (rev 289416)
@@ -294,6 +294,7 @@
ExceptionOr<Ref<DOMRectList>> inspectorHighlightRects();
ExceptionOr<unsigned> inspectorGridOverlayCount();
+ ExceptionOr<unsigned> inspectorFlexOverlayCount();
ExceptionOr<unsigned> inspectorPaintRectCount();
ExceptionOr<unsigned> markerCountForNode(Node&, const String&);
Modified: trunk/Source/WebCore/testing/Internals.idl (289415 => 289416)
--- trunk/Source/WebCore/testing/Internals.idl 2022-02-08 19:59:52 UTC (rev 289415)
+++ trunk/Source/WebCore/testing/Internals.idl 2022-02-08 20:25:39 UTC (rev 289416)
@@ -406,6 +406,7 @@
DOMRect boundingBox(Element element);
unsigned long inspectorGridOverlayCount();
+ unsigned long inspectorFlexOverlayCount();
DOMRectList inspectorHighlightRects();
unsigned long inspectorPaintRectCount();
Modified: trunk/Source/WebKit/ChangeLog (289415 => 289416)
--- trunk/Source/WebKit/ChangeLog 2022-02-08 19:59:52 UTC (rev 289415)
+++ trunk/Source/WebKit/ChangeLog 2022-02-08 20:25:39 UTC (rev 289416)
@@ -1,3 +1,19 @@
+2022-02-08 Razvan Caliman <rcali...@apple.com>
+
+ Web Inspector: [Flexbox] Add support for showing/hiding flex container overlays and basic overlay drawing
+ https://bugs.webkit.org/show_bug.cgi?id=236013
+ <rdar://87893201>
+
+ Reviewed by Patrick Angle.
+
+ Add basic logic to draw a flex overlay on top of a flex container on iOS/iPadOS. Used by Web Inspector.
+
+ * Shared/WebCoreArgumentCoders.cpp:
+ (IPC::ArgumentCoder<InspectorOverlay::Highlight>::encode):
+ (IPC::ArgumentCoder<InspectorOverlay::Highlight>::decode):
+ * UIProcess/Inspector/ios/WKInspectorHighlightView.mm:
+ (-[WKInspectorHighlightView drawRect:]):
+
2022-02-08 Youenn Fablet <you...@apple.com>
LibWebRTCCodecs SharedVideoFrameWriters can deadlock in case of GPUProcess crash
Modified: trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp (289415 => 289416)
--- trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp 2022-02-08 19:59:52 UTC (rev 289415)
+++ trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp 2022-02-08 20:25:39 UTC (rev 289416)
@@ -1680,6 +1680,7 @@
encoder << highlight.marginColor;
encoder << highlight.quads;
encoder << highlight.gridHighlightOverlays;
+ encoder << highlight.flexHighlightOverlays;
}
bool ArgumentCoder<InspectorOverlay::Highlight>::decode(Decoder& decoder, InspectorOverlay::Highlight& highlight)
@@ -1705,6 +1706,8 @@
return false;
if (!decoder.decode(highlight.gridHighlightOverlays))
return false;
+ if (!decoder.decode(highlight.flexHighlightOverlays))
+ return false;
return true;
}
Modified: trunk/Source/WebKit/UIProcess/Inspector/ios/WKInspectorHighlightView.mm (289415 => 289416)
--- trunk/Source/WebKit/UIProcess/Inspector/ios/WKInspectorHighlightView.mm 2022-02-08 19:59:52 UTC (rev 289415)
+++ trunk/Source/WebKit/UIProcess/Inspector/ios/WKInspectorHighlightView.mm 2022-02-08 20:25:39 UTC (rev 289416)
@@ -277,6 +277,9 @@
for (auto gridHighlightOverlay : _highlight->gridHighlightOverlays)
WebCore::InspectorOverlay::drawGridOverlay(context, gridHighlightOverlay);
+
+ for (auto flexHighlightOverlay : _highlight->flexHighlightOverlays)
+ WebCore::InspectorOverlay::drawFlexOverlay(context, flexHighlightOverlay);
}
- (void)update:(const WebCore::InspectorOverlay::Highlight&)highlight scale:(double)scale frame:(const WebCore::FloatRect&)frame