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

Delta Between Two Patch Sets: lib/matcher.js

Issue 8790183: Added handling of whitelisting rules like @@||example.com^$document (Closed)
Left Patch Set: Created Nov. 14, 2012, 12:30 p.m.
Right Patch Set: Created Nov. 14, 2012, 1:46 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « background.js ('k') | options.html » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* 1 /*
2 * This file is part of the Adblock Plus extension, 2 * This file is part of the Adblock Plus extension,
3 * Copyright (C) 2006-2012 Eyeo GmbH 3 * Copyright (C) 2006-2012 Eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 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 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
(...skipping 18 matching lines...) Expand all
29 29
30 var WhitelistFilter = null; 30 var WhitelistFilter = null;
31 var RegExpFilter = null; 31 var RegExpFilter = null;
32 var resourceTypes = [ 32 var resourceTypes = [
33 "FONT", "IMAGE", "MEDIA", "OBJECT", "OBJECT_SUBREQUEST", 33 "FONT", "IMAGE", "MEDIA", "OBJECT", "OBJECT_SUBREQUEST",
34 "OTHER", "SCRIPT", "STYLESHEET", "SUBDOCUMENT", "XMLHTTPREQUEST" 34 "OTHER", "SCRIPT", "STYLESHEET", "SUBDOCUMENT", "XMLHTTPREQUEST"
35 ]; 35 ];
36 36
37 require.scopes.matcher = 37 require.scopes.matcher =
38 { 38 {
39 init: function()
40 {
41 WhitelistFilter = require("filterClasses").WhitelistFilter;
42 RegExpFilter = require("filterClasses").RegExpFilter;
43 },
44
39 defaultMatcher: 45 defaultMatcher:
40 { 46 {
41 _rules: {}, 47 _rules: {},
42 _domainExceptions: {}, 48 _domainExceptions: {},
43 _domainExceptionsTimeout: null, 49 _domainExceptionsTimeout: null,
44 50
45 /** 51 /**
46 * Converts rule text from Adblock Plus format (implicit * at beginning 52 * Converts rule text from Adblock Plus format (implicit * at beginning
47 * and end of the rule unless there is an anchor) to Opera format (* has 53 * and end of the rule unless there is an anchor) to Opera format (* has
48 * to be specified explicitly). 54 * to be specified explicitly).
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 options: { 153 options: {
148 resources: this._getRuleTypes(filter) 154 resources: this._getRuleTypes(filter)
149 } 155 }
150 }; 156 };
151 this._getRuleDomains(filter, rule.options); 157 this._getRuleDomains(filter, rule.options);
152 this._getRuleThirdParty(filter, rule.options); 158 this._getRuleThirdParty(filter, rule.options);
153 return rule; 159 return rule;
154 }, 160 },
155 161
156 /** 162 /**
157 * Extracts the domain to which the exception applies if any. 163 * Checks whether the filter is a domain exception and adds/removes it
158 */ 164 * according to the add parameter. Returns true if a domain exception
159 _getDomainFromException: function(/**Filter*/ filter) /**String*/ 165 * has been processed, false otherwise.
160 { 166 */
161 if (filter.domainSource) 167 _processDomainException: function(/**Filter*/ filter, /**Boolean*/ add) /* *Boolean*/
162 return null; 168 {
169 if (!(filter instanceof WhitelistFilter) ||
170 filter.contentType != RegExpFilter.typeMap.DOCUMENT ||
171 filter.domainSource)
172 {
173 return false;
174 }
163 175
164 var match = /^\|\|([^\/]+)\^$/.exec(filter.regexpSource); 176 var match = /^\|\|([^\/]+)\^$/.exec(filter.regexpSource);
165 if (!match) 177 if (!match)
166 return null; 178 return false;
167 179
168 return match[1]; 180 var domain = match[1];
169 }, 181 if (add)
170 182 this._domainExceptions[domain] = true;
171 /** 183 else
172 * Adds a global exception for a particular document domain. 184 delete this._domainExceptions[domain];
173 */ 185
174 _addDomainException: function(/**String*/ domain) 186 this._updateDomainExceptions();
175 { 187 return true;
176 this._domainExceptions[domain] = true; 188 },
177 189
178 // Update domain exceptions rule delayed to prevent multiple subsequent 190 /**
179 // updates. 191 * Updates domain exceptions rule, execution happens delayed to prevent
192 * multiple subsequent updates.
193 */
194 _updateDomainExceptions: function()
195 {
180 if (this._domainExceptionsTimeout) 196 if (this._domainExceptionsTimeout)
181 window.clearTimeout(this._domainExceptionsTimeout); 197 window.clearTimeout(this._domainExceptionsTimeout);
182 this._domainExceptionsTimeout = window.setTimeout(this._updateDomainExce ptions.bind(this), 0); 198
183 }, 199 this._domainExceptionsTimeout = window.setTimeout(function()
184 200 {
185 /** 201 this._domainExceptionsTimeout = null;
186 * Removes a global exception for a particular document domain. 202 opera.extension.urlfilter.allow.remove("*:*");
187 */ 203
188 _removeDomainException: function(/**String*/ domain) 204 var domains = Object.keys(this._domainExceptions);
189 { 205 if (domains.length)
190 delete this._domainExceptions[domain]; 206 {
191 207 opera.extension.urlfilter.allow.add("*:*", {
192 // Update domain exceptions rule delayed to prevent multiple subsequent 208 includeDomains: domains
193 // updates. 209 });
194 if (this._domainExceptionsTimeout) 210 }
195 window.clearTimeout(this._domainExceptionsTimeout); 211 }.bind(this), 0);
196 this._domainExceptionsTimeout = window.setTimeout(this._updateDomainExce ptions.bind(this), 0);
197 },
198
199 /**
200 * Updates domain exceptions rule (should be called delayed).
201 */
202 _updateDomainExceptions: function()
203 {
204 this._domainExceptionsTimeout = null;
205 opera.extension.urlfilter.allow.remove("*:*");
206
207 var domains = Object.keys(this._domainExceptions);
208 if (domains.length)
209 {
210 opera.extension.urlfilter.allow.add("*:*", {
211 includeDomains: domains
212 });
213 }
214 }, 212 },
215 213
216 add: function(filter) 214 add: function(filter)
217 { 215 {
218 if (!WhitelistFilter) 216 if (this._processDomainException(filter, true))
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
219 { 217 return;
220 WhitelistFilter = require("filterClasses").WhitelistFilter;
221 RegExpFilter = require("filterClasses").RegExpFilter;
222 }
223
224 if (filter instanceof WhitelistFilter && filter.contentType == RegExpFil ter.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
225 {
226 var domain = this._getDomainFromException(filter);
227 if (domain)
228 this._addDomainException(domain);
229 }
230 218
231 if (filter.text in this._rules) 219 if (filter.text in this._rules)
232 return; 220 return;
233 221
234 if (!filter.regexpSource) // Regular expressions aren't supported 222 if (!filter.regexpSource) // Regular expressions aren't supported
235 return; 223 return;
236 224
237 var rule = this._generateRule(filter); 225 var rule = this._generateRule(filter);
238 opera.extension.urlfilter[rule.type].add(rule.text, rule.options); 226 opera.extension.urlfilter[rule.type].add(rule.text, rule.options);
239 this._rules[filter.text] = rule; 227 this._rules[filter.text] = rule;
240 }, 228 },
241 229
242 remove: function(filter) 230 remove: function(filter)
243 { 231 {
244 if (filter instanceof WhitelistFilter && filter.contentType == RegExpFil ter.typeMap.DOCUMENT) 232 if (this._processDomainException(filter, false))
245 { 233 return;
246 var domain = this._getDomainFromException(filter);
247 if (domain)
248 this._removeDomainException(domain);
249 }
250 234
251 if (!(filter.text in this._rules)) 235 if (!(filter.text in this._rules))
252 return; 236 return;
253 237
254 var rule = this._rules[filter.text]; 238 var rule = this._rules[filter.text];
255 opera.extension.urlfilter[rule.type].remove(rule.text); 239 opera.extension.urlfilter[rule.type].remove(rule.text);
256 delete this._rules[filter.text]; 240 delete this._rules[filter.text];
257 }, 241 },
258 242
259 clear: function() 243 clear: function()
260 { 244 {
261 for (var text in this._rules) 245 for (var text in this._rules)
262 { 246 {
263 var rule = this._rules[text]; 247 var rule = this._rules[text];
264 opera.extension.urlfilter[rule.type].remove(rule.text); 248 opera.extension.urlfilter[rule.type].remove(rule.text);
265 } 249 }
266 this._rules = {}; 250 this._rules = {};
267 251
268 for (var domain in this._domainExceptions)
269 this._removeDomainException(domain);
270 this._domainExceptions = {}; 252 this._domainExceptions = {};
253 this._updateDomainExceptions();
271 } 254 }
272 } 255 }
273 }; 256 };
274 })(); 257 })();
LEFTRIGHT

Powered by Google App Engine
This is Rietveld