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

Side by Side Diff: lib/abp2blocklist.js

Issue 29439639: Issue 4329 - Add $generichide support (Closed) Base URL: https://hg.adblockplus.org/abp2blocklist
Patch Set: Make matchDomain argument non-optional Created May 20, 2017, 12:16 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
« no previous file with comments | « no previous file | test/abp2blocklist.js » ('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 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 };
OLDNEW
« no previous file with comments | « no previous file | test/abp2blocklist.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld