OLD | NEW |
(Empty) | |
| 1 /* |
| 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 |
| 4 * http://mozilla.org/MPL/2.0/. |
| 5 */ |
| 6 |
| 7 // |
| 8 // This mimicks the API of the Matcher module in ABP/Firefox but users Opera's |
| 9 // URLFilter API. |
| 10 // |
| 11 |
| 12 (function() |
| 13 { |
| 14 var WhitelistFilter = null; |
| 15 var RegExpFilter = null; |
| 16 var resourceTypes = [ |
| 17 "DOCUMENT", "FONT", "IMAGE", "MEDIA", "OBJECT", "OBJECT_SUBREQUEST", |
| 18 "OTHER", "SCRIPT", "STYLESHEET", "SUBDOCUMENT", "XMLHTTPREQUEST" |
| 19 ]; |
| 20 |
| 21 require.scopes.matcher = |
| 22 { |
| 23 defaultMatcher: |
| 24 { |
| 25 _rules: {}, |
| 26 |
| 27 /** |
| 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*/ |
| 33 { |
| 34 var text = filter.regexpSource; |
| 35 |
| 36 // |foo => foo |
| 37 // foo => *foo |
| 38 // *foo and ||foo stay unchanged |
| 39 if (text.substr(0, 2) != "||") |
| 40 { |
| 41 var start = text.substr(0, 1); |
| 42 if (start == "|") |
| 43 text = text.slice(1); |
| 44 else if (start != "*") |
| 45 text = "*" + text; |
| 46 } |
| 47 |
| 48 // foo| => foo |
| 49 // foo => foo* |
| 50 // foo* stays unchanged |
| 51 var end = text.substr(-1); |
| 52 if (end == "|") |
| 53 text = text.slice(0, -1); |
| 54 else if (end != "*") |
| 55 text = text + "*"; |
| 56 |
| 57 return text; |
| 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; |
| 66 var urlfilter = opera.extension.urlfilter; |
| 67 for (var i = 0; i < resourceTypes.length; i++) |
| 68 { |
| 69 var type = resourceTypes[i]; |
| 70 if (filter.contentType & RegExpFilter.typeMap[type]) |
| 71 types |= urlfilter["RESOURCE_" + type]; |
| 72 } |
| 73 return types; |
| 74 }, |
| 75 |
| 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 { |
| 83 if (filter.domainSource) |
| 84 { |
| 85 var domains = filter.domainSource.split(filter.domainSeparator); |
| 86 for (var i = 0; i < domains.length; i++) |
| 87 { |
| 88 var domain = domains[i]; |
| 89 if (domain == "") |
| 90 continue; |
| 91 |
| 92 var type = "includeDomains"; |
| 93 if (domain[0] == "~") |
| 94 { |
| 95 type = "excludeDomains"; |
| 96 domain = domain.substr(1); |
| 97 } |
| 98 if (!(type in options)) |
| 99 options[type] = []; |
| 100 options[type].push(domain); |
| 101 } |
| 102 } |
| 103 }, |
| 104 |
| 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 { |
| 112 if (filter.thirdParty !== null) |
| 113 options.thirdParty = filter.thirdParty; |
| 114 }, |
| 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); |
| 141 return rule; |
| 142 }, |
| 143 |
| 144 add: function(filter) |
| 145 { |
| 146 if (filter.text in this._rules) |
| 147 return; |
| 148 |
| 149 var rule = this._generateRule(filter); |
| 150 opera.extension.urlfilter[rule.type].add(rule.text, rule.options); |
| 151 this._rules[filter.text] = rule; |
| 152 }, |
| 153 |
| 154 remove: function(filter) |
| 155 { |
| 156 if (!(filter.text in this._rules)) |
| 157 return; |
| 158 |
| 159 var rule = this._rules[filter.text]; |
| 160 opera.extension.urlfilter[rule.type].remove(rule.text); |
| 161 delete this._rules[filter.text]; |
| 162 }, |
| 163 |
| 164 clear: function() |
| 165 { |
| 166 for (var text in this._rules) |
| 167 { |
| 168 var rule = this._rules[text]; |
| 169 opera.extension.urlfilter[rule.type].remove(rule.text); |
| 170 } |
| 171 this._rules = {}; |
| 172 } |
| 173 } |
| 174 }; |
| 175 })(); |
OLD | NEW |