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

Delta Between Two Patch Sets: lib/matcher.js

Issue 8483154: Adding ABP core modules to ABP/Opera (Closed)
Left Patch Set: Created Oct. 9, 2012, 9:51 a.m.
Right Patch Set: Created Oct. 11, 2012, 9:35 a.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
LEFTRIGHT
1 /* 1 /*
2 * This Source Code is subject to the terms of the Mozilla Public License 2 * This Source Code is subject to the terms of the Mozilla Public License
3 * version 2.0 (the "License"). You can obtain a copy of the License at 3 * version 2.0 (the "License"). You can obtain a copy of the License at
4 * http://mozilla.org/MPL/2.0/. 4 * http://mozilla.org/MPL/2.0/.
5 */ 5 */
6 6
7 // 7 //
8 // This mimicks the API of the Matcher module in ABP/Firefox but users Opera's 8 // This mimicks the API of the Matcher module in ABP/Firefox but users Opera's
9 // URLFilter API. 9 // URLFilter API.
10 // 10 //
11 11
12 (function() 12 (function()
13 { 13 {
14 var WhitelistFilter = null; 14 var WhitelistFilter = null;
15 var RegExpFilter = null; 15 var RegExpFilter = null;
16 var resourceTypes = [ 16 var resourceTypes = [
17 "DOCUMENT", "FONT", "IMAGE", "MEDIA", "OBJECT", "OBJECT_SUBREQUEST", 17 "DOCUMENT", "FONT", "IMAGE", "MEDIA", "OBJECT", "OBJECT_SUBREQUEST",
18 "OTHER", "SCRIPT", "STYLESHEET", "SUBDOCUMENT", "XMLHTTPREQUEST" 18 "OTHER", "SCRIPT", "STYLESHEET", "SUBDOCUMENT", "XMLHTTPREQUEST"
19 ]; 19 ];
20 20
21 require.scopes.matcher = 21 require.scopes.matcher =
22 { 22 {
23 defaultMatcher: 23 defaultMatcher:
24 { 24 {
25 _rules: {}, 25 _rules: {},
26 26
27 _generateRule: function(filter) 27 /**
Felix Dahlke 2012/10/10 12:11:22 I'd love it if the code segments below comments ("
28 * Converts rule text from Adblock Plus format (implicit * at beginning
29 * and end of the rule unless there is an anchor) to Opera format (* has
30 * to be specified explicitly).
31 */
32 _getRuleText: function(/**Filter*/ filter) /**String*/
28 { 33 {
29 if (!WhitelistFilter) 34 var text = filter.regexpSource;
30 {
31 WhitelistFilter = require("filterClasses").WhitelistFilter;
32 RegExpFilter = require("filterClasses").RegExpFilter;
33 }
34
35 var rule = {
36 type: filter instanceof WhitelistFilter ? "allow" : "block",
37 text: filter.regexpSource,
38 options: {}
39 };
40
41 // Convert anchors, Opera requires explicit *
42 35
43 // |foo => foo 36 // |foo => foo
44 // foo => *foo 37 // foo => *foo
45 // *foo and ||foo stay unchanged 38 // *foo and ||foo stay unchanged
46 if (rule.text.substr(0, 2) != "||") 39 if (text.substr(0, 2) != "||")
47 { 40 {
48 if (rule.text.substr(0, 1) == "|") 41 var start = text.substr(0, 1);
Felix Dahlke 2012/10/10 12:11:22 This value is used twice, so how about storing it
49 rule.text = rule.text.slice(1); 42 if (start == "|")
50 else if (rule.text.substr(0, 1) != "*") 43 text = text.slice(1);
51 rule.text = "*" + rule.text; 44 else if (start != "*")
45 text = "*" + text;
52 } 46 }
53 47
54 // foo| => foo 48 // foo| => foo
55 // foo => foo* 49 // foo => foo*
56 // foo* stays unchanged 50 // foo* stays unchanged
57 if (rule.text.substr(-1) == "|") 51 var end = text.substr(-1);
Felix Dahlke 2012/10/10 12:11:22 As above, how about storing this in a variable las
58 rule.text = rule.text.slice(0, -1); 52 if (end == "|")
59 else if (rule.text.substr(-1) != "*") 53 text = text.slice(0, -1);
60 rule.text = rule.text + "*"; 54 else if (end != "*")
55 text = text + "*";
61 56
62 // Translate type options 57 return text;
63 var resources = 0; 58 },
59
60 /**
61 * Converts type options of a filter into a bit mask as expected by Opera.
62 */
63 _getRuleTypes: function(/**Filter*/ filter) /**Integer*/
64 {
65 var types = 0;
64 var urlfilter = opera.extension.urlfilter; 66 var urlfilter = opera.extension.urlfilter;
65 for (var i = 0; i < resourceTypes.length; i++) 67 for (var i = 0; i < resourceTypes.length; i++)
66 { 68 {
67 var type = resourceTypes[i]; 69 var type = resourceTypes[i];
68 if (filter.contentType & RegExpFilter.typeMap[type]) 70 if (filter.contentType & RegExpFilter.typeMap[type])
69 resources = resources | urlfilter["RESOURCE_" + type]; 71 types |= urlfilter["RESOURCE_" + type];
Felix Dahlke 2012/10/10 12:11:22 How about: resources |= urlfilter["RESOURCE_" + ty
Wladimir Palant 2012/10/11 09:36:26 I thought that JavaScript doesn't support |= but i
70 } 72 }
71 rule.options.resources = resources; 73 return types;
74 },
72 75
73 // Translate domain options 76 /**
77 * Converts domain options of a filter into includeDomains/excludeDomains
78 * options as expected by Opera. The options object has to be passed in,
79 * properties will be added to it if necessary.
80 */
81 _getRuleDomains: function(/**Filter*/ filter, /**Object*/ options)
82 {
74 if (filter.domainSource) 83 if (filter.domainSource)
75 { 84 {
76 var domains = filter.domainSource.split(filter.domainSeparator); 85 var domains = filter.domainSource.split(filter.domainSeparator);
77 for (var i = 0; i < domains.length; i++) 86 for (var i = 0; i < domains.length; i++)
78 { 87 {
79 var domain = domains[i]; 88 var domain = domains[i];
80 if (domain == "") 89 if (domain == "")
81 continue; 90 continue;
82 91
83 var type = "includeDomains"; 92 var type = "includeDomains";
84 if (domain[0] == "~") 93 if (domain[0] == "~")
85 { 94 {
86 type = "excludeDomains"; 95 type = "excludeDomains";
87 domain = domain.substr(1); 96 domain = domain.substr(1);
88 } 97 }
89 if (!(type in rule.options)) 98 if (!(type in options))
90 rule.options[type] = []; 99 options[type] = [];
91 rule.options[type].push(domain); 100 options[type].push(domain);
92 } 101 }
93 } 102 }
103 },
94 104
95 // Translate third-party option 105 /**
106 * Converts third-party filter option to the format expected by Opera.
107 * The options object has to be passed in, a property will be added to it
108 * if necessary.
109 */
110 _getRuleThirdParty: function(/**Filter*/ filter, /**Object*/ options)
111 {
96 if (filter.thirdParty !== null) 112 if (filter.thirdParty !== null)
97 rule.options.thirdParty = filter.thirdParty; 113 options.thirdParty = filter.thirdParty;
114 },
98 115
116 /**
117 * Converts an Adblock Plus filter to a rule that can be processed by
118 * Opera. The following options will be set:
119 *
120 * type: urlfilter to be used, either "allow" or "block"
121 * text: rule text
122 * options: rule options
123 */
124 _generateRule: function(/**Filter*/ filter) /**Object*/
125 {
126 if (!WhitelistFilter)
127 {
128 WhitelistFilter = require("filterClasses").WhitelistFilter;
129 RegExpFilter = require("filterClasses").RegExpFilter;
130 }
131
132 var rule = {
133 type: filter instanceof WhitelistFilter ? "allow" : "block",
134 text: this._getRuleText(filter),
135 options: {
136 resources: this._getRuleTypes(filter)
137 }
138 };
139 this._getRuleDomains(filter, rule.options);
140 this._getRuleThirdParty(filter, rule.options);
99 return rule; 141 return rule;
100 }, 142 },
101 143
102 add: function(filter) 144 add: function(filter)
103 { 145 {
104 if (filter.text in this._rules) 146 if (filter.text in this._rules)
105 return; 147 return;
106 148
107 var rule = this._generateRule(filter); 149 var rule = this._generateRule(filter);
108 if (filter.text == "http://")
Felix Dahlke 2012/10/10 12:11:22 Why just check for the string "http://" here? Woul
Wladimir Palant 2012/10/11 09:36:26 This is just debugging code I forgot :)
109 Cu.reportError(JSON.stringify(rule));
110 opera.extension.urlfilter[rule.type].add(rule.text, rule.options); 150 opera.extension.urlfilter[rule.type].add(rule.text, rule.options);
111 this._rules[filter.text] = rule; 151 this._rules[filter.text] = rule;
112 }, 152 },
113 153
114 remove: function(filter) 154 remove: function(filter)
115 { 155 {
116 if (!(filter.text in this._rules)) 156 if (!(filter.text in this._rules))
117 return; 157 return;
118 158
119 var rule = this._rules[filter.text]; 159 var rule = this._rules[filter.text];
120 opera.extension.urlfilter[rule.type].remove(rule.text); 160 opera.extension.urlfilter[rule.type].remove(rule.text);
121 delete this._rules[filter.text]; 161 delete this._rules[filter.text];
122 }, 162 },
123 163
124 clear: function(filter) 164 clear: function()
125 { 165 {
126 for (var text in this._rules) 166 for (var text in this._rules)
127 { 167 {
128 var rule = this._rules[text]; 168 var rule = this._rules[text];
129 opera.extension.urlfilter[rule.type].remove(rule); 169 opera.extension.urlfilter[rule.type].remove(rule.text);
Felix Dahlke 2012/10/10 12:11:22 Shouldn't this be "remove(text)"?
130 } 170 }
131 this._rules = {}; 171 this._rules = {};
132 } 172 }
133 } 173 }
134 }; 174 };
135 })(); 175 })();
LEFTRIGHT

Powered by Google App Engine
This is Rietveld