Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: lib/filterValidation.js

Issue 4515985834901504: Issue 2664 - Remove ignoreHeaders argument from parseFilter(s) and move the logic to the UI (Closed)
Patch Set: Created June 8, 2015, 4:46 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « background.js ('k') | options.js » ('j') | options.js » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 /**
23 * An error returned by
24 * {@link module:filterValidation.parseFilter parseFilter()} or
25 * {@link module:filterValidation.parseFilters parseFilters()}
26 * indicating that a given filter cannot be parsed,
27 * contains an invalid CSS selector or is a filter list header.
28 *
29 * @constructor
30 */
31 function FilterParsingError(type, details)
32 {
33 /**
34 * Indicates why the filter is rejected. Possible choices:
35 * "invalid-filter", "invalid-css-selector", "unexpected-filter-list-header"
36 *
37 * @type {string}
38 */
39 this.type = type;
40
41 if (details)
42 {
43 if ("reason" in details)
44 this.reason = details.reason;
45 if ("selector" in details)
46 this.selector = details.selector;
47 }
48 }
49 FilterParsingError.prototype = {
50 /**
51 * The line number the error occurred on if
52 * {@link module:filterValidation.parseFilters parseFilters()}
53 * were used. Or null if the error was returned by
54 * {@link module:filterValidation.parseFilter parseFilter()}.
55 *
56 * @type {?number}
57 */
58 lineno: null,
59
60 /**
61 * Returns a detailed translated error message.
62 *
63 * @return {string}
64 */
65 toString: function()
66 {
67 let message = this.reason || ext.i18n.getMessage(
68 this.type.replace(/-/g, "_"),
69 "selector" in this ? "'" + this.selector + "'" : null
70 );
71
72 if (this.lineno)
73 message = ext.i18n.getMessage("line", this.lineno.toLocaleString()) + ": " + message;
74
75 return message;
76 }
77 };
78
22 function isValidCSSSelector(selector) 79 function isValidCSSSelector(selector)
23 { 80 {
24 let style = document.createElement("style"); 81 let style = document.createElement("style");
25 document.documentElement.appendChild(style); 82 document.documentElement.appendChild(style);
26 let sheet = style.sheet; 83 let sheet = style.sheet;
27 document.documentElement.removeChild(style); 84 document.documentElement.removeChild(style);
28 85
29 try 86 try
30 { 87 {
31 document.querySelector(selector); 88 document.querySelector(selector);
32 sheet.insertRule(selector + "{}", 0); 89 sheet.insertRule(selector + "{}", 0);
33 } 90 }
34 catch (e) 91 catch (e)
35 { 92 {
36 return false; 93 return false;
37 } 94 }
38 return true; 95 return true;
39 } 96 }
40 97
41 /** 98 /**
42 * @typedef ParsedFilter 99 * @typedef ParsedFilter
43 * @property {?Filter} [filter] The parsed filter if it is valid. Or null if 100 * @property {?Filter} [filter] The parsed filter if it is valid.
44 * the given string is empty or a filter list head er. 101 * Or null if the given string is empty.
45 * @property {string} [error] An error message indicated that the filter cann ot 102 * @property {FilterParsingError} [error] See {@link module:filterValidation~Fi lterParsingError FilterParsingError}
46 * be parsed or contains an invalid CSS selector. 103 *
47 */ 104 */
48 105
49 let parseFilter = 106 let parseFilter =
50 /** 107 /**
51 * Parses and validates a filter given by the user. 108 * Parses and validates a filter given by the user.
52 * 109 *
53 * @param {string} text 110 * @param {string} text
54 * @param {Boolean} [ignoreHeaders=false] If true, {filter: null} is
55 returned instead an error
56 for filter list headers.
57 * @return {ParsedFilter} 111 * @return {ParsedFilter}
58 */ 112 */
59 exports.parseFilter = function(text, ignoreHeaders) 113 exports.parseFilter = function(text)
60 { 114 {
61 let filter = null; 115 let filter = null;
62 text = Filter.normalize(text); 116 text = Filter.normalize(text);
63 117
64 if (text) 118 if (text)
65 { 119 {
66 if (text[0] != "[") 120 if (text[0] == "[")
67 { 121 return {error: new FilterParsingError("unexpected-filter-list-header")};
68 filter = Filter.fromText(text);
69 122
70 if (filter instanceof InvalidFilter) 123 filter = Filter.fromText(text);
71 return {error: filter.reason};
72 124
73 if (filter instanceof ElemHideBase && !isValidCSSSelector(filter.selector) ) 125 if (filter instanceof InvalidFilter)
74 return {error: ext.i18n.getMessage("invalid_css_selector", "'" + filter. selector + "'")}; 126 return {error: new FilterParsingError("invalid-filter", {reason: filter.re ason})};
75 } 127
76 else if (!ignoreHeaders) 128 if (filter instanceof ElemHideBase && !isValidCSSSelector(filter.selector))
77 { 129 return {error: new FilterParsingError("invalid-css-selector", {selector: f ilter.selector})};
78 return {error: ext.i18n.getMessage("unexpected_filter_list_header")};
79 }
80 } 130 }
81 131
82 return {filter: filter}; 132 return {filter: filter};
83 }; 133 };
84 134
85 /** 135 /**
86 * @typedef ParsedFilters 136 * @typedef ParsedFilters
87 * @property {Filter[]} [filters] The parsed filters if all of them are valid. 137 * @property {Filter[]} filters The parsed result without invalid filters.
88 * @property {string} [error] An error message indicated that any filter ca nnot 138 * @property {FilterParsingError[]} errors See {@link module:filterValidation~F ilterParsingError FilterParsingError}
89 * be parsed or contains an invalid CSS selector .
90 */ 139 */
91 140
92 /** 141 /**
93 * Parses and validates a newline-separated list of filters given by the user. 142 * Parses and validates a newline-separated list of filters given by the user.
94 * 143 *
95 * @param {string} text 144 * @param {string} text
96 * @param {Boolean} [ignoreHeaders=false] If true, filter list headers
97 * will be stripped instead of
98 * returning an error.
99 * @return {ParsedFilters} 145 * @return {ParsedFilters}
100 */ 146 */
101 exports.parseFilters = function(text, ignoreHeaders) 147 exports.parseFilters = function(text)
102 { 148 {
103 let lines = text.split("\n"); 149 let lines = text.split("\n");
104 let filters = []; 150 let filters = [];
151 let errors = [];
105 152
106 for (let i = 0; i < lines.length; i++) 153 for (let i = 0; i < lines.length; i++)
107 { 154 {
108 let {filter, error} = parseFilter(lines[i], ignoreHeaders); 155 let {filter, error} = parseFilter(lines[i]);
109
110 if (error)
111 return {error: ext.i18n.getMessage("line", (i + 1).toString()) + ": " + er ror};
112 156
113 if (filter) 157 if (filter)
114 filters.push(filter); 158 filters.push(filter);
159
160 if (error)
161 {
162 error.lineno = i + 1;
163 errors.push(error);
164 }
115 } 165 }
116 166
117 return {filters: filters}; 167 return {filters: filters, errors: errors};
118 }; 168 };
OLDNEW
« no previous file with comments | « background.js ('k') | options.js » ('j') | options.js » ('J')

Powered by Google App Engine
This is Rietveld