File: implementation.js

package info (click to toggle)
xnote 4.6.51-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 960 kB
  • sloc: javascript: 7,147; makefile: 22; sh: 9
file content (135 lines) | stat: -rw-r--r-- 4,924 bytes parent folder | download | duplicates (2)
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * This file is provided by the addon-developer-support repository at
 * https://github.com/thundernest/addon-developer-support
 *
 * Version 1.1
 *  - added startup event, to make sure API is ready as soon as the add-on is starting
 *    NOTE: This requires to add the startup event to the manifest, see:
 *    https://github.com/thundernest/addon-developer-support/tree/master/auxiliary-apis/NotifyTools#usage
 *
 * Author: John Bieling (john@thunderbird.net)
 *
 * 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/.
 */

// Get various parts of the WebExtension framework that we need.
var { ExtensionCommon } = ChromeUtils.import ?  ChromeUtils.import("resource://gre/modules/ExtensionCommon.jsm")
:   ChromeUtils.importESModule(
  "resource://gre/modules/ExtensionCommon.sys.mjs"
);
var { ExtensionSupport } = ChromeUtils.import ?  ChromeUtils.import("resource:///modules/ExtensionSupport.jsm")
:   ChromeUtils.importESModule(
  "resource:///modules/ExtensionSupport.sys.mjs"
);
//var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
//var Services = globalThis.Services || ChromeUtils.import("resource://gre/modules/Services.jsm").Services;

var NotifyTools = class extends ExtensionCommon.ExtensionAPI {
  getAPI(context) {
    var self = this;

    this.onNotifyBackgroundObserver = {
      observe: async function (aSubject, aTopic, aData) {
        if (
          Object.keys(self.observerTracker).length > 0 &&
          aData == self.extension.id
        ) {
          let payload = aSubject.wrappedJSObject;

          // Make sure payload has a resolve function, which we use to resolve the
          // observer notification.
          if (payload.resolve) {
            let observerTrackerPromises = [];
            // Push listener into promise array, so they can run in parallel
            for (let listener of Object.values(self.observerTracker)) {
              observerTrackerPromises.push(listener(payload.data));
            }
            // We still have to await all of them but wait time is just the time needed
            // for the slowest one.
            let results = [];
            for (let observerTrackerPromise of observerTrackerPromises) {
              let rv = await observerTrackerPromise;
              if (rv != null) results.push(rv);
            }
            if (results.length == 0) {
              payload.resolve();
            } else {
              if (results.length > 1) {
                console.warn(
                  "Received multiple results from onNotifyBackground listeners. Using the first one, which can lead to inconsistent behavior.",
                  results
                );
              }
              payload.resolve(results[0]);
            }
          } else {
            // Older version of NotifyTools, which is not sending a resolve function, deprecated.
            console.log("Please update the notifyTools API and the notifyTools script to at least v1.5");
            for (let listener of Object.values(self.observerTracker)) {
              listener(payload.data);
            }
          }
        }
      },
    };

    this.observerTracker = {};
    this.observerTrackerNext = 1;
    // Add observer for notifyTools.js
    Services.obs.addObserver(
      this.onNotifyBackgroundObserver,
      "NotifyBackgroundObserver",
      false
    );

    return {
      NotifyTools: {

        notifyExperiment(data) {
          return new Promise(resolve => {
            Services.obs.notifyObservers(
              { data, resolve },
              "NotifyExperimentObserver",
              self.extension.id
            );
          });
        },

        onNotifyBackground: new ExtensionCommon.EventManager({
          context,
          name: "NotifyTools.onNotifyBackground",
          register: (fire) => {
            let trackerId = self.observerTrackerNext++;
            self.observerTracker[trackerId] = fire.sync;
            return () => {
              delete self.observerTracker[trackerId];
            };
          },
        }).api(),

      }
    };
  }

  // Force API to run at startup, otherwise event listeners might not be added at the requested time. Also needs
  // "events": ["startup"] in the experiment manifest

  onStartup() { }

  onShutdown(isAppShutdown) {
    if (isAppShutdown) {
      return; // the application gets unloaded anyway
    }

    // Remove observer for notifyTools.js
    Services.obs.removeObserver(
      this.onNotifyBackgroundObserver,
      "NotifyBackgroundObserver"
    );

    // Flush all caches
    Services.obs.notifyObservers(null, "startupcache-invalidate");
  }
};