Web Inspector: Allow users to log any tracked canvas context
authordrousso@apple.com <drousso@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Jul 2017 20:13:56 +0000 (20:13 +0000)
committerdrousso@apple.com <drousso@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Jul 2017 20:13:56 +0000 (20:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=173397
<rdar://problem/33111581>

Reviewed by Joseph Pecoraro.

Source/JavaScriptCore:

* inspector/protocol/Canvas.json:
Add `resolveCanvasContext` command that returns a RemoteObject for the given canvas context.

Source/WebCore:

Tests: inspector/canvas/resolveCanvasContext-2d.html
       inspector/canvas/resolveCanvasContext-webgl.html
       inspector/canvas/resolveCanvasContext-webgl2.html
       inspector/canvas/resolveCanvasContext-webgpu.html

* inspector/InspectorCanvasAgent.h:
* inspector/InspectorCanvasAgent.cpp:
(WebCore::InspectorCanvasAgent::InspectorCanvasAgent):
(WebCore::contextAsScriptValue):
(WebCore::InspectorCanvasAgent::resolveCanvasContext):

Source/WebInspectorUI:

* Localizations/en.lproj/localizedStrings.js:
* UserInterface/Protocol/RemoteObject.js:
(WebInspector.RemoteObject.resolveCanvasContext):
* UserInterface/Views/CanvasTreeElement.js:
(WebInspector.CanvasTreeElement.prototype.populateContextMenu):

LayoutTests:

* inspector/canvas/resolveCanvasContext-2d-expected.txt: Added.
* inspector/canvas/resolveCanvasContext-2d.html: Added.
* inspector/canvas/resolveCanvasContext-webgl-expected.txt: Added.
* inspector/canvas/resolveCanvasContext-webgl.html: Added.
* inspector/canvas/resolveCanvasContext-webgl2-expected.txt: Added.
* inspector/canvas/resolveCanvasContext-webgl2.html: Added.
* inspector/canvas/resolveCanvasContext-webgpu-expected.txt: Added.
* inspector/canvas/resolveCanvasContext-webgpu.html: Added.
* platform/gtk/TestExpectations:
* platform/ios/TestExpectations:
* platform/win/TestExpectations:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@219150 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
LayoutTests/ChangeLog
LayoutTests/inspector/canvas/resolveCanvasContext-2d-expected.txt [new file with mode: 0644]
LayoutTests/inspector/canvas/resolveCanvasContext-2d.html [new file with mode: 0644]
LayoutTests/inspector/canvas/resolveCanvasContext-webgl-expected.txt [new file with mode: 0644]
LayoutTests/inspector/canvas/resolveCanvasContext-webgl.html [new file with mode: 0644]
LayoutTests/inspector/canvas/resolveCanvasContext-webgl2-expected.txt [new file with mode: 0644]
LayoutTests/inspector/canvas/resolveCanvasContext-webgl2.html [new file with mode: 0644]
LayoutTests/inspector/canvas/resolveCanvasContext-webgpu-expected.txt [new file with mode: 0644]
LayoutTests/inspector/canvas/resolveCanvasContext-webgpu.html [new file with mode: 0644]
LayoutTests/platform/gtk/TestExpectations
LayoutTests/platform/ios/TestExpectations
LayoutTests/platform/win/TestExpectations
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/inspector/protocol/Canvas.json
Source/WebCore/ChangeLog
Source/WebCore/inspector/InspectorCanvasAgent.cpp
Source/WebCore/inspector/InspectorCanvasAgent.h
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js
Source/WebInspectorUI/UserInterface/Views/CanvasTreeElement.js

index 5b5e49e..1957ff8 100644 (file)
@@ -1,3 +1,23 @@
+2017-07-05  Devin Rousso  <drousso@apple.com>
+
+        Web Inspector: Allow users to log any tracked canvas context
+        https://bugs.webkit.org/show_bug.cgi?id=173397
+        <rdar://problem/33111581>
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/canvas/resolveCanvasContext-2d-expected.txt: Added.
+        * inspector/canvas/resolveCanvasContext-2d.html: Added.
+        * inspector/canvas/resolveCanvasContext-webgl-expected.txt: Added.
+        * inspector/canvas/resolveCanvasContext-webgl.html: Added.
+        * inspector/canvas/resolveCanvasContext-webgl2-expected.txt: Added.
+        * inspector/canvas/resolveCanvasContext-webgl2.html: Added.
+        * inspector/canvas/resolveCanvasContext-webgpu-expected.txt: Added.
+        * inspector/canvas/resolveCanvasContext-webgpu.html: Added.
+        * platform/gtk/TestExpectations:
+        * platform/ios/TestExpectations:
+        * platform/win/TestExpectations:
+
 2017-07-05  Antti Koivisto  <antti@apple.com>
 
         Low memory notification shouldn't cause style recalc
diff --git a/LayoutTests/inspector/canvas/resolveCanvasContext-2d-expected.txt b/LayoutTests/inspector/canvas/resolveCanvasContext-2d-expected.txt
new file mode 100644 (file)
index 0000000..d921f24
--- /dev/null
@@ -0,0 +1,12 @@
+Tests for the Canvas.resolveCanvasContext command for 2D contexts.
+
+
+== Running test suite: Canvas.resolveCanvasContext2D
+-- Running test case: Canvas.resolveCanvasContext2D.validIdentifier
+PASS: Payload should have type "object".
+PASS: Payload should have className "CanvasRenderingContext2D".
+
+-- Running test case: Canvas.resolveCanvasContext.invalidIdentifier
+PASS: Should produce an error.
+Error: Invalid canvas identifier
+
diff --git a/LayoutTests/inspector/canvas/resolveCanvasContext-2d.html b/LayoutTests/inspector/canvas/resolveCanvasContext-2d.html
new file mode 100644 (file)
index 0000000..b3e2ebe
--- /dev/null
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
+<script>
+function load() {
+    window.context2d = document.body.appendChild(document.createElement("canvas")).getContext("2d");
+
+    runTest();
+}
+
+function test()
+{
+    let suite = InspectorTest.createAsyncSuite("Canvas.resolveCanvasContext2D");
+
+    suite.addTestCase({
+        name: `Canvas.resolveCanvasContext2D.validIdentifier`,
+        description: "Should return a valid object for the given canvas identifier.",
+        test(resolve, reject) {
+            let canvas = WebInspector.canvasManager.canvases.find((canvas) => canvas.contextType === WebInspector.Canvas.ContextType.Canvas2D);
+            if (!canvas) {
+                reject(`Missing Canvas.`);
+                return;
+            }
+
+            const objectGroup = "test";
+            CanvasAgent.resolveCanvasContext(canvas.identifier, objectGroup)
+            .then(({object}) => {
+                InspectorTest.expectEqual(object.type, "object", `Payload should have type "object".`);
+                InspectorTest.expectEqual(object.className, "CanvasRenderingContext2D", `Payload should have className "CanvasRenderingContext2D".`);
+            })
+            .then(resolve, reject);
+        }
+    });
+
+    // ------
+
+    suite.addTestCase({
+        name: "Canvas.resolveCanvasContext.invalidIdentifier",
+        description: "Invalid canvas identifiers should cause an error.",
+        test(resolve, reject) {
+            const identifier = "DOES_NOT_EXIST";
+            const objectGroup = "test";
+            CanvasAgent.resolveCanvasContext(identifier, objectGroup, (error) => {
+                InspectorTest.expectThat(error, "Should produce an error.");
+                InspectorTest.log("Error: " + error);
+                resolve();
+            });
+        }
+    });
+
+    suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body onload="load()">
+    <p>Tests for the Canvas.resolveCanvasContext command for 2D contexts.</p>
+</body>
+</html>
diff --git a/LayoutTests/inspector/canvas/resolveCanvasContext-webgl-expected.txt b/LayoutTests/inspector/canvas/resolveCanvasContext-webgl-expected.txt
new file mode 100644 (file)
index 0000000..9ab62a2
--- /dev/null
@@ -0,0 +1,8 @@
+Tests for the Canvas.resolveCanvasContext command for WebGL contexts.
+
+
+== Running test suite: Canvas.resolveCanvasContextWebGL
+-- Running test case: Canvas.resolveCanvasContextWebGL.validIdentifier
+PASS: Payload should have type "object".
+PASS: Payload should have className "WebGLRenderingContext".
+
diff --git a/LayoutTests/inspector/canvas/resolveCanvasContext-webgl.html b/LayoutTests/inspector/canvas/resolveCanvasContext-webgl.html
new file mode 100644 (file)
index 0000000..45098eb
--- /dev/null
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
+<script>
+function load() {
+    window.contextWebGL = document.body.appendChild(document.createElement("canvas")).getContext("webgl");
+
+    runTest();
+}
+
+function test()
+{
+    let suite = InspectorTest.createAsyncSuite("Canvas.resolveCanvasContextWebGL");
+
+    suite.addTestCase({
+        name: `Canvas.resolveCanvasContextWebGL.validIdentifier`,
+        description: "Should return a valid object for the given canvas identifier.",
+        test(resolve, reject) {
+            let canvas = WebInspector.canvasManager.canvases.find((canvas) => canvas.contextType === WebInspector.Canvas.ContextType.WebGL);
+            if (!canvas) {
+                reject(`Missing Canvas.`);
+                return;
+            }
+
+            const objectGroup = "test";
+            CanvasAgent.resolveCanvasContext(canvas.identifier, objectGroup)
+            .then(({object}) => {
+                InspectorTest.expectEqual(object.type, "object", `Payload should have type "object".`);
+                InspectorTest.expectEqual(object.className, "WebGLRenderingContext", `Payload should have className "WebGLRenderingContext".`);
+            })
+            .then(resolve, reject);
+        }
+    });
+
+    suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body onload="load()">
+    <p>Tests for the Canvas.resolveCanvasContext command for WebGL contexts.</p>
+</body>
+</html>
diff --git a/LayoutTests/inspector/canvas/resolveCanvasContext-webgl2-expected.txt b/LayoutTests/inspector/canvas/resolveCanvasContext-webgl2-expected.txt
new file mode 100644 (file)
index 0000000..38c34c2
--- /dev/null
@@ -0,0 +1,8 @@
+Tests for the Canvas.resolveCanvasContext command for WebGL2 contexts.
+
+
+== Running test suite: Canvas.resolveCanvasContextWebGL2
+-- Running test case: Canvas.resolveCanvasContextWebGL2.validIdentifier
+PASS: Payload should have type "object".
+PASS: Payload should have className "WebGL2RenderingContext".
+
diff --git a/LayoutTests/inspector/canvas/resolveCanvasContext-webgl2.html b/LayoutTests/inspector/canvas/resolveCanvasContext-webgl2.html
new file mode 100644 (file)
index 0000000..5bcfbe2
--- /dev/null
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
+<script>
+if (window.internals)
+    window.internals.settings.setWebGL2Enabled(true);
+
+function load() {
+    window.contextWebGL2 = document.body.appendChild(document.createElement("canvas")).getContext("webgl2");
+
+    runTest();
+}
+
+function test()
+{
+    let suite = InspectorTest.createAsyncSuite("Canvas.resolveCanvasContextWebGL2");
+
+    suite.addTestCase({
+        name: `Canvas.resolveCanvasContextWebGL2.validIdentifier`,
+        description: "Should return a valid object for the given canvas identifier.",
+        test(resolve, reject) {
+            let canvas = WebInspector.canvasManager.canvases.find((canvas) => canvas.contextType === WebInspector.Canvas.ContextType.WebGL2);
+            if (!canvas) {
+                reject(`Missing Canvas.`);
+                return;
+            }
+
+            const objectGroup = "test";
+            CanvasAgent.resolveCanvasContext(canvas.identifier, objectGroup)
+            .then(({object}) => {
+                InspectorTest.expectEqual(object.type, "object", `Payload should have type "object".`);
+                InspectorTest.expectEqual(object.className, "WebGL2RenderingContext", `Payload should have className "WebGL2RenderingContext".`);
+            })
+            .then(resolve, reject);
+        }
+    });
+
+    suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body onload="load()">
+    <p>Tests for the Canvas.resolveCanvasContext command for WebGL2 contexts.</p>
+</body>
+</html>
diff --git a/LayoutTests/inspector/canvas/resolveCanvasContext-webgpu-expected.txt b/LayoutTests/inspector/canvas/resolveCanvasContext-webgpu-expected.txt
new file mode 100644 (file)
index 0000000..dd4b3e3
--- /dev/null
@@ -0,0 +1,8 @@
+Tests for the Canvas.resolveCanvasContext command for WebGPU contexts.
+
+
+== Running test suite: Canvas.resolveCanvasContextWebGPU
+-- Running test case: Canvas.resolveCanvasContextWebGPU.validIdentifier
+PASS: Payload should have type "object".
+PASS: Payload should have className "WebGPURenderingContext".
+
diff --git a/LayoutTests/inspector/canvas/resolveCanvasContext-webgpu.html b/LayoutTests/inspector/canvas/resolveCanvasContext-webgpu.html
new file mode 100644 (file)
index 0000000..78b68ff
--- /dev/null
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
+<script>
+if (window.internals)
+    window.internals.settings.setWebGPUEnabled(true);
+
+function load() {
+    window.contextWebGPU = document.body.appendChild(document.createElement("canvas")).getContext("webgpu");
+
+    runTest();
+}
+
+function test()
+{
+    let suite = InspectorTest.createAsyncSuite("Canvas.resolveCanvasContextWebGPU");
+
+    suite.addTestCase({
+        name: `Canvas.resolveCanvasContextWebGPU.validIdentifier`,
+        description: "Should return a valid object for the given canvas identifier.",
+        test(resolve, reject) {
+            let canvas = WebInspector.canvasManager.canvases.find((canvas) => canvas.contextType === WebInspector.Canvas.ContextType.WebGPU);
+            if (!canvas) {
+                reject(`Missing Canvas.`);
+                return;
+            }
+
+            const objectGroup = "test";
+            CanvasAgent.resolveCanvasContext(canvas.identifier, objectGroup)
+            .then(({object}) => {
+                InspectorTest.expectEqual(object.type, "object", `Payload should have type "object".`);
+                InspectorTest.expectEqual(object.className, "WebGPURenderingContext", `Payload should have className "WebGPURenderingContext".`);
+            })
+            .then(resolve, reject);
+        }
+    });
+
+    suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body onload="load()">
+    <p>Tests for the Canvas.resolveCanvasContext command for WebGPU contexts.</p>
+</body>
+</html>
index ddbe416..998ee48 100644 (file)
@@ -595,6 +595,7 @@ webkit.org/b/166536 fast/canvas/webgl/webgl2-runtime-flag.html [ Skip ]
 webkit.org/b/166536 fast/canvas/webgl/webgl2-texStorage.html [ Skip ]
 webkit.org/b/166536 fast/canvas/webgl/webgl2-texture-upload-enums.html [ Skip ]
 webkit.org/b/166536 inspector/canvas/create-context-webgl2.html [ Skip ]
+webkit.org/b/166536 inspector/canvas/resolveCanvasContext-webgl2.html [ Skip ]
 
 # These tests reference specific fonts on Mac port.
 Bug(GTK) fast/text/font-weights.html [ WontFix ]
@@ -1253,6 +1254,7 @@ fast/animation/request-animation-frame-throttling-lowPowerMode.html [ Failure ]
 # WebGPU is not enabled on GTK+.
 fast/canvas/webgpu [ Skip ]
 inspector/canvas/create-context-webgpu.html [ Skip ]
+inspector/canvas/resolveCanvasContext-webgpu.html [ Skip ]
 
 # We don't support APPLE_PAY.
 http/tests/ssl/applepay [ Skip ]
index 6ea1bf8..71255ba 100644 (file)
@@ -36,6 +36,7 @@ http/tests/fullscreen
 # WebGPU is not enabled on iOS Simulator.
 fast/canvas/webgpu
 inspector/canvas/create-context-webgpu.html [ Skip ]
+inspector/canvas/resolveCanvasContext-webgpu.html [ Skip ]
 
 # Encrypted Media Extensions are not enabled
 media/encrypted-media/
index 973406c..3d085ca 100644 (file)
@@ -1913,6 +1913,8 @@ http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html
 http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html [ Skip ]
 inspector/canvas/create-context-webgl.html [ Skip ]
 inspector/canvas/create-context-webgl2.html [ Skip ]
+inspector/canvas/resolveCanvasContext-webgl.html [ Skip ]
+inspector/canvas/resolveCanvasContext-webgl2.html [ Skip ]
 ################################################################################
 #################          End WebGL Issues              #######################
 ################################################################################
@@ -2382,6 +2384,7 @@ inspector/memory [ Skip ]
 # inspector/debugger/searchInContent-linebreaks.html [ Pass Crash ] # Flaky
 
 inspector/canvas/create-context-webgpu.html [ Skip ]
+inspector/canvas/resolveCanvasContext-webgpu.html [ Skip ]
 
 ################################################################################
 #################        End Inspector Issues               ####################
index 7b625d0..6eac695 100644 (file)
@@ -1,3 +1,14 @@
+2017-07-05  Devin Rousso  <drousso@apple.com>
+
+        Web Inspector: Allow users to log any tracked canvas context
+        https://bugs.webkit.org/show_bug.cgi?id=173397
+        <rdar://problem/33111581>
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/protocol/Canvas.json:
+        Add `resolveCanvasContext` command that returns a RemoteObject for the given canvas context.
+
 2017-07-05  Jonathan Bedard  <jbedard@apple.com>
 
         Add WebKitPrivateFrameworkStubs for iOS 11
index cca1e12..3e15537 100644 (file)
             "returns": [
                 { "name": "content", "type": "string", "description": "Base64-encoded data of the canvas' contents." }
             ]
+        },
+        {
+            "name": "resolveCanvasContext",
+            "description": "Resolves JavaScript canvas context object for given canvasId.",
+            "parameters": [
+                { "name": "canvasId", "$ref": "CanvasId", "description": "Canvas identifier." },
+                { "name": "objectGroup", "type": "string", "optional": true, "description": "Symbolic group name that can be used to release multiple objects." }
+            ],
+            "returns": [
+                { "name": "object", "$ref": "Runtime.RemoteObject", "description": "JavaScript object wrapper for given canvas context." }
+            ]
         }
     ],
     "events": [
index b0afb9a..e530ca9 100644 (file)
@@ -1,3 +1,22 @@
+2017-07-05  Devin Rousso  <drousso@apple.com>
+
+        Web Inspector: Allow users to log any tracked canvas context
+        https://bugs.webkit.org/show_bug.cgi?id=173397
+        <rdar://problem/33111581>
+
+        Reviewed by Joseph Pecoraro.
+
+        Tests: inspector/canvas/resolveCanvasContext-2d.html
+               inspector/canvas/resolveCanvasContext-webgl.html
+               inspector/canvas/resolveCanvasContext-webgl2.html
+               inspector/canvas/resolveCanvasContext-webgpu.html
+
+        * inspector/InspectorCanvasAgent.h:
+        * inspector/InspectorCanvasAgent.cpp:
+        (WebCore::InspectorCanvasAgent::InspectorCanvasAgent):
+        (WebCore::contextAsScriptValue):
+        (WebCore::InspectorCanvasAgent::resolveCanvasContext):
+
 2017-07-05  Emilio Cobos Ãlvarez  <ecobos@igalia.com>
 
         Style sharing check for fullscreen element seems bogus.
index b7b1890..1b0a105 100644 (file)
 #include "InspectorDOMAgent.h"
 #include "InspectorPageAgent.h"
 #include "InstrumentingAgents.h"
+#include "JSCanvasRenderingContext2D.h"
+#include "JSMainThreadExecState.h"
 #include "MainFrame.h"
+#include "ScriptState.h"
 #include <inspector/IdentifiersFactory.h>
+#include <inspector/InjectedScript.h>
+#include <inspector/InjectedScriptManager.h>
 #include <inspector/InspectorProtocolObjects.h>
+#include <runtime/JSCInlines.h>
 
 #if ENABLE(WEBGL)
+#include "JSWebGLRenderingContext.h"
 #include "WebGLContextAttributes.h"
 #include "WebGLRenderingContext.h"
 #include "WebGLRenderingContextBase.h"
 #endif
 
 #if ENABLE(WEBGL2)
+#include "JSWebGL2RenderingContext.h"
 #include "WebGL2RenderingContext.h"
 #endif
 
 #if ENABLE(WEBGPU)
+#include "JSWebGPURenderingContext.h"
 #include "WebGPURenderingContext.h"
 #endif
 
@@ -59,6 +68,7 @@ InspectorCanvasAgent::InspectorCanvasAgent(WebAgentContext& context, InspectorPa
     : InspectorAgentBase(ASCIILiteral("Canvas"), context)
     , m_frontendDispatcher(std::make_unique<Inspector::CanvasFrontendDispatcher>(context.frontendRouter))
     , m_backendDispatcher(Inspector::CanvasBackendDispatcher::create(context.backendDispatcher, this))
+    , m_injectedScriptManager(context.injectedScriptManager)
     , m_pageAgent(pageAgent)
     , m_timer(*this, &InspectorCanvasAgent::canvasDestroyedTimerFired)
 {
@@ -145,6 +155,58 @@ void InspectorCanvasAgent::requestContent(ErrorString& errorString, const String
     }
 }
 
+static JSC::JSValue contextAsScriptValue(JSC::ExecState& state, CanvasRenderingContext* context)
+{
+    JSC::JSLockHolder lock(&state);
+
+    if (is<CanvasRenderingContext2D>(context))
+        return toJS(&state, deprecatedGlobalObjectForPrototype(&state), downcast<CanvasRenderingContext2D>(context));
+#if ENABLE(WEBGL)
+    if (is<WebGLRenderingContext>(context))
+        return toJS(&state, deprecatedGlobalObjectForPrototype(&state), downcast<WebGLRenderingContext>(context));
+#endif
+#if ENABLE(WEBGL2)
+    if (is<WebGL2RenderingContext>(context))
+        return toJS(&state, deprecatedGlobalObjectForPrototype(&state), downcast<WebGL2RenderingContext>(context));
+#endif
+#if ENABLE(WEBGPU)
+    if (is<WebGPURenderingContext>(context))
+        return toJS(&state, deprecatedGlobalObjectForPrototype(&state), downcast<WebGPURenderingContext>(context));
+#endif
+
+    return { };
+}
+
+void InspectorCanvasAgent::resolveCanvasContext(ErrorString& errorString, const String& canvasId, const String* const objectGroup, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result)
+{
+    const CanvasEntry* canvasEntry = getCanvasEntry(canvasId);
+    if (!canvasEntry) {
+        errorString = ASCIILiteral("Invalid canvas identifier");
+        return;
+    }
+
+    Frame* frame = canvasEntry->element->document().frame();
+    if (!frame) {
+        errorString = ASCIILiteral("Canvas belongs to a document without a frame");
+        return;
+    }
+
+    auto& state = *mainWorldExecState(frame);
+    auto injectedScript = m_injectedScriptManager.injectedScriptFor(&state);
+    ASSERT(!injectedScript.hasNoValue());
+
+    CanvasRenderingContext* context = canvasEntry->element->renderingContext();
+    JSC::JSValue value = contextAsScriptValue(state, context);
+    if (!value) {
+        ASSERT_NOT_REACHED();
+        errorString = ASCIILiteral("Unknown context type");
+        return;
+    }
+
+    String objectGroupName = objectGroup ? *objectGroup : String();
+    result = injectedScript.wrapObject(value, objectGroupName);
+}
+
 void InspectorCanvasAgent::frameNavigated(Frame& frame)
 {
     if (frame.isMainFrame()) {
index 1acf02a..733073d 100644 (file)
 #include <wtf/Vector.h>
 #include <wtf/text/WTFString.h>
 
+namespace Inspector {
+class InjectedScriptManager;
+}
+
 namespace WebCore {
 
 class InspectorPageAgent;
@@ -59,6 +63,7 @@ public:
     void disable(ErrorString&) override;
     void requestNode(ErrorString&, const String& canvasId, int* nodeId) override;
     void requestContent(ErrorString&, const String& canvasId, String* content) override;
+    void resolveCanvasContext(ErrorString&, const String& canvasId, const String* const objectGroup, RefPtr<Inspector::Protocol::Runtime::RemoteObject>&) override;
 
     // InspectorInstrumentation
     void frameNavigated(Frame&);
@@ -94,6 +99,7 @@ private:
 
     std::unique_ptr<Inspector::CanvasFrontendDispatcher> m_frontendDispatcher;
     RefPtr<Inspector::CanvasBackendDispatcher> m_backendDispatcher;
+    Inspector::InjectedScriptManager& m_injectedScriptManager;
     InspectorPageAgent* m_pageAgent;
 
     HashMap<HTMLCanvasElement*, CanvasEntry> m_canvasEntries;
index 9190995..a85d34e 100644 (file)
@@ -1,3 +1,17 @@
+2017-07-05  Devin Rousso  <drousso@apple.com>
+
+        Web Inspector: Allow users to log any tracked canvas context
+        https://bugs.webkit.org/show_bug.cgi?id=173397
+        <rdar://problem/33111581>
+
+        Reviewed by Joseph Pecoraro.
+
+        * Localizations/en.lproj/localizedStrings.js:
+        * UserInterface/Protocol/RemoteObject.js:
+        (WebInspector.RemoteObject.resolveCanvasContext):
+        * UserInterface/Views/CanvasTreeElement.js:
+        (WebInspector.CanvasTreeElement.prototype.populateContextMenu):
+
 2017-07-03  Devin Rousso  <drousso@apple.com>
 
         Web Inspector: Support listing WebGL2 and WebGPU contexts
index 9da5794..c95713e 100644 (file)
@@ -491,7 +491,6 @@ localizedStrings["Key"] = "Key";
 localizedStrings["Key Path"] = "Key Path";
 localizedStrings["Label"] = "Label";
 localizedStrings["Latency"] = "Latency";
-localizedStrings["Layer"] = "Layer";
 localizedStrings["Layer Count: %d"] = "Layer Count: %d";
 localizedStrings["Layer Info"] = "Layer Info";
 localizedStrings["Layers"] = "Layers";
@@ -517,6 +516,7 @@ localizedStrings["Local Storage"] = "Local Storage";
 localizedStrings["Local Variables"] = "Local Variables";
 localizedStrings["Located at %s"] = "Located at %s";
 localizedStrings["Location"] = "Location";
+localizedStrings["Log Canvas Context"] = "Log Canvas Context";
 localizedStrings["Log Element"] = "Log Element";
 localizedStrings["Log Frame Text"] = "Log Frame Text";
 localizedStrings["Log Frame Value"] = "Log Frame Value";
@@ -739,6 +739,7 @@ localizedStrings["Select baseline snapshot"] = "Select baseline snapshot";
 localizedStrings["Select comparison snapshot"] = "Select comparison snapshot";
 localizedStrings["Select text on first click"] = "Select text on first click";
 localizedStrings["Selected"] = "Selected";
+localizedStrings["Selected Canvas Context"] = "Selected Canvas Context";
 localizedStrings["Selected Element"] = "Selected Element";
 localizedStrings["Selected Frame"] = "Selected Frame";
 localizedStrings["Selected Item"] = "Selected Item";
index 4ba690e..6212247 100644 (file)
@@ -150,6 +150,18 @@ WebInspector.RemoteObject = class RemoteObject
         });
     }
 
+    static resolveCanvasContext(canvas, objectGroup, callback)
+    {
+        console.assert(typeof callback === "function");
+
+        CanvasAgent.resolveCanvasContext(canvas.identifier, objectGroup, (error, object) => {
+            if (error || !object)
+                callback(null);
+            else
+                callback(WebInspector.RemoteObject.fromPayload(object, WebInspector.mainTarget));
+        });
+    }
+
     static type(remoteObject)
     {
         if (remoteObject === null)
index d3a8062..43b3ca6 100644 (file)
@@ -32,4 +32,24 @@ WebInspector.CanvasTreeElement = class CanvasTreeElement extends WebInspector.Ge
         const subtitle = null;
         super(["canvas", representedObject.contextType], representedObject.displayName, subtitle, representedObject);
     }
+
+    // Protected
+
+    populateContextMenu(contextMenu, event)
+    {
+        super.populateContextMenu(contextMenu, event);
+
+        contextMenu.appendItem(WebInspector.UIString("Log Canvas Context"), () => {
+            WebInspector.RemoteObject.resolveCanvasContext(this.representedObject, WebInspector.RuntimeManager.ConsoleObjectGroup, (remoteObject) => {
+                if (!remoteObject)
+                    return;
+
+                const text = WebInspector.UIString("Selected Canvas Context");
+                const addSpecialUserLogClass = true;
+                WebInspector.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, addSpecialUserLogClass);
+            });
+        });
+
+        contextMenu.appendSeparator();
+    }
 };