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

Side by Side Diff: lib/subscriptionClasses.js

Issue 29384812: Issue 4127 - [emscripten] Convert subscription classes to C++ - Part 1 (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore
Patch Set: Removed unnecessary raw buffer Created April 10, 2017, 6:27 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
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
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 /**
19 * @fileOverview Definition of Subscription class and its subclasses.
20 */
21
22 "use strict"; 18 "use strict";
23 19
24 let {ActiveFilter, BlockingFilter, WhitelistFilter, ElemHideBase} = require("fil terClasses"); 20 let compiled = require("compiled");
25 let {FilterNotifier} = require("filterNotifier"); 21 for (let cls of ["Subscription", "SpecialSubscription",
26 22 "DownloadableSubscription"])
27 /**
28 * Abstract base class for filter subscriptions
29 *
30 * @param {String} url download location of the subscription
31 * @param {String} [title] title of the filter subscription
32 * @constructor
33 */
34 function Subscription(url, title)
35 { 23 {
36 this.url = url; 24 exports[cls] = compiled[cls];
37 this.filters = [];
38 if (title)
39 this._title = title;
40 Subscription.knownSubscriptions[url] = this;
41 } 25 }
42 exports.Subscription = Subscription;
43
44 Subscription.prototype =
45 {
46 /**
47 * Download location of the subscription
48 * @type String
49 */
50 url: null,
51
52 /**
53 * Filters contained in the filter subscription
54 * @type Filter[]
55 */
56 filters: null,
57
58 _title: null,
59 _fixedTitle: false,
60 _disabled: false,
61
62 /**
63 * Title of the filter subscription
64 * @type String
65 */
66 get title()
67 {
68 return this._title;
69 },
70 set title(value)
71 {
72 if (value != this._title)
73 {
74 let oldValue = this._title;
75 this._title = value;
76 FilterNotifier.triggerListeners("subscription.title", this, value, oldValu e);
77 }
78 return this._title;
79 },
80
81 /**
82 * Determines whether the title should be editable
83 * @type Boolean
84 */
85 get fixedTitle()
86 {
87 return this._fixedTitle;
88 },
89 set fixedTitle(value)
90 {
91 if (value != this._fixedTitle)
92 {
93 let oldValue = this._fixedTitle;
94 this._fixedTitle = value;
95 FilterNotifier.triggerListeners("subscription.fixedTitle", this, value, ol dValue);
96 }
97 return this._fixedTitle;
98 },
99
100 /**
101 * Defines whether the filters in the subscription should be disabled
102 * @type Boolean
103 */
104 get disabled()
105 {
106 return this._disabled;
107 },
108 set disabled(value)
109 {
110 if (value != this._disabled)
111 {
112 let oldValue = this._disabled;
113 this._disabled = value;
114 FilterNotifier.triggerListeners("subscription.disabled", this, value, oldV alue);
115 }
116 return this._disabled;
117 },
118
119 /**
120 * Serializes the subscription to an array of strings for writing out on the d isk.
121 * @param {string[]} buffer buffer to push the serialization results into
122 */
123 serialize: function(buffer)
124 {
125 buffer.push("[Subscription]");
126 buffer.push("url=" + this.url);
127 if (this._title)
128 buffer.push("title=" + this._title);
129 if (this._fixedTitle)
130 buffer.push("fixedTitle=true");
131 if (this._disabled)
132 buffer.push("disabled=true");
133 },
134
135 serializeFilters: function(buffer)
136 {
137 for (let filter of this.filters)
138 buffer.push(filter.text.replace(/\[/g, "\\["));
139 },
140
141 toString: function()
142 {
143 let buffer = [];
144 this.serialize(buffer);
145 return buffer.join("\n");
146 }
147 };
148
149 /**
150 * Cache for known filter subscriptions, maps URL to subscription objects.
151 * @type Object
152 */
153 Subscription.knownSubscriptions = Object.create(null);
154
155 /**
156 * Returns a subscription from its URL, creates a new one if necessary.
157 * @param {String} url URL of the subscription
158 * @return {Subscription} subscription or null if the subscription couldn't be c reated
159 */
160 Subscription.fromURL = function(url)
161 {
162 if (url in Subscription.knownSubscriptions)
163 return Subscription.knownSubscriptions[url];
164
165 if (url[0] != "~")
166 return new DownloadableSubscription(url, null);
167 else
168 return new SpecialSubscription(url);
169 };
170
171 /**
172 * Deserializes a subscription
173 *
174 * @param {Object} obj map of serialized properties and their values
175 * @return {Subscription} subscription or null if the subscription couldn't be c reated
176 */
177 Subscription.fromObject = function(obj)
178 {
179 let result;
180 if (obj.url[0] != "~")
181 {
182 // URL is valid - this is a downloadable subscription
183 result = new DownloadableSubscription(obj.url, obj.title);
184 if ("downloadStatus" in obj)
185 result._downloadStatus = obj.downloadStatus;
186 if ("lastSuccess" in obj)
187 result.lastSuccess = parseInt(obj.lastSuccess, 10) || 0;
188 if ("lastCheck" in obj)
189 result._lastCheck = parseInt(obj.lastCheck, 10) || 0;
190 if ("expires" in obj)
191 result.expires = parseInt(obj.expires, 10) || 0;
192 if ("softExpiration" in obj)
193 result.softExpiration = parseInt(obj.softExpiration, 10) || 0;
194 if ("errors" in obj)
195 result._errors = parseInt(obj.errors, 10) || 0;
196 if ("version" in obj)
197 result.version = parseInt(obj.version, 10) || 0;
198 if ("requiredVersion" in obj)
199 result.requiredVersion = obj.requiredVersion;
200 if ("homepage" in obj)
201 result._homepage = obj.homepage;
202 if ("lastDownload" in obj)
203 result._lastDownload = parseInt(obj.lastDownload, 10) || 0;
204 if ("downloadCount" in obj)
205 result.downloadCount = parseInt(obj.downloadCount, 10) || 0;
206 }
207 else
208 {
209 result = new SpecialSubscription(obj.url, obj.title);
210 if ("defaults" in obj)
211 result.defaults = obj.defaults.split(" ");
212 }
213 if ("fixedTitle" in obj)
214 result._fixedTitle = (obj.fixedTitle == "true");
215 if ("disabled" in obj)
216 result._disabled = (obj.disabled == "true");
217
218 return result;
219 };
220
221 /**
222 * Class for special filter subscriptions (user's filters)
223 * @param {String} url see Subscription()
224 * @param {String} [title] see Subscription()
225 * @constructor
226 * @augments Subscription
227 */
228 function SpecialSubscription(url, title)
229 {
230 Subscription.call(this, url, title);
231 }
232 exports.SpecialSubscription = SpecialSubscription;
233
234 SpecialSubscription.prototype =
235 {
236 __proto__: Subscription.prototype,
237
238 /**
239 * Filter types that should be added to this subscription by default
240 * (entries should correspond to keys in SpecialSubscription.defaultsMap).
241 * @type string[]
242 */
243 defaults: null,
244
245 /**
246 * Tests whether a filter should be added to this group by default
247 * @param {Filter} filter filter to be tested
248 * @return {Boolean}
249 */
250 isDefaultFor: function(filter)
251 {
252 if (this.defaults && this.defaults.length)
253 {
254 for (let type of this.defaults)
255 {
256 if (filter instanceof SpecialSubscription.defaultsMap[type])
257 return true;
258 if (!(filter instanceof ActiveFilter) && type == "blacklist")
259 return true;
260 }
261 }
262
263 return false;
264 },
265
266 /**
267 * See Subscription.serialize()
268 */
269 serialize: function(buffer)
270 {
271 Subscription.prototype.serialize.call(this, buffer);
272 if (this.defaults && this.defaults.length)
273 buffer.push("defaults=" + this.defaults.filter((type) => type in SpecialSu bscription.defaultsMap).join(" "));
274 if (this._lastDownload)
275 buffer.push("lastDownload=" + this._lastDownload);
276 }
277 };
278
279 SpecialSubscription.defaultsMap = {
280 __proto__: null,
281 "whitelist": WhitelistFilter,
282 "blocking": BlockingFilter,
283 "elemhide": ElemHideBase
284 };
285
286 /**
287 * Creates a new user-defined filter group.
288 * @param {String} [title] title of the new filter group
289 * @result {SpecialSubscription}
290 */
291 SpecialSubscription.create = function(title)
292 {
293 let url;
294 do
295 {
296 url = "~user~" + Math.round(Math.random()*1000000);
297 } while (url in Subscription.knownSubscriptions);
298 return new SpecialSubscription(url, title);
299 };
300
301 /**
302 * Creates a new user-defined filter group and adds the given filter to it.
303 * This group will act as the default group for this filter type.
304 */
305 SpecialSubscription.createForFilter = function(/**Filter*/ filter) /**SpecialSub scription*/
306 {
307 let subscription = SpecialSubscription.create();
308 subscription.filters.push(filter);
309 for (let type in SpecialSubscription.defaultsMap)
310 {
311 if (filter instanceof SpecialSubscription.defaultsMap[type])
312 subscription.defaults = [type];
313 }
314 if (!subscription.defaults)
315 subscription.defaults = ["blocking"];
316 return subscription;
317 };
318
319 /**
320 * Abstract base class for regular filter subscriptions (both internally and ext ernally updated)
321 * @param {String} url see Subscription()
322 * @param {String} [title] see Subscription()
323 * @constructor
324 * @augments Subscription
325 */
326 function RegularSubscription(url, title)
327 {
328 Subscription.call(this, url, title || url);
329 }
330 exports.RegularSubscription = RegularSubscription;
331
332 RegularSubscription.prototype =
333 {
334 __proto__: Subscription.prototype,
335
336 _homepage: null,
337 _lastDownload: 0,
338
339 /**
340 * Filter subscription homepage if known
341 * @type String
342 */
343 get homepage()
344 {
345 return this._homepage;
346 },
347 set homepage(value)
348 {
349 if (value != this._homepage)
350 {
351 let oldValue = this._homepage;
352 this._homepage = value;
353 FilterNotifier.triggerListeners("subscription.homepage", this, value, oldV alue);
354 }
355 return this._homepage;
356 },
357
358 /**
359 * Time of the last subscription download (in seconds since the beginning of t he epoch)
360 * @type Number
361 */
362 get lastDownload()
363 {
364 return this._lastDownload;
365 },
366 set lastDownload(value)
367 {
368 if (value != this._lastDownload)
369 {
370 let oldValue = this._lastDownload;
371 this._lastDownload = value;
372 FilterNotifier.triggerListeners("subscription.lastDownload", this, value, oldValue);
373 }
374 return this._lastDownload;
375 },
376
377 /**
378 * See Subscription.serialize()
379 */
380 serialize: function(buffer)
381 {
382 Subscription.prototype.serialize.call(this, buffer);
383 if (this._homepage)
384 buffer.push("homepage=" + this._homepage);
385 if (this._lastDownload)
386 buffer.push("lastDownload=" + this._lastDownload);
387 }
388 };
389
390 /**
391 * Class for filter subscriptions updated externally (by other extension)
392 * @param {String} url see Subscription()
393 * @param {String} [title] see Subscription()
394 * @constructor
395 * @augments RegularSubscription
396 */
397 function ExternalSubscription(url, title)
398 {
399 RegularSubscription.call(this, url, title);
400 }
401 exports.ExternalSubscription = ExternalSubscription;
402
403 ExternalSubscription.prototype =
404 {
405 __proto__: RegularSubscription.prototype,
406
407 /**
408 * See Subscription.serialize()
409 */
410 serialize: function(buffer)
411 {
412 throw new Error("Unexpected call, external subscriptions should not be seria lized");
413 }
414 };
415
416 /**
417 * Class for filter subscriptions updated externally (by other extension)
418 * @param {String} url see Subscription()
419 * @param {String} [title] see Subscription()
420 * @constructor
421 * @augments RegularSubscription
422 */
423 function DownloadableSubscription(url, title)
424 {
425 RegularSubscription.call(this, url, title);
426 }
427 exports.DownloadableSubscription = DownloadableSubscription;
428
429 DownloadableSubscription.prototype =
430 {
431 __proto__: RegularSubscription.prototype,
432
433 _downloadStatus: null,
434 _lastCheck: 0,
435 _errors: 0,
436
437 /**
438 * Status of the last download (ID of a string)
439 * @type String
440 */
441 get downloadStatus()
442 {
443 return this._downloadStatus;
444 },
445 set downloadStatus(value)
446 {
447 let oldValue = this._downloadStatus;
448 this._downloadStatus = value;
449 FilterNotifier.triggerListeners("subscription.downloadStatus", this, value, oldValue);
450 return this._downloadStatus;
451 },
452
453 /**
454 * Time of the last successful download (in seconds since the beginning of the
455 * epoch).
456 */
457 lastSuccess: 0,
458
459 /**
460 * Time when the subscription was considered for an update last time (in secon ds
461 * since the beginning of the epoch). This will be used to increase softExpira tion
462 * if the user doesn't use Adblock Plus for some time.
463 * @type Number
464 */
465 get lastCheck()
466 {
467 return this._lastCheck;
468 },
469 set lastCheck(value)
470 {
471 if (value != this._lastCheck)
472 {
473 let oldValue = this._lastCheck;
474 this._lastCheck = value;
475 FilterNotifier.triggerListeners("subscription.lastCheck", this, value, old Value);
476 }
477 return this._lastCheck;
478 },
479
480 /**
481 * Hard expiration time of the filter subscription (in seconds since the begin ning of the epoch)
482 * @type Number
483 */
484 expires: 0,
485
486 /**
487 * Soft expiration time of the filter subscription (in seconds since the begin ning of the epoch)
488 * @type Number
489 */
490 softExpiration: 0,
491
492 /**
493 * Number of download failures since last success
494 * @type Number
495 */
496 get errors()
497 {
498 return this._errors;
499 },
500 set errors(value)
501 {
502 if (value != this._errors)
503 {
504 let oldValue = this._errors;
505 this._errors = value;
506 FilterNotifier.triggerListeners("subscription.errors", this, value, oldVal ue);
507 }
508 return this._errors;
509 },
510
511 /**
512 * Version of the subscription data retrieved on last successful download
513 * @type Number
514 */
515 version: 0,
516
517 /**
518 * Minimal Adblock Plus version required for this subscription
519 * @type String
520 */
521 requiredVersion: null,
522
523 /**
524 * Number indicating how often the object was downloaded.
525 * @type Number
526 */
527 downloadCount: 0,
528
529 /**
530 * See Subscription.serialize()
531 */
532 serialize: function(buffer)
533 {
534 RegularSubscription.prototype.serialize.call(this, buffer);
535 if (this.downloadStatus)
536 buffer.push("downloadStatus=" + this.downloadStatus);
537 if (this.lastSuccess)
538 buffer.push("lastSuccess=" + this.lastSuccess);
539 if (this.lastCheck)
540 buffer.push("lastCheck=" + this.lastCheck);
541 if (this.expires)
542 buffer.push("expires=" + this.expires);
543 if (this.softExpiration)
544 buffer.push("softExpiration=" + this.softExpiration);
545 if (this.errors)
546 buffer.push("errors=" + this.errors);
547 if (this.version)
548 buffer.push("version=" + this.version);
549 if (this.requiredVersion)
550 buffer.push("requiredVersion=" + this.requiredVersion);
551 if (this.downloadCount)
552 buffer.push("downloadCount=" + this.downloadCount);
553 }
554 };
OLDNEW

Powered by Google App Engine
This is Rietveld