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-2016 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 /** @module filterValidation */ | 18 /** @module filterValidation */ |
19 | 19 |
20 "use strict"; | 20 "use strict"; |
21 | 21 |
22 const {Filter, InvalidFilter, ElemHideBase} = require("filterClasses"); | 22 const {Filter, InvalidFilter, ElemHideBase} = require("filterClasses"); |
23 const {Utils} = require("utils"); | 23 const {Utils} = require("utils"); |
24 | 24 |
25 /** | 25 /** |
26 * An error returned by | 26 * An error returned by |
27 * {@link module:filterValidation.parseFilter parseFilter()} or | 27 * {@link module:filterValidation.parseFilter parseFilter()} or |
28 * {@link module:filterValidation.parseFilters parseFilters()} | 28 * {@link module:filterValidation.parseFilters parseFilters()} |
29 * indicating that a given filter cannot be parsed, | 29 * indicating that a given filter cannot be parsed, |
30 * contains an invalid CSS selector or is a filter list header. | 30 * contains an invalid CSS selector or is a filter list header. |
31 * | 31 * |
| 32 * @param {string} type See documentation in the constructor below. |
| 33 * @param {Object} [details] Contains the "reason" and / or "selector" |
| 34 * properties. |
32 * @constructor | 35 * @constructor |
33 */ | 36 */ |
34 function FilterParsingError(type, details) | 37 function FilterParsingError(type, details) |
35 { | 38 { |
36 /** | 39 /** |
37 * Indicates why the filter is rejected. Possible choices: | 40 * Indicates why the filter is rejected. Possible choices: |
38 * "invalid-filter", "invalid-css-selector", "unexpected-filter-list-header" | 41 * "invalid-filter", "invalid-css-selector", "unexpected-filter-list-header" |
39 * | 42 * |
40 * @type {string} | 43 * @type {string} |
41 */ | 44 */ |
(...skipping 22 matching lines...) Expand all Loading... |
64 * Returns a detailed translated error message. | 67 * Returns a detailed translated error message. |
65 * | 68 * |
66 * @return {string} | 69 * @return {string} |
67 */ | 70 */ |
68 toString() | 71 toString() |
69 { | 72 { |
70 let message; | 73 let message; |
71 if (this.reason) | 74 if (this.reason) |
72 message = Utils.getString(this.reason); | 75 message = Utils.getString(this.reason); |
73 else | 76 else |
| 77 { |
74 message = ext.i18n.getMessage( | 78 message = ext.i18n.getMessage( |
75 this.type.replace(/-/g, "_"), | 79 this.type.replace(/-/g, "_"), |
76 "selector" in this ? "'" + this.selector + "'" : null | 80 "selector" in this ? "'" + this.selector + "'" : null |
77 ); | 81 ); |
| 82 } |
78 | 83 |
79 if (this.lineno) | 84 if (this.lineno) |
80 message = ext.i18n.getMessage("line", this.lineno.toLocaleString()) + ": "
+ message; | 85 { |
81 | 86 message = ext.i18n.getMessage( |
| 87 "line", this.lineno.toLocaleString() |
| 88 ) + ": " + message; |
| 89 } |
82 return message; | 90 return message; |
83 } | 91 } |
84 }; | 92 }; |
85 | 93 |
86 function isValidCSSSelector(selector) | 94 function isValidCSSSelector(selector) |
87 { | 95 { |
88 let style = document.createElement("style"); | 96 let style = document.createElement("style"); |
89 document.documentElement.appendChild(style); | 97 document.documentElement.appendChild(style); |
90 let sheet = style.sheet; | 98 let {sheet} = style; |
91 document.documentElement.removeChild(style); | 99 document.documentElement.removeChild(style); |
92 | 100 |
93 try | 101 try |
94 { | 102 { |
95 document.querySelector(selector); | 103 document.querySelector(selector); |
96 sheet.insertRule(selector + "{}", 0); | 104 sheet.insertRule(selector + "{}", 0); |
97 } | 105 } |
98 catch (e) | 106 catch (e) |
99 { | 107 { |
100 return false; | 108 return false; |
101 } | 109 } |
102 return true; | 110 return true; |
103 } | 111 } |
104 | 112 |
105 /** | 113 /** |
106 * @typedef ParsedFilter | 114 * @typedef ParsedFilter |
107 * @property {?Filter} [filter] The parsed filter if it is valid. | 115 * @property {?Filter} [filter] |
108 * Or null if the given string is empty. | 116 * The parsed filter if it is valid. Or null if the given string is empty. |
109 * @property {FilterParsingError} [error] See {@link module:filterValidation~Fi
lterParsingError FilterParsingError} | 117 * @property {FilterParsingError} [error] |
110 * | 118 * See {@link module:filterValidation~FilterParsingError FilterParsingError} |
111 */ | 119 */ |
112 | 120 |
113 let parseFilter = | 121 let parseFilter = |
114 /** | 122 /** |
115 * Parses and validates a filter given by the user. | 123 * Parses and validates a filter given by the user. |
116 * | 124 * |
117 * @param {string} text | 125 * @param {string} text |
118 * @return {ParsedFilter} | 126 * @return {ParsedFilter} |
119 */ | 127 */ |
120 exports.parseFilter = text => | 128 exports.parseFilter = text => |
121 { | 129 { |
122 let filter = null; | 130 let filter = null; |
123 text = Filter.normalize(text); | 131 text = Filter.normalize(text); |
124 | 132 |
125 if (text) | 133 if (text) |
126 { | 134 { |
127 if (text[0] == "[") | 135 if (text[0] == "[") |
128 return {error: new FilterParsingError("unexpected-filter-list-header")}; | 136 return {error: new FilterParsingError("unexpected-filter-list-header")}; |
129 | 137 |
130 filter = Filter.fromText(text); | 138 filter = Filter.fromText(text); |
131 | 139 |
132 if (filter instanceof InvalidFilter) | 140 if (filter instanceof InvalidFilter) |
133 return {error: new FilterParsingError("invalid-filter", {reason: filter.re
ason})}; | 141 { |
134 | 142 return {error: new FilterParsingError("invalid-filter", |
| 143 {reason: filter.reason})}; |
| 144 } |
135 if (filter instanceof ElemHideBase && !isValidCSSSelector(filter.selector)) | 145 if (filter instanceof ElemHideBase && !isValidCSSSelector(filter.selector)) |
136 return {error: new FilterParsingError("invalid-css-selector", {selector: f
ilter.selector})}; | 146 { |
| 147 return {error: new FilterParsingError("invalid-css-selector", |
| 148 {selector: filter.selector})}; |
| 149 } |
137 } | 150 } |
138 | 151 |
139 return {filter: filter}; | 152 return {filter}; |
140 }; | 153 }; |
141 | 154 |
142 /** | 155 /** |
143 * @typedef ParsedFilters | 156 * @typedef ParsedFilters |
144 * @property {Filter[]} filters The parsed result without invalid filters. | 157 * @property {Filter[]} filters |
145 * @property {FilterParsingError[]} errors See {@link module:filterValidation~F
ilterParsingError FilterParsingError} | 158 * The parsed result without invalid filters. |
| 159 * @property {FilterParsingError[]} errors |
| 160 * See {@link module:filterValidation~FilterParsingError FilterParsingError} |
146 */ | 161 */ |
147 | 162 |
148 /** | 163 /** |
149 * Parses and validates a newline-separated list of filters given by the user. | 164 * Parses and validates a newline-separated list of filters given by the user. |
150 * | 165 * |
151 * @param {string} text | 166 * @param {string} text |
152 * @return {ParsedFilters} | 167 * @return {ParsedFilters} |
153 */ | 168 */ |
154 exports.parseFilters = text => | 169 exports.parseFilters = text => |
155 { | 170 { |
156 let lines = text.split("\n"); | 171 let lines = text.split("\n"); |
157 let filters = []; | 172 let filters = []; |
158 let errors = []; | 173 let errors = []; |
159 | 174 |
160 for (let i = 0; i < lines.length; i++) | 175 for (let i = 0; i < lines.length; i++) |
161 { | 176 { |
162 let {filter, error} = parseFilter(lines[i]); | 177 let {filter, error} = parseFilter(lines[i]); |
163 | 178 |
164 if (filter) | 179 if (filter) |
165 filters.push(filter); | 180 filters.push(filter); |
166 | 181 |
167 if (error) | 182 if (error) |
168 { | 183 { |
169 error.lineno = i + 1; | 184 error.lineno = i + 1; |
170 errors.push(error); | 185 errors.push(error); |
171 } | 186 } |
172 } | 187 } |
173 | 188 |
174 return {filters: filters, errors: errors}; | 189 return {filters, errors}; |
175 }; | 190 }; |
OLD | NEW |