s draft
authorFred Lin <gasolin@mozilla.com>
Mon, 17 Oct 2016 15:01:52 +0800
changeset 426693 f5d9b8a36fa5d4ee58d54a8692380edac29765f0
parent 426690 29f57d48fdf4789847ec80dfeb47535dc643de4c
child 426694 6ed42e0ddf0e08897d82140d494f59ea780325b1
push id32778
push userbmo:gasolin@mozilla.com
push dateWed, 19 Oct 2016 01:51:53 +0000
milestone52.0a1
s MozReview-Commit-ID: AAvK4aBim8K
devtools/client/netmonitor/netmonitor.xul
devtools/client/netmonitor/requests-menu-view.js
--- a/devtools/client/netmonitor/netmonitor.xul
+++ b/devtools/client/netmonitor/netmonitor.xul
@@ -11,58 +11,16 @@
         xmlns:html="http://www.w3.org/1999/xhtml"
         data-localization-bundle="devtools/locale/netmonitor.properties">
 
   <script type="application/javascript;version=1.8"
           src="chrome://devtools/content/shared/theme-switching.js"/>
   <script type="text/javascript" src="netmonitor-controller.js"/>
   <script type="text/javascript" src="netmonitor-view.js"/>
 
-  <popupset id="networkPopupSet">
-    <menupopup id="network-request-popup">
-      <menuitem id="request-menu-context-copy-url"
-                data-localization="label=netmonitor.context.copyUrl;accesskey=netmonitor.context.copyUrl.accesskey"/>
-      <menuitem id="request-menu-context-copy-url-params"
-                data-localization="label=netmonitor.context.copyUrlParams;accesskey=netmonitor.context.copyUrlParams.accesskey"
-                oncommand="NetMonitorView.RequestsMenu.copyUrlParams();"/>
-      <menuitem id="request-menu-context-copy-post-data"
-                data-localization="label=netmonitor.context.copyPostData;accesskey=netmonitor.context.copyPostData.accesskey"
-                oncommand="NetMonitorView.RequestsMenu.copyPostData();"/>
-      <menuitem id="request-menu-context-copy-as-curl"
-                data-localization="label=netmonitor.context.copyAsCurl;accesskey=netmonitor.context.copyAsCurl.accesskey"
-                oncommand="NetMonitorView.RequestsMenu.copyAsCurl();"/>
-      <menuseparator class="request-menu-context-separator"/>
-      <menuitem id="request-menu-context-copy-request-headers"
-                data-localization="label=netmonitor.context.copyRequestHeaders;accesskey=netmonitor.context.copyRequestHeaders.accesskey"
-                oncommand="NetMonitorView.RequestsMenu.copyRequestHeaders();"/>
-      <menuitem id="response-menu-context-copy-response-headers"
-                data-localization="label=netmonitor.context.copyResponseHeaders;accesskey=netmonitor.context.copyResponseHeaders.accesskey"
-                oncommand="NetMonitorView.RequestsMenu.copyResponseHeaders();"/>
-      <menuitem id="request-menu-context-copy-response"
-                data-localization="label=netmonitor.context.copyResponse;accesskey=netmonitor.context.copyResponse.accesskey"/>
-      <menuitem id="request-menu-context-copy-image-as-data-uri"
-                data-localization="label=netmonitor.context.copyImageAsDataUri;accesskey=netmonitor.context.copyImageAsDataUri.accesskey"/>
-      <menuseparator class="request-menu-context-separator"/>
-      <menuitem id="request-menu-context-copy-all-as-har"
-                data-localization="label=netmonitor.context.copyAllAsHar;accesskey=netmonitor.context.copyAllAsHar.accesskey"
-                oncommand="NetMonitorView.RequestsMenu.copyAllAsHar();"/>
-      <menuitem id="request-menu-context-save-all-as-har"
-                data-localization="label=netmonitor.context.saveAllAsHar;accesskey=netmonitor.context.saveAllAsHar.accesskey"
-                oncommand="NetMonitorView.RequestsMenu.saveAllAsHar();"/>
-      <menuseparator class="request-menu-context-separator"/>
-      <menuitem id="request-menu-context-resend"
-                data-localization="label=netmonitor.context.editAndResend;accesskey=netmonitor.context.editAndResend.accesskey"/>
-      <menuseparator class="request-menu-context-separator"/>
-      <menuitem id="request-menu-context-newtab"
-                data-localization="label=netmonitor.context.newTab;accesskey=netmonitor.context.newTab.accesskey"/>
-      <menuitem id="request-menu-context-perf"
-                data-localization="label=netmonitor.context.perfTools;accesskey=netmonitor.context.perfTools.accesskey"/>
-    </menupopup>
-  </popupset>
-
   <commandset>
     <command id="freeTextFilterCommand"
              oncommand="NetMonitorView.RequestsMenu.freetextFilterBox.focus()"/>
   </commandset>
 
   <keyset>
     <key id="freeTextFilterKey"
          data-localization="key=netmonitor.footer.filterFreetext.key"
