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

Side by Side Diff: test/browser/elemHideEmulation.js

Issue 29383960: Issue 3143 - Filter elements with :-abp-has() (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore
Patch Set: Validate the syntax, remove unused flags Created April 10, 2017, 1:12 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
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-2017 eyeo GmbH 3 * Copyright (C) 2006-2017 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 30 matching lines...) Expand all
41 } 41 }
42 42
43 callback(); 43 callback();
44 }; 44 };
45 45
46 exports.tearDown = function(callback) 46 exports.tearDown = function(callback)
47 { 47 {
48 var styleElements = document.head.getElementsByTagName("style"); 48 var styleElements = document.head.getElementsByTagName("style");
49 while (styleElements.length) 49 while (styleElements.length)
50 styleElements[0].parentNode.removeChild(styleElements[0]); 50 styleElements[0].parentNode.removeChild(styleElements[0]);
51 var child;
52 while (child = document.body.firstChild)
53 {
54 document.body.removeChild(child);
55 }
51 callback(); 56 callback();
52 }; 57 };
53 58
54 function expectHidden(test, element) 59 function expectHidden(test, element)
55 { 60 {
56 test.equal(window.getComputedStyle(element).display, "none", 61 test.equal(window.getComputedStyle(element).display, "none",
57 "The element's display property should be set to 'none'"); 62 "The element's display property should be set to 'none'");
58 } 63 }
59 64
60 function expectVisible(test, element) 65 function expectVisible(test, element)
(...skipping 17 matching lines...) Expand all
78 if (styleElements.length) 83 if (styleElements.length)
79 styleElement = styleElements[0]; 84 styleElement = styleElements[0];
80 else 85 else
81 { 86 {
82 styleElement = document.createElement("style"); 87 styleElement = document.createElement("style");
83 document.head.appendChild(styleElement); 88 document.head.appendChild(styleElement);
84 } 89 }
85 styleElement.sheet.insertRule(rule, styleElement.sheet.cssRules.length); 90 styleElement.sheet.insertRule(rule, styleElement.sheet.cssRules.length);
86 } 91 }
87 92
88 function createElementWithStyle(styleBlock) 93 // insert a <div> with a unique id and and empty CSS rule
94 // for the the selector matching the id.
95 function createElementWithStyle(styleBlock, parent)
89 { 96 {
90 var element = document.createElement("div"); 97 var element = document.createElement("div");
91 element.id = findUniqueId(); 98 element.id = findUniqueId();
92 document.body.appendChild(element); 99 if (!parent)
100 document.body.appendChild(element);
101 else
102 parent.appendChild(element);
93 insertStyleRule("#" + element.id + " " + styleBlock); 103 insertStyleRule("#" + element.id + " " + styleBlock);
94 return element; 104 return element;
95 } 105 }
96 106
97 function applyElemHideEmulation(selectors, callback) 107 // Will ensure the class ElemHideEmulation is loaded
108 // and then will call the callback.
109 // NOTE: if it never loads, this will probably hang in an infinite
110 // loop
111 function loadElemHideEmulation(callback)
98 { 112 {
99 if (typeof ElemHideEmulation == "undefined") 113 if (typeof ElemHideEmulation == "undefined")
100 { 114 {
101 loadScript(myUrl + "/../../../lib/common.js", function() 115 loadScript(myUrl + "/../../../lib/common.js", function()
102 { 116 {
103 loadScript(myUrl + "/../../../chrome/content/elemHideEmulation.js", 117 loadScript(myUrl + "/../../../chrome/content/elemHideEmulation.js",
104 function() 118 function()
105 { 119 {
106 applyElemHideEmulation(selectors, callback); 120 loadElemHideEmulation(callback);
107 }); 121 });
108 }); 122 });
109 return; 123 return;
110 } 124 }
111 125
112 var elemHideEmulation = new ElemHideEmulation( 126 callback();
113 window, 127 }
114 function(callback) 128
115 { 129 // instantiate a ElemHideEmulation with @selectors.
116 var patterns = []; 130 function applyElemHideEmulation(selectors, callback)
117 selectors.forEach(function(selector) 131 {
132 loadElemHideEmulation(function()
133 {
134 var elemHideEmulation = new ElemHideEmulation(
135 window,
136 function(callback)
118 { 137 {
119 patterns.push({selector: selector}); 138 var patterns = [];
120 }); 139 selectors.forEach(function(selector)
121 callback(patterns); 140 {
122 }, 141 patterns.push({selector: selector});
123 function(selectors) 142 });
124 { 143 callback(patterns);
125 if (!selectors.length) 144 },
126 return; 145 function(selectors)
127 var selector = selectors.join(", "); 146 {
128 insertStyleRule(selector + "{display: none !important;}"); 147 if (!selectors.length)
129 } 148 return;
130 ); 149 var selector = selectors.join(", ");
131 150 insertStyleRule(selector + "{display: none !important;}");
132 elemHideEmulation.apply(); 151 },
133 callback(); 152 function(elements)
153 {
154 if (!elements.length)
155 return;
156 for (var i = 0; i < elements.length; i++)
157 elements[i].style.display = "none";
158 }
159 );
160
161 elemHideEmulation.apply();
162 callback();
163 }.bind(this));
164 }
165
166 exports.testPseudoHasRule = function(test)
167 {
168 loadElemHideEmulation(function()
169 {
170 var selector = "div:has(span)";
171 // testing the regexp
172 var match = pseudoClassHasSelectorRegExp.exec(selector);
173 test.ok(match);
174 test.equal(match[1], "span");
175
176 selector = ":has(div.inside)";
177 match = pseudoClassHasSelectorRegExp.exec(selector);
178 test.ok(match);
179 test.equal(match[1], "div.inside");
180
181 selector = "div[-abp-selector=':has(div.inside)']";
182 match = abpSelectorRegExp.exec(selector);
183 test.ok(match);
184 test.equal(match[2], ":has(div.inside)");
185
186 selector = "[-abp-selector=':has(div.inside)']";
187 match = abpSelectorRegExp.exec(selector);
188 test.ok(match);
189 test.equal(match[2], ":has(div.inside)");
190
191 selector = "div[-abp-selector=':has(:-abp-properties(\"background-color: rgb (0, 0, 0)\"))']";
192 match = abpSelectorRegExp.exec(selector);
193 test.ok(match);
194 test.equal(match[2], ":has(:-abp-properties(\"background-color: rgb(0, 0, 0) \"))");
195
196 test.done();
197 });
198 };
199
200 exports.testSplitStyleRule = function(test)
201 {
202 loadElemHideEmulation(function()
203 {
204 var selectors = splitSelector("div:has(div) > [-abp-properties='background-c olor: rgb(0, 0, 0)'] > span");
205 test.ok(selectors);
206 test.equal(selectors.length, 1, "There is only one selector");
207
208 selectors = splitSelector("div:has(div), [-abp-properties='background-color: rgb(0, 0, 0)']");
209 test.ok(selectors);
210 test.equal(selectors.length, 2, "There are two selectors");
211
212 test.done();
213 });
214 };
215
216 exports.testParsePattern = function(test)
217 {
218 loadElemHideEmulation(function()
219 {
220 var pattern = unwrapPattern({selector: "[-abp-properties='background-color: rgb(0, 0, 0)']"});
221 test.ok(pattern);
222 test.equal(pattern.type, "props");
223 pattern = parsePattern({selector: "[-abp-properties='background-color: rgb(0 , 0, 0)']"}, false);
224 test.ok(pattern);
225 test.equal(pattern.type, "props");
226 pattern = parsePattern({selector: "[-abp-properties='background-color: rgb(0 , 0, 0)']"}, true);
227 test.ok(pattern);
228 test.equal(pattern.type, "props");
229
230 pattern = unwrapPattern({selector: "[-abp-selector=':-abp-properties(\"backg round-color: rgb(0, 0, 0)\")']"});
231 test.ok(pattern);
232 test.equal(pattern.type, "props");
233 pattern = parsePattern({selector: "[-abp-selector=':-abp-properties(\"backgr ound-color: rgb(0, 0, 0)\")']"}, false);
234 test.equal(pattern, undefined);
235 pattern = parsePattern({selector: "[-abp-selector=':-abp-properties(\"backgr ound-color: rgb(0, 0, 0)\")']"}, true);
236 test.equal(pattern, undefined);
237
238 pattern = unwrapPattern({selector: ":has(div)"});
239 test.equal(pattern, undefined);
240 pattern = parsePattern({selector: ":has(div)"}, false);
241 test.equal(pattern, undefined);
242 pattern = parsePattern({selector: ":has(div)"}, true);
243 test.ok(pattern);
244 test.equal(pattern.type, "has");
245
246 pattern = unwrapPattern({selector: ":-abp-properties('background-color: rgb( 0, 0, 0)')"});
247 test.equal(pattern, undefined);
248 pattern = parsePattern({selector: ":-abp-properties('background-color: rgb(0 , 0, 0)')"}, false);
249 test.equal(pattern, undefined);
250 pattern = parsePattern({selector: ":-abp-properties('background-color: rgb(0 , 0, 0)')"}, true);
251 test.ok(pattern);
252 test.equal(pattern.type, "props");
253
254 test.done();
255 });
256 };
257
258 function runTestVerbatimPropertySelector(test, selector)
259 {
260 var toHide = createElementWithStyle("{background-color: #000}");
261 applyElemHideEmulation(
262 [selector],
263 function()
264 {
265 expectHidden(test, toHide);
266 test.done();
267 }
268 );
134 } 269 }
135 270
136 exports.testVerbatimPropertySelector = function(test) 271 exports.testVerbatimPropertySelector = function(test)
137 { 272 {
273 runTestVerbatimPropertySelector(test, "[-abp-properties='background-color: rgb (0, 0, 0)']");
274 };
275
276 /* Testing the new syntax */
277 exports.testVerbatimPropertyPseudoSelector = function(test)
278 {
279 runTestVerbatimPropertySelector(test, "[-abp-selector=':-abp-properties(\"back ground-color: rgb(0, 0, 0)\")']");
280 };
281
282 function runTestVerbatimPropertySelectorWithPrefix(test, selector)
283 {
284 var parent = createElementWithStyle("{background-color: #000}");
285 var toHide = createElementWithStyle("{background-color: #000}", parent);
286 applyElemHideEmulation(
287 [selector],
288 function()
289 {
290 expectVisible(test, parent);
291 expectHidden(test, toHide);
292 test.done();
293 }
294 );
295 }
296
297 exports.testVerbatimPropertySelectorWithPrefix = function(test)
298 {
299 runTestVerbatimPropertySelectorWithPrefix(test, "div > [-abp-properties='backg round-color: rgb(0, 0, 0)']");
300 };
301
302 // testing the new syntax
303 exports.testVerbatimPropertyPseudoSelectorWithPrefix = function(test)
304 {
305 runTestVerbatimPropertySelectorWithPrefix(test, "div > [-abp-selector=':-abp-p roperties(\"background-color: rgb(0, 0, 0)\")']");
306 };
307
308 exports.testVerbatimPropertySelectorWithPrefixNoMatch = function(test)
309 {
310 var parent = createElementWithStyle("{background-color: #000}");
311 var toHide = createElementWithStyle("{background-color: #fff}", parent);
312 applyElemHideEmulation(
313 ["div > [-abp-properties='background-color: rgb(0, 0, 0)']"],
314 function()
315 {
316 expectVisible(test, parent);
317 expectVisible(test, toHide);
318 test.done();
319 }
320 );
321 };
322
323 function runTestVerbatimPropertySelectorWithSuffix(test, selector)
324 {
325 var parent = createElementWithStyle("{background-color: #000}");
326 var toHide = createElementWithStyle("{background-color: #000}", parent);
327 applyElemHideEmulation(
328 [selector],
329 function()
330 {
331 expectVisible(test, parent);
332 expectHidden(test, toHide);
333 test.done();
334 }
335 );
336 }
337
338 exports.testVerbatimPropertySelectorWithSuffix = function(test)
339 {
340 runTestVerbatimPropertySelectorWithSuffix(test, "[-abp-properties='background- color: rgb(0, 0, 0)'] > div");
341 };
342
343 exports.testVerbatimPropertyPseudoSelectorWithSuffix = function(test)
344 {
345 runTestVerbatimPropertySelectorWithSuffix(test, "[-abp-selector=':-abp-propert ies(\"background-color: rgb(0, 0, 0)\")'] > div");
346 };
347
348 function runTestVerbatimPropertySelectorWithPrefixAndSuffix(test, selector)
349 {
350 var parent = createElementWithStyle("{background-color: #000}");
351 var middle = createElementWithStyle("{background-color: #000}", parent);
352 var toHide = createElementWithStyle("{background-color: #000}", middle);
353 applyElemHideEmulation(
354 [selector],
355 function()
356 {
357 expectVisible(test, parent);
358 expectVisible(test, middle);
359 expectHidden(test, toHide);
360 test.done();
361 }
362 );
363 }
364
365 exports.testVerbatimPropertySelectorWithPrefixAndSuffix = function(test)
366 {
367 runTestVerbatimPropertySelectorWithPrefixAndSuffix(test, "div > [-abp-properti es='background-color: rgb(0, 0, 0)'] > div");
368 };
369
370 exports.testVerbatimPropertyPseudoSelectorWithPrefixAndSuffix = function(test)
371 {
372 runTestVerbatimPropertySelectorWithPrefixAndSuffix(test, "div > [-abp-selector =':-abp-properties(\"background-color: rgb(0, 0, 0)\")'] > div");
373 };
374
375 exports.testPropertySelectorWithWildcard = function(test)
376 {
138 var toHide = createElementWithStyle("{background-color: #000}"); 377 var toHide = createElementWithStyle("{background-color: #000}");
139 applyElemHideEmulation( 378 applyElemHideEmulation(
140 ["[-abp-properties='background-color: rgb(0, 0, 0)']"],
141 function()
142 {
143 expectHidden(test, toHide);
144 test.done();
145 }
146 );
147 };
148
149 exports.testPropertySelectorWithWildcard = function(test)
150 {
151 var toHide = createElementWithStyle("{background-color: #000}");
152 applyElemHideEmulation(
153 ["[-abp-properties='*color: rgb(0, 0, 0)']"], 379 ["[-abp-properties='*color: rgb(0, 0, 0)']"],
154 function() 380 function()
155 { 381 {
156 expectHidden(test, toHide); 382 expectHidden(test, toHide);
157 test.done(); 383 test.done();
158 } 384 }
159 ); 385 );
160 }; 386 };
161 387
162 exports.testPropertySelectorWithRegularExpression = function(test) 388 exports.testPropertySelectorWithRegularExpression = function(test)
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 expectVisible(test, toHide); 434 expectVisible(test, toHide);
209 insertStyleRule("#" + toHide.id + " {background-color: #000}"); 435 insertStyleRule("#" + toHide.id + " {background-color: #000}");
210 window.setTimeout(function() 436 window.setTimeout(function()
211 { 437 {
212 expectHidden(test, toHide); 438 expectHidden(test, toHide);
213 test.done(); 439 test.done();
214 }, 0); 440 }, 0);
215 } 441 }
216 ); 442 );
217 }; 443 };
444
445 exports.testPseudoClassHasMatcher = function(test)
446 {
447 var parent = createElementWithStyle("{}");
448 var child = createElementWithStyle("{}", parent);
449 loadElemHideEmulation(function()
450 {
451 var matcher = new PseudoHasMatcher("div");
452 test.equal(matcher.match(parent), true, "Parent should contain what is expec ted");
453 test.equal(matcher.match(child), false, "Child shouldn't match");
454
455 var matcher2 = new PseudoHasMatcher("span");
456 test.equal(matcher2.match(parent), false, "Doesn't have a <span> child, shou ldn't match");
457 test.equal(matcher2.match(child), false, "Child shouldn't match");
458
459 test.done();
460 });
461 };
462
463 exports.testPseudoClassHasSelector = function(test)
464 {
465 var toHide = createElementWithStyle("{}");
466 applyElemHideEmulation(
467 ["div[-abp-selector=':has(div)']"],
468 function()
469 {
470 expectVisible(test, toHide);
471 test.done();
472 }
473 );
474 };
475
476 exports.testPseudoClassHasSelectorWithPrefix = function(test)
477 {
478 var parent = createElementWithStyle("{}");
479 var child = createElementWithStyle("{}", parent);
480 applyElemHideEmulation(
481 ["div[-abp-selector=':has(div)']"],
482 function()
483 {
484 expectHidden(test, parent);
485 expectVisible(test, child);
486 test.done();
487 }
488 );
489 };
490
491 exports.testPseudoClassHasSelectorWithSuffix = function(test)
492 {
493 var parent = createElementWithStyle("{}");
494 var middle = createElementWithStyle("{}", parent);
495 var child = createElementWithStyle("{}", middle);
496 applyElemHideEmulation(
497 ["div[-abp-selector=':has(div)'] > div"],
498 function()
499 {
500 expectVisible(test, parent);
501 expectHidden(test, middle);
502 expectHidden(test, child);
503 test.done();
504 }
505 );
506 };
507
508 exports.testPseudoClassHasSelectorWithSuffixSibling = function(test)
509 {
510 var parent = createElementWithStyle("{}");
511 var middle = createElementWithStyle("{}", parent);
512 var toHide = createElementWithStyle("{}");
513 applyElemHideEmulation(
514 ["div[-abp-selector=':has(div)'] + div"],
515 function()
516 {
517 expectVisible(test, parent);
518 expectVisible(test, middle);
519 expectHidden(test, toHide);
520 test.done();
521 }
522 );
523 };
524
525 exports.testPseudoClassHasSelectorWithSuffixSiblingChild = function(test)
526 {
527 // <div>
528 // <div></div>
529 // <div>
530 // <div>to hide</div>
531 // </div>
532 // </div>
533 var parent = createElementWithStyle("{}");
534 var middle = createElementWithStyle("{}", parent);
535 var sibling = createElementWithStyle("{}");
536 var toHide = createElementWithStyle("{}", sibling);
537 applyElemHideEmulation(
538 ["div[-abp-selector=':has(div)'] + div > div"],
539 function()
540 {
541 expectVisible(test, parent);
542 expectVisible(test, middle);
543 expectVisible(test, sibling);
544 expectHidden(test, toHide);
545 test.done();
546 }
547 );
548 };
549
550 function runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, selector )
551 {
552 document.body.innerHTML = '<div id="parent">' +
553 '<div id="middle">' +
554 '<div id="middle.1"><div id="inside" class="inside"></div></div>' +
555 '</div>' +
556 '<div id="sibling">' +
557 '<div id="tohide">to hide</div>' +
558 '</div>' +
559 '<div id="sibling2">' +
560 '<div id="sibling2.1"><div id="sibling2.1.1" class="inside"></div></div>' +
561 '</div>' +
562 '</div>';
563 var parent = document.getElementById("parent");
564 var middle = document.getElementById("middle");
565 var inside = document.getElementById("inside");
566 var sibling = document.getElementById("sibling");
567 var sibling2 = document.getElementById("sibling2");
568 var toHide = document.getElementById("tohide");
569
570 applyElemHideEmulation(
571 [selector],
572 function()
573 {
574 expectVisible(test, parent);
575 expectVisible(test, middle);
576 expectVisible(test, inside);
577 expectVisible(test, sibling);
578 expectVisible(test, sibling2);
579 expectHidden(test, toHide);
580 test.done();
581 }
582 );
583 }
584
585 exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling = function(test)
586 {
587 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, "div[-abp-selec tor=':has(:has(div.inside))'] + div > div");
588 };
589
590 exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling2 = function(test)
591 {
592 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, "div[-abp-selec tor=':has(:has(> div.inside))'] + div > div");
593 };
594
595 exports.testPseudoClassHasSelectorWithPropSelector = function(test)
596 {
597 var parent = createElementWithStyle("{}");
598 var child = createElementWithStyle("{background-color: #000}", parent);
599 applyElemHideEmulation(
600 ["div[-abp-selector=':has(:-abp-properties(\"background-color: rgb(0, 0, 0)\ "))']"],
601 function()
602 {
603 expectVisible(test, child);
604 expectHidden(test, parent);
605 test.done();
606 }
607 );
608 };
OLDNEW

Powered by Google App Engine
This is Rietveld