Index: lib/filterStorage.js |
=================================================================== |
--- a/lib/filterStorage.js |
+++ b/lib/filterStorage.js |
@@ -163,16 +163,18 @@ |
{ |
if (this.knownSubscriptions.has(subscription.url)) |
return; |
this.knownSubscriptions.set(subscription.url, subscription); |
connectSubscriptionFilters(subscription); |
filterNotifier.emit("subscription.added", subscription); |
+ |
+ subscription.clearCaches(); |
} |
/** |
* Removes a subscription from the storage. |
* @param {Subscription} subscription The subscription to be removed. |
*/ |
removeSubscription(subscription) |
{ |
@@ -192,21 +194,28 @@ |
/** |
* Replaces the list of filters in a subscription with a new list. |
* @param {Subscription} subscription The subscription to be updated. |
* @param {Array.<Filter>} filters The new list of filters. |
*/ |
updateSubscriptionFilters(subscription, filters) |
{ |
- disconnectSubscriptionFilters(subscription); |
- let oldFilters = subscription.filters; |
- subscription.filters = filters; |
- connectSubscriptionFilters(subscription); |
+ let oldFilters = [...subscription.filters()]; |
+ disconnectSubscriptionFilters(subscription, oldFilters); |
+ subscription.clearFilters(); |
+ |
+ for (let filter of filters) |
+ subscription.addFilter(filter); |
+ |
+ connectSubscriptionFilters(subscription, filters); |
+ |
filterNotifier.emit("subscription.updated", subscription, oldFilters); |
+ |
+ subscription.clearCaches(); |
} |
/** |
* Adds a user-defined filter to the storage. |
* @param {Filter} filter |
* @param {?SpecialSubscription} [subscription] The subscription that the |
* filter should be added to. |
* @param {number} [position] The position within the subscription at which |
@@ -231,20 +240,20 @@ |
{ |
// No group for this filter exists, create one |
subscription = SpecialSubscription.createForFilter(filter); |
this.addSubscription(subscription); |
return; |
} |
if (typeof position == "undefined") |
- position = subscription.filters.length; |
+ position = subscription.filterCount; |
filter.addSubscription(subscription); |
- subscription.filters.splice(position, 0, filter); |
+ subscription.insertFilterAt(filter, position); |
filterNotifier.emit("filter.added", filter, subscription, position); |
} |
/** |
* Removes a user-defined filter from the storage. |
* @param {Filter} filter |
* @param {?SpecialSubscription} [subscription] The subscription that the |
* filter should be removed from. If not specified, the filter will be |
@@ -263,31 +272,32 @@ |
if (currentSubscription instanceof SpecialSubscription) |
{ |
let positions = []; |
if (typeof position == "undefined") |
{ |
let index = -1; |
do |
{ |
- index = currentSubscription.filters.indexOf(filter, index + 1); |
+ index = currentSubscription.searchFilter(filter, index + 1); |
if (index >= 0) |
positions.push(index); |
} while (index >= 0); |
} |
else |
positions.push(position); |
for (let j = positions.length - 1; j >= 0; j--) |
{ |
let currentPosition = positions[j]; |
- if (currentSubscription.filters[currentPosition] == filter) |
+ let currentFilter = currentSubscription.filterAt(currentPosition); |
+ if (currentFilter && currentFilter.text == filter.text) |
{ |
- currentSubscription.filters.splice(currentPosition, 1); |
- if (currentSubscription.filters.indexOf(filter) < 0) |
+ currentSubscription.deleteFilterAt(currentPosition); |
+ if (currentSubscription.searchFilter(filter) < 0) |
filter.removeSubscription(currentSubscription); |
filterNotifier.emit("filter.removed", filter, currentSubscription, |
currentPosition); |
} |
} |
} |
} |
} |
@@ -297,29 +307,30 @@ |
* @param {Filter} filter |
* @param {SpecialSubscription} subscription The subscription where the |
* filter is located. |
* @param {number} oldPosition The current position of the filter. |
* @param {number} newPosition The new position of the filter. |
*/ |
moveFilter(filter, subscription, oldPosition, newPosition) |
{ |
- if (!(subscription instanceof SpecialSubscription) || |
- subscription.filters[oldPosition] != filter) |
- { |
+ if (!(subscription instanceof SpecialSubscription)) |
return; |
- } |
+ |
+ let currentFilter = subscription.filterAt(oldPosition); |
+ if (!currentFilter || currentFilter.text != filter.text) |
+ return; |
newPosition = Math.min(Math.max(newPosition, 0), |
- subscription.filters.length - 1); |
+ subscription.filterCount - 1); |
if (oldPosition == newPosition) |
return; |
- subscription.filters.splice(oldPosition, 1); |
- subscription.filters.splice(newPosition, 0, filter); |
+ subscription.deleteFilterAt(oldPosition); |
+ subscription.insertFilterAt(filter, newPosition); |
filterNotifier.emit("filter.moved", filter, subscription, oldPosition, |
newPosition); |
} |
/** |
* Increases the hit count for a filter by one. |
* @param {Filter} filter |
*/ |
@@ -375,17 +386,23 @@ |
knownSubscriptions.set(subscription.url, subscription); |
this.fileProperties = parser.fileProperties; |
this.knownSubscriptions = knownSubscriptions; |
Filter.knownFilters = parser.knownFilters; |
Subscription.knownSubscriptions = parser.knownSubscriptions; |
if (!silent) |
+ { |
filterNotifier.emit("load"); |
+ |
+ // Clear any in-memory caches that may have been created during |
+ // initialization. |
+ clearSubscriptionCaches(); |
+ } |
} |
}; |
} |
/** |
* Loads all subscriptions from disk. |
* @returns {Promise} A promise resolved or rejected when loading is complete. |
*/ |
@@ -424,16 +441,17 @@ |
}).catch(error => |
{ |
Cu.reportError(error); |
return tryBackup(1); |
}).then(() => |
{ |
this.initialized = true; |
filterNotifier.emit("load"); |
+ clearSubscriptionCaches(); |
}); |
} |
/** |
* Constructs the file name for a <code>patterns.ini</code> backup. |
* @param {number} backupIndex Number of the backup file (1 being the most |
* recent). |
* @returns {string} Backup file name. |
@@ -471,17 +489,17 @@ |
*exportData() |
{ |
// Do not persist external subscriptions |
let subscriptions = []; |
for (let subscription of this.subscriptions()) |
{ |
if (!(subscription instanceof ExternalSubscription) && |
!(subscription instanceof SpecialSubscription && |
- subscription.filters.length == 0)) |
+ subscription.filterCount == 0)) |
{ |
subscriptions.push(subscription); |
} |
} |
yield "# Adblock Plus preferences"; |
yield "version=" + this.formatVersion; |
@@ -492,17 +510,17 @@ |
{ |
yield* subscription.serialize(); |
yield* subscription.serializeFilters(); |
} |
// Save filter data |
for (let subscription of subscriptions) |
{ |
- for (let filter of subscription.filters) |
+ for (let filter of subscription.filters()) |
{ |
if (!saved.has(filter.text)) |
{ |
yield* filter.serialize(); |
saved.add(filter.text); |
} |
} |
} |
@@ -642,31 +660,46 @@ |
let filterStorage = new FilterStorage(); |
exports.filterStorage = filterStorage; |
/** |
* Connects a subscription to its filters without any notifications. |
* @param {Subscription} subscription The subscription that should be |
* connected to its filters. |
+ * @param {?Array.<Filter>} [filters] A list of filters to which the |
+ * subscription should be connected. If this is not given, the subscription |
+ * is connected to its own filters. |
*/ |
-function connectSubscriptionFilters(subscription) |
+function connectSubscriptionFilters(subscription, filters) |
{ |
if (!filterStorage.knownSubscriptions.has(subscription.url)) |
return; |
- for (let filter of subscription.filters) |
+ for (let filter of filters || subscription.filters()) |
filter.addSubscription(subscription); |
} |
/** |
* Disconnects a subscription from its filters without any notifications. |
* @param {Subscription} subscription The subscription that should be |
* disconnected from its filters. |
+ * @param {?Array.<Filter>} [filters] A list of filters from which the |
+ * subscription should be disconnected. If this is not given, the |
+ * subscription is disconnected from its own filters. |
*/ |
-function disconnectSubscriptionFilters(subscription) |
+function disconnectSubscriptionFilters(subscription, filters) |
{ |
if (!filterStorage.knownSubscriptions.has(subscription.url)) |
return; |
- for (let filter of subscription.filters) |
+ for (let filter of filters || subscription.filters()) |
filter.removeSubscription(subscription); |
} |
+ |
+/** |
+ * Clears any in-memory caches held by subscriptions in the storage. |
+ */ |
+function clearSubscriptionCaches() |
+{ |
+ for (let subscription of filterStorage.subscriptions()) |
+ subscription.clearCaches(); |
+} |