Bug 1428816 - Show reload help on first RDM open. r=ochameau draft
authorJ. Ryan Stinnett <jryans@gmail.com>
Thu, 08 Feb 2018 18:43:23 -0600
changeset 758578 dba08ff6fedada12d4ed77d2fc6759961dfa32d2
parent 758577 6249f7f609e2d79222c74735ce37d0bbcc7ba14b
push id100108
push userbmo:jryans@gmail.com
push dateThu, 22 Feb 2018 18:02:07 +0000
reviewersochameau
bugs1428816
milestone60.0a1
Bug 1428816 - Show reload help on first RDM open. r=ochameau The first time RDM is opened after this, show a notification explaining that a reload is needed to apply certain emulation features. MozReview-Commit-ID: 26GMbhT5MUo
devtools/client/locales/en-US/responsive.properties
devtools/client/preferences/devtools.js
devtools/client/responsive.html/manager.js
devtools/client/responsive.html/utils/moz.build
devtools/client/responsive.html/utils/notification.js
--- a/devtools/client/locales/en-US/responsive.properties
+++ b/devtools/client/locales/en-US/responsive.properties
@@ -148,9 +148,14 @@ responsive.reloadConditions.label=Reload when…
 responsive.reloadConditions.title=Choose whether to reload the page automatically when certain actions occur
 
 # LOCALIZATION NOTE (responsive.reloadConditions.touchSimulation): Label on checkbox used
 # to select whether to reload when touch simulation is toggled.
 responsive.reloadConditions.touchSimulation=Reload when touch simulation is toggled
 
 # LOCALIZATION NOTE (responsive.reloadConditions.userAgent): Label on checkbox used
 # to select whether to reload when user agent is changed.
-responsive.reloadConditions.userAgent=Reload when user agent is changed
\ No newline at end of file
+responsive.reloadConditions.userAgent=Reload when user agent is changed
+
+# LOCALIZATION NOTE (responsive.reloadNotification.description): Text in notification bar
+# shown on first open to clarify that some features need a reload to apply.  %1$S is the
+# label on the reload conditions menu (responsive.reloadConditions.label).
+responsive.reloadNotification.description=Device simulation changes require a reload to fully apply.  Automatic reloads are disabled by default to avoid losing any changes in DevTools.  You can enable reloading via the “%1$S” menu.
--- a/devtools/client/preferences/devtools.js
+++ b/devtools/client/preferences/devtools.js
@@ -357,8 +357,10 @@ pref("devtools.editor.autocomplete", tru
 // opened developer tool. This allows us to ping telemetry just once per browser
 // version for each user.
 pref("devtools.telemetry.tools.opened.version", "{}");
 
 // Whether to reload when touch simulation is toggled
 pref("devtools.responsive.reloadConditions.touchSimulation", false);
 // Whether to reload when user agent is changed
 pref("devtools.responsive.reloadConditions.userAgent", false);
+// Whether to show the notification about reloading to apply emulation
+pref("devtools.responsive.reloadNotification.enabled", true);
--- a/devtools/client/responsive.html/manager.js
+++ b/devtools/client/responsive.html/manager.js
@@ -8,32 +8,27 @@ const { Ci } = require("chrome");
 const promise = require("promise");
 const Services = require("Services");
 const EventEmitter = require("devtools/shared/old-event-emitter");
 
 const TOOL_URL = "chrome://devtools/content/responsive.html/index.xhtml";
 
 loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/debugger-client", true);
 loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
-loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/target", true);
-loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true);
-loader.lazyRequireGetter(this, "throttlingProfiles",
-  "devtools/client/shared/network-throttling-profiles");
-loader.lazyRequireGetter(this, "swapToInnerBrowser",
-  "devtools/client/responsive.html/browser/swap", true);
-loader.lazyRequireGetter(this, "startup",
-  "devtools/client/responsive.html/utils/window", true);
-loader.lazyRequireGetter(this, "message",
-  "devtools/client/responsive.html/utils/message");
-loader.lazyRequireGetter(this, "getStr",
-  "devtools/client/responsive.html/utils/l10n", true);
-loader.lazyRequireGetter(this, "EmulationFront",
-  "devtools/shared/fronts/emulation", true);
+loader.lazyRequireGetter(this, "throttlingProfiles", "devtools/client/shared/network-throttling-profiles");
+loader.lazyRequireGetter(this, "swapToInnerBrowser", "devtools/client/responsive.html/browser/swap", true);
+loader.lazyRequireGetter(this, "startup", "devtools/client/responsive.html/utils/window", true);
+loader.lazyRequireGetter(this, "message", "devtools/client/responsive.html/utils/message");
+loader.lazyRequireGetter(this, "showNotification", "devtools/client/responsive.html/utils/notification", true);
+loader.lazyRequireGetter(this, "l10n", "devtools/client/responsive.html/utils/l10n");
+loader.lazyRequireGetter(this, "EmulationFront", "devtools/shared/fronts/emulation", true);
+loader.lazyRequireGetter(this, "PriorityLevels", "devtools/client/shared/components/NotificationBox", true);
 
 const RELOAD_CONDITION_PREF_PREFIX = "devtools.responsive.reloadConditions.";
+const RELOAD_NOTIFICATION_PREF = "devtools.responsive.reloadNotification.enabled";
 
 function debug(msg) {
   // console.log(`RDM manager: ${msg}`);
 }
 
 /**
  * ResponsiveUIManager is the external API for the browser UI, etc. to use when
  * opening and closing the responsive UI.
@@ -219,52 +214,30 @@ const ResponsiveUIManager = exports.Resp
     await startup(window);
 
     let menu = window.document.getElementById("menu_responsiveUI");
     if (menu) {
       menu.setAttribute("checked", this.isActiveForTab(tab));
     }
   },
 
-  showRemoteOnlyNotification(window, tab, options) {
-    this.showErrorNotification(window, tab, options, getStr("responsive.remoteOnly"));
-  },
-
-  showNoContainerTabsNotification(window, tab, options) {
-    this.showErrorNotification(window, tab, options,
-                               getStr("responsive.noContainerTabs"));
+  showRemoteOnlyNotification(window, tab, { command } = {}) {
+    showNotification(window, tab, {
+      command,
+      msg: l10n.getStr("responsive.remoteOnly"),
+      priority: PriorityLevels.PRIORITY_CRITICAL_MEDIUM,
+    });
   },
 
-  showErrorNotification(window, tab, { command } = {}, msg) {
-    // Default to using the browser's per-tab notification box
-    let nbox = window.gBrowser.getNotificationBox(tab.linkedBrowser);
-
-    // If opening was initiated by GCLI command bar or toolbox button, check for an open
-    // toolbox for the tab.  If one exists, use the toolbox's notification box so that the
-    // message is placed closer to the action taken by the user.
-    if (command) {
-      let target = TargetFactory.forTab(tab);
-      let toolbox = gDevTools.getToolbox(target);
-      if (toolbox) {
-        nbox = toolbox.notificationBox;
-      }
-    }
-
-    let value = "devtools-responsive-error";
-    if (nbox.getNotificationWithValue(value)) {
-      // Notification already displayed
-      return;
-    }
-
-    nbox.appendNotification(
-       msg,
-       value,
-       null,
-       nbox.PRIORITY_CRITICAL_MEDIUM,
-       []);
+  showNoContainerTabsNotification(window, tab, { command } = {}) {
+    showNotification(window, tab, {
+      command,
+      msg: l10n.getStr("responsive.noContainerTabs"),
+      priority: PriorityLevels.PRIORITY_CRITICAL_MEDIUM,
+    });
   },
 };
 
 // GCLI commands in ./commands.js listen for events from this object to know
 // when the UI for a tab has opened or closed.
 EventEmitter.decorate(ResponsiveUIManager);
 
 /**
@@ -450,17 +423,31 @@ ResponsiveUI.prototype = {
     DebuggerServer.init();
     DebuggerServer.registerAllActors();
     this.client = new DebuggerClient(DebuggerServer.connectPipe());
     await this.client.connect();
     let { tab } = await this.client.getTab();
     this.emulationFront = EmulationFront(this.client, tab);
   },
 
+  /**
+   * Show one-time notification about reloads for emulation.
+   */
+  showReloadNotification() {
+    if (Services.prefs.getBoolPref(RELOAD_NOTIFICATION_PREF, false)) {
+      showNotification(this.browserWindow, this.tab, {
+        msg: l10n.getFormatStr("responsive.reloadNotification.description",
+                               l10n.getStr("responsive.reloadConditions.label")),
+      });
+      Services.prefs.setBoolPref(RELOAD_NOTIFICATION_PREF, false);
+    }
+  },
+
   reloadOnChange(id) {
+    this.showReloadNotification();
     let pref = RELOAD_CONDITION_PREF_PREFIX + id;
     return Services.prefs.getBoolPref(pref, false);
   },
 
   handleEvent(event) {
     let { browserWindow, tab } = this;
 
     switch (event.type) {
--- a/devtools/client/responsive.html/utils/moz.build
+++ b/devtools/client/responsive.html/utils/moz.build
@@ -5,10 +5,11 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DevToolsModules(
     'css.js',
     'e10s.js',
     'key.js',
     'l10n.js',
     'message.js',
+    'notification.js',
     'window.js',
 )
new file mode 100644
--- /dev/null
+++ b/devtools/client/responsive.html/utils/notification.js
@@ -0,0 +1,53 @@
+/* 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/. */
+
+"use strict";
+
+loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/target", true);
+loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true);
+
+/**
+ * Displays a notification either at the browser or toolbox level, depending on whether
+ * a toolbox is currently open for this tab.
+ *
+ * @param window
+ *        The main browser chrome window.
+ * @param tab
+ *        The browser tab.
+ * @param options
+ *        Other options associated with opening.  Currently includes:
+ *        - `command`: Whether initiated via GCLI command bar or toolbox button
+ *        - `msg`: String to show in the notification
+ *        - `priority`: Priority level for the notification, which affects the icon and
+ *                      overall appearance.
+ */
+function showNotification(window, tab, { command, msg, priority } = {}) {
+  // Default to using the browser's per-tab notification box
+  let nbox = window.gBrowser.getNotificationBox(tab.linkedBrowser);
+
+  // If opening was initiated by GCLI command bar or toolbox button, check for an open
+  // toolbox for the tab.  If one exists, use the toolbox's notification box so that the
+  // message is placed closer to the action taken by the user.
+  if (command) {
+    let target = TargetFactory.forTab(tab);
+    let toolbox = gDevTools.getToolbox(target);
+    if (toolbox) {
+      nbox = toolbox.notificationBox;
+    }
+  }
+
+  let value = "devtools-responsive";
+  if (nbox.getNotificationWithValue(value)) {
+    // Notification already displayed
+    return;
+  }
+
+  if (!priority) {
+    priority = nbox.PRIORITY_INFO_MEDIUM;
+  }
+
+  nbox.appendNotification(msg, value, null, priority, []);
+}
+
+exports.showNotification = showNotification;