Left: | ||
Right: |
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-2016 Eyeo GmbH | 3 * Copyright (C) 2006-2016 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
93 * @type {RegExp} | 93 * @type {RegExp} |
94 */ | 94 */ |
95 Filter.regexpRegExp = /^(@@)?\/.*\/(?:\$~?[\w-]+(?:=[^,\s]+)?(?:,~?[\w-]+(?:=[^, \s]+)?)*)?$/; | 95 Filter.regexpRegExp = /^(@@)?\/.*\/(?:\$~?[\w-]+(?:=[^,\s]+)?(?:,~?[\w-]+(?:=[^, \s]+)?)*)?$/; |
96 /** | 96 /** |
97 * Regular expression that options on a RegExp filter should match | 97 * Regular expression that options on a RegExp filter should match |
98 * @type {RegExp} | 98 * @type {RegExp} |
99 */ | 99 */ |
100 Filter.optionsRegExp = /\$(~?[\w-]+(?:=[^,\s]+)?(?:,~?[\w-]+(?:=[^,\s]+)?)*)$/; | 100 Filter.optionsRegExp = /\$(~?[\w-]+(?:=[^,\s]+)?(?:,~?[\w-]+(?:=[^,\s]+)?)*)$/; |
101 | 101 |
102 /** | 102 /** |
103 * Creates a filter of correct type from its text representation - | 103 * Creates a filter of correct type from its text representation - does the |
104 * does the basic parsing and calls the right constructor then. | 104 * basic parsing and calls the right constructor then. |
Wladimir Palant
2017/03/02 14:06:45
Nit: "does the" belongs on the previous line.
kzar
2017/03/08 12:33:31
Done.
| |
105 * | 105 * |
106 * @param {string} text as in Filter() | 106 * @param {string} text as in Filter() |
107 * @return {Filter} | 107 * @return {Filter} |
108 */ | 108 */ |
109 Filter.fromText = function(text) | 109 Filter.fromText = function(text) |
110 { | 110 { |
111 if (text in Filter.knownFilters) | 111 if (text in Filter.knownFilters) |
112 return Filter.knownFilters[text]; | 112 return Filter.knownFilters[text]; |
113 | 113 |
114 let ret; | 114 let ret; |
115 let match = (text.includes("#") ? Filter.elemhideRegExp.exec(text) : null); | 115 let match = (text.includes("#") ? Filter.elemhideRegExp.exec(text) : null); |
Wladimir Palant
2017/03/02 14:06:47
Please add integration notes to the issue - this i
kzar
2017/03/08 12:33:36
Done.
| |
116 if (match) | 116 if (match) |
117 { | 117 { |
118 ret = ElemHideBase.fromText( | 118 ret = ElemHideBase.fromText( |
119 text, match[1], !!match[2], match[3], match[4], match[5] | 119 text, match[1], !!match[2], match[3], match[4], match[5] |
120 ); | 120 ); |
121 } | 121 } |
122 else if (text[0] == "!") | 122 else if (text[0] == "!") |
123 ret = new CommentFilter(text); | 123 ret = new CommentFilter(text); |
124 else | 124 else |
125 ret = RegExpFilter.fromText(text); | 125 ret = RegExpFilter.fromText(text); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
163 // Remove line breaks and such | 163 // Remove line breaks and such |
164 text = text.replace(/[^\S ]/g, ""); | 164 text = text.replace(/[^\S ]/g, ""); |
165 | 165 |
166 if (/^\s*!/.test(text)) | 166 if (/^\s*!/.test(text)) |
167 { | 167 { |
168 // Don't remove spaces inside comments | 168 // Don't remove spaces inside comments |
169 return text.trim(); | 169 return text.trim(); |
170 } | 170 } |
171 else if (Filter.elemhideRegExp.test(text)) | 171 else if (Filter.elemhideRegExp.test(text)) |
172 { | 172 { |
173 // Special treatment for element hiding filters, right side is | 173 // Special treatment for element hiding filters, right side is allowed to |
174 // allowed to contain spaces | 174 // contain spaces |
Wladimir Palant
2017/03/02 14:06:45
Nit: "allowed to" belongs on the previous line.
kzar
2017/03/08 12:33:30
Done.
| |
175 let [, domain, separator, selector] = /^(.*?)(#@?#?)(.*)$/.exec(text); | 175 let [, domain, separator, selector] = /^(.*?)(#@?#?)(.*)$/.exec(text); |
176 return domain.replace(/\s/g, "") + separator + selector.trim(); | 176 return domain.replace(/\s/g, "") + separator + selector.trim(); |
177 } | 177 } |
178 return text.replace(/\s/g, ""); | 178 return text.replace(/\s/g, ""); |
179 }; | 179 }; |
180 | 180 |
181 /** | 181 /** |
182 * @see filterToRegExp | 182 * @see filterToRegExp |
183 */ | 183 */ |
184 Filter.toRegExp = filterToRegExp; | 184 Filter.toRegExp = filterToRegExp; |
(...skipping 17 matching lines...) Expand all Loading... | |
202 type: "invalid", | 202 type: "invalid", |
203 | 203 |
204 /** | 204 /** |
205 * Reason why this filter is invalid | 205 * Reason why this filter is invalid |
206 * @type {string} | 206 * @type {string} |
207 */ | 207 */ |
208 reason: null, | 208 reason: null, |
209 | 209 |
210 /** | 210 /** |
211 * See Filter.serialize() | 211 * See Filter.serialize() |
212 * @param {string[]} buffer buffer to push the serialization results into | 212 * @inheritdoc |
Wladimir Palant
2017/03/02 14:06:46
Do we really want to duplicate this description ev
kzar
2017/03/08 12:33:32
Well I've removed those duplicate descriptions but
| |
213 */ | 213 */ |
214 serialize(buffer) {} | 214 serialize(buffer) {} |
215 }); | 215 }); |
216 | 216 |
217 /** | 217 /** |
218 * Class for comments | 218 * Class for comments |
219 * @param {string} text see Filter() | 219 * @param {string} text see Filter() |
220 * @constructor | 220 * @constructor |
221 * @augments Filter | 221 * @augments Filter |
222 */ | 222 */ |
223 function CommentFilter(text) | 223 function CommentFilter(text) |
224 { | 224 { |
225 Filter.call(this, text); | 225 Filter.call(this, text); |
226 } | 226 } |
227 exports.CommentFilter = CommentFilter; | 227 exports.CommentFilter = CommentFilter; |
228 | 228 |
229 CommentFilter.prototype = extend(Filter, { | 229 CommentFilter.prototype = extend(Filter, { |
230 type: "comment", | 230 type: "comment", |
231 | 231 |
232 /** | 232 /** |
233 * See Filter.serialize() | 233 * See Filter.serialize() |
234 * @param {string[]} buffer buffer to push the serialization results into | 234 * @inheritdoc |
235 */ | 235 */ |
236 serialize(buffer) {} | 236 serialize(buffer) {} |
237 }); | 237 }); |
238 | 238 |
239 /** | 239 /** |
240 * Abstract base class for filters that can get hits | 240 * Abstract base class for filters that can get hits |
241 * @param {string} text see Filter() | 241 * @param {string} text |
242 * @param {string} [domains] Domains that the filter is restricted to | 242 * see Filter() |
243 * separated by domainSeparator e.g. "foo.com|bar.com|~baz.com" | 243 * @param {string} [domains] |
Wladimir Palant
2017/03/02 14:06:49
As before, I'd suggest avoiding the messy indentat
kzar
2017/03/08 12:33:35
Done.
| |
244 * Domains that the filter is restricted to separated by domainSeparator | |
245 * e.g. "foo.com|bar.com|~baz.com" | |
244 * @constructor | 246 * @constructor |
245 * @augments Filter | 247 * @augments Filter |
246 */ | 248 */ |
247 function ActiveFilter(text, domains) | 249 function ActiveFilter(text, domains) |
248 { | 250 { |
249 Filter.call(this, text); | 251 Filter.call(this, text); |
250 | 252 |
251 this.domainSource = domains; | 253 this.domainSource = domains; |
252 } | 254 } |
253 exports.ActiveFilter = ActiveFilter; | 255 exports.ActiveFilter = ActiveFilter; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
289 if (value != this._hitCount) | 291 if (value != this._hitCount) |
290 { | 292 { |
291 let oldValue = this._hitCount; | 293 let oldValue = this._hitCount; |
292 this._hitCount = value; | 294 this._hitCount = value; |
293 FilterNotifier.triggerListeners("filter.hitCount", this, value, oldValue); | 295 FilterNotifier.triggerListeners("filter.hitCount", this, value, oldValue); |
294 } | 296 } |
295 return this._hitCount; | 297 return this._hitCount; |
296 }, | 298 }, |
297 | 299 |
298 /** | 300 /** |
299 * Last time the filter had a hit (in milliseconds since the | 301 * Last time the filter had a hit (in milliseconds since the beginning of the |
300 * beginning of the epoch) | 302 * epoch) |
Wladimir Palant
2017/03/02 14:06:48
Why change the spacing in this description?
kzar
2017/03/08 12:33:30
Done.
| |
301 * @type {number} | 303 * @type {number} |
302 */ | 304 */ |
303 get lastHit() | 305 get lastHit() |
304 { | 306 { |
305 return this._lastHit; | 307 return this._lastHit; |
306 }, | 308 }, |
307 set lastHit(value) | 309 set lastHit(value) |
308 { | 310 { |
309 if (value != this._lastHit) | 311 if (value != this._lastHit) |
310 { | 312 { |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
426 * @param {string} [sitekey] public key provided by the document | 428 * @param {string} [sitekey] public key provided by the document |
427 * @return {boolean} true in case of the filter being active | 429 * @return {boolean} true in case of the filter being active |
428 */ | 430 */ |
429 isActiveOnDomain(docDomain, sitekey) | 431 isActiveOnDomain(docDomain, sitekey) |
430 { | 432 { |
431 // Sitekeys are case-sensitive so we shouldn't convert them to | 433 // Sitekeys are case-sensitive so we shouldn't convert them to |
432 // upper-case to avoid false positives here. Instead we need to | 434 // upper-case to avoid false positives here. Instead we need to |
433 // change the way filter options are parsed. | 435 // change the way filter options are parsed. |
434 if (this.sitekeys && | 436 if (this.sitekeys && |
435 (!sitekey || this.sitekeys.indexOf(sitekey.toUpperCase()) < 0)) | 437 (!sitekey || this.sitekeys.indexOf(sitekey.toUpperCase()) < 0)) |
438 { | |
436 return false; | 439 return false; |
440 } | |
437 | 441 |
438 // If no domains are set the rule matches everywhere | 442 // If no domains are set the rule matches everywhere |
439 if (!this.domains) | 443 if (!this.domains) |
440 return true; | 444 return true; |
441 | 445 |
442 // If the document has no host name, match only if the filter | 446 // If the document has no host name, match only if the filter |
443 // isn't restricted to specific domains | 447 // isn't restricted to specific domains |
444 if (!docDomain) | 448 if (!docDomain) |
445 return this.domains[""]; | 449 return this.domains[""]; |
446 | 450 |
(...skipping 28 matching lines...) Expand all Loading... | |
475 docDomain = docDomain.replace(/\.+$/, ""); | 479 docDomain = docDomain.replace(/\.+$/, ""); |
476 docDomain = docDomain.toUpperCase(); | 480 docDomain = docDomain.toUpperCase(); |
477 | 481 |
478 for (let domain in this.domains) | 482 for (let domain in this.domains) |
479 { | 483 { |
480 if (this.domains[domain] && domain != docDomain) | 484 if (this.domains[domain] && domain != docDomain) |
481 { | 485 { |
482 if (domain.length <= docDomain.length) | 486 if (domain.length <= docDomain.length) |
483 return false; | 487 return false; |
484 | 488 |
485 let pos = domain.indexOf("." + docDomain); | 489 if (!domain.endsWith("." + docDomain)) |
486 if (pos != domain.length - docDomain.length - 1) | |
Wladimir Palant
2017/03/02 14:06:48
Just change this into:
if (!domain.endsWith("."
kzar
2017/03/08 12:33:29
Done.
| |
487 return false; | 490 return false; |
488 } | 491 } |
489 } | 492 } |
490 | 493 |
491 return true; | 494 return true; |
492 }, | 495 }, |
493 | 496 |
494 /** | 497 /** |
495 * Checks whether this filter is generic or specific | 498 * Checks whether this filter is generic or specific |
496 * @return {boolean} | 499 * @return {boolean} |
497 */ | 500 */ |
498 isGeneric() | 501 isGeneric() |
499 { | 502 { |
500 return !(this.sitekeys && this.sitekeys.length) && | 503 return !(this.sitekeys && this.sitekeys.length) && |
501 (!this.domains || this.domains[""]); | 504 (!this.domains || this.domains[""]); |
502 }, | 505 }, |
503 | 506 |
504 /** | 507 /** |
505 * See Filter.serialize() | 508 * See Filter.serialize() |
506 * @param {string[]} buffer buffer to push the serialization results into | 509 * @inheritdoc |
507 */ | 510 */ |
508 serialize(buffer) | 511 serialize(buffer) |
509 { | 512 { |
510 if (this._disabled || this._hitCount || this._lastHit) | 513 if (this._disabled || this._hitCount || this._lastHit) |
511 { | 514 { |
512 Filter.prototype.serialize.call(this, buffer); | 515 Filter.prototype.serialize.call(this, buffer); |
513 if (this._disabled) | 516 if (this._disabled) |
514 buffer.push("disabled=true"); | 517 buffer.push("disabled=true"); |
515 if (this._hitCount) | 518 if (this._hitCount) |
516 buffer.push("hitCount=" + this._hitCount); | 519 buffer.push("hitCount=" + this._hitCount); |
517 if (this._lastHit) | 520 if (this._lastHit) |
518 buffer.push("lastHit=" + this._lastHit); | 521 buffer.push("lastHit=" + this._lastHit); |
519 } | 522 } |
520 } | 523 } |
521 }); | 524 }); |
522 | 525 |
523 /** | 526 /** |
524 * Abstract base class for RegExp-based filters | 527 * Abstract base class for RegExp-based filters |
525 * @param {string} text see Filter() | 528 * @param {string} text see Filter() |
526 * @param {string} regexpSource filter part that the regular expression should | 529 * @param {string} regexpSource |
527 * be build from | 530 * filter part that the regular expression should be build from |
528 * @param {number} [contentType] Content types the filter applies to, | 531 * @param {number} [contentType] |
529 * combination of values from RegExpFilter.typeMap | 532 * Content types the filter applies to, combination of values from |
530 * @param {boolean} [matchCase] Defines whether the filter should distinguish | 533 * RegExpFilter.typeMap |
531 * between lower and upper case letters | 534 * @param {boolean} [matchCase] |
532 * @param {string} [domains] Domains that the filter is restricted to, | 535 * Defines whether the filter should distinguish between lower and upper case |
533 * e.g. "foo.com|bar.com|~baz.com" | 536 * letters |
534 * @param {boolean} [thirdParty] Defines whether the filter should apply to | 537 * @param {string} [domains] |
535 * third-party or first-party content only | 538 * Domains that the filter is restricted to, e.g. "foo.com|bar.com|~baz.com" |
536 * @param {string} [sitekeys] Public keys of websites that this filter should | 539 * @param {boolean} [thirdParty] |
537 * apply to | 540 * Defines whether the filter should apply to third-party or first-party |
Wladimir Palant
2017/03/02 14:06:48
As before, please avoid the messy indentation here
kzar
2017/03/08 12:33:33
Done.
| |
541 * content only | |
542 * @param {string} [sitekeys] | |
543 * Public keys of websites that this filter should apply to | |
538 * @constructor | 544 * @constructor |
539 * @augments ActiveFilter | 545 * @augments ActiveFilter |
540 */ | 546 */ |
541 function RegExpFilter(text, regexpSource, contentType, matchCase, domains, | 547 function RegExpFilter(text, regexpSource, contentType, matchCase, domains, |
542 thirdParty, sitekeys) | 548 thirdParty, sitekeys) |
543 { | 549 { |
544 ActiveFilter.call(this, text, domains, sitekeys); | 550 ActiveFilter.call(this, text, domains, sitekeys); |
545 | 551 |
546 if (contentType != null) | 552 if (contentType != null) |
547 this.contentType = contentType; | 553 this.contentType = contentType; |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
670 * @param {boolean} thirdParty should be true if the URL is a third-party | 676 * @param {boolean} thirdParty should be true if the URL is a third-party |
671 * request | 677 * request |
672 * @param {string} sitekey public key provided by the document | 678 * @param {string} sitekey public key provided by the document |
673 * @return {boolean} true in case of a match | 679 * @return {boolean} true in case of a match |
674 */ | 680 */ |
675 matches(location, typeMask, docDomain, thirdParty, sitekey) | 681 matches(location, typeMask, docDomain, thirdParty, sitekey) |
676 { | 682 { |
677 if (this.contentType & typeMask && | 683 if (this.contentType & typeMask && |
678 (this.thirdParty == null || this.thirdParty == thirdParty) && | 684 (this.thirdParty == null || this.thirdParty == thirdParty) && |
679 this.isActiveOnDomain(docDomain, sitekey) && this.regexp.test(location)) | 685 this.isActiveOnDomain(docDomain, sitekey) && this.regexp.test(location)) |
686 { | |
680 return true; | 687 return true; |
Wladimir Palant
2017/03/02 14:06:45
Since ESLint won't let you keep the braces here, I
kzar
2017/03/08 12:33:35
We can keep the braces now.
| |
688 } | |
681 return false; | 689 return false; |
682 } | 690 } |
683 }); | 691 }); |
684 | 692 |
685 // Required to optimize Matcher, see also RegExpFilter.prototype.length | 693 // Required to optimize Matcher, see also RegExpFilter.prototype.length |
686 Object.defineProperty(RegExpFilter.prototype, "0", { | 694 Object.defineProperty(RegExpFilter.prototype, "0", { |
687 get() { return this; } | 695 get() { return this; } |
688 }); | 696 }); |
689 | 697 |
690 /** | 698 /** |
691 * Creates a RegExp filter from its text representation | 699 * Creates a RegExp filter from its text representation |
692 * @param {string} text same as in Filter() | 700 * @param {string} text same as in Filter() |
693 * @return {RegExpFilter} | 701 * @return {Filter} |
Wladimir Palant
2017/03/02 14:06:49
This should be RegExpFilter|InvalidFilter. Or mayb
kzar
2017/03/08 12:33:34
Done.
| |
694 */ | 702 */ |
695 RegExpFilter.fromText = function(text) | 703 RegExpFilter.fromText = function(text) |
696 { | 704 { |
697 let blocking = true; | 705 let blocking = true; |
698 let origText = text; | 706 let origText = text; |
699 if (text.indexOf("@@") == 0) | 707 if (text.indexOf("@@") == 0) |
700 { | 708 { |
701 blocking = false; | 709 blocking = false; |
702 text = text.substr(2); | 710 text = text.substr(2); |
703 } | 711 } |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
811 | 819 |
812 /** | 820 /** |
813 * Class for blocking filters | 821 * Class for blocking filters |
814 * @param {string} text see Filter() | 822 * @param {string} text see Filter() |
815 * @param {string} regexpSource see RegExpFilter() | 823 * @param {string} regexpSource see RegExpFilter() |
816 * @param {number} contentType see RegExpFilter() | 824 * @param {number} contentType see RegExpFilter() |
817 * @param {boolean} matchCase see RegExpFilter() | 825 * @param {boolean} matchCase see RegExpFilter() |
818 * @param {string} domains see RegExpFilter() | 826 * @param {string} domains see RegExpFilter() |
819 * @param {boolean} thirdParty see RegExpFilter() | 827 * @param {boolean} thirdParty see RegExpFilter() |
820 * @param {string} sitekeys see RegExpFilter() | 828 * @param {string} sitekeys see RegExpFilter() |
821 * @param {boolean} collapse defines whether the filter should collapse blocked | 829 * @param {boolean} collapse |
822 * content, can be null | 830 * defines whether the filter should collapse blocked content, can be null |
Wladimir Palant
2017/03/02 14:06:47
Messy indentation as before.
kzar
2017/03/08 12:33:31
Done.
| |
823 * @constructor | 831 * @constructor |
824 * @augments RegExpFilter | 832 * @augments RegExpFilter |
825 */ | 833 */ |
826 function BlockingFilter(text, regexpSource, contentType, matchCase, domains, | 834 function BlockingFilter(text, regexpSource, contentType, matchCase, domains, |
827 thirdParty, sitekeys, collapse) | 835 thirdParty, sitekeys, collapse) |
828 { | 836 { |
829 RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, | 837 RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, |
830 thirdParty, sitekeys); | 838 thirdParty, sitekeys); |
831 | 839 |
832 this.collapse = collapse; | 840 this.collapse = collapse; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
914 * CSS selector for the HTML elements that should be hidden | 922 * CSS selector for the HTML elements that should be hidden |
915 * @type {string} | 923 * @type {string} |
916 */ | 924 */ |
917 selector: null | 925 selector: null |
918 }); | 926 }); |
919 | 927 |
920 /** | 928 /** |
921 * Creates an element hiding filter from a pre-parsed text representation | 929 * Creates an element hiding filter from a pre-parsed text representation |
922 * | 930 * |
923 * @param {string} text same as in Filter() | 931 * @param {string} text same as in Filter() |
924 * @param {string} domain domain part of the text representation | 932 * @param {string} domain |
925 * (can be empty) | 933 * domain part of the text representation (can be empty) |
926 * @param {boolean} isException exception rule indicator | 934 * @param {boolean} isException exception rule indicator |
927 * @param {string} tagName tag name part (can be empty) | 935 * @param {string} tagName tag name part (can be empty) |
928 * @param {string} attrRules attribute matching rules (can be empty) | 936 * @param {string} attrRules attribute matching rules (can be empty) |
929 * @param {string} selector raw CSS selector (can be empty) | 937 * @param {string} selector raw CSS selector (can be empty) |
Wladimir Palant
2017/03/02 14:06:46
Messy indentation as before.
kzar
2017/03/08 12:33:32
Done.
| |
930 * @return {ElemHideFilter|ElemHideException| | 938 * @return {ElemHideFilter|ElemHideException| |
931 * ElemHideEmulationFilter|InvalidFilter} | 939 * ElemHideEmulationFilter|InvalidFilter} |
932 */ | 940 */ |
933 ElemHideBase.fromText = function(text, domain, isException, tagName, attrRules, | 941 ElemHideBase.fromText = function(text, domain, isException, tagName, attrRules, |
934 selector) | 942 selector) |
935 { | 943 { |
936 if (!selector) | 944 if (!selector) |
937 { | 945 { |
938 if (tagName == "*") | 946 if (tagName == "*") |
939 tagName = ""; | 947 tagName = ""; |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1038 */ | 1046 */ |
1039 function ElemHideEmulationFilter(text, domains, selector) | 1047 function ElemHideEmulationFilter(text, domains, selector) |
1040 { | 1048 { |
1041 ElemHideBase.call(this, text, domains, selector); | 1049 ElemHideBase.call(this, text, domains, selector); |
1042 } | 1050 } |
1043 exports.ElemHideEmulationFilter = ElemHideEmulationFilter; | 1051 exports.ElemHideEmulationFilter = ElemHideEmulationFilter; |
1044 | 1052 |
1045 ElemHideEmulationFilter.prototype = extend(ElemHideBase, { | 1053 ElemHideEmulationFilter.prototype = extend(ElemHideBase, { |
1046 type: "elemhideemulation" | 1054 type: "elemhideemulation" |
1047 }); | 1055 }); |
LEFT | RIGHT |