Bug 966209 - Add a context menu for images in the Response panel. r=rickychien
authorVangelis Katsikaros <vkatsikaros@gmail.com>
Mon, 10 Apr 2017 12:21:36 +0300
changeset 560195 dd7433e1cae3ac88b2f92f9e374847c2b44ee6e3
parent 560194 efdb4e01ad4e4ee99f5b8c3718873530b63e2c17
child 560196 fda9bea59c6f18fabf6474519027d53b3f1cc7f6
push id53365
push userjichen@mozilla.com
push dateTue, 11 Apr 2017 08:35:12 +0000
reviewersrickychien
bugs966209
milestone55.0a1
Bug 966209 - Add a context menu for images in the Response panel. r=rickychien MozReview-Commit-ID: B3aNoGxVBNQ
devtools/client/locales/en-US/netmonitor.properties
devtools/client/netmonitor/src/request-list-context-menu.js
--- a/devtools/client/locales/en-US/netmonitor.properties
+++ b/devtools/client/locales/en-US/netmonitor.properties
@@ -711,16 +711,25 @@ netmonitor.context.copyResponse.accesske
 # LOCALIZATION NOTE (netmonitor.context.copyImageAsDataUri): This is the label displayed
 # on the context menu that copies the selected image as data uri
 netmonitor.context.copyImageAsDataUri=Copy Image as Data URI
 
 # LOCALIZATION NOTE (netmonitor.context.copyImageAsDataUri.accesskey): This is the access key
 # for the Copy Image As Data URI menu item displayed in the context menu for a request
 netmonitor.context.copyImageAsDataUri.accesskey=I
 
+# LOCALIZATION NOTE (netmonitor.context.saveImageAs): This is the label displayed
+# on the context menu that save the Image
+netmonitor.context.saveImageAs=Save Image As
+
+# LOCALIZATION NOTE (netmonitor.context.copyImageAsDataUri.accesskey): This is the access key
+# for the Copy Image As Data URI menu item displayed in the context menu for a request
+netmonitor.context.saveImageAs.accesskey=V
+
+
 # LOCALIZATION NOTE (netmonitor.context.copyAllAsHar): This is the label displayed
 # on the context menu that copies all as HAR format
 netmonitor.context.copyAllAsHar=Copy All As HAR
 
 # LOCALIZATION NOTE (netmonitor.context.copyAllAsHar.accesskey): This is the access key
 # for the Copy All As HAR menu item displayed in the context menu for a network panel
 netmonitor.context.copyAllAsHar.accesskey=O
 
--- a/devtools/client/netmonitor/src/request-list-context-menu.js
+++ b/devtools/client/netmonitor/src/request-list-context-menu.js
@@ -4,16 +4,17 @@
 
 "use strict";
 
 const Services = require("Services");
 const { Curl } = require("devtools/client/shared/curl");
 const { gDevTools } = require("devtools/client/framework/devtools");
 const Menu = require("devtools/client/framework/menu");
 const MenuItem = require("devtools/client/framework/menu-item");
+const FileSaver = require("devtools/client/shared/file-saver");
 const clipboardHelper = require("devtools/shared/platform/clipboard");
 const { HarExporter } = require("./har/har-exporter");
 const { NetMonitorController } = require("./netmonitor-controller");
 const { getLongString } = require("./utils/client");
 const { L10N } = require("./utils/l10n");
 const {
   formDataURI,
   getFormDataSections,
@@ -151,16 +152,26 @@ RequestListContextMenu.prototype = {
       id: "request-list-context-save-all-as-har",
       label: L10N.getStr("netmonitor.context.saveAllAsHar"),
       accesskey: L10N.getStr("netmonitor.context.saveAllAsHar.accesskey"),
       visible: this.sortedRequests.size > 0,
       click: () => this.saveAllAsHar(),
     }));
 
     menu.append(new MenuItem({
+      id: "request-list-context-save-image-as",
+      label: L10N.getStr("netmonitor.context.saveImageAs"),
+      accesskey: L10N.getStr("netmonitor.context.saveImageAs.accesskey"),
+      visible: !!(selectedRequest &&
+               selectedRequest.responseContent &&
+               selectedRequest.responseContent.content.mimeType.includes("image/")),
+      click: () => this.saveImageAs(),
+    }));
+
+    menu.append(new MenuItem({
       type: "separator",
       visible: !!(NetMonitorController.supportsCustomRequest &&
                selectedRequest && !selectedRequest.isCustom),
     }));
 
     menu.append(new MenuItem({
       id: "request-list-context-resend",
       label: L10N.getStr("netmonitor.context.editAndResend"),
@@ -319,16 +330,36 @@ RequestListContextMenu.prototype = {
 
     getLongString(text).then(string => {
       let data = formDataURI(mimeType, encoding, string);
       clipboardHelper.copyString(data);
     });
   },
 
   /**
+   * Save image as.
+   */
+  saveImageAs() {
+    const { encoding, text } = this.selectedRequest.responseContent.content;
+    let fileName = this.selectedRequest.urlDetails.baseNameWithQuery;
+    let data;
+    if (encoding === "base64") {
+      let decoded = atob(text);
+      data = new Uint8Array(decoded.length);
+      for (let i = 0; i < decoded.length; ++i) {
+        data[i] = decoded.charCodeAt(i);
+      }
+    } else {
+      data = text;
+    }
+    let blob = new Blob([data]);
+    FileSaver.saveAs(blob, fileName, document);
+  },
+
+  /**
    * Copy response data as a string.
    */
   copyResponse() {
     const { text } = this.selectedRequest.responseContent.content;
 
     getLongString(text).then(string => {
       clipboardHelper.copyString(string);
     });