OLD | NEW |
| (Empty) |
1 /* | |
2 * This file is part of Adblock Plus <https://adblockplus.org/>, | |
3 * Copyright (C) 2006-2016 Eyeo GmbH | |
4 * | |
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 | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * Adblock Plus is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 * GNU General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU General Public License | |
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | |
16 */ | |
17 | |
18 // | |
19 // This file has been generated automatically, relevant repositories: | |
20 // * https://hg.adblockplus.org/adblockplus/ | |
21 // * https://hg.adblockplus.org/jshydra/ | |
22 // | |
23 | |
24 function Filter(text) | |
25 { | |
26 this.text = text; | |
27 this.subscriptions = []; | |
28 } | |
29 exports.Filter = Filter; | |
30 Filter.prototype = { | |
31 text: null, | |
32 subscriptions: null, | |
33 get type() | |
34 { | |
35 throw new Error("Please define filter type in the subclass"); | |
36 }, | |
37 serialize: function(buffer) | |
38 { | |
39 buffer.push("[Filter]"); | |
40 buffer.push("text=" + this.text); | |
41 }, | |
42 toString: function() | |
43 { | |
44 return this.text; | |
45 } | |
46 }; | |
47 Filter.knownFilters = Object.create(null); | |
48 Filter.elemhideRegExp = /^([^\/\*\|\@"!]*?)#(\@)?(?:([\w\-]+|\*)((?:\([\w\-]+(?:
[$^*]?=[^\(\)"]*)?\))*)|#([^{}]+))$/; | |
49 Filter.regexpRegExp = /^(@@)?\/.*\/(?:\$~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[
^,\s]+)?)*)?$/; | |
50 Filter.optionsRegExp = /\$(~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[^,\s]+)?)*)$/
; | |
51 Filter.csspropertyRegExp = /\[\-abp\-properties=(["'])([^"']+)\1\]/; | |
52 Filter.fromText = function(text) | |
53 { | |
54 if (text in Filter.knownFilters) | |
55 { | |
56 return Filter.knownFilters[text]; | |
57 } | |
58 var ret; | |
59 var match = text.indexOf("#") >= 0 ? Filter.elemhideRegExp.exec(text) : null; | |
60 if (match) | |
61 { | |
62 ret = ElemHideBase.fromText(text, match[1], !!match[2], match[3], match[4],
match[5]); | |
63 } | |
64 else if (text[0] == "!") | |
65 { | |
66 ret = new CommentFilter(text); | |
67 } | |
68 else | |
69 { | |
70 ret = RegExpFilter.fromText(text); | |
71 } | |
72 Filter.knownFilters[ret.text] = ret; | |
73 return ret; | |
74 }; | |
75 Filter.fromObject = function(obj) | |
76 { | |
77 var ret = Filter.fromText(obj.text); | |
78 if (ret instanceof ActiveFilter) | |
79 { | |
80 if ("disabled" in obj) | |
81 { | |
82 ret._disabled = obj.disabled == "true"; | |
83 } | |
84 if ("hitCount" in obj) | |
85 { | |
86 ret._hitCount = parseInt(obj.hitCount) || 0; | |
87 } | |
88 if ("lastHit" in obj) | |
89 { | |
90 ret._lastHit = parseInt(obj.lastHit) || 0; | |
91 } | |
92 } | |
93 return ret; | |
94 }; | |
95 Filter.normalize = function(text) | |
96 { | |
97 if (!text) | |
98 { | |
99 return text; | |
100 } | |
101 text = text.replace(/[^\S ]/g, ""); | |
102 if (/^\s*!/.test(text)) | |
103 { | |
104 return text.trim(); | |
105 } | |
106 else if (Filter.elemhideRegExp.test(text)) | |
107 { | |
108 var _tempVar0 = /^(.*?)(#\@?#?)(.*)$/.exec(text); | |
109 var domain = _tempVar0[1]; | |
110 var separator = _tempVar0[2]; | |
111 var selector = _tempVar0[3]; | |
112 return domain.replace(/\s/g, "") + separator + selector.trim(); | |
113 } | |
114 else | |
115 { | |
116 return text.replace(/\s/g, ""); | |
117 } | |
118 }; | |
119 Filter.toRegExp = function(text) | |
120 { | |
121 return text.replace(/\*+/g, "*").replace(/\^\|$/, "^").replace(/\W/g, "\\$&").
replace(/\\\*/g, ".*").replace(/\\\^/g, "(?:[\\x00-\\x24\\x26-\\x2C\\x2F\\x3A-\\
x40\\x5B-\\x5E\\x60\\x7B-\\x7F]|$)").replace(/^\\\|\\\|/, "^[\\w\\-]+:\\/+(?!\\/
)(?:[^\\/]+\\.)?").replace(/^\\\|/, "^").replace(/\\\|$/, "$").replace(/^(\.\*)/
, "").replace(/(\.\*)$/, ""); | |
122 }; | |
123 | |
124 function InvalidFilter(text, reason) | |
125 { | |
126 Filter.call(this, text); | |
127 this.reason = reason; | |
128 } | |
129 exports.InvalidFilter = InvalidFilter; | |
130 InvalidFilter.prototype = { | |
131 __proto__: Filter.prototype, | |
132 type: "invalid", | |
133 reason: null, | |
134 serialize: function(buffer) | |
135 {} | |
136 }; | |
137 | |
138 function CommentFilter(text) | |
139 { | |
140 Filter.call(this, text); | |
141 } | |
142 exports.CommentFilter = CommentFilter; | |
143 CommentFilter.prototype = { | |
144 __proto__: Filter.prototype, | |
145 type: "comment", | |
146 serialize: function(buffer) | |
147 {} | |
148 }; | |
149 | |
150 function ActiveFilter(text, domains) | |
151 { | |
152 Filter.call(this, text); | |
153 this.domainSource = domains; | |
154 } | |
155 exports.ActiveFilter = ActiveFilter; | |
156 ActiveFilter.prototype = { | |
157 __proto__: Filter.prototype, | |
158 _disabled: false, | |
159 _hitCount: 0, | |
160 _lastHit: 0, | |
161 get disabled() | |
162 { | |
163 return this._disabled; | |
164 }, | |
165 set disabled(value) | |
166 { | |
167 if (value != this._disabled) | |
168 { | |
169 var oldValue = this._disabled; | |
170 this._disabled = value; | |
171 } | |
172 return this._disabled; | |
173 }, | |
174 get hitCount() | |
175 { | |
176 return this._hitCount; | |
177 }, | |
178 set hitCount(value) | |
179 { | |
180 if (value != this._hitCount) | |
181 { | |
182 var oldValue = this._hitCount; | |
183 this._hitCount = value; | |
184 } | |
185 return this._hitCount; | |
186 }, | |
187 get lastHit() | |
188 { | |
189 return this._lastHit; | |
190 }, | |
191 set lastHit(value) | |
192 { | |
193 if (value != this._lastHit) | |
194 { | |
195 var oldValue = this._lastHit; | |
196 this._lastHit = value; | |
197 } | |
198 return this._lastHit; | |
199 }, | |
200 domainSource: null, | |
201 domainSeparator: null, | |
202 ignoreTrailingDot: true, | |
203 domainSourceIsUpperCase: false, | |
204 get domains() | |
205 { | |
206 var prop = Object.getOwnPropertyDescriptor(this, "domains"); | |
207 if (prop) | |
208 { | |
209 return prop.value; | |
210 } | |
211 var domains = null; | |
212 if (this.domainSource) | |
213 { | |
214 var source = this.domainSource; | |
215 if (!this.domainSourceIsUpperCase) | |
216 { | |
217 source = source.toUpperCase(); | |
218 } | |
219 var list = source.split(this.domainSeparator); | |
220 if (list.length == 1 && list[0][0] != "~") | |
221 { | |
222 domains = { | |
223 __proto__: null, | |
224 "": false | |
225 }; | |
226 if (this.ignoreTrailingDot) | |
227 { | |
228 list[0] = list[0].replace(/\.+$/, ""); | |
229 } | |
230 domains[list[0]] = true; | |
231 } | |
232 else | |
233 { | |
234 var hasIncludes = false; | |
235 for (var i = 0; i < list.length; i++) | |
236 { | |
237 var domain = list[i]; | |
238 if (this.ignoreTrailingDot) | |
239 { | |
240 domain = domain.replace(/\.+$/, ""); | |
241 } | |
242 if (domain == "") | |
243 { | |
244 continue; | |
245 } | |
246 var include; | |
247 if (domain[0] == "~") | |
248 { | |
249 include = false; | |
250 domain = domain.substr(1); | |
251 } | |
252 else | |
253 { | |
254 include = true; | |
255 hasIncludes = true; | |
256 } | |
257 if (!domains) | |
258 { | |
259 domains = Object.create(null); | |
260 } | |
261 domains[domain] = include; | |
262 } | |
263 domains[""] = !hasIncludes; | |
264 } | |
265 this.domainSource = null; | |
266 } | |
267 Object.defineProperty(this, "domains", | |
268 { | |
269 value: domains, | |
270 enumerable: true | |
271 }); | |
272 return this.domains; | |
273 }, | |
274 sitekeys: null, | |
275 isActiveOnDomain: function(docDomain, sitekey) | |
276 { | |
277 if (this.sitekeys && (!sitekey || this.sitekeys.indexOf(sitekey.toUpperCase(
)) < 0)) | |
278 { | |
279 return false; | |
280 } | |
281 if (!this.domains) | |
282 { | |
283 return true; | |
284 } | |
285 if (!docDomain) | |
286 { | |
287 return this.domains[""]; | |
288 } | |
289 if (this.ignoreTrailingDot) | |
290 { | |
291 docDomain = docDomain.replace(/\.+$/, ""); | |
292 } | |
293 docDomain = docDomain.toUpperCase(); | |
294 while (true) | |
295 { | |
296 if (docDomain in this.domains) | |
297 { | |
298 return this.domains[docDomain]; | |
299 } | |
300 var nextDot = docDomain.indexOf("."); | |
301 if (nextDot < 0) | |
302 { | |
303 break; | |
304 } | |
305 docDomain = docDomain.substr(nextDot + 1); | |
306 } | |
307 return this.domains[""]; | |
308 }, | |
309 isActiveOnlyOnDomain: function(docDomain) | |
310 { | |
311 if (!docDomain || !this.domains || this.domains[""]) | |
312 { | |
313 return false; | |
314 } | |
315 if (this.ignoreTrailingDot) | |
316 { | |
317 docDomain = docDomain.replace(/\.+$/, ""); | |
318 } | |
319 docDomain = docDomain.toUpperCase(); | |
320 for (var domain in this.domains) | |
321 { | |
322 if (this.domains[domain] && domain != docDomain && (domain.length <= docDo
main.length || domain.indexOf("." + docDomain) != domain.length - docDomain.leng
th - 1)) | |
323 { | |
324 return false; | |
325 } | |
326 } | |
327 return true; | |
328 }, | |
329 isGeneric: function() | |
330 { | |
331 return !(this.sitekeys && this.sitekeys.length) && (!this.domains || this.do
mains[""]); | |
332 }, | |
333 serialize: function(buffer) | |
334 { | |
335 if (this._disabled || this._hitCount || this._lastHit) | |
336 { | |
337 Filter.prototype.serialize.call(this, buffer); | |
338 if (this._disabled) | |
339 { | |
340 buffer.push("disabled=true"); | |
341 } | |
342 if (this._hitCount) | |
343 { | |
344 buffer.push("hitCount=" + this._hitCount); | |
345 } | |
346 if (this._lastHit) | |
347 { | |
348 buffer.push("lastHit=" + this._lastHit); | |
349 } | |
350 } | |
351 } | |
352 }; | |
353 | |
354 function RegExpFilter(text, regexpSource, contentType, matchCase, domains, third
Party, sitekeys) | |
355 { | |
356 ActiveFilter.call(this, text, domains, sitekeys); | |
357 if (contentType != null) | |
358 { | |
359 this.contentType = contentType; | |
360 } | |
361 if (matchCase) | |
362 { | |
363 this.matchCase = matchCase; | |
364 } | |
365 if (thirdParty != null) | |
366 { | |
367 this.thirdParty = thirdParty; | |
368 } | |
369 if (sitekeys != null) | |
370 { | |
371 this.sitekeySource = sitekeys; | |
372 } | |
373 if (regexpSource.length >= 2 && regexpSource[0] == "/" && regexpSource[regexpS
ource.length - 1] == "/") | |
374 { | |
375 var regexp = new RegExp(regexpSource.substr(1, regexpSource.length - 2), thi
s.matchCase ? "" : "i"); | |
376 Object.defineProperty(this, "regexp", | |
377 { | |
378 value: regexp | |
379 }); | |
380 } | |
381 else | |
382 { | |
383 this.regexpSource = regexpSource; | |
384 } | |
385 } | |
386 exports.RegExpFilter = RegExpFilter; | |
387 RegExpFilter.prototype = { | |
388 __proto__: ActiveFilter.prototype, | |
389 domainSourceIsUpperCase: true, | |
390 length: 1, | |
391 domainSeparator: "|", | |
392 regexpSource: null, | |
393 get regexp() | |
394 { | |
395 var prop = Object.getOwnPropertyDescriptor(this, "regexp"); | |
396 if (prop) | |
397 { | |
398 return prop.value; | |
399 } | |
400 var source = Filter.toRegExp(this.regexpSource); | |
401 var regexp = new RegExp(source, this.matchCase ? "" : "i"); | |
402 Object.defineProperty(this, "regexp", | |
403 { | |
404 value: regexp | |
405 }); | |
406 return regexp; | |
407 }, | |
408 contentType: 2147483647, | |
409 matchCase: false, | |
410 thirdParty: null, | |
411 sitekeySource: null, | |
412 get sitekeys() | |
413 { | |
414 var prop = Object.getOwnPropertyDescriptor(this, "sitekeys"); | |
415 if (prop) | |
416 { | |
417 return prop.value; | |
418 } | |
419 var sitekeys = null; | |
420 if (this.sitekeySource) | |
421 { | |
422 sitekeys = this.sitekeySource.split("|"); | |
423 this.sitekeySource = null; | |
424 } | |
425 Object.defineProperty(this, "sitekeys", | |
426 { | |
427 value: sitekeys, | |
428 enumerable: true | |
429 }); | |
430 return this.sitekeys; | |
431 }, | |
432 matches: function(location, typeMask, docDomain, thirdParty, sitekey) | |
433 { | |
434 if (this.contentType & typeMask && (this.thirdParty == null || this.thirdPar
ty == thirdParty) && this.isActiveOnDomain(docDomain, sitekey) && this.regexp.te
st(location)) | |
435 { | |
436 return true; | |
437 } | |
438 return false; | |
439 } | |
440 }; | |
441 Object.defineProperty(RegExpFilter.prototype, "0", | |
442 { | |
443 get: function() | |
444 { | |
445 return this; | |
446 } | |
447 }); | |
448 RegExpFilter.fromText = function(text) | |
449 { | |
450 var blocking = true; | |
451 var origText = text; | |
452 if (text.indexOf("@@") == 0) | |
453 { | |
454 blocking = false; | |
455 text = text.substr(2); | |
456 } | |
457 var contentType = null; | |
458 var matchCase = null; | |
459 var domains = null; | |
460 var sitekeys = null; | |
461 var thirdParty = null; | |
462 var collapse = null; | |
463 var options; | |
464 var match = text.indexOf("$") >= 0 ? Filter.optionsRegExp.exec(text) : null; | |
465 if (match) | |
466 { | |
467 options = match[1].toUpperCase().split(","); | |
468 text = match.input.substr(0, match.index); | |
469 for (var _loopIndex1 = 0; _loopIndex1 < options.length; ++_loopIndex1) | |
470 { | |
471 var option = options[_loopIndex1]; | |
472 var value = null; | |
473 var separatorIndex = option.indexOf("="); | |
474 if (separatorIndex >= 0) | |
475 { | |
476 value = option.substr(separatorIndex + 1); | |
477 option = option.substr(0, separatorIndex); | |
478 } | |
479 option = option.replace(/-/, "_"); | |
480 if (option in RegExpFilter.typeMap) | |
481 { | |
482 if (contentType == null) | |
483 { | |
484 contentType = 0; | |
485 } | |
486 contentType |= RegExpFilter.typeMap[option]; | |
487 } | |
488 else if (option[0] == "~" && option.substr(1) in RegExpFilter.typeMap) | |
489 { | |
490 if (contentType == null) | |
491 { | |
492 contentType = RegExpFilter.prototype.contentType; | |
493 } | |
494 contentType &= ~RegExpFilter.typeMap[option.substr(1)]; | |
495 } | |
496 else if (option == "MATCH_CASE") | |
497 { | |
498 matchCase = true; | |
499 } | |
500 else if (option == "~MATCH_CASE") | |
501 { | |
502 matchCase = false; | |
503 } | |
504 else if (option == "DOMAIN" && typeof value != "undefined") | |
505 { | |
506 domains = value; | |
507 } | |
508 else if (option == "THIRD_PARTY") | |
509 { | |
510 thirdParty = true; | |
511 } | |
512 else if (option == "~THIRD_PARTY") | |
513 { | |
514 thirdParty = false; | |
515 } | |
516 else if (option == "COLLAPSE") | |
517 { | |
518 collapse = true; | |
519 } | |
520 else if (option == "~COLLAPSE") | |
521 { | |
522 collapse = false; | |
523 } | |
524 else if (option == "SITEKEY" && typeof value != "undefined") | |
525 { | |
526 sitekeys = value; | |
527 } | |
528 else | |
529 { | |
530 return new InvalidFilter(origText, "Unknown option " + option.toLowerCas
e()); | |
531 } | |
532 } | |
533 } | |
534 try | |
535 { | |
536 if (blocking) | |
537 { | |
538 return new BlockingFilter(origText, text, contentType, matchCase, domains,
thirdParty, sitekeys, collapse); | |
539 } | |
540 else | |
541 { | |
542 return new WhitelistFilter(origText, text, contentType, matchCase, domains
, thirdParty, sitekeys); | |
543 } | |
544 } | |
545 catch (e) | |
546 { | |
547 return new InvalidFilter(origText, e); | |
548 } | |
549 }; | |
550 RegExpFilter.typeMap = { | |
551 OTHER: 1, | |
552 SCRIPT: 2, | |
553 IMAGE: 4, | |
554 STYLESHEET: 8, | |
555 OBJECT: 16, | |
556 SUBDOCUMENT: 32, | |
557 DOCUMENT: 64, | |
558 XBL: 1, | |
559 PING: 1024, | |
560 XMLHTTPREQUEST: 2048, | |
561 OBJECT_SUBREQUEST: 4096, | |
562 DTD: 1, | |
563 MEDIA: 16384, | |
564 FONT: 32768, | |
565 BACKGROUND: 4, | |
566 POPUP: 268435456, | |
567 GENERICBLOCK: 536870912, | |
568 ELEMHIDE: 1073741824, | |
569 GENERICHIDE: 2147483648 | |
570 }; | |
571 RegExpFilter.prototype.contentType &= ~ (RegExpFilter.typeMap.DOCUMENT | RegExpF
ilter.typeMap.ELEMHIDE | RegExpFilter.typeMap.POPUP | RegExpFilter.typeMap.GENER
ICHIDE | RegExpFilter.typeMap.GENERICBLOCK); | |
572 | |
573 function BlockingFilter(text, regexpSource, contentType, matchCase, domains, thi
rdParty, sitekeys, collapse) | |
574 { | |
575 RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, t
hirdParty, sitekeys); | |
576 this.collapse = collapse; | |
577 } | |
578 exports.BlockingFilter = BlockingFilter; | |
579 BlockingFilter.prototype = { | |
580 __proto__: RegExpFilter.prototype, | |
581 type: "blocking", | |
582 collapse: null | |
583 }; | |
584 | |
585 function WhitelistFilter(text, regexpSource, contentType, matchCase, domains, th
irdParty, sitekeys) | |
586 { | |
587 RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, t
hirdParty, sitekeys); | |
588 } | |
589 exports.WhitelistFilter = WhitelistFilter; | |
590 WhitelistFilter.prototype = { | |
591 __proto__: RegExpFilter.prototype, | |
592 type: "whitelist" | |
593 }; | |
594 | |
595 function ElemHideBase(text, domains, selector) | |
596 { | |
597 ActiveFilter.call(this, text, domains || null); | |
598 if (domains) | |
599 { | |
600 this.selectorDomain = domains.replace(/,~[^,]+/g, "").replace(/^~[^,]+,?/, "
").toLowerCase(); | |
601 } | |
602 this.selector = selector; | |
603 } | |
604 exports.ElemHideBase = ElemHideBase; | |
605 ElemHideBase.prototype = { | |
606 __proto__: ActiveFilter.prototype, | |
607 domainSeparator: ",", | |
608 ignoreTrailingDot: false, | |
609 selectorDomain: null, | |
610 selector: null | |
611 }; | |
612 ElemHideBase.fromText = function(text, domain, isException, tagName, attrRules,
selector) | |
613 { | |
614 if (!selector) | |
615 { | |
616 if (tagName == "*") | |
617 { | |
618 tagName = ""; | |
619 } | |
620 var id = null; | |
621 var additional = ""; | |
622 if (attrRules) | |
623 { | |
624 attrRules = attrRules.match(/\([\w\-]+(?:[$^*]?=[^\(\)"]*)?\)/g); | |
625 for (var _loopIndex2 = 0; _loopIndex2 < attrRules.length; ++_loopIndex2) | |
626 { | |
627 var rule = attrRules[_loopIndex2]; | |
628 rule = rule.substr(1, rule.length - 2); | |
629 var separatorPos = rule.indexOf("="); | |
630 if (separatorPos > 0) | |
631 { | |
632 rule = rule.replace(/=/, "=\"") + "\""; | |
633 additional += "[" + rule + "]"; | |
634 } | |
635 else | |
636 { | |
637 if (id) | |
638 { | |
639 return new InvalidFilter(text); | |
640 } | |
641 id = rule; | |
642 } | |
643 } | |
644 } | |
645 if (id) | |
646 { | |
647 selector = tagName + "." + id + additional + "," + tagName + "#" + id + ad
ditional; | |
648 } | |
649 else if (tagName || additional) | |
650 { | |
651 selector = tagName + additional; | |
652 } | |
653 else | |
654 { | |
655 return new InvalidFilter(text); | |
656 } | |
657 } | |
658 if (isException) | |
659 { | |
660 return new ElemHideException(text, domain, selector); | |
661 } | |
662 var match = Filter.csspropertyRegExp.exec(selector); | |
663 if (match) | |
664 { | |
665 if (!/,[^~][^,.]*\.[^,]/.test("," + domain)) | |
666 { | |
667 return new InvalidFilter(text); | |
668 } | |
669 return new CSSPropertyFilter(text, domain, selector, match[2], selector.subs
tr(0, match.index), selector.substr(match.index + match[0].length)); | |
670 } | |
671 return new ElemHideFilter(text, domain, selector); | |
672 }; | |
673 | |
674 function ElemHideFilter(text, domains, selector) | |
675 { | |
676 ElemHideBase.call(this, text, domains, selector); | |
677 } | |
678 exports.ElemHideFilter = ElemHideFilter; | |
679 ElemHideFilter.prototype = { | |
680 __proto__: ElemHideBase.prototype, | |
681 type: "elemhide" | |
682 }; | |
683 | |
684 function ElemHideException(text, domains, selector) | |
685 { | |
686 ElemHideBase.call(this, text, domains, selector); | |
687 } | |
688 exports.ElemHideException = ElemHideException; | |
689 ElemHideException.prototype = { | |
690 __proto__: ElemHideBase.prototype, | |
691 type: "elemhideexception" | |
692 }; | |
693 | |
694 function CSSPropertyFilter(text, domains, selector, regexpSource, selectorPrefix
, selectorSuffix) | |
695 { | |
696 ElemHideBase.call(this, text, domains, selector); | |
697 this.regexpSource = regexpSource; | |
698 this.selectorPrefix = selectorPrefix; | |
699 this.selectorSuffix = selectorSuffix; | |
700 } | |
701 exports.CSSPropertyFilter = CSSPropertyFilter; | |
702 CSSPropertyFilter.prototype = { | |
703 __proto__: ElemHideBase.prototype, | |
704 type: "cssproperty", | |
705 regexpSource: null, | |
706 selectorPrefix: null, | |
707 selectorSuffix: null, | |
708 get regexpString() | |
709 { | |
710 var prop = Object.getOwnPropertyDescriptor(this, "regexpString"); | |
711 if (prop) | |
712 { | |
713 return prop.value; | |
714 } | |
715 var regexp = Filter.toRegExp(this.regexpSource); | |
716 Object.defineProperty(this, "regexpString", | |
717 { | |
718 value: regexp | |
719 }); | |
720 return regexp; | |
721 } | |
722 }; | |
OLD | NEW |