Web Inspector: expose node and frame snapshot capabilities.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 6 Dec 2013 00:57:43 +0000 (00:57 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 6 Dec 2013 00:57:43 +0000 (00:57 +0000)
https://bugs.webkit.org/show_bug.cgi?id=124326

Patch by Brian J. Burg <burg@cs.washington.edu> on 2013-12-05
Reviewed by Joseph Pecoraro.

Source/WebCore:

This adds snapshotRect() and snapshotNode() to the Page domain.
Both methods create snapshots using FrameSnapshotting APIs
and send images to the inspector frontend as a data URL.

Remove the unimplemented Page.captureScreenshot API.

* inspector/InspectorPageAgent.cpp:
(WebCore::InspectorPageAgent::snapshotNode): Added.
(WebCore::InspectorPageAgent::snapshotRect): Added.
* inspector/InspectorPageAgent.h:
* inspector/protocol/Page.json: Added new protocol APIs.

Source/WebInspectorUI:

Add method signatures for snapshotNode() and snapshotRect().
Remove method signature for unimplemented Page.captureScreenshot.

* UserInterface/InspectorBackendCommands.js:

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

Source/WebCore/ChangeLog
Source/WebCore/inspector/InspectorPageAgent.cpp
Source/WebCore/inspector/InspectorPageAgent.h
Source/WebCore/inspector/protocol/Page.json
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/InspectorBackendCommands.js
Source/WebInspectorUI/UserInterface/Legacy/7.0/InspectorBackendCommands.js
Source/WebInspectorUI/Versions/Inspector-iOS-7.0.json

index f372b41..1282b8d 100644 (file)
@@ -1,3 +1,22 @@
+2013-12-05  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: expose node and frame snapshot capabilities.
+        https://bugs.webkit.org/show_bug.cgi?id=124326
+
+        Reviewed by Joseph Pecoraro.
+
+        This adds snapshotRect() and snapshotNode() to the Page domain.
+        Both methods create snapshots using FrameSnapshotting APIs
+        and send images to the inspector frontend as a data URL.
+
+        Remove the unimplemented Page.captureScreenshot API.
+
+        * inspector/InspectorPageAgent.cpp:
+        (WebCore::InspectorPageAgent::snapshotNode): Added.
+        (WebCore::InspectorPageAgent::snapshotRect): Added.
+        * inspector/InspectorPageAgent.h:
+        * inspector/protocol/Page.json: Added new protocol APIs.
+
 2013-12-04 Bear Travis <betravis@adobe.com>
 
     [CSS Shapes] Enable CSS Shapes on Windows
index 73d906d..7e58f36 100644 (file)
 #include "DocumentLoader.h"
 #include "Frame.h"
 #include "FrameLoader.h"
+#include "FrameSnapshotting.h"
 #include "FrameView.h"
 #include "GeolocationController.h"
 #include "GeolocationError.h"
 #include "HTMLFrameOwnerElement.h"
 #include "HTMLNames.h"
 #include "IdentifiersFactory.h"
+#include "ImageBuffer.h"
 #include "InjectedScriptManager.h"
 #include "InspectorAgent.h"
 #include "InspectorClient.h"
+#include "InspectorDOMAgent.h"
 #include "InspectorFrontend.h"
 #include "InspectorInstrumentation.h"
 #include "InspectorOverlay.h"
@@ -1251,10 +1254,44 @@ void InspectorPageAgent::setCompositingBordersVisible(ErrorString*, bool visible
     m_page->settings().setShowRepaintCounter(visible);
 }
 
-void InspectorPageAgent::captureScreenshot(ErrorString* errorString, String* data)
+void InspectorPageAgent::snapshotNode(ErrorString* errorString, int nodeId, String* outDataURL)
 {
-    if (!m_client->captureScreenshot(data))
-        *errorString = "Could not capture screenshot";
+    Frame* frame = mainFrame();
+    ASSERT(frame);
+
+    InspectorDOMAgent* domAgent = m_instrumentingAgents->inspectorDOMAgent();
+    ASSERT(domAgent);
+    Node* node = domAgent->assertNode(errorString, nodeId);
+    if (!node)
+        return;
+
+    std::unique_ptr<ImageBuffer> snapshot = WebCore::snapshotNode(*frame, *node);
+    if (!snapshot) {
+        *errorString = ASCIILiteral("Could not capture snapshot");
+        return;
+    }
+
+    *outDataURL = snapshot->toDataURL(ASCIILiteral("image/png"));
+}
+
+void InspectorPageAgent::snapshotRect(ErrorString* errorString, int x, int y, int width, int height, const String& coordinateSystem, String* outDataURL)
+{
+    Frame* frame = mainFrame();
+    ASSERT(frame);
+
+    SnapshotOptions options = SnapshotOptionsNone;
+    if (coordinateSystem == "Viewport")
+        options |= SnapshotOptionsInViewCoordinates;
+
+    IntRect rectangle(x, y, width, height);
+    std::unique_ptr<ImageBuffer> snapshot = snapshotFrameRect(*frame, rectangle, options);
+
+    if (!snapshot) {
+        *errorString = ASCIILiteral("Could not capture snapshot");
+        return;
+    }
+
+    *outDataURL = snapshot->toDataURL(ASCIILiteral("image/png"));
 }
 
 void InspectorPageAgent::handleJavaScriptDialog(ErrorString* errorString, bool accept, const String* promptText)
index c121141..12e4f2c 100644 (file)
@@ -129,7 +129,8 @@ public:
     virtual void setEmulatedMedia(ErrorString*, const String&);
     virtual void getCompositingBordersVisible(ErrorString*, bool* out_param);
     virtual void setCompositingBordersVisible(ErrorString*, bool);
-    virtual void captureScreenshot(ErrorString*, String* data);
+    virtual void snapshotNode(ErrorString*, int nodeId, String* outDataURL);
+    virtual void snapshotRect(ErrorString*, int x, int y, int width, int height, const String& coordinateSystem, String* outDataURL);
     virtual void handleJavaScriptDialog(ErrorString*, bool accept, const String* promptText);
     virtual void archive(ErrorString*, String* data);
 
index 7ee1f68..affaa72 100644 (file)
@@ -9,6 +9,12 @@
             "description": "Resource type as it was perceived by the rendering engine."
         },
         {
+            "id": "CoordinateSystem",
+            "type": "string",
+            "enum": ["Viewport", "Page"],
+            "description": "Coordinate system used by supplied coordinates."
+        },
+        {
             "id": "Frame",
             "type": "object",
             "description": "Information about the Frame on the page.",
             ]
         },
         {
-            "name": "captureScreenshot",
-            "description": "Capture page screenshot.",
+            "name": "snapshotNode",
+            "description": "Capture a snapshot of the specified node that does not include unrelated layers.",
+            "parameters": [
+                { "name": "nodeId", "$ref": "DOM.NodeId", "description": "Id of the node to snapshot." }
+            ],
+            "returns": [
+                { "name": "dataURL", "type": "string", "description": "Base64-encoded image data (PNG)." }
+            ]
+        },
+        {
+            "name": "snapshotRect",
+            "description": "Capture a snapshot of the page within the specified rectangle and coordinate system.",
+            "parameters": [
+                { "name": "x", "type": "integer", "description": "X coordinate" },
+                { "name": "y", "type": "integer", "description": "Y coordinate" },
+                { "name": "width", "type": "integer", "description": "Rectangle width" },
+                { "name": "height", "type": "integer", "description": "Rectangle height" },
+                { "name": "coordinateSystem", "$ref": "CoordinateSystem", "description": "Indicates the coordinate system of the supplied rectangle." }
+            ],
             "returns": [
-                { "name": "data", "type": "string", "description": "Base64-encoded image data (PNG)." }
+                { "name": "dataURL", "type": "string", "description": "Base64-encoded image data (PNG)." }
             ]
         },
         {
index 41b8d46..88c07bc 100644 (file)
@@ -1,3 +1,15 @@
+2013-12-05  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Inspector: expose node and frame snapshot capabilities.
+        https://bugs.webkit.org/show_bug.cgi?id=124326
+
+        Reviewed by Joseph Pecoraro.
+
+        Add method signatures for snapshotNode() and snapshotRect().
+        Remove method signature for unimplemented Page.captureScreenshot.
+
+        * UserInterface/InspectorBackendCommands.js:
+
 2013-12-05  Alexandru Chiculita  <achicu@adobe.com>
 
         Web Inspector: [CSS Regions] Show a list of containing regions when clicking a node that is part of a flow
index 112e52e..b251ad0 100644 (file)
@@ -1,5 +1,6 @@
 // File is generated by Source/WebCore/inspector/CodeGeneratorInspector.py
 
+// Copyright (c) 2013 Apple Inc. All Rights Reserved.
 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
@@ -289,6 +290,7 @@ InspectorBackend.registerCommand("Network.setCacheDisabled", [{"name": "cacheDis
 // Page.
 InspectorBackend.registerPageDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Page");
 InspectorBackend.registerEnum("Page.ResourceType", {Document: "Document", Stylesheet: "Stylesheet", Image: "Image", Font: "Font", Script: "Script", XHR: "XHR", WebSocket: "WebSocket", Other: "Other"});
+InspectorBackend.registerEnum("Page.CoordinateSystem", {Viewport: "Viewport", Page: "Page"});
 InspectorBackend.registerEvent("Page.domContentEventFired", ["timestamp"]);
 InspectorBackend.registerEvent("Page.loadEventFired", ["timestamp"]);
 InspectorBackend.registerEvent("Page.frameNavigated", ["frame"]);
@@ -334,7 +336,8 @@ InspectorBackend.registerCommand("Page.setTouchEmulationEnabled", [{"name": "ena
 InspectorBackend.registerCommand("Page.setEmulatedMedia", [{"name": "media", "type": "string", "optional": false}], []);
 InspectorBackend.registerCommand("Page.getCompositingBordersVisible", [], ["result"]);
 InspectorBackend.registerCommand("Page.setCompositingBordersVisible", [{"name": "visible", "type": "boolean", "optional": false}], []);
-InspectorBackend.registerCommand("Page.captureScreenshot", [], ["data"]);
+InspectorBackend.registerCommand("Page.snapshotNode", [{"name": "nodeId", "type": "number", "optional": false}], ["dataURL"]);
+InspectorBackend.registerCommand("Page.snapshotRect", [{"name": "x", "type": "number", "optional": false}, {"name": "y", "type": "number", "optional": false}, {"name": "width", "type": "number", "optional": false}, {"name": "height", "type": "number", "optional": false}, {"name": "coordinateSystem", "type": "string", "optional": false}], ["dataURL"]);
 InspectorBackend.registerCommand("Page.handleJavaScriptDialog", [{"name": "accept", "type": "boolean", "optional": false}, {"name": "promptText", "type": "string", "optional": true}], []);
 InspectorBackend.registerCommand("Page.archive", [], ["data"]);
 
index c7eacdf..edd947c 100644 (file)
@@ -1,5 +1,6 @@
 // File is generated by Source/WebCore/inspector/CodeGeneratorInspector.py
 
+// Copyright (c) 2013 Apple Inc. All Rights Reserved.
 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
@@ -66,7 +67,6 @@ InspectorBackend.registerCommand("Page.setTouchEmulationEnabled", [{"name": "ena
 InspectorBackend.registerCommand("Page.setEmulatedMedia", [{"name": "media", "type": "string", "optional": false}], []);
 InspectorBackend.registerCommand("Page.getCompositingBordersVisible", [], ["result"]);
 InspectorBackend.registerCommand("Page.setCompositingBordersVisible", [{"name": "visible", "type": "boolean", "optional": false}], []);
-InspectorBackend.registerCommand("Page.captureScreenshot", [], ["data"]);
 InspectorBackend.registerCommand("Page.handleJavaScriptDialog", [{"name": "accept", "type": "boolean", "optional": false}, {"name": "promptText", "type": "string", "optional": true}], []);
 
 // Runtime.
index eceddd1..9d7f7cd 100644 (file)
                 ]
             },
             {
-                "name": "captureScreenshot",
-                "description": "Capture page screenshot.",
-                "returns": [
-                    { "name": "data", "type": "string", "description": "Base64-encoded image data (PNG)." }
-                ]
-            },
-            {
                 "name": "handleJavaScriptDialog",
                 "description": "Accepts or dismisses a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload).",
                 "parameters": [