Bug 1266415 - display a warning on about:debugging if service workers are disabled; r=jdescottes
authorgasolin <gasolin@gmail.com>
Sun, 29 May 2016 19:18:11 -0700
changeset 338325 e0354aa795ba11ec139cbe286e7217ba4fd0ad3e
parent 338324 6c33f0e30df2c7ce28ded1b97820149722cad493
child 338326 cad514ad49c199e823a92e8c8d27e16c22c3cac7
child 338481 42f95268a3210bc372c55cdc94fdae081544aa1a
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdescottes
bugs1266415
milestone49.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1266415 - display a warning on about:debugging if service workers are disabled; r=jdescottes MozReview-Commit-ID: 5OipoBx7LH2
devtools/client/aboutdebugging/aboutdebugging.css
devtools/client/aboutdebugging/components/addons/controls.js
devtools/client/aboutdebugging/components/target-list.js
devtools/client/aboutdebugging/components/workers/panel.js
devtools/client/aboutdebugging/test/browser.ini
devtools/client/aboutdebugging/test/browser_service_workers_not_compatible.js
devtools/client/aboutdebugging/test/head.js
devtools/client/locales/en-US/aboutdebugging.properties
--- a/devtools/client/aboutdebugging/aboutdebugging.css
+++ b/devtools/client/aboutdebugging/aboutdebugging.css
@@ -107,26 +107,28 @@ button {
 }
 
 .addons-install-error {
   background-color: #f3b0b0;
   padding: 5px 10px;
   margin: 5px 4px 5px 0px;
 }
 
+.service-worker-disabled .warning,
 .addons-install-error .warning {
   background-image: url(chrome://devtools/skin/images/alerticon-warning.png);
   background-size: 13px 12px;
   margin-right: 10px;
   display: inline-block;
   width: 13px;
   height: 12px;
 }
 
 @media (min-resolution: 1.1dppx) {
+  .service-worker-disabled .warning,
   .addons-install-error .warning {
     background-image: url(chrome://devtools/skin/images/alerticon-warning@2x.png);
   }
 }
 
 .addons-options {
   flex: 1;
 }
--- a/devtools/client/aboutdebugging/components/addons/controls.js
+++ b/devtools/client/aboutdebugging/components/addons/controls.js
@@ -75,17 +75,17 @@ module.exports = createClass({
           }),
           dom.label({
             className: "addons-debugging-label",
             htmlFor: "enable-addon-debugging",
             title: Strings.GetStringFromName("addonDebugging.tooltip")
           }, Strings.GetStringFromName("addonDebugging.label")),
           "(",
           dom.a({ href: MORE_INFO_URL, target: "_blank" },
-            Strings.GetStringFromName("addonDebugging.moreInfo")),
+            Strings.GetStringFromName("moreInfo")),
           ")"
         ),
         dom.button({
           id: "load-addon-from-file",
           onClick: this.loadAddonFromFile,
         }, Strings.GetStringFromName("loadTemporaryAddon"))
       ),
       AddonsInstallError({ error: this.state.installError }));
--- a/devtools/client/aboutdebugging/components/target-list.js
+++ b/devtools/client/aboutdebugging/components/target-list.js
@@ -14,24 +14,29 @@ const Strings = Services.strings.createB
 const LocaleCompare = (a, b) => {
   return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
 };
 
 module.exports = createClass({
   displayName: "TargetList",
 
   render() {
-    let { client, debugDisabled, targetClass, targets, sort } = this.props;
+    let { client, debugDisabled, error, targetClass, targets, sort } = this.props;
     if (sort) {
       targets = targets.sort(LocaleCompare);
     }
     targets = targets.map(target => {
       return targetClass({ client, target, debugDisabled });
     });
 
+    let content = "";
+    if (error) {
+      content = error;
+    } else if (targets.length > 0) {
+      content = dom.ul({ className: "target-list" }, targets);
+    } else {
+      content = dom.p(null, Strings.GetStringFromName("nothing"));
+    }
+
     return dom.div({ id: this.props.id, className: "targets" },
-      dom.h2(null, this.props.name),
-      targets.length > 0 ?
-        dom.ul({ className: "target-list" }, targets) :
-        dom.p(null, Strings.GetStringFromName("nothing"))
-    );
+      dom.h2(null, this.props.name), content);
   },
 });
--- a/devtools/client/aboutdebugging/components/workers/panel.js
+++ b/devtools/client/aboutdebugging/components/workers/panel.js
@@ -1,29 +1,33 @@
 /* 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 window */
+"use strict";
 
-"use strict";
+loader.lazyImporter(this, "PrivateBrowsingUtils",
+  "resource://gre/modules/PrivateBrowsingUtils.jsm");
 
 const { Ci } = require("chrome");
 const { createClass, createFactory, DOM: dom } =
   require("devtools/client/shared/vendor/react");
 const { getWorkerForms } = require("../../modules/worker");
 const Services = require("Services");
 
 const PanelHeader = createFactory(require("../panel-header"));
 const TargetList = createFactory(require("../target-list"));
 const WorkerTarget = createFactory(require("./target"));
 const ServiceWorkerTarget = createFactory(require("./service-worker-target"));
 
 const Strings = Services.strings.createBundle(
   "chrome://devtools/locale/aboutdebugging.properties");
 
 const WorkerIcon = "chrome://devtools/skin/images/debugging-workers.svg";
+const MORE_INFO_URL = "https://developer.mozilla.org/en-US/docs/Tools/about%3Adebugging";
 
 module.exports = createClass({
   displayName: "WorkersPanel",
 
   getInitialState() {
     return {
       workers: {
         service: [],
@@ -98,29 +102,45 @@ module.exports = createClass({
       this.setState({ workers });
     });
   },
 
   render() {
     let { client, id } = this.props;
     let { workers } = this.state;
 
+    let isWindowPrivate = PrivateBrowsingUtils.isContentWindowPrivate(window);
+    let isPrivateBrowsingMode = PrivateBrowsingUtils.permanentPrivateBrowsing;
+    let isServiceWorkerDisabled = !Services.prefs
+                                    .getBoolPref("dom.serviceWorkers.enabled");
+    let errorMsg = isWindowPrivate || isPrivateBrowsingMode ||
+           isServiceWorkerDisabled ?
+      dom.p({ className: "service-worker-disabled" },
+        dom.div({ className: "warning" }),
+        Strings.GetStringFromName("configurationIsNotCompatible"),
+        " (",
+        dom.a({ href: MORE_INFO_URL, target: "_blank" },
+          Strings.GetStringFromName("moreInfo")),
+        ")"
+      ) : "";
+
     return dom.div({
       id: id + "-panel",
       className: "panel",
       role: "tabpanel",
       "aria-labelledby": id + "-header"
     },
     PanelHeader({
       id: id + "-header",
       name: Strings.GetStringFromName("workers")
     }),
     dom.div({ id: "workers", className: "inverted-icons" },
       TargetList({
         client,
+        error: errorMsg,
         id: "service-workers",
         name: Strings.GetStringFromName("serviceWorkers"),
         sort: true,
         targetClass: ServiceWorkerTarget,
         targets: workers.service
       }),
       TargetList({
         client,
--- a/devtools/client/aboutdebugging/test/browser.ini
+++ b/devtools/client/aboutdebugging/test/browser.ini
@@ -14,14 +14,15 @@ support-files =
 
 [browser_addons_debug_bootstrapped.js]
 [browser_addons_debugging_initial_state.js]
 [browser_addons_install.js]
 [browser_addons_reload.js]
 [browser_addons_toggle_debug.js]
 [browser_page_not_found.js]
 [browser_service_workers.js]
+[browser_service_workers_not_compatible.js]
 [browser_service_workers_push.js]
 [browser_service_workers_start.js]
 [browser_service_workers_timeout.js]
 skip-if = true # Bug 1232931
 [browser_service_workers_unregister.js]
 [browser_tabs.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/aboutdebugging/test/browser_service_workers_not_compatible.js
@@ -0,0 +1,60 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test that Service Worker section should show warning message in
+// about:debugging if any of following conditions is met:
+// 1. service worker is disabled
+// 2. the about:debugging pannel is openned in private browsing mode
+// 3. the about:debugging pannel is openned in private content window
+
+var imgClass = ".service-worker-disabled .warning";
+
+add_task(function* () {
+  yield new Promise(done => {
+    info("disable service workers");
+    let options = {"set": [
+      ["dom.serviceWorkers.enabled", false],
+    ]};
+    SpecialPowers.pushPrefEnv(options, done);
+  });
+
+  let { tab, document } = yield openAboutDebugging("workers");
+  // Check that the warning img appears in the UI
+  let img = document.querySelector(imgClass);
+  ok(img, "warning message is rendered");
+
+  yield closeAboutDebugging(tab);
+});
+
+add_task(function* () {
+  yield new Promise(done => {
+    info("set private browsing mode as default");
+    let options = {"set": [
+      ["browser.privatebrowsing.autostart", true],
+    ]};
+    SpecialPowers.pushPrefEnv(options, done);
+  });
+
+  let { tab, document } = yield openAboutDebugging("workers");
+  // Check that the warning img appears in the UI
+  let img = document.querySelector(imgClass);
+  ok(img, "warning message is rendered");
+
+  yield closeAboutDebugging(tab);
+});
+
+add_task(function* () {
+  info("Opening a new private window");
+  let win = OpenBrowserWindow({private: true});
+  yield waitForDelayedStartupFinished(win);
+
+  let { tab, document } = yield openAboutDebugging("workers", win);
+  // Check that the warning img appears in the UI
+  let img = document.querySelector(imgClass);
+  ok(img, "warning message is rendered");
+
+  yield closeAboutDebugging(tab, win);
+  win.close();
+});
--- a/devtools/client/aboutdebugging/test/head.js
+++ b/devtools/client/aboutdebugging/test/head.js
@@ -1,17 +1,18 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /* eslint-env browser */
 /* eslint-disable mozilla/no-cpows-in-tests */
 /* exported openAboutDebugging, changeAboutDebuggingHash, closeAboutDebugging,
    installAddon, uninstallAddon, waitForMutation, assertHasTarget,
    getServiceWorkerList, getTabList, openPanel, waitForInitialAddonList,
-   waitForServiceWorkerRegistered, unregisterServiceWorker */
+   waitForServiceWorkerRegistered, unregisterServiceWorker,
+   waitForDelayedStartupFinished */
 
 "use strict";
 
 var { utils: Cu, classes: Cc, interfaces: Ci } = Components;
 
 const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
 const { AddonManager } = Cu.import("resource://gre/modules/AddonManager.jsm", {});
 const Services = require("Services");
@@ -19,24 +20,24 @@ const DevToolsUtils = require("devtools/
 DevToolsUtils.testing = true;
 
 const CHROME_ROOT = gTestPath.substr(0, gTestPath.lastIndexOf("/") + 1);
 
 registerCleanupFunction(() => {
   DevToolsUtils.testing = false;
 });
 
-function* openAboutDebugging(page) {
+function* openAboutDebugging(page, win) {
   info("opening about:debugging");
   let url = "about:debugging";
   if (page) {
     url += "#" + page;
   }
 
-  let tab = yield addTab(url);
+  let tab = yield addTab(url, win);
   let browser = tab.linkedBrowser;
   let document = browser.contentDocument;
 
   if (!document.querySelector(".app")) {
     yield waitForMutation(document.body, { childList: true });
   }
 
   return { tab, document };
@@ -58,19 +59,19 @@ function changeAboutDebuggingHash(docume
 
 function openPanel(document, panelId) {
   info(`Opening ${panelId} panel`);
   document.querySelector(`[aria-controls="${panelId}"]`).click();
   return waitForMutation(
     document.querySelector(".main-content"), {childList: true});
 }
 
-function closeAboutDebugging(tab) {
+function closeAboutDebugging(tab, win) {
   info("Closing about:debugging");
-  return removeTab(tab);
+  return removeTab(tab, win);
 }
 
 function addTab(url, win, backgroundTab = false) {
   info("Adding tab: " + url);
 
   return new Promise(done => {
     let targetWindow = win || window;
     let targetBrowser = targetWindow.gBrowser;
@@ -291,8 +292,25 @@ function waitForServiceWorkerRegistered(
 function unregisterServiceWorker(tab) {
   return ContentTask.spawn(tab.linkedBrowser, {}, function* () {
     // Retrieve the `sw` promise created in the html page
     let { sw } = content.wrappedJSObject;
     let registration = yield sw;
     yield registration.unregister();
   });
 }
+
+/**
+ * Waits for the creation of a new window, usually used with create private
+ * browsing window.
+ * Returns a promise that will resolve when the window is successfully created.
+ * @param {window} win
+ */
+function waitForDelayedStartupFinished(win) {
+  return new Promise(function (resolve) {
+    Services.obs.addObserver(function observer(subject, topic) {
+      if (win == subject) {
+        Services.obs.removeObserver(observer, topic);
+        resolve();
+      }
+    }, "browser-delayed-startup-finished", false);
+  });
+}
--- a/devtools/client/locales/en-US/aboutdebugging.properties
+++ b/devtools/client/locales/en-US/aboutdebugging.properties
@@ -7,17 +7,17 @@ push = Push
 start = Start
 
 scope = Scope
 unregister = unregister
 
 addons = Add-ons
 addonDebugging.label = Enable add-on debugging
 addonDebugging.tooltip = Turning this on will allow you to debug add-ons and various other parts of the browser chrome
-addonDebugging.moreInfo = more info
+moreInfo = more info
 loadTemporaryAddon = Load Temporary Add-on
 extensions = Extensions
 selectAddonFromFile2 = Select Manifest File or Package (.xpi)
 reload = Reload
 reloadDisabledTooltip = Only temporarily installed add-ons can be reloaded
 
 workers = Workers
 serviceWorkers = Service Workers
@@ -25,8 +25,9 @@ sharedWorkers = Shared Workers
 otherWorkers = Other Workers
 
 tabs = Tabs
 
 pageNotFound = Page not found
 doesNotExist = #%S does not exist!
 
 nothing = Nothing yet.
+configurationIsNotCompatible = Your browser configuration is not compatible with Service Workers