Title: [219268] trunk
Revision
219268
Author
[email protected]
Date
2017-07-07 14:30:47 -0700 (Fri, 07 Jul 2017)

Log Message

Web Inspector: Show all elements currently using a given CSS Canvas
https://bugs.webkit.org/show_bug.cgi?id=173965

Reviewed by Joseph Pecoraro.

Source/_javascript_Core:

* inspector/protocol/Canvas.json:
 - Add `requestCSSCanvasClientNodes` command for getting the node IDs all nodes using this
   canvas via -webkit-canvas.
 - Add `cssCanvasClientNodesChanged` event that is dispatched whenever a node is
   added/removed from the list of -webkit-canvas clients.

Source/WebCore:

Test: inspector/canvas/css-canvas-clients.html

* css/CSSImageGeneratorValue.cpp:
(WebCore::CSSImageGeneratorValue::addClient):
(WebCore::CSSImageGeneratorValue::removeClient):
* css/CSSImageGeneratorValue.h:
(WebCore::CSSImageGeneratorValue::clients):
* html/HTMLCanvasElement.cpp:
(WebCore::HTMLCanvasElement::addObserver):
(WebCore::HTMLCanvasElement::removeObserver):
(WebCore::HTMLCanvasElement::cssCanvasClients):
Each time an observer is added/removed for a given HTMLCanvasElement, send an event to the
inspector frontend that the CSS canvas client nodes have changed. Additionally, anytime a
client/use is added/removed from one of the observing CSSCanvasValue, fire the same event.

* css/CSSCanvasValue.h:
(isType):
* html/HTMLCanvasElement.h:
(WebCore::CanvasObserver::isCSSCanvasValueObserver):
Allows type traits to distinguish CanvasObserver from CSSCanvasValue::CanvasObserverProxy.

* inspector/InspectorCanvasAgent.h:
* inspector/InspectorCanvasAgent.cpp:
(WebCore::InspectorCanvasAgent::requestCSSCanvasClientNodes):
(WebCore::InspectorCanvasAgent::didChangeCSSCanvasClientNodes):
* inspector/InspectorInstrumentation.h:
(WebCore::InspectorInstrumentation::didChangeCSSCanvasClientNodes):
* inspector/InspectorInstrumentation.cpp:
(WebCore::InspectorInstrumentation::didChangeCSSCanvasClientNodesImpl):
Notify the frontend that the list of client nodes has changed for the given canvas. Let the
frontend request the actual list of node IDs when it needs, possibly at a later time.

Source/WebInspectorUI:

* UserInterface/Controllers/CanvasManager.js:
(WebInspector.CanvasManager.prototype.cssCanvasClientNodesChanged):
* UserInterface/Models/Canvas.js:
(WebInspector.Canvas.prototype.requestCSSCanvasClientNodes):
(WebInspector.Canvas.prototype.cssCanvasClientNodesChanged):
* UserInterface/Protocol/CanvasObserver.js:
(WebInspector.CanvasObserver.prototype.cssCanvasClientNodesChanged):

* Localizations/en.lproj/localizedStrings.js:
* UserInterface/Views/CanvasDetailsSidebarPanel.js:
(WebInspector.CanvasDetailsSidebarPanel):
(WebInspector.CanvasDetailsSidebarPanel.prototype.set canvas):
(WebInspector.CanvasDetailsSidebarPanel.prototype.initialLayout):
(WebInspector.CanvasDetailsSidebarPanel.prototype.layout):
(WebInspector.CanvasDetailsSidebarPanel.prototype._refreshCSSCanvasSection):
(WebInspector.CanvasDetailsSidebarPanel.prototype._formatMemoryRow):
Add CSS section for CSS canvases. Currently displays a list of node links, each of which is
using the selected canvas via -webkit-canvas.

* UserInterface/Main.html:
* UserInterface/Views/CanvasDetailsSidebarPanel.css: Added.
(.sidebar > .panel.details.canvas .details-section > .content .row.simple > .value > .node-link):

* UserInterface/Controllers/DOMTreeManager.js:
(WebInspector.DOMTreeManager.prototype.ensureDocument):
* UserInterface/Models/Canvas.js:
(WebInspector.Canvas.prototype.requestNode):
* UserInterface/Views/SearchSidebarPanel.js:
(WebInspector.SearchSidebarPanel.prototype.performSearch):
Add convenience function that will call DOMAgent.getDocument with an empty function. Should
be used when it is necessary that the document has been sent to the frontend, but the
document node itself is not needed.

LayoutTests:

* inspector/canvas/css-canvas-clients-expected.txt: Added.
* inspector/canvas/css-canvas-clients.html: Added.
* platform/mac/TestExpectations:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (219267 => 219268)


--- trunk/LayoutTests/ChangeLog	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/LayoutTests/ChangeLog	2017-07-07 21:30:47 UTC (rev 219268)
@@ -1,3 +1,14 @@
+2017-07-07  Devin Rousso  <[email protected]>
+
+        Web Inspector: Show all elements currently using a given CSS Canvas
+        https://bugs.webkit.org/show_bug.cgi?id=173965
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/canvas/css-canvas-clients-expected.txt: Added.
+        * inspector/canvas/css-canvas-clients.html: Added.
+        * platform/mac/TestExpectations:
+
 2017-07-07  Matt Lewis  <[email protected]>
 
         Adjusted test expectations for webrtc/video-replace-muted-track.html.

Added: trunk/LayoutTests/inspector/canvas/css-canvas-clients-expected.txt (0 => 219268)