@@ -282,17 +240,17 @@
               <button id="requests-menu-perf-notice-button"
                       class="devtools-toolbarbutton"
                       standalone="true"
                       data-localization="tooltiptext=netmonitor.perfNotice3"/>
               <label data-localization="content=netmonitor.perfNotice2"/>
             </hbox>
           </vbox>
 
-          <vbox id="requests-menu-contents" flex="1" context="network-request-popup">
+          <vbox id="requests-menu-contents" flex="1">
             <hbox id="requests-menu-item-template" hidden="true">
               <hbox class="requests-menu-subitem requests-menu-status"
                     align="center">
                 <box class="requests-menu-status-icon"/>
                 <label class="plain requests-menu-status-code"
                        crop="end"/>
               </hbox>
               <hbox class="requests-menu-subitem requests-menu-method-box"
--- a/devtools/client/netmonitor/requests-menu-view.js
+++ b/devtools/client/netmonitor/requests-menu-view.js
@@ -9,16 +9,18 @@ const {DeferredTask} = Cu.import("resour
 /* 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 {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,
        writeHeaderText,
@@ -120,17 +122,16 @@ RequestsMenuView.prototype = Heritage.ex
       .createInstance(Ci.nsITimer);
 
     // Create a tooltip for the newly appended network request item.
     this.tooltip = new HTMLTooltip(NetMonitorController._toolbox.doc, { type: "arrow" });
     this.tooltip.startTogglingOnHover(widgetParentEl, this._onHover, {
       toggleDelay: REQUESTS_TOOLTIP_TOGGLE_DELAY,
       interactive: true
     });
-    $("#requests-menu-contents").addEventListener("scroll", this._onScroll, true);
 
     Prefs.filters.forEach(type => this.filterOn(type));
     this.sortContents((a, b) => Sorters.waterfall(a.attachment, b.attachment));
 
     this.allowFocusOnRightClick = true;
     this.maintainSelectionVisible = true;
 
     this.widget.addEventListener("select", this._onSelect, false);
@@ -139,17 +140,17 @@ RequestsMenuView.prototype = Heritage.ex
     window.addEventListener("resize", this._onResize, false);
 
     this.requestsMenuSortEvent = getKeyWithEvent(this.sortBy.bind(this));
     this.requestsMenuSortKeyboardEvent = getKeyWithEvent(this.sortBy.bind(this), true);
     this.requestsMenuFilterEvent = getKeyWithEvent(this.filterOn.bind(this));
     this.requestsMenuFilterKeyboardEvent = getKeyWithEvent(
       this.filterOn.bind(this), true);
     this.reqeustsMenuClearEvent = this.clear.bind(this);
-    this._onContextShowing = this._onContextShowing.bind(this);
+    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();
@@ -177,62 +178,48 @@ RequestsMenuView.prototype = Heritage.ex
     $("#toolbar-labels").addEventListener("keydown",
       this.requestsMenuSortKeyboardEvent, false);
     $("#requests-menu-filter-buttons").addEventListener("click",
       this.requestsMenuFilterEvent, false);
     $("#requests-menu-filter-buttons").addEventListener("keydown",
       this.requestsMenuFilterKeyboardEvent, false);
     $("#requests-menu-clear-button").addEventListener("click",
       this.reqeustsMenuClearEvent, false);
-    $("#network-request-popup").addEventListener("popupshowing",
-      this._onContextShowing, false);
-    $("#request-menu-context-newtab").addEventListener("command",
-      this._onContextNewTabCommand, false);
-    $("#request-menu-context-copy-url").addEventListener("command",
-      this._onContextCopyUrlCommand, false);
-    $("#request-menu-context-copy-response").addEventListener("command",
-      this._onContextCopyResponseCommand, false);
-    $("#request-menu-context-copy-image-as-data-uri").addEventListener(
-      "command", this._onContextCopyImageAsDataUriCommand, false);
     $("#toggle-raw-headers").addEventListener("click",
       this.toggleRawHeadersEvent, false);
+    $("#requests-menu-contents").addEventListener("scroll", this._onScroll, true);
+    $("#requests-menu-contents").addEventListener("contextmenu", this._onContextMenu);
 
     window.once("connected", this._onConnect.bind(this));
   },
 
   _onConnect: function () {
     $("#requests-menu-reload-notice-button").addEventListener("command",
       this._onReloadCommand, false);
 
     if (NetMonitorController.supportsCustomRequest) {
-      $("#request-menu-context-resend").addEventListener("command",
-        this._onContextResendCommand, false);
       $("#custom-request-send-button").addEventListener("click",
         this.sendCustomRequestEvent, false);
       $("#custom-request-close-button").addEventListener("click",
         this.closeCustomRequestEvent, false);
       $("#headers-summary-resend").addEventListener("click",
         this.cloneSelectedRequestEvent, false);
     } else {
-      $("#request-menu-context-resend").hidden = true;
       $("#headers-summary-resend").hidden = true;
     }
 
     if (NetMonitorController.supportsPerfStats) {
-      $("#request-menu-context-perf").addEventListener("command",
-        this._onContextPerfCommand, false);
       $("#requests-menu-perf-notice-button").addEventListener("command",
         this._onContextPerfCommand, false);
       $("#requests-menu-network-summary-button").addEventListener("command",
         this._onContextPerfCommand, false);
       $("#network-statistics-back-button").addEventListener("command",
         this._onContextPerfCommand, false);
     } else {
       $("#notice-perf-message").hidden = true;
-      $("#request-menu-context-perf").hidden = true;
       $("#requests-menu-network-summary-button").hidden = true;
     }
 
     if (!NetMonitorController.supportsTransferredResponseSize) {
       $("#requests-menu-transferred-header-box").hidden = true;
       $("#requests-menu-item-template .requests-menu-transferred")
         .hidden = true;
     }
@@ -245,16 +232,17 @@ RequestsMenuView.prototype = Heritage.ex
     dumpn("Destroying the RequestsMenuView");
 
     Prefs.filters = this._activeFilters;
 
     /* Destroy the tooltip */
     this.tooltip.stopTogglingOnHover();
     this.tooltip.destroy();
     $("#requests-menu-contents").removeEventListener("scroll", this._onScroll, true);
+    $("#requests-menu-contents").removeEventListener("contextmenu", this._onContextMenu);
 
     this.widget.removeEventListener("select", this._onSelect, false);
     this.widget.removeEventListener("swap", this._onSwap, false);
     this._splitter.removeEventListener("mousemove", this._onResize, false);
     window.removeEventListener("resize", this._onResize, false);
 
     $("#toolbar-labels").removeEventListener("click",
       this.requestsMenuSortEvent, false);
@@ -269,31 +257,16 @@ RequestsMenuView.prototype = Heritage.ex
     this.freetextFilterBox.removeEventListener("input",
       this.requestsFreetextFilterEvent, false);
     this.freetextFilterBox.removeEventListener("command",
       this.requestsFreetextFilterEvent, false);
 
     this.userInputTimer.cancel();
     this._flushRequestsTask.disarm();
 
-    $("#network-request-popup").removeEventListener("popupshowing",
-      this._onContextShowing, false);
-    $("#request-menu-context-newtab").removeEventListener("command",
-      this._onContextNewTabCommand, false);
-    $("#request-menu-context-copy-url").removeEventListener("command",
-      this._onContextCopyUrlCommand, false);
-    $("#request-menu-context-copy-response").removeEventListener("command",
-      this._onContextCopyResponseCommand, false);
-    $("#request-menu-context-copy-image-as-data-uri").removeEventListener(
-      "command", this._onContextCopyImageAsDataUriCommand, false);
-    $("#request-menu-context-resend").removeEventListener("command",
-      this._onContextResendCommand, false);
-    $("#request-menu-context-perf").removeEventListener("command",
-      this._onContextPerfCommand, false);
-
     $("#requests-menu-reload-notice-button").removeEventListener("command",
       this._onReloadCommand, false);
     $("#requests-menu-perf-notice-button").removeEventListener("command",
       this._onContextPerfCommand, false);
     $("#requests-menu-network-summary-button").removeEventListener("command",
       this._onContextPerfCommand, false);
     $("#network-statistics-back-button").removeEventListener("command",
       this._onContextPerfCommand, false);
@@ -1839,73 +1812,163 @@ RequestsMenuView.prototype = Heritage.ex
    */
   _onScroll: function () {
     this.tooltip.hide();
   },
 
   /**
    * Handle the context menu opening. Hide items if no request is selected.
    */
-  _onContextShowing: function () {
+  _onContextMenu: function (e) {
+    e.preventDefault();
+    this._openMenu({
+      screenX: e.screenX,
+      screenY: e.screenY,
+      target: e.target,
+    });
+  },
+
+   _openMenu: function ({ target, screenX = 0, screenY = 0 } = { }) {
     let selectedItem = this.selectedItem;
 
-    let resendElement = $("#request-menu-context-resend");
-    resendElement.hidden = !NetMonitorController.supportsCustomRequest ||
-      !selectedItem || selectedItem.attachment.isCustom;
+    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(),
+    }));
 
