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

Side by Side Diff: lib/matcher.js

Issue 29375915: Issue 4878 - Start using ESLint for adblockpluscore (Closed)
Patch Set: Created Feb. 20, 2017, 10:02 a.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-2016 Eyeo GmbH 3 * Copyright (C) 2006-2016 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 "use strict";
19
18 /** 20 /**
19 * @fileOverview Matcher class implementing matching addresses against a list of filters. 21 * @fileOverview Matcher class implementing matching addresses against
22 * a list of filters.
20 */ 23 */
21 24
22 let {Filter, RegExpFilter, WhitelistFilter} = require("filterClasses"); 25 let {Filter, RegExpFilter, WhitelistFilter} = require("filterClasses");
23 26
24 /** 27 /**
25 * Blacklist/whitelist filter matching 28 * Blacklist/whitelist filter matching
26 * @constructor 29 * @constructor
27 */ 30 */
28 function Matcher() 31 function Matcher()
29 { 32 {
30 this.clear(); 33 this.clear();
31 } 34 }
32 exports.Matcher = Matcher; 35 exports.Matcher = Matcher;
33 36
34 Matcher.prototype = { 37 Matcher.prototype = {
35 /** 38 /**
36 * Lookup table for filters by their associated keyword 39 * Lookup table for filters by their associated keyword
37 * @type Object 40 * @type {Object}
38 */ 41 */
39 filterByKeyword: null, 42 filterByKeyword: null,
40 43
41 /** 44 /**
42 * Lookup table for keywords by the filter text 45 * Lookup table for keywords by the filter text
43 * @type Object 46 * @type {Object}
44 */ 47 */
45 keywordByFilter: null, 48 keywordByFilter: null,
46 49
47 /** 50 /**
48 * Removes all known filters 51 * Removes all known filters
49 */ 52 */
50 clear: function() 53 clear()
51 { 54 {
52 this.filterByKeyword = Object.create(null); 55 this.filterByKeyword = Object.create(null);
53 this.keywordByFilter = Object.create(null); 56 this.keywordByFilter = Object.create(null);
54 }, 57 },
55 58
56 /** 59 /**
57 * Adds a filter to the matcher 60 * Adds a filter to the matcher
58 * @param {RegExpFilter} filter 61 * @param {RegExpFilter} filter
59 */ 62 */
60 add: function(filter) 63 add(filter)
61 { 64 {
62 if (filter.text in this.keywordByFilter) 65 if (filter.text in this.keywordByFilter)
63 return; 66 return;
64 67
65 // Look for a suitable keyword 68 // Look for a suitable keyword
66 let keyword = this.findKeyword(filter); 69 let keyword = this.findKeyword(filter);
67 let oldEntry = this.filterByKeyword[keyword]; 70 let oldEntry = this.filterByKeyword[keyword];
68 if (typeof oldEntry == "undefined") 71 if (typeof oldEntry == "undefined")
69 this.filterByKeyword[keyword] = filter; 72 this.filterByKeyword[keyword] = filter;
70 else if (oldEntry.length == 1) 73 else if (oldEntry.length == 1)
71 this.filterByKeyword[keyword] = [oldEntry, filter]; 74 this.filterByKeyword[keyword] = [oldEntry, filter];
72 else 75 else
73 oldEntry.push(filter); 76 oldEntry.push(filter);
74 this.keywordByFilter[filter.text] = keyword; 77 this.keywordByFilter[filter.text] = keyword;
75 }, 78 },
76 79
77 /** 80 /**
78 * Removes a filter from the matcher 81 * Removes a filter from the matcher
79 * @param {RegExpFilter} filter 82 * @param {RegExpFilter} filter
80 */ 83 */
81 remove: function(filter) 84 remove(filter)
82 { 85 {
83 if (!(filter.text in this.keywordByFilter)) 86 if (!(filter.text in this.keywordByFilter))
84 return; 87 return;
85 88
86 let keyword = this.keywordByFilter[filter.text]; 89 let keyword = this.keywordByFilter[filter.text];
87 let list = this.filterByKeyword[keyword]; 90 let list = this.filterByKeyword[keyword];
88 if (list.length <= 1) 91 if (list.length <= 1)
89 delete this.filterByKeyword[keyword]; 92 delete this.filterByKeyword[keyword];
90 else 93 else
91 { 94 {
92 let index = list.indexOf(filter); 95 let index = list.indexOf(filter);
93 if (index >= 0) 96 if (index >= 0)
94 { 97 {
95 list.splice(index, 1); 98 list.splice(index, 1);
96 if (list.length == 1) 99 if (list.length == 1)
97 this.filterByKeyword[keyword] = list[0]; 100 this.filterByKeyword[keyword] = list[0];
98 } 101 }
99 } 102 }
100 103
101 delete this.keywordByFilter[filter.text]; 104 delete this.keywordByFilter[filter.text];
102 }, 105 },
103 106
104 /** 107 /**
105 * Chooses a keyword to be associated with the filter 108 * Chooses a keyword to be associated with the filter
106 * @param {String} text text representation of the filter 109 * @param {Filter} filter
107 * @return {String} keyword (might be empty string) 110 * @return {String} keyword
108 */ 111 */
109 findKeyword: function(filter) 112 findKeyword(filter)
110 { 113 {
111 let result = ""; 114 let result = "";
112 let text = filter.text; 115 let {text} = filter;
113 if (Filter.regexpRegExp.test(text)) 116 if (Filter.regexpRegExp.test(text))
114 return result; 117 return result;
115 118
116 // Remove options 119 // Remove options
117 let match = Filter.optionsRegExp.exec(text); 120 let match = Filter.optionsRegExp.exec(text);
118 if (match) 121 if (match)
119 text = match.input.substr(0, match.index); 122 text = match.input.substr(0, match.index);
120 123
121 // Remove whitelist marker 124 // Remove whitelist marker
122 if (text.substr(0, 2) == "@@") 125 if (text.substr(0, 2) == "@@")
123 text = text.substr(2); 126 text = text.substr(2);
124 127
125 let candidates = text.toLowerCase().match(/[^a-z0-9%*][a-z0-9%]{3,}(?=[^a-z0 -9%*])/g); 128 let candidates = text.toLowerCase().match(
129 /[^a-z0-9%*][a-z0-9%]{3,}(?=[^a-z0-9%*])/g
130 );
126 if (!candidates) 131 if (!candidates)
127 return result; 132 return result;
128 133
129 let hash = this.filterByKeyword; 134 let hash = this.filterByKeyword;
130 let resultCount = 0xFFFFFF; 135 let resultCount = 0xFFFFFF;
131 let resultLength = 0; 136 let resultLength = 0;
132 for (let i = 0, l = candidates.length; i < l; i++) 137 for (let i = 0, l = candidates.length; i < l; i++)
133 { 138 {
134 let candidate = candidates[i].substr(1); 139 let candidate = candidates[i].substr(1);
135 let count = (candidate in hash ? hash[candidate].length : 0); 140 let count = (candidate in hash ? hash[candidate].length : 0);
136 if (count < resultCount || (count == resultCount && candidate.length > res ultLength)) 141 if (count < resultCount ||
142 (count == resultCount && candidate.length > resultLength))
137 { 143 {
138 result = candidate; 144 result = candidate;
139 resultCount = count; 145 resultCount = count;
140 resultLength = candidate.length; 146 resultLength = candidate.length;
141 } 147 }
142 } 148 }
143 return result; 149 return result;
144 }, 150 },
145 151
146 /** 152 /**
147 * Checks whether a particular filter is being matched against. 153 * Checks whether a particular filter is being matched against.
154 * @param {RegExpFilter} filter
155 * @return {Boolean}
148 */ 156 */
149 hasFilter: function(/**RegExpFilter*/ filter) /**Boolean*/ 157 hasFilter(filter)
150 { 158 {
151 return (filter.text in this.keywordByFilter); 159 return (filter.text in this.keywordByFilter);
152 }, 160 },
153 161
154 /** 162 /**
155 * Returns the keyword used for a filter, null for unknown filters. 163 * Returns the keyword used for a filter, null for unknown filters.
164 * @param {RegExpFilter} filter
165 * @return {String}
156 */ 166 */
157 getKeywordForFilter: function(/**RegExpFilter*/ filter) /**String*/ 167 getKeywordForFilter(filter)
158 { 168 {
159 if (filter.text in this.keywordByFilter) 169 if (filter.text in this.keywordByFilter)
160 return this.keywordByFilter[filter.text]; 170 return this.keywordByFilter[filter.text];
161 else 171 return null;
162 return null;
163 }, 172 },
164 173
165 /** 174 /**
166 * Checks whether the entries for a particular keyword match a URL 175 * Checks whether the entries for a particular keyword match a URL
176 * @param {String} keyword
177 * @param {String} location
178 * @param {Number} typeMask
179 * @param {String} docDomain
180 * @param {Boolean} thirdParty
181 * @param {String} sitekey
182 * @param {Boolean} specificOnly
183 * @return {Filter|null}
167 */ 184 */
168 _checkEntryMatch: function(keyword, location, typeMask, docDomain, thirdParty, sitekey, specificOnly) 185 _checkEntryMatch(keyword, location, typeMask, docDomain, thirdParty, sitekey,
186 specificOnly)
169 { 187 {
170 let list = this.filterByKeyword[keyword]; 188 let list = this.filterByKeyword[keyword];
171 for (let i = 0; i < list.length; i++) 189 for (let i = 0; i < list.length; i++)
172 { 190 {
173 let filter = list[i]; 191 let filter = list[i];
174 192
175 if (specificOnly && filter.isGeneric() && 193 if (specificOnly && filter.isGeneric() &&
176 !(filter instanceof WhitelistFilter)) 194 !(filter instanceof WhitelistFilter))
177 continue; 195 continue;
178 196
179 if (filter.matches(location, typeMask, docDomain, thirdParty, sitekey)) 197 if (filter.matches(location, typeMask, docDomain, thirdParty, sitekey))
180 return filter; 198 return filter;
181 } 199 }
182 return null; 200 return null;
183 }, 201 },
184 202
185 /** 203 /**
186 * Tests whether the URL matches any of the known filters 204 * Tests whether the URL matches any of the known filters
187 * @param {String} location URL to be tested 205 * @param {String} location URL to be tested
188 * @param {number} typeMask bitmask of content / request types to match 206 * @param {number} typeMask bitmask of content / request types to match
189 * @param {String} docDomain domain name of the document that loads the URL 207 * @param {String} docDomain domain name of the document that loads the URL
190 * @param {Boolean} thirdParty should be true if the URL is a third-party requ est 208 * @param {Boolean} thirdParty should be true if the URL is a third-party
209 * request
191 * @param {String} sitekey public key provided by the document 210 * @param {String} sitekey public key provided by the document
192 * @param {Boolean} specificOnly should be true if generic matches should be i gnored 211 * @param {Boolean} specificOnly should be true if generic matches should be
193 * @return {RegExpFilter} matching filter or null 212 * ignored
213 * @return {RegExpFilter|null} matching filter or null
194 */ 214 */
195 matchesAny: function(location, typeMask, docDomain, thirdParty, sitekey, speci ficOnly) 215 matchesAny(location, typeMask, docDomain, thirdParty, sitekey, specificOnly)
196 { 216 {
197 let candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g); 217 let candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g);
198 if (candidates === null) 218 if (candidates === null)
199 candidates = []; 219 candidates = [];
200 candidates.push(""); 220 candidates.push("");
201 for (let i = 0, l = candidates.length; i < l; i++) 221 for (let i = 0, l = candidates.length; i < l; i++)
202 { 222 {
203 let substr = candidates[i]; 223 let substr = candidates[i];
204 if (substr in this.filterByKeyword) 224 if (substr in this.filterByKeyword)
205 { 225 {
206 let result = this._checkEntryMatch(substr, location, typeMask, docDomain , thirdParty, sitekey, specificOnly); 226 let result = this._checkEntryMatch(substr, location, typeMask,
227 docDomain, thirdParty, sitekey,
228 specificOnly);
207 if (result) 229 if (result)
208 return result; 230 return result;
209 } 231 }
210 } 232 }
211 233
212 return null; 234 return null;
213 } 235 }
214 }; 236 };
215 237
216 /** 238 /**
217 * Combines a matcher for blocking and exception rules, automatically sorts 239 * Combines a matcher for blocking and exception rules, automatically sorts
218 * rules into two Matcher instances. 240 * rules into two Matcher instances.
219 * @constructor 241 * @constructor
220 */ 242 */
221 function CombinedMatcher() 243 function CombinedMatcher()
222 { 244 {
223 this.blacklist = new Matcher(); 245 this.blacklist = new Matcher();
224 this.whitelist = new Matcher(); 246 this.whitelist = new Matcher();
225 this.resultCache = Object.create(null); 247 this.resultCache = Object.create(null);
226 } 248 }
227 exports.CombinedMatcher = CombinedMatcher; 249 exports.CombinedMatcher = CombinedMatcher;
228 250
229 /** 251 /**
230 * Maximal number of matching cache entries to be kept 252 * Maximal number of matching cache entries to be kept
231 * @type Number 253 * @type {Number}
232 */ 254 */
233 CombinedMatcher.maxCacheEntries = 1000; 255 CombinedMatcher.maxCacheEntries = 1000;
234 256
235 CombinedMatcher.prototype = 257 CombinedMatcher.prototype =
236 { 258 {
237 /** 259 /**
238 * Matcher for blocking rules. 260 * Matcher for blocking rules.
239 * @type Matcher 261 * @type {Matcher}
240 */ 262 */
241 blacklist: null, 263 blacklist: null,
242 264
243 /** 265 /**
244 * Matcher for exception rules. 266 * Matcher for exception rules.
245 * @type Matcher 267 * @type {Matcher}
246 */ 268 */
247 whitelist: null, 269 whitelist: null,
248 270
249 /** 271 /**
250 * Lookup table of previous matchesAny results 272 * Lookup table of previous matchesAny results
251 * @type Object 273 * @type {Object}
252 */ 274 */
253 resultCache: null, 275 resultCache: null,
254 276
255 /** 277 /**
256 * Number of entries in resultCache 278 * Number of entries in resultCache
257 * @type Number 279 * @type {Number}
258 */ 280 */
259 cacheEntries: 0, 281 cacheEntries: 0,
260 282
261 /** 283 /**
262 * @see Matcher#clear 284 * @see Matcher#clear
263 */ 285 */
264 clear: function() 286 clear()
265 { 287 {
266 this.blacklist.clear(); 288 this.blacklist.clear();
267 this.whitelist.clear(); 289 this.whitelist.clear();
268 this.resultCache = Object.create(null); 290 this.resultCache = Object.create(null);
269 this.cacheEntries = 0; 291 this.cacheEntries = 0;
270 }, 292 },
271 293
272 /** 294 /**
273 * @see Matcher#add 295 * @see Matcher#add
296 * @param {Filter} filter
274 */ 297 */
275 add: function(filter) 298 add(filter)
276 { 299 {
277 if (filter instanceof WhitelistFilter) 300 if (filter instanceof WhitelistFilter)
278 this.whitelist.add(filter); 301 this.whitelist.add(filter);
279 else 302 else
280 this.blacklist.add(filter); 303 this.blacklist.add(filter);
281 304
282 if (this.cacheEntries > 0) 305 if (this.cacheEntries > 0)
283 { 306 {
284 this.resultCache = Object.create(null); 307 this.resultCache = Object.create(null);
285 this.cacheEntries = 0; 308 this.cacheEntries = 0;
286 } 309 }
287 }, 310 },
288 311
289 /** 312 /**
290 * @see Matcher#remove 313 * @see Matcher#remove
314 * @param {Filter} filter
291 */ 315 */
292 remove: function(filter) 316 remove(filter)
293 { 317 {
294 if (filter instanceof WhitelistFilter) 318 if (filter instanceof WhitelistFilter)
295 this.whitelist.remove(filter); 319 this.whitelist.remove(filter);
296 else 320 else
297 this.blacklist.remove(filter); 321 this.blacklist.remove(filter);
298 322
299 if (this.cacheEntries > 0) 323 if (this.cacheEntries > 0)
300 { 324 {
301 this.resultCache = Object.create(null); 325 this.resultCache = Object.create(null);
302 this.cacheEntries = 0; 326 this.cacheEntries = 0;
303 } 327 }
304 }, 328 },
305 329
306 /** 330 /**
307 * @see Matcher#findKeyword 331 * @see Matcher#findKeyword
332 * @param {Filter} filter
333 * @return {String} keyword
308 */ 334 */
309 findKeyword: function(filter) 335 findKeyword(filter)
310 { 336 {
311 if (filter instanceof WhitelistFilter) 337 if (filter instanceof WhitelistFilter)
312 return this.whitelist.findKeyword(filter); 338 return this.whitelist.findKeyword(filter);
313 else 339 return this.blacklist.findKeyword(filter);
314 return this.blacklist.findKeyword(filter);
315 }, 340 },
316 341
317 /** 342 /**
318 * @see Matcher#hasFilter 343 * @see Matcher#hasFilter
344 * @param {Filter} filter
345 * @return {Boolean}
319 */ 346 */
320 hasFilter: function(filter) 347 hasFilter(filter)
321 { 348 {
322 if (filter instanceof WhitelistFilter) 349 if (filter instanceof WhitelistFilter)
323 return this.whitelist.hasFilter(filter); 350 return this.whitelist.hasFilter(filter);
324 else 351 return this.blacklist.hasFilter(filter);
325 return this.blacklist.hasFilter(filter);
326 }, 352 },
327 353
328 /** 354 /**
329 * @see Matcher#getKeywordForFilter 355 * @see Matcher#getKeywordForFilter
356 * @param {Filter} filter
357 * @return {String} keyword
330 */ 358 */
331 getKeywordForFilter: function(filter) 359 getKeywordForFilter(filter)
332 { 360 {
333 if (filter instanceof WhitelistFilter) 361 if (filter instanceof WhitelistFilter)
334 return this.whitelist.getKeywordForFilter(filter); 362 return this.whitelist.getKeywordForFilter(filter);
335 else 363 return this.blacklist.getKeywordForFilter(filter);
336 return this.blacklist.getKeywordForFilter(filter);
337 }, 364 },
338 365
339 /** 366 /**
340 * Checks whether a particular filter is slow 367 * Checks whether a particular filter is slow
368 * @param {RegExpFilter} filter
369 * @return {Boolean}
341 */ 370 */
342 isSlowFilter: function(/**RegExpFilter*/ filter) /**Boolean*/ 371 isSlowFilter(filter)
343 { 372 {
344 let matcher = (filter instanceof WhitelistFilter ? this.whitelist : this.bla cklist); 373 let matcher = (
374 filter instanceof WhitelistFilter ? this.whitelist : this.blacklist
375 );
345 if (matcher.hasFilter(filter)) 376 if (matcher.hasFilter(filter))
346 return !matcher.getKeywordForFilter(filter); 377 return !matcher.getKeywordForFilter(filter);
347 else 378 return !matcher.findKeyword(filter);
348 return !matcher.findKeyword(filter);
349 }, 379 },
350 380
351 /** 381 /**
352 * Optimized filter matching testing both whitelist and blacklist matchers 382 * Optimized filter matching testing both whitelist and blacklist matchers
353 * simultaneously. For parameters see Matcher.matchesAny(). 383 * simultaneously. For parameters see Matcher.matchesAny().
354 * @see Matcher#matchesAny 384 * @see Matcher#matchesAny
385 * @param {String} location URL to be tested
386 * @param {number} typeMask bitmask of content / request types to match
387 * @param {String} docDomain domain name of the document that loads the URL
388 * @param {Boolean} thirdParty should be true if the URL is a third-party
389 * request
390 * @param {String} sitekey public key provided by the document
391 * @param {Boolean} specificOnly should be true if generic matches should be
392 * ignored
393 * @return {RegExpFilter|null} matching filter or null
355 */ 394 */
356 matchesAnyInternal: function(location, typeMask, docDomain, thirdParty, siteke y, specificOnly) 395 matchesAnyInternal(location, typeMask, docDomain, thirdParty, sitekey,
396 specificOnly)
357 { 397 {
358 let candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g); 398 let candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g);
359 if (candidates === null) 399 if (candidates === null)
360 candidates = []; 400 candidates = [];
361 candidates.push(""); 401 candidates.push("");
362 402
363 let blacklistHit = null; 403 let blacklistHit = null;
364 for (let i = 0, l = candidates.length; i < l; i++) 404 for (let i = 0, l = candidates.length; i < l; i++)
365 { 405 {
366 let substr = candidates[i]; 406 let substr = candidates[i];
367 if (substr in this.whitelist.filterByKeyword) 407 if (substr in this.whitelist.filterByKeyword)
368 { 408 {
369 let result = this.whitelist._checkEntryMatch(substr, location, typeMask, docDomain, thirdParty, sitekey); 409 let result = this.whitelist._checkEntryMatch(
410 substr, location, typeMask, docDomain, thirdParty, sitekey
411 );
370 if (result) 412 if (result)
371 return result; 413 return result;
372 } 414 }
373 if (substr in this.blacklist.filterByKeyword && blacklistHit === null) 415 if (substr in this.blacklist.filterByKeyword && blacklistHit === null)
374 blacklistHit = this.blacklist._checkEntryMatch(substr, location, typeMas k, docDomain, thirdParty, sitekey, specificOnly); 416 {
417 blacklistHit = this.blacklist._checkEntryMatch(
418 substr, location, typeMask, docDomain, thirdParty, sitekey,
419 specificOnly
420 );
421 }
375 } 422 }
376 return blacklistHit; 423 return blacklistHit;
377 }, 424 },
378 425
379 /** 426 /**
380 * @see Matcher#matchesAny 427 * @see Matcher#matchesAny
428 * @param {String} location URL to be tested
429 * @param {number} typeMask bitmask of content / request types to match
430 * @param {String} docDomain domain name of the document that loads the URL
431 * @param {Boolean} thirdParty should be true if the URL is a third-party
432 * request
433 * @param {String} sitekey public key provided by the document
434 * @param {Boolean} specificOnly should be true if generic matches should be
435 * ignored
436 * @return {RegExpFilter} matching filter or null
381 */ 437 */
382 matchesAny: function(location, typeMask, docDomain, thirdParty, sitekey, speci ficOnly) 438 matchesAny(location, typeMask, docDomain, thirdParty, sitekey, specificOnly)
383 { 439 {
384 let key = location + " " + typeMask + " " + docDomain + " " + thirdParty + " " + sitekey + " " + specificOnly; 440 let key = location + " " + typeMask + " " + docDomain + " " + thirdParty +
441 " " + sitekey + " " + specificOnly;
385 if (key in this.resultCache) 442 if (key in this.resultCache)
386 return this.resultCache[key]; 443 return this.resultCache[key];
387 444
388 let result = this.matchesAnyInternal(location, typeMask, docDomain, thirdPar ty, sitekey, specificOnly); 445 let result = this.matchesAnyInternal(location, typeMask, docDomain,
446 thirdParty, sitekey, specificOnly);
389 447
390 if (this.cacheEntries >= CombinedMatcher.maxCacheEntries) 448 if (this.cacheEntries >= CombinedMatcher.maxCacheEntries)
391 { 449 {
392 this.resultCache = Object.create(null); 450 this.resultCache = Object.create(null);
393 this.cacheEntries = 0; 451 this.cacheEntries = 0;
394 } 452 }
395 453
396 this.resultCache[key] = result; 454 this.resultCache[key] = result;
397 this.cacheEntries++; 455 this.cacheEntries++;
398 456
399 return result; 457 return result;
400 } 458 }
401 } 459 };
402 460
403 /** 461 /**
404 * Shared CombinedMatcher instance that should usually be used. 462 * Shared CombinedMatcher instance that should usually be used.
405 * @type CombinedMatcher 463 * @type {CombinedMatcher}
406 */ 464 */
407 let defaultMatcher = exports.defaultMatcher = new CombinedMatcher(); 465 let defaultMatcher = exports.defaultMatcher = new CombinedMatcher();
OLDNEW
« lib/filterStorage.js ('K') | « lib/filterStorage.js ('k') | lib/notification.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld