 Issue 29737558:
  Issue 6538, 6781 - Implement support for snippet filters  (Closed) 
  Base URL: https://hg.adblockplus.org/adblockpluscore/
    
  
    Issue 29737558:
  Issue 6538, 6781 - Implement support for snippet filters  (Closed) 
  Base URL: https://hg.adblockplus.org/adblockpluscore/| Index: lib/filterClasses.js | 
| =================================================================== | 
| --- a/lib/filterClasses.js | 
| +++ b/lib/filterClasses.js | 
| @@ -79,20 +79,20 @@ | 
| /** | 
| * Cache for known filters, maps string representation to filter objects. | 
| * @type {Map.<string,Filter>} | 
| */ | 
| Filter.knownFilters = new Map(); | 
| /** | 
| - * Regular expression that element hiding filters should match | 
| + * Regular expression that code injection filters should match | 
| * @type {RegExp} | 
| */ | 
| -Filter.elemhideRegExp = /^([^/*|@"!]*?)#([@?])?#(.+)$/; | 
| +Filter.codeInjectionRegExp = /^([^/*|@"!]*?)#([@?$])?#(.+)$/; | 
| /** | 
| * Regular expression that RegExp filters specified as RegExps should match | 
| * @type {RegExp} | 
| */ | 
| Filter.regexpRegExp = /^(@@)?\/.*\/(?:\$~?[\w-]+(?:=[^,\s]+)?(?:,~?[\w-]+(?:=[^,\s]+)?)*)?$/; | 
| /** | 
| * Regular expression that options on a RegExp filter should match | 
| * @type {RegExp} | 
| @@ -112,31 +112,34 @@ | 
| * @return {Filter} | 
| */ | 
| Filter.fromText = function(text) | 
| { | 
| let filter = Filter.knownFilters.get(text); | 
| if (filter) | 
| return filter; | 
| - let match = (text.includes("#") ? Filter.elemhideRegExp.exec(text) : null); | 
| + let match = text.includes("#") ? Filter.codeInjectionRegExp.exec(text) : null; | 
| if (match) | 
| { | 
| let propsMatch; | 
| if (!match[2] && | 
| (propsMatch = /\[-abp-properties=(["'])([^"']+)\1\]/.exec(match[3]))) | 
| { | 
| // This is legacy CSS properties syntax, convert to current syntax | 
| let prefix = match[3].substr(0, propsMatch.index); | 
| let expression = propsMatch[2]; | 
| let suffix = match[3].substr(propsMatch.index + propsMatch[0].length); | 
| return Filter.fromText(`${match[1]}#?#` + | 
| `${prefix}:-abp-properties(${expression})${suffix}`); | 
| } | 
| + if (match[2] == "$") | 
| + return new SnippetFilter(text, match[1], match[3]); | 
| 
hub
2018/05/03 22:59:38
Here you shouldn't return, but rather assign it to
 
Manish Jethani
2018/05/07 19:03:27
Done.
 | 
| + | 
| filter = ElemHideBase.fromText( | 
| text, match[1], match[2], match[3] | 
| ); | 
| } | 
| else if (text[0] == "!") | 
| filter = new CommentFilter(text); | 
| else | 
| filter = RegExpFilter.fromText(text); | 
| @@ -179,22 +182,22 @@ | 
| // Remove line breaks, tabs etc | 
| text = text.replace(/[^\S ]+/g, ""); | 
| // Don't remove spaces inside comments | 
| if (/^ *!/.test(text)) | 
| return text.trim(); | 
| - // Special treatment for element hiding filters, right side is allowed to | 
| + // Special treatment for code injection filters, right side is allowed to | 
| // contain spaces | 
| - if (Filter.elemhideRegExp.test(text)) | 
| + if (Filter.codeInjectionRegExp.test(text)) | 
| { | 
| - let [, domain, separator, selector] = /^(.*?)(#[@?]?#?)(.*)$/.exec(text); | 
| - return domain.replace(/ +/g, "") + separator + selector.trim(); | 
| + let [, domain, separator, code] = /^(.*?)(#[@?$]?#?)(.*)$/.exec(text); | 
| + return domain.replace(/ +/g, "") + separator + code.trim(); | 
| } | 
| // For most regexp filters we strip all spaces, but $csp filter options | 
| // are allowed to contain single (non trailing) spaces. | 
| let strippedText = text.replace(/ +/g, ""); | 
| if (!strippedText.includes("$") || !/\bcsp=/i.test(strippedText)) | 
| return strippedText; | 
| @@ -945,65 +948,84 @@ | 
| } | 
| exports.WhitelistFilter = WhitelistFilter; | 
| WhitelistFilter.prototype = extend(RegExpFilter, { | 
| type: "whitelist" | 
| }); | 
| /** | 
| - * Base class for element hiding filters | 
| + * Base class for code injection filters | 
| * @param {string} text see Filter() | 
| * @param {string} [domains] Host names or domains the filter should be | 
| * restricted to | 
| - * @param {string} selector CSS selector for the HTML elements that should be | 
| - * hidden | 
| + * @param {string} code Code that should be injected | 
| * @constructor | 
| * @augments ActiveFilter | 
| */ | 
| -function ElemHideBase(text, domains, selector) | 
| +function CodeInjectionFilter(text, domains, code) | 
| { | 
| ActiveFilter.call(this, text, domains || null); | 
| if (domains) | 
| { | 
| - this.selectorDomain = domains.replace(/,~[^,]+/g, "") | 
| - .replace(/^~[^,]+,?/, "").toLowerCase(); | 
| + this.injectionDomain = domains.replace(/,~[^,]+/g, "") | 
| + .replace(/^~[^,]+,?/, "").toLowerCase(); | 
| } | 
| - // Braces are being escaped to prevent CSS rule injection. | 
| - this.selector = selector.replace("{", "\\7B ").replace("}", "\\7D "); | 
| + this.code = code; | 
| } | 
| -exports.ElemHideBase = ElemHideBase; | 
| +exports.CodeInjectionFilter = CodeInjectionFilter; | 
| -ElemHideBase.prototype = extend(ActiveFilter, { | 
| +CodeInjectionFilter.prototype = extend(ActiveFilter, { | 
| /** | 
| * @see ActiveFilter.domainSeparator | 
| */ | 
| domainSeparator: ",", | 
| /** | 
| * @see ActiveFilter.ignoreTrailingDot | 
| */ | 
| ignoreTrailingDot: false, | 
| /** | 
| * Host name or domain the filter should be restricted to (can be null for | 
| * no restriction) | 
| * @type {string} | 
| */ | 
| - selectorDomain: null, | 
| + injectionDomain: null, | 
| + | 
| /** | 
| - * CSS selector for the HTML elements that should be hidden | 
| + * Code that should be injected | 
| * @type {string} | 
| */ | 
| - selector: null | 
| + code: null | 
| }); | 
| /** | 
| + * Base class for element hiding filters | 
| + * @param {string} text see Filter() | 
| + * @param {string} [domains] see CodeInjectionFilter() | 
| + * @param {string} selector CSS selector for the HTML elements that should be | 
| + * hidden | 
| + * @constructor | 
| + * @augments CodeInjectionFilter | 
| + */ | 
| +function ElemHideBase(text, domains, selector) | 
| +{ | 
| + CodeInjectionFilter.call(this, text, domains, selector); | 
| + | 
| + // Braces are being escaped to prevent CSS rule injection. | 
| + this.code = this.code.replace("{", "\\7B ").replace("}", "\\7D "); | 
| +} | 
| +exports.ElemHideBase = ElemHideBase; | 
| + | 
| +ElemHideBase.prototype = extend(CodeInjectionFilter, {}); | 
| + | 
| +/** | 
| * Creates an element hiding filter from a pre-parsed text representation | 
| * | 
| * @param {string} text same as in Filter() | 
| * @param {string?} domain | 
| * domain part of the text representation | 
| * @param {string?} type | 
| * rule type, either empty or @ (exception) or ? (emulation rule) | 
| * @param {string} selector raw CSS selector | 
| @@ -1082,8 +1104,26 @@ | 
| { | 
| ElemHideBase.call(this, text, domains, selector); | 
| } | 
| exports.ElemHideEmulationFilter = ElemHideEmulationFilter; | 
| ElemHideEmulationFilter.prototype = extend(ElemHideBase, { | 
| type: "elemhideemulation" | 
| }); | 
| + | 
| +/** | 
| + * Class for snippet filters | 
| + * @param {string} text see Filter() | 
| + * @param {string} [domains] see CodeInjectionFilter() | 
| + * @param {string} script Script that should be executed | 
| + * @constructor | 
| + * @augments CodeInjectionFilter | 
| + */ | 
| +function SnippetFilter(text, domains, script) | 
| +{ | 
| + CodeInjectionFilter.call(this, text, domains, script); | 
| +} | 
| +exports.SnippetFilter = SnippetFilter; | 
| + | 
| +SnippetFilter.prototype = extend(CodeInjectionFilter, { | 
| + type: "snippet" | 
| +}); |