--- trunk/LayoutTests/inspector/canvas/css-canvas-clients-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/inspector/canvas/css-canvas-clients-expected.txt	2017-07-07 21:30:47 UTC (rev 219268)
@@ -0,0 +1,22 @@
+Test that CanvasAgent tracks changes in the client nodes of a CSS canvas.
+
+
+== Running test suite: Canvas.CSSCanvasClients
+-- Running test case: Canvas.CSSCanvasClients.InitialLoad
+PASS: CanvasManager should have one canvas.
+PASS: Canvas should have CSS name "css-canvas".
+PASS: There should be no client nodes.
+
+-- Running test case: Canvas.CSSCanvasClients.Create
+PASS: Canvas with created client should have CSS name "css-canvas".
+PASS: There should be one client node.
+PASS: Client node "div" is valid.
+
+-- Running test case: Canvas.CSSCanvasClients.Destroy
+PASS: Canvas with destroyed client should have CSS name "css-canvas".
+PASS: There should be no client nodes.
+
+-- Running test case: Canvas.CSSCanvasClients.InvalidCanvasId
+PASS: Should produce an error.
+Error: Invalid canvas identifier
+

Added: trunk/LayoutTests/inspector/canvas/css-canvas-clients.html (0 => 219268)


--- trunk/LayoutTests/inspector/canvas/css-canvas-clients.html	                        (rev 0)
+++ trunk/LayoutTests/inspector/canvas/css-canvas-clients.html	2017-07-07 21:30:47 UTC (rev 219268)
@@ -0,0 +1,124 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+function load() {
+    window.context2d = document.getCSSCanvasContext("2d", "css-canvas", 10, 10);
+
+    runTest();
+}
+
+let cssCanvasClients = [];
+
+function createCSSCanvasClient() {
+    cssCanvasClients.push(document.body.appendChild(document.createElement("div")));
+}
+
+function destroyCSSCanvasClients() {
+    for (let cssCanvasClient of cssCanvasClients)
+        cssCanvasClient.remove();
+
+    cssCanvasClients = [];
+
+    setTimeout(() => { GCController.collect(); }, 0);
+}
+
+function test() {
+    let suite = InspectorTest.createAsyncSuite("Canvas.CSSCanvasClients");
+
+    function logClientNodes(clientNodes) {
+        for (let clientNode of clientNodes) {
+            if (clientNode)
+                InspectorTest.pass(`Client node "${clientNode.appropriateSelectorFor()}" is valid.`);
+            else
+                InspectorTest.fail("Invalid client node.");
+        }
+    }
+
+    suite.addTestCase({
+        name: "Canvas.CSSCanvasClients.InitialLoad",
+        description: "Check that the CanvasManager has one CSS canvas initially.",
+        test(resolve, reject) {
+            let canvases = WebInspector.canvasManager.canvases;
+            InspectorTest.expectEqual(canvases.length, 1, "CanvasManager should have one canvas.");
+            if (!canvases.length) {
+                reject("Missing canvas.");
+                return;
+            }
+
+            InspectorTest.expectEqual(canvases[0].cssCanvasName, "css-canvas", `Canvas should have CSS name "css-canvas".`);
+            canvases[0].requestCSSCanvasClientNodes((clientNodes) => {
+                InspectorTest.expectEqual(clientNodes.length, 0, "There should be no client nodes.");
+                logClientNodes(clientNodes);
+                resolve();
+            });
+        }
+    });
+
+    suite.addTestCase({
+        name: "Canvas.CSSCanvasClients.Create",
+        description: "Check that creating a CSS canvas client node is tracked correctly.",
+        test(resolve, reject) {
+            WebInspector.Canvas.awaitEvent(WebInspector.Canvas.Event.CSSCanvasClientNodesChanged)
+            .then((event) => {
+                InspectorTest.expectEqual(event.target.cssCanvasName, "css-canvas", `Canvas with created client should have CSS name "css-canvas".`);
+                event.target.requestCSSCanvasClientNodes((clientNodes) => {
+                    InspectorTest.expectEqual(clientNodes.length, 1, "There should be one client node.");
+                    logClientNodes(clientNodes);
+                    resolve();
+                });
+            });
+
+            InspectorTest.evaluateInPage(`createCSSCanvasClient()`);
+        }
+    });
+
+    suite.addTestCase({
+        name: "Canvas.CSSCanvasClients.Destroy",
+        description: "Check that destroying a CSS canvas client node is tracked correctly.",
+        test(resolve, reject) {
+            WebInspector.Canvas.awaitEvent(WebInspector.Canvas.Event.CSSCanvasClientNodesChanged)
+            .then((event) => {
+                InspectorTest.expectEqual(event.target.cssCanvasName, "css-canvas", `Canvas with destroyed client should have CSS name "css-canvas".`);
+                event.target.requestCSSCanvasClientNodes((clientNodes) => {
+                    InspectorTest.expectEqual(clientNodes.length, 0, "There should be no client nodes.");
+                    logClientNodes(clientNodes);
+                    resolve();
+                });
+            });
+
+            InspectorTest.evaluateInPage(`destroyCSSCanvasClients()`);
+        }
+    });
+
+    // ------
+
+    suite.addTestCase({
+        name: "Canvas.CSSCanvasClients.InvalidCanvasId",
+        description: "Invalid canvas identifiers should cause an error.",
+        test(resolve, reject) {
+            const canvasId = "DOES_NOT_EXIST";
+            CanvasAgent.requestCSSCanvasClientNodes(canvasId, (error, clientNodeIds) => {
+                InspectorTest.expectThat(error, "Should produce an error.");
+                InspectorTest.log("Error: " + error);
+                resolve();
+            });
+        }
+    });
+
+    suite.runTestCasesAndFinish();
+}
+</script>
+<style>
+    div {
+        width: 10px;
+        height: 10px;
+        background-image: -webkit-canvas(css-canvas);
+    }
+</style>
+</head>
+<body _onload_="load()">
+    <p>Test that CanvasAgent tracks changes in the client nodes of a CSS canvas.</p>
+</body>
+</html>

Modified: trunk/LayoutTests/platform/mac/TestExpectations (219267 => 219268)


--- trunk/LayoutTests/platform/mac/TestExpectations	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/LayoutTests/platform/mac/TestExpectations	2017-07-07 21:30:47 UTC (rev 219268)
@@ -1141,6 +1141,7 @@
 
 webkit.org/b/174066 inspector/canvas/create-context-webgl2.html [ Pass Timeout ]
 webkit.org/b/174066 inspector/canvas/create-context-webgpu.html [ Pass Timeout ]
+webkit.org/b/174272 inspector/canvas/css-canvas-clients.html [ Pass Timeout ]
 webkit.org/b/170615 inspector/codemirror/prettyprinting-css.html [ Pass Timeout ]
 webkit.org/b/153460 inspector/codemirror/prettyprinting-css-rules.html [ Pass Timeout ]
 webkit.org/b/160048 [ Debug ] inspector/codemirror/prettyprinting-_javascript_.html [ Pass Timeout ]

Modified: trunk/Source/_javascript_Core/ChangeLog (219267 => 219268)


--- trunk/Source/_javascript_Core/ChangeLog	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-07-07 21:30:47 UTC (rev 219268)
@@ -1,3 +1,16 @@
+2017-07-07  Devin Rousso  <[email protected]>
+
+        Web Inspector: Show all elements currently using a given CSS Canvas
+        https://bugs.webkit.org/show_bug.cgi?id=173965
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/protocol/Canvas.json:
+         - Add `requestCSSCanvasClientNodes` command for getting the node IDs all nodes using this
+           canvas via -webkit-canvas.
+         - Add `cssCanvasClientNodesChanged` event that is dispatched whenever a node is
+           added/removed from the list of -webkit-canvas clients.
+
 2017-07-07  Mark Lam  <[email protected]>
 
         \n\r is not the same as \r\n.

Modified: trunk/Source/_javascript_Core/inspector/protocol/Canvas.json (219267 => 219268)


--- trunk/Source/_javascript_Core/inspector/protocol/Canvas.json	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/Source/_javascript_Core/inspector/protocol/Canvas.json	2017-07-07 21:30:47 UTC (rev 219268)
@@ -73,6 +73,16 @@
             ]
         },
         {
+            "name": "requestCSSCanvasClientNodes",
+            "description": "Gets all the nodes that are using this canvas via -webkit-canvas.",
+            "parameters": [
+                { "name": "canvasId", "$ref": "CanvasId" }
+            ],
+            "returns": [
+                { "name": "clientNodeIds", "type": "array", "items": { "$ref": "DOM.NodeId" } }
+            ]
+        },
+        {
             "name": "resolveCanvasContext",
             "description": "Resolves _javascript_ canvas context object for given canvasId.",
             "parameters": [
@@ -103,6 +113,12 @@
                 { "name": "canvasId", "$ref": "CanvasId", "description": "Identifier of canvas that changed." },
                 { "name": "memoryCost", "type": "number", "description": "New memory cost value for the canvas in bytes." }
             ]
+        },
+        {
+            "name": "cssCanvasClientNodesChanged",
+            "parameters": [
+                { "name": "canvasId", "$ref": "CanvasId", "description": "Identifier of canvas that changed." }
+            ]
         }
     ]
 }

Modified: trunk/Source/WebCore/ChangeLog (219267 => 219268)


--- trunk/Source/WebCore/ChangeLog	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/Source/WebCore/ChangeLog	2017-07-07 21:30:47 UTC (rev 219268)
@@ -1,3 +1,42 @@
+2017-07-07  Devin Rousso  <[email protected]>
+
+        Web Inspector: Show all elements currently using a given CSS Canvas
+        https://bugs.webkit.org/show_bug.cgi?id=173965
+
+        Reviewed by Joseph Pecoraro.
+
+        Test: inspector/canvas/css-canvas-clients.html
+
+        * css/CSSImageGeneratorValue.cpp:
+        (WebCore::CSSImageGeneratorValue::addClient):
+        (WebCore::CSSImageGeneratorValue::removeClient):
+        * css/CSSImageGeneratorValue.h:
+        (WebCore::CSSImageGeneratorValue::clients):
+        * html/HTMLCanvasElement.cpp:
+        (WebCore::HTMLCanvasElement::addObserver):
+        (WebCore::HTMLCanvasElement::removeObserver):
+        (WebCore::HTMLCanvasElement::cssCanvasClients):
+        Each time an observer is added/removed for a given HTMLCanvasElement, send an event to the
+        inspector frontend that the CSS canvas client nodes have changed. Additionally, anytime a
+        client/use is added/removed from one of the observing CSSCanvasValue, fire the same event.
+
+        * css/CSSCanvasValue.h:
+        (isType):
+        * html/HTMLCanvasElement.h:
+        (WebCore::CanvasObserver::isCSSCanvasValueObserver):
+        Allows type traits to distinguish CanvasObserver from CSSCanvasValue::CanvasObserverProxy.
+
+        * inspector/InspectorCanvasAgent.h:
+        * inspector/InspectorCanvasAgent.cpp:
+        (WebCore::InspectorCanvasAgent::requestCSSCanvasClientNodes):
+        (WebCore::InspectorCanvasAgent::didChangeCSSCanvasClientNodes):
+        * inspector/InspectorInstrumentation.h:
+        (WebCore::InspectorInstrumentation::didChangeCSSCanvasClientNodes):
+        * inspector/InspectorInstrumentation.cpp:
+        (WebCore::InspectorInstrumentation::didChangeCSSCanvasClientNodesImpl):
+        Notify the frontend that the list of client nodes has changed for the given canvas. Let the
+        frontend request the actual list of node IDs when it needs, possibly at a later time.
+
 2017-07-07  Jer Noble  <[email protected]>
 
         AVPlayer can continue to be active after released by MediaPlayerPrivateAVFoundationObjC.

Modified: trunk/Source/WebCore/css/CSSCanvasValue.h (219267 => 219268)


--- trunk/Source/WebCore/css/CSSCanvasValue.h	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/Source/WebCore/css/CSSCanvasValue.h	2017-07-07 21:30:47 UTC (rev 219268)
@@ -44,19 +44,13 @@
     bool isFixedSize() const { return true; }
     FloatSize fixedSize(const RenderElement*);
 
+    HTMLCanvasElement* element() const { return m_element; }
+
     bool isPending() const { return false; }
     void loadSubimages(CachedResourceLoader&, const ResourceLoaderOptions&) { }
 
     bool equals(const CSSCanvasValue&) const;
 
-private:
-    explicit CSSCanvasValue(const String& name)
-        : CSSImageGeneratorValue(CanvasClass)
-        , m_canvasObserver(*this)
-        , m_name(name)
-    {
-    }
-
     // NOTE: We put the CanvasObserver in a member instead of inheriting from it
     // to avoid adding a vptr to CSSCanvasValue.
     class CanvasObserverProxy final : public CanvasObserver {
@@ -70,6 +64,10 @@
         {
         }
 
+        bool isCanvasObserverProxy() const final { return true; }
+
+        const CSSCanvasValue& ownerValue() const { return m_ownerValue; }
+
     private:
         void canvasChanged(HTMLCanvasElement& canvas, const FloatRect& changedRect) final
         {
@@ -87,6 +85,14 @@
         CSSCanvasValue& m_ownerValue;
     };
 
+private:
+    explicit CSSCanvasValue(const String& name)
+        : CSSImageGeneratorValue(CanvasClass)
+        , m_canvasObserver(*this)
+        , m_name(name)
+    {
+    }
+
     void canvasChanged(HTMLCanvasElement&, const FloatRect& changedRect);
     void canvasResized(HTMLCanvasElement&);
     void canvasDestroyed(HTMLCanvasElement&);
@@ -105,3 +111,7 @@
 
 SPECIALIZE_TYPE_TRAITS_CSS_VALUE(CSSCanvasValue, isCanvasValue())
 
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::CSSCanvasValue::CanvasObserverProxy)
+    static bool isType(const WebCore::CanvasObserver& canvasObserver) { return canvasObserver.isCanvasObserverProxy(); }
+SPECIALIZE_TYPE_TRAITS_END()
+

Modified: trunk/Source/WebCore/css/CSSImageGeneratorValue.cpp (219267 => 219268)


--- trunk/Source/WebCore/css/CSSImageGeneratorValue.cpp	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/Source/WebCore/css/CSSImageGeneratorValue.cpp	2017-07-07 21:30:47 UTC (rev 219268)
@@ -34,6 +34,8 @@
 #include "CSSImageValue.h"
 #include "CSSNamedImageValue.h"
 #include "GeneratedImage.h"
+#include "HTMLCanvasElement.h"
+#include "InspectorInstrumentation.h"
 #include "RenderElement.h"
 
 namespace WebCore {
@@ -69,13 +71,27 @@
 {
     if (m_clients.isEmpty())
         ref();
+
     m_clients.add(&renderer);
+
+    if (is<CSSCanvasValue>(this)) {
+        if (HTMLCanvasElement* canvasElement = downcast<CSSCanvasValue>(this)->element())
+            InspectorInstrumentation::didChangeCSSCanvasClientNodes(*canvasElement);
+    }
 }
 
 void CSSImageGeneratorValue::removeClient(RenderElement& renderer)
 {
     ASSERT(m_clients.contains(&renderer));
-    if (m_clients.remove(&renderer) && m_clients.isEmpty())
+    if (!m_clients.remove(&renderer))
+        return;
+
+    if (is<CSSCanvasValue>(this)) {
+        if (HTMLCanvasElement* canvasElement = downcast<CSSCanvasValue>(this)->element())
+            InspectorInstrumentation::didChangeCSSCanvasClientNodes(*canvasElement);
+    }
+
+    if (m_clients.isEmpty())
         deref();
 }
 

Modified: trunk/Source/WebCore/css/CSSImageGeneratorValue.h (219267 => 219268)


--- trunk/Source/WebCore/css/CSSImageGeneratorValue.h	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/Source/WebCore/css/CSSImageGeneratorValue.h	2017-07-07 21:30:47 UTC (rev 219268)
@@ -45,6 +45,7 @@
 
     void addClient(RenderElement&);
     void removeClient(RenderElement&);
+    const HashCountedSet<RenderElement*>& clients() const { return m_clients; }
 
     RefPtr<Image> image(RenderElement&, const FloatSize&);
 
@@ -61,7 +62,6 @@
 
     GeneratedImage* cachedImageForSize(FloatSize);
     void saveCachedImageForSize(FloatSize, GeneratedImage&);
-    const HashCountedSet<RenderElement*>& clients() const { return m_clients; }
 
     // Helper functions for Crossfade and Filter.
     static CachedImage* cachedImageForCSSValue(CSSValue&, CachedResourceLoader&, const ResourceLoaderOptions&);

Modified: trunk/Source/WebCore/html/HTMLCanvasElement.cpp (219267 => 219268)


--- trunk/Source/WebCore/html/HTMLCanvasElement.cpp	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/Source/WebCore/html/HTMLCanvasElement.cpp	2017-07-07 21:30:47 UTC (rev 219268)
@@ -30,6 +30,7 @@
 
 #include "Blob.h"
 #include "BlobCallback.h"
+#include "CSSCanvasValue.h"
 #include "CanvasGradient.h"
 #include "CanvasPattern.h"
 #include "CanvasRenderingContext2D.h"
@@ -45,6 +46,7 @@
 #include "ImageData.h"
 #include "InspectorInstrumentation.h"
 #include "MIMETypeRegistry.h"
+#include "RenderElement.h"
 #include "RenderHTMLCanvas.h"
 #include "RuntimeEnabledFeatures.h"
 #include "ScriptController.h"
@@ -168,13 +170,35 @@
 void HTMLCanvasElement::addObserver(CanvasObserver& observer)
 {
     m_observers.add(&observer);
+
+    if (is<CSSCanvasValue::CanvasObserverProxy>(observer))
+        InspectorInstrumentation::didChangeCSSCanvasClientNodes(*this);
 }
 
 void HTMLCanvasElement::removeObserver(CanvasObserver& observer)
 {
     m_observers.remove(&observer);
+
+    if (is<CSSCanvasValue::CanvasObserverProxy>(observer))
+        InspectorInstrumentation::didChangeCSSCanvasClientNodes(*this);
 }
 
+HashSet<Element*> HTMLCanvasElement::cssCanvasClients() const
+{
+    HashSet<Element*> cssCanvasClients;
+    for (auto& observer : m_observers) {
+        if (!is<CSSCanvasValue::CanvasObserverProxy>(observer))
+            continue;
+
+        auto clients = downcast<CSSCanvasValue::CanvasObserverProxy>(observer)->ownerValue().clients();
+        for (auto& entry : clients) {
+            if (Element* element = entry.key->element())
+                cssCanvasClients.add(element);
+        }
+    }
+    return cssCanvasClients;
+}
+
 void HTMLCanvasElement::setHeight(unsigned value)
 {
     setAttributeWithoutSynchronization(heightAttr, AtomicString::number(limitToOnlyHTMLNonNegative(value, defaultHeight)));

Modified: trunk/Source/WebCore/html/HTMLCanvasElement.h (219267 => 219268)


--- trunk/Source/WebCore/html/HTMLCanvasElement.h	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/Source/WebCore/html/HTMLCanvasElement.h	2017-07-07 21:30:47 UTC (rev 219268)
@@ -32,6 +32,7 @@
 #include "IntSize.h"
 #include <memory>
 #include <wtf/Forward.h>
+#include <wtf/HashSet.h>
 
 #if ENABLE(WEBGL)
 #include "WebGLContextAttributes.h"
@@ -58,6 +59,8 @@
 public:
     virtual ~CanvasObserver() { }
 
+    virtual bool isCanvasObserverProxy() const { return false; }
+
     virtual void canvasChanged(HTMLCanvasElement&, const FloatRect& changedRect) = 0;
     virtual void canvasResized(HTMLCanvasElement&) = 0;
     virtual void canvasDestroyed(HTMLCanvasElement&) = 0;
@@ -71,6 +74,7 @@
 
     void addObserver(CanvasObserver&);
     void removeObserver(CanvasObserver&);
+    HashSet<Element*> cssCanvasClients() const;
 
     unsigned width() const { return size().width(); }
     unsigned height() const { return size().height(); }

Modified: trunk/Source/WebCore/inspector/InspectorCanvasAgent.cpp (219267 => 219268)


--- trunk/Source/WebCore/inspector/InspectorCanvasAgent.cpp	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/Source/WebCore/inspector/InspectorCanvasAgent.cpp	2017-07-07 21:30:47 UTC (rev 219268)
@@ -29,6 +29,7 @@
 #include "CanvasRenderingContext.h"
 #include "CanvasRenderingContext2D.h"
 #include "Document.h"
+#include "Element.h"
 #include "Frame.h"
 #include "InspectorDOMAgent.h"
 #include "InspectorPageAgent.h"
@@ -170,6 +171,21 @@
         errorString = ASCIILiteral("Unsupported canvas context type");
 }
 
+void InspectorCanvasAgent::requestCSSCanvasClientNodes(ErrorString& errorString, const String& canvasId, RefPtr<Inspector::Protocol::Array<int>>& result)
+{
+    const CanvasEntry* canvasEntry = getCanvasEntry(canvasId);
+    if (!canvasEntry) {
+        errorString = ASCIILiteral("Invalid canvas identifier");
+        return;
+    }
+
+    result = Inspector::Protocol::Array<int>::create();
+    for (Element* element : canvasEntry->element->cssCanvasClients()) {
+        if (int documentNodeId = m_instrumentingAgents.inspectorDOMAgent()->boundNodeId(&element->document()))
+            result->addItem(m_instrumentingAgents.inspectorDOMAgent()->pushNodeToFrontend(errorString, documentNodeId, element));
+    }
+}
+
 static JSC::JSValue contextAsScriptValue(JSC::ExecState& state, CanvasRenderingContext* context)
 {
     JSC::JSLockHolder lock(&state);
@@ -250,6 +266,15 @@
     m_canvasToCSSCanvasId.set(&canvasElement, name);
 }
 
+void InspectorCanvasAgent::didChangeCSSCanvasClientNodes(HTMLCanvasElement& canvasElement)
+{
+    const CanvasEntry* canvasEntry = getCanvasEntry(canvasElement);
+    if (!canvasEntry)
+        return;
+
+    m_frontendDispatcher->cssCanvasClientNodesChanged(canvasEntry->identifier);
+}
+
 void InspectorCanvasAgent::didCreateCanvasRenderingContext(HTMLCanvasElement& canvasElement)
 {
     if (m_canvasEntries.contains(&canvasElement)) {

Modified: trunk/Source/WebCore/inspector/InspectorCanvasAgent.h (219267 => 219268)


--- trunk/Source/WebCore/inspector/InspectorCanvasAgent.h	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/Source/WebCore/inspector/InspectorCanvasAgent.h	2017-07-07 21:30:47 UTC (rev 219268)
@@ -63,11 +63,13 @@
     void disable(ErrorString&) override;
     void requestNode(ErrorString&, const String& canvasId, int* nodeId) override;
     void requestContent(ErrorString&, const String& canvasId, String* content) override;
+    void requestCSSCanvasClientNodes(ErrorString&, const String& canvasId, RefPtr<Inspector::Protocol::Array<int>>&) override;
     void resolveCanvasContext(ErrorString&, const String& canvasId, const String* const objectGroup, RefPtr<Inspector::Protocol::Runtime::RemoteObject>&) override;
 
     // InspectorInstrumentation
     void frameNavigated(Frame&);
     void didCreateCSSCanvas(HTMLCanvasElement&, const String&);
+    void didChangeCSSCanvasClientNodes(HTMLCanvasElement&);
     void didCreateCanvasRenderingContext(HTMLCanvasElement&);
     void didChangeCanvasMemory(HTMLCanvasElement&);
 

Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp (219267 => 219268)


--- trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp	2017-07-07 21:30:47 UTC (rev 219268)
@@ -999,6 +999,12 @@
         canvasAgent->didCreateCSSCanvas(canvasElement, name);
 }
 
+void InspectorInstrumentation::didChangeCSSCanvasClientNodesImpl(InstrumentingAgents* instrumentingAgents, HTMLCanvasElement& canvasElement)
+{
+    if (InspectorCanvasAgent* canvasAgent = instrumentingAgents->inspectorCanvasAgent())
+        canvasAgent->didChangeCSSCanvasClientNodes(canvasElement);
+}
+
 void InspectorInstrumentation::didCreateCanvasRenderingContextImpl(InstrumentingAgents* instrumentingAgents, HTMLCanvasElement& canvasElement)
 {
     if (InspectorCanvasAgent* canvasAgent = instrumentingAgents->inspectorCanvasAgent())

Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.h (219267 => 219268)


--- trunk/Source/WebCore/inspector/InspectorInstrumentation.h	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.h	2017-07-07 21:30:47 UTC (rev 219268)
@@ -247,6 +247,7 @@
 #endif
 
     static void didCreateCSSCanvas(HTMLCanvasElement&, const String&);
+    static void didChangeCSSCanvasClientNodes(HTMLCanvasElement&);
     static void didCreateCanvasRenderingContext(HTMLCanvasElement&);
     static void didChangeCanvasMemory(HTMLCanvasElement&);
 
@@ -423,6 +424,7 @@
     static void updateApplicationCacheStatusImpl(InstrumentingAgents&, Frame&);
 
     static void didCreateCSSCanvasImpl(InstrumentingAgents*, HTMLCanvasElement&, const String&);
+    static void didChangeCSSCanvasClientNodesImpl(InstrumentingAgents*, HTMLCanvasElement&);
     static void didCreateCanvasRenderingContextImpl(InstrumentingAgents*, HTMLCanvasElement&);
     static void didChangeCanvasMemoryImpl(InstrumentingAgents*, HTMLCanvasElement&);
 
@@ -1189,7 +1191,14 @@
     if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(&canvasElement.document()))
         didCreateCSSCanvasImpl(instrumentingAgents, canvasElement, name);
 }
-    
+
+inline void InspectorInstrumentation::didChangeCSSCanvasClientNodes(HTMLCanvasElement& canvasElement)
+{
+    FAST_RETURN_IF_NO_FRONTENDS(void());
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(&canvasElement.document()))
+        didChangeCSSCanvasClientNodesImpl(instrumentingAgents, canvasElement);
+}
+
 inline void InspectorInstrumentation::didCreateCanvasRenderingContext(HTMLCanvasElement& canvasElement)
 {
     if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(&canvasElement.document()))

