summaryrefslogtreecommitdiffstats
path: root/devtools/server/actors/worker/service-worker-registration-list.js
blob: 6093edc97e757ffad9578823301d76d5d9d208ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/* 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 { XPCOMUtils } = ChromeUtils.importESModule(
  "resource://gre/modules/XPCOMUtils.sys.mjs",
  { global: "contextual" }
);
loader.lazyRequireGetter(
  this,
  "ServiceWorkerRegistrationActor",
  "resource://devtools/server/actors/worker/service-worker-registration.js",
  true
);

XPCOMUtils.defineLazyServiceGetter(
  this,
  "swm",
  "@mozilla.org/serviceworkers/manager;1",
  "nsIServiceWorkerManager"
);

class ServiceWorkerRegistrationActorList {
  constructor(conn) {
    this._conn = conn;
    this._actors = new Map();
    this._onListChanged = null;
    this._mustNotify = false;
    this.onRegister = this.onRegister.bind(this);
    this.onUnregister = this.onUnregister.bind(this);
  }

  getList() {
    // Create a set of registrations.
    const registrations = new Set();
    const array = swm.getAllRegistrations();
    for (let index = 0; index < array.length; ++index) {
      registrations.add(
        array.queryElementAt(index, Ci.nsIServiceWorkerRegistrationInfo)
      );
    }

    // Delete each actor for which we don't have a registration.
    for (const [registration] of this._actors) {
      if (!registrations.has(registration)) {
        this._actors.delete(registration);
      }
    }

    // Create an actor for each registration for which we don't have one.
    for (const registration of registrations) {
      if (!this._actors.has(registration)) {
        this._actors.set(
          registration,
          new ServiceWorkerRegistrationActor(this._conn, registration)
        );
      }
    }

    if (!this._mustNotify) {
      if (this._onListChanged !== null) {
        swm.addListener(this);
      }
      this._mustNotify = true;
    }

    const actors = [];
    for (const [, actor] of this._actors) {
      actors.push(actor);
    }

    return Promise.resolve(actors);
  }

  get onListchanged() {
    return this._onListchanged;
  }

  set onListChanged(onListChanged) {
    if (typeof onListChanged !== "function" && onListChanged !== null) {
      throw new Error("onListChanged must be either a function or null.");
    }

    if (this._mustNotify) {
      if (this._onListChanged === null && onListChanged !== null) {
        swm.addListener(this);
      }
      if (this._onListChanged !== null && onListChanged === null) {
        swm.removeListener(this);
      }
    }
    this._onListChanged = onListChanged;
  }

  _notifyListChanged() {
    this._onListChanged();

    if (this._onListChanged !== null) {
      swm.removeListener(this);
    }
    this._mustNotify = false;
  }

  onRegister() {
    this._notifyListChanged();
  }

  onUnregister() {
    this._notifyListChanged();
  }
}

exports.ServiceWorkerRegistrationActorList = ServiceWorkerRegistrationActorList;