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: Lots of cleanup. Simpler, better. Created April 3, 2017, 8:09 a.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 | « lib/filterClasses.js ('k') | test/filterClasses.js » ('j') | no next file with comments »
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-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(
113 window,
114 function(callback)
115 {
116 var patterns = [];
117 selectors.forEach(function(selector)
118 {
119 patterns.push({selector: selector});
120 });
121 callback(patterns);
122 },
123 function(selectors)
124 {
125 if (!selectors.length)
126 return;
127 var selector = selectors.join(", ");
128 insertStyleRule(selector + "{display: none !important;}");
129 }
130 );
131
132 elemHideEmulation.apply();
133 callback(); 126 callback();
134 } 127 }
135 128
129 // instantiate a ElemHideEmulation with @selectors.
130 function applyElemHideEmulation(selectors, callback)
131 {
132 loadElemHideEmulation(function()
133 {
134 var elemHideEmulation = new ElemHideEmulation(
135 window,
136 function(callback)
137 {
138 var patterns = [];
139 selectors.forEach(function(selector)
140 {
141 patterns.push({selector: selector});
142 });
143 callback(patterns);
144 },
145 function(selectors)
146 {
147 if (!selectors.length)
148 return;
149 var selector = selectors.join(", ");
150 insertStyleRule(selector + "{display: none !important;}");
151 },
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 selectors = ["div:has(span)"];
171 // testing the regexp
172 var match = pseudoClassHasSelectorRegExp.exec(selectors[0]);
173 test.ok(match);
174 test.equal(match[1], "span");
175
176 selectors = [":has(div.inside)"];
177 match = pseudoClassHasSelectorRegExp.exec(selectors[0]);
178 test.ok(match);
179 test.equal(match[1], "div.inside");
180
181 test.done();
182 });
183 };
184
185 exports.testSplitStyleRule = function(test)
186 {
187 loadElemHideEmulation(function()
188 {
189 var selectors = splitSelector("div:has(div) > [-abp-properties='background-c olor: rgb(0, 0, 0)'] > span");
190 test.ok(selectors);
191 test.equal(selectors.length, 1, "There is only one selector");
192
193 selectors = splitSelector("div:has(div), [-abp-properties='background-color: rgb(0, 0, 0)']");
194 test.ok(selectors);
195 test.equal(selectors.length, 2, "There are two selectors");
196
197 test.done();
198 });
199 };
200
136 exports.testVerbatimPropertySelector = function(test) 201 exports.testVerbatimPropertySelector = function(test)
137 { 202 {
138 var toHide = createElementWithStyle("{background-color: #000}"); 203 var toHide = createElementWithStyle("{background-color: #000}");
139 applyElemHideEmulation( 204 applyElemHideEmulation(
140 ["[-abp-properties='background-color: rgb(0, 0, 0)']"], 205 ["[-abp-properties='background-color: rgb(0, 0, 0)']"],
141 function() 206 function()
142 { 207 {
143 expectHidden(test, toHide); 208 expectHidden(test, toHide);
144 test.done(); 209 test.done();
145 } 210 }
146 ); 211 );
147 }; 212 };
148 213
214 exports.testVerbatimPropertySelectorWithPrefix = function(test)
215 {
216 var parent = createElementWithStyle("{background-color: #000}");
217 var toHide = createElementWithStyle("{background-color: #000}", parent);
218 applyElemHideEmulation(
219 ["div > [-abp-properties='background-color: rgb(0, 0, 0)']"],
220 function()
221 {
222 expectVisible(test, parent);
223 expectHidden(test, toHide);
224 test.done();
225 }
226 );
227 };
228
229 exports.testVerbatimPropertySelectorWithPrefixNoMatch = function(test)
230 {
231 var parent = createElementWithStyle("{background-color: #000}");
232 var toHide = createElementWithStyle("{background-color: #fff}", parent);
233 applyElemHideEmulation(
234 ["div > [-abp-properties='background-color: rgb(0, 0, 0)']"],
235 function()
236 {
237 expectVisible(test, parent);
238 expectVisible(test, toHide);
239 test.done();
240 }
241 );
242 };
243
244 exports.testVerbatimPropertySelectorWithSuffix = function(test)
245 {
246 var parent = createElementWithStyle("{background-color: #000}");
247 var toHide = createElementWithStyle("{background-color: #000}", parent);
248 applyElemHideEmulation(
249 ["[-abp-properties='background-color: rgb(0, 0, 0)'] > div"],
250 function()
251 {
252 expectVisible(test, parent);
253 expectHidden(test, toHide);
254 test.done();
255 }
256 );
257 };
258
259 exports.testVerbatimPropertySelectorWithPrefixAndSuffix = function(test)
260 {
261 var parent = createElementWithStyle("{background-color: #000}");
262 var middle = createElementWithStyle("{background-color: #000}", parent);
263 var toHide = createElementWithStyle("{background-color: #000}", middle);
264 applyElemHideEmulation(
265 ["div > [-abp-properties='background-color: rgb(0, 0, 0)'] > div"],
266 function()
267 {
268 expectVisible(test, parent);
269 expectVisible(test, middle);
270 expectHidden(test, toHide);
271 test.done();
272 }
273 );
274 };
275
149 exports.testPropertySelectorWithWildcard = function(test) 276 exports.testPropertySelectorWithWildcard = function(test)
150 { 277 {
151 var toHide = createElementWithStyle("{background-color: #000}"); 278 var toHide = createElementWithStyle("{background-color: #000}");
152 applyElemHideEmulation( 279 applyElemHideEmulation(
153 ["[-abp-properties='*color: rgb(0, 0, 0)']"], 280 ["[-abp-properties='*color: rgb(0, 0, 0)']"],
154 function() 281 function()
155 { 282 {
156 expectHidden(test, toHide); 283 expectHidden(test, toHide);
157 test.done(); 284 test.done();
158 } 285 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 expectVisible(test, toHide); 335 expectVisible(test, toHide);
209 insertStyleRule("#" + toHide.id + " {background-color: #000}"); 336 insertStyleRule("#" + toHide.id + " {background-color: #000}");
210 window.setTimeout(function() 337 window.setTimeout(function()
211 { 338 {
212 expectHidden(test, toHide); 339 expectHidden(test, toHide);
213 test.done(); 340 test.done();
214 }, 0); 341 }, 0);
215 } 342 }
216 ); 343 );
217 }; 344 };
345
346 exports.testPseudoClassHasMatcher = function(test)
347 {
348 var parent = createElementWithStyle("{}");
349 var child = createElementWithStyle("{}", parent);
350 loadElemHideEmulation(function()
351 {
352 var matcher = new PseudoHasMatcher("div");
353 test.equal(matcher.match(parent), true, "Parent should contain what is expec ted");
354 test.equal(matcher.match(child), false, "Child shouldn't match");
355
356 var matcher2 = new PseudoHasMatcher("span");
357 test.equal(matcher2.match(parent), false, "Doesn't have a <span> child, shou ldn't match");
358 test.equal(matcher2.match(child), false, "Child shouldn't match");
359
360 test.done();
361 });
362 };
363
364 exports.testPseudoClassHasSelector = function(test)
365 {
366 var toHide = createElementWithStyle("{}");
367 applyElemHideEmulation(
368 ["div:has(div)"],
369 function()
370 {
371 expectVisible(test, toHide);
372 test.done();
373 }
374 );
375 };
376
377 exports.testPseudoClassHasSelectorWithPrefix = function(test)
378 {
379 var parent = createElementWithStyle("{}");
380 var child = createElementWithStyle("{}", parent);
381 applyElemHideEmulation(
382 ["div:has(div)"],
383 function()
384 {
385 expectHidden(test, parent);
386 expectVisible(test, child);
387 test.done();
388 }
389 );
390 };
391
392 exports.testPseudoClassHasSelectorWithSuffix = function(test)
393 {
394 var parent = createElementWithStyle("{}");
395 var middle = createElementWithStyle("{}", parent);
396 var child = createElementWithStyle("{}", middle);
397 applyElemHideEmulation(
398 ["div:has(div) > div"],
399 function()
400 {
401 expectVisible(test, parent);
402 expectHidden(test, middle);
403 expectHidden(test, child);
404 test.done();
405 }
406 );
407 };
408
409 exports.testPseudoClassHasSelectorWithSuffixSibling = function(test)
410 {
411 var parent = createElementWithStyle("{}");
412 var middle = createElementWithStyle("{}", parent);
413 var toHide = createElementWithStyle("{}");
414 applyElemHideEmulation(
415 ["div:has(div) + div"],
416 function()
417 {
418 expectVisible(test, parent);
419 expectVisible(test, middle);
420 expectHidden(test, toHide);
421 test.done();
422 }
423 );
424 };
425
426 exports.testPseudoClassHasSelectorWithSuffixSiblingChild = function(test)
427 {
428 // <div>
429 // <div></div>
430 // <div>
431 // <div>to hide</div>
432 // </div>
433 // </div>
434 var parent = createElementWithStyle("{}");
435 var middle = createElementWithStyle("{}", parent);
436 var sibling = createElementWithStyle("{}");
437 var toHide = createElementWithStyle("{}", sibling);
438 applyElemHideEmulation(
439 ["div:has(div) + div > div"],
440 function()
441 {
442 expectVisible(test, parent);
443 expectVisible(test, middle);
444 expectVisible(test, sibling);
445 expectHidden(test, toHide);
446 test.done();
447 }
448 );
449 };
450
451 function runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, selector )
452 {
453 document.body.innerHTML = '<div id="parent">'+
454 '<div id="middle">' +
455 '<div id="middle.1"><div id="inside" class="inside"></div></div>' +
456 '</div>' +
457 '<div id="sibling">' +
458 '<div id="tohide">to hide</div>' +
459 '</div>' +
460 '<div id="sibling2">' +
461 '<div id="sibling2.1"><div id="sibling2.1.1" class="inside"></div></div>' +
462 '</div>' +
463 '</div>';
464 var parent = document.getElementById("parent");
465 var middle = document.getElementById("middle");
466 var inside = document.getElementById("inside");
467 var sibling = document.getElementById("sibling");
468 var sibling2 = document.getElementById("sibling2");
469 var toHide = document.getElementById("tohide");
470
471 applyElemHideEmulation(
472 [selector],
473 function()
474 {
475 expectVisible(test, parent);
476 expectVisible(test, middle);
477 expectVisible(test, inside);
478 expectVisible(test, sibling);
479 expectVisible(test, sibling2);
480 expectHidden(test, toHide);
481 test.done();
482 }
483 );
484 }
485
486 exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling = function(test)
487 {
488 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, "div:has(:has(d iv.inside)) + div > div");
489 };
490
491 exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling2 = function(test)
492 {
493 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, "div:has(:has(> div.inside)) + div > div");
494 }
495
496 exports.testPseudoClassHasSelectorWithPropSelector = function(test)
497 {
498 var parent = createElementWithStyle("{}");
499 var child = createElementWithStyle("{background-color: #000}", parent);
500 applyElemHideEmulation(
501 ["div:has([-abp-properties='background-color: rgb(0, 0, 0)'])"],
502 function()
503 {
504 expectVisible(test, child);
505 expectHidden(test, parent);
506 test.done();
507 }
508 );
509 };
OLDNEW
« no previous file with comments | « lib/filterClasses.js ('k') | test/filterClasses.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld