Bug 1635401 - Part 2: add colored dot to mark service worker state r=jdescottes
authorBelén Albeza <balbeza@mozilla.com>
Tue, 12 May 2020 15:47:54 +0000
changeset 529853 28529c0faf8f52387d1777c64ce83904a869a2d4
parent 529852 c5841a4c7ab6949519ab442b3459afa5f78fe28e
child 529854 1141a5933cc0becf72f5ffc42144fe84fb8126b8
push id115942
push userbalbeza@mozilla.com
push dateThu, 14 May 2020 11:06:40 +0000
treeherderautoland@3a030dbe3444 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdescottes
bugs1635401
milestone78.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 1635401 - Part 2: add colored dot to mark service worker state r=jdescottes Differential Revision: https://phabricator.services.mozilla.com/D74659
devtools/client/application/src/components/service-workers/Registration.js
devtools/client/application/src/components/service-workers/Worker.css
devtools/client/application/src/components/service-workers/Worker.js
devtools/client/application/src/reducers/workers-state.js
devtools/client/application/src/types/service-workers.js
devtools/client/application/test/node/components/service-workers/__snapshots__/components_application_panel-Registration.test.js.snap
devtools/client/application/test/node/components/service-workers/__snapshots__/components_application_panel-RegistrationList.test.js.snap
devtools/client/application/test/node/components/service-workers/__snapshots__/components_application_panel-Worker.test.js.snap
devtools/client/application/test/node/components/service-workers/__snapshots__/components_application_panel-WorkersPage.test.js.snap
devtools/client/application/test/node/fixtures/Chrome.js
devtools/client/application/test/node/fixtures/data/constants.js
devtools/client/application/test/xpcshell/test_workers_reducer.js
--- a/devtools/client/application/src/components/service-workers/Registration.js
+++ b/devtools/client/application/src/components/service-workers/Registration.js
@@ -1,14 +1,16 @@
 /* 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";
 
+const { Ci } = require("chrome");
+
 const {
   createFactory,
   PureComponent,
 } = require("devtools/client/shared/vendor/react");
 
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
 
 const {
@@ -60,17 +62,19 @@ class Registration extends PureComponent
 
   unregister() {
     const { registrationFront } = this.props.registration;
     registrationFront.unregister();
   }
 
   isActive() {
     const { workers } = this.props.registration;
-    return workers.some(x => x.isActive);
+    return workers.some(
+      x => x.state === Ci.nsIServiceWorkerInfo.STATE_ACTIVATED
+    );
   }
 
   formatScope(scope) {
     const [, remainder] = getUnicodeUrl(scope).split("://");
     return remainder || scope;
   }
 
   render() {
--- a/devtools/client/application/src/components/service-workers/Worker.css
+++ b/devtools/client/application/src/components/service-workers/Worker.css
@@ -38,9 +38,37 @@
 
 .worker__link-start,
 .worker__link-debug {
   margin: 0 calc(var(--base-unit) * 2);
 }
 
 .worker__status {
   text-transform: capitalize;
+  --status-bg-color: transparent;
+  --status-border-color: transparent;
 }
+
+.worker__status::before {
+  content: "";
+  margin-inline-end: var(--base-unit);
+  width: calc(var(--base-unit) * 2);
+  height: calc(var(--base-unit) * 2);
+  display: inline-block;
+  background: var(--status-bg-color);
+  border: 1px solid var(--status-border-color);
+  border-radius: 100%;
+}
+
+.worker__status--active {
+  --status-bg-color: var(--green-60);
+  --status-border-color: var(--green-60);
+}
+
+.worker__status--waiting {
+  --status-bg-color: var(--theme-text-color-alt);
+  --status-border-color: var(--theme-text-color-alt);
+}
+
+.worker__status--installing, .worker__status--default {
+  --status-bg-color: transparent;
+  --status-border-color: var(--theme-text-color-alt);
+}
--- a/devtools/client/application/src/components/service-workers/Worker.js
+++ b/devtools/client/application/src/components/service-workers/Worker.js
@@ -1,14 +1,16 @@
 /* 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";
 
+const { Ci } = require("chrome");
+
 const {
   createFactory,
   PureComponent,
 } = require("devtools/client/shared/vendor/react");
 
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
 
 const {
@@ -80,30 +82,47 @@ class Worker extends PureComponent {
   }
 
   isRunning() {
     // We know the worker is running if it has a worker actor.
     return !!this.props.worker.workerTargetFront;
   }
 
   isActive() {
-    return this.props.worker.isActive;
+    return this.props.worker.state === Ci.nsIServiceWorkerInfo.STATE_ACTIVATED;
   }
 
   getLocalizedStatus() {
     if (this.isActive() && this.isRunning()) {
       return l10n.getString("serviceworker-worker-status-running");
     } else if (this.isActive()) {
       return l10n.getString("serviceworker-worker-status-stopped");
     }
     // NOTE: this is already localized by the service worker front
     // (strings are in debugger.properties)
     return this.props.worker.stateText;
   }
 
+  getClassNameForStatus(baseClass) {
+    const { state } = this.props.worker;
+
+    switch (state) {
+      case Ci.nsIServiceWorkerInfo.STATE_PARSED:
+      case Ci.nsIServiceWorkerInfo.STATE_INSTALLING:
+        return "worker__status--installing";
+      case Ci.nsIServiceWorkerInfo.STATE_INSTALLED:
+      case Ci.nsIServiceWorkerInfo.STATE_ACTIVATING:
+        return "worker__status--waiting";
+      case Ci.nsIServiceWorkerInfo.STATE_ACTIVATED:
+        return "worker__status--active";
+    }
+
+    return "worker__status--default";
+  }
+
   formatSource(source) {
     const parts = source.split("/");
     return getUnicodeUrlPath(parts[parts.length - 1]);
   }
 
   renderDebugButton() {
     const { isDebugEnabled } = this.props;
 
@@ -155,16 +174,17 @@ class Worker extends PureComponent {
         size: "micro",
       })
     );
   }
 
   render() {
     const { worker } = this.props;
     const statusText = this.getLocalizedStatus();
+    const statusClassName = this.getClassNameForStatus();
 
     return section(
       { className: "worker js-sw-worker" },
       dl(
         { className: "worker__data" },
         Localized(
           { id: "serviceworker-worker-source" },
           dt({ className: "worker__meta-name" })
@@ -182,17 +202,20 @@ class Worker extends PureComponent {
           this.renderDebugButton()
         ),
         Localized(
           { id: "serviceworker-worker-status" },
           dt({ className: "worker__meta-name" })
         ),
         dd(
           {},
-          span({ className: "js-worker-status worker__status" }, statusText),
+          span(
+            { className: `js-worker-status worker__status ${statusClassName}` },
+            statusText
+          ),
           " ",
           this.renderStartButton()
         )
       )
     );
   }
 }
 
--- a/devtools/client/application/src/reducers/workers-state.js
+++ b/devtools/client/application/src/reducers/workers-state.js
@@ -1,16 +1,14 @@
 /* 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";
 
-const { Ci } = require("chrome");
-
 const {
   UPDATE_CAN_DEBUG_WORKERS,
   UPDATE_WORKERS,
 } = require("devtools/client/application/src/constants");
 
 function WorkersState() {
   return {
     // Array of all service worker registrations
@@ -22,18 +20,18 @@ function WorkersState() {
 function buildWorkerDataFromFronts({ registration, workers }) {
   return {
     id: registration.id,
     lastUpdateTime: registration.lastUpdateTime,
     registrationFront: registration,
     scope: registration.scope,
     workers: workers.map(worker => ({
       id: worker.id,
-      isActive: worker.state === Ci.nsIServiceWorkerInfo.STATE_ACTIVATED,
       url: worker.url,
+      state: worker.state,
       stateText: worker.stateText,
       registrationFront: registration,
       workerTargetFront: worker.workerTargetFront,
     })),
   };
 }
 
 function workersReducer(state = WorkersState(), action) {
--- a/devtools/client/application/src/types/service-workers.js
+++ b/devtools/client/application/src/types/service-workers.js
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
 
 const worker = {
   id: PropTypes.string.isRequired,
-  isActive: PropTypes.bool.isRequired,
+  state: PropTypes.number.isRequired,
   stateText: PropTypes.string.isRequired,
   url: PropTypes.string.isRequired,
   workerTargetFront: PropTypes.object,
   registrationFront: PropTypes.object,
 };
 
 const workerArray = PropTypes.arrayOf(PropTypes.shape(worker));
 
--- a/devtools/client/application/test/node/components/service-workers/__snapshots__/components_application_panel-Registration.test.js.snap
+++ b/devtools/client/application/test/node/components/service-workers/__snapshots__/components_application_panel-Registration.test.js.snap
@@ -34,17 +34,16 @@ exports[`Registration Renders the expect
         className="registration__workers-item"
         key="id-worker-1-example"
       >
         <Worker
           isDebugEnabled={true}
           worker={
             Object {
               "id": "id-worker-1-example",
-              "isActive": true,
               "state": 4,
               "stateText": "activated",
               "url": "http://example.com/worker.js",
               "workerTargetFront": "",
             }
           }
         />
       </li>
@@ -87,17 +86,16 @@ exports[`Registration Renders the expect
         className="registration__workers-item"
         key="id-worker-1-example"
       >
         <Worker
           isDebugEnabled={true}
           worker={
             Object {
               "id": "id-worker-1-example",
-              "isActive": true,
               "state": 4,
               "stateText": "activated",
               "url": "http://example.com/worker.js",
               "workerTargetFront": "",
             }
           }
         />
       </li>
@@ -105,17 +103,16 @@ exports[`Registration Renders the expect
         className="registration__workers-item"
         key="id-worker-2-example"
       >
         <Worker
           isDebugEnabled={true}
           worker={
             Object {
               "id": "id-worker-2-example",
-              "isActive": false,
               "state": 2,
               "stateText": "installed",
               "url": "http://example.com/worker.js",
               "workerTargetFront": "",
             }
           }
         />
       </li>
@@ -158,17 +155,16 @@ exports[`Registration Renders the expect
         className="registration__workers-item"
         key="id-worker-1-example"
       >
         <Worker
           isDebugEnabled={false}
           worker={
             Object {
               "id": "id-worker-1-example",
-              "isActive": true,
               "state": 4,
               "stateText": "activated",
               "url": "http://example.com/worker.js",
               "workerTargetFront": "",
             }
           }
         />
       </li>
--- a/devtools/client/application/test/node/components/service-workers/__snapshots__/components_application_panel-RegistrationList.test.js.snap
+++ b/devtools/client/application/test/node/components/service-workers/__snapshots__/components_application_panel-RegistrationList.test.js.snap
@@ -23,17 +23,16 @@ Array [
         registration={
           Object {
             "id": "id-reg-1-example",
             "registrationFront": "",
             "scope": "SCOPE 123",
             "workers": Array [
               Object {
                 "id": "id-worker-1-example",
-                "isActive": true,
                 "state": 4,
                 "stateText": "activated",
                 "url": "http://example.com/worker.js",
                 "workerTargetFront": "",
               },
             ],
           }
         }
@@ -80,17 +79,16 @@ Array [
         registration={
           Object {
             "id": "id-reg-1-example",
             "registrationFront": "",
             "scope": "SCOPE1",
             "workers": Array [
               Object {
                 "id": "id-worker-1-example",
-                "isActive": true,
                 "state": 4,
                 "stateText": "activated",
                 "url": "http://example.com/worker.js",
                 "workerTargetFront": "",
               },
             ],
           }
         }
@@ -102,17 +100,16 @@ Array [
         registration={
           Object {
             "id": "id-reg-1-example",
             "registrationFront": "",
             "scope": "SCOPE2",
             "workers": Array [
               Object {
                 "id": "id-worker-2-example",
-                "isActive": false,
                 "state": 2,
                 "stateText": "installed",
                 "url": "http://example.com/worker.js",
                 "workerTargetFront": "",
               },
             ],
           }
         }
@@ -124,17 +121,16 @@ Array [
         registration={
           Object {
             "id": "id-reg-3-example",
             "registrationFront": "",
             "scope": "SCOPE3",
             "workers": Array [
               Object {
                 "id": "id-worker-3-example",
-                "isActive": true,
                 "state": 4,
                 "stateText": "activated",
                 "url": "http://example.com/worker.js",
                 "workerTargetFront": "",
               },
             ],
           }
         }
--- a/devtools/client/application/test/node/components/service-workers/__snapshots__/components_application_panel-Worker.test.js.snap
+++ b/devtools/client/application/test/node/components/service-workers/__snapshots__/components_application_panel-Worker.test.js.snap
@@ -42,17 +42,17 @@ exports[`Worker Renders the expected sna
       id="serviceworker-worker-status"
     >
       <dt
         className="worker__meta-name"
       />
     </Localized>
     <dd>
       <span
-        className="js-worker-status worker__status"
+        className="js-worker-status worker__status worker__status--waiting"
       >
         installed
       </span>
        
     </dd>
   </dl>
 </section>
 `;
@@ -99,17 +99,17 @@ exports[`Worker Renders the expected sna
       id="serviceworker-worker-status"
     >
       <dt
         className="worker__meta-name"
       />
     </Localized>
     <dd>
       <span
-        className="js-worker-status worker__status"
+        className="js-worker-status worker__status worker__status--active"
       >
         serviceworker-worker-status-running
       </span>
        
     </dd>
   </dl>
 </section>
 `;
@@ -156,17 +156,17 @@ exports[`Worker Renders the expected sna
       id="serviceworker-worker-status"
     >
       <dt
         className="worker__meta-name"
       />
     </Localized>
     <dd>
       <span
-        className="js-worker-status worker__status"
+        className="js-worker-status worker__status worker__status--active"
       >
         serviceworker-worker-status-stopped
       </span>
        
       <Localized
         attrs={
           Object {
             "title": true,
--- a/devtools/client/application/test/node/components/service-workers/__snapshots__/components_application_panel-WorkersPage.test.js.snap
+++ b/devtools/client/application/test/node/components/service-workers/__snapshots__/components_application_panel-WorkersPage.test.js.snap
@@ -10,32 +10,30 @@ exports[`WorkersPage filters out workers
       Array [
         Object {
           "id": "id-reg-1-example",
           "registrationFront": "",
           "scope": "SCOPE1",
           "workers": Array [
             Object {
               "id": "id-worker-1-example",
-              "isActive": true,
               "state": 4,
               "stateText": "activated",
               "url": "http://example.com/worker.js",
               "workerTargetFront": "",
             },
           ],
         },
         Object {
           "id": "id-reg-2-example",
           "registrationFront": "",
           "scope": "SCOPE2",
           "workers": Array [
             Object {
               "id": "id-worker-2-example",
-              "isActive": true,
               "state": 4,
               "stateText": "activated",
               "url": "http://example.com/worker.js",
               "workerTargetFront": "",
             },
           ],
         },
       ]
@@ -62,17 +60,16 @@ exports[`WorkersPage it renders a list w
       Array [
         Object {
           "id": "id-reg-1-example",
           "registrationFront": "",
           "scope": "SCOPE 123",
           "workers": Array [
             Object {
               "id": "id-worker-1-example",
-              "isActive": true,
               "state": 4,
               "stateText": "activated",
               "url": "http://example.com/worker.js",
               "workerTargetFront": "",
             },
           ],
         },
       ]
@@ -91,47 +88,44 @@ exports[`WorkersPage renders a list with
       Array [
         Object {
           "id": "id-reg-1-example",
           "registrationFront": "",
           "scope": "SCOPE1",
           "workers": Array [
             Object {
               "id": "id-worker-1-example",
-              "isActive": true,
               "state": 4,
               "stateText": "activated",
               "url": "http://example.com/worker.js",
               "workerTargetFront": "",
             },
           ],
         },
         Object {
           "id": "id-reg-1-example",
           "registrationFront": "",
           "scope": "SCOPE2",
           "workers": Array [
             Object {
               "id": "id-worker-2-example",
-              "isActive": false,
               "state": 2,
               "stateText": "installed",
               "url": "http://example.com/worker.js",
               "workerTargetFront": "",
             },
           ],
         },
         Object {
           "id": "id-reg-3-example",
           "registrationFront": "",
           "scope": "SCOPE3",
           "workers": Array [
             Object {
               "id": "id-worker-3-example",
-              "isActive": true,
               "state": 4,
               "stateText": "activated",
               "url": "http://example.com/worker.js",
               "workerTargetFront": "",
             },
           ],
         },
       ]
--- a/devtools/client/application/test/node/fixtures/Chrome.js
+++ b/devtools/client/application/test/node/fixtures/Chrome.js
@@ -1,11 +1,23 @@
 /* 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";
 
 module.exports = {
   Cc: {},
-  Ci: {},
+  Ci: {
+    // sw states from
+    // mozilla-central/source/dom/interfaces/base/nsIServiceWorkerManager.idl
+    nsIServiceWorkerInfo: {
+      STATE_PARSED: 0,
+      STATE_INSTALLING: 1,
+      STATE_INSTALLED: 2,
+      STATE_ACTIVATING: 3,
+      STATE_ACTIVATED: 4,
+      STATE_REDUNDANT: 5,
+      STATE_UNKNOWN: 6,
+    },
+  },
   Cu: {},
 };
--- a/devtools/client/application/test/node/fixtures/data/constants.js
+++ b/devtools/client/application/test/node/fixtures/data/constants.js
@@ -6,90 +6,83 @@
 
 // NOTE: worker state values are defined in an enum in nsIServiceWorkerManager
 // https://searchfox.org/mozilla-central/source/dom/interfaces/base/nsIServiceWorkerManager.idl
 
 const EMPTY_WORKER_LIST = [];
 
 const WORKER_RUNNING = {
   id: "id-worker-1-example",
-  isActive: true,
   workerTargetFront: true,
   url: "http://example.com/worker.js",
   state: 4,
   stateText: "activated",
 };
 
 const WORKER_STOPPED = {
   id: "id-worker-1-example",
-  isActive: true,
   workerTargetFront: false,
   url: "http://example.com/worker.js",
   state: 4,
   stateText: "activated",
 };
 
 const WORKER_WAITING = {
   id: "id-worker-1-example",
-  isActive: false,
   workerTargetFront: false,
   url: "http://example.com/worker.js",
   state: 2,
   stateText: "installed",
 };
 
 const REGISTRATION_SINGLE_WORKER = {
   id: "id-reg-1-example",
   scope: "SCOPE 123",
   registrationFront: "",
   workers: [
     {
       id: "id-worker-1-example",
-      isActive: true,
       workerTargetFront: "",
       url: "http://example.com/worker.js",
       state: 4,
       stateText: "activated",
     },
   ],
 };
 
 const REGISTRATION_MULTIPLE_WORKERS = {
   id: "id-reg-1-example",
   scope: "SCOPE 123",
   registrationFront: "",
   workers: [
     {
       id: "id-worker-1-example",
-      isActive: true,
       workerTargetFront: "",
       url: "http://example.com/worker.js",
       state: 4,
       stateText: "activated",
     },
     {
       id: "id-worker-2-example",
-      isActive: false,
       workerTargetFront: "",
       url: "http://example.com/worker.js",
       state: 2,
       stateText: "installed",
     },
   ],
 };
 
 const SINGLE_WORKER_DEFAULT_DOMAIN_LIST = [
   {
     id: "id-reg-1-example",
     scope: "SCOPE 123",
     registrationFront: "",
     workers: [
       {
         id: "id-worker-1-example",
-        isActive: true,
         workerTargetFront: "",
         url: "http://example.com/worker.js",
         state: 4,
         stateText: "activated",
       },
     ],
   },
 ];
@@ -97,17 +90,16 @@ const SINGLE_WORKER_DEFAULT_DOMAIN_LIST 
 const SINGLE_WORKER_DIFFERENT_DOMAIN_LIST = [
   {
     id: "id-reg-1-example",
     scope: "SCOPE 123",
     registrationFront: "",
     workers: [
       {
         id: "id-worker-1-example",
-        isActive: true,
         workerTargetFront: "",
         url: "http://different-example.com/worker.js",
         state: 4,
         stateText: "activated",
       },
     ],
   },
 ];
@@ -115,47 +107,44 @@ const SINGLE_WORKER_DIFFERENT_DOMAIN_LIS
 const MULTIPLE_WORKER_LIST = [
   {
     id: "id-reg-1-example",
     scope: "SCOPE1",
     registrationFront: "",
     workers: [
       {
         id: "id-worker-1-example",
-        isActive: true,
         workerTargetFront: "",
         url: "http://example.com/worker.js",
         state: 4,
         stateText: "activated",
       },
     ],
   },
   {
     id: "id-reg-1-example",
     scope: "SCOPE2",
     registrationFront: "",
     workers: [
       {
         id: "id-worker-2-example",
-        isActive: false,
         workerTargetFront: "",
         url: "http://example.com/worker.js",
         state: 2,
         stateText: "installed",
       },
     ],
   },
   {
     id: "id-reg-3-example",
     scope: "SCOPE3",
     registrationFront: "",
     workers: [
       {
         id: "id-worker-3-example",
-        isActive: true,
         workerTargetFront: "",
         url: "http://example.com/worker.js",
         state: 4,
         stateText: "activated",
       },
     ],
   },
 ];
@@ -163,47 +152,44 @@ const MULTIPLE_WORKER_LIST = [
 const MULTIPLE_WORKER_MIXED_DOMAINS_LIST = [
   {
     id: "id-reg-1-example",
     scope: "SCOPE1",
     registrationFront: "",
     workers: [
       {
         id: "id-worker-1-example",
-        isActive: true,
         workerTargetFront: "",
         url: "http://example.com/worker.js",
         state: 4,
         stateText: "activated",
       },
     ],
   },
   {
     id: "id-reg-2-example",
     scope: "SCOPE2",
     registrationFront: "",
     workers: [
       {
         id: "id-worker-2-example",
-        isActive: true,
         workerTargetFront: "",
         url: "http://example.com/worker.js",
         state: 4,
         stateText: "activated",
       },
     ],
   },
   {
     id: "id-reg-3-example",
     scope: "SCOPE3",
     registrationFront: "",
     workers: [
       {
         id: "id-worker-3-example",
-        isActive: true,
         workerTargetFront: "",
         url: "http://different-example.com/worker.js",
         state: 4,
         stateText: "activated",
       },
     ],
   },
 ];
--- a/devtools/client/application/test/xpcshell/test_workers_reducer.js
+++ b/devtools/client/application/test/xpcshell/test_workers_reducer.js
@@ -67,28 +67,28 @@ add_task(async function() {
     {
       id: "r1",
       lastUpdateTime: 42,
       registrationFront: rawData[0].registration,
       scope: "lorem-ipsum",
       workers: [
         {
           id: "w1",
-          isActive: true,
           url: "https://example.com/w1.js",
           workerTargetFront: rawData[0].workers[0].workerTargetFront,
           registrationFront: rawData[0].registration,
+          state: Ci.nsIServiceWorkerInfo.STATE_ACTIVATED,
           stateText: "activated",
         },
         {
           id: "w2",
-          isActive: false,
           url: "https://example.com/w2.js",
           workerTargetFront: undefined,
           registrationFront: rawData[0].registration,
+          state: Ci.nsIServiceWorkerInfo.STATE_INSTALLED,
           stateText: "installed",
         },
       ],
     },
   ];
 
   const action = updateWorkers(rawData);
   const newState = workersReducer(state, action);