| Index: lib/notification.js |
| =================================================================== |
| --- a/lib/notification.js |
| +++ b/lib/notification.js |
| @@ -38,6 +38,7 @@ |
| relentless: 2, |
| critical: 3 |
| }; |
| +const MATCHER = Symbol("Notification matcher"); |
| let showListeners = []; |
| let questionListeners = {}; |
| @@ -103,10 +104,76 @@ |
| } |
| /** |
| + * Initializes notification's matcher based on notification's URL filters |
| + * @param {Object} notification |
| + */ |
| +function initNotificationMatcher(notification) |
| +{ |
| + if (MATCHER in notification || !(notification.urlFilters instanceof Array)) |
| + return; |
| + |
| + let matcher = new Matcher(); |
| + for (let urlFilter of notification.urlFilters) |
| + { |
| + matcher.add(Filter.fromText(urlFilter)); |
| + } |
| + notification[MATCHER] = matcher; |
| +} |
| + |
| +/** |
| + * Matches URL against notification's URL filters |
| + * @param {Object} notification |
| + * @param {string} [url] |
| + * @return {boolean} whether notification and URL match |
| + */ |
| +function matchesUrl(notification, url) |
| +{ |
| + // No matching necessary if there's nothing to match |
| + if (typeof url !== "string" && !(MATCHER in notification)) |
| + return true; |
| + |
| + // Notification shouldn't match if extension is disabled |
| + if (!Prefs.enabled) |
| + return false; |
| + |
| + // Notification shouldn't match if matching cannot be done |
| + if (typeof url !== "string" || !(MATCHER in notification)) |
| + return false; |
|
sergei
2018/01/30 17:25:05
It somehow conflicts with above
if (typeof url !==
Thomas Greiner
2018/01/30 19:17:53
The logic behind it is that if the notification do
sergei
2018/01/30 21:06:48
Acknowledged.
|
| + |
| + let host; |
| + try |
| + { |
| + host = new URL(url).hostname; |
| + } |
| + catch (e) |
| + { |
| + host = ""; |
| + } |
| + |
| + // Notification shouldn't match if extension is disabled on provided domain |
| + let exception = defaultMatcher.matchesAny( |
| + url, RegExpFilter.typeMap.DOCUMENT, host, false, null |
| + ); |
| + if (exception instanceof WhitelistFilter) |
| + return false; |
| + |
| + // Notification should match if one of its filters matches |
| + let filter = notification[MATCHER].matchesAny( |
| + url, RegExpFilter.typeMap.DOCUMENT, host, false, null |
| + ); |
| + return !!filter; |
| +} |
| + |
| +/** |
| * The object providing actual downloading functionality. |
| * @type {Downloader} |
| */ |
| let downloader = null; |
| + |
| +/** |
| + * List of notifications provided by the extension |
| + * @type {Object[]} |
| + */ |
| let localData = []; |
| /** |
| @@ -120,6 +187,15 @@ |
| */ |
| init() |
| { |
| + let {data} = Prefs.notificationdata; |
|
sergei
2018/01/30 17:25:05
Prefs' properties can be not ready yet, I would re
sergei
2018/01/30 17:28:24
Perhaps alternatively we could do it in `matchesUr
Thomas Greiner
2018/01/30 19:17:53
In theory that's correct but in practice this is n
sergei
2018/01/30 21:06:48
It does happen on practice (at least I observed th
kzar
2018/01/31 11:06:27
How about using the Prefs.untilLoaded Promise?
sergei
2018/02/05 12:49:34
It seems the best option.
|
| + if (data) |
| + { |
| + for (let notification of data.notifications) |
| + { |
| + initNotificationMatcher(notification); |
| + } |
| + } |
| + |
| downloader = new Downloader(this._getDownloadables.bind(this), |
| INITIAL_DELAY, CHECK_INTERVAL); |
| downloader.onExpirationChange = this._onExpirationChange.bind(this); |
| @@ -174,6 +250,7 @@ |
| notification.type = notification.severity; |
| delete notification.severity; |
| } |
| + initNotificationMatcher(notification); |
| } |
| Prefs.notificationdata.data = data; |
| } |
| @@ -239,7 +316,6 @@ |
| { |
| remoteData = Prefs.notificationdata.data.notifications; |
| } |
| - |
| let notifications = localData.concat(remoteData); |
| if (notifications.length === 0) |
| return null; |
| @@ -298,39 +374,8 @@ |
| } |
| } |
| - 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 (!matchesUrl(notification, url)) |
| + continue; |
| if (notification.targets instanceof Array) |
| { |
| @@ -433,7 +478,10 @@ |
| addNotification(notification) |
| { |
| if (localData.indexOf(notification) == -1) |
| + { |
| + initNotificationMatcher(notification); |
| localData.push(notification); |
| + } |
| }, |
| /** |