| Left: | ||
| Right: |
| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
| 3 * Copyright (C) 2006-present eyeo GmbH | 3 * Copyright (C) 2006-present eyeo GmbH |
| 4 * | 4 * |
| 5 * Adblock Plus is free software: you can redistribute it and/or modify | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
| 6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
| 7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
| 8 * | 8 * |
| 9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 161 */ | 161 */ |
| 162 addSubscription(subscription) | 162 addSubscription(subscription) |
| 163 { | 163 { |
| 164 if (this.knownSubscriptions.has(subscription.url)) | 164 if (this.knownSubscriptions.has(subscription.url)) |
| 165 return; | 165 return; |
| 166 | 166 |
| 167 this.knownSubscriptions.set(subscription.url, subscription); | 167 this.knownSubscriptions.set(subscription.url, subscription); |
| 168 connectSubscriptionFilters(subscription); | 168 connectSubscriptionFilters(subscription); |
| 169 | 169 |
| 170 filterNotifier.emit("subscription.added", subscription); | 170 filterNotifier.emit("subscription.added", subscription); |
| 171 | |
| 172 subscription.clearCaches(); | |
| 171 } | 173 } |
| 172 | 174 |
| 173 /** | 175 /** |
| 174 * Removes a subscription from the storage. | 176 * Removes a subscription from the storage. |
| 175 * @param {Subscription} subscription The subscription to be removed. | 177 * @param {Subscription} subscription The subscription to be removed. |
| 176 */ | 178 */ |
| 177 removeSubscription(subscription) | 179 removeSubscription(subscription) |
| 178 { | 180 { |
| 179 if (!this.knownSubscriptions.has(subscription.url)) | 181 if (!this.knownSubscriptions.has(subscription.url)) |
| 180 return; | 182 return; |
| 181 | 183 |
| 182 disconnectSubscriptionFilters(subscription); | 184 disconnectSubscriptionFilters(subscription); |
| 183 | 185 |
| 184 this.knownSubscriptions.delete(subscription.url); | 186 this.knownSubscriptions.delete(subscription.url); |
| 185 | 187 |
| 186 // This should be the last remaining reference to the Subscription | 188 // This should be the last remaining reference to the Subscription |
| 187 // object. | 189 // object. |
| 188 Subscription.knownSubscriptions.delete(subscription.url); | 190 Subscription.knownSubscriptions.delete(subscription.url); |
| 189 | 191 |
| 190 filterNotifier.emit("subscription.removed", subscription); | 192 filterNotifier.emit("subscription.removed", subscription); |
| 191 } | 193 } |
| 192 | 194 |
| 193 /** | 195 /** |
| 194 * Replaces the list of filters in a subscription with a new list. | 196 * Replaces the list of filters in a subscription with a new list. |
| 195 * @param {Subscription} subscription The subscription to be updated. | 197 * @param {Subscription} subscription The subscription to be updated. |
| 196 * @param {Array.<Filter>} filters The new list of filters. | 198 * @param {Array.<Filter>} filters The new list of filters. |
| 197 */ | 199 */ |
| 198 updateSubscriptionFilters(subscription, filters) | 200 updateSubscriptionFilters(subscription, filters) |
| 199 { | 201 { |
| 200 disconnectSubscriptionFilters(subscription); | 202 let oldFilters = [...subscription.filters()]; |
| 201 let oldFilters = subscription.filters; | 203 disconnectSubscriptionFilters(subscription, oldFilters); |
| 202 subscription.filters = filters; | 204 subscription.clearFilters(); |
| 203 connectSubscriptionFilters(subscription); | 205 |
| 206 for (let filter of filters) | |
| 207 subscription.addFilter(filter); | |
| 208 | |
| 209 connectSubscriptionFilters(subscription, filters); | |
| 210 | |
| 204 filterNotifier.emit("subscription.updated", subscription, oldFilters); | 211 filterNotifier.emit("subscription.updated", subscription, oldFilters); |
| 212 | |
| 213 subscription.clearCaches(); | |
|
Manish Jethani
2018/11/18 02:25:50
Typically a subscription will be updated with mult
| |
| 205 } | 214 } |
| 206 | 215 |
| 207 /** | 216 /** |
| 208 * Adds a user-defined filter to the storage. | 217 * Adds a user-defined filter to the storage. |
| 209 * @param {Filter} filter | 218 * @param {Filter} filter |
| 210 * @param {?SpecialSubscription} [subscription] The subscription that the | 219 * @param {?SpecialSubscription} [subscription] The subscription that the |
| 211 * filter should be added to. | 220 * filter should be added to. |
| 212 * @param {number} [position] The position within the subscription at which | 221 * @param {number} [position] The position within the subscription at which |
| 213 * the filter should be added. If not specified, the filter is added at the | 222 * the filter should be added. If not specified, the filter is added at the |
| 214 * end of the subscription. | 223 * end of the subscription. |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 229 } | 238 } |
| 230 if (!subscription) | 239 if (!subscription) |
| 231 { | 240 { |
| 232 // No group for this filter exists, create one | 241 // No group for this filter exists, create one |
| 233 subscription = SpecialSubscription.createForFilter(filter); | 242 subscription = SpecialSubscription.createForFilter(filter); |
| 234 this.addSubscription(subscription); | 243 this.addSubscription(subscription); |
| 235 return; | 244 return; |
| 236 } | 245 } |
| 237 | 246 |
| 238 if (typeof position == "undefined") | 247 if (typeof position == "undefined") |
| 239 position = subscription.filters.length; | 248 position = subscription.filterCount; |
| 240 | 249 |
| 241 filter.addSubscription(subscription); | 250 filter.addSubscription(subscription); |
| 242 subscription.filters.splice(position, 0, filter); | 251 subscription.insertFilterAt(filter, position); |
| 243 filterNotifier.emit("filter.added", filter, subscription, position); | 252 filterNotifier.emit("filter.added", filter, subscription, position); |
| 244 } | 253 } |
| 245 | 254 |
| 246 /** | 255 /** |
| 247 * Removes a user-defined filter from the storage. | 256 * Removes a user-defined filter from the storage. |
| 248 * @param {Filter} filter | 257 * @param {Filter} filter |
| 249 * @param {?SpecialSubscription} [subscription] The subscription that the | 258 * @param {?SpecialSubscription} [subscription] The subscription that the |
| 250 * filter should be removed from. If not specified, the filter will be | 259 * filter should be removed from. If not specified, the filter will be |
| 251 * removed from all subscriptions. | 260 * removed from all subscriptions. |
| 252 * @param {number} [position] The position within the subscription at which | 261 * @param {number} [position] The position within the subscription at which |
| 253 * the filter should be removed. If not specified, all instances of the | 262 * the filter should be removed. If not specified, all instances of the |
| 254 * filter will be removed. | 263 * filter will be removed. |
| 255 */ | 264 */ |
| 256 removeFilter(filter, subscription, position) | 265 removeFilter(filter, subscription, position) |
| 257 { | 266 { |
| 258 let subscriptions = ( | 267 let subscriptions = ( |
| 259 subscription ? [subscription] : filter.subscriptions() | 268 subscription ? [subscription] : filter.subscriptions() |
| 260 ); | 269 ); |
| 261 for (let currentSubscription of subscriptions) | 270 for (let currentSubscription of subscriptions) |
| 262 { | 271 { |
| 263 if (currentSubscription instanceof SpecialSubscription) | 272 if (currentSubscription instanceof SpecialSubscription) |
| 264 { | 273 { |
| 265 let positions = []; | 274 let positions = []; |
| 266 if (typeof position == "undefined") | 275 if (typeof position == "undefined") |
| 267 { | 276 { |
| 268 let index = -1; | 277 let index = -1; |
| 269 do | 278 do |
| 270 { | 279 { |
| 271 index = currentSubscription.filters.indexOf(filter, index + 1); | 280 index = currentSubscription.searchFilter(filter, index + 1); |
| 272 if (index >= 0) | 281 if (index >= 0) |
| 273 positions.push(index); | 282 positions.push(index); |
| 274 } while (index >= 0); | 283 } while (index >= 0); |
| 275 } | 284 } |
| 276 else | 285 else |
| 277 positions.push(position); | 286 positions.push(position); |
| 278 | 287 |
| 279 for (let j = positions.length - 1; j >= 0; j--) | 288 for (let j = positions.length - 1; j >= 0; j--) |
| 280 { | 289 { |
| 281 let currentPosition = positions[j]; | 290 let currentPosition = positions[j]; |
| 282 if (currentSubscription.filters[currentPosition] == filter) | 291 let currentFilter = currentSubscription.filterAt(currentPosition); |
| 292 if (currentFilter && currentFilter.text == filter.text) | |
| 283 { | 293 { |
| 284 currentSubscription.filters.splice(currentPosition, 1); | 294 currentSubscription.deleteFilterAt(currentPosition); |
| 285 if (currentSubscription.filters.indexOf(filter) < 0) | 295 if (currentSubscription.searchFilter(filter) < 0) |
| 286 filter.removeSubscription(currentSubscription); | 296 filter.removeSubscription(currentSubscription); |
| 287 filterNotifier.emit("filter.removed", filter, currentSubscription, | 297 filterNotifier.emit("filter.removed", filter, currentSubscription, |
| 288 currentPosition); | 298 currentPosition); |
| 289 } | 299 } |
| 290 } | 300 } |
| 291 } | 301 } |
| 292 } | 302 } |
| 293 } | 303 } |
| 294 | 304 |
| 295 /** | 305 /** |
| 296 * Moves a user-defined filter to a new position. | 306 * Moves a user-defined filter to a new position. |
| 297 * @param {Filter} filter | 307 * @param {Filter} filter |
| 298 * @param {SpecialSubscription} subscription The subscription where the | 308 * @param {SpecialSubscription} subscription The subscription where the |
| 299 * filter is located. | 309 * filter is located. |
| 300 * @param {number} oldPosition The current position of the filter. | 310 * @param {number} oldPosition The current position of the filter. |
| 301 * @param {number} newPosition The new position of the filter. | 311 * @param {number} newPosition The new position of the filter. |
| 302 */ | 312 */ |
| 303 moveFilter(filter, subscription, oldPosition, newPosition) | 313 moveFilter(filter, subscription, oldPosition, newPosition) |
| 304 { | 314 { |
| 305 if (!(subscription instanceof SpecialSubscription) || | 315 if (!(subscription instanceof SpecialSubscription)) |
| 306 subscription.filters[oldPosition] != filter) | |
| 307 { | |
| 308 return; | 316 return; |
| 309 } | 317 |
| 318 let currentFilter = subscription.filterAt(oldPosition); | |
| 319 if (!currentFilter || currentFilter.text != filter.text) | |
| 320 return; | |
| 310 | 321 |
| 311 newPosition = Math.min(Math.max(newPosition, 0), | 322 newPosition = Math.min(Math.max(newPosition, 0), |
| 312 subscription.filters.length - 1); | 323 subscription.filterCount - 1); |
| 313 if (oldPosition == newPosition) | 324 if (oldPosition == newPosition) |
| 314 return; | 325 return; |
| 315 | 326 |
| 316 subscription.filters.splice(oldPosition, 1); | 327 subscription.deleteFilterAt(oldPosition); |
| 317 subscription.filters.splice(newPosition, 0, filter); | 328 subscription.insertFilterAt(filter, newPosition); |
| 318 filterNotifier.emit("filter.moved", filter, subscription, oldPosition, | 329 filterNotifier.emit("filter.moved", filter, subscription, oldPosition, |
| 319 newPosition); | 330 newPosition); |
| 320 } | 331 } |
| 321 | 332 |
| 322 /** | 333 /** |
| 323 * Increases the hit count for a filter by one. | 334 * Increases the hit count for a filter by one. |
| 324 * @param {Filter} filter | 335 * @param {Filter} filter |
| 325 */ | 336 */ |
| 326 increaseHitCount(filter) | 337 increaseHitCount(filter) |
| 327 { | 338 { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 373 let knownSubscriptions = new Map(); | 384 let knownSubscriptions = new Map(); |
| 374 for (let subscription of parser.subscriptions) | 385 for (let subscription of parser.subscriptions) |
| 375 knownSubscriptions.set(subscription.url, subscription); | 386 knownSubscriptions.set(subscription.url, subscription); |
| 376 | 387 |
| 377 this.fileProperties = parser.fileProperties; | 388 this.fileProperties = parser.fileProperties; |
| 378 this.knownSubscriptions = knownSubscriptions; | 389 this.knownSubscriptions = knownSubscriptions; |
| 379 Filter.knownFilters = parser.knownFilters; | 390 Filter.knownFilters = parser.knownFilters; |
| 380 Subscription.knownSubscriptions = parser.knownSubscriptions; | 391 Subscription.knownSubscriptions = parser.knownSubscriptions; |
| 381 | 392 |
| 382 if (!silent) | 393 if (!silent) |
| 394 { | |
| 383 filterNotifier.emit("load"); | 395 filterNotifier.emit("load"); |
| 396 | |
| 397 // Clear any in-memory caches that may have been created during | |
| 398 // initialization. | |
| 399 clearSubscriptionCaches(); | |
|
Manish Jethani
2018/11/18 02:25:50
This is not necessary right now but better to do i
| |
| 400 } | |
| 384 } | 401 } |
| 385 }; | 402 }; |
| 386 } | 403 } |
| 387 | 404 |
| 388 /** | 405 /** |
| 389 * Loads all subscriptions from disk. | 406 * Loads all subscriptions from disk. |
| 390 * @returns {Promise} A promise resolved or rejected when loading is complete. | 407 * @returns {Promise} A promise resolved or rejected when loading is complete. |
| 391 */ | 408 */ |
| 392 loadFromDisk() | 409 loadFromDisk() |
| 393 { | 410 { |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 422 } | 439 } |
| 423 }); | 440 }); |
| 424 }).catch(error => | 441 }).catch(error => |
| 425 { | 442 { |
| 426 Cu.reportError(error); | 443 Cu.reportError(error); |
| 427 return tryBackup(1); | 444 return tryBackup(1); |
| 428 }).then(() => | 445 }).then(() => |
| 429 { | 446 { |
| 430 this.initialized = true; | 447 this.initialized = true; |
| 431 filterNotifier.emit("load"); | 448 filterNotifier.emit("load"); |
| 449 clearSubscriptionCaches(); | |
| 432 }); | 450 }); |
| 433 } | 451 } |
| 434 | 452 |
| 435 /** | 453 /** |
| 436 * Constructs the file name for a <code>patterns.ini</code> backup. | 454 * Constructs the file name for a <code>patterns.ini</code> backup. |
| 437 * @param {number} backupIndex Number of the backup file (1 being the most | 455 * @param {number} backupIndex Number of the backup file (1 being the most |
| 438 * recent). | 456 * recent). |
| 439 * @returns {string} Backup file name. | 457 * @returns {string} Backup file name. |
| 440 */ | 458 */ |
| 441 getBackupName(backupIndex) | 459 getBackupName(backupIndex) |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 469 * @yields {string} | 487 * @yields {string} |
| 470 */ | 488 */ |
| 471 *exportData() | 489 *exportData() |
| 472 { | 490 { |
| 473 // Do not persist external subscriptions | 491 // Do not persist external subscriptions |
| 474 let subscriptions = []; | 492 let subscriptions = []; |
| 475 for (let subscription of this.subscriptions()) | 493 for (let subscription of this.subscriptions()) |
| 476 { | 494 { |
| 477 if (!(subscription instanceof ExternalSubscription) && | 495 if (!(subscription instanceof ExternalSubscription) && |
| 478 !(subscription instanceof SpecialSubscription && | 496 !(subscription instanceof SpecialSubscription && |
| 479 subscription.filters.length == 0)) | 497 subscription.filterCount == 0)) |
| 480 { | 498 { |
| 481 subscriptions.push(subscription); | 499 subscriptions.push(subscription); |
| 482 } | 500 } |
| 483 } | 501 } |
| 484 | 502 |
| 485 yield "# Adblock Plus preferences"; | 503 yield "# Adblock Plus preferences"; |
| 486 yield "version=" + this.formatVersion; | 504 yield "version=" + this.formatVersion; |
| 487 | 505 |
| 488 let saved = new Set(); | 506 let saved = new Set(); |
| 489 | 507 |
| 490 // Save subscriptions | 508 // Save subscriptions |
| 491 for (let subscription of subscriptions) | 509 for (let subscription of subscriptions) |
| 492 { | 510 { |
| 493 yield* subscription.serialize(); | 511 yield* subscription.serialize(); |
| 494 yield* subscription.serializeFilters(); | 512 yield* subscription.serializeFilters(); |
| 495 } | 513 } |
| 496 | 514 |
| 497 // Save filter data | 515 // Save filter data |
| 498 for (let subscription of subscriptions) | 516 for (let subscription of subscriptions) |
| 499 { | 517 { |
| 500 for (let filter of subscription.filters) | 518 for (let filter of subscription.filters()) |
| 501 { | 519 { |
| 502 if (!saved.has(filter.text)) | 520 if (!saved.has(filter.text)) |
| 503 { | 521 { |
| 504 yield* filter.serialize(); | 522 yield* filter.serialize(); |
| 505 saved.add(filter.text); | 523 saved.add(filter.text); |
| 506 } | 524 } |
| 507 } | 525 } |
| 508 } | 526 } |
| 509 } | 527 } |
| 510 | 528 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 640 * back to disk. | 658 * back to disk. |
| 641 */ | 659 */ |
| 642 let filterStorage = new FilterStorage(); | 660 let filterStorage = new FilterStorage(); |
| 643 | 661 |
| 644 exports.filterStorage = filterStorage; | 662 exports.filterStorage = filterStorage; |
| 645 | 663 |
| 646 /** | 664 /** |
| 647 * Connects a subscription to its filters without any notifications. | 665 * Connects a subscription to its filters without any notifications. |
| 648 * @param {Subscription} subscription The subscription that should be | 666 * @param {Subscription} subscription The subscription that should be |
| 649 * connected to its filters. | 667 * connected to its filters. |
| 668 * @param {?Array.<Filter>} [filters] A list of filters to which the | |
| 669 * subscription should be connected. If this is not given, the subscription | |
| 670 * is connected to its own filters. | |
| 650 */ | 671 */ |
| 651 function connectSubscriptionFilters(subscription) | 672 function connectSubscriptionFilters(subscription, filters) |
| 652 { | 673 { |
| 653 if (!filterStorage.knownSubscriptions.has(subscription.url)) | 674 if (!filterStorage.knownSubscriptions.has(subscription.url)) |
| 654 return; | 675 return; |
| 655 | 676 |
| 656 for (let filter of subscription.filters) | 677 for (let filter of filters || subscription.filters()) |
| 657 filter.addSubscription(subscription); | 678 filter.addSubscription(subscription); |
| 658 } | 679 } |
| 659 | 680 |
| 660 /** | 681 /** |
| 661 * Disconnects a subscription from its filters without any notifications. | 682 * Disconnects a subscription from its filters without any notifications. |
| 662 * @param {Subscription} subscription The subscription that should be | 683 * @param {Subscription} subscription The subscription that should be |
| 663 * disconnected from its filters. | 684 * disconnected from its filters. |
| 685 * @param {?Array.<Filter>} [filters] A list of filters from which the | |
| 686 * subscription should be disconnected. If this is not given, the | |
| 687 * subscription is disconnected from its own filters. | |
| 664 */ | 688 */ |
| 665 function disconnectSubscriptionFilters(subscription) | 689 function disconnectSubscriptionFilters(subscription, filters) |
| 666 { | 690 { |
| 667 if (!filterStorage.knownSubscriptions.has(subscription.url)) | 691 if (!filterStorage.knownSubscriptions.has(subscription.url)) |
| 668 return; | 692 return; |
| 669 | 693 |
| 670 for (let filter of subscription.filters) | 694 for (let filter of filters || subscription.filters()) |
| 671 filter.removeSubscription(subscription); | 695 filter.removeSubscription(subscription); |
| 672 } | 696 } |
| 697 | |
| 698 /** | |
| 699 * Clears any in-memory caches held by subscriptions in the storage. | |
| 700 */ | |
| 701 function clearSubscriptionCaches() | |
| 702 { | |
| 703 for (let subscription of filterStorage.subscriptions()) | |
| 704 subscription.clearCaches(); | |
| 705 } | |
| OLD | NEW |