OLD | NEW |
1 /* | 1 /* |
2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
3 * Copyright (C) 2006-2017 eyeo GmbH | 3 * Copyright (C) 2006-2017 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 |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU General Public License | 14 * You should have received a copy of the GNU General Public License |
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
16 */ | 16 */ |
17 | 17 |
18 /* globals filterToRegExp */ | 18 /* globals filterToRegExp */ |
19 | 19 |
20 "use strict"; | 20 "use strict"; |
21 | 21 |
22 let propertySelectorRegExp = /\[-abp-properties=(["'])([^"']+)\1\]/; | 22 const abpSelectorRegexp = /:-abp-([\w-]+)\(/i; |
23 | 23 |
24 function splitSelector(selector) | 24 function splitSelector(selector) |
25 { | 25 { |
26 if (selector.indexOf(",") == -1) | 26 if (selector.indexOf(",") == -1) |
27 return [selector]; | 27 return [selector]; |
28 | 28 |
29 let selectors = []; | 29 let selectors = []; |
30 let start = 0; | 30 let start = 0; |
31 let level = 0; | 31 let level = 0; |
32 let sep = ""; | 32 let sep = ""; |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 this.addSelectors([stylesheet]); | 143 this.addSelectors([stylesheet]); |
144 }, | 144 }, |
145 | 145 |
146 apply() | 146 apply() |
147 { | 147 { |
148 this.getFiltersFunc(patterns => | 148 this.getFiltersFunc(patterns => |
149 { | 149 { |
150 this.patterns = []; | 150 this.patterns = []; |
151 for (let pattern of patterns) | 151 for (let pattern of patterns) |
152 { | 152 { |
153 let match = propertySelectorRegExp.exec(pattern.selector); | 153 let match = abpSelectorRegexp.exec(pattern.selector); |
154 if (!match) | 154 if (!match || match[1] != "properties") |
| 155 { |
| 156 console.error(new SyntaxError( |
| 157 `Failed to parse Adblock Plus selector ${pattern.selector}, ` + |
| 158 `invalid pseudo-class :-abp-${match[1]}().` |
| 159 )); |
155 continue; | 160 continue; |
| 161 } |
156 | 162 |
157 let propertyExpression = match[2]; | 163 let expressionStart = match.index + match[0].length; |
| 164 let parens = 1; |
| 165 let quote = null; |
| 166 let i; |
| 167 for (i = expressionStart; i < pattern.selector.length; i++) |
| 168 { |
| 169 let c = pattern.selector[i]; |
| 170 if (c == "\\") |
| 171 { |
| 172 // Ignore escaped characters |
| 173 i++; |
| 174 } |
| 175 else if (quote) |
| 176 { |
| 177 if (c == quote) |
| 178 quote = null; |
| 179 } |
| 180 else if (c == "'" || c == '"') |
| 181 quote = c; |
| 182 else if (c == "(") |
| 183 parens++; |
| 184 else if (c == ")") |
| 185 { |
| 186 parens--; |
| 187 if (parens == 0) |
| 188 break; |
| 189 } |
| 190 } |
| 191 |
| 192 if (parens > 0) |
| 193 { |
| 194 console.error(new SyntaxError( |
| 195 `Failed to parse Adblock Plus selector ${pattern.selector} ` + |
| 196 "due to unmatched parentheses." |
| 197 )); |
| 198 continue; |
| 199 } |
| 200 |
| 201 let propertyExpression = pattern.selector.substring(expressionStart, i); |
158 let regexpString; | 202 let regexpString; |
159 if (propertyExpression.length >= 2 && propertyExpression[0] == "/" && | 203 if (propertyExpression.length >= 2 && propertyExpression[0] == "/" && |
160 propertyExpression[propertyExpression.length - 1] == "/") | 204 propertyExpression[propertyExpression.length - 1] == "/") |
161 { | 205 { |
162 regexpString = propertyExpression.slice(1, -1) | 206 regexpString = propertyExpression.slice(1, -1) |
163 .replace("\\x7B ", "{").replace("\\x7D ", "}"); | 207 .replace("\\x7B ", "{").replace("\\x7D ", "}"); |
164 } | 208 } |
165 else | 209 else |
166 regexpString = filterToRegExp(propertyExpression); | 210 regexpString = filterToRegExp(propertyExpression); |
167 | 211 |
168 this.patterns.push({ | 212 this.patterns.push({ |
169 text: pattern.text, | 213 text: pattern.text, |
170 regexp: new RegExp(regexpString, "i"), | 214 regexp: new RegExp(regexpString, "i"), |
171 prefix: pattern.selector.substr(0, match.index), | 215 prefix: pattern.selector.substr(0, match.index), |
172 suffix: pattern.selector.substr(match.index + match[0].length) | 216 suffix: pattern.selector.substr(i + 1) |
173 }); | 217 }); |
174 } | 218 } |
175 | 219 |
176 if (this.patterns.length > 0) | 220 if (this.patterns.length > 0) |
177 { | 221 { |
178 let {document} = this.window; | 222 let {document} = this.window; |
179 this.addSelectors(document.styleSheets); | 223 this.addSelectors(document.styleSheets); |
180 document.addEventListener("load", this.onLoad.bind(this), true); | 224 document.addEventListener("load", this.onLoad.bind(this), true); |
181 } | 225 } |
182 }); | 226 }); |
183 } | 227 } |
184 }; | 228 }; |
OLD | NEW |