158 lines
3.7 KiB
JavaScript
158 lines
3.7 KiB
JavaScript
/* 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";
|
|
|
|
// Manages an alarm created by the extension (alarms API).
|
|
class Alarm {
|
|
constructor(api, name, alarmInfo) {
|
|
this.api = api;
|
|
this.name = name;
|
|
this.when = alarmInfo.when;
|
|
this.delayInMinutes = alarmInfo.delayInMinutes;
|
|
this.periodInMinutes = alarmInfo.periodInMinutes;
|
|
this.canceled = false;
|
|
|
|
let delay, scheduledTime;
|
|
if (this.when) {
|
|
scheduledTime = this.when;
|
|
delay = this.when - Date.now();
|
|
} else {
|
|
if (!this.delayInMinutes) {
|
|
this.delayInMinutes = this.periodInMinutes;
|
|
}
|
|
delay = this.delayInMinutes * 60 * 1000;
|
|
scheduledTime = Date.now() + delay;
|
|
}
|
|
|
|
this.scheduledTime = scheduledTime;
|
|
|
|
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
|
delay = delay > 0 ? delay : 0;
|
|
timer.init(this, delay, Ci.nsITimer.TYPE_ONE_SHOT);
|
|
this.timer = timer;
|
|
}
|
|
|
|
clear() {
|
|
this.timer.cancel();
|
|
this.api.alarms.delete(this.name);
|
|
this.canceled = true;
|
|
}
|
|
|
|
observe() {
|
|
if (this.canceled) {
|
|
return;
|
|
}
|
|
|
|
for (let callback of this.api.callbacks) {
|
|
callback(this);
|
|
}
|
|
|
|
if (!this.periodInMinutes) {
|
|
this.clear();
|
|
return;
|
|
}
|
|
|
|
let delay = this.periodInMinutes * 60 * 1000;
|
|
this.scheduledTime = Date.now() + delay;
|
|
this.timer.init(this, delay, Ci.nsITimer.TYPE_ONE_SHOT);
|
|
}
|
|
|
|
get data() {
|
|
return {
|
|
name: this.name,
|
|
scheduledTime: this.scheduledTime,
|
|
periodInMinutes: this.periodInMinutes,
|
|
};
|
|
}
|
|
}
|
|
|
|
this.alarms = class extends ExtensionAPIPersistent {
|
|
constructor(extension) {
|
|
super(extension);
|
|
|
|
this.alarms = new Map();
|
|
this.callbacks = new Set();
|
|
}
|
|
|
|
onShutdown() {
|
|
for (let alarm of this.alarms.values()) {
|
|
alarm.clear();
|
|
}
|
|
}
|
|
|
|
PERSISTENT_EVENTS = {
|
|
onAlarm({ fire }) {
|
|
let callback = alarm => {
|
|
fire.sync(alarm.data);
|
|
};
|
|
|
|
this.callbacks.add(callback);
|
|
|
|
return {
|
|
unregister: () => {
|
|
this.callbacks.delete(callback);
|
|
},
|
|
convert(_fire) {
|
|
fire = _fire;
|
|
},
|
|
};
|
|
},
|
|
};
|
|
|
|
getAPI(context) {
|
|
const self = this;
|
|
|
|
return {
|
|
alarms: {
|
|
create: function (name, alarmInfo) {
|
|
name = name || "";
|
|
if (self.alarms.has(name)) {
|
|
self.alarms.get(name).clear();
|
|
}
|
|
let alarm = new Alarm(self, name, alarmInfo);
|
|
self.alarms.set(alarm.name, alarm);
|
|
},
|
|
|
|
get: function (name) {
|
|
name = name || "";
|
|
if (self.alarms.has(name)) {
|
|
return Promise.resolve(self.alarms.get(name).data);
|
|
}
|
|
return Promise.resolve();
|
|
},
|
|
|
|
getAll: function () {
|
|
let result = Array.from(self.alarms.values(), alarm => alarm.data);
|
|
return Promise.resolve(result);
|
|
},
|
|
|
|
clear: function (name) {
|
|
name = name || "";
|
|
if (self.alarms.has(name)) {
|
|
self.alarms.get(name).clear();
|
|
return Promise.resolve(true);
|
|
}
|
|
return Promise.resolve(false);
|
|
},
|
|
|
|
clearAll: function () {
|
|
let cleared = false;
|
|
for (let alarm of self.alarms.values()) {
|
|
alarm.clear();
|
|
cleared = true;
|
|
}
|
|
return Promise.resolve(cleared);
|
|
},
|
|
|
|
onAlarm: new EventManager({
|
|
context,
|
|
module: "alarms",
|
|
event: "onAlarm",
|
|
extensionApi: self,
|
|
}).api(),
|
|
},
|
|
};
|
|
}
|
|
};
|