-    let copyUrlElement = $("#request-menu-context-copy-url");
-    copyUrlElement.hidden = !selectedItem;
+    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(),
+    }));
 
-    let copyUrlParamsElement = $("#request-menu-context-copy-url-params");
-    copyUrlParamsElement.hidden = !selectedItem ||
-      !NetworkHelper.nsIURL(selectedItem.attachment.url).query;
+    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(),
+    }));
 
-    let copyPostDataElement = $("#request-menu-context-copy-post-data");
-    copyPostDataElement.hidden = !selectedItem ||
-      !selectedItem.attachment.requestPostData;
+    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,
+    }));
 
-    let copyAsCurlElement = $("#request-menu-context-copy-as-curl");
-    copyAsCurlElement.hidden = !selectedItem || !selectedItem.attachment;
+    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(),
+    }));
 
-    let copyRequestHeadersElement =
-      $("#request-menu-context-copy-request-headers");
-    copyRequestHeadersElement.hidden = !selectedItem ||
-    !selectedItem.attachment.requestHeaders;
+    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(),
+    }));
 
-    let copyResponseHeadersElement =
-      $("#response-menu-context-copy-response-headers");
-    copyResponseHeadersElement.hidden = !selectedItem ||
-      !selectedItem.attachment.responseHeaders;
+    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,
+    }));
 
