summaryrefslogtreecommitdiffstats
path: root/dom/push/test/lifetime_worker.js
blob: 251a4a2beed570362f5601fa01f239f1b11bd301 (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
var state = "from_scope";
var resolvePromiseCallback;

self.onfetch = function (event) {
  if (event.request.url.includes("lifetime_frame.html")) {
    event.respondWith(new Response("iframe_lifetime"));
    return;
  }

  var currentState = state;
  event.waitUntil(
    self.clients.matchAll().then(clients => {
      clients.forEach(client => {
        client.postMessage({ type: "fetch", state: currentState });
      });
    })
  );

  if (event.request.url.includes("update")) {
    state = "update";
  } else if (event.request.url.includes("wait")) {
    event.respondWith(
      new Promise(function (res) {
        if (resolvePromiseCallback) {
          dump("ERROR: service worker was already waiting on a promise.\n");
        }
        resolvePromiseCallback = function () {
          res(new Response("resolve_respondWithPromise"));
        };
      })
    );
    state = "wait";
  } else if (event.request.url.includes("release")) {
    state = "release";
    resolvePromise();
  }
};

function resolvePromise() {
  if (resolvePromiseCallback === undefined || resolvePromiseCallback == null) {
    dump("ERROR: wait promise was not set.\n");
    return;
  }
  resolvePromiseCallback();
  resolvePromiseCallback = null;
}

self.onmessage = function (event) {
  var lastState = state;
  state = event.data;
  if (state === "wait") {
    event.waitUntil(
      new Promise(function (res) {
        if (resolvePromiseCallback) {
          dump("ERROR: service worker was already waiting on a promise.\n");
        }
        resolvePromiseCallback = res;
      })
    );
  } else if (state === "release") {
    resolvePromise();
  }
  event.source.postMessage({ type: "message", state: lastState });
};

self.onpush = function (event) {
  var pushResolve;
  event.waitUntil(
    new Promise(function (resolve) {
      pushResolve = resolve;
    })
  );

  // FIXME(catalinb): push message carry no data. So we assume the only
  // push message we get is "wait"
  self.clients.matchAll().then(function (client) {
    if (!client.length) {
      dump("ERROR: no clients to send the response to.\n");
    }

    client[0].postMessage({ type: "push", state });

    state = "wait";
    if (resolvePromiseCallback) {
      dump("ERROR: service worker was already waiting on a promise.\n");
    } else {
      resolvePromiseCallback = pushResolve;
    }
  });
};