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

Side by Side Diff: abp2blocklist.js

Issue 29336525: Issue 3584 - Work around WebKit uppercase ID matching bug (Closed)
Patch Set: Don't forget IDs at the end of the string Created Feb. 17, 2016, 2:06 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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)
Sebastian Noack 2016/02/17 14:40:59 Perhaps a better name for this function: convertID
kzar 2016/02/17 15:13:52 Done.
258 {
259 if (selector.indexOf("#") == -1)
Sebastian Noack 2016/02/17 14:22:19 Does this optimization has any measurable impact o
kzar 2016/02/17 15:13:52 No, removed.
260 return selector;
261
262 // First we figure out where all the IDs are
263 let sep = "";
264 let IDstart = null;
Sebastian Noack 2016/02/17 14:40:59 Nit: Since we only have one kind of start value an
kzar 2016/02/17 15:13:52 Done.
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 != "-" ||
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});
Sebastian Noack 2016/02/17 14:22:19 I wonder we should do the replace inline: selecto
Sebastian Noack 2016/02/17 14:41:00 Here is an example how that could look like: fu
kzar 2016/02/17 15:13:52 Mind if I leave this as is? It works fine and I fi
289 IDstart = null;
290 }
291 }
292 }
293 if (IDstart != null)
294 IDpositions.push({start: IDstart, end: selector.length});
295
296 if (IDpositions.length == 0)
Sebastian Noack 2016/02/17 14:22:20 Does this optimization has any measurable impact o
kzar 2016/02/17 15:13:52 No, removed.
297 return selector;
298
299 // Now replace them all with the [id="someID"] form
300 let newSelector = "";
301 let position = 0;
302 for (let ID of IDpositions)
303 {
304 newSelector += selector.substring(position, ID.start);
305 newSelector += '[id="' + selector.substring(ID.start + 1, ID.end) + '"]';
Sebastian Noack 2016/02/17 14:22:19 The quotes are actually redundant, as we copy an u
kzar 2016/02/17 15:13:52 Acknowledged.
306 position = ID.end;
307 }
308 newSelector += selector.substring(position);
309
310 return newSelector;
311 }
312
257 function logRules() 313 function logRules()
258 { 314 {
259 let rules = []; 315 let rules = [];
260 316
261 function addRule(rule) 317 function addRule(rule)
262 { 318 {
263 if (!hasNonASCI(rule)) 319 if (!hasNonASCI(rule))
264 rules.push(rule); 320 rules.push(rule);
265 } 321 }
266 322
(...skipping 12 matching lines...) Expand all
279 let group = groupedElemhideFilters.get(matchDomain) || []; 335 let group = groupedElemhideFilters.get(matchDomain) || [];
280 group.push(result.selector); 336 group.push(result.selector);
281 groupedElemhideFilters.set(matchDomain, group); 337 groupedElemhideFilters.set(matchDomain, group);
282 } 338 }
283 } 339 }
284 340
285 groupedElemhideFilters.forEach((selectors, matchDomain) => 341 groupedElemhideFilters.forEach((selectors, matchDomain) =>
286 { 342 {
287 while (selectors.length) 343 while (selectors.length)
288 { 344 {
345 let selector = selectors.splice(0, selectorLimit).join(", ");
346
347 // As of Safari 9.0 element IDs are matched as lowercase. We work around
348 // this by converting to the attribute format [id="elementID"]
349 selector = attributeSyntaxForIDs(selector);
350
289 addRule({ 351 addRule({
290 trigger: {"url-filter": matchDomain}, 352 trigger: {"url-filter": matchDomain},
291 action: {type: "css-display-none", 353 action: {type: "css-display-none",
292 selector: selectors.splice(0, selectorLimit).join(", ")} 354 selector: selector}
293 }); 355 });
294 } 356 }
295 }); 357 });
296 358
297 for (let filter of elemhideExceptions) 359 for (let filter of elemhideExceptions)
298 addRule(convertFilter(filter, "ignore-previous-rules", false)); 360 addRule(convertFilter(filter, "ignore-previous-rules", false));
299 361
300 for (let filter of requestFilters) 362 for (let filter of requestFilters)
301 addRule(convertFilter(filter, "block", true)); 363 addRule(convertFilter(filter, "block", true));
302 for (let filter of requestExceptions) 364 for (let filter of requestExceptions)
303 addRule(convertFilter(filter, "ignore-previous-rules", true)); 365 addRule(convertFilter(filter, "ignore-previous-rules", true));
304 366
305 console.log(JSON.stringify(rules, null, "\t")); 367 console.log(JSON.stringify(rules, null, "\t"));
306 } 368 }
307 369
308 let rl = readline.createInterface({input: process.stdin, terminal: false}); 370 let rl = readline.createInterface({input: process.stdin, terminal: false});
309 rl.on("line", parseFilter); 371 rl.on("line", parseFilter);
310 rl.on("close", logRules); 372 rl.on("close", logRules);
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld