| Left: | ||
| Right: | 
| 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-2015 Eyeo GmbH | 3 * Copyright (C) 2006-2015 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 let {Filter, InvalidFilter, ElemHideBase} = require("filterClasses"); | 20 let {Filter, InvalidFilter, ElemHideBase} = require("filterClasses"); | 
| 21 | 21 | 
| 22 function isValidCSSSelector(selector) | |
| 23 { | |
| 24 let style = document.createElement("style"); | |
| 25 document.documentElement.appendChild(style); | |
| 26 let sheet = style.sheet; | |
| 27 document.documentElement.removeChild(style); | |
| 28 | |
| 29 try | |
| 30 { | |
| 31 document.querySelector(selector); | |
| 32 sheet.insertRule(selector + "{}", 0); | |
| 33 } | |
| 34 catch (e) | |
| 35 { | |
| 36 return false; | |
| 37 } | |
| 38 return true; | |
| 39 } | |
| 40 | |
| 41 /** | |
| 42 * @typedef ParsedFilter | |
| 43 * @property {?Filter} [filter] The parsed filter is it is valid. Or null if | |
| 
 
kzar
2015/06/08 11:28:04
Nit: Typo "The parsed filter_if_ it is valid"
 
Sebastian Noack
2015/06/08 12:00:08
Done.
 
 | |
| 44 * the given string is empty or a filter list head er. | |
| 45 * @property {string} [error] An error message indicated that the filter cann ot | |
| 46 * be parsed or contains an invalid CSS selector. | |
| 47 */ | |
| 48 | |
| 49 let parseFilter = | |
| 22 /** | 50 /** | 
| 23 * Parses and validates a filter given by the user. | 51 * Parses and validates a filter given by the user. | 
| 24 * | 52 * | 
| 25 * @param {string} text | 53 * @param {string} text | 
| 26 * @param {Boolean} [ignoreHeaders=false] If true, no exception is raised | 54 * @param {Boolean} [ignoreHeaders=false] If true, no error is produced | 
| 27 * for filter list headers, instead | 55 * for filter list headers, instead | 
| 28 * the function will return null. | 56 * {filter: null} is returned. | 
| 29 * @return {Filter} | 57 * @return {ParsedFilter} | 
| 30 * @throws Will throw an exception if filter cannot be | |
| 31 * parsed or contains an invalid CSS selector. | |
| 32 * @static | |
| 33 */ | 58 */ | 
| 34 function parseFilter(text, ignoreHeaders) | 59 exports.parseFilter = function(text, ignoreHeaders) | 
| 35 { | 60 { | 
| 61 let filter = null; | |
| 36 text = Filter.normalize(text); | 62 text = Filter.normalize(text); | 
| 37 if (!text) | |
| 38 return null; | |
| 39 | 63 | 
| 40 if (text[0] == "[") | 64 if (text) | 
| 41 { | 65 { | 
| 42 if (ignoreHeaders) | 66 if (text[0] != "[") | 
| 43 return null; | 67 { | 
| 68 filter = Filter.fromText(text); | |
| 44 | 69 | 
| 45 throw ext.i18n.getMessage("unexpected_filter_list_header"); | 70 if (filter instanceof InvalidFilter) | 
| 46 } | 71 return {error: filter.reason}; | 
| 47 | 72 | 
| 48 let filter = Filter.fromText(text); | 73 if (filter instanceof ElemHideBase && !isValidCSSSelector(filter.selector) ) | 
| 49 | 74 return {error: ext.i18n.getMessage("invalid_css_selector", "'" + filter. selector + "'")}; | 
| 50 if (filter instanceof InvalidFilter) | 75 } | 
| 51 throw filter.reason; | 76 else if (!ignoreHeaders) | 
| 52 | |
| 53 if (filter instanceof ElemHideBase) | |
| 54 { | |
| 55 let style = document.createElement("style"); | |
| 56 document.documentElement.appendChild(style); | |
| 57 let sheet = style.sheet; | |
| 58 document.documentElement.removeChild(style); | |
| 59 | |
| 60 try | |
| 61 { | 77 { | 
| 62 document.querySelector(filter.selector); | 78 return {error: ext.i18n.getMessage("unexpected_filter_list_header")}; | 
| 63 sheet.insertRule(filter.selector + "{}", 0); | |
| 64 } | |
| 65 catch (error) | |
| 66 { | |
| 67 throw ext.i18n.getMessage("invalid_css_selector", "'" + filter.selector + "'"); | |
| 68 } | 79 } | 
| 69 } | 80 } | 
| 70 | 81 | 
| 71 return filter; | 82 return {filter: filter}; | 
| 72 } | 83 }; | 
| 73 exports.parseFilter = parseFilter; | 84 | 
| 85 /** | |
| 86 * @typedef ParsedFilters | |
| 87 * @property {Filter[]} [filters] The parsed filters if all of them are valid. | |
| 88 * @property {string} [error] An error message indicated that any filter ca nnot | |
| 89 * be parsed or contains an invalid CSS selector . | |
| 90 */ | |
| 74 | 91 | 
| 75 /** | 92 /** | 
| 76 * Parses and validates a newline-separated list of filters given by the user. | 93 * Parses and validates a newline-separated list of filters given by the user. | 
| 77 * | 94 * | 
| 78 * @param {string} text | 95 * @param {string} text | 
| 79 * @param {Boolean} [ignoreHeaders=false] If true, filter list headers | 96 * @param {Boolean} [ignoreHeaders=false] If true, filter list headers | 
| 80 * will be stripped instead of | 97 * will be stripped instead of | 
| 81 * raising an exception. | 98 * producing an error. | 
| 
 
kzar
2015/06/08 11:28:04
Nit: "returning"?
 
Sebastian Noack
2015/06/08 12:00:08
I did not say to "return" an error, because strict
 
 | |
| 82 * @return {Filter[]} | 99 * @return {ParsedFilters} | 
| 83 * @throws Will throw an exception if one of the filters cannot | |
| 84 be parsed or contains an invalid CSS selector. | |
| 85 */ | 100 */ | 
| 86 exports.parseFilters = function(text, ignoreHeaders) | 101 exports.parseFilters = function(text, ignoreHeaders) | 
| 87 { | 102 { | 
| 88 let lines = text.split("\n"); | 103 let lines = text.split("\n"); | 
| 89 let filters = []; | 104 let filters = []; | 
| 90 | 105 | 
| 91 for (let i = 0; i < lines.length; i++) | 106 for (let i = 0; i < lines.length; i++) | 
| 92 { | 107 { | 
| 93 let filter; | 108 let {filter, error} = parseFilter(lines[i], ignoreHeaders); | 
| 94 try | 109 | 
| 95 { | 110 if (error) | 
| 96 filter = parseFilter(lines[i], ignoreHeaders); | 111 return {error: ext.i18n.getMessage("line", (i + 1).toString()) + ": " + er ror}; | 
| 97 } | |
| 98 catch (error) | |
| 99 { | |
| 100 throw ext.i18n.getMessage("line", (i + 1).toString()) + ": " + error; | |
| 101 } | |
| 102 | 112 | 
| 103 if (filter) | 113 if (filter) | 
| 
 
kzar
2015/06/08 11:28:04
Nit: Should be `else if (filter)` IMO
 
Sebastian Noack
2015/06/08 12:00:08
No, it shouldn't. The else would be redundant, as
 
 | |
| 104 filters.push(filter); | 114 filters.push(filter); | 
| 105 } | 115 } | 
| 106 | 116 | 
| 107 return filters; | 117 return {filters: filters}; | 
| 108 }; | 118 }; | 
| OLD | NEW |