Modified: trunk/Source/WebInspectorUI/ChangeLog (219267 => 219268)


--- trunk/Source/WebInspectorUI/ChangeLog	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/Source/WebInspectorUI/ChangeLog	2017-07-07 21:30:47 UTC (rev 219268)
@@ -1,3 +1,43 @@
+2017-07-07  Devin Rousso  <[email protected]>
+
+        Web Inspector: Show all elements currently using a given CSS Canvas
+        https://bugs.webkit.org/show_bug.cgi?id=173965
+
+        Reviewed by Joseph Pecoraro.
+
+        * UserInterface/Controllers/CanvasManager.js:
+        (WebInspector.CanvasManager.prototype.cssCanvasClientNodesChanged):
+        * UserInterface/Models/Canvas.js:
+        (WebInspector.Canvas.prototype.requestCSSCanvasClientNodes):
+        (WebInspector.Canvas.prototype.cssCanvasClientNodesChanged):
+        * UserInterface/Protocol/CanvasObserver.js:
+        (WebInspector.CanvasObserver.prototype.cssCanvasClientNodesChanged):
+
+        * Localizations/en.lproj/localizedStrings.js:
+        * UserInterface/Views/CanvasDetailsSidebarPanel.js:
+        (WebInspector.CanvasDetailsSidebarPanel):
+        (WebInspector.CanvasDetailsSidebarPanel.prototype.set canvas):
+        (WebInspector.CanvasDetailsSidebarPanel.prototype.initialLayout):
+        (WebInspector.CanvasDetailsSidebarPanel.prototype.layout):
+        (WebInspector.CanvasDetailsSidebarPanel.prototype._refreshCSSCanvasSection):
+        (WebInspector.CanvasDetailsSidebarPanel.prototype._formatMemoryRow):
+        Add CSS section for CSS canvases. Currently displays a list of node links, each of which is
+        using the selected canvas via -webkit-canvas.
+
+        * UserInterface/Main.html:
+        * UserInterface/Views/CanvasDetailsSidebarPanel.css: Added.
+        (.sidebar > .panel.details.canvas .details-section > .content .row.simple > .value > .node-link):
+
+        * UserInterface/Controllers/DOMTreeManager.js:
+        (WebInspector.DOMTreeManager.prototype.ensureDocument):
+        * UserInterface/Models/Canvas.js:
+        (WebInspector.Canvas.prototype.requestNode):
+        * UserInterface/Views/SearchSidebarPanel.js:
+        (WebInspector.SearchSidebarPanel.prototype.performSearch):
+        Add convenience function that will call DOMAgent.getDocument with an empty function. Should
+        be used when it is necessary that the document has been sent to the frontend, but the
+        document node itself is not needed.
+
 2017-07-07  Joseph Pecoraro  <[email protected]>
 
         Web Inspector: Clean up some unnecessary constructors

Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (219267 => 219268)


--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2017-07-07 21:30:47 UTC (rev 219268)
@@ -139,6 +139,7 @@
 localizedStrings["Bubbling"] = "Bubbling";
 localizedStrings["Busy"] = "Busy";
 localizedStrings["CSP Hash"] = "CSP Hash";
+localizedStrings["CSS"] = "CSS";
 localizedStrings["CSS Canvas"] = "CSS Canvas";
 localizedStrings["CSS canvas ā€œ%sā€"] = "CSS canvas ā€œ%sā€";
 localizedStrings["Cached"] = "Cached";
@@ -588,6 +589,7 @@
 localizedStrings["No preview available"] = "No preview available";
 localizedStrings["Node"] = "Node";
 localizedStrings["Node Removed"] = "Node Removed";
+localizedStrings["Nodes"] = "Nodes";
 localizedStrings["Not found"] = "Not found";
 localizedStrings["Number"] = "Number";
 localizedStrings["Numeric"] = "Numeric";

Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js (219267 => 219268)


--- trunk/Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js	2017-07-07 21:30:47 UTC (rev 219268)
@@ -84,6 +84,18 @@
         canvas.memoryCost = memoryCost;
     }
 
+    cssCanvasClientNodesChanged(canvasIdentifier)
+    {
+        // Called from WebInspector.CanvasObserver.
+
+        let canvas = this._canvasIdentifierMap.get(canvasIdentifier);
+        console.assert(canvas);
+        if (!canvas)
+            return;
+
+        canvas.cssCanvasClientNodesChanged();
+    }
+
     // Private
 
     _mainResourceDidChange(event)

Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/DOMTreeManager.js (219267 => 219268)


--- trunk/Source/WebInspectorUI/UserInterface/Controllers/DOMTreeManager.js	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/DOMTreeManager.js	2017-07-07 21:30:47 UTC (rev 219268)
@@ -85,6 +85,11 @@
         DOMAgent.getDocument(onDocumentAvailable.bind(this));
     }
 
+    ensureDocument()
+    {
+        this.requestDocument(function(){});
+    }
+
     pushNodeToFrontend(objectId, callback)
     {
         this._dispatchWhenDocumentAvailable(DOMAgent.requestNode.bind(DOMAgent, objectId), callback);

Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (219267 => 219268)


--- trunk/Source/WebInspectorUI/UserInterface/Main.html	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html	2017-07-07 21:30:47 UTC (rev 219268)
@@ -46,6 +46,7 @@
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
+    <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""

Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Canvas.js (219267 => 219268)


--- trunk/Source/WebInspectorUI/UserInterface/Models/Canvas.js	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Canvas.js	2017-07-07 21:30:47 UTC (rev 219268)
@@ -40,6 +40,8 @@
         this._cssCanvasName = cssCanvasName || "";
         this._contextAttributes = contextAttributes || {};
         this._memoryCost = memoryCost || NaN;
+
+        this._cssCanvasClientNodes = null;
     }
 
     // Static
@@ -140,16 +142,16 @@
             return;
         }
 
-        WebInspector.domTreeManager.requestDocument((document) => {
-            CanvasAgent.requestNode(this._identifier, (error, nodeId) => {
-                if (error) {
-                    callback(null);
-                    return;
-                }
+        WebInspector.domTreeManager.ensureDocument();
 
-                this._domNode = WebInspector.domTreeManager.nodeForId(nodeId);
-                callback(this._domNode);
-            });
+        CanvasAgent.requestNode(this._identifier, (error, nodeId) => {
+            if (error) {
+                callback(null);
+                return;
+            }
+
+            this._domNode = WebInspector.domTreeManager.nodeForId(nodeId);
+            callback(this._domNode);
         });
     }
 
@@ -165,6 +167,33 @@
         });
     }
 
+    requestCSSCanvasClientNodes(callback)
+    {
+        if (!this._cssCanvasName) {
+            callback([]);
+            return;
+        }
+
+        if (this._cssCanvasClientNodes) {
+            callback(this._cssCanvasClientNodes);
+            return;
+        }
+
+        WebInspector.domTreeManager.ensureDocument();
+
+        CanvasAgent.requestCSSCanvasClientNodes(this._identifier, (error, clientNodeIds) => {
+            if (error) {
+                callback([]);
+                return;
+            }
+
+            clientNodeIds = Array.isArray(clientNodeIds) ? clientNodeIds : [];
+            this._cssCanvasClientNodes = clientNodeIds.map((clientNodeId) => WebInspector.domTreeManager.nodeForId(clientNodeId));
+
+            callback(this._cssCanvasClientNodes);
+        });
+    }
+
     saveIdentityToCookie(cookie)
     {
         cookie[WebInspector.Canvas.FrameURLCookieKey] = this._frame.url.hash;
@@ -175,6 +204,18 @@
             cookie[WebInspector.Canvas.NodePathCookieKey] = this._domNode.path;
 
     }
+
+    cssCanvasClientNodesChanged()
+    {
+        // Called from WebInspector.CanvasManager.
+
+        if (!this._cssCanvasName)
+            return;
+
+        this._cssCanvasClientNodes = null;
+
+        this.dispatchEventToListeners(WebInspector.Canvas.Event.CSSCanvasClientNodesChanged);
+    }
 };
 
 WebInspector.Canvas._nextUniqueDisplayNameNumber = 1;
@@ -193,4 +234,5 @@
 
 WebInspector.Canvas.Event = {
     MemoryChanged: "canvas-memory-changed",
+    CSSCanvasClientNodesChanged: "canvas-css-canvas-client-nodes-changed",
 };

Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/CanvasObserver.js (219267 => 219268)


--- trunk/Source/WebInspectorUI/UserInterface/Protocol/CanvasObserver.js	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/CanvasObserver.js	2017-07-07 21:30:47 UTC (rev 219268)
@@ -41,4 +41,9 @@
     {
         WebInspector.canvasManager.canvasMemoryChanged(canvasId, memoryCost);
     }
+
+    cssCanvasClientNodesChanged(canvasId)
+    {
+        WebInspector.canvasManager.cssCanvasClientNodesChanged(canvasId);
+    }
 };

Copied: trunk/Source/WebInspectorUI/UserInterface/Views/CanvasDetailsSidebarPanel.css (from rev 219267, trunk/Source/WebInspectorUI/UserInterface/Protocol/CanvasObserver.js) (0 => 219268)


--- trunk/Source/WebInspectorUI/UserInterface/Views/CanvasDetailsSidebarPanel.css	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/CanvasDetailsSidebarPanel.css	2017-07-07 21:30:47 UTC (rev 219268)
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+.sidebar > .panel.details.canvas .details-section > .content .row.simple > .value > .node-link {
+    display: block;
+}

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/CanvasDetailsSidebarPanel.js (219267 => 219268)


--- trunk/Source/WebInspectorUI/UserInterface/Views/CanvasDetailsSidebarPanel.js	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/CanvasDetailsSidebarPanel.js	2017-07-07 21:30:47 UTC (rev 219268)
@@ -27,7 +27,7 @@
 {
     constructor()
     {
-        super("canvas-details", WebInspector.UIString("Canvas"));
+        super("canvas", WebInspector.UIString("Canvas"));
 
         this.element.classList.add("canvas");
 
@@ -64,13 +64,17 @@
             this._node = null;
         }
 
-        if (this._canvas)
+        if (this._canvas) {
             this._canvas.removeEventListener(WebInspector.Canvas.Event.MemoryChanged, this._canvasMemoryChanged, this);
+            this._canvas.removeEventListener(WebInspector.Canvas.Event.CSSCanvasClientNodesChanged, this._refreshCSSCanvasSection, this);
+        }
 
         this._canvas = canvas || null;
 
-        if (this._canvas)
+        if (this._canvas) {
             this._canvas.addEventListener(WebInspector.Canvas.Event.MemoryChanged, this._canvasMemoryChanged, this);
+            this._canvas.addEventListener(WebInspector.Canvas.Event.CSSCanvasClientNodesChanged, this._refreshCSSCanvasSection, this);
+        }
 
         this.needsLayout();
     }
@@ -84,6 +88,7 @@
         this._nameRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Name"));
         this._typeRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Type"));
         this._memoryRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Memory"));
+        this._memoryRow.tooltip = WebInspector.UIString("Memory usage of this canvas");
 
         let identitySection = new WebInspector.DetailsSection("canvas-details", WebInspector.UIString("Identity"));
         identitySection.groups = [new WebInspector.DetailsSectionGroup([this._nameRow, this._typeRow, this._memoryRow])];
@@ -104,6 +109,13 @@
         let attributesSection = new WebInspector.DetailsSection("canvas-attributes", WebInspector.UIString("Attributes"));
         attributesSection.groups = [new WebInspector.DetailsSectionGroup([this._attributesDataGridRow])];
         this.contentView.element.appendChild(attributesSection.element);
+
+        this._cssCanvasClientsRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Nodes"));
+
+        this._cssCanvasSection = new WebInspector.DetailsSection("canvas-css", WebInspector.UIString("CSS"));
+        this._cssCanvasSection.groups = [new WebInspector.DetailsSectionGroup([this._cssCanvasClientsRow])];
+        this._cssCanvasSection.element.hidden = true;
+        this.contentView.element.appendChild(this._cssCanvasSection.element);
     }
 
     layout()
@@ -116,6 +128,7 @@
         this._refreshIdentitySection();
         this._refreshSourceSection();
         this._refreshAttributesSection();
+        this._refreshCSSCanvasSection();
     }
 
     sizeDidChange()
@@ -239,6 +252,31 @@
         dataGrid.updateLayoutIfNeeded();
     }
 
+    _refreshCSSCanvasSection()
+    {
+        if (!this._canvas)
+            return;
+
+        if (!this._canvas.cssCanvasName) {
+            this._cssCanvasSection.element.hidden = true;
+            return;
+        }
+
+        this._cssCanvasClientsRow.value = emDash;
+
+        this._cssCanvasSection.element.hidden = false;
+
+        this._canvas.requestCSSCanvasClientNodes((cssCanvasClientNodes) => {
+            if (!cssCanvasClientNodes.length)
+                return;
+
+            let fragment = document.createDocumentFragment();
+            for (let clientNode of cssCanvasClientNodes)
+                fragment.appendChild(WebInspector.linkifyNodeReference(clientNode));
+            this._cssCanvasClientsRow.value = fragment;
+        });
+    }
+
     _formatMemoryRow()
     {
         if (!this._canvas.memoryCost || isNaN(this._canvas.memoryCost)) {
@@ -246,9 +284,7 @@
             return;
         }
 
-        let canvasMemory = Number.bytesToString(this._canvas.memoryCost);
-        this._memoryRow.value = canvasMemory;
-        this._memoryRow.tooltip = WebInspector.UIString("Memory usage of this canvas");
+        this._memoryRow.value = Number.bytesToString(this._canvas.memoryCost);
     }
 
     _canvasMemoryChanged(event)

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SearchSidebarPanel.js (219267 => 219268)


--- trunk/Source/WebInspectorUI/UserInterface/Views/SearchSidebarPanel.js	2017-07-07 20:38:33 UTC (rev 219267)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SearchSidebarPanel.js	2017-07-07 21:30:47 UTC (rev 219268)
@@ -278,7 +278,7 @@
         }
 
         if (window.DOMAgent)
-            WebInspector.domTreeManager.requestDocument(function(){});
+            WebInspector.domTreeManager.ensureDocument();
 
         if (window.PageAgent)
             PageAgent.searchInResources(searchQuery, isCaseSensitive, isRegex, resourcesCallback.bind(this));
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to