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

Side by Side Diff: lib/filterStorage.js

Issue 29416573: Issue 5153 - Simplify patterns.ini parsing (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Patch Set: Created April 18, 2017, 1:33 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | test/data/patterns.ini » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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-2017 eyeo GmbH 3 * Copyright (C) 2006-2017 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 15 matching lines...) Expand all
26 const {Prefs} = require("prefs"); 26 const {Prefs} = require("prefs");
27 const {Filter, ActiveFilter} = require("filterClasses"); 27 const {Filter, ActiveFilter} = require("filterClasses");
28 const {Subscription, SpecialSubscription, 28 const {Subscription, SpecialSubscription,
29 ExternalSubscription} = require("subscriptionClasses"); 29 ExternalSubscription} = require("subscriptionClasses");
30 const {FilterNotifier} = require("filterNotifier"); 30 const {FilterNotifier} = require("filterNotifier");
31 31
32 /** 32 /**
33 * Version number of the filter storage file format. 33 * Version number of the filter storage file format.
34 * @type {number} 34 * @type {number}
35 */ 35 */
36 let formatVersion = 4; 36 let formatVersion = 5;
37 37
38 /** 38 /**
39 * This class reads user's filters from disk, manages them in memory 39 * This class reads user's filters from disk, manages them in memory
40 * and writes them back. 40 * and writes them back.
41 * @class 41 * @class
42 */ 42 */
43 let FilterStorage = exports.FilterStorage = 43 let FilterStorage = exports.FilterStorage =
44 { 44 {
45 /** 45 /**
46 * Will be set to true after the initial loadFromDisk() call completes. 46 * Will be set to true after the initial loadFromDisk() call completes.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 generalSubscription = subscription; 114 generalSubscription = subscription;
115 } 115 }
116 } 116 }
117 } 117 }
118 return generalSubscription; 118 return generalSubscription;
119 }, 119 },
120 120
121 /** 121 /**
122 * Adds a filter subscription to the list 122 * Adds a filter subscription to the list
123 * @param {Subscription} subscription filter subscription to be added 123 * @param {Subscription} subscription filter subscription to be added
124 * @param {boolean} silent if true, no listeners will be triggered
125 * (to be used when filter list is reloaded)
126 */ 124 */
127 addSubscription(subscription, silent) 125 addSubscription(subscription)
128 { 126 {
129 if (subscription.url in FilterStorage.knownSubscriptions) 127 if (subscription.url in FilterStorage.knownSubscriptions)
130 return; 128 return;
131 129
132 FilterStorage.subscriptions.push(subscription); 130 FilterStorage.subscriptions.push(subscription);
133 FilterStorage.knownSubscriptions[subscription.url] = subscription; 131 FilterStorage.knownSubscriptions[subscription.url] = subscription;
134 addSubscriptionFilters(subscription); 132 addSubscriptionFilters(subscription);
135 133
136 if (!silent) 134 FilterNotifier.triggerListeners("subscription.added", subscription);
137 FilterNotifier.triggerListeners("subscription.added", subscription);
138 }, 135 },
139 136
140 /** 137 /**
141 * Removes a filter subscription from the list 138 * Removes a filter subscription from the list
142 * @param {Subscription} subscription filter subscription to be removed 139 * @param {Subscription} subscription filter subscription to be removed
143 * @param {boolean} silent if true, no listeners will be triggered
144 * (to be used when filter list is reloaded)
145 */ 140 */
146 removeSubscription(subscription, silent) 141 removeSubscription(subscription)
147 { 142 {
148 for (let i = 0; i < FilterStorage.subscriptions.length; i++) 143 for (let i = 0; i < FilterStorage.subscriptions.length; i++)
149 { 144 {
150 if (FilterStorage.subscriptions[i].url == subscription.url) 145 if (FilterStorage.subscriptions[i].url == subscription.url)
151 { 146 {
152 removeSubscriptionFilters(subscription); 147 removeSubscriptionFilters(subscription);
153 148
154 FilterStorage.subscriptions.splice(i--, 1); 149 FilterStorage.subscriptions.splice(i--, 1);
155 delete FilterStorage.knownSubscriptions[subscription.url]; 150 delete FilterStorage.knownSubscriptions[subscription.url];
156 if (!silent) 151 FilterNotifier.triggerListeners("subscription.removed", subscription);
157 FilterNotifier.triggerListeners("subscription.removed", subscription);
158 return; 152 return;
159 } 153 }
160 } 154 }
161 }, 155 },
162 156
163 /** 157 /**
164 * Moves a subscription in the list to a new position. 158 * Moves a subscription in the list to a new position.
165 * @param {Subscription} subscription filter subscription to be moved 159 * @param {Subscription} subscription filter subscription to be moved
166 * @param {Subscription} [insertBefore] filter subscription to insert before 160 * @param {Subscription} [insertBefore] filter subscription to insert before
167 * (if omitted the subscription will be put at the end of the list) 161 * (if omitted the subscription will be put at the end of the list)
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 delete subscription.oldFilters; 198 delete subscription.oldFilters;
205 }, 199 },
206 200
207 /** 201 /**
208 * Adds a user-defined filter to the list 202 * Adds a user-defined filter to the list
209 * @param {Filter} filter 203 * @param {Filter} filter
210 * @param {SpecialSubscription} [subscription] 204 * @param {SpecialSubscription} [subscription]
211 * particular group that the filter should be added to 205 * particular group that the filter should be added to
212 * @param {number} [position] 206 * @param {number} [position]
213 * position within the subscription at which the filter should be added 207 * position within the subscription at which the filter should be added
214 * @param {boolean} silent
215 * if true, no listeners will be triggered (to be used when filter list is
216 * reloaded)
217 */ 208 */
218 addFilter(filter, subscription, position, silent) 209 addFilter(filter, subscription, position)
219 { 210 {
220 if (!subscription) 211 if (!subscription)
221 { 212 {
222 if (filter.subscriptions.some(s => s instanceof SpecialSubscription && 213 if (filter.subscriptions.some(s => s instanceof SpecialSubscription &&
223 !s.disabled)) 214 !s.disabled))
224 { 215 {
225 return; // No need to add 216 return; // No need to add
226 } 217 }
227 subscription = FilterStorage.getGroupForFilter(filter); 218 subscription = FilterStorage.getGroupForFilter(filter);
228 } 219 }
229 if (!subscription) 220 if (!subscription)
230 { 221 {
231 // No group for this filter exists, create one 222 // No group for this filter exists, create one
232 subscription = SpecialSubscription.createForFilter(filter); 223 subscription = SpecialSubscription.createForFilter(filter);
233 this.addSubscription(subscription); 224 this.addSubscription(subscription);
234 return; 225 return;
235 } 226 }
236 227
237 if (typeof position == "undefined") 228 if (typeof position == "undefined")
238 position = subscription.filters.length; 229 position = subscription.filters.length;
239 230
240 if (filter.subscriptions.indexOf(subscription) < 0) 231 if (filter.subscriptions.indexOf(subscription) < 0)
241 filter.subscriptions.push(subscription); 232 filter.subscriptions.push(subscription);
242 subscription.filters.splice(position, 0, filter); 233 subscription.filters.splice(position, 0, filter);
243 if (!silent) 234 FilterNotifier.triggerListeners("filter.added", filter, subscription,
244 { 235 position);
245 FilterNotifier.triggerListeners("filter.added", filter, subscription,
246 position);
247 }
248 }, 236 },
249 237
250 /** 238 /**
251 * Removes a user-defined filter from the list 239 * Removes a user-defined filter from the list
252 * @param {Filter} filter 240 * @param {Filter} filter
253 * @param {SpecialSubscription} [subscription] a particular filter group that 241 * @param {SpecialSubscription} [subscription] a particular filter group that
254 * the filter should be removed from (if ommited will be removed from all 242 * the filter should be removed from (if ommited will be removed from all
255 * subscriptions) 243 * subscriptions)
256 * @param {number} [position] position inside the filter group at which the 244 * @param {number} [position] position inside the filter group at which the
257 * filter should be removed (if ommited all instances will be removed) 245 * filter should be removed (if ommited all instances will be removed)
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 * forgetting this callback. 365 * forgetting this callback.
378 */ 366 */
379 importData(silent) 367 importData(silent)
380 { 368 {
381 let parser = new INIParser(); 369 let parser = new INIParser();
382 return line => 370 return line =>
383 { 371 {
384 parser.process(line); 372 parser.process(line);
385 if (line === null) 373 if (line === null)
386 { 374 {
387 // Old special groups might have been converted, remove them if
388 // they are empty
389 let specialMap = new Set(["~il~", "~wl~", "~fl~", "~eh~"]);
390 let knownSubscriptions = Object.create(null); 375 let knownSubscriptions = Object.create(null);
391 for (let i = 0; i < parser.subscriptions.length; i++) 376 for (let subscription of parser.subscriptions)
392 { 377 knownSubscriptions[subscription.url] = subscription;
393 let subscription = parser.subscriptions[i];
394 if (subscription instanceof SpecialSubscription &&
395 subscription.filters.length == 0 &&
396 specialMap.has(subscription.url))
397 {
398 parser.subscriptions.splice(i--, 1);
399 }
400 else
401 knownSubscriptions[subscription.url] = subscription;
402 }
403 378
404 this.fileProperties = parser.fileProperties; 379 this.fileProperties = parser.fileProperties;
405 this.subscriptions = parser.subscriptions; 380 this.subscriptions = parser.subscriptions;
406 this.knownSubscriptions = knownSubscriptions; 381 this.knownSubscriptions = knownSubscriptions;
407 Filter.knownFilters = parser.knownFilters; 382 Filter.knownFilters = parser.knownFilters;
408 Subscription.knownSubscriptions = parser.knownSubscriptions; 383 Subscription.knownSubscriptions = parser.knownSubscriptions;
409 384
410 if (parser.userFilters)
411 {
412 for (let filter of parser.userFilters)
413 this.addFilter(Filter.fromText(filter), null, undefined, true);
414 }
415
416 if (!silent) 385 if (!silent)
417 FilterNotifier.triggerListeners("load"); 386 FilterNotifier.triggerListeners("load");
418 } 387 }
419 }; 388 };
420 }, 389 },
421 390
422 /** 391 /**
423 * Loads all subscriptions from the disk. 392 * Loads all subscriptions from the disk.
424 * @return {Promise} promise resolved or rejected when loading is complete 393 * @return {Promise} promise resolved or rejected when loading is complete
425 */ 394 */
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 let subscriptions = this.subscriptions.filter( 475 let subscriptions = this.subscriptions.filter(
507 s => !(s instanceof ExternalSubscription) 476 s => !(s instanceof ExternalSubscription)
508 ); 477 );
509 478
510 yield "# Adblock Plus preferences"; 479 yield "# Adblock Plus preferences";
511 yield "version=" + formatVersion; 480 yield "version=" + formatVersion;
512 481
513 let saved = new Set(); 482 let saved = new Set();
514 let buf = []; 483 let buf = [];
515 484
485 // Save subscriptions
486 for (let subscription of subscriptions)
487 {
488 yield "";
489
490 subscription.serialize(buf);
491 if (subscription.filters.length)
492 {
493 buf.push("", "[Subscription filters]");
494 subscription.serializeFilters(buf);
495 }
496 for (let line of buf)
497 yield line;
498 buf.splice(0);
499 }
500
516 // Save filter data 501 // Save filter data
517 for (let subscription of subscriptions) 502 for (let subscription of subscriptions)
518 { 503 {
519 for (let filter of subscription.filters) 504 for (let filter of subscription.filters)
520 { 505 {
521 if (!saved.has(filter.text)) 506 if (!saved.has(filter.text))
522 { 507 {
523 filter.serialize(buf); 508 filter.serialize(buf);
524 saved.add(filter.text); 509 saved.add(filter.text);
525 for (let line of buf) 510 for (let line of buf)
526 yield line; 511 yield line;
527 buf.splice(0); 512 buf.splice(0);
528 } 513 }
529 } 514 }
530 } 515 }
531
532 // Save subscriptions
533 for (let subscription of subscriptions)
534 {
535 yield "";
536
537 subscription.serialize(buf);
538 if (subscription.filters.length)
539 {
540 buf.push("", "[Subscription filters]");
541 subscription.serializeFilters(buf);
542 }
543 for (let line of buf)
544 yield line;
545 buf.splice(0);
546 }
547 }, 516 },
548 517
549 /** 518 /**
550 * Will be set to true if saveToDisk() is running (reentrance protection). 519 * Will be set to true if saveToDisk() is running (reentrance protection).
551 * @type {boolean} 520 * @type {boolean}
552 */ 521 */
553 _saving: false, 522 _saving: false,
554 523
555 /** 524 /**
556 * Will be set to true if a saveToDisk() call arrives while saveToDisk() is 525 * Will be set to true if a saveToDisk() call arrives while saveToDisk() is
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
732 INIParser.prototype = 701 INIParser.prototype =
733 { 702 {
734 linesProcessed: 0, 703 linesProcessed: 0,
735 subscriptions: null, 704 subscriptions: null,
736 knownFilters: null, 705 knownFilters: null,
737 knownSubscriptions: null, 706 knownSubscriptions: null,
738 wantObj: true, 707 wantObj: true,
739 fileProperties: null, 708 fileProperties: null,
740 curObj: null, 709 curObj: null,
741 curSection: null, 710 curSection: null,
742 userFilters: null,
743 711
744 process(val) 712 process(val)
745 { 713 {
746 let origKnownFilters = Filter.knownFilters; 714 let origKnownFilters = Filter.knownFilters;
747 Filter.knownFilters = this.knownFilters; 715 Filter.knownFilters = this.knownFilters;
748 let origKnownSubscriptions = Subscription.knownSubscriptions; 716 let origKnownSubscriptions = Subscription.knownSubscriptions;
749 Subscription.knownSubscriptions = this.knownSubscriptions; 717 Subscription.knownSubscriptions = this.knownSubscriptions;
750 let match; 718 let match;
751 try 719 try
752 { 720 {
753 if (this.wantObj === true && (match = /^(\w+)=(.*)$/.exec(val))) 721 if (this.wantObj === true && (match = /^(\w+)=(.*)$/.exec(val)))
754 this.curObj[match[1]] = match[2]; 722 this.curObj[match[1]] = match[2];
755 else if (val === null || (match = /^\s*\[(.+)\]\s*$/.exec(val))) 723 else if (val === null || (match = /^\s*\[(.+)\]\s*$/.exec(val)))
756 { 724 {
757 if (this.curObj) 725 if (this.curObj)
758 { 726 {
759 // Process current object before going to next section 727 // Process current object before going to next section
760 switch (this.curSection) 728 switch (this.curSection)
761 { 729 {
762 case "filter": 730 case "filter":
763 case "pattern":
764 if ("text" in this.curObj) 731 if ("text" in this.curObj)
765 Filter.fromObject(this.curObj); 732 Filter.fromObject(this.curObj);
766 break; 733 break;
767 case "subscription": { 734 case "subscription": {
768 let subscription = Subscription.fromObject(this.curObj); 735 let subscription = Subscription.fromObject(this.curObj);
769 if (subscription) 736 if (subscription)
770 this.subscriptions.push(subscription); 737 this.subscriptions.push(subscription);
771 break; 738 break;
772 } 739 }
773 case "subscription filters": 740 case "subscription filters":
774 case "subscription patterns":
775 if (this.subscriptions.length) 741 if (this.subscriptions.length)
776 { 742 {
777 let subscription = this.subscriptions[ 743 let subscription = this.subscriptions[
778 this.subscriptions.length - 1 744 this.subscriptions.length - 1
779 ]; 745 ];
780 for (let text of this.curObj) 746 for (let text of this.curObj)
781 { 747 {
782 let filter = Filter.fromText(text); 748 let filter = Filter.fromText(text);
783 subscription.filters.push(filter); 749 subscription.filters.push(filter);
784 filter.subscriptions.push(subscription); 750 filter.subscriptions.push(subscription);
785 } 751 }
786 } 752 }
787 break; 753 break;
788 case "user patterns":
789 this.userFilters = this.curObj;
790 break;
791 } 754 }
792 } 755 }
793 756
794 if (val === null) 757 if (val === null)
795 return; 758 return;
796 759
797 this.curSection = match[1].toLowerCase(); 760 this.curSection = match[1].toLowerCase();
798 switch (this.curSection) 761 switch (this.curSection)
799 { 762 {
800 case "filter": 763 case "filter":
801 case "pattern":
802 case "subscription": 764 case "subscription":
803 this.wantObj = true; 765 this.wantObj = true;
804 this.curObj = {}; 766 this.curObj = {};
805 break; 767 break;
806 case "subscription filters": 768 case "subscription filters":
807 case "subscription patterns":
808 case "user patterns":
809 this.wantObj = false; 769 this.wantObj = false;
810 this.curObj = []; 770 this.curObj = [];
811 break; 771 break;
812 default: 772 default:
813 this.wantObj = undefined; 773 this.wantObj = undefined;
814 this.curObj = null; 774 this.curObj = null;
815 } 775 }
816 } 776 }
817 else if (this.wantObj === false && val) 777 else if (this.wantObj === false && val)
818 this.curObj.push(val.replace(/\\\[/g, "[")); 778 this.curObj.push(val.replace(/\\\[/g, "["));
819 } 779 }
820 finally 780 finally
821 { 781 {
822 Filter.knownFilters = origKnownFilters; 782 Filter.knownFilters = origKnownFilters;
823 Subscription.knownSubscriptions = origKnownSubscriptions; 783 Subscription.knownSubscriptions = origKnownSubscriptions;
824 } 784 }
825 } 785 }
826 }; 786 };
OLDNEW
« no previous file with comments | « no previous file | test/data/patterns.ini » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld