Diff
Modified: trunk/LayoutTests/ChangeLog (272196 => 272197)
--- trunk/LayoutTests/ChangeLog 2021-02-02 08:52:42 UTC (rev 272196)
+++ trunk/LayoutTests/ChangeLog 2021-02-02 09:02:31 UTC (rev 272197)
@@ -1,3 +1,25 @@
+2021-02-02 BJ Burg <[email protected]>
+
+ Web Inspector: implement the basics for showing/hiding grid overlays
+ https://bugs.webkit.org/show_bug.cgi?id=221062
+
+ Reviewed by Devin Rousso.
+
+ * inspector/dom/showGridOverlay-expected.txt: Added.
+ * inspector/dom/showGridOverlay.html: Added.
+ This test does not cover the actual drawing code. The drawing method
+ will change a lot and is not easy to test currently. The new test
+ covers the behavior of showGridOverlay/hideGridOverlay by querying
+ how many grid overlays are active according to InspectorOverlay.
+
+ * inspector/model/color-expected.txt:
+ * inspector/model/color.html:
+ Add a test case to exercise WI.Color.prototype.toProtocol().
+
+ * inspector/unit-tests/test-harness-expect-functions-async-expected.txt:
+ Rebaseline results after adding more state dumping in the failure case
+ for InspectorTest.expectException().
+
2021-02-01 Lauro Moura <[email protected]>
[GLIB] Gardening crashes common to both glib ports
Added: trunk/LayoutTests/inspector/dom/showGridOverlay-expected.txt (0 => 272197)
--- trunk/LayoutTests/inspector/dom/showGridOverlay-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/dom/showGridOverlay-expected.txt 2021-02-02 09:02:31 UTC (rev 272197)
@@ -0,0 +1,63 @@
+Tests for the DOM.showGridOverlay command.
+
+A
+B
+C
+D
+E
+F
+
+A
+B
+C
+D
+E
+F
+
+== Running test suite: DOM.showGridOverlay
+-- Running test case: DOM.showGridOverlay.ShowOneGrid
+PASS: Should have 0 grids displayed.
+Requesting to show grid overlay for first .grid-container
+PASS: Should have 1 grid displayed.
+Requesting to show a different grid overlay for first .grid-container
+PASS: Should have 1 grid displayed.
+Requesting to hide grid overlay
+PASS: Should have 0 grids displayed.
+
+-- Running test case: DOM.showGridOverlay.ShowTwoGrids
+PASS: Should have 0 grids displayed.
+Requesting to show first grid overlay
+PASS: Should have 1 grid displayed.
+Requesting to show second grid overlay
+PASS: Should have 2 grids displayed.
+Requesting to hide first grid overlay
+PASS: Should have 1 grid displayed.
+Requesting to hide second grid overlay
+PASS: Should have 0 grids displayed.
+
+-- Running test case: DOM.showGridOverlay.HideAllGrids
+PASS: Should have 0 grids displayed.
+Requesting to show grid overlay
+PASS: Should have 1 grid displayed.
+Requesting to show a different grid overlay
+PASS: Should have 2 grids displayed.
+Requesting to hide all grid overlays. Hiding all grids is idempotent and should not throw an error.
+PASS: Should have 0 grids displayed.
+Requesting to hide all grid overlays again, expecting none to be cleared. Hiding all grids is idempotent and should not throw an error.
+PASS: Should have 0 grids displayed.
+
+-- Running test case: DOM.showGridOverlay.HideBeforeShowShouldError
+PASS: Should have 0 grids displayed.
+Requesting to hide grid overlay for .grid-container
+PASS: Should produce an exception.
+Error: No grid overlay exists for the node, so cannot clear.
+Requesting to hide all grid overlays. Hiding all grids is idempotent and should not throw an error.
+PASS: Should have 0 grids displayed.
+
+-- Running test case: DOM.showGridOverlay.ForNonexistentNodeShouldError
+PASS: Should have 0 grids displayed.
+Requesting to show grid overlay for invalid nodeId -1
+PASS: Should produce an exception.
+Error: Missing node for given nodeId
+PASS: Should have 0 grids displayed.
+
Added: trunk/LayoutTests/inspector/dom/showGridOverlay.html (0 => 272197)
--- trunk/LayoutTests/inspector/dom/showGridOverlay.html (rev 0)
+++ trunk/LayoutTests/inspector/dom/showGridOverlay.html 2021-02-02 09:02:31 UTC (rev 272197)
@@ -0,0 +1,199 @@
+<!doctype html>
+<html>
+<head>
+<script src=""
+<script>
+function test()
+{
+ let suite = InspectorTest.createAsyncSuite("DOM.showGridOverlay");
+
+ async function getGridContainerNode() {
+ let doc = await WI.domManager.requestDocument();
+ let nodeId = await doc.querySelector(".grid-container");
+ return WI.domManager.nodeForId(nodeId);
+ }
+
+ async function getAllGridContainerNodes() {
+ let doc = await WI.domManager.requestDocument();
+ let nodeIds = await doc.querySelectorAll(".grid-container");
+ return nodeIds.map((nodeId) => WI.domManager.nodeForId(nodeId));
+ }
+
+ async function gridOverlayCount() {
+ return InspectorTest.evaluateInPage("window.internals.inspectorGridOverlayCount()");
+ }
+
+ async function checkGridOverlayCount(expected) {
+ let actual = await gridOverlayCount();
+ let message;
+ switch (expected) {
+ case 1:
+ message = "Should have 1 grid displayed.";
+ break;
+ default:
+ message = `Should have ${expected} grids displayed.`;
+ break;
+ }
+
+ InspectorTest.expectEqual(actual, expected, message);
+ }
+
+ suite.addTestCase({
+ name: "DOM.showGridOverlay.ShowOneGrid",
+ description: "No error occurs when requesting to show a grid overlay.",
+ async test() {
+ await checkGridOverlayCount(0);
+ let container = await getGridContainerNode();
+
+ InspectorTest.log("Requesting to show grid overlay for first .grid-container");
+ await DOMAgent.showGridOverlay(container.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 for first .grid-container");
+ await DOMAgent.showGridOverlay(container.id, WI.Color.fromString("green").toProtocol());
+ await checkGridOverlayCount(1);
+
+ // No error should occur when hiding the grid overlay.
+ InspectorTest.log("Requesting to hide grid overlay");
+ await DOMAgent.hideGridOverlay(container.id);
+ await checkGridOverlayCount(0);
+ }
+ });
+
+ suite.addTestCase({
+ name: "DOM.showGridOverlay.ShowTwoGrids",
+ description: "No error occurs when requesting to show multiple grid overlays.",
+ async test() {
+ await checkGridOverlayCount(0);
+ let [first, second] = await getAllGridContainerNodes();
+
+ InspectorTest.log("Requesting to show first grid overlay");
+ 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);
+
+ // No error should occur when hiding the grid overlay.
+ InspectorTest.log("Requesting to hide first grid overlay");
+ await DOMAgent.hideGridOverlay(first.id);
+ await checkGridOverlayCount(1);
+
+ // No error should occur when hiding the grid overlay.
+ InspectorTest.log("Requesting to hide second grid overlay");
+ await DOMAgent.hideGridOverlay(second.id);
+ await checkGridOverlayCount(0);
+ }
+ });
+
+ suite.addTestCase({
+ name: "DOM.showGridOverlay.HideAllGrids",
+ description: "No error occurs when requesting to show multiple grid overlays.",
+ async test() {
+ await checkGridOverlayCount(0);
+ let [first, second] = await getAllGridContainerNodes();
+
+ InspectorTest.log("Requesting to show grid overlay");
+ 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);
+
+ // No error should occur when hiding the grid overlay.
+ InspectorTest.log("Requesting to hide all grid overlays. Hiding all grids is idempotent and should not throw an error.");
+ await DOMAgent.hideGridOverlay();
+ await checkGridOverlayCount(0);
+
+ // No error should occur when hiding the grid overlay.
+ InspectorTest.log("Requesting to hide all grid overlays again, expecting none to be cleared. Hiding all grids is idempotent and should not throw an error.");
+ await DOMAgent.hideGridOverlay();
+ await checkGridOverlayCount(0);
+ }
+ });
+
+ suite.addTestCase({
+ name: "DOM.showGridOverlay.HideBeforeShowShouldError",
+ description: "Return an error when requesting to hide a grid overlay when none is active for the node.",
+ async test() {
+ let container = await getGridContainerNode();
+
+ await checkGridOverlayCount(0);
+
+ InspectorTest.log("Requesting to hide grid overlay for .grid-container");
+ await InspectorTest.expectException(async () => {
+ await DOMAgent.hideGridOverlay(container.id);
+ });
+
+ InspectorTest.log("Requesting to hide all grid overlays. Hiding all grids is idempotent and should not throw an error.");
+ await DOMAgent.hideGridOverlay();
+ await checkGridOverlayCount(0);
+ }
+ });
+
+ suite.addTestCase({
+ name: "DOM.showGridOverlay.ForNonexistentNodeShouldError",
+ description: "Return an error when requesting to show a grid overlay for a nonexistent node.",
+ async test() {
+ await checkGridOverlayCount(0);
+
+ InspectorTest.log("Requesting to show grid overlay for invalid nodeId -1");
+ await InspectorTest.expectException(async () => {
+ await DOMAgent.showGridOverlay(-1, WI.Color.fromString("magenta").toProtocol());
+ });
+
+ await checkGridOverlayCount(0);
+ }
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+ <style>
+ body {
+ margin: 100px;
+ }
+ .grid-container {
+ display: grid;
+ grid-gap: 10px;
+ grid-template-columns: 100px 100px 100px;
+ background-color: white;
+ color: gray;
+ }
+
+ .grid-container > .box {
+ background-color: gray;
+ color: white;
+ border-radius: 5px;
+ padding: 20px;
+ font-size: 150%;
+ }
+ </style>
+
+ <p>Tests for the DOM.showGridOverlay command.</p>
+ <div class="grid-container" style="color: #366">
+ <div class="box a">A</div>
+ <div class="box b">B</div>
+ <div class="box c">C</div>
+ <div class="box d">D</div>
+ <div class="box e">E</div>
+ <div class="box f">F</div>
+ </div>
+ <br />
+ <div class="grid-container" style="color: #636">
+ <div class="box a">A</div>
+ <div class="box b">B</div>
+ <div class="box c">C</div>
+ <div class="box d">D</div>
+ <div class="box e">E</div>
+ <div class="box f">F</div>
+ </div>
+</body>
+</html>
Modified: trunk/LayoutTests/inspector/model/color-expected.txt (272196 => 272197)
--- trunk/LayoutTests/inspector/model/color-expected.txt 2021-02-02 08:52:42 UTC (rev 272196)
+++ trunk/LayoutTests/inspector/model/color-expected.txt 2021-02-02 09:02:31 UTC (rev 272197)
@@ -543,3 +543,9 @@
"color(display-p3 1 0 0)" is outside sRGB.
"color(display-p3 0.93 0.353 0.353)" is outside sRGB.
+-- Running test case: WI.Color.toProtocol
+PASS: Should convert rgba(10,20,30,40) to {"r":10,"g":20,"b":30,"a":1}.
+PASS: Should convert rgb(10 20 30 / 40%) to {"r":10,"g":20,"b":30,"a":0.4}.
+PASS: Should convert #a0Aa0A to {"r":160,"g":170,"b":10,"a":1}.
+PASS: Should convert rgb(10% 20% 30% / 40%) to {"r":25.5,"g":51,"b":76.5,"a":0.4}.
+
Modified: trunk/LayoutTests/inspector/model/color.html (272196 => 272197)
--- trunk/LayoutTests/inspector/model/color.html 2021-02-02 08:52:42 UTC (rev 272196)
+++ trunk/LayoutTests/inspector/model/color.html 2021-02-02 09:02:31 UTC (rev 272197)
@@ -672,6 +672,25 @@
}
});
+ suite.addTestCase({
+ name: "WI.Color.toProtocol",
+ description: "Test serialization of WI.Color into DOM.RGBAColor.",
+ test() {
+ function testInput(input, expected) {
+ let color = WI.Color.fromString(input);
+ let actual = color.toProtocol();
+ InspectorTest.expectShallowEqual(actual, expected, `Should convert ${input} to ${JSON.stringify(expected)}.`);
+ }
+
+ testInput("rgba(10,20,30,40)", {r: 10, g: 20, b: 30, a: 1});
+ testInput("rgb(10 20 30 / 40%)", {r: 10, g: 20, b: 30, a: 0.4});
+ testInput("#a0Aa0A", {r: 160, g: 170, b: 10, a: 1});
+ testInput("rgb(10% 20% 30% / 40%)", {r: 25.5, g: 51, b: 76.5, a: 0.4});
+
+ return true;
+ }
+ });
+
suite.runTestCasesAndFinish();
}
</script>
Modified: trunk/LayoutTests/inspector/unit-tests/test-harness-expect-functions-async-expected.txt (272196 => 272197)
--- trunk/LayoutTests/inspector/unit-tests/test-harness-expect-functions-async-expected.txt 2021-02-02 08:52:42 UTC (rev 272196)
+++ trunk/LayoutTests/inspector/unit-tests/test-harness-expect-functions-async-expected.txt 2021-02-02 09:02:31 UTC (rev 272197)
@@ -17,6 +17,7 @@
FAIL: Should produce an exception.
Expected: not null
Actual: null
+PASS: Exception-producing work should not return a value
PASS: Rejected value should be the returned value.
-- Running test case: expectException.AsyncWorkThatRejects
@@ -30,6 +31,9 @@
FAIL: Should produce an exception.
Expected: not null
Actual: null
+FAIL: Exception-producing work should not return a value
+ Expected: undefined
+ Actual: 42
PASS: Rejected value should be the returned value.
-- Running test case: expectException.AsyncWorkThatResolvesImplicitly
@@ -37,5 +41,6 @@
FAIL: Should produce an exception.
Expected: not null
Actual: null
+PASS: Exception-producing work should not return a value
PASS: Implicitly resolved value should be undefined.
Modified: trunk/Source/_javascript_Core/ChangeLog (272196 => 272197)
--- trunk/Source/_javascript_Core/ChangeLog 2021-02-02 08:52:42 UTC (rev 272196)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-02-02 09:02:31 UTC (rev 272197)
@@ -1,3 +1,17 @@
+2021-02-02 BJ Burg <[email protected]>
+
+ Web Inspector: implement the basics for showing/hiding grid overlays
+ https://bugs.webkit.org/show_bug.cgi?id=221062
+
+ Reviewed by Devin Rousso.
+
+ Add new commands to show and hide CSS grid overlays:
+
+ - DOM.showGridOverlay
+ - DOM.hideGridOverlay
+
+ * inspector/protocol/DOM.json:
+
2021-02-02 Adrian Perez de Castro <[email protected]>
Non-unified build fixes, late January 2021 edition
Modified: trunk/Source/_javascript_Core/inspector/protocol/DOM.json (272196 => 272197)
--- trunk/Source/_javascript_Core/inspector/protocol/DOM.json 2021-02-02 08:52:42 UTC (rev 272196)
+++ trunk/Source/_javascript_Core/inspector/protocol/DOM.json 2021-02-02 09:02:31 UTC (rev 272197)
@@ -494,6 +494,28 @@
"description": "Highlights owner element of the frame with given id."
},
{
+ "name": "showGridOverlay",
+ "description": "Shows a grid overlay for a node that begins a 'grid' layout context. The command has no effect if <code>nodeId</code> is invalid or the associated node does not begin a 'grid' layout context. A node can only have one grid 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 grid overlay should be shown." },
+ { "name": "gridColor", "$ref": "RGBAColor", "description": "The primary color to use for the grid overlay." },
+ { "name": "showLineNames", "type": "boolean", "optional": true, "description": "Show labels for grid line names. If not specified, the default value is false." },
+ { "name": "showLineNumbers", "type": "boolean", "optional": true, "description": "Show labels for grid line numbers. If not specified, the default value is false." },
+ { "name": "showExtendedGridlines", "type": "boolean", "optional": true, "description": "Show grid lines that extend beyond the bounds of the grid. If not specified, the default value is false." },
+ { "name": "showTrackSizes", "type": "boolean", "optional": true, "description": "Show grid track size information. If not specified, the default value is false." },
+ { "name": "showAreaNames", "type": "boolean", "optional": true, "description": "Show labels for grid area names. If not specified, the default value is false." }
+ ]
+ },
+ {
+ "name": "hideGridOverlay",
+ "description": "Hides a grid overlay for a node that begins a 'grid' 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 grid overlay should be hidden. If a <code>nodeId</code> is not specified, all grid 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 (272196 => 272197)
--- trunk/Source/WebCore/ChangeLog 2021-02-02 08:52:42 UTC (rev 272196)
+++ trunk/Source/WebCore/ChangeLog 2021-02-02 09:02:31 UTC (rev 272197)
@@ -1,3 +1,58 @@
+2021-02-02 BJ Burg <[email protected]>
+
+ Web Inspector: implement the basics for showing/hiding grid overlays
+ https://bugs.webkit.org/show_bug.cgi?id=221062
+
+ Reviewed by Devin Rousso.
+
+ Implement backend commands for showing and hiding CSS grid overlays.
+ This patch draws a very simplistic grid overlay. Support for the
+ various grid overlay options will be added in later patches.
+
+ New test: inspector/dom/showGridOverlay.html
+
+ * inspector/InspectorOverlay.h:
+ (WebCore::InspectorOverlay::gridOverlayCount const):
+ Added, for testing only.
+
+ * inspector/InspectorOverlay.cpp:
+ (WebCore::InspectorOverlay::paint):
+ (WebCore::InspectorOverlay::shouldShowOverlay const):
+ Hook up the painting of any active grid overlays.
+
+ (WebCore::InspectorOverlay::setGridOverlayForNode):
+ (WebCore::InspectorOverlay::clearGridOverlayForNode):
+ (WebCore::InspectorOverlay::clearAllGridOverlays):
+ Maintain the list of active grid overlays. A node can only
+ have one grid overlay at a time.
+
+ (WebCore::InspectorOverlay::drawNodeHighlight):
+ Add a note about why grid overlays are not considered when
+ calculating the ruler exclusion area.
+
+ (WebCore::InspectorOverlay::drawGridOverlay): Added.
+ This drawing code exists to flesh out the rest of this patch,
+ and is obviously incomplete.
+
+ Draw grid lines that extend to the edge of the viewport,
+ equivalent to `config.showExtendedGridLines = true`.
+
+ * inspector/agents/InspectorDOMAgent.h:
+ * inspector/agents/InspectorDOMAgent.cpp:
+ (WebCore::InspectorDOMAgent::showGridOverlay):
+ (WebCore::InspectorDOMAgent::hideGridOverlay):
+ Translate protocol commands into InspectorOverlay method calls.
+
+ * inspector/InspectorController.h:
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorController::gridOverlayCount const):
+ Added. This is used for testing purposes only.
+
+ * testing/Internals.h:
+ * testing/Internals.idl:
+ * testing/Internals.cpp:
+ (WebCore::Internals::inspectorGridOverlayCount): Added.
+
2021-02-02 Carlos Garcia Campos <[email protected]>
[SOUP] Stop using SoupBuffer in preparation for libsoup3
Modified: trunk/Source/WebCore/inspector/InspectorController.cpp (272196 => 272197)
--- trunk/Source/WebCore/inspector/InspectorController.cpp 2021-02-02 08:52:42 UTC (rev 272196)
+++ trunk/Source/WebCore/inspector/InspectorController.cpp 2021-02-02 09:02:31 UTC (rev 272197)
@@ -361,6 +361,11 @@
m_overlay->getHighlight(highlight, coordinateSystem);
}
+unsigned InspectorController::gridOverlayCount() const
+{
+ return m_overlay->gridOverlayCount();
+}
+
bool InspectorController::shouldShowOverlay() const
{
return m_overlay->shouldShowOverlay();
Modified: trunk/Source/WebCore/inspector/InspectorController.h (272196 => 272197)
--- trunk/Source/WebCore/inspector/InspectorController.h 2021-02-02 08:52:42 UTC (rev 272196)
+++ trunk/Source/WebCore/inspector/InspectorController.h 2021-02-02 09:02:31 UTC (rev 272197)
@@ -101,9 +101,11 @@
WEBCORE_EXPORT void willComposite(Frame&);
WEBCORE_EXPORT void didComposite(Frame&);
+ // Testing support.
bool isUnderTest() const { return m_isUnderTest; }
void setIsUnderTest(bool isUnderTest) { m_isUnderTest = isUnderTest; }
WEBCORE_EXPORT void evaluateForTestInFrontend(const String& script);
+ WEBCORE_EXPORT unsigned gridOverlayCount() const;
InspectorClient* inspectorClient() const { return m_inspectorClient; }
InspectorFrontendClient* inspectorFrontendClient() const { return m_inspectorFrontendClient; }
Modified: trunk/Source/WebCore/inspector/InspectorOverlay.cpp (272196 => 272197)
--- trunk/Source/WebCore/inspector/InspectorOverlay.cpp 2021-02-02 08:52:42 UTC (rev 272196)
+++ trunk/Source/WebCore/inspector/InspectorOverlay.cpp 2021-02-02 09:02:31 UTC (rev 272197)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
- * Copyright (C) 2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2019-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -43,6 +43,7 @@
#include "Frame.h"
#include "FrameView.h"
#include "GraphicsContext.h"
+#include "GridPositionsResolver.h"
#include "InspectorClient.h"
#include "IntPoint.h"
#include "IntRect.h"
@@ -53,6 +54,7 @@
#include "PseudoElement.h"
#include "RenderBox.h"
#include "RenderBoxModelObject.h"
+#include "RenderGrid.h"
#include "RenderInline.h"
#include "RenderObject.h"
#include "Settings.h"
@@ -409,6 +411,9 @@
rulerExclusion.titlePath = nodeRulerExclusion.titlePath;
}
+ for (const InspectorOverlay::Grid& gridOverlay : m_activeGridOverlays)
+ drawGridOverlay(context, gridOverlay);
+
if (!m_paintRects.isEmpty())
drawPaintRects(context, m_paintRects);
@@ -495,7 +500,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;
+ return m_highlightNode || m_highlightNodeList || m_highlightQuad || m_indicating || m_showPaintRects || m_showRulers || m_activeGridOverlays.size();
}
void InspectorOverlay::update()
@@ -555,6 +560,46 @@
update();
}
+bool InspectorOverlay::removeGridOverlayForNode(Node& node)
+{
+ // Try to remove `node`. Also clear any grid overlays whose WeakPtr<Node> has been cleared.
+ return m_activeGridOverlays.removeAllMatching([&] (const InspectorOverlay::Grid& gridOverlay) {
+ return !gridOverlay.gridNode || gridOverlay.gridNode.get() == &node;
+ });
+}
+
+ErrorStringOr<void> InspectorOverlay::setGridOverlayForNode(Node& node, const InspectorOverlay::Grid::Config& gridOverlayConfig)
+{
+ RenderObject* renderer = node.renderer();
+ if (!is<RenderGrid>(renderer))
+ return makeUnexpected("Node does not initiate a grid context");
+
+ removeGridOverlayForNode(node);
+
+ m_activeGridOverlays.append({ makeWeakPtr(node), gridOverlayConfig });
+
+ update();
+
+ return { };
+}
+
+ErrorStringOr<void> InspectorOverlay::clearGridOverlayForNode(Node& node)
+{
+ if (!removeGridOverlayForNode(node))
+ return makeUnexpected("No grid overlay exists for the node, so cannot clear.");
+
+ update();
+
+ return { };
+}
+
+void InspectorOverlay::clearAllGridOverlays()
+{
+ m_activeGridOverlays.clear();
+
+ update();
+}
+
void InspectorOverlay::updatePaintRectsTimerFired()
{
MonotonicTime now = MonotonicTime::now();
@@ -587,6 +632,9 @@
if (m_nodeHighlightConfig.showInfo)
rulerExclusion.titlePath = drawElementTitle(context, node, rulerExclusion.bounds);
+ // Note: since grid overlays may cover the entire viewport with little lines, grid overlay bounds
+ // are not considered as part of the combined bounds used as the ruler exclusion area.
+
return rulerExclusion;
}
@@ -1092,4 +1140,82 @@
return path;
}
+void InspectorOverlay::drawGridOverlay(GraphicsContext& context, const InspectorOverlay::Grid& gridOverlay)
+{
+ // If the node WeakPtr has been cleared, then the node is gone and there's nothing to draw.
+ if (!gridOverlay.gridNode) {
+ m_activeGridOverlays.removeAllMatching([&] (const InspectorOverlay::Grid& gridOverlay) {
+ return !gridOverlay.gridNode;
+ });
+ return;
+ }
+
+ // Always re-check because the node's renderer may have changed since being added.
+ // If renderer is no longer a grid, then remove the grid overlay for the node.
+ Node* node = gridOverlay.gridNode.get();
+ auto renderer = node->renderer();
+ if (!is<RenderGrid>(renderer)) {
+ removeGridOverlayForNode(*node);
+ return;
+ }
+
+ auto* renderGrid = downcast<RenderGrid>(renderer);
+ LayoutRect paddingBox = renderGrid->clientBoxRect();
+ LayoutRect contentBox = LayoutRect(paddingBox.x() + renderGrid->paddingLeft(), paddingBox.y() + renderGrid->paddingTop(),
+ paddingBox.width() - renderGrid->paddingLeft() - renderGrid->paddingRight(), paddingBox.height() - renderGrid->paddingTop() - renderGrid->paddingBottom());
+ FloatQuad absContentQuad = renderer->localToAbsoluteQuad(FloatRect(contentBox));
+ FloatRect gridBoundingBox = absContentQuad.boundingBox();
+ FrameView* pageView = m_page.mainFrame().view();
+ FloatSize contentInset(0, pageView->topContentInset(ScrollView::TopContentInsetType::WebCoreOrPlatformContentInset));
+ FloatSize viewportSize = pageView->sizeForVisibleContent();
+
+ GraphicsContextStateSaver saver(context);
+
+ // Drawing code is relative to the visible viewport area.
+ context.translate(0, contentInset.height());
+
+ // FIXME: if showExtendedGridlines is false, set the clip path to the gridBoundingBox (maybe inflated?)
+
+ // Draw columns and rows.
+ context.setStrokeThickness(1);
+ context.setStrokeColor(gridOverlay.config.gridColor);
+
+ auto columnPositions = renderGrid->columnPositions();
+ auto columnWidths = renderGrid->trackSizesForComputedStyle(GridTrackSizingDirection::ForColumns);
+ for (unsigned i = 0; i < columnPositions.size(); ++i) {
+ // Column positions are (apparently) relative to the element's content area.
+ auto position = columnPositions[i] + gridBoundingBox.x();
+
+ Path columnPaths;
+ columnPaths.moveTo({ position, 0 });
+ columnPaths.addLineTo({ position, viewportSize.height() });
+
+ if (i < columnWidths.size()) {
+ auto width = columnWidths[i];
+ columnPaths.moveTo({ position + width, 0 });
+ columnPaths.addLineTo({ position + width, viewportSize.height() });
+ }
+
+ context.strokePath(columnPaths);
+ }
+
+ auto rowPositions = renderGrid->rowPositions();
+ auto rowHeights = renderGrid->trackSizesForComputedStyle(GridTrackSizingDirection::ForRows);
+ for (unsigned i = 0; i < rowPositions.size(); ++i) {
+ auto position = rowPositions[i] + gridBoundingBox.y();
+
+ Path rowPaths;
+ rowPaths.moveTo({ 0, position });
+ rowPaths.addLineTo({ viewportSize.width(), position });
+
+ if (i < rowHeights.size()) {
+ auto height = rowHeights[i];
+ rowPaths.moveTo({ 0, position + height });
+ rowPaths.addLineTo({ viewportSize.width(), position + height });
+ }
+
+ context.strokePath(rowPaths);
+ }
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/inspector/InspectorOverlay.h (272196 => 272197)
--- trunk/Source/WebCore/inspector/InspectorOverlay.h 2021-02-02 08:52:42 UTC (rev 272196)
+++ trunk/Source/WebCore/inspector/InspectorOverlay.h 2021-02-02 09:02:31 UTC (rev 272197)
@@ -39,8 +39,16 @@
#include <wtf/Optional.h>
#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
+#include <wtf/WeakPtr.h>
#include <wtf/text/WTFString.h>
+namespace Inspector {
+using ErrorString = String;
+
+template <typename T>
+using ErrorStringOr = Expected<T, ErrorString>;
+}
+
namespace WebCore {
class GraphicsContext;
@@ -98,6 +106,24 @@
using Bounds = FloatRect;
};
+ struct Grid {
+ WTF_MAKE_STRUCT_FAST_ALLOCATED;
+
+ struct Config {
+ WTF_MAKE_STRUCT_FAST_ALLOCATED;
+
+ Color gridColor;
+ bool showLineNames;
+ bool showLineNumbers;
+ bool showExtendedGridlines;
+ bool showTrackSizes;
+ bool showAreaNames;
+ };
+
+ WeakPtr<Node> gridNode;
+ 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.
@@ -120,11 +146,18 @@
void setShowRulersDuringElementSelection(bool enabled) { m_showRulersDuringElementSelection = enabled; }
Node* highlightedNode() const;
+ unsigned gridOverlayCount() const { return m_activeGridOverlays.size(); }
void didSetSearchingForNode(bool enabled);
void setIndicating(bool indicating);
+ // Multiple grid 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();
+
private:
using TimeRectPair = std::pair<MonotonicTime, FloatRect>;
@@ -141,8 +174,12 @@
Path drawElementTitle(GraphicsContext&, Node&, const Highlight::Bounds&);
+ void drawGridOverlay(GraphicsContext&, const InspectorOverlay::Grid&);
+
void updatePaintRectsTimerFired();
+ bool removeGridOverlayForNode(Node&);
+
Page& m_page;
InspectorClient* m_client;
@@ -156,6 +193,8 @@
Deque<TimeRectPair> m_paintRects;
Timer m_paintRectUpdateTimer;
+ Vector<InspectorOverlay::Grid> m_activeGridOverlays;
+
bool m_indicating { false };
bool m_showPaintRects { false };
bool m_showRulers { false };
Modified: trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp (272196 => 272197)
--- trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp 2021-02-02 08:52:42 UTC (rev 272196)
+++ trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp 2021-02-02 09:02:31 UTC (rev 272197)
@@ -116,6 +116,7 @@
#include <_javascript_Core/JSCInlines.h>
#include <pal/crypto/CryptoDigest.h>
#include <wtf/Function.h>
+#include <wtf/Optional.h>
#include <wtf/text/Base64.h>
#include <wtf/text/CString.h>
#include <wtf/text/WTFString.h>
@@ -129,26 +130,26 @@
static const size_t maxTextSize = 10000;
static const UChar ellipsisUChar[] = { 0x2026, 0 };
-static Color parseColor(RefPtr<JSON::Object>&& colorObject)
+static Optional<Color> parseColor(RefPtr<JSON::Object>&& colorObject)
{
if (!colorObject)
- return Color::transparentBlack;
+ return WTF::nullopt;
auto r = colorObject->getInteger(Protocol::DOM::RGBAColor::rKey);
auto g = colorObject->getInteger(Protocol::DOM::RGBAColor::gKey);
auto b = colorObject->getInteger(Protocol::DOM::RGBAColor::bKey);
if (!r || !g || !b)
- return Color::transparentBlack;
+ return WTF::nullopt;
auto a = colorObject->getDouble(Protocol::DOM::RGBAColor::aKey);
if (!a)
- return makeFromComponentsClamping<SRGBA<uint8_t>>(*r, *g, *b);
- return makeFromComponentsClampingExceptAlpha<SRGBA<uint8_t>>(*r, *g, *b, convertFloatAlphaTo<uint8_t>(*a));
+ return { makeFromComponentsClamping<SRGBA<uint8_t>>(*r, *g, *b) };
+ return { makeFromComponentsClampingExceptAlpha<SRGBA<uint8_t>>(*r, *g, *b, convertFloatAlphaTo<uint8_t>(*a)) };
}
static Color parseConfigColor(const String& fieldName, JSON::Object& configObject)
{
- return parseColor(configObject.getObject(fieldName));
+ return parseColor(configObject.getObject(fieldName)).valueOr(Color::transparentBlack);
}
static bool parseQuad(Ref<JSON::Array>&& quadArray, FloatQuad* quad)
@@ -1291,8 +1292,8 @@
void InspectorDOMAgent::innerHighlightQuad(std::unique_ptr<FloatQuad> quad, RefPtr<JSON::Object>&& color, RefPtr<JSON::Object>&& outlineColor, Optional<bool>&& usePageCoordinates)
{
auto highlightConfig = makeUnique<InspectorOverlay::Highlight::Config>();
- highlightConfig->content = parseColor(WTFMove(color));
- highlightConfig->contentOutline = parseColor(WTFMove(outlineColor));
+ highlightConfig->content = parseColor(WTFMove(color)).valueOr(Color::transparentBlack);
+ highlightConfig->contentOutline = parseColor(WTFMove(outlineColor)).valueOr(Color::transparentBlack);
highlightConfig->usePageCoordinates = usePageCoordinates ? *usePageCoordinates : false;
m_overlay->highlightQuad(WTFMove(quad), *highlightConfig);
}
@@ -1458,8 +1459,8 @@
if (frame->ownerElement()) {
auto highlightConfig = makeUnique<InspectorOverlay::Highlight::Config>();
highlightConfig->showInfo = true; // Always show tooltips for frames.
- highlightConfig->content = parseColor(WTFMove(color));
- highlightConfig->contentOutline = parseColor(WTFMove(outlineColor));
+ highlightConfig->content = parseColor(WTFMove(color)).valueOr(Color::transparentBlack);
+ highlightConfig->contentOutline = parseColor(WTFMove(outlineColor)).valueOr(Color::transparentBlack);
m_overlay->highlightNode(frame->ownerElement(), *highlightConfig);
}
@@ -1473,6 +1474,46 @@
return { };
}
+Inspector::Protocol::ErrorStringOr<void> InspectorDOMAgent::showGridOverlay(Inspector::Protocol::DOM::NodeId nodeId, Ref<JSON::Object>&& gridColor, Optional<bool>&& showLineNames, Optional<bool>&& showLineNumbers, Optional<bool>&& showExtendedGridlines, Optional<bool>&& showTrackSizes, Optional<bool>&& showAreaNames)
+{
+ Protocol::ErrorString errorString;
+ Node* node = assertNode(errorString, nodeId);
+ if (!node)
+ return makeUnexpected(errorString);
+
+ auto parsedColor = parseColor(WTFMove(gridColor));
+ if (!parsedColor)
+ return makeUnexpected("Invalid color could not be parsed.");
+
+ InspectorOverlay::Grid::Config config;
+ config.gridColor = *parsedColor;
+ config.showLineNames = showLineNames.valueOr(false);
+ config.showLineNumbers = showLineNumbers.valueOr(false);
+ config.showExtendedGridlines = showExtendedGridlines.valueOr(false);
+ config.showTrackSizes = showTrackSizes.valueOr(false);
+ config.showAreaNames = showAreaNames.valueOr(false);
+
+ m_overlay->setGridOverlayForNode(*node, config);
+
+ return { };
+}
+
+Inspector::Protocol::ErrorStringOr<void> InspectorDOMAgent::hideGridOverlay(Optional<Protocol::DOM::NodeId>&& nodeId)
+{
+ if (nodeId) {
+ Protocol::ErrorString errorString;
+ auto node = assertNode(errorString, *nodeId);
+ if (!node)
+ return makeUnexpected(errorString);
+
+ return m_overlay->clearGridOverlayForNode(*node);
+}
+
+ m_overlay->clearAllGridOverlays();
+
+ return { };
+}
+
Protocol::ErrorStringOr<Protocol::DOM::NodeId> InspectorDOMAgent::moveTo(Protocol::DOM::NodeId nodeId, Protocol::DOM::NodeId targetNodeId, Optional<Protocol::DOM::NodeId>&& insertBeforeNodeId)
{
Protocol::ErrorString errorString;
Modified: trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.h (272196 => 272197)
--- trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.h 2021-02-02 08:52:42 UTC (rev 272196)
+++ trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.h 2021-02-02 09:02:31 UTC (rev 272197)
@@ -144,6 +144,8 @@
Inspector::Protocol::ErrorStringOr<void> highlightNode(Ref<JSON::Object>&& highlightConfig, Optional<Inspector::Protocol::DOM::NodeId>&&, const Inspector::Protocol::Runtime::RemoteObjectId&);
Inspector::Protocol::ErrorStringOr<void> highlightNodeList(Ref<JSON::Array>&& nodeIds, Ref<JSON::Object>&& highlightConfig);
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, Optional<bool>&& showLineNames, Optional<bool>&& showLineNumbers, Optional<bool>&& showExtendedGridlines, Optional<bool>&& showTrackSizes, Optional<bool>&& showAreaNames);
+ Inspector::Protocol::ErrorStringOr<void> hideGridOverlay(Optional<Inspector::Protocol::DOM::NodeId>&&);
Inspector::Protocol::ErrorStringOr<Inspector::Protocol::DOM::NodeId> moveTo(Inspector::Protocol::DOM::NodeId nodeId, Inspector::Protocol::DOM::NodeId targetNodeId, Optional<Inspector::Protocol::DOM::NodeId>&& insertBeforeNodeId);
Inspector::Protocol::ErrorStringOr<void> undo();
Inspector::Protocol::ErrorStringOr<void> redo();
@@ -213,6 +215,7 @@
void highlightMousedOverNode();
void setSearchingForNode(Inspector::Protocol::ErrorString&, bool enabled, RefPtr<JSON::Object>&& highlightConfig, bool showRulers);
std::unique_ptr<InspectorOverlay::Highlight::Config> highlightConfigFromInspectorObject(Inspector::Protocol::ErrorString&, RefPtr<JSON::Object>&& highlightInspectorObject);
+ std::unique_ptr<InspectorOverlay::Grid::Config> gridOverlayConfigFromInspectorObject(Inspector::Protocol::ErrorString&, RefPtr<JSON::Object>&& gridOverlayInspectorObject);
// Node-related methods.
typedef HashMap<RefPtr<Node>, Inspector::Protocol::DOM::NodeId> NodeToIdMap;
Modified: trunk/Source/WebCore/testing/Internals.cpp (272196 => 272197)
--- trunk/Source/WebCore/testing/Internals.cpp 2021-02-02 08:52:42 UTC (rev 272196)
+++ trunk/Source/WebCore/testing/Internals.cpp 2021-02-02 09:02:31 UTC (rev 272197)
@@ -1664,6 +1664,15 @@
return DOMRect::create(renderer->absoluteBoundingBoxRectIgnoringTransforms());
}
+ExceptionOr<unsigned> Internals::inspectorGridOverlayCount()
+{
+ Document* document = contextDocument();
+ if (!document || !document->page())
+ return Exception { InvalidAccessError };
+
+ return document->page()->inspectorController().gridOverlayCount();
+}
+
ExceptionOr<Ref<DOMRectList>> Internals::inspectorHighlightRects()
{
Document* document = contextDocument();
Modified: trunk/Source/WebCore/testing/Internals.h (272196 => 272197)
--- trunk/Source/WebCore/testing/Internals.h 2021-02-02 08:52:42 UTC (rev 272196)
+++ trunk/Source/WebCore/testing/Internals.h 2021-02-02 09:02:31 UTC (rev 272197)
@@ -271,6 +271,7 @@
Ref<DOMRect> boundingBox(Element&);
ExceptionOr<Ref<DOMRectList>> inspectorHighlightRects();
+ ExceptionOr<unsigned> inspectorGridOverlayCount();
ExceptionOr<unsigned> markerCountForNode(Node&, const String&);
ExceptionOr<RefPtr<Range>> markerRangeForNode(Node&, const String& markerType, unsigned index);
Modified: trunk/Source/WebCore/testing/Internals.idl (272196 => 272197)
--- trunk/Source/WebCore/testing/Internals.idl 2021-02-02 08:52:42 UTC (rev 272196)
+++ trunk/Source/WebCore/testing/Internals.idl 2021-02-02 09:02:31 UTC (rev 272197)
@@ -329,6 +329,7 @@
DOMRect boundingBox(Element element);
+ [MayThrowException] unsigned long inspectorGridOverlayCount();
[MayThrowException] DOMRectList inspectorHighlightRects();
[MayThrowException] unsigned long markerCountForNode(Node node, DOMString markerType);
Modified: trunk/Source/WebInspectorUI/ChangeLog (272196 => 272197)
--- trunk/Source/WebInspectorUI/ChangeLog 2021-02-02 08:52:42 UTC (rev 272196)
+++ trunk/Source/WebInspectorUI/ChangeLog 2021-02-02 09:02:31 UTC (rev 272197)
@@ -1,3 +1,54 @@
+2021-02-02 BJ Burg <[email protected]>
+
+ Web Inspector: implement the basics for showing/hiding grid overlays
+ https://bugs.webkit.org/show_bug.cgi?id=221062
+
+ Reviewed by Devin Rousso.
+
+ Expose new DOM.showGridOverlay and DOM.hideGridOverlay commands
+ via WI.DOMNode. Add initial engineering UI to toggle grid overlays.
+
+ New methods are covered by a new test:
+
+ inspector/dom/showGridOverlay.html
+
+ Additions to WI.DOMManager.prototype.requestDocument are covered
+ by existing tests (callback case) and a new test (promise case).
+
+ Additions to WI.Color are covered by a new test case in:
+
+ inspector/model/color.html
+
+ * UserInterface/Controllers/DOMManager.js:
+ (WI.DOMManager.prototype.requestDocument):
+ (WI.DOMManager.prototype._requestDocumentWithPromise):
+ Drive-by: upgrade requestDocument() to return a promise if
+ no callback argument was passed. This is used by a new test.
+
+ * UserInterface/Models/Color.js:
+ (WI.Color.prototype.toProtocol): Added. The protocol object is
+ DOM.RGBAColor, which is the same thing as WI.Color.Format.RGBA.
+
+ * UserInterface/Models/DOMNode.js:
+ (WI.DOMNode.prototype.showGridOverlay):
+ (WI.DOMNode.prototype.hideGridOverlay):
+ Added. These are the methods that the rest of WebInspectorUI uses
+ to interact with grid overlays for a particular node. Note that
+ these methods return either an unsettled promise (from the agent call)
+ or a rejected promise (in the case that the node is destroyed).
+ This allows test cases to `await` before checking the grid overlay count.
+
+ * UserInterface/Test/TestHarness.js:
+ (TestHarness.prototype.expectException): Improve logging output
+ when InspectorTest.expectException does not catch an exception.
+
+ * UserInterface/Views/ContextMenuUtilities.js:
+ Add some engineering-only context menu items for showing/hiding
+ grid overlays to DOMTreeElements in the Elements Tab.
+
+ These are in place for development purposes and should eventually
+ be removed when no longer needed.
+
2021-02-01 Patrick Angle <[email protected]>
REGRESSION(r270637): Web Inspector: Filtering field no longer shows in Computed panel
Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/DOMManager.js (272196 => 272197)
--- trunk/Source/WebInspectorUI/UserInterface/Controllers/DOMManager.js 2021-02-02 08:52:42 UTC (rev 272196)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/DOMManager.js 2021-02-02 09:02:31 UTC (rev 272197)
@@ -40,6 +40,7 @@
this._idToDOMNode = {};
this._document = null;
+ this._documentPromise = null;
this._attributeLoadNodeIds = {};
this._restoreSelectedNodeIsAllowed = true;
this._loadNodeAttributesTimeout = 0;
@@ -155,36 +156,10 @@
requestDocument(callback)
{
- if (this._document) {
- callback(this._document);
- return;
- }
+ if (typeof callback !== "function")
+ return this._requestDocumentWithPromise();
- if (this._pendingDocumentRequestCallbacks)
- this._pendingDocumentRequestCallbacks.push(callback);
- else
- this._pendingDocumentRequestCallbacks = [callback];
-
- if (this._hasRequestedDocument)
- return;
-
- if (!WI.pageTarget)
- return;
-
- if (!WI.pageTarget.hasDomain("DOM"))
- return;
-
- this._hasRequestedDocument = true;
-
- WI.pageTarget.DOMAgent.getDocument((error, root) => {
- if (!error)
- this._setDocument(root);
-
- for (let callback of this._pendingDocumentRequestCallbacks)
- callback(this._document);
-
- this._pendingDocumentRequestCallbacks = null;
- });
+ this._requestDocumentWithCallback(callback);
}
ensureDocument()
@@ -264,6 +239,57 @@
this.requestDocument(onDocumentAvailable.bind(this));
}
+ _requestDocumentWithPromise()
+ {
+ if (this._documentPromise)
+ return this._documentPromise.promise;
+
+ this._documentPromise = new WI.WrappedPromise;
+ if (this._document)
+ this._documentPromise.resolve(this._document);
+ else {
+ this._requestDocumentWithCallback((doc) => {
+ this._documentPromise.resolve(doc);
+ });
+ }
+
+ return this._documentPromise.promise;
+ }
+
+ _requestDocumentWithCallback(callback)
+ {
+ if (this._document) {
+ callback(this._document);
+ return;
+ }
+
+ if (this._pendingDocumentRequestCallbacks)
+ this._pendingDocumentRequestCallbacks.push(callback);
+ else
+ this._pendingDocumentRequestCallbacks = [callback];
+
+ if (this._hasRequestedDocument)
+ return;
+
+ if (!WI.pageTarget)
+ return;
+
+ if (!WI.pageTarget.hasDomain("DOM"))
+ return;
+
+ this._hasRequestedDocument = true;
+
+ WI.pageTarget.DOMAgent.getDocument((error, root) => {
+ if (!error)
+ this._setDocument(root);
+
+ for (let callback of this._pendingDocumentRequestCallbacks)
+ callback(this._document);
+
+ this._pendingDocumentRequestCallbacks = null;
+ });
+ }
+
_attributeModified(nodeId, name, value)
{
var node = this._idToDOMNode[nodeId];
@@ -361,6 +387,9 @@
this._document = newDocument;
+ // Force the promise to be recreated so that it resolves to the new document.
+ this._documentPromise = null;
+
if (!this._document)
this._hasRequestedDocument = false;
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Color.js (272196 => 272197)
--- trunk/Source/WebInspectorUI/UserInterface/Models/Color.js 2021-02-02 08:52:42 UTC (rev 272196)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Color.js 2021-02-02 09:02:31 UTC (rev 272197)
@@ -638,6 +638,12 @@
return "";
}
+ toProtocol()
+ {
+ let [r, g, b, a] = this.rgba;
+ return {r, g, b, a};
+ }
+
isKeyword()
{
if (this.keyword)
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/DOMNode.js (272196 => 272197)
--- trunk/Source/WebInspectorUI/UserInterface/Models/DOMNode.js 2021-02-02 08:52:42 UTC (rev 272196)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/DOMNode.js 2021-02-02 09:02:31 UTC (rev 272197)
@@ -553,6 +553,34 @@
target.DOMAgent.highlightNode(WI.DOMManager.buildHighlightConfig(mode), this.id);
}
+ showGridOverlay(color, {showLineNames, showLineNumbers, showExtendedGridLines, showTrackSizes, showAreaNames} = {})
+ {
+ console.assert(color instanceof WI.Color, color);
+
+ if (this._destroyed)
+ return Promise.reject("Cannot show overlay, node is destroyed");
+
+ let target = WI.assumingMainTarget();
+ return target.DOMAgent.showGridOverlay.invoke({
+ nodeId: this.id,
+ gridColor: color.toProtocol(),
+ showLineNames: !!showLineNames,
+ showLineNumbers: !!showLineNumbers,
+ showExtendedGridLines: !!showExtendedGridLines,
+ showTrackSizes: !!showTrackSizes,
+ showAreaNames: !!showAreaNames,
+ });
+ }
+
+ hideGridOverlay()
+ {
+ if (this._destroyed)
+ return Promise.reject("Cannot hide overlay, node is destroyed");
+
+ let target = WI.assumingMainTarget();
+ return target.DOMAgent.hideGridOverlay(this.id);
+ }
+
scrollIntoView()
{
WI.RemoteObject.resolveNode(this).then((object) => {
Modified: trunk/Source/WebInspectorUI/UserInterface/Test/TestHarness.js (272196 => 272197)
--- trunk/Source/WebInspectorUI/UserInterface/Test/TestHarness.js 2021-02-02 08:52:42 UTC (rev 272196)
+++ trunk/Source/WebInspectorUI/UserInterface/Test/TestHarness.js 2021-02-02 09:02:31 UTC (rev 272197)
@@ -257,10 +257,12 @@
if (typeof work !== "function")
throw new Error("Invalid argument to catchException: work must be a function.");
- let expectAndDumpError = (e) => {
+ let expectAndDumpError = (e, resolvedValue) => {
this.expectNotNull(e, "Should produce an exception.");
- if (!e)
+ if (!e) {
+ this.expectEqual(resolvedValue, undefined, "Exception-producing work should not return a value");
return;
+ }
if (e instanceof Error || !(e instanceof Object))
this.log(e.toString());
@@ -284,7 +286,7 @@
// Invert the promise's settled state to match the expectation of the caller.
if (result instanceof Promise) {
return result.then((resolvedValue) => {
- expectAndDumpError(null);
+ expectAndDumpError(null, resolvedValue);
return Promise.reject(resolvedValue);
}, (e) => { // Don't chain the .catch as it will log the value we just rejected.
expectAndDumpError(e);
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ContextMenuUtilities.js (272196 => 272197)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ContextMenuUtilities.js 2021-02-02 08:52:42 UTC (rev 272196)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ContextMenuUtilities.js 2021-02-02 09:02:31 UTC (rev 272197)
@@ -386,6 +386,28 @@
}
contextMenu.appendSeparator();
+
+ // FIXME: <https://webkit.org/b/221246> remove these engineering-only menu items when removing the feature flag.
+ if (WI.isEngineeringBuild && WI.settings.experimentalEnableLayoutPanel.value) {
+ if (InspectorBackend.hasCommand("DOM.showGridOverlay") && attached) {
+ contextMenu.appendItem(WI.unlocalizedString("Add Grid Overlay with Random Color"), () => {
+ let randomComponent = () => Math.floor(Math.random() * 255);
+ let color = new WI.Color(WI.Color.Format.RGB, [randomComponent(), randomComponent(), randomComponent()]);
+ domNode.showGridOverlay(color).catch(console.error);
+ });
+
+ contextMenu.appendItem(WI.unlocalizedString("Remove Grid Overlay for this Node"), () => {
+ domNode.hideGridOverlay();
+ });
+
+ contextMenu.appendItem(WI.unlocalizedString("Remove All Grid Overlays"), () => {
+ let target = WI.assumingMainTarget();
+ target.DOMAgent.hideGridOverlay();
+ });
+ }
+ }
+
+ contextMenu.appendSeparator();
}
};