--- a/devtools/client/locales/en-US/responsiveUI.properties
+++ b/devtools/client/locales/en-US/responsiveUI.properties
@@ -6,17 +6,16 @@
# which is available from the Web Developer sub-menu -> 'Responsive Mode'.
#
# The correct localization of this file might be to keep it in
# English, or another language commonly spoken among web developers.
# You want to make that choice consistent across the developer tools.
# A good criteria is the language in which you'd find the best
# documentation on web development on the web.
-
# LOCALIZATION NOTE (responsiveUI.rotate2): tooltip of the rotate button.
responsiveUI.rotate2=Rotate
# LOCALIZATION NOTE (responsiveUI.screenshot): tooltip of the screenshot button.
responsiveUI.screenshot=Screenshot
# LOCALIZATION NOTE (responsiveUI.userAgentPlaceholder): placeholder for the user agent input.
responsiveUI.userAgentPlaceholder=Custom User Agent
@@ -62,8 +61,18 @@ responsiveUI.resizerTooltip=Use the Cont
# LOCALIZATION NOTE (responsiveUI.needReload): notification that appears
# when touch events are enabled
responsiveUI.needReload=If touch event listeners have been added earlier, the page needs to be reloaded.
responsiveUI.notificationReload=Reload
responsiveUI.notificationReload_accesskey=R
responsiveUI.dontShowReloadNotification=Never show again
responsiveUI.dontShowReloadNotification_accesskey=N
+
+# LOCALIZATION NOTE (responsiveUI.newVersionUserDisabled): notification that appears
+# when old RDM is displayed because the user has disabled new RDM.
+responsiveUI.newVersionUserDisabled=A new version of Responsive Design Mode is available, but it appears to be disabled. Please enable it and provide feedback, as this version will be removed.
+# LOCALIZATION NOTE (responsiveUI.newVersionE10sDisabled): notification that appears
+# when old RDM is displayed because e10s is disabled.
+responsiveUI.newVersionE10sDisabled=A new version of Responsive Design Mode is available, but it requires multi-process mode, which is currently disabled. Please enable it and provide feedback, as this version will be removed.
+# LOCALIZATION NOTE (responsiveUI.newVersionEnableAndRestart): button text in notification
+# to enable new RDM itself or e10s as a prerequisite for new RDM.
+responsiveUI.newVersionEnableAndRestart=Enable and Restart
\ No newline at end of file
--- a/devtools/client/responsivedesign/responsivedesign.jsm
+++ b/devtools/client/responsivedesign/responsivedesign.jsm
@@ -9,32 +9,37 @@ const Cu = Components.utils;
const { loader, require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
const { LocalizationHelper } = require("devtools/shared/l10n");
const { Task } = require("devtools/shared/task");
const Services = require("Services");
const EventEmitter = require("devtools/shared/event-emitter");
loader.lazyImporter(this, "SystemAppProxy",
"resource://gre/modules/SystemAppProxy.jsm");
+loader.lazyImporter(this, "BrowserUtils",
+ "resource://gre/modules/BrowserUtils.jsm");
loader.lazyRequireGetter(this, "Telemetry", "devtools/client/shared/telemetry");
loader.lazyRequireGetter(this, "showDoorhanger",
"devtools/client/shared/doorhanger", true);
loader.lazyRequireGetter(this, "TouchEventSimulator",
"devtools/shared/touch/simulator", true);
loader.lazyRequireGetter(this, "flags",
"devtools/shared/flags");
loader.lazyRequireGetter(this, "EmulationFront",
"devtools/shared/fronts/emulation", true);
loader.lazyRequireGetter(this, "DebuggerClient",
"devtools/shared/client/main", true);
loader.lazyRequireGetter(this, "DebuggerServer",
"devtools/server/main", true);
+loader.lazyRequireGetter(this, "system", "devtools/shared/system");
this.EXPORTED_SYMBOLS = ["ResponsiveUIManager"];
+const NEW_RDM_ENABLED = "devtools.responsive.html.enabled";
+
const MIN_WIDTH = 50;
const MIN_HEIGHT = 50;
const MAX_WIDTH = 10000;
const MAX_HEIGHT = 10000;
const SLOW_RATIO = 6;
const ROUND_RATIO = 10;
@@ -131,17 +136,17 @@ var Manager = {
};
EventEmitter.decorate(Manager);
// If the new HTML RDM UI is enabled and e10s is enabled by default (e10s is required for
// the new HTML RDM UI to function), delegate the ResponsiveUIManager API over to that
// tool instead. Performing this delegation here allows us to contain the pref check to a
// single place.
-if (Services.prefs.getBoolPref("devtools.responsive.html.enabled") &&
+if (Services.prefs.getBoolPref(NEW_RDM_ENABLED) &&
Services.appinfo.browserTabsRemoteAutostart) {
let { ResponsiveUIManager } =
require("devtools/client/responsive.html/manager");
this.ResponsiveUIManager = ResponsiveUIManager;
} else {
this.ResponsiveUIManager = Manager;
}
@@ -261,16 +266,18 @@ ResponsiveUI.prototype = {
// Hook to display promotional Developer Edition doorhanger.
// Only displayed once.
showDoorhanger({
window: this.mainWindow,
type: "deveditionpromo",
anchor: this.chromeDoc.querySelector("#content")
});
+ this.showNewUINotification();
+
// Notify that responsive mode is on.
this._telemetry.toolOpened("responsive");
ResponsiveUIManager.emit("on", { tab: this.tab });
}),
connectToServer: Task.async(function* () {
if (!DebuggerServer.initialized) {
DebuggerServer.init();
@@ -394,22 +401,24 @@ ResponsiveUI.prototype = {
this.touchEventSimulator.stop();
}
yield this.client.close();
this.client = this.emulationFront = null;
this._telemetry.toolClosed("responsive");
- if (this.tab.linkedBrowser.messageManager) {
+ if (this.tab.linkedBrowser && this.tab.linkedBrowser.messageManager) {
let stopped = this.waitForMessage("ResponsiveMode:Stop:Done");
this.tab.linkedBrowser.messageManager.sendAsyncMessage("ResponsiveMode:Stop");
yield stopped;
}
+ this.hideNewUINotification();
+
this.inited = null;
ResponsiveUIManager.emit("off", { tab: this.tab });
}),
waitForMessage(message) {
return new Promise(resolve => {
let listener = () => {
this.mm.removeMessageListener(message, listener);
@@ -678,16 +687,79 @@ ResponsiveUI.prototype = {
homeButton.addEventListener("mouseup", () => {
SystemAppProxy.dispatchKeyboardEvent("keyup", { key: "Home" });
});
bottomToolbar.appendChild(homeButton);
this.bottomToolbar = bottomToolbar;
this.container.appendChild(bottomToolbar);
},
+ showNewUINotification() {
+ let nbox = this.mainWindow.gBrowser.getNotificationBox(this.browser);
+
+ // One reason we might be using old RDM is that the user explcitly disabled new RDM.
+ // We should encourage them to use the new one, since the old one will be removed.
+ if (Services.prefs.prefHasUserValue(NEW_RDM_ENABLED) &&
+ !Services.prefs.getBoolPref(NEW_RDM_ENABLED)) {
+ let buttons = [{
+ label: this.strings.GetStringFromName("responsiveUI.newVersionEnableAndRestart"),
+ callback: () => {
+ Services.prefs.setBoolPref(NEW_RDM_ENABLED, true);
+ BrowserUtils.restartApplication();
+ },
+ }];
+ nbox.appendNotification(
+ this.strings.GetStringFromName("responsiveUI.newVersionUserDisabled"),
+ "responsive-ui-new-version-user-disabled",
+ null,
+ nbox.PRIORITY_INFO_LOW,
+ buttons
+ );
+ return;
+ }
+
+ // Only show a notification about the new RDM UI on channels where there is an e10s
+ // switch in the preferences UI (Dev. Ed, Nightly). On other channels, it is less
+ // clear how a user would proceed here, so don't show a message.
+ if (!system.constants.E10S_TESTING_ONLY) {
+ return;
+ }
+
+ let buttons = [{
+ label: this.strings.GetStringFromName("responsiveUI.newVersionEnableAndRestart"),
+ callback: () => {
+ Services.prefs.setBoolPref("browser.tabs.remote.autostart", true);
+ Services.prefs.setBoolPref("browser.tabs.remote.autostart.2", true);
+ BrowserUtils.restartApplication();
+ },
+ }];
+ nbox.appendNotification(
+ this.strings.GetStringFromName("responsiveUI.newVersionE10sDisabled"),
+ "responsive-ui-new-version-e10s-disabled",
+ null,
+ nbox.PRIORITY_INFO_LOW,
+ buttons
+ );
+ },
+
+ hideNewUINotification() {
+ if (!this.mainWindow.gBrowser || !this.mainWindow.gBrowser.getNotificationBox) {
+ return;
+ }
+ let nbox = this.mainWindow.gBrowser.getNotificationBox(this.browser);
+ let n = nbox.getNotificationWithValue("responsive-ui-new-version-user-disabled");
+ if (n) {
+ n.close();
+ }
+ n = nbox.getNotificationWithValue("responsive-ui-new-version-e10s-disabled");
+ if (n) {
+ n.close();
+ }
+ },
+
/**
* Validate and apply any user input on the editable menulist
*/
handleManualInput: function () {
let userInput = this.menulist.inputField.value;
let value = INPUT_PARSER.exec(userInput);
let selectedPreset = this.menuitems.get(this.selectedItem);