| Index: lib/filterClasses.js | 
| =================================================================== | 
| --- a/lib/filterClasses.js | 
| +++ b/lib/filterClasses.js | 
| @@ -921,16 +921,19 @@ | 
| selectorDomain: null, | 
| /** | 
| * CSS selector for the HTML elements that should be hidden | 
| * @type {string} | 
| */ | 
| selector: null | 
| }); | 
|  | 
| +const abpSelectorRegExp = /\[-abp-selector=(["'])(.+)\1\]/; | 
| +const abpPropertySelectorRegExp = /\[-abp-properties=(["'])([^"']+)\1\]/; | 
| + | 
| /** | 
| * 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 (can be empty) | 
| * @param {boolean} isException exception rule indicator | 
| * @param {string} tagName      tag name part (can be empty) | 
| @@ -980,20 +983,48 @@ | 
| } | 
|  | 
| // We don't allow ElemHide filters which have any empty domains. | 
| // Note: The ElemHide.prototype.domainSeparator is duplicated here, if that | 
| // changes this must be changed too. | 
| if (domain && /(^|,)~?(,|$)/.test(domain)) | 
| return new InvalidFilter(text, "filter_invalid_domain"); | 
|  | 
| +  let isHideEmulation = false; | 
| +  if ((selector.indexOf("[-abp-properties=") != -1) || | 
| +      (selector.indexOf("[-abp-selector=") != -1)) | 
| +  { | 
| +    isHideEmulation = true; | 
| + | 
| +    // Element hiding emulation filters are inefficient so we need to make sure | 
| +    // that they're only applied if they specify active domains | 
| +    if (!/,[^~][^,.]*\.[^,]/.test("," + domain)) | 
| +      return new InvalidFilter(text, "filter_elemhideemulation_nodomain"); | 
| + | 
| +    let match = abpSelectorRegExp.exec(selector); | 
| +    if (match) | 
| +    { | 
| +      let prefix = selector.substr(0, match.index); | 
| +      let suffix = selector.substr(match.index + match[0].length); | 
| +      selector = prefix + match[2] + suffix; | 
| +    } | 
| +    match = abpPropertySelectorRegExp.exec(selector); | 
| +    if (match) | 
| +    { | 
| +      let prefix = selector.substr(0, match.index); | 
| +      let suffix = selector.substr(match.index + match[0].length); | 
| +      selector = prefix + ":-abp-properties(" + | 
| +        match[1] + match[2] + match[1] + ")" + suffix; | 
| +    } | 
| +  } | 
| + | 
| if (isException) | 
| return new ElemHideException(text, domain, selector); | 
|  | 
| -  if (selector.indexOf("[-abp-properties=") != -1) | 
| +  if (isHideEmulation) | 
| { | 
| // Element hiding emulation filters are inefficient so we need to make sure | 
| // that they're only applied if they specify active domains | 
| if (!/,[^~][^,.]*\.[^,]/.test("," + domain)) | 
| return new InvalidFilter(text, "filter_elemhideemulation_nodomain"); | 
|  | 
| return new ElemHideEmulationFilter(text, domain, selector); | 
| } | 
|  |