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

Unified Diff: lib/matcher.js

Issue 8790183: Added handling of whitelisting rules like @@||example.com^$document (Closed)
Patch Set: Created Nov. 14, 2012, 12:30 p.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
« no previous file with comments | « no previous file | options.html » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/matcher.js
===================================================================
--- a/lib/matcher.js
+++ b/lib/matcher.js
@@ -25,25 +25,27 @@
// Make sure that filters don't apply to extension pages. We shouldn't allow
// users to break our options page unintentionally, recovering is very hard
// if they do.
opera.extension.urlfilter.allow.add("widget://*");
var WhitelistFilter = null;
var RegExpFilter = null;
var resourceTypes = [
- "DOCUMENT", "FONT", "IMAGE", "MEDIA", "OBJECT", "OBJECT_SUBREQUEST",
+ "FONT", "IMAGE", "MEDIA", "OBJECT", "OBJECT_SUBREQUEST",
"OTHER", "SCRIPT", "STYLESHEET", "SUBDOCUMENT", "XMLHTTPREQUEST"
];
require.scopes.matcher =
{
defaultMatcher:
{
_rules: {},
+ _domainExceptions: {},
+ _domainExceptionsTimeout: null,
/**
* 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*/
{
@@ -134,61 +136,139 @@
* 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;
},
+ /**
+ * Extracts the domain to which the exception applies if any.
+ */
+ _getDomainFromException: function(/**Filter*/ filter) /**String*/
+ {
+ if (filter.domainSource)
+ return null;
+
+ var match = /^\|\|([^\/]+)\^$/.exec(filter.regexpSource);
+ if (!match)
+ return null;
+
+ return match[1];
+ },
+
+ /**
+ * Adds a global exception for a particular document domain.
+ */
+ _addDomainException: function(/**String*/ domain)
+ {
+ this._domainExceptions[domain] = true;
+
+ // Update domain exceptions rule delayed to prevent multiple subsequent
+ // updates.
+ if (this._domainExceptionsTimeout)
+ window.clearTimeout(this._domainExceptionsTimeout);
+ this._domainExceptionsTimeout = window.setTimeout(this._updateDomainExceptions.bind(this), 0);
+ },
+
+ /**
+ * Removes a global exception for a particular document domain.
+ */
+ _removeDomainException: function(/**String*/ domain)
+ {
+ delete this._domainExceptions[domain];
+
+ // Update domain exceptions rule delayed to prevent multiple subsequent
+ // updates.
+ if (this._domainExceptionsTimeout)
+ window.clearTimeout(this._domainExceptionsTimeout);
+ this._domainExceptionsTimeout = window.setTimeout(this._updateDomainExceptions.bind(this), 0);
+ },
+
+ /**
+ * Updates domain exceptions rule (should be called delayed).
+ */
+ _updateDomainExceptions: function()
+ {
+ this._domainExceptionsTimeout = null;
+ opera.extension.urlfilter.allow.remove("*:*");
+
+ var domains = Object.keys(this._domainExceptions);
+ if (domains.length)
+ {
+ opera.extension.urlfilter.allow.add("*:*", {
+ includeDomains: domains
+ });
+ }
+ },
+
add: function(filter)
{
+ if (!WhitelistFilter)
Felix Dahlke 2012/11/14 13:03:51 Not a new problem, but can't we do this earlier? B
Wladimir Palant 2012/11/14 13:46:53 Yes, it's ugly. Problem is that matcher.js needs t
+ {
+ WhitelistFilter = require("filterClasses").WhitelistFilter;
+ RegExpFilter = require("filterClasses").RegExpFilter;
+ }
+
+ if (filter instanceof WhitelistFilter && filter.contentType == RegExpFilter.typeMap.DOCUMENT)
Felix Dahlke 2012/11/14 13:03:51 I'd like a function for both this check and the _g
Wladimir Palant 2012/11/14 13:46:53 Ok, I changed the solution to have maximal code re
+ {
+ var domain = this._getDomainFromException(filter);
+ if (domain)
+ this._addDomainException(domain);
+ }
+
if (filter.text in this._rules)
return;
if (!filter.regexpSource) // Regular expressions aren't supported
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 instanceof WhitelistFilter && filter.contentType == RegExpFilter.typeMap.DOCUMENT)
+ {
+ var domain = this._getDomainFromException(filter);
+ if (domain)
+ this._removeDomainException(domain);
+ }
+
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 = {};
+
+ for (var domain in this._domainExceptions)
+ this._removeDomainException(domain);
+ this._domainExceptions = {};
}
}
};
})();
« no previous file with comments | « no previous file | options.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld