Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: assets/js/FilterClasses.jsm

Issue 8482109: ABP/Android JavaScript code (Closed)
Patch Set: Created Oct. 5, 2012, 9:23 a.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: assets/js/FilterClasses.jsm
===================================================================
new file mode 100755
--- /dev/null
+++ b/assets/js/FilterClasses.jsm
@@ -0,0 +1,455 @@
+/*
+ * This Source Code is subject to the terms of the Mozilla Public License
+ * version 2.0 (the "License"). You can obtain a copy of the License at
+ * http://mozilla.org/MPL/2.0/.
+ */
+
+//
+// This file has been generated automatically from Adblock Plus source code
+//
+
+(function (_patchFunc2) {
+ function Filter(text) {
+ this.text = text;
+ this.subscriptions = [];
+ }
+ Filter.prototype = {
+ text: null,
+ subscriptions: null,
+ serialize: function (buffer) {
+ buffer.push("[Filter]");
+ buffer.push("text=" + this.text);
+ }
+ ,
+ toString: function () {
+ return this.text;
+ }
+
+ };
+ Filter.knownFilters = {
+ __proto__: null
+ };
+ Filter.elemhideRegExp = /^([^\/\*\|\@"!]*?)#(?:([\w\-]+|\*)((?:\([\w\-]+(?:[$^*]?=[^\(\)"]*)?\))*)|#([^{}]+))$/;
+ Filter.regexpRegExp = /^(@@)?\/.*\/(?:\$~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[^,\s]+)?)*)?$/;
+ Filter.optionsRegExp = /\$(~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[^,\s]+)?)*)$/;
+ Filter.fromText = (function (text) {
+ if (text in Filter.knownFilters)
+ return Filter.knownFilters[text];
+ if (!/\S/.test(text))
+ return null;
+ var ret;
+ if (Filter.elemhideRegExp.test(text))
+ ret = ElemHideFilter.fromText(text, RegExp["$1"], RegExp["$2"], RegExp["$3"], RegExp["$4"]);
+ else
+ if (text[0] == "!")
+ ret = new CommentFilter(text);
+ else
+ ret = RegExpFilter.fromText(text);
+ Filter.knownFilters[ret.text] = ret;
+ return ret;
+ }
+ );
+ Filter.fromObject = (function (obj) {
+ var ret = Filter.fromText(obj.text);
+ if (ret instanceof ActiveFilter) {
+ if ("disabled" in obj)
+ ret._disabled = (obj.disabled == "true");
+ if ("hitCount" in obj)
+ ret._hitCount = parseInt(obj.hitCount) || 0;
+ if ("lastHit" in obj)
+ ret._lastHit = parseInt(obj.lastHit) || 0;
+ }
+ return ret;
+ }
+ );
+ Filter.normalize = (function (text) {
+ if (!text)
+ return text;
+ text = text.replace(/[^\S ]/g, "");
+ if (/^\s*!/.test(text)) {
+ return text.replace(/^\s+/, "").replace(/\s+$/, "");
+ }
+ else
+ if (Filter.elemhideRegExp.test(text)) {
+ /^(.*?)(#+)(.*)$/.test(text);
+ var domain = RegExp["$1"];
+ var separator = RegExp["$2"];
+ var selector = RegExp["$3"];
+ return domain.replace(/\s/g, "") + separator + selector.replace(/^\s+/, "").replace(/\s+$/, "");
+ }
+ else
+ return text.replace(/\s/g, "");
+ }
+ );
+ function InvalidFilter(text, reason) {
+ Filter.call(this, text);
+ this.reason = reason;
+ }
+ InvalidFilter.prototype = {
+ __proto__: Filter.prototype,
+ reason: null,
+ serialize: function (buffer) {}
+ };
+ function CommentFilter(text) {
+ Filter.call(this, text);
+ }
+ CommentFilter.prototype = {
+ __proto__: Filter.prototype,
+ serialize: function (buffer) {}
+ };
+ function ActiveFilter(text, domains) {
+ Filter.call(this, text);
+ if (domains) {
+ this.domainSource = domains;
+ this.__defineGetter__("domains", this._getDomains);
+ }
+ }
+ ActiveFilter.prototype = {
+ __proto__: Filter.prototype,
+ _disabled: false,
+ _hitCount: 0,
+ _lastHit: 0,
+ get disabled() {
+ return this._disabled;
+ },
+ set disabled(value) {
+ if (value != this._disabled) {
+ var oldValue = this._disabled;
+ this._disabled = value;
+ FilterNotifier.triggerListeners("filter.disabled", this, value, oldValue);
+ }
+ return this._disabled;
+ }
+ ,
+ get hitCount() {
+ return this._hitCount;
+ },
+ set hitCount(value) {
+ if (value != this._hitCount) {
+ var oldValue = this._hitCount;
+ this._hitCount = value;
+ FilterNotifier.triggerListeners("filter.hitCount", this, value, oldValue);
+ }
+ return this._hitCount;
+ }
+ ,
+ get lastHit() {
+ return this._lastHit;
+ },
+ set lastHit(value) {
+ if (value != this._lastHit) {
+ var oldValue = this._lastHit;
+ this._lastHit = value;
+ FilterNotifier.triggerListeners("filter.lastHit", this, value, oldValue);
+ }
+ return this._lastHit;
+ }
+ ,
+ domainSource: null,
+ domainSeparator: null,
+ domains: null,
+ _getDomains: function () {
+ this._generateDomains();
+ return this.domains;
+ }
+ ,
+ _generateDomains: function () {
+ var domains = this.domainSource.split(this.domainSeparator);
+ delete this.domainSource;
+ delete this.domains;
+ if (domains.length == 1 && domains[0][0] != "~") {
+ this.domains = {
+ __proto__: null,
+ "": false
+ };
+ this.domains[domains[0]] = true;
+ }
+ else {
+ var hasIncludes = false;
+ for (var i = 0;
+ i < domains.length; i++) {
+ var domain = domains[i];
+ if (domain == "")
+ continue;
+ var include;
+ if (domain[0] == "~") {
+ include = false;
+ domain = domain.substr(1);
+ }
+ else {
+ include = true;
+ hasIncludes = true;
+ }
+ if (!this.domains)
+ this.domains = {
+ __proto__: null
+ };
+ this.domains[domain] = include;
+ }
+ this.domains[""] = !hasIncludes;
+ }
+ }
+ ,
+ isActiveOnDomain: function (docDomain) {
+ if (!this.domains)
+ return true;
+ if (!docDomain)
+ return this.domains[""];
+ docDomain = docDomain.replace(/\.+$/, "").toUpperCase();
+ while (true) {
+ if (docDomain in this.domains)
+ return this.domains[docDomain];
+ var nextDot = docDomain.indexOf(".");
+ if (nextDot < 0)
+ break;
+ docDomain = docDomain.substr(nextDot + 1);
+ }
+ return this.domains[""];
+ }
+ ,
+ isActiveOnlyOnDomain: function (docDomain) {
+ if (!docDomain || !this.domains || this.domains[""])
+ return false;
+ docDomain = docDomain.replace(/\.+$/, "").toUpperCase();
+ for (var domain in this.domains)
+ if (this.domains[domain] && domain != docDomain && (domain.length <= docDomain.length || domain.indexOf("." + docDomain) != domain.length - docDomain.length - 1))
+ return false;
+ return true;
+ }
+ ,
+ serialize: function (buffer) {
+ if (this._disabled || this._hitCount || this._lastHit) {
+ Filter.prototype.serialize.call(this, buffer);
+ if (this._disabled)
+ buffer.push("disabled=true");
+ if (this._hitCount)
+ buffer.push("hitCount=" + this._hitCount);
+ if (this._lastHit)
+ buffer.push("lastHit=" + this._lastHit);
+ }
+ }
+
+ };
+ function RegExpFilter(text, regexpSource, contentType, matchCase, domains, thirdParty) {
+ ActiveFilter.call(this, text, domains);
+ if (contentType != null)
+ this.contentType = contentType;
+ if (matchCase)
+ this.matchCase = matchCase;
+ if (thirdParty != null)
+ this.thirdParty = thirdParty;
+ if (regexpSource.length >= 2 && regexpSource[0] == "/" && regexpSource[regexpSource.length - 1] == "/") {
+ this.regexp = new RegExp(regexpSource.substr(1, regexpSource.length - 2), this.matchCase ? "" : "i");
+ }
+ else {
+ this.regexpSource = regexpSource;
+ this.__defineGetter__("regexp", this._generateRegExp);
+ }
+ }
+ RegExpFilter.prototype = {
+ __proto__: ActiveFilter.prototype,
+ domainSeparator: "|",
+ regexpSource: null,
+ regexp: null,
+ contentType: 2147483647,
+ matchCase: false,
+ thirdParty: null,
+ _generateRegExp: function () {
+ var source = this.regexpSource.replace(/\*+/g, "*");
+ if (source[0] == "*")
+ source = source.substr(1);
+ var pos = source.length - 1;
+ if (pos >= 0 && source[pos] == "*")
+ source = source.substr(0, pos);
+ source = source.replace(/\^\|$/, "^").replace(/\W/g, "\\$&").replace(/\\\*/g, ".*").replace(/\\\^/g, "(?:[\\x00-\\x24\\x26-\\x2C\\x2F\\x3A-\\x40\\x5B-\\x5E\\x60\\x7B-\\x80]|$)").replace(/^\\\|\\\|/, "^[\\w\\-]+:\\/+(?!\\/)(?:[^.\\/]+\\.)*?").replace(/^\\\|/, "^").replace(/\\\|$/, "$");
+ var regexp = new RegExp(source, this.matchCase ? "" : "i");
+ delete this.regexp;
+ delete this.regexpSource;
+ return (this.regexp = regexp);
+ }
+ ,
+ matches: function (location, contentType, docDomain, thirdParty) {
+ if (this.regexp.test(location) && (RegExpFilter.typeMap[contentType] & this.contentType) != 0 && (this.thirdParty == null || this.thirdParty == thirdParty) && this.isActiveOnDomain(docDomain)) {
+ return true;
+ }
+ return false;
+ }
+
+ };
+ RegExpFilter.fromText = (function (text) {
+ var blocking = true;
+ var origText = text;
+ if (text.indexOf("@@") == 0) {
+ blocking = false;
+ text = text.substr(2);
+ }
+ var contentType = null;
+ var matchCase = null;
+ var domains = null;
+ var siteKeys = null;
+ var thirdParty = null;
+ var collapse = null;
+ var options;
+ if (Filter.optionsRegExp.test(text)) {
+ options = RegExp["$1"].toUpperCase().split(",");
+ text = RegExp.leftContext;
+ for (var _loopIndex0 = 0;
+ _loopIndex0 < options.length; ++ _loopIndex0) {
+ var option = options[_loopIndex0];
+ var value = null;
+ var separatorIndex = option.indexOf("=");
+ if (separatorIndex >= 0) {
+ value = option.substr(separatorIndex + 1);
+ option = option.substr(0, separatorIndex);
+ }
+ option = option.replace(/-/, "_");
+ if (option in RegExpFilter.typeMap) {
+ if (contentType == null)
+ contentType = 0;
+ contentType |= RegExpFilter.typeMap[option];
+ }
+ else
+ if (option[0] == "~" && option.substr(1) in RegExpFilter.typeMap) {
+ if (contentType == null)
+ contentType = RegExpFilter.prototype.contentType;
+ contentType &= ~RegExpFilter.typeMap[option.substr(1)];
+ }
+ else
+ if (option == "MATCH_CASE")
+ matchCase = true;
+ else
+ if (option == "DOMAIN" && typeof value != "undefined")
+ domains = value;
+ else
+ if (option == "THIRD_PARTY")
+ thirdParty = true;
+ else
+ if (option == "~THIRD_PARTY")
+ thirdParty = false;
+ else
+ if (option == "COLLAPSE")
+ collapse = true;
+ else
+ if (option == "~COLLAPSE")
+ collapse = false;
+ else
+ if (option == "SITEKEY" && typeof value != "undefined")
+ siteKeys = value.split(/\|/);
+ }
+ }
+ if (!blocking && (contentType == null || (contentType & RegExpFilter.typeMap.DOCUMENT)) && (!options || options.indexOf("DOCUMENT") < 0) && !/^\|?[\w\-]+:/.test(text)) {
+ if (contentType == null)
+ contentType = RegExpFilter.prototype.contentType;
+ contentType &= ~RegExpFilter.typeMap.DOCUMENT;
+ }
+ if (!blocking && siteKeys)
+ contentType = RegExpFilter.typeMap.DOCUMENT;
+ try {
+ if (blocking)
+ return new BlockingFilter(origText, text, contentType, matchCase, domains, thirdParty, collapse);
+ else
+ return new WhitelistFilter(origText, text, contentType, matchCase, domains, thirdParty, siteKeys);
+ }
+ catch (e){
+ return new InvalidFilter(text, e);
+ }
+ }
+ );
+ RegExpFilter.typeMap = {
+ OTHER: 1,
+ SCRIPT: 2,
+ IMAGE: 4,
+ STYLESHEET: 8,
+ OBJECT: 16,
+ SUBDOCUMENT: 32,
+ DOCUMENT: 64,
+ XBL: 1,
+ PING: 1,
+ XMLHTTPREQUEST: 2048,
+ OBJECT_SUBREQUEST: 4096,
+ DTD: 1,
+ MEDIA: 16384,
+ FONT: 32768,
+ BACKGROUND: 4,
+ POPUP: 268435456,
+ DONOTTRACK: 536870912,
+ ELEMHIDE: 1073741824
+ };
+ RegExpFilter.prototype.contentType &= ~(RegExpFilter.typeMap.ELEMHIDE | RegExpFilter.typeMap.DONOTTRACK | RegExpFilter.typeMap.POPUP);
+ function BlockingFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, collapse) {
+ RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, thirdParty);
+ this.collapse = collapse;
+ }
+ BlockingFilter.prototype = {
+ __proto__: RegExpFilter.prototype,
+ collapse: null
+ };
+ function WhitelistFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, siteKeys) {
+ RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, thirdParty);
+ if (siteKeys != null)
+ this.siteKeys = siteKeys;
+ }
+ WhitelistFilter.prototype = {
+ __proto__: RegExpFilter.prototype,
+ siteKeys: null
+ };
+ function ElemHideFilter(text, domains, selector) {
+ ActiveFilter.call(this, text, domains ? domains.toUpperCase() : null);
+ if (domains)
+ this.selectorDomain = domains.replace(/,~[^,]+/g, "").replace(/^~[^,]+,?/, "").toLowerCase();
+ this.selector = selector;
+ }
+ ElemHideFilter.prototype = {
+ __proto__: ActiveFilter.prototype,
+ domainSeparator: ",",
+ selectorDomain: null,
+ selector: null
+ };
+ ElemHideFilter.fromText = (function (text, domain, tagName, attrRules, selector) {
+ if (!selector) {
+ if (tagName == "*")
+ tagName = "";
+ var id = null;
+ var additional = "";
+ if (attrRules) {
+ attrRules = attrRules.match(/\([\w\-]+(?:[$^*]?=[^\(\)"]*)?\)/g);
+ for (var _loopIndex1 = 0;
+ _loopIndex1 < attrRules.length; ++ _loopIndex1) {
+ var rule = attrRules[_loopIndex1];
+ rule = rule.substr(1, rule.length - 2);
+ var separatorPos = rule.indexOf("=");
+ if (separatorPos > 0) {
+ rule = rule.replace(/=/, "=\"") + "\"";
+ additional += "[" + rule + "]";
+ }
+ else {
+ if (id)
+ return new InvalidFilter(text, Utils.getString("filter_elemhide_duplicate_id"));
+ else
+ id = rule;
+ }
+ }
+ }
+ if (id)
+ selector = tagName + "." + id + additional + "," + tagName + "#" + id + additional;
+ else
+ if (tagName || additional)
+ selector = tagName + additional;
+ else
+ return new InvalidFilter(text, Utils.getString("filter_elemhide_nocriteria"));
+ }
+ return new ElemHideFilter(text, domain, selector);
+ }
+ );
+ if (typeof _patchFunc2 != "undefined")
+ eval("(" + _patchFunc2.toString() + ")()");
+ window.Filter = Filter;
+ window.InvalidFilter = InvalidFilter;
+ window.CommentFilter = CommentFilter;
+ window.ActiveFilter = ActiveFilter;
+ window.RegExpFilter = RegExpFilter;
+ window.BlockingFilter = BlockingFilter;
+ window.WhitelistFilter = WhitelistFilter;
+ window.ElemHideFilter = ElemHideFilter;
+}
+)(window.FilterClassesPatch);

Powered by Google App Engine
This is Rietveld