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

Unified Diff: lib/matcher.js

Issue 8483154: Adding ABP core modules to ABP/Opera (Closed)
Patch Set: Created Oct. 11, 2012, 9:35 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: lib/matcher.js
===================================================================
new file mode 100644
--- /dev/null
+++ b/lib/matcher.js
@@ -0,0 +1,175 @@
+/*
+ * 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 mimicks the API of the Matcher module in ABP/Firefox but users Opera's
+// URLFilter API.
+//
+
+(function()
+{
+ var WhitelistFilter = null;
+ var RegExpFilter = null;
+ var resourceTypes = [
+ "DOCUMENT", "FONT", "IMAGE", "MEDIA", "OBJECT", "OBJECT_SUBREQUEST",
+ "OTHER", "SCRIPT", "STYLESHEET", "SUBDOCUMENT", "XMLHTTPREQUEST"
+ ];
+
+ require.scopes.matcher =
+ {
+ defaultMatcher:
+ {
+ _rules: {},
+
+ /**
+ * Converts rule text from Adblock Plus format (implicit * at beginning
+ * and end of the rule unless there is an anchor) to Opera format (* has
+ * to be specified explicitly).
+ */
+ _getRuleText: function(/**Filter*/ filter) /**String*/
+ {
+ var text = filter.regexpSource;
+
+ // |foo => foo
+ // foo => *foo
+ // *foo and ||foo stay unchanged
+ if (text.substr(0, 2) != "||")
+ {
+ var start = text.substr(0, 1);
+ if (start == "|")
+ text = text.slice(1);
+ else if (start != "*")
+ text = "*" + text;
+ }
+
+ // foo| => foo
+ // foo => foo*
+ // foo* stays unchanged
+ var end = text.substr(-1);
+ if (end == "|")
+ text = text.slice(0, -1);
+ else if (end != "*")
+ text = text + "*";
+
+ return text;
+ },
+
+ /**
+ * Converts type options of a filter into a bit mask as expected by Opera.
+ */
+ _getRuleTypes: function(/**Filter*/ filter) /**Integer*/
+ {
+ var types = 0;
+ var urlfilter = opera.extension.urlfilter;
+ for (var i = 0; i < resourceTypes.length; i++)
+ {
+ var type = resourceTypes[i];
+ if (filter.contentType & RegExpFilter.typeMap[type])
+ types |= urlfilter["RESOURCE_" + type];
+ }
+ return types;
+ },
+
+ /**
+ * Converts domain options of a filter into includeDomains/excludeDomains
+ * options as expected by Opera. The options object has to be passed in,
+ * properties will be added to it if necessary.
+ */
+ _getRuleDomains: function(/**Filter*/ filter, /**Object*/ options)
+ {
+ if (filter.domainSource)
+ {
+ var domains = filter.domainSource.split(filter.domainSeparator);
+ for (var i = 0; i < domains.length; i++)
+ {
+ var domain = domains[i];
+ if (domain == "")
+ continue;
+
+ var type = "includeDomains";
+ if (domain[0] == "~")
+ {
+ type = "excludeDomains";
+ domain = domain.substr(1);
+ }
+ if (!(type in options))
+ options[type] = [];
+ options[type].push(domain);
+ }
+ }
+ },
+
+ /**
+ * Converts third-party filter option to the format expected by Opera.
+ * The options object has to be passed in, a property will be added to it
+ * if necessary.
+ */
+ _getRuleThirdParty: function(/**Filter*/ filter, /**Object*/ options)
+ {
+ if (filter.thirdParty !== null)
+ options.thirdParty = filter.thirdParty;
+ },
+
+ /**
+ * Converts an Adblock Plus filter to a rule that can be processed by
+ * Opera. The following options will be set:
+ *
+ * type: urlfilter to be used, either "allow" or "block"
+ * text: rule text
+ * options: rule options
+ */
+ _generateRule: function(/**Filter*/ filter) /**Object*/
+ {
+ if (!WhitelistFilter)
+ {
+ WhitelistFilter = require("filterClasses").WhitelistFilter;
+ RegExpFilter = require("filterClasses").RegExpFilter;
+ }
+
+ var rule = {
+ type: filter instanceof WhitelistFilter ? "allow" : "block",
+ text: this._getRuleText(filter),
+ options: {
+ resources: this._getRuleTypes(filter)
+ }
+ };
+ this._getRuleDomains(filter, rule.options);
+ this._getRuleThirdParty(filter, rule.options);
+ return rule;
+ },
+
+ add: function(filter)
+ {
+ if (filter.text in this._rules)
+ return;
+
+ var rule = this._generateRule(filter);
+ opera.extension.urlfilter[rule.type].add(rule.text, rule.options);
+ this._rules[filter.text] = rule;
+ },
+
+ remove: function(filter)
+ {
+ if (!(filter.text in this._rules))
+ return;
+
+ var rule = this._rules[filter.text];
+ opera.extension.urlfilter[rule.type].remove(rule.text);
+ delete this._rules[filter.text];
+ },
+
+ clear: function()
+ {
+ for (var text in this._rules)
+ {
+ var rule = this._rules[text];
+ opera.extension.urlfilter[rule.type].remove(rule.text);
+ }
+ this._rules = {};
+ }
+ }
+ };
+})();
« lib/adblockplus_compat.js ('K') | « lib/adblockplus_compat.js ('k') | subscriptions.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld