| 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-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 332 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 343   { | 343   { | 
| 344     newSelector.push(selector.substring(i, pos.start)); | 344     newSelector.push(selector.substring(i, pos.start)); | 
| 345     newSelector.push('[id=', selector.substring(pos.start + 1, pos.end), ']'); | 345     newSelector.push('[id=', selector.substring(pos.start + 1, pos.end), ']'); | 
| 346     i = pos.end; | 346     i = pos.end; | 
| 347   } | 347   } | 
| 348   newSelector.push(selector.substring(i)); | 348   newSelector.push(selector.substring(i)); | 
| 349 | 349 | 
| 350   return newSelector.join(""); | 350   return newSelector.join(""); | 
| 351 } | 351 } | 
| 352 | 352 | 
|  | 353 function addCSSRules(rules, selectors, matchDomain) | 
|  | 354 { | 
|  | 355   while (selectors.length) | 
|  | 356   { | 
|  | 357     let selector = selectors.splice(0, selectorLimit).join(", "); | 
|  | 358 | 
|  | 359     // As of Safari 9.0 element IDs are matched as lowercase. We work around | 
|  | 360     // this by converting to the attribute format [id="elementID"] | 
|  | 361     selector = convertIDSelectorsToAttributeSelectors(selector); | 
|  | 362 | 
|  | 363     rules.push({ | 
|  | 364       trigger: {"url-filter": matchDomain, | 
|  | 365                 "url-filter-is-case-sensitive": true}, | 
|  | 366       action: {type: "css-display-none", | 
|  | 367                selector: selector} | 
|  | 368     }); | 
|  | 369   } | 
|  | 370 } | 
|  | 371 | 
| 353 let ContentBlockerList = | 372 let ContentBlockerList = | 
| 354 /** | 373 /** | 
| 355  * Create a new Adblock Plus filter to content blocker list converter | 374  * Create a new Adblock Plus filter to content blocker list converter | 
| 356  * | 375  * | 
| 357  * @constructor | 376  * @constructor | 
| 358  */ | 377  */ | 
| 359 exports.ContentBlockerList = function () | 378 exports.ContentBlockerList = function () | 
| 360 { | 379 { | 
| 361   this.requestFilters = []; | 380   this.requestFilters = []; | 
| 362   this.requestExceptions = []; | 381   this.requestExceptions = []; | 
| 363   this.elemhideFilters = []; | 382   this.elemhideFilters = []; | 
| 364   this.elemhideExceptions =  []; | 383   this.elemhideExceptions =  []; | 
|  | 384   this.generichideExceptions = []; | 
| 365   this.elemhideSelectorExceptions = new Map(); | 385   this.elemhideSelectorExceptions = new Map(); | 
| 366 }; | 386 }; | 
| 367 | 387 | 
| 368 /** | 388 /** | 
| 369  * Add Adblock Plus filter to be converted | 389  * Add Adblock Plus filter to be converted | 
| 370  * | 390  * | 
| 371  * @param {Filter} filter Filter to convert | 391  * @param {Filter} filter Filter to convert | 
| 372  */ | 392  */ | 
| 373 ContentBlockerList.prototype.addFilter = function(filter) | 393 ContentBlockerList.prototype.addFilter = function(filter) | 
| 374 { | 394 { | 
| 375   if (filter.sitekeys) | 395   if (filter.sitekeys) | 
| 376     return; | 396     return; | 
| 377   if (filter instanceof filterClasses.RegExpFilter && | 397   if (filter instanceof filterClasses.RegExpFilter && | 
| 378       filter.regexpSource == null) | 398       filter.regexpSource == null) | 
| 379     return; | 399     return; | 
| 380 | 400 | 
| 381   if (filter instanceof filterClasses.BlockingFilter) | 401   if (filter instanceof filterClasses.BlockingFilter) | 
| 382     this.requestFilters.push(filter); | 402     this.requestFilters.push(filter); | 
| 383 | 403 | 
| 384   if (filter instanceof filterClasses.WhitelistFilter) | 404   if (filter instanceof filterClasses.WhitelistFilter) | 
| 385   { | 405   { | 
| 386     if (filter.contentType & (typeMap.DOCUMENT | whitelistableRequestTypes)) | 406     if (filter.contentType & (typeMap.DOCUMENT | whitelistableRequestTypes)) | 
| 387       this.requestExceptions.push(filter); | 407       this.requestExceptions.push(filter); | 
| 388 | 408 | 
| 389       if (filter.contentType & typeMap.ELEMHIDE) | 409     if (filter.contentType & typeMap.ELEMHIDE) | 
| 390         this.elemhideExceptions.push(filter); | 410       this.elemhideExceptions.push(filter); | 
|  | 411     else if (filter.contentType & typeMap.GENERICHIDE) | 
|  | 412       this.generichideExceptions.push(filter); | 
| 391   } | 413   } | 
| 392 | 414 | 
| 393   if (filter instanceof filterClasses.ElemHideFilter) | 415   if (filter instanceof filterClasses.ElemHideFilter) | 
| 394     this.elemhideFilters.push(filter); | 416     this.elemhideFilters.push(filter); | 
| 395 | 417 | 
| 396   if (filter instanceof filterClasses.ElemHideException) | 418   if (filter instanceof filterClasses.ElemHideException) | 
| 397   { | 419   { | 
| 398     let domains = this.elemhideSelectorExceptions[filter.selector]; | 420     let domains = this.elemhideSelectorExceptions[filter.selector]; | 
| 399     if (!domains) | 421     if (!domains) | 
| 400       domains = this.elemhideSelectorExceptions[filter.selector] = []; | 422       domains = this.elemhideSelectorExceptions[filter.selector] = []; | 
| 401 | 423 | 
| 402     parseDomains(filter.domains, domains, []); | 424     parseDomains(filter.domains, domains, []); | 
| 403   } | 425   } | 
| 404 }; | 426 }; | 
| 405 | 427 | 
| 406 /** | 428 /** | 
| 407  * Generate content blocker list for all filters that were added | 429  * Generate content blocker list for all filters that were added | 
| 408  * | 430  * | 
| 409  * @returns   {Filter}   filter    Filter to convert | 431  * @returns   {Filter}   filter    Filter to convert | 
| 410  */ | 432  */ | 
| 411 ContentBlockerList.prototype.generateRules = function(filter) | 433 ContentBlockerList.prototype.generateRules = function(filter) | 
| 412 { | 434 { | 
| 413   let rules = []; | 435   let rules = []; | 
| 414 | 436 | 
|  | 437   let genericSelectors = []; | 
| 415   let groupedElemhideFilters = new Map(); | 438   let groupedElemhideFilters = new Map(); | 
|  | 439 | 
| 416   for (let filter of this.elemhideFilters) | 440   for (let filter of this.elemhideFilters) | 
| 417   { | 441   { | 
| 418     let result = convertElemHideFilter(filter, this.elemhideSelectorExceptions); | 442     let result = convertElemHideFilter(filter, this.elemhideSelectorExceptions); | 
| 419     if (!result) | 443     if (!result) | 
| 420       continue; | 444       continue; | 
| 421 | 445 | 
| 422     if (result.matchDomains.length == 0) | 446     if (result.matchDomains.length == 0) | 
| 423       result.matchDomains = ["^https?://"]; |  | 
| 424 |  | 
| 425     for (let matchDomain of result.matchDomains) |  | 
| 426     { | 447     { | 
| 427       let group = groupedElemhideFilters.get(matchDomain) || []; | 448       genericSelectors.push(result.selector); | 
| 428       group.push(result.selector); | 449     } | 
| 429       groupedElemhideFilters.set(matchDomain, group); | 450     else | 
|  | 451     { | 
|  | 452       for (let matchDomain of result.matchDomains) | 
|  | 453       { | 
|  | 454         let group = groupedElemhideFilters.get(matchDomain) || []; | 
|  | 455         group.push(result.selector); | 
|  | 456         groupedElemhideFilters.set(matchDomain, group); | 
|  | 457       } | 
| 430     } | 458     } | 
| 431   } | 459   } | 
| 432 | 460 | 
|  | 461   addCSSRules(rules, genericSelectors, "^https?://"); | 
|  | 462 | 
|  | 463   // Right after the generic element hiding filters, add the exceptions that | 
|  | 464   // should apply only to those filters. | 
|  | 465   for (let filter of this.generichideExceptions) | 
|  | 466     convertFilterAddRules(rules, filter, "ignore-previous-rules", false); | 
|  | 467 | 
| 433   groupedElemhideFilters.forEach((selectors, matchDomain) => | 468   groupedElemhideFilters.forEach((selectors, matchDomain) => | 
| 434   { | 469   { | 
| 435     while (selectors.length) | 470     addCSSRules(rules, selectors, matchDomain); | 
| 436     { |  | 
| 437       let selector = selectors.splice(0, selectorLimit).join(", "); |  | 
| 438 |  | 
| 439       // As of Safari 9.0 element IDs are matched as lowercase. We work around |  | 
| 440       // this by converting to the attribute format [id="elementID"] |  | 
| 441       selector = convertIDSelectorsToAttributeSelectors(selector); |  | 
| 442 |  | 
| 443       rules.push({ |  | 
| 444         trigger: {"url-filter": matchDomain, |  | 
| 445                   "url-filter-is-case-sensitive": true}, |  | 
| 446         action: {type: "css-display-none", |  | 
| 447                  selector: selector} |  | 
| 448       }); |  | 
| 449     } |  | 
| 450   }); | 471   }); | 
| 451 | 472 | 
| 452   for (let filter of this.elemhideExceptions) | 473   for (let filter of this.elemhideExceptions) | 
| 453     convertFilterAddRules(rules, filter, "ignore-previous-rules", false); | 474     convertFilterAddRules(rules, filter, "ignore-previous-rules", false); | 
| 454   for (let filter of this.requestFilters) | 475   for (let filter of this.requestFilters) | 
| 455     convertFilterAddRules(rules, filter, "block", true); | 476     convertFilterAddRules(rules, filter, "block", true); | 
| 456   for (let filter of this.requestExceptions) | 477   for (let filter of this.requestExceptions) | 
| 457     convertFilterAddRules(rules, filter, "ignore-previous-rules", true); | 478     convertFilterAddRules(rules, filter, "ignore-previous-rules", true); | 
| 458 | 479 | 
| 459   return rules.filter(rule => !hasNonASCI(rule)); | 480   return rules.filter(rule => !hasNonASCI(rule)); | 
| 460 }; | 481 }; | 
| OLD | NEW | 
|---|