--- a/devtools/client/netmonitor/har/test/browser_net_har_copy_all_as_har.js
+++ b/devtools/client/netmonitor/har/test/browser_net_har_copy_all_as_har.js
@@ -15,17 +15,17 @@ add_task(function* () {
let { RequestsMenu } = NetMonitorView;
RequestsMenu.lazyUpdate = false;
let wait = waitForNetworkEvents(monitor, 1);
tab.linkedBrowser.reload();
yield wait;
- yield RequestsMenu.copyAllAsHar();
+ yield RequestsMenu.contextMenu.copyAllAsHar();
let jsonString = SpecialPowers.getClipboardData("text/unicode");
let har = JSON.parse(jsonString);
// Check out HAR log
isnot(har.log, null, "The HAR log must exist");
is(har.log.creator.name, "Firefox", "The creator field must be set");
is(har.log.browser.name, "Firefox", "The browser field must be set");
--- a/devtools/client/netmonitor/har/test/browser_net_har_post_data.js
+++ b/devtools/client/netmonitor/har/test/browser_net_har_post_data.js
@@ -20,17 +20,17 @@ add_task(function* () {
// Execute one POST request on the page and wait till its done.
let wait = waitForNetworkEvents(monitor, 0, 1);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.executeTest();
});
yield wait;
// Copy HAR into the clipboard (asynchronous).
- let jsonString = yield RequestsMenu.copyAllAsHar();
+ let jsonString = yield RequestsMenu.contextMenu.copyAllAsHar();
let har = JSON.parse(jsonString);
// Check out the HAR log.
isnot(har.log, null, "The HAR log must exist");
is(har.log.pages.length, 1, "There must be one page");
is(har.log.entries.length, 1, "There must be one request");
let entry = har.log.entries[0];
--- a/devtools/client/netmonitor/har/test/browser_net_har_throttle_upload.js
+++ b/devtools/client/netmonitor/har/test/browser_net_har_throttle_upload.js
@@ -46,17 +46,17 @@ function* throttleUploadTest(actuallyThr
// Execute one POST request on the page and wait till its done.
let wait = waitForNetworkEvents(monitor, 0, 1);
yield ContentTask.spawn(tab.linkedBrowser, { size }, function* (args) {
content.wrappedJSObject.executeTest2(args.size);
});
yield wait;
// Copy HAR into the clipboard (asynchronous).
- let jsonString = yield RequestsMenu.copyAllAsHar();
+ let jsonString = yield RequestsMenu.contextMenu.copyAllAsHar();
let har = JSON.parse(jsonString);
// Check out the HAR log.
isnot(har.log, null, "The HAR log must exist");
is(har.log.pages.length, 1, "There must be one page");
is(har.log.entries.length, 1, "There must be one request");
let entry = har.log.entries[0];
--- a/devtools/client/netmonitor/moz.build
+++ b/devtools/client/netmonitor/moz.build
@@ -15,16 +15,17 @@ DevToolsModules(
'constants.js',
'custom-request-view.js',
'events.js',
'filter-predicates.js',
'l10n.js',
'panel.js',
'performance-statistics-view.js',
'prefs.js',
+ 'request-list-context-menu.js',
'request-utils.js',
'requests-menu-view.js',
'sort-predicates.js',
'store.js',
'toolbar-view.js',
)
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/request-list-context-menu.js
@@ -0,0 +1,357 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* globals NetMonitorController, NetMonitorView, gNetwork */
+
+"use strict";
+
+const Services = require("Services");
+const { Task } = require("devtools/shared/task");
+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 { L10N } = require("./l10n");
+const { formDataURI, getFormDataSections } = require("./request-utils");
+
+loader.lazyRequireGetter(this, "HarExporter",
+ "devtools/client/netmonitor/har/har-exporter", true);
+
+loader.lazyServiceGetter(this, "clipboardHelper",
+ "@mozilla.org/widget/clipboardhelper;1", "nsIClipboardHelper");
+
+loader.lazyRequireGetter(this, "NetworkHelper",
+ "devtools/shared/webconsole/network-helper");
+
+function RequestListContextMenu() {}
+
+RequestListContextMenu.prototype = {
+ get selectedItem() {
+ return NetMonitorView.RequestsMenu.selectedItem;
+ },
+
+ get items() {
+ return NetMonitorView.RequestsMenu.items;
+ },
+
+ /**
+ * Handle the context menu opening. Hide items if no request is selected.
+ * Since visible attribute only accept boolean value but the method call may
+ * return undefined, we use !! to force convert any object to boolean
+ */
+ open({ screenX = 0, screenY = 0 } = {}) {
+ let selectedItem = this.selectedItem;
+
+ let menu = new Menu();
+ menu.append(new MenuItem({
+ id: "request-menu-context-copy-url",
+ label: L10N.getStr("netmonitor.context.copyUrl"),
+ accesskey: L10N.getStr("netmonitor.context.copyUrl.accesskey"),
+ visible: !!selectedItem,
+ click: () => this.copyUrl(),
+ }));
+
+ menu.append(new MenuItem({
+ id: "request-menu-context-copy-url-params",
+ label: L10N.getStr("netmonitor.context.copyUrlParams"),
+ accesskey: L10N.getStr("netmonitor.context.copyUrlParams.accesskey"),
+ visible: !!(selectedItem &&
+ NetworkHelper.nsIURL(selectedItem.attachment.url).query),
+ click: () => this.copyUrlParams(),
+ }));
+
+ menu.append(new MenuItem({
+ id: "request-menu-context-copy-post-data",
+ label: L10N.getStr("netmonitor.context.copyPostData"),
+ accesskey: L10N.getStr("netmonitor.context.copyPostData.accesskey"),
+ visible: !!(selectedItem && selectedItem.attachment.requestPostData),
+ click: () => this.copyPostData(),
+ }));
+
+ menu.append(new MenuItem({
+ id: "request-menu-context-copy-as-curl",
+ label: L10N.getStr("netmonitor.context.copyAsCurl"),
+ accesskey: L10N.getStr("netmonitor.context.copyAsCurl.accesskey"),
+ visible: !!(selectedItem && selectedItem.attachment),
+ click: () => this.copyAsCurl(),
+ }));
+
+ menu.append(new MenuItem({
+ type: "separator",
+ visible: !!selectedItem,
+ }));
+
+ menu.append(new MenuItem({
+ id: "request-menu-context-copy-request-headers",
+ label: L10N.getStr("netmonitor.context.copyRequestHeaders"),
+ accesskey: L10N.getStr("netmonitor.context.copyRequestHeaders.accesskey"),
+ visible: !!(selectedItem && selectedItem.attachment.requestHeaders),
+ click: () => this.copyRequestHeaders(),
+ }));
+
+ menu.append(new MenuItem({
+ id: "response-menu-context-copy-response-headers",
+ label: L10N.getStr("netmonitor.context.copyResponseHeaders"),
+ accesskey: L10N.getStr("netmonitor.context.copyResponseHeaders.accesskey"),
+ visible: !!(selectedItem && selectedItem.attachment.responseHeaders),
+ click: () => this.copyResponseHeaders(),
+ }));
+
+ menu.append(new MenuItem({
+ id: "request-menu-context-copy-response",
+ label: L10N.getStr("netmonitor.context.copyResponse"),
+ accesskey: L10N.getStr("netmonitor.context.copyResponse.accesskey"),
+ visible: !!(selectedItem &&
+ selectedItem.attachment.responseContent &&
+ selectedItem.attachment.responseContent.content.text &&
+ selectedItem.attachment.responseContent.content.text.length !== 0),
+ click: () => this.copyResponse(),
+ }));
+
+ menu.append(new MenuItem({
+ id: "request-menu-context-copy-image-as-data-uri",
+ label: L10N.getStr("netmonitor.context.copyImageAsDataUri"),
+ accesskey: L10N.getStr("netmonitor.context.copyImageAsDataUri.accesskey"),
+ visible: !!(selectedItem &&
+ selectedItem.attachment.responseContent &&
+ selectedItem.attachment.responseContent.content
+ .mimeType.includes("image/")),
+ click: () => this.copyImageAsDataUri(),
+ }));
+
+ menu.append(new MenuItem({
+ type: "separator",
+ visible: !!selectedItem,
+ }));
+
+ menu.append(new MenuItem({
+ id: "request-menu-context-copy-all-as-har",
+ label: L10N.getStr("netmonitor.context.copyAllAsHar"),
+ accesskey: L10N.getStr("netmonitor.context.copyAllAsHar.accesskey"),
+ visible: !!this.items.length,
+ click: () => this.copyAllAsHar(),
+ }));
+
+ menu.append(new MenuItem({
+ id: "request-menu-context-save-all-as-har",
+ label: L10N.getStr("netmonitor.context.saveAllAsHar"),
+ accesskey: L10N.getStr("netmonitor.context.saveAllAsHar.accesskey"),
+ visible: !!this.items.length,
+ click: () => this.saveAllAsHar(),
+ }));
+
+ menu.append(new MenuItem({
+ type: "separator",
+ visible: !!selectedItem,
+ }));
+
+ menu.append(new MenuItem({
+ id: "request-menu-context-resend",
+ label: L10N.getStr("netmonitor.context.editAndResend"),
+ accesskey: L10N.getStr("netmonitor.context.editAndResend.accesskey"),
+ visible: !!(NetMonitorController.supportsCustomRequest &&
+ selectedItem &&
+ !selectedItem.attachment.isCustom),
+ click: () => NetMonitorView.RequestsMenu.cloneSelectedRequest(),
+ }));
+
+ menu.append(new MenuItem({
+ type: "separator",
+ visible: !!selectedItem,
+ }));
+
+ menu.append(new MenuItem({
+ id: "request-menu-context-newtab",
+ label: L10N.getStr("netmonitor.context.newTab"),
+ accesskey: L10N.getStr("netmonitor.context.newTab.accesskey"),
+ visible: !!selectedItem,
+ click: () => this.openRequestInTab()
+ }));
+
+ menu.append(new MenuItem({
+ id: "request-menu-context-perf",
+ label: L10N.getStr("netmonitor.context.perfTools"),
+ accesskey: L10N.getStr("netmonitor.context.perfTools.accesskey"),
+ visible: !!NetMonitorController.supportsPerfStats,
+ click: () => NetMonitorView.toggleFrontendMode()
+ }));
+
+ menu.popup(screenX, screenY, NetMonitorController._toolbox);
+ return menu;
+ },
+
+ /**
+ * Opens selected item in a new tab.
+ */
+ openRequestInTab() {
+ let win = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
+ let { url } = this.selectedItem.attachment;
+ win.openUILinkIn(url, "tab", { relatedToCurrent: true });
+ },
+
+ /**
+ * Copy the request url from the currently selected item.
+ */
+ copyUrl() {
+ clipboardHelper.copyString(this.selectedItem.attachment.url);
+ },
+
+ /**
+ * Copy the request url query string parameters from the currently
+ * selected item.
+ */
+ copyUrlParams() {
+ let { url } = this.selectedItem.attachment;
+ let params = NetworkHelper.nsIURL(url).query.split("&");
+ let string = params.join(Services.appinfo.OS === "WINNT" ? "\r\n" : "\n");
+ clipboardHelper.copyString(string);
+ },
+
+ /**
+ * Copy the request form data parameters (or raw payload) from
+ * the currently selected item.
+ */
+ copyPostData: Task.async(function* () {
+ let selected = this.selectedItem.attachment;
+
+ // Try to extract any form data parameters.
+ let formDataSections = yield getFormDataSections(
+ selected.requestHeaders,
+ selected.requestHeadersFromUploadStream,
+ selected.requestPostData,
+ gNetwork.getString.bind(gNetwork));
+
+ let params = [];
+ formDataSections.forEach(section => {
+ let paramsArray = NetworkHelper.parseQueryString(section);
+ if (paramsArray) {
+ params = [...params, ...paramsArray];
+ }
+ });
+
+ let string = params
+ .map(param => param.name + (param.value ? "=" + param.value : ""))
+ .join(Services.appinfo.OS === "WINNT" ? "\r\n" : "\n");
+
+ // Fall back to raw payload.
+ if (!string) {
+ let postData = selected.requestPostData.postData.text;
+ string = yield gNetwork.getString(postData);
+ if (Services.appinfo.OS !== "WINNT") {
+ string = string.replace(/\r/g, "");
+ }
+ }
+
+ clipboardHelper.copyString(string);
+ }),
+
+ /**
+ * Copy a cURL command from the currently selected item.
+ */
+ copyAsCurl: Task.async(function* () {
+ let selected = this.selectedItem.attachment;
+
+ // Create a sanitized object for the Curl command generator.
+ let data = {
+ url: selected.url,
+ method: selected.method,
+ headers: [],
+ httpVersion: selected.httpVersion,
+ postDataText: null
+ };
+
+ // Fetch header values.
+ for (let { name, value } of selected.requestHeaders.headers) {
+ let text = yield gNetwork.getString(value);
+ data.headers.push({ name: name, value: text });
+ }
+
+ // Fetch the request payload.
+ if (selected.requestPostData) {
+ let postData = selected.requestPostData.postData.text;
+ data.postDataText = yield gNetwork.getString(postData);
+ }
+
+ clipboardHelper.copyString(Curl.generateCommand(data));
+ }),
+
+ /**
+ * Copy the raw request headers from the currently selected item.
+ */
+ copyRequestHeaders() {
+ let selected = this.selectedItem.attachment;
+ let rawHeaders = selected.requestHeaders.rawHeaders.trim();
+ if (Services.appinfo.OS !== "WINNT") {
+ rawHeaders = rawHeaders.replace(/\r/g, "");
+ }
+ clipboardHelper.copyString(rawHeaders);
+ },
+
+ /**
+ * Copy the raw response headers from the currently selected item.
+ */
+ copyResponseHeaders() {
+ let selected = this.selectedItem.attachment;
+ let rawHeaders = selected.responseHeaders.rawHeaders.trim();
+ if (Services.appinfo.OS !== "WINNT") {
+ rawHeaders = rawHeaders.replace(/\r/g, "");
+ }
+ clipboardHelper.copyString(rawHeaders);
+ },
+
+ /**
+ * Copy image as data uri.
+ */
+ copyImageAsDataUri() {
+ let selected = this.selectedItem.attachment;
+ let { mimeType, text, encoding } = selected.responseContent.content;
+
+ gNetwork.getString(text).then(string => {
+ let data = formDataURI(mimeType, encoding, string);
+ clipboardHelper.copyString(data);
+ });
+ },
+
+ /**
+ * Copy response data as a string.
+ */
+ copyResponse() {
+ let selected = this.selectedItem.attachment;
+ let text = selected.responseContent.content.text;
+
+ gNetwork.getString(text).then(string => {
+ clipboardHelper.copyString(string);
+ });
+ },
+
+ /**
+ * Copy HAR from the network panel content to the clipboard.
+ */
+ copyAllAsHar() {
+ let options = this.getDefaultHarOptions();
+ return HarExporter.copy(options);
+ },
+
+ /**
+ * Save HAR from the network panel content to a file.
+ */
+ saveAllAsHar() {
+ let options = this.getDefaultHarOptions();
+ return HarExporter.save(options);
+ },
+
+ getDefaultHarOptions() {
+ let form = NetMonitorController._target.form;
+ let title = form.title || form.url;
+
+ return {
+ getString: gNetwork.getString.bind(gNetwork),
+ view: NetMonitorView.RequestsMenu,
+ items: NetMonitorView.RequestsMenu.items,
+ title: title
+ };
+ }
+};
+
+module.exports = RequestListContextMenu;
--- a/devtools/client/netmonitor/requests-menu-view.js
+++ b/devtools/client/netmonitor/requests-menu-view.js
@@ -1,47 +1,43 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
/* globals document, window, dumpn, $, gNetwork, EVENTS, Prefs,
NetMonitorController, NetMonitorView */
+
"use strict";
+
/* eslint-disable mozilla/reject-some-requires */
const { Cu } = require("chrome");
-const Services = require("Services");
const {Task} = require("devtools/shared/task");
const {DeferredTask} = Cu.import("resource://gre/modules/DeferredTask.jsm", {});
/* eslint-disable mozilla/reject-some-requires */
const {SideMenuWidget} = require("resource://devtools/client/shared/widgets/SideMenuWidget.jsm");
const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip");
const {setImageTooltip, getImageDimensions} =
require("devtools/client/shared/widgets/tooltip/ImageTooltipHelper");
const {Heritage, WidgetMethods, setNamedTimeout} =
require("devtools/client/shared/widgets/view-helpers");
-const {gDevTools} = require("devtools/client/framework/devtools");
-const Menu = require("devtools/client/framework/menu");
-const MenuItem = require("devtools/client/framework/menu-item");
-const {Curl, CurlUtils} = require("devtools/client/shared/curl");
+const {CurlUtils} = require("devtools/client/shared/curl");
const {PluralForm} = require("devtools/shared/plural-form");
const {Filters, isFreetextMatch} = require("./filter-predicates");
const {Sorters} = require("./sort-predicates");
const {L10N, WEBCONSOLE_L10N} = require("./l10n");
-const {getFormDataSections,
- formDataURI,
+const {formDataURI,
writeHeaderText,
getKeyWithEvent,
getAbbreviatedMimeType,
getUriNameWithQuery,
getUriHostPort,
getUriHost,
loadCauseString} = require("./request-utils");
const Actions = require("./actions/index");
-
-loader.lazyServiceGetter(this, "clipboardHelper",
- "@mozilla.org/widget/clipboardhelper;1", "nsIClipboardHelper");
-
-loader.lazyRequireGetter(this, "HarExporter",
- "devtools/client/netmonitor/har/har-exporter", true);
+const RequestListContextMenu = require("./request-list-context-menu");
loader.lazyRequireGetter(this, "NetworkHelper",
"devtools/shared/webconsole/network-helper");
const HTML_NS = "http://www.w3.org/1999/xhtml";
const EPSILON = 0.001;
// ms
const RESIZE_REFRESH_RATE = 50;
@@ -123,16 +119,18 @@ RequestsMenuView.prototype = Heritage.ex
/**
* Initialization function, called when the network monitor is started.
*/
initialize: function (store) {
dumpn("Initializing the RequestsMenuView");
this.store = store;
+ this.contextMenu = new RequestListContextMenu();
+
let widgetParentEl = $("#requests-menu-contents");
this.widget = new SideMenuWidget(widgetParentEl);
this._splitter = $("#network-inspector-view-splitter");
this._summary = $("#requests-menu-network-summary-button");
this._summary.setAttribute("label", L10N.getStr("networkMenu.empty"));
// Create a tooltip for the newly appended network request item.
this.tooltip = new HTMLTooltip(NetMonitorController._toolbox.doc, { type: "arrow" });
@@ -149,23 +147,16 @@ RequestsMenuView.prototype = Heritage.ex
this.widget.addEventListener("select", this._onSelect, false);
this.widget.addEventListener("swap", this._onSwap, false);
this._splitter.addEventListener("mousemove", this._onResize, false);
window.addEventListener("resize", this._onResize, false);
this.requestsMenuSortEvent = getKeyWithEvent(this.sortBy.bind(this));
this.requestsMenuSortKeyboardEvent = getKeyWithEvent(this.sortBy.bind(this), true);
this._onContextMenu = this._onContextMenu.bind(this);
- this._onContextNewTabCommand = this.openRequestInTab.bind(this);
- this._onContextCopyUrlCommand = this.copyUrl.bind(this);
- this._onContextCopyImageAsDataUriCommand =
- this.copyImageAsDataUri.bind(this);
- this._onContextCopyResponseCommand = this.copyResponse.bind(this);
- this._onContextResendCommand = this.cloneSelectedRequest.bind(this);
- this._onContextToggleRawHeadersCommand = this.toggleRawHeaders.bind(this);
this._onContextPerfCommand = () => NetMonitorView.toggleFrontendMode();
this._onReloadCommand = () => NetMonitorView.reloadPage();
this._flushRequestsTask = new DeferredTask(this._flushRequests,
REQUESTS_REFRESH_RATE);
this.sendCustomRequestEvent = this.sendCustomRequest.bind(this);
this.closeCustomRequestEvent = this.closeCustomRequest.bind(this);
this.cloneSelectedRequestEvent = this.cloneSelectedRequest.bind(this);
@@ -344,191 +335,16 @@ RequestsMenuView.prototype = Heritage.ex
return void this._flushRequests();
}
this._flushRequestsTask.arm();
return undefined;
},
/**
- * Opens selected item in a new tab.
- */
- openRequestInTab: function () {
- let win = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
- let selected = this.selectedItem.attachment;
- win.openUILinkIn(selected.url, "tab", { relatedToCurrent: true });
- },
-
- /**
- * Copy the request url from the currently selected item.
- */
- copyUrl: function () {
- let selected = this.selectedItem.attachment;
- clipboardHelper.copyString(selected.url);
- },
-
- /**
- * Copy the request url query string parameters from the currently
- * selected item.
- */
- copyUrlParams: function () {
- let selected = this.selectedItem.attachment;
- let params = NetworkHelper.nsIURL(selected.url).query.split("&");
- let string = params.join(Services.appinfo.OS === "WINNT" ? "\r\n" : "\n");
- clipboardHelper.copyString(string);
- },
-
- /**
- * Copy the request form data parameters (or raw payload) from
- * the currently selected item.
- */
- copyPostData: Task.async(function* () {
- let selected = this.selectedItem.attachment;
-
- // Try to extract any form data parameters.
- let formDataSections = yield getFormDataSections(
- selected.requestHeaders,
- selected.requestHeadersFromUploadStream,
- selected.requestPostData,
- gNetwork.getString.bind(gNetwork));
-
- let params = [];
- formDataSections.forEach(section => {
- let paramsArray = NetworkHelper.parseQueryString(section);
- if (paramsArray) {
- params = [...params, ...paramsArray];
- }
- });
-
- let string = params
- .map(param => param.name + (param.value ? "=" + param.value : ""))
- .join(Services.appinfo.OS === "WINNT" ? "\r\n" : "\n");
-
- // Fall back to raw payload.
- if (!string) {
- let postData = selected.requestPostData.postData.text;
- string = yield gNetwork.getString(postData);
- if (Services.appinfo.OS !== "WINNT") {
- string = string.replace(/\r/g, "");
- }
- }
-
- clipboardHelper.copyString(string);
- }),
-
- /**
- * Copy a cURL command from the currently selected item.
- */
- copyAsCurl: function () {
- let selected = this.selectedItem.attachment;
-
- Task.spawn(function* () {
- // Create a sanitized object for the Curl command generator.
- let data = {
- url: selected.url,
- method: selected.method,
- headers: [],
- httpVersion: selected.httpVersion,
- postDataText: null
- };
-
- // Fetch header values.
- for (let { name, value } of selected.requestHeaders.headers) {
- let text = yield gNetwork.getString(value);
- data.headers.push({ name: name, value: text });
- }
-
- // Fetch the request payload.
- if (selected.requestPostData) {
- let postData = selected.requestPostData.postData.text;
- data.postDataText = yield gNetwork.getString(postData);
- }
-
- clipboardHelper.copyString(Curl.generateCommand(data));
- });
- },
-
- /**
- * Copy HAR from the network panel content to the clipboard.
- */
- copyAllAsHar: function () {
- let options = this.getDefaultHarOptions();
- return HarExporter.copy(options);
- },
-
- /**
- * Save HAR from the network panel content to a file.
- */
- saveAllAsHar: function () {
- let options = this.getDefaultHarOptions();
- return HarExporter.save(options);
- },
-
- getDefaultHarOptions: function () {
- let form = NetMonitorController._target.form;
- let title = form.title || form.url;
-
- return {
- getString: gNetwork.getString.bind(gNetwork),
- view: this,
- items: NetMonitorView.RequestsMenu.items,
- title: title
- };
- },
-
- /**
- * Copy the raw request headers from the currently selected item.
- */
- copyRequestHeaders: function () {
- let selected = this.selectedItem.attachment;
- let rawHeaders = selected.requestHeaders.rawHeaders.trim();
- if (Services.appinfo.OS !== "WINNT") {
- rawHeaders = rawHeaders.replace(/\r/g, "");
- }
- clipboardHelper.copyString(rawHeaders);
- },
-
- /**
- * Copy the raw response headers from the currently selected item.
- */
- copyResponseHeaders: function () {
- let selected = this.selectedItem.attachment;
- let rawHeaders = selected.responseHeaders.rawHeaders.trim();
- if (Services.appinfo.OS !== "WINNT") {
- rawHeaders = rawHeaders.replace(/\r/g, "");
- }
- clipboardHelper.copyString(rawHeaders);
- },
-
- /**
- * Copy image as data uri.
- */
- copyImageAsDataUri: function () {
- let selected = this.selectedItem.attachment;
- let { mimeType, text, encoding } = selected.responseContent.content;
-
- gNetwork.getString(text).then(string => {
- let data = formDataURI(mimeType, encoding, string);
- clipboardHelper.copyString(data);
- });
- },
-
- /**
- * Copy response data as a string.
- */
- copyResponse: function () {
- let selected = this.selectedItem.attachment;
- let text = selected.responseContent.content.text;
-
- gNetwork.getString(text).then(string => {
- clipboardHelper.copyString(string);
- });
- },
-
- /**
* Create a new custom request form populated with the data from
* the currently selected request.
*/
cloneSelectedRequest: function () {
let selected = this.selectedItem.attachment;
// Create the element node for the network request item.
let menuView = this._createMenuView(selected.method, selected.url,
@@ -1708,167 +1524,17 @@ RequestsMenuView.prototype = Heritage.ex
this.tooltip.hide();
},
/**
* Open context menu
*/
_onContextMenu: function (e) {
e.preventDefault();
- this._openMenu({
- screenX: e.screenX,
- screenY: e.screenY,
- target: e.target,
- });
- },
-
- /**
- * Handle the context menu opening. Hide items if no request is selected.
- * Since visible attribute only accept boolean value but the method call may
- * return undefined, we use !! to force convert any object to boolean
- */
- _openMenu: function ({ target, screenX = 0, screenY = 0 } = { }) {
- let selectedItem = this.selectedItem;
-
- let menu = new Menu();
- menu.append(new MenuItem({
- id: "request-menu-context-copy-url",
- label: L10N.getStr("netmonitor.context.copyUrl"),
- accesskey: L10N.getStr("netmonitor.context.copyUrl.accesskey"),
- visible: !!selectedItem,
- click: () => this._onContextCopyUrlCommand(),
- }));
-
- menu.append(new MenuItem({
- id: "request-menu-context-copy-url-params",
- label: L10N.getStr("netmonitor.context.copyUrlParams"),
- accesskey: L10N.getStr("netmonitor.context.copyUrlParams.accesskey"),
- visible: !!(selectedItem &&
- NetworkHelper.nsIURL(selectedItem.attachment.url).query),
- click: () => this.copyUrlParams(),
- }));
-
- menu.append(new MenuItem({
- id: "request-menu-context-copy-post-data",
- label: L10N.getStr("netmonitor.context.copyPostData"),
- accesskey: L10N.getStr("netmonitor.context.copyPostData.accesskey"),
- visible: !!(selectedItem && selectedItem.attachment.requestPostData),
- click: () => this.copyPostData(),
- }));
-
- menu.append(new MenuItem({
- id: "request-menu-context-copy-as-curl",
- label: L10N.getStr("netmonitor.context.copyAsCurl"),
- accesskey: L10N.getStr("netmonitor.context.copyAsCurl.accesskey"),
- visible: !!(selectedItem && selectedItem.attachment),
- click: () => this.copyAsCurl(),
- }));
-
- menu.append(new MenuItem({
- type: "separator",
- visible: !!selectedItem,
- }));
-
- menu.append(new MenuItem({
- id: "request-menu-context-copy-request-headers",
- label: L10N.getStr("netmonitor.context.copyRequestHeaders"),
- accesskey: L10N.getStr("netmonitor.context.copyRequestHeaders.accesskey"),
- visible: !!(selectedItem && selectedItem.attachment.requestHeaders),
- click: () => this.copyRequestHeaders(),
- }));
-
- menu.append(new MenuItem({
- id: "response-menu-context-copy-response-headers",
- label: L10N.getStr("netmonitor.context.copyResponseHeaders"),
- accesskey: L10N.getStr("netmonitor.context.copyResponseHeaders.accesskey"),
- visible: !!(selectedItem && selectedItem.attachment.responseHeaders),
- click: () => this.copyResponseHeaders(),
- }));
-
- menu.append(new MenuItem({
- id: "request-menu-context-copy-response",
- label: L10N.getStr("netmonitor.context.copyResponse"),
- accesskey: L10N.getStr("netmonitor.context.copyResponse.accesskey"),
- visible: !!(selectedItem &&
- selectedItem.attachment.responseContent &&
- selectedItem.attachment.responseContent.content.text &&
- selectedItem.attachment.responseContent.content.text.length !== 0),
- click: () => this._onContextCopyResponseCommand(),
- }));
-
- menu.append(new MenuItem({
- id: "request-menu-context-copy-image-as-data-uri",
- label: L10N.getStr("netmonitor.context.copyImageAsDataUri"),
- accesskey: L10N.getStr("netmonitor.context.copyImageAsDataUri.accesskey"),
- visible: !!(selectedItem &&
- selectedItem.attachment.responseContent &&
- selectedItem.attachment.responseContent.content
- .mimeType.includes("image/")),
- click: () => this._onContextCopyImageAsDataUriCommand(),
- }));
-
- menu.append(new MenuItem({
- type: "separator",
- visible: !!selectedItem,
- }));
-
- menu.append(new MenuItem({
- id: "request-menu-context-copy-all-as-har",
- label: L10N.getStr("netmonitor.context.copyAllAsHar"),
- accesskey: L10N.getStr("netmonitor.context.copyAllAsHar.accesskey"),
- visible: !!this.items.length,
- click: () => this.copyAllAsHar(),
- }));
-
- menu.append(new MenuItem({
- id: "request-menu-context-save-all-as-har",
- label: L10N.getStr("netmonitor.context.saveAllAsHar"),
- accesskey: L10N.getStr("netmonitor.context.saveAllAsHar.accesskey"),
- visible: !!this.items.length,
- click: () => this.saveAllAsHar(),
- }));
-
- menu.append(new MenuItem({
- type: "separator",
- visible: !!selectedItem,
- }));
-
- menu.append(new MenuItem({
- id: "request-menu-context-resend",
- label: L10N.getStr("netmonitor.context.editAndResend"),
- accesskey: L10N.getStr("netmonitor.context.editAndResend.accesskey"),
- visible: !!(NetMonitorController.supportsCustomRequest &&
- selectedItem &&
- !selectedItem.attachment.isCustom),
- click: () => this._onContextResendCommand(),
- }));
-
- menu.append(new MenuItem({
- type: "separator",
- visible: !!selectedItem,
- }));
-
- menu.append(new MenuItem({
- id: "request-menu-context-newtab",
- label: L10N.getStr("netmonitor.context.newTab"),
- accesskey: L10N.getStr("netmonitor.context.newTab.accesskey"),
- visible: !!selectedItem,
- click: () => this._onContextNewTabCommand(),
- }));
-
- menu.append(new MenuItem({
- id: "request-menu-context-perf",
- label: L10N.getStr("netmonitor.context.perfTools"),
- accesskey: L10N.getStr("netmonitor.context.perfTools.accesskey"),
- visible: !!NetMonitorController.supportsPerfStats,
- click: () => this._onContextPerfCommand(),
- }));
-
- menu.popup(screenX, screenY, NetMonitorController._toolbox);
- return menu;
+ this.contextMenu.open(e);
},
/**
* Checks if the specified unix time is the first one to be known of,
* and saves it if so.
*
* @param number unixTime
* The milliseconds to check and save.
--- a/devtools/client/netmonitor/test/browser_net_copy_as_curl.js
+++ b/devtools/client/netmonitor/test/browser_net_copy_as_curl.js
@@ -50,17 +50,17 @@ add_task(function* () {
content.wrappedJSObject.performRequest(url);
});
yield wait;
let requestItem = RequestsMenu.getItemAtIndex(0);
RequestsMenu.selectedItem = requestItem;
yield waitForClipboardPromise(function setup() {
- RequestsMenu.copyAsCurl();
+ RequestsMenu.contextMenu.copyAsCurl();
}, function validate(result) {
if (typeof result !== "string") {
return false;
}
// Different setups may produce the same command, but with the
// parameters in a different order in the commandline (which is fine).
// Here we confirm that the commands are the same even in that case.
--- a/devtools/client/netmonitor/test/browser_net_copy_headers.js
+++ b/devtools/client/netmonitor/test/browser_net_copy_headers.js
@@ -34,17 +34,17 @@ add_task(function* () {
"Accept-Encoding: gzip, deflate",
"Connection: keep-alive",
"Upgrade-Insecure-Requests: 1",
"Pragma: no-cache",
"Cache-Control: no-cache"
].join("\n");
yield waitForClipboardPromise(function setup() {
- RequestsMenu.copyRequestHeaders();
+ RequestsMenu.contextMenu.copyRequestHeaders();
}, function validate(result) {
// Sometimes, a "Cookie" header is left over from other tests. Remove it:
result = String(result).replace(/Cookie: [^\n]+\n/, "");
return result === EXPECTED_REQUEST_HEADERS;
});
info("Clipboard contains the currently selected item's request headers.");
const EXPECTED_RESPONSE_HEADERS = [
@@ -53,17 +53,17 @@ add_task(function* () {
"Content-Type: text/html",
"Content-Length: 465",
"Connection: close",
"Server: httpd.js",
"Date: Sun, 3 May 2015 11:11:11 GMT"
].join("\n");
yield waitForClipboardPromise(function setup() {
- RequestsMenu.copyResponseHeaders();
+ RequestsMenu.contextMenu.copyResponseHeaders();
}, function validate(result) {
// Fake the "Last-Modified" and "Date" headers because they will vary:
result = String(result)
.replace(/Last-Modified: [^\n]+ GMT/, "Last-Modified: Sun, 3 May 2015 11:11:11 GMT")
.replace(/Date: [^\n]+ GMT/, "Date: Sun, 3 May 2015 11:11:11 GMT");
return result === EXPECTED_RESPONSE_HEADERS;
});
info("Clipboard contains the currently selected item's response headers.");
--- a/devtools/client/netmonitor/test/browser_net_copy_image_as_data_uri.js
+++ b/devtools/client/netmonitor/test/browser_net_copy_image_as_data_uri.js
@@ -21,15 +21,15 @@ add_task(function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
let requestItem = RequestsMenu.getItemAtIndex(5);
RequestsMenu.selectedItem = requestItem;
yield waitForClipboardPromise(function setup() {
- RequestsMenu.copyImageAsDataUri();
+ RequestsMenu.contextMenu.copyImageAsDataUri();
}, TEST_IMAGE_DATA_URI);
ok(true, "Clipboard contains the currently selected image as data uri.");
yield teardown(monitor);
});
--- a/devtools/client/netmonitor/test/browser_net_copy_params.js
+++ b/devtools/client/netmonitor/test/browser_net_copy_params.js
@@ -70,29 +70,29 @@ add_task(function* () {
item.id === "request-menu-context-copy-url-params");
is(copyUrlParamsNode.visible, !hidden,
"The \"Copy URL Parameters\" context menu item should" + (hidden ? " " : " not ") +
"be hidden.");
}
function* testCopyUrlParams(queryString) {
yield waitForClipboardPromise(function setup() {
- RequestsMenu.copyUrlParams();
+ RequestsMenu.contextMenu.copyUrlParams();
}, queryString);
ok(true, "The url query string copied from the selected item is correct.");
}
function testCopyPostDataHidden(hidden) {
let allMenuItems = openContextMenuAndGetAllItems(NetMonitorView);
let copyPostDataNode = allMenuItems.find(item =>
item.id === "request-menu-context-copy-post-data");
is(copyPostDataNode.visible, !hidden,
"The \"Copy POST Data\" context menu item should" + (hidden ? " " : " not ") +
"be hidden.");
}
function* testCopyPostData(postData) {
yield waitForClipboardPromise(function setup() {
- RequestsMenu.copyPostData();
+ RequestsMenu.contextMenu.copyPostData();
}, postData);
ok(true, "The post data string copied from the selected item is correct.");
}
});
--- a/devtools/client/netmonitor/test/browser_net_copy_response.js
+++ b/devtools/client/netmonitor/test/browser_net_copy_response.js
@@ -23,13 +23,13 @@ add_task(function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
let requestItem = RequestsMenu.getItemAtIndex(3);
RequestsMenu.selectedItem = requestItem;
yield waitForClipboardPromise(function setup() {
- RequestsMenu.copyResponse();
+ RequestsMenu.contextMenu.copyResponse();
}, EXPECTED_RESULT);
yield teardown(monitor);
});
--- a/devtools/client/netmonitor/test/browser_net_copy_svg_image_as_data_uri.js
+++ b/devtools/client/netmonitor/test/browser_net_copy_svg_image_as_data_uri.js
@@ -23,15 +23,15 @@ add_task(function* () {
content.wrappedJSObject.performRequest(url);
});
yield wait;
let requestItem = RequestsMenu.getItemAtIndex(0);
RequestsMenu.selectedItem = requestItem;
yield waitForClipboardPromise(function setup() {
- RequestsMenu.copyImageAsDataUri();
+ RequestsMenu.contextMenu.copyImageAsDataUri();
}, function check(text) {
return text.startsWith("data:") && !/undefined/.test(text);
});
yield teardown(monitor);
});
--- a/devtools/client/netmonitor/test/browser_net_copy_url.js
+++ b/devtools/client/netmonitor/test/browser_net_copy_url.js
@@ -19,13 +19,13 @@ add_task(function* () {
content.wrappedJSObject.performRequests(1);
});
yield wait;
let requestItem = RequestsMenu.getItemAtIndex(0);
RequestsMenu.selectedItem = requestItem;
yield waitForClipboardPromise(function setup() {
- RequestsMenu.copyUrl();
+ RequestsMenu.contextMenu.copyUrl();
}, requestItem.attachment.url);
yield teardown(monitor);
});
--- a/devtools/client/netmonitor/test/browser_net_open_request_in_tab.js
+++ b/devtools/client/netmonitor/test/browser_net_open_request_in_tab.js
@@ -21,17 +21,17 @@ add_task(function* () {
content.wrappedJSObject.performRequests(1);
});
yield wait;
let requestItem = RequestsMenu.getItemAtIndex(0);
RequestsMenu.selectedItem = requestItem;
let onTabOpen = once(gBrowser.tabContainer, "TabOpen", false);
- RequestsMenu.openRequestInTab();
+ RequestsMenu.contextMenu.openRequestInTab();
yield onTabOpen;
ok(true, "A new tab has been opened");
yield teardown(monitor);
gBrowser.removeCurrentTab();
});
--- a/devtools/client/netmonitor/test/head.js
+++ b/devtools/client/netmonitor/test/head.js
@@ -490,21 +490,21 @@ function waitForContentMessage(name) {
def.resolve(msg);
});
return def.promise;
}
/**
* Open the requestMenu menu and return all of it's items in a flat array
* @param {netmonitorPanel} netmonitor
- * @param {Object} options to pass into openMenu
+ * @param {Event} event mouse event with screenX and screenX coordinates
* @return An array of MenuItems
*/
-function openContextMenuAndGetAllItems(netmonitor, options) {
- let menu = netmonitor.RequestsMenu._openMenu(options);
+function openContextMenuAndGetAllItems(netmonitor, event) {
+ let menu = netmonitor.RequestsMenu.contextMenu.open(event);
// Flatten all menu items into a single array to make searching through it easier
let allItems = [].concat.apply([], menu.items.map(function addItem(item) {
if (item.submenu) {
return addItem(item.submenu.items);
}
return item;
}));