LEFT | RIGHT |
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 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 | 233 |
234 for (let type of nonDefaultTypes(filter.contentType)) | 234 for (let type of nonDefaultTypes(filter.contentType)) |
235 { | 235 { |
236 let map = this._filterMapsByType.get(type); | 236 let map = this._filterMapsByType.get(type); |
237 if (!map) | 237 if (!map) |
238 this._filterMapsByType.set(type, map = new Map()); | 238 this._filterMapsByType.set(type, map = new Map()); |
239 | 239 |
240 addFilterByKeyword(filter, keyword, map); | 240 addFilterByKeyword(filter, keyword, map); |
241 } | 241 } |
242 | 242 |
| 243 let {domains} = filter; |
| 244 |
243 let filtersByDomain = this._filterDomainMapsByKeyword.get(keyword); | 245 let filtersByDomain = this._filterDomainMapsByKeyword.get(keyword); |
244 if (!filtersByDomain) | 246 if (!filtersByDomain) |
245 this._filterDomainMapsByKeyword.set(keyword, filtersByDomain = new Map()); | 247 { |
246 | 248 // In most cases, there is only one pure generic filter to a keyword. |
247 for (let [domain, include] of filter.domains || defaultDomains) | 249 // Instead of Map { "foo" => Map { "" => Map { filter => true } } }, we |
| 250 // can just reduce it to Map { "foo" => filter } and save a lot of |
| 251 // memory. |
| 252 if (!domains) |
| 253 { |
| 254 this._filterDomainMapsByKeyword.set(keyword, filter); |
| 255 return; |
| 256 } |
| 257 |
| 258 filtersByDomain = new Map(); |
| 259 this._filterDomainMapsByKeyword.set(keyword, filtersByDomain); |
| 260 } |
| 261 else if (!(filtersByDomain instanceof Map)) |
| 262 { |
| 263 filtersByDomain = new Map([["", filtersByDomain]]); |
| 264 this._filterDomainMapsByKeyword.set(keyword, filtersByDomain); |
| 265 } |
| 266 |
| 267 for (let [domain, include] of domains || defaultDomains) |
248 { | 268 { |
249 if (!include && domain == "") | 269 if (!include && domain == "") |
250 continue; | 270 continue; |
251 | 271 |
252 let map = filtersByDomain.get(domain); | 272 let map = filtersByDomain.get(domain); |
253 if (!map) | 273 if (!map) |
254 { | 274 { |
255 filtersByDomain.set(domain, include ? filter : | 275 filtersByDomain.set(domain, include ? filter : |
256 map = new Map([[filter, false]])); | 276 map = new Map([[filter, false]])); |
257 } | 277 } |
258 else if (map.size == 1 && !(map instanceof Map)) | 278 else if (map.size == 1 && !(map instanceof Map)) |
259 { | 279 { |
260 if (filter != map) | 280 if (filter != map) |
261 { | 281 { |
262 filtersByDomain.set(domain, new Map([[map, true], | 282 filtersByDomain.set(domain, new Map([[map, true], |
263 [filter, include]])); | 283 [filter, include]])); |
264 } | 284 } |
265 } | 285 } |
266 else | 286 else |
(...skipping 27 matching lines...) Expand all Loading... |
294 for (let type of nonDefaultTypes(filter.contentType)) | 314 for (let type of nonDefaultTypes(filter.contentType)) |
295 { | 315 { |
296 let map = this._filterMapsByType.get(type); | 316 let map = this._filterMapsByType.get(type); |
297 if (map) | 317 if (map) |
298 removeFilterByKeyword(filter, keyword, map); | 318 removeFilterByKeyword(filter, keyword, map); |
299 } | 319 } |
300 | 320 |
301 let filtersByDomain = this._filterDomainMapsByKeyword.get(keyword); | 321 let filtersByDomain = this._filterDomainMapsByKeyword.get(keyword); |
302 if (filtersByDomain) | 322 if (filtersByDomain) |
303 { | 323 { |
| 324 // Because of the memory optimization in the add function, most of the |
| 325 // time this will be a filter rather than a map. |
| 326 if (!(filtersByDomain instanceof Map)) |
| 327 { |
| 328 this._filterDomainMapsByKeyword.delete(keyword); |
| 329 return; |
| 330 } |
| 331 |
304 let domains = filter.domains || defaultDomains; | 332 let domains = filter.domains || defaultDomains; |
305 for (let domain of domains.keys()) | 333 for (let domain of domains.keys()) |
306 { | 334 { |
307 let map = filtersByDomain.get(domain); | 335 let map = filtersByDomain.get(domain); |
308 if (map) | 336 if (map) |
309 { | 337 { |
310 if (map.size > 1 || map instanceof Map) | 338 if (map.size > 1 || map instanceof Map) |
311 { | 339 { |
312 map.delete(filter); | 340 map.delete(filter); |
313 | 341 |
314 if (map.size == 0) | 342 if (map.size == 0) |
| 343 { |
315 filtersByDomain.delete(domain); | 344 filtersByDomain.delete(domain); |
| 345 } |
| 346 else if (map.size == 1) |
| 347 { |
| 348 for (let [lastFilter, include] of map) |
| 349 { |
| 350 // Reduce Map { "example.com" => Map { filter => true } } to |
| 351 // Map { "example.com" => filter } |
| 352 if (include) |
| 353 filtersByDomain.set(domain, lastFilter); |
| 354 |
| 355 break; |
| 356 } |
| 357 } |
316 } | 358 } |
317 else if (filter == map) | 359 else if (filter == map) |
318 { | 360 { |
319 filtersByDomain.delete(domain); | 361 filtersByDomain.delete(domain); |
320 } | 362 } |
| 363 } |
| 364 } |
| 365 |
| 366 if (filtersByDomain.size == 0) |
| 367 { |
| 368 this._filterDomainMapsByKeyword.delete(keyword); |
| 369 } |
| 370 else if (filtersByDomain.size == 1) |
| 371 { |
| 372 for (let [lastDomain, map] of filtersByDomain) |
| 373 { |
| 374 // Reduce Map { "foo" => Map { "" => filter } } to |
| 375 // Map { "foo" => filter } |
| 376 if (lastDomain == "" && !(map instanceof Map)) |
| 377 this._filterDomainMapsByKeyword.set(keyword, map); |
| 378 |
| 379 break; |
321 } | 380 } |
322 } | 381 } |
323 } | 382 } |
324 } | 383 } |
325 | 384 |
326 /** | 385 /** |
327 * Chooses a keyword to be associated with the filter | 386 * Chooses a keyword to be associated with the filter |
328 * @param {Filter} filter | 387 * @param {Filter} filter |
329 * @returns {string} keyword or an empty string if no keyword could be found | 388 * @returns {string} keyword or an empty string if no keyword could be found |
330 * @protected | 389 * @protected |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 | 476 |
418 return null; | 477 return null; |
419 } | 478 } |
420 | 479 |
421 _checkEntryMatchByDomain(keyword, location, typeMask, docDomain, thirdParty, | 480 _checkEntryMatchByDomain(keyword, location, typeMask, docDomain, thirdParty, |
422 sitekey, specificOnly, collection) | 481 sitekey, specificOnly, collection) |
423 { | 482 { |
424 let filtersByDomain = this._filterDomainMapsByKeyword.get(keyword); | 483 let filtersByDomain = this._filterDomainMapsByKeyword.get(keyword); |
425 if (filtersByDomain) | 484 if (filtersByDomain) |
426 { | 485 { |
427 // The code in this block is similar to the generateStyleSheetForDomain | 486 // Because of the memory optimization in the add function, most of the |
428 // function in lib/elemHide.js. | 487 // time this will be a filter rather than a map. |
| 488 if (!(filtersByDomain instanceof Map)) |
| 489 { |
| 490 if (filtersByDomain.matchesWithoutDomain(location, typeMask, |
| 491 thirdParty, sitekey)) |
| 492 { |
| 493 if (!collection) |
| 494 return filtersByDomain; |
| 495 |
| 496 collection.push(filtersByDomain); |
| 497 } |
| 498 |
| 499 return null; |
| 500 } |
429 | 501 |
430 let excluded = new Set(); | 502 let excluded = new Set(); |
431 | 503 |
432 for (let suffix of suffixes(docDomain ? normalizeHostname(docDomain) : "", | 504 for (let suffix of suffixes(docDomain ? normalizeHostname(docDomain) : "", |
433 !specificOnly)) | 505 !specificOnly)) |
434 { | 506 { |
435 let filters = filtersByDomain.get(suffix); | 507 let filters = filtersByDomain.get(suffix); |
436 if (filters) | 508 if (filters) |
437 { | 509 { |
438 for (let [filter, include] of filters.entries()) | 510 for (let [filter, include] of filters.entries()) |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
814 | 886 |
815 exports.CombinedMatcher = CombinedMatcher; | 887 exports.CombinedMatcher = CombinedMatcher; |
816 | 888 |
817 /** | 889 /** |
818 * Shared {@link CombinedMatcher} instance that should usually be used. | 890 * Shared {@link CombinedMatcher} instance that should usually be used. |
819 * @type {CombinedMatcher} | 891 * @type {CombinedMatcher} |
820 */ | 892 */ |
821 let defaultMatcher = new CombinedMatcher(); | 893 let defaultMatcher = new CombinedMatcher(); |
822 | 894 |
823 exports.defaultMatcher = defaultMatcher; | 895 exports.defaultMatcher = defaultMatcher; |
LEFT | RIGHT |