| 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-2016 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 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 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 20 matching lines...) Expand all Loading... |
| 62 | 65 |
| 63 /** | 66 /** |
| 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) |
| 75 { |
| 72 message = Utils.getString(this.reason); | 76 message = Utils.getString(this.reason); |
| 77 } |
| 73 else | 78 else |
| 79 { |
| 74 message = ext.i18n.getMessage( | 80 message = ext.i18n.getMessage( |
| 75 this.type.replace(/-/g, "_"), | 81 this.type.replace(/-/g, "_"), |
| 76 "selector" in this ? "'" + this.selector + "'" : null | 82 "selector" in this ? "'" + this.selector + "'" : null |
| 77 ); | 83 ); |
| 84 } |
| 78 | 85 |
| 79 if (this.lineno) | 86 if (this.lineno) |
| 80 message = ext.i18n.getMessage("line", this.lineno.toLocaleString()) + ": "
+ message; | 87 { |
| 81 | 88 message = ext.i18n.getMessage( |
| 89 "line", this.lineno.toLocaleString() |
| 90 ) + ": " + message; |
| 91 } |
| 82 return message; | 92 return message; |
| 83 } | 93 } |
| 84 }; | 94 }; |
| 85 | 95 |
| 86 function isValidCSSSelector(selector) | 96 function isValidCSSSelector(selector) |
| 87 { | 97 { |
| 88 let style = document.createElement("style"); | 98 let style = document.createElement("style"); |
| 89 document.documentElement.appendChild(style); | 99 document.documentElement.appendChild(style); |
| 90 let sheet = style.sheet; | 100 let {sheet} = style; |
| 91 document.documentElement.removeChild(style); | 101 document.documentElement.removeChild(style); |
| 92 | 102 |
| 93 try | 103 try |
| 94 { | 104 { |
| 95 document.querySelector(selector); | 105 document.querySelector(selector); |
| 96 sheet.insertRule(selector + "{}", 0); | 106 sheet.insertRule(selector + "{}", 0); |
| 97 } | 107 } |
| 98 catch (e) | 108 catch (e) |
| 99 { | 109 { |
| 100 return false; | 110 return false; |
| 101 } | 111 } |
| 102 return true; | 112 return true; |
| 103 } | 113 } |
| 104 | 114 |
| 105 /** | 115 /** |
| 106 * @typedef ParsedFilter | 116 * @typedef ParsedFilter |
| 107 * @property {?Filter} [filter] The parsed filter if it is valid. | 117 * @property {?Filter} [filter] The parsed filter if it is valid. |
| 108 * Or null if the given string is empty. | 118 * Or null if the given string is empty. |
| 109 * @property {FilterParsingError} [error] See {@link module:filterValidation~Fi
lterParsingError FilterParsingError} | 119 * @property {FilterParsingError} [error] |
| 110 * | 120 * See {@link module:filterValidation~FilterParsingError FilterParsingError} |
| 111 */ | 121 */ |
| 112 | 122 |
| 113 let parseFilter = | 123 let parseFilter = |
| 114 /** | 124 /** |
| 115 * Parses and validates a filter given by the user. | 125 * Parses and validates a filter given by the user. |
| 116 * | 126 * |
| 117 * @param {string} text | 127 * @param {string} text |
| 118 * @return {ParsedFilter} | 128 * @return {ParsedFilter} |
| 119 */ | 129 */ |
| 120 exports.parseFilter = text => | 130 exports.parseFilter = text => |
| 121 { | 131 { |
| 122 let filter = null; | 132 let filter = null; |
| 123 text = Filter.normalize(text); | 133 text = Filter.normalize(text); |
| 124 | 134 |
| 125 if (text) | 135 if (text) |
| 126 { | 136 { |
| 127 if (text[0] == "[") | 137 if (text[0] == "[") |
| 128 return {error: new FilterParsingError("unexpected-filter-list-header")}; | 138 return {error: new FilterParsingError("unexpected-filter-list-header")}; |
| 129 | 139 |
| 130 filter = Filter.fromText(text); | 140 filter = Filter.fromText(text); |
| 131 | 141 |
| 132 if (filter instanceof InvalidFilter) | 142 if (filter instanceof InvalidFilter) |
| 133 return {error: new FilterParsingError("invalid-filter", {reason: filter.re
ason})}; | 143 { |
| 134 | 144 return {error: new FilterParsingError("invalid-filter", |
| 145 {reason: filter.reason})}; |
| 146 } |
| 135 if (filter instanceof ElemHideBase && !isValidCSSSelector(filter.selector)) | 147 if (filter instanceof ElemHideBase && !isValidCSSSelector(filter.selector)) |
| 136 return {error: new FilterParsingError("invalid-css-selector", {selector: f
ilter.selector})}; | 148 { |
| 149 return {error: new FilterParsingError("invalid-css-selector", |
| 150 {selector: filter.selector})}; |
| 151 } |
| 137 } | 152 } |
| 138 | 153 |
| 139 return {filter: filter}; | 154 return {filter}; |
| 140 }; | 155 }; |
| 141 | 156 |
| 142 /** | 157 /** |
| 143 * @typedef ParsedFilters | 158 * @typedef ParsedFilters |
| 144 * @property {Filter[]} filters The parsed result without invalid filters. | 159 * @property {Filter[]} filters The parsed result without invalid filters. |
| 145 * @property {FilterParsingError[]} errors See {@link module:filterValidation~F
ilterParsingError FilterParsingError} | 160 * @property {FilterParsingError[]} errors |
| 161 * See {@link module:filterValidation~FilterParsingError FilterParsingError} |
| 146 */ | 162 */ |
| 147 | 163 |
| 148 /** | 164 /** |
| 149 * Parses and validates a newline-separated list of filters given by the user. | 165 * Parses and validates a newline-separated list of filters given by the user. |
| 150 * | 166 * |
| 151 * @param {string} text | 167 * @param {string} text |
| 152 * @return {ParsedFilters} | 168 * @return {ParsedFilters} |
| 153 */ | 169 */ |
| 154 exports.parseFilters = text => | 170 exports.parseFilters = text => |
| 155 { | 171 { |
| 156 let lines = text.split("\n"); | 172 let lines = text.split("\n"); |
| 157 let filters = []; | 173 let filters = []; |
| 158 let errors = []; | 174 let errors = []; |
| 159 | 175 |
| 160 for (let i = 0; i < lines.length; i++) | 176 for (let i = 0; i < lines.length; i++) |
| 161 { | 177 { |
| 162 let {filter, error} = parseFilter(lines[i]); | 178 let {filter, error} = parseFilter(lines[i]); |
| 163 | 179 |
| 164 if (filter) | 180 if (filter) |
| 165 filters.push(filter); | 181 filters.push(filter); |
| 166 | 182 |
| 167 if (error) | 183 if (error) |
| 168 { | 184 { |
| 169 error.lineno = i + 1; | 185 error.lineno = i + 1; |
| 170 errors.push(error); | 186 errors.push(error); |
| 171 } | 187 } |
| 172 } | 188 } |
| 173 | 189 |
| 174 return {filters: filters, errors: errors}; | 190 return {filters, errors}; |
| 175 }; | 191 }; |
| OLD | NEW |