-    let copyResponse = $("#request-menu-context-copy-response");
-    copyResponse.hidden = !selectedItem ||
-      !selectedItem.attachment.responseContent ||
-      !selectedItem.attachment.responseContent.content.text ||
-      selectedItem.attachment.responseContent.content.text.length === 0;
+    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: NetMonitorView.RequestsMenu.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: NetMonitorView.RequestsMenu.items.length,
+      click: () => this.saveAllAsHar(),
+    }));
 
-    let copyImageAsDataUriElement =
-      $("#request-menu-context-copy-image-as-data-uri");
-    copyImageAsDataUriElement.hidden = !selectedItem ||
-      !selectedItem.attachment.responseContent ||
-      !selectedItem.attachment.responseContent.content
-        .mimeType.includes("image/");
+    menu.append(new MenuItem({
+      type: "separator",
+      visible: selectedItem,
+    }));
+
+    menu.append(new MenuItem({
+      id: "request-menu-context-resend",
+      label: L10N.getStr("netmonitor.summary.editAndResend"),
+      accesskey: L10N.getStr("netmonitor.summary.editAndResend.accesskey"),
+      visible: NetMonitorController.supportsCustomRequest &&
+               selectedItem &&
+               !selectedItem.attachment.isCustom,
+      click: () => this._onContextResendCommand(),
+    }));
 
-    let separators = $all(".request-menu-context-separator");
-    Array.forEach(separators, separator => {
-      separator.hidden = !selectedItem;
-    });
+    menu.append(new MenuItem({
+      type: "separator",
+      visible: !selectedItem,
+    }));
 
-    let copyAsHar = $("#request-menu-context-copy-all-as-har");
-    copyAsHar.hidden = !NetMonitorView.RequestsMenu.items.length;
+    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(),
+    }));
 
-    let saveAsHar = $("#request-menu-context-save-all-as-har");
-    saveAsHar.hidden = !NetMonitorView.RequestsMenu.items.length;
+    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(),
+    }));
 
-    let newTabElement = $("#request-menu-context-newtab");
-    newTabElement.hidden = !selectedItem;
+    menu.popup(screenX, screenY, NetMonitorController._toolbox);
+    return menu;
   },
 
   /**
    * 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.