| 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 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 |