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: Updated patch following feedback. Created March 29, 2017, 2 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 | « 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( 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)
134 } 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.testExtraFirstSelector = function(test)
186 {
187 loadElemHideEmulation(function()
188 {
189 var myselector = "elem.class1.class2";
190 var shortSel = extractFirstSelector(myselector);
191
192 test.equal(shortSel, myselector);
193
194 myselector = "elem > elem2";
195 shortSel = extractFirstSelector(myselector);
196
197 test.equal(shortSel, "elem");
198
199 myselector = "elem+elem2 > elem3";
200 shortSel = extractFirstSelector(myselector);
201
202 test.equal(shortSel, "elem");
203
204 myselector = "elem~elem2 > elem3";
205 shortSel = extractFirstSelector(myselector);
206
207 test.equal(shortSel, "elem");
208
209 test.done();
210 });
211 };
212
213 exports.testSplitStyleRule = function(test)
214 {
215 loadElemHideEmulation(function()
216 {
217 var selectors = splitSelector("div:has(div) > [-abp-properties='background-c olor: rgb(0, 0, 0)'] > span");
218 test.ok(selectors);
219 test.equal(selectors.length, 1, "There is only one selector");
220
221 selectors = splitSelector("div:has(div), [-abp-properties='background-color: rgb(0, 0, 0)']");
222 test.ok(selectors);
223 test.equal(selectors.length, 2, "There are two selectors");
224
225 test.done();
226 });
227 };
135 228
136 exports.testVerbatimPropertySelector = function(test) 229 exports.testVerbatimPropertySelector = function(test)
137 { 230 {
138 var toHide = createElementWithStyle("{background-color: #000}"); 231 var toHide = createElementWithStyle("{background-color: #000}");
139 applyElemHideEmulation( 232 applyElemHideEmulation(
140 ["[-abp-properties='background-color: rgb(0, 0, 0)']"], 233 ["[-abp-properties='background-color: rgb(0, 0, 0)']"],
141 function() 234 function()
142 { 235 {
143 expectHidden(test, toHide); 236 expectHidden(test, toHide);
144 test.done(); 237 test.done();
145 } 238 }
146 ); 239 );
147 }; 240 };
148 241
242 exports.testVerbatimPropertySelectorWithPrefix = function(test)
243 {
244 var parent = createElementWithStyle("{background-color: #000}");
245 var toHide = createElementWithStyle("{background-color: #000}", parent);
246 applyElemHideEmulation(
247 ["div > [-abp-properties='background-color: rgb(0, 0, 0)']"],
248 function()
249 {
250 expectVisible(test, parent);
251 expectHidden(test, toHide);
252 test.done();
253 }
254 );
255 };
256
257 exports.testVerbatimPropertySelectorWithPrefixNoMatch = function(test)
258 {
259 var parent = createElementWithStyle("{background-color: #000}");
260 var toHide = createElementWithStyle("{background-color: #fff}", parent);
261 applyElemHideEmulation(
262 ["div > [-abp-properties='background-color: rgb(0, 0, 0)']"],
263 function()
264 {
265 expectVisible(test, parent);
266 expectVisible(test, toHide);
267 test.done();
268 }
269 );
270 };
271
272 exports.testVerbatimPropertySelectorWithSuffix = function(test)
273 {
274 var parent = createElementWithStyle("{background-color: #000}");
275 var toHide = createElementWithStyle("{background-color: #000}", parent);
276 applyElemHideEmulation(
277 ["[-abp-properties='background-color: rgb(0, 0, 0)'] > div"],
278 function()
279 {
280 expectVisible(test, parent);
281 expectHidden(test, toHide);
282 test.done();
283 }
284 );
285 };
286
287 exports.testVerbatimPropertySelectorWithPrefixAndSuffix = function(test)
288 {
289 var parent = createElementWithStyle("{background-color: #000}");
290 var middle = createElementWithStyle("{background-color: #000}", parent);
291 var toHide = createElementWithStyle("{background-color: #000}", middle);
292 applyElemHideEmulation(
293 ["div > [-abp-properties='background-color: rgb(0, 0, 0)'] > div"],
294 function()
295 {
296 expectVisible(test, parent);
297 expectVisible(test, middle);
298 expectHidden(test, toHide);
299 test.done();
300 }
301 );
302 };
303
149 exports.testPropertySelectorWithWildcard = function(test) 304 exports.testPropertySelectorWithWildcard = function(test)
150 { 305 {
151 var toHide = createElementWithStyle("{background-color: #000}"); 306 var toHide = createElementWithStyle("{background-color: #000}");
152 applyElemHideEmulation( 307 applyElemHideEmulation(
153 ["[-abp-properties='*color: rgb(0, 0, 0)']"], 308 ["[-abp-properties='*color: rgb(0, 0, 0)']"],
154 function() 309 function()
155 { 310 {
156 expectHidden(test, toHide); 311 expectHidden(test, toHide);
157 test.done(); 312 test.done();
158 } 313 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 expectVisible(test, toHide); 363 expectVisible(test, toHide);
209 insertStyleRule("#" + toHide.id + " {background-color: #000}"); 364 insertStyleRule("#" + toHide.id + " {background-color: #000}");
210 window.setTimeout(function() 365 window.setTimeout(function()
211 { 366 {
212 expectHidden(test, toHide); 367 expectHidden(test, toHide);
213 test.done(); 368 test.done();
214 }, 0); 369 }, 0);
215 } 370 }
216 ); 371 );
217 }; 372 };
373
374 exports.testPseudoClassHasMatcher = function(test)
375 {
376 var parent = createElementWithStyle("{}");
377 var child = createElementWithStyle("{}", parent);
378 loadElemHideEmulation(function()
379 {
380 var matcher = new PseudoHasMatcher("div");
381 test.equal(matcher.match(parent).length, 1, "Parent should contain what is e xpected");
382 test.equal(matcher.match(child).length, 0, "Child shouldn't match");
383
384 var matcher2 = new PseudoHasMatcher("span");
385 test.equal(matcher2.match(parent), 0, "Doesn't have a <span> child, shouldn' t mactch");
386 test.equal(matcher2.match(child), 0, "Child shouldn't match");
387
388 test.done();
389 });
390 };
391
392 exports.testPseudoClassHasSelector = function(test)
393 {
394 var toHide = createElementWithStyle("{}");
395 applyElemHideEmulation(
396 ["div:has(div)"],
397 function()
398 {
399 expectVisible(test, toHide);
400 test.done();
401 }
402 );
403 };
404
405 exports.testPseudoClassHasSelectorWithPrefix = function(test)
406 {
407 var parent = createElementWithStyle("{}");
408 var child = createElementWithStyle("{}", parent);
409 applyElemHideEmulation(
410 ["div:has(div)"],
411 function()
412 {
413 expectHidden(test, parent);
414 expectVisible(test, child);
415 test.done();
416 }
417 );
418 };
419
420 exports.testPseudoClassHasSelectorWithSuffix = function(test)
421 {
422 var parent = createElementWithStyle("{}");
423 var middle = createElementWithStyle("{}", parent);
424 var child = createElementWithStyle("{}", middle);
425 applyElemHideEmulation(
426 ["div:has(div) > div"],
427 function()
428 {
429 expectVisible(test, parent);
430 expectVisible(test, middle);
431 expectHidden(test, child);
432 test.done();
433 }
434 );
435 };
436
437 exports.testPseudoClassHasSelectorWithSuffixSibling = function(test)
438 {
439 var parent = createElementWithStyle("{}");
440 var middle = createElementWithStyle("{}", parent);
441 var toHide = createElementWithStyle("{}", parent);
442 applyElemHideEmulation(
443 ["div:has(div) + div"],
444 function()
445 {
446 expectVisible(test, parent);
447 expectVisible(test, middle);
448 expectHidden(test, toHide);
449 test.done();
450 }
451 );
452 };
453
454 exports.testPseudoClassHasSelectorWithSuffixSibling = function(test)
455 {
456 // <div>
457 // <div></div>
458 // <div>
459 // <div>to hide</div>
460 // </div>
461 // </div>
462 var parent = createElementWithStyle("{}");
463 var middle = createElementWithStyle("{}", parent);
464 var sibling = createElementWithStyle("{}", parent);
465 var toHide = createElementWithStyle("{}", sibling);
466 applyElemHideEmulation(
467 ["div:has(div) + div > div"],
468 function()
469 {
470 expectVisible(test, parent);
471 expectVisible(test, middle);
472 expectVisible(test, sibling);
473 expectHidden(test, toHide);
474 test.done();
475 }
476 );
477 };
478
479 exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling = function(test)
480 {
481 // <div id="parent">
482 // <div id="middle">
483 // <div id="inside" class="inside"></div>
484 // </div>
485 // <div id="sibling">
486 // <div id="tohide">to hide</div>
487 // </div>
488 // </div>
489 var parent = createElementWithStyle("{}");
490 parent.id = "parent";
491 var middle = createElementWithStyle("{}", parent);
492 middle.id = "middle";
493 var inside = createElementWithStyle("{}", middle);
494 inside.id = "inside";
495 inside.className = "inside";
496 var sibling = createElementWithStyle("{}", parent);
497 sibling.id = "sibling";
498 var toHide = createElementWithStyle("{}", sibling);
499 toHide.id = "tohide";
500
501 applyElemHideEmulation(
502 ["div:has(:has(div.inside)) + div > div"],
503 function()
504 {
505 expectVisible(test, parent);
506 expectVisible(test, middle);
507 expectVisible(test, inside);
508 expectVisible(test, sibling);
509 expectHidden(test, toHide);
510 test.done();
511 }
512 );
513 };
514
515
516 exports.testPseudoClassHasSelectorWithPropSelector = function(test)
517 {
518 var parent = createElementWithStyle("{}");
519 var child = createElementWithStyle("{background-color: #000}", parent);
520 applyElemHideEmulation(
521 ["div:has([-abp-properties='background-color: rgb(0, 0, 0)'])"],
522 function()
523 {
524 expectVisible(test, child);
525 expectHidden(test, parent);
526 test.done();
527 }
528 );
529 };
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