| 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 |