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

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

Issue 29494577: Issue 5438 - Observer DOM changes to reapply filters. (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Patch Set: Updated the tests. Created Aug. 23, 2017, 4:37 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-present eyeo GmbH 3 * Copyright (C) 2006-present 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
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 "use strict"; 18 "use strict";
19 19
20 const {ElemHideEmulation} = require("../../lib/content/elemHideEmulation"); 20 const {ElemHideEmulation} = require("../../lib/content/elemHideEmulation");
21 21
22 exports.tearDown = function(callback) 22 const REFRESH_INTERVAL = 200;
23
24 let testDocument = null;
25
26 exports.setUp = function(callback)
23 { 27 {
24 let styleElements = document.head.getElementsByTagName("style"); 28 let iframe = document.createElement("iframe");
25 while (styleElements.length) 29 document.body.appendChild(iframe);
26 styleElements[0].parentNode.removeChild(styleElements[0]); 30 testDocument = iframe.contentDocument;
27
28 let child;
29 while (child = document.body.firstChild)
30 child.parentNode.removeChild(child);
31 31
32 callback(); 32 callback();
33 }; 33 };
34 34
35 exports.tearDown = function(callback)
36 {
37 let iframe = testDocument.defaultView.frameElement;
38 iframe.parentNode.removeChild(iframe);
39 testDocument = null;
40
41 callback();
42 };
43
44 function timeout(delay)
45 {
46 return new Promise((resolve, reject) =>
47 {
48 window.setTimeout(resolve, delay);
49 });
50 }
51
35 function unexpectedError(error) 52 function unexpectedError(error)
36 { 53 {
37 console.error(error); 54 console.error(error);
38 this.ok(false, "Unexpected error: " + error); 55 this.ok(false, "Unexpected error: " + error);
39 } 56 }
40 57
41 function expectHidden(test, element) 58 function expectHidden(test, element)
42 { 59 {
43 test.equal(window.getComputedStyle(element).display, "none", 60 test.equal(window.getComputedStyle(element).display, "none",
44 "The element's display property should be set to 'none'"); 61 "The element's display property should be set to 'none'");
45 } 62 }
46 63
47 function expectVisible(test, element) 64 function expectVisible(test, element)
48 { 65 {
49 test.notEqual(window.getComputedStyle(element).display, "none", 66 test.notEqual(window.getComputedStyle(element).display, "none",
50 "The element's display property should not be set to 'none'"); 67 "The element's display property should not be set to 'none'");
51 } 68 }
52 69
53 function findUniqueId() 70 function findUniqueId()
54 { 71 {
55 let id = "elemHideEmulationTest-" + Math.floor(Math.random() * 10000); 72 let id = "elemHideEmulationTest-" + Math.floor(Math.random() * 10000);
56 if (!document.getElementById(id)) 73 if (!testDocument.getElementById(id))
57 return id; 74 return id;
58 return findUniqueId(); 75 return findUniqueId();
59 } 76 }
60 77
61 function insertStyleRule(rule) 78 function insertStyleRule(rule)
62 { 79 {
63 let styleElement; 80 let styleElement;
64 let styleElements = document.head.getElementsByTagName("style"); 81 let styleElements = testDocument.head.getElementsByTagName("style");
65 if (styleElements.length) 82 if (styleElements.length)
66 styleElement = styleElements[0]; 83 styleElement = styleElements[0];
67 else 84 else
68 { 85 {
69 styleElement = document.createElement("style"); 86 styleElement = testDocument.createElement("style");
70 document.head.appendChild(styleElement); 87 testDocument.head.appendChild(styleElement);
71 } 88 }
72 styleElement.sheet.insertRule(rule, styleElement.sheet.cssRules.length); 89 styleElement.sheet.insertRule(rule, styleElement.sheet.cssRules.length);
73 } 90 }
74 91
75 // Insert a <div> with a unique id and a CSS rule 92 // Insert a <div> with a unique id and a CSS rule
76 // for the the selector matching the id. 93 // for the the selector matching the id.
77 function createElementWithStyle(styleBlock, parent) 94 function createElementWithStyle(styleBlock, parent)
78 { 95 {
79 let element = document.createElement("div"); 96 let element = testDocument.createElement("div");
80 element.id = findUniqueId(); 97 element.id = findUniqueId();
81 if (!parent) 98 if (!parent)
82 document.body.appendChild(element); 99 testDocument.body.appendChild(element);
83 else 100 else
84 parent.appendChild(element); 101 parent.appendChild(element);
85 insertStyleRule("#" + element.id + " " + styleBlock); 102 insertStyleRule("#" + element.id + " " + styleBlock);
86 return element; 103 return element;
87 } 104 }
88 105
89 // Create a new ElemHideEmulation instance with @selectors. 106 // Create a new ElemHideEmulation instance with @selectors.
90 function applyElemHideEmulation(selectors) 107 function applyElemHideEmulation(selectors)
91 { 108 {
92 return Promise.resolve().then(() => 109 return Promise.resolve().then(() =>
93 { 110 {
94 let elemHideEmulation = new ElemHideEmulation( 111 let elemHideEmulation = new ElemHideEmulation(
95 window, 112 testDocument.defaultView,
96 callback => 113 callback =>
97 { 114 {
98 let patterns = []; 115 let patterns = [];
99 selectors.forEach(selector => 116 selectors.forEach(selector =>
100 { 117 {
101 patterns.push({selector}); 118 patterns.push({selector});
102 }); 119 });
103 callback(patterns); 120 callback(patterns);
104 }, 121 },
105 newSelectors => 122 newSelectors =>
106 { 123 {
107 if (!newSelectors.length) 124 if (!newSelectors.length)
108 return; 125 return;
109 let selector = newSelectors.join(", "); 126 let selector = newSelectors.join(", ");
110 insertStyleRule(selector + "{display: none !important;}"); 127 insertStyleRule(selector + "{display: none !important;}");
111 }, 128 },
112 elems => 129 elems =>
113 { 130 {
114 for (let elem of elems) 131 for (let elem of elems)
115 elem.style.display = "none"; 132 elem.style.display = "none";
116 } 133 }
117 ); 134 );
118 135
136 elemHideEmulation._invocationInterval = 100;
Wladimir Palant 2017/08/25 07:44:59 REFRESH_INTERVAL / 2?
hub 2017/08/25 13:48:13 Done.
119 elemHideEmulation.apply(); 137 elemHideEmulation.apply();
120 return elemHideEmulation; 138 return elemHideEmulation;
121 }); 139 });
122 } 140 }
123 141
124 exports.testVerbatimPropertySelector = function(test) 142 exports.testVerbatimPropertySelector = function(test)
125 { 143 {
126 let toHide = createElementWithStyle("{background-color: #000}"); 144 let toHide = createElementWithStyle("{background-color: #000}");
127 applyElemHideEmulation( 145 applyElemHideEmulation(
128 [":-abp-properties(background-color: rgb(0, 0, 0))"] 146 [":-abp-properties(background-color: rgb(0, 0, 0))"]
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 250
233 exports.testDynamicallyChangedProperty = function(test) 251 exports.testDynamicallyChangedProperty = function(test)
234 { 252 {
235 let toHide = createElementWithStyle("{}"); 253 let toHide = createElementWithStyle("{}");
236 applyElemHideEmulation( 254 applyElemHideEmulation(
237 [":-abp-properties(background-color: rgb(0, 0, 0))"] 255 [":-abp-properties(background-color: rgb(0, 0, 0))"]
238 ).then(() => 256 ).then(() =>
239 { 257 {
240 expectVisible(test, toHide); 258 expectVisible(test, toHide);
241 insertStyleRule("#" + toHide.id + " {background-color: #000}"); 259 insertStyleRule("#" + toHide.id + " {background-color: #000}");
242 return new Promise((resolve, reject) => 260
243 { 261 // Re-evaluation will only happen after a few seconds
Wladimir Palant 2017/08/25 07:44:59 "after hundred milliseconds" or just "after a dela
hub 2017/08/25 13:48:12 Done.
244 // Re-evaluation will only happen after a few seconds 262 expectVisible(test, toHide);
Wladimir Palant 2017/08/25 07:44:59 Testing for synchronous changes here and below is
hub 2017/08/25 13:48:14 Done.
Wladimir Palant 2017/08/25 20:57:40 You only fixed one instance of this issue. I noted
245 expectVisible(test, toHide); 263 return timeout(REFRESH_INTERVAL);
246 window.setTimeout(() => 264 }).then(() =>
247 { 265 {
248 expectHidden(test, toHide); 266 expectHidden(test, toHide);
249 resolve();
250 }, 4000);
251 });
252 }).catch(unexpectedError.bind(test)).then(() => test.done()); 267 }).catch(unexpectedError.bind(test)).then(() => test.done());
253 }; 268 };
254 269
255 exports.testPseudoClassWithPropBeforeSelector = function(test) 270 exports.testPseudoClassWithPropBeforeSelector = function(test)
256 { 271 {
257 let parent = createElementWithStyle("{}"); 272 let parent = createElementWithStyle("{}");
258 let child = createElementWithStyle("{background-color: #000}", parent); 273 let child = createElementWithStyle("{background-color: #000}", parent);
259 insertStyleRule(`#${child.id}::before {content: "publicite"}`); 274 insertStyleRule(`#${child.id}::before {content: "publicite"}`);
260 275
261 applyElemHideEmulation( 276 applyElemHideEmulation(
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 { 354 {
340 expectVisible(test, parent); 355 expectVisible(test, parent);
341 expectVisible(test, middle); 356 expectVisible(test, middle);
342 expectVisible(test, sibling); 357 expectVisible(test, sibling);
343 expectHidden(test, toHide); 358 expectHidden(test, toHide);
344 }).catch(unexpectedError.bind(test)).then(() => test.done()); 359 }).catch(unexpectedError.bind(test)).then(() => test.done());
345 }; 360 };
346 361
347 function runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, selector , expectations) 362 function runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, selector , expectations)
348 { 363 {
349 document.body.innerHTML = `<div id="parent"> 364 testDocument.body.innerHTML = `<div id="parent">
350 <div id="middle"> 365 <div id="middle">
351 <div id="middle1"><div id="inside" class="inside"></div></div> 366 <div id="middle1"><div id="inside" class="inside"></div></div>
352 </div> 367 </div>
353 <div id="sibling"> 368 <div id="sibling">
354 <div id="tohide">to hide</div> 369 <div id="tohide">to hide</div>
355 </div> 370 </div>
356 <div id="sibling2"> 371 <div id="sibling2">
357 <div id="sibling21"><div id="sibling211" class="inside"></div></div> 372 <div id="sibling21"><div id="sibling211" class="inside"></div></div>
358 </div> 373 </div>
359 </div>`; 374 </div>`;
360 let elems = { 375 let elems = {
361 parent: document.getElementById("parent"), 376 parent: testDocument.getElementById("parent"),
362 middle: document.getElementById("middle"), 377 middle: testDocument.getElementById("middle"),
363 inside: document.getElementById("inside"), 378 inside: testDocument.getElementById("inside"),
364 sibling: document.getElementById("sibling"), 379 sibling: testDocument.getElementById("sibling"),
365 sibling2: document.getElementById("sibling2"), 380 sibling2: testDocument.getElementById("sibling2"),
366 toHide: document.getElementById("tohide") 381 toHide: testDocument.getElementById("tohide")
367 }; 382 };
368 383
369 insertStyleRule(".inside {}"); 384 insertStyleRule(".inside {}");
370 385
371 applyElemHideEmulation( 386 applyElemHideEmulation(
372 [selector] 387 [selector]
373 ).then(() => 388 ).then(() =>
374 { 389 {
375 for (let elem in expectations) 390 for (let elem in expectations)
376 if (elems[elem]) 391 if (elems[elem])
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 sibling: true, 435 sibling: true,
421 sibling2: true, 436 sibling2: true,
422 toHide: true 437 toHide: true
423 }; 438 };
424 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling( 439 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(
425 test, "div:-abp-has(> body div.inside) + div > div", expectations); 440 test, "div:-abp-has(> body div.inside) + div > div", expectations);
426 }; 441 };
427 442
428 exports.testPseudoClassContains = function(test) 443 exports.testPseudoClassContains = function(test)
429 { 444 {
430 document.body.innerHTML = `<div id="parent"> 445 testDocument.body.innerHTML = `<div id="parent">
431 <div id="middle"> 446 <div id="middle">
432 <div id="middle1"><div id="inside" class="inside"></div></div> 447 <div id="middle1"><div id="inside" class="inside"></div></div>
433 </div> 448 </div>
434 <div id="sibling"> 449 <div id="sibling">
435 <div id="tohide">to hide</div> 450 <div id="tohide">to hide</div>
436 </div> 451 </div>
437 <div id="sibling2"> 452 <div id="sibling2">
438 <div id="sibling21"><div id="sibling211" class="inside"></div></div> 453 <div id="sibling21"><div id="sibling211" class="inside"></div></div>
439 </div> 454 </div>
440 </div>`; 455 </div>`;
441 let parent = document.getElementById("parent"); 456 let parent = testDocument.getElementById("parent");
442 let middle = document.getElementById("middle"); 457 let middle = testDocument.getElementById("middle");
443 let inside = document.getElementById("inside"); 458 let inside = testDocument.getElementById("inside");
444 let sibling = document.getElementById("sibling"); 459 let sibling = testDocument.getElementById("sibling");
445 let sibling2 = document.getElementById("sibling2"); 460 let sibling2 = testDocument.getElementById("sibling2");
446 let toHide = document.getElementById("tohide"); 461 let toHide = testDocument.getElementById("tohide");
447 462
448 applyElemHideEmulation( 463 applyElemHideEmulation(
449 ["#parent div:-abp-contains(to hide)"] 464 ["#parent div:-abp-contains(to hide)"]
450 ).then(() => 465 ).then(() =>
451 { 466 {
452 expectVisible(test, parent); 467 expectVisible(test, parent);
453 expectVisible(test, middle); 468 expectVisible(test, middle);
454 expectVisible(test, inside); 469 expectVisible(test, inside);
455 expectHidden(test, sibling); 470 expectHidden(test, sibling);
456 expectVisible(test, sibling2); 471 expectVisible(test, sibling2);
(...skipping 20 matching lines...) Expand all
477 let child = createElementWithStyle("{}", parent); 492 let child = createElementWithStyle("{}", parent);
478 insertStyleRule("body #" + parent.id + " > div { background-color: #000}"); 493 insertStyleRule("body #" + parent.id + " > div { background-color: #000}");
479 applyElemHideEmulation( 494 applyElemHideEmulation(
480 ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"] 495 ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"]
481 ).then(() => 496 ).then(() =>
482 { 497 {
483 expectVisible(test, child); 498 expectVisible(test, child);
484 expectHidden(test, parent); 499 expectHidden(test, parent);
485 }).catch(unexpectedError.bind(test)).then(() => test.done()); 500 }).catch(unexpectedError.bind(test)).then(() => test.done());
486 }; 501 };
502
503 exports.testDomUpdatesStyle = function(test)
504 {
505 let parent = createElementWithStyle("{}");
506 let child = createElementWithStyle("{}", parent);
507 applyElemHideEmulation(
508 ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"]
509 ).then(() =>
510 {
511 expectVisible(test, child);
512 expectVisible(test, parent);
513
514 insertStyleRule("body #" + parent.id + " > div { background-color: #000}");
515
516 expectVisible(test, child);
517 expectVisible(test, parent);
518 return timeout(REFRESH_INTERVAL);
519 }).then(() =>
520 {
521 expectVisible(test, child);
522 expectHidden(test, parent);
523 }).catch(unexpectedError.bind(test)).then(() => test.done());
524 };
525
526 exports.testDomUpdatesContent = function(test)
527 {
528 let parent = createElementWithStyle("{}");
529 let child = createElementWithStyle("{}", parent);
530 applyElemHideEmulation(
531 ["div > div:-abp-contains(hide me)"]
532 ).then(() =>
533 {
534 expectVisible(test, parent);
535 expectVisible(test, child);
536
537 child.textContent = "hide me";
538
539 expectVisible(test, parent);
540 expectVisible(test, child);
541 return timeout(REFRESH_INTERVAL);
542 }).then(() =>
543 {
544 expectVisible(test, parent);
545 expectHidden(test, child);
546 }).catch(unexpectedError.bind(test)).then(() => test.done());
547 };
548
549 exports.testDomUpdatesNewElement = function(test)
550 {
551 let parent = createElementWithStyle("{}");
552 let child = createElementWithStyle("{ background-color: #000}", parent);
553 let sibling;
554 let child2;
555 applyElemHideEmulation(
556 ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"]
557 ).then(() =>
558 {
559 expectHidden(test, parent);
560 expectVisible(test, child);
561
562 sibling = createElementWithStyle("{}");
563 expectVisible(test, sibling);
564
Wladimir Palant 2017/08/25 07:44:59 I guess the two lines above should be removed? You
hub 2017/08/25 13:48:14 Done.
565 expectHidden(test, parent);
566 expectVisible(test, child);
567 expectVisible(test, sibling);
568
569 return timeout(REFRESH_INTERVAL);
570 }).then(() =>
571 {
572 expectHidden(test, parent);
573 expectVisible(test, child);
574 expectVisible(test, sibling);
575
576 child2 = createElementWithStyle("{ background-color: #000}",
577 sibling);
578 expectVisible(test, child2);
579 return timeout(REFRESH_INTERVAL);
580 }).then(() =>
581 {
582 expectHidden(test, parent);
583 expectVisible(test, child);
584 expectHidden(test, sibling);
585 expectVisible(test, child2);
586 }).catch(unexpectedError.bind(test)).then(() => test.done());
587 };
OLDNEW
« lib/content/elemHideEmulation.js ('K') | « lib/content/elemHideEmulation.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld