summaryrefslogtreecommitdiff
path: root/data/extensions/spyblock@gnu.org/lib/notification.js
diff options
context:
space:
mode:
Diffstat (limited to 'data/extensions/spyblock@gnu.org/lib/notification.js')
-rw-r--r--data/extensions/spyblock@gnu.org/lib/notification.js475
1 files changed, 0 insertions, 475 deletions
diff --git a/data/extensions/spyblock@gnu.org/lib/notification.js b/data/extensions/spyblock@gnu.org/lib/notification.js
deleted file mode 100644
index 311e4e8..0000000
--- a/data/extensions/spyblock@gnu.org/lib/notification.js
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * This file is part of Adblock Plus <https://adblockplus.org/>,
- * Copyright (C) 2006-2017 eyeo GmbH
- *
- * Adblock Plus is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 3 as
- * published by the Free Software Foundation.
- *
- * Adblock Plus is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
- */
-
-"use strict";
-
-/**
- * @fileOverview Handles notifications.
- */
-
-const {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
-
-const {Prefs} = require("prefs");
-const {Downloader, Downloadable,
- MILLIS_IN_MINUTE, MILLIS_IN_HOUR, MILLIS_IN_DAY} = require("downloader");
-const {Utils} = require("utils");
-const {Matcher, defaultMatcher} = require("matcher");
-const {Filter, RegExpFilter, WhitelistFilter} = require("filterClasses");
-
-const INITIAL_DELAY = 1 * MILLIS_IN_MINUTE;
-const CHECK_INTERVAL = 1 * MILLIS_IN_HOUR;
-const EXPIRATION_INTERVAL = 1 * MILLIS_IN_DAY;
-const TYPE = {
- information: 0,
- question: 1,
- relentless: 2,
- critical: 3
-};
-
-let showListeners = [];
-let questionListeners = {};
-
-function getNumericalSeverity(notification)
-{
- if (notification.type in TYPE)
- return TYPE[notification.type];
- return TYPE.information;
-}
-
-function saveNotificationData()
-{
- // HACK: JSON values aren't saved unless they are assigned a different object.
- Prefs.notificationdata = JSON.parse(JSON.stringify(Prefs.notificationdata));
-}
-
-function localize(translations, locale)
-{
- if (locale in translations)
- return translations[locale];
-
- let languagePart = locale.substring(0, locale.indexOf("-"));
- if (languagePart && languagePart in translations)
- return translations[languagePart];
-
- let defaultLocale = "en-US";
- return translations[defaultLocale];
-}
-
-/**
- * The object providing actual downloading functionality.
- * @type {Downloader}
- */
-let downloader = null;
-let localData = [];
-
-/**
- * Regularly fetches notifications and decides which to show.
- * @class
- */
-let Notification = exports.Notification =
-{
- /**
- * Called on module startup.
- */
- init()
- {
- downloader = new Downloader(this._getDownloadables.bind(this),
- INITIAL_DELAY, CHECK_INTERVAL);
- downloader.onExpirationChange = this._onExpirationChange.bind(this);
- downloader.onDownloadSuccess = this._onDownloadSuccess.bind(this);
- downloader.onDownloadError = this._onDownloadError.bind(this);
- onShutdown.add(() => downloader.cancel());
- },
-
- /**
- * Yields a Downloadable instances for the notifications download.
- */
- *_getDownloadables()
- {
- let downloadable = new Downloadable(Prefs.notificationurl);
- if (typeof Prefs.notificationdata.lastError === "number")
- downloadable.lastError = Prefs.notificationdata.lastError;
- if (typeof Prefs.notificationdata.lastCheck === "number")
- downloadable.lastCheck = Prefs.notificationdata.lastCheck;
- if (typeof Prefs.notificationdata.data === "object" &&
- "version" in Prefs.notificationdata.data)
- {
- downloadable.lastVersion = Prefs.notificationdata.data.version;
- }
- if (typeof Prefs.notificationdata.softExpiration === "number")
- downloadable.softExpiration = Prefs.notificationdata.softExpiration;
- if (typeof Prefs.notificationdata.hardExpiration === "number")
- downloadable.hardExpiration = Prefs.notificationdata.hardExpiration;
- if (typeof Prefs.notificationdata.downloadCount === "number")
- downloadable.downloadCount = Prefs.notificationdata.downloadCount;
- yield downloadable;
- },
-
- _onExpirationChange(downloadable)
- {
- Prefs.notificationdata.lastCheck = downloadable.lastCheck;
- Prefs.notificationdata.softExpiration = downloadable.softExpiration;
- Prefs.notificationdata.hardExpiration = downloadable.hardExpiration;
- saveNotificationData();
- },
-
- _onDownloadSuccess(downloadable, responseText, errorCallback,
- redirectCallback)
- {
- try
- {
- let data = JSON.parse(responseText);
- for (let notification of data.notifications)
- {
- if ("severity" in notification)
- {
- if (!("type" in notification))
- notification.type = notification.severity;
- delete notification.severity;
- }
- }
- Prefs.notificationdata.data = data;
- }
- catch (e)
- {
- Cu.reportError(e);
- errorCallback("synchronize_invalid_data");
- return;
- }
-
- Prefs.notificationdata.lastError = 0;
- Prefs.notificationdata.downloadStatus = "synchronize_ok";
- [
- Prefs.notificationdata.softExpiration,
- Prefs.notificationdata.hardExpiration
- ] = downloader.processExpirationInterval(EXPIRATION_INTERVAL);
- Prefs.notificationdata.downloadCount = downloadable.downloadCount;
- saveNotificationData();
-
- Notification.showNext();
- },
-
- _onDownloadError(downloadable, downloadURL, error, channelStatus,
- responseStatus, redirectCallback)
- {
- Prefs.notificationdata.lastError = Date.now();
- Prefs.notificationdata.downloadStatus = error;
- saveNotificationData();
- },
-
- /**
- * Adds a listener for notifications to be shown.
- * @param {Function} listener Listener to be invoked when a notification is
- * to be shown
- */
- addShowListener(listener)
- {
- if (showListeners.indexOf(listener) == -1)
- showListeners.push(listener);
- },
-
- /**
- * Removes the supplied listener.
- * @param {Function} listener Listener that was added via addShowListener()
- */
- removeShowListener(listener)
- {
- let index = showListeners.indexOf(listener);
- if (index != -1)
- showListeners.splice(index, 1);
- },
-
- /**
- * Determines which notification is to be shown next.
- * @param {string} url URL to match notifications to (optional)
- * @return {Object} notification to be shown, or null if there is none
- */
- _getNextToShow(url)
- {
- function checkTarget(target, parameter, name, version)
- {
- let minVersionKey = parameter + "MinVersion";
- let maxVersionKey = parameter + "MaxVersion";
- return !((parameter in target && target[parameter] != name) ||
- (minVersionKey in target &&
- Services.vc.compare(version, target[minVersionKey]) < 0) ||
- (maxVersionKey in target &&
- Services.vc.compare(version, target[maxVersionKey]) > 0));
- }
-
- let remoteData = [];
- if (typeof Prefs.notificationdata.data == "object" &&
- Prefs.notificationdata.data.notifications instanceof Array)
- {
- remoteData = Prefs.notificationdata.data.notifications;
- }
-
- let notifications = localData.concat(remoteData);
- if (notifications.length === 0)
- return null;
-
- const {addonName, addonVersion, application,
- applicationVersion, platform, platformVersion} = require("info");
- let notificationToShow = null;
- for (let notification of notifications)
- {
- if (typeof notification.type === "undefined" ||
- notification.type !== "critical")
- {
- let shown;
- if (typeof Prefs.notificationdata.shown == "object")
- shown = Prefs.notificationdata.shown[notification.id];
-
- if (typeof shown != "undefined")
- {
- if (typeof notification.interval == "number")
- {
- if (shown + notification.interval > Date.now())
- continue;
- }
- else if (shown)
- continue;
- }
-
- if (notification.type !== "relentless" &&
- Prefs.notifications_ignoredcategories.indexOf("*") != -1)
- {
- continue;
- }
- }
-
- if (typeof url === "string" || notification.urlFilters instanceof Array)
- {
- if (Prefs.enabled && typeof url === "string" &&
- notification.urlFilters instanceof Array)
- {
- let host;
- try
- {
- host = new URL(url).hostname;
- }
- catch (e)
- {
- host = "";
- }
-
- let exception = defaultMatcher.matchesAny(
- url, RegExpFilter.typeMap.DOCUMENT, host, false, null
- );
- if (exception instanceof WhitelistFilter)
- continue;
-
- let matcher = new Matcher();
- for (let urlFilter of notification.urlFilters)
- matcher.add(Filter.fromText(urlFilter));
- if (!matcher.matchesAny(url, RegExpFilter.typeMap.DOCUMENT, host,
- false, null))
- {
- continue;
- }
- }
- else
- continue;
- }
-
- if (notification.targets instanceof Array)
- {
- let match = false;
- for (let target of notification.targets)
- {
- if (checkTarget(target, "extension", addonName, addonVersion) &&
- checkTarget(target, "application", application,
- applicationVersion) &&
- checkTarget(target, "platform", platform, platformVersion))
- {
- match = true;
- break;
- }
- }
- if (!match)
- continue;
- }
-
- if (!notificationToShow ||
- getNumericalSeverity(notification) >
- getNumericalSeverity(notificationToShow))
- notificationToShow = notification;
- }
-
- return notificationToShow;
- },
-
- /**
- * Invokes the listeners added via addShowListener() with the next
- * notification to be shown.
- * @param {string} url URL to match notifications to (optional)
- */
- showNext(url)
- {
- let notification = Notification._getNextToShow(url);
- if (notification)
- {
- for (let showListener of showListeners)
- showListener(notification);
- }
- },
-
- /**
- * Marks a notification as shown.
- * @param {string} id ID of the notification to be marked as shown
- */
- markAsShown(id)
- {
- let now = Date.now();
- let data = Prefs.notificationdata;
-
- if (data.shown instanceof Array)
- {
- let newShown = {};
- for (let oldId of data.shown)
- newShown[oldId] = now;
- data.shown = newShown;
- }
-
- if (typeof data.shown != "object")
- data.shown = {};
-
- data.shown[id] = now;
-
- saveNotificationData();
- },
-
- /**
- * Localizes the texts of the supplied notification.
- * @param {Object} notification notification to translate
- * @param {string} locale the target locale (optional, defaults to the
- * application locale)
- * @return {Object} the translated texts
- */
- getLocalizedTexts(notification, locale)
- {
- locale = locale || Utils.appLocale;
- let textKeys = ["title", "message"];
- let localizedTexts = [];
- for (let key of textKeys)
- {
- if (key in notification)
- {
- if (typeof notification[key] == "string")
- localizedTexts[key] = notification[key];
- else
- localizedTexts[key] = localize(notification[key], locale);
- }
- }
- return localizedTexts;
- },
-
- /**
- * Adds a local notification.
- * @param {Object} notification notification to add
- */
- addNotification(notification)
- {
- if (localData.indexOf(notification) == -1)
- localData.push(notification);
- },
-
- /**
- * Removes an existing local notification.
- * @param {Object} notification notification to remove
- */
- removeNotification(notification)
- {
- let index = localData.indexOf(notification);
- if (index > -1)
- localData.splice(index, 1);
- },
-
- /**
- * A callback function which listens to see if notifications were approved.
- *
- * @callback QuestionListener
- * @param {boolean} approved
- */
-
- /**
- * Adds a listener for question-type notifications
- * @param {string} id
- * @param {QuestionListener} listener
- */
- addQuestionListener(id, listener)
- {
- if (!(id in questionListeners))
- questionListeners[id] = [];
- if (questionListeners[id].indexOf(listener) === -1)
- questionListeners[id].push(listener);
- },
-
- /**
- * Removes a listener that was previously added via addQuestionListener
- * @param {string} id
- * @param {QuestionListener} listener
- */
- removeQuestionListener(id, listener)
- {
- if (!(id in questionListeners))
- return;
- let index = questionListeners[id].indexOf(listener);
- if (index > -1)
- questionListeners[id].splice(index, 1);
- if (questionListeners[id].length === 0)
- delete questionListeners[id];
- },
-
- /**
- * Notifies question listeners about interactions with a notification
- * @param {string} id notification ID
- * @param {boolean} approved indicator whether notification has been approved
- */
- triggerQuestionListeners(id, approved)
- {
- if (!(id in questionListeners))
- return;
- let listeners = questionListeners[id];
- for (let listener of listeners)
- listener(approved);
- },
-
- /**
- * Toggles whether notifications of a specific category should be ignored
- * @param {string} category notification category identifier
- * @param {boolean} [forceValue] force specified value
- */
- toggleIgnoreCategory(category, forceValue)
- {
- let categories = Prefs.notifications_ignoredcategories;
- let index = categories.indexOf(category);
- if (index == -1 && forceValue !== false)
- {
- categories.push(category);
- Prefs.notifications_showui = true;
- }
- else if (index != -1 && forceValue !== true)
- categories.splice(index, 1);
-
- // HACK: JSON values aren't saved unless they are assigned a
- // different object.
- Prefs.notifications_ignoredcategories =
- JSON.parse(JSON.stringify(categories));
- }
-};
-Notification.init();