Left: | ||
Right: |
LEFT | RIGHT |
---|---|
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 })(); |
LEFT | RIGHT |