Left: | ||
Right: |
OLD | NEW |
---|---|
1 "use strict"; | 1 "use strict"; |
2 | 2 |
3 let readline = require("readline"); | 3 let readline = require("readline"); |
4 let punycode = require("punycode"); | 4 let punycode = require("punycode"); |
5 let tldjs = require("tldjs"); | 5 let tldjs = require("tldjs"); |
6 let filterClasses = require("./adblockplus.js"); | 6 let filterClasses = require("./adblockplus.js"); |
7 | 7 |
8 let typeMap = filterClasses.RegExpFilter.typeMap; | 8 let typeMap = filterClasses.RegExpFilter.typeMap; |
9 | 9 |
10 const selectorLimit = 5000; | 10 const selectorLimit = 5000; |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
247 return true; | 247 return true; |
248 | 248 |
249 for (let name of Object.getOwnPropertyNames(obj)) | 249 for (let name of Object.getOwnPropertyNames(obj)) |
250 if (hasNonASCI(obj[name])) | 250 if (hasNonASCI(obj[name])) |
251 return true; | 251 return true; |
252 } | 252 } |
253 | 253 |
254 return false; | 254 return false; |
255 } | 255 } |
256 | 256 |
257 function attributeSyntaxForIDs(selector) | |
258 { | |
259 if (selector.indexOf("#") == -1) | |
260 return selector; | |
261 | |
262 // First we figure out where all the IDs are | |
263 let sep = ""; | |
264 let IDstart = null; | |
265 let IDpositions = []; | |
266 for (let i = 0; i < selector.length; i++) | |
267 { | |
268 let chr = selector[i]; | |
269 | |
270 if (chr == "\\") // ignore escaped characters | |
271 i++; | |
272 else if (chr == sep) // don't split within quoted text | |
273 sep = ""; // e.g. [attr=","] | |
274 else if (sep == "") | |
275 { | |
276 if (chr == '"' || chr == "'") | |
277 sep = chr; | |
278 else if (IDstart == null) // look for the start of an ID | |
279 { | |
280 if (chr == "#") | |
281 IDstart = i; | |
282 } | |
283 else if (chr < "0" && chr != "-" || | |
Sebastian Noack
2016/02/17 14:22:19
I'd find the logic here easier to read if you'd ch
kzar
2016/02/17 15:35:03
Done.
| |
284 chr > "9" && chr < "A" || | |
285 chr > "Z" && chr != "_" && chr < "a" || | |
286 chr > "z" && chr < "\x80") // look for the end of the ID | |
287 { | |
288 IDpositions.push({start: IDstart, end: i}); | |
289 IDstart = null; | |
290 } | |
291 } | |
292 } | |
293 | |
294 if (IDpositions.length == 0) | |
295 return selector; | |
296 | |
297 // Now replace them all with the [id="someID"] form | |
298 let newSelector = ""; | |
299 let position = 0; | |
300 for (let ID of IDpositions) | |
301 { | |
302 newSelector += selector.substring(position, ID.start); | |
303 newSelector += '[id="' + selector.substring(ID.start + 1, ID.end) + '"]'; | |
304 position = ID.end; | |
305 } | |
306 newSelector += selector.substring(position); | |
307 | |
308 return newSelector; | |
309 } | |
310 | |
257 function logRules() | 311 function logRules() |
258 { | 312 { |
259 let rules = []; | 313 let rules = []; |
260 | 314 |
261 function addRule(rule) | 315 function addRule(rule) |
262 { | 316 { |
263 if (!hasNonASCI(rule)) | 317 if (!hasNonASCI(rule)) |
264 rules.push(rule); | 318 rules.push(rule); |
265 } | 319 } |
266 | 320 |
(...skipping 12 matching lines...) Expand all Loading... | |
279 let group = groupedElemhideFilters.get(matchDomain) || []; | 333 let group = groupedElemhideFilters.get(matchDomain) || []; |
280 group.push(result.selector); | 334 group.push(result.selector); |
281 groupedElemhideFilters.set(matchDomain, group); | 335 groupedElemhideFilters.set(matchDomain, group); |
282 } | 336 } |
283 } | 337 } |
284 | 338 |
285 groupedElemhideFilters.forEach((selectors, matchDomain) => | 339 groupedElemhideFilters.forEach((selectors, matchDomain) => |
286 { | 340 { |
287 while (selectors.length) | 341 while (selectors.length) |
288 { | 342 { |
343 let selector = selectors.splice(0, selectorLimit).join(", "); | |
344 | |
345 // As of Safari 9.0 element IDs are matched as lowercase. We work around | |
346 // this by converting to the attribute format [id="elementID"] | |
347 selector = attributeSyntaxForIDs(selector); | |
348 | |
289 addRule({ | 349 addRule({ |
290 trigger: {"url-filter": matchDomain}, | 350 trigger: {"url-filter": matchDomain}, |
291 action: {type: "css-display-none", | 351 action: {type: "css-display-none", |
292 selector: selectors.splice(0, selectorLimit).join(", ")} | 352 selector: selector} |
293 }); | 353 }); |
294 } | 354 } |
295 }); | 355 }); |
296 | 356 |
297 for (let filter of elemhideExceptions) | 357 for (let filter of elemhideExceptions) |
298 addRule(convertFilter(filter, "ignore-previous-rules", false)); | 358 addRule(convertFilter(filter, "ignore-previous-rules", false)); |
299 | 359 |
300 for (let filter of requestFilters) | 360 for (let filter of requestFilters) |
301 addRule(convertFilter(filter, "block", true)); | 361 addRule(convertFilter(filter, "block", true)); |
302 for (let filter of requestExceptions) | 362 for (let filter of requestExceptions) |
303 addRule(convertFilter(filter, "ignore-previous-rules", true)); | 363 addRule(convertFilter(filter, "ignore-previous-rules", true)); |
304 | 364 |
305 console.log(JSON.stringify(rules, null, "\t")); | 365 console.log(JSON.stringify(rules, null, "\t")); |
306 } | 366 } |
307 | 367 |
308 let rl = readline.createInterface({input: process.stdin, terminal: false}); | 368 let rl = readline.createInterface({input: process.stdin, terminal: false}); |
309 rl.on("line", parseFilter); | 369 rl.on("line", parseFilter); |
310 rl.on("close", logRules); | 370 rl.on("close", logRules); |
OLD | NEW |