Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: lib/notification.js

Issue 5330039625220096: Issue 1162 - Cache notification URL matcher
Patch Set: Fixed regression: Error if notification data not yet initialized Created Jan. 29, 2018, 3:36 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
+ }
},
/**
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld