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

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

Issue 29713565: Issue 6437 - Filter out patterns that do not match DOM mutations (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Patch Set: Add tests Created April 24, 2018, 12:39 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
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 if (styleElements.length) 92 if (styleElements.length)
93 styleElement = styleElements[0]; 93 styleElement = styleElements[0];
94 else 94 else
95 { 95 {
96 styleElement = testDocument.createElement("style"); 96 styleElement = testDocument.createElement("style");
97 testDocument.head.appendChild(styleElement); 97 testDocument.head.appendChild(styleElement);
98 } 98 }
99 styleElement.sheet.insertRule(rule, styleElement.sheet.cssRules.length); 99 styleElement.sheet.insertRule(rule, styleElement.sheet.cssRules.length);
100 } 100 }
101 101
102 // Insert a <div> with a unique id and a CSS rule 102 function createElement(parent)
103 // for the the selector matching the id.
104 function createElementWithStyle(styleBlock, parent)
105 { 103 {
106 let element = testDocument.createElement("div"); 104 let element = testDocument.createElement("div");
107 element.id = findUniqueId(); 105 element.id = findUniqueId();
108 if (!parent) 106 if (!parent)
109 testDocument.body.appendChild(element); 107 testDocument.body.appendChild(element);
110 else 108 else
111 parent.appendChild(element); 109 parent.appendChild(element);
110 return element;
111 }
112
113 // Insert a <div> with a unique id and a CSS rule
114 // for the the selector matching the id.
115 function createElementWithStyle(styleBlock, parent)
116 {
117 let element = createElement(parent);
112 insertStyleRule("#" + element.id + " " + styleBlock); 118 insertStyleRule("#" + element.id + " " + styleBlock);
113 return element; 119 return element;
114 } 120 }
115 121
116 // Create a new ElemHideEmulation instance with @selectors. 122 // Create a new ElemHideEmulation instance with @selectors.
117 function applyElemHideEmulation(selectors) 123 function applyElemHideEmulation(selectors)
118 { 124 {
119 return Promise.resolve().then(() => 125 return Promise.resolve().then(() =>
120 { 126 {
121 let elemHideEmulation = new ElemHideEmulation( 127 let elemHideEmulation = new ElemHideEmulation(
122 newSelectors => 128 newSelectors =>
123 { 129 {
124 if (!newSelectors.length) 130 if (!newSelectors.length)
125 return; 131 return;
126 let selector = newSelectors.join(", "); 132 let selector = newSelectors.join(", ");
127 insertStyleRule(selector + "{display: none !important;}"); 133 insertStyleRule(selector + "{display: none !important;}");
128 }, 134 },
129 elems => 135 elems =>
130 { 136 {
131 for (let elem of elems) 137 for (let elem of elems)
132 elem.style.display = "none"; 138 elem.style.display = "none";
133 } 139 }
134 ); 140 );
135 141
136 elemHideEmulation.document = testDocument; 142 elemHideEmulation.document = testDocument;
137 elemHideEmulation.MIN_INVOCATION_INTERVAL = REFRESH_INTERVAL / 2; 143 elemHideEmulation.MIN_INVOCATION_INTERVAL = REFRESH_INTERVAL / 2;
138 elemHideEmulation.apply(selectors.map(selector => ({selector}))); 144 elemHideEmulation.apply(selectors.map(
145 selector => ({selector, text: selector})
Manish Jethani 2018/04/24 12:43:01 This is useful for debugging.
146 ));
139 return elemHideEmulation; 147 return elemHideEmulation;
140 }); 148 });
141 } 149 }
142 150
143 exports.testVerbatimPropertySelector = function(test) 151 exports.testVerbatimPropertySelector = function(test)
144 { 152 {
145 let toHide = createElementWithStyle("{background-color: #000}"); 153 let toHide = createElementWithStyle("{background-color: #000}");
146 applyElemHideEmulation( 154 applyElemHideEmulation(
147 [":-abp-properties(background-color: rgb(0, 0, 0))"] 155 [":-abp-properties(background-color: rgb(0, 0, 0))"]
148 ).then(() => 156 ).then(() =>
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 expectVisible(test, child2); 700 expectVisible(test, child2);
693 return timeout(REFRESH_INTERVAL); 701 return timeout(REFRESH_INTERVAL);
694 }).then(() => 702 }).then(() =>
695 { 703 {
696 expectHidden(test, parent); 704 expectHidden(test, parent);
697 expectVisible(test, child); 705 expectVisible(test, child);
698 expectHidden(test, sibling); 706 expectHidden(test, sibling);
699 expectVisible(test, child2); 707 expectVisible(test, child2);
700 }).catch(unexpectedError.bind(test)).then(() => test.done()); 708 }).catch(unexpectedError.bind(test)).then(() => test.done());
701 }; 709 };
710
711 exports.testPseudoClassPropertiesOnStyleSheetLoad = function(test)
712 {
713 let parent = createElement();
714 let child = createElement(parent);
715 applyElemHideEmulation(
716 ["div:-abp-properties(background-color: rgb(0, 0, 0))",
717 "div:-abp-contains(hide me)",
718 "div:-abp-has(> div.hideMe)"]
719 ).then(() => timeout(REFRESH_INTERVAL)
720 ).then(() =>
721 {
722 expectVisible(test, parent);
723 expectVisible(test, child);
724
725 // Load a style sheet that targets the parent element. This should run only
726 // the "div:-abp-properties(background-color: rgb(0, 0, 0))" pattern.
727 insertStyleRule("#" + parent.id + " {background-color: #000}");
728
729 return timeout(REFRESH_INTERVAL);
730 }).then(() =>
731 {
732 expectHidden(test, parent);
733 expectVisible(test, child);
734 }).catch(unexpectedError.bind(test)).then(() => test.done());
735 };
736
737 exports.testPlainAttributeOnDomMutation = function(test)
738 {
739 let parent = createElement();
740 let child = createElement(parent);
741 applyElemHideEmulation(
742 ["div:-abp-properties(background-color: rgb(0, 0, 0))",
743 "div[data-hide-me]",
744 "div:-abp-contains(hide me)",
745 "div:-abp-has(> div.hideMe)"]
746 ).then(() => timeout(REFRESH_INTERVAL)
747 ).then(() =>
748 {
749 expectVisible(test, parent);
750 expectVisible(test, child);
751
752 // Set the "data-hide-me" attribute on the child element.
753 //
754 // Note: Since the "div[data-hide-me]" pattern has already been processed
755 // and the selector added to the document's style sheet, this will in fact
756 // not do anything at our end, but the browser will just match the selector
757 // and hide the element.
758 child.setAttribute("data-hide-me", "");
759
760 return timeout(REFRESH_INTERVAL);
761 }).then(() =>
762 {
763 expectVisible(test, parent);
764 expectHidden(test, child);
765 }).catch(unexpectedError.bind(test)).then(() => test.done());
766 };
767
768 exports.testPseudoClassContainsOnDomMutation = function(test)
769 {
770 let parent = createElement();
771 let child = createElement(parent);
772
773 child.innerText = "do nothing";
774
775 applyElemHideEmulation(
776 ["div:-abp-properties(background-color: rgb(0, 0, 0))",
777 "div[data-hide-me]",
778 "div:-abp-contains(hide me)",
779 "div:-abp-has(> div.hideMe)"]
780 ).then(() => timeout(REFRESH_INTERVAL)
781 ).then(() =>
782 {
783 expectVisible(test, parent);
784 expectVisible(test, child);
785
786 // Set the child element's text to "hide me". This should run only the
787 // "div:-abp-contains(hide me)" pattern.
788 //
789 // Note: We need to set Node.innerText here in order to trigger the
790 // "characterData" DOM mutation on Chromium. If we set Node.textContent
791 // instead, it triggers the "childList" DOM mutation instead.
792 child.innerText = "hide me";
793
794 return timeout(REFRESH_INTERVAL);
795 }).then(() =>
796 {
797 expectHidden(test, parent);
798 expectVisible(test, child);
799 }).catch(unexpectedError.bind(test)).then(() => test.done());
800 };
801
802 exports.testPseudoClassHasOnDomMutation = function(test)
803 {
804 let parent = createElement();
805 let child = null;
806 applyElemHideEmulation(
807 ["div:-abp-properties(background-color: rgb(0, 0, 0))",
808 "div[data-hide-me]",
809 "div:-abp-contains(hide me)",
810 "div:-abp-has(> div)"]
811 ).then(() => timeout(REFRESH_INTERVAL)
812 ).then(() =>
813 {
814 expectVisible(test, parent);
815
816 // Add the child element. This should run all the DOM-dependent patterns
817 // ("div:-abp-contains(hide me)" and "div:-abp-has(> div)").
818 child = createElement(parent);
819
820 return timeout(REFRESH_INTERVAL);
821 }).then(() =>
822 {
823 expectHidden(test, parent);
824 expectVisible(test, child);
825 }).catch(unexpectedError.bind(test)).then(() => test.done());
826 };
827
828 exports.testPseudoClassHasWithClassOnDomMutation = function(test)
829 {
830 let parent = createElement();
831 let child = createElement(parent);
832 applyElemHideEmulation(
833 ["div:-abp-properties(background-color: rgb(0, 0, 0))",
834 "div[data-hide-me]",
835 "div:-abp-contains(hide me)",
836 "div:-abp-has(> div.hideMe)"]
837 ).then(() => timeout(REFRESH_INTERVAL)
838 ).then(() =>
839 {
840 expectVisible(test, parent);
841 expectVisible(test, child);
842
843 // Set the child element's class to "hideMe". This should run only the
844 // "div:-abp-has(> div.hideMe)" pattern.
845 child.className = "hideMe";
846
847 return timeout(REFRESH_INTERVAL);
848 }).then(() =>
849 {
850 expectHidden(test, parent);
851 expectVisible(test, child);
852 }).catch(unexpectedError.bind(test)).then(() => test.done());
853 };
854
855 exports.testPseudoClassHasWithPseudoClassContainsOnDomMutation = function(test)
856 {
857 let parent = createElement();
858 let child = createElement(parent);
859
860 child.innerText = "do nothing";
861
862 applyElemHideEmulation(
863 ["div:-abp-properties(background-color: rgb(0, 0, 0))",
864 "div[data-hide-me]",
865 "div:-abp-contains(hide me)",
866 "div:-abp-has(> div:-abp-contains(hide me))"]
867 ).then(() => timeout(REFRESH_INTERVAL)
868 ).then(() =>
869 {
870 expectVisible(test, parent);
871 expectVisible(test, child);
872
873 // Set the child element's text to "hide me". This should run only the
874 // "div:-abp-contains(hide me)" and
875 // "div:-abp-has(> div:-abp-contains(hide me))" patterns.
876 child.innerText = "hide me";
877
878 return timeout(REFRESH_INTERVAL);
879 }).then(() =>
880 {
881 // Note: Even though it runs both the :-abp-contains() patterns, it only
882 // hides the parent element because of revision d7d51d29aa34.
883 expectHidden(test, parent);
884 expectVisible(test, child);
885 }).catch(unexpectedError.bind(test)).then(() => test.done());
886 };
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