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

Delta Between Two Patch Sets: test/browser/elemHideEmulation.js

Issue 29460576: Issue 5079 - Turn elemHideEmulation into a CommonJS module (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Left Patch Set: Rebased. No longer need browser env Created June 12, 2017, 3:20 p.m.
Right Patch Set: Rebased on master Created Aug. 10, 2017, 2:44 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« lib/content/elemHideEmulation.js ('K') | « lib/content/elemHideEmulation.js ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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
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 /* globals ElemHideEmulation, splitSelector, 20 /* globals ElemHideEmulation */
21 parseSelectorContent,
22 parseSelector, positionInParent, makeSelector,
23 PlainSelector, HasSelector, PropsSelector, ContainsSelector */
24 21
25 let myUrl = document.currentScript.src; 22 let myUrl = document.currentScript.src;
26 23
27 exports.tearDown = function(callback) 24 exports.tearDown = function(callback)
28 { 25 {
29 let styleElements = document.head.getElementsByTagName("style"); 26 let styleElements = document.head.getElementsByTagName("style");
30 while (styleElements.length) 27 while (styleElements.length)
31 styleElements[0].parentNode.removeChild(styleElements[0]); 28 styleElements[0].parentNode.removeChild(styleElements[0]);
32 29
33 let child; 30 let child;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 element.id = findUniqueId(); 82 element.id = findUniqueId();
86 if (!parent) 83 if (!parent)
87 document.body.appendChild(element); 84 document.body.appendChild(element);
88 else 85 else
89 parent.appendChild(element); 86 parent.appendChild(element);
90 insertStyleRule("#" + element.id + " " + styleBlock); 87 insertStyleRule("#" + element.id + " " + styleBlock);
91 return element; 88 return element;
92 } 89 }
93 90
94 // Will ensure the class ElemHideEmulation is loaded. 91 // Will ensure the class ElemHideEmulation is loaded.
95 // NOTE: if it never loads, this will probably hang. 92 // Pass true when it calls itself.
96 function loadElemHideEmulation() 93 function loadElemHideEmulation(inside)
97 { 94 {
98 if (typeof ElemHideEmulation == "undefined") 95 if (typeof ElemHideEmulation == "undefined")
99 { 96 {
97 if (inside)
98 return Promise.reject("Failed to load ElemHideEmulation.");
99
100 return loadScript(myUrl + "/../../../lib/common.js").then(() => 100 return loadScript(myUrl + "/../../../lib/common.js").then(() =>
101 { 101 {
102 return loadScript(myUrl + "/../../../lib/content/elemHideEmulation.js"); 102 return loadScript(myUrl + "/../../../lib/content/elemHideEmulation.js");
103 }).then(() => 103 }).then(() =>
104 { 104 {
105 return loadElemHideEmulation(); 105 return loadElemHideEmulation(true);
106 }); 106 });
107 } 107 }
108 108
109 return Promise.resolve(); 109 return Promise.resolve();
110 } 110 }
111 111
112 // Create a new ElemHideEmulation instance with @selectors. 112 // Create a new ElemHideEmulation instance with @selectors.
113 function applyElemHideEmulation(selectors) 113 function applyElemHideEmulation(selectors)
114 { 114 {
115 return loadElemHideEmulation().then(() => 115 return loadElemHideEmulation().then(() =>
(...skipping 21 matching lines...) Expand all
137 for (let elem of elems) 137 for (let elem of elems)
138 elem.style.display = "none"; 138 elem.style.display = "none";
139 } 139 }
140 ); 140 );
141 141
142 elemHideEmulation.apply(); 142 elemHideEmulation.apply();
143 return Promise.resolve(elemHideEmulation); 143 return Promise.resolve(elemHideEmulation);
144 }); 144 });
145 } 145 }
146 146
147 // internals testing
148
149 exports.testParseSelectorContent = function(test)
150 {
151 loadElemHideEmulation().then(() =>
152 {
153 let parsed = parseSelectorContent(":-abp-has(> div) > div", 10);
154 test.equal(parsed.text, "> div");
155 test.equal(parsed.end, 15);
156
157 parsed = parseSelectorContent("> div) > div", 0);
158 test.equal(parsed.text, "> div");
159 test.equal(parsed.end, 5);
160
161 // parens not closed.
162 parsed = parseSelectorContent("> div > div", 0);
163 test.equal(parsed, null);
164 }).catch(unexpectedError.bind(test)).then(() => test.done());
165 };
166
167 exports.testParseSelector = function(test)
168 {
169 loadElemHideEmulation().then(() =>
170 {
171 let selectors = parseSelector("");
172 test.equal(selectors.length, 0);
173
174 let selector = "div > :-abp-properties('background-color: rgb(0, 0, 0)')";
175 selectors = parseSelector(selector);
176 test.equal(selectors.length, 2);
177 test.ok(selectors[0] instanceof PlainSelector);
178 test.ok(selectors[1] instanceof PropsSelector);
179
180 selector = "div > :-abp-has(> div.inside) > div";
181 selectors = parseSelector(selector);
182 test.equal(selectors.length, 3);
183 test.ok(selectors[0] instanceof PlainSelector);
184 test.ok(selectors[1] instanceof HasSelector);
185 test.ok(selectors[2] instanceof PlainSelector);
186
187 selector = "div > div:-abp-has(> div.inside) > div";
188 selectors = parseSelector(selector);
189
190 test.equal(selectors.length, 3);
191 test.ok(selectors[0] instanceof PlainSelector);
192 test.ok(selectors[1] instanceof HasSelector);
193 test.ok(selectors[2] instanceof PlainSelector);
194
195 selector = "div > :-abp-has(> div.inside) > :-abp-properties(background-colo r: rgb(0, 0, 0))";
196 selectors = parseSelector(selector);
197
198 test.equal(selectors.length, 4);
199 test.ok(selectors[0] instanceof PlainSelector);
200 test.ok(selectors[1] instanceof HasSelector);
201 test.ok(selectors[2] instanceof PlainSelector);
202 test.ok(selectors[3] instanceof PropsSelector);
203
204 selector = "div > :-abp-has(> div.inside > :-abp-properties(background-color : rgb(0, 0, 0))";
205 selectors = parseSelector(selector);
206 test.equal(selectors, null);
207
208 selector = 'div[arial-label="Story"]:-abp-has(> div > div > span > span:-abp -contains(Suggested Post))';
209 selectors = parseSelector(selector);
210 test.equal(selectors.length, 2);
211 test.ok(selectors[0] instanceof PlainSelector);
212 test.ok(selectors[1] instanceof HasSelector);
213
214 selectors = selectors[1]._innerSelectors;
215 test.equals(selectors.length, 2);
216 test.ok(selectors[0] instanceof PlainSelector);
217 test.ok(selectors[1] instanceof ContainsSelector);
218 test.equals(selectors[1]._text, "Suggested Post");
219
220 // -abp-has-unsupported() is unknown. Ensure we fail parsing.
221 selector = 'div[arial-label="Story"]:-abp-has(> div > div > span > span:-abp -unsupported("Suggested Post"))';
222 selectors = parseSelector(selector);
223 test.equal(selectors, null);
224 }).catch(unexpectedError.bind(test)).then(() => test.done());
225 };
226
227 function buildDom(doc)
228 {
229 doc.body.innerHTML = `<div id="parent">
230 <div id="middle">
231 <div id="middle1"><div id="inside" class="inside"></div></div>
232 </div>
233 <div id="sibling">
234 <div id="tohide">to hide</div>
235 </div>
236 <div id="sibling2">
237 <div id="sibling21"><div id="sibling211" class="inside"></div></div>
238 </div>
239 </div>`;
240 let parent = document.getElementById("parent");
241 let middle = document.getElementById("middle");
242 let middle1 = document.getElementById("middle1");
243 let inside = document.getElementById("inside");
244 let sibling = document.getElementById("sibling");
245 let sibling2 = document.getElementById("sibling2");
246 let toHide = document.getElementById("tohide");
247 return {parent, middle, middle1, inside, sibling, sibling2, toHide};
248 }
249
250 exports.testPositionInParent = function(test)
251 {
252 let nodes = buildDom(document);
253
254 loadElemHideEmulation().then(() =>
255 {
256 test.equal(positionInParent(nodes.middle1), 1);
257 test.equal(positionInParent(nodes.inside), 1);
258 test.equal(positionInParent(nodes.sibling2), 3);
259 }).catch(unexpectedError.bind(test)).then(() => test.done());
260 };
261
262 exports.testMakeSelector = function(test)
263 {
264 let nodes = buildDom(document);
265
266 loadElemHideEmulation().then(() =>
267 {
268 test.equal(makeSelector(nodes.middle, ""),
269 ":root > BODY:nth-child(2) > DIV:nth-child(1) > DIV:nth-child(1)" );
270 test.equal(makeSelector(nodes.toHide, ""),
271 ":root > BODY:nth-child(2) > DIV:nth-child(1) > DIV:nth-child(2) > DIV:nth-child(1)");
272 }).catch(unexpectedError.bind(test)).then(() => test.done());
273 };
274
275 exports.testPlainSelector = function(test)
276 {
277 buildDom(document);
278
279 loadElemHideEmulation().then(() =>
280 {
281 let selector = new PlainSelector("div > div");
282
283 let iter = selector.getSelectors("foo > ");
284 let value = iter.next();
285 test.equal(value.value[0], "foo > div > div");
286 test.ok(iter.next().done);
287 }).catch(unexpectedError.bind(test)).then(() => test.done());
288 };
289
290 exports.testHasSelector = function(test)
291 {
292 buildDom(document);
293
294 loadElemHideEmulation().then(() =>
295 {
296 let selector = new HasSelector("> div.inside");
297
298 let iter = selector.getSelectors("", document, document.sheet);
299 let value = iter.next();
300 test.ok(!value.done);
301 test.equal(value.value[0],
302 ":root > BODY:nth-child(2) > DIV:nth-child(1) > DIV:nth-child(1) > DIV:nth-child(1)");
303
304 iter = selector.getElements("", document, document.sheet);
305 value = iter.next();
306 test.ok(!value.done);
307 test.equal(value.value.id, "middle1");
308 value = iter.next();
309 test.ok(!value.done);
310 test.equal(value.value.id, "sibling21");
311 value = iter.next();
312 test.ok(value.done);
313
314 selector = new HasSelector(":-abp-has(> div.inside)");
315
316 test.ok(selector._innerSelectors);
317 }).catch(unexpectedError.bind(test)).then(() => test.done());
318 };
319
320 exports.testContainsSelector = function(test)
321 {
322 let {toHide} = buildDom(document);
323
324 loadElemHideEmulation().then(() =>
325 {
326 let selector = new ContainsSelector("to hide");
327
328 let iter = selector.getSelectors("", document, document.sheet);
329 let value = iter.next();
330 test.ok(!value.done);
331 test.equal(value.value[0],
332 ":root > BODY:nth-child(2) > DIV:nth-child(1) > DIV:nth-child(2) > DIV:nth-child(1)");
333
334 iter = selector.getElements("", document, document.sheet);
335 value = iter.next();
336 test.ok(!value.done);
337 test.equal(value.value, toHide);
338 value = iter.next();
339 test.ok(value.done);
340 }).catch(unexpectedError.bind(test)).then(() => test.done());
341 };
342
343 exports.testSplitStyleRule = function(test)
344 {
345 loadElemHideEmulation().then(() =>
346 {
347 let selectors = splitSelector("div:-abp-has(div) > [-abp-properties='backgro und-color: rgb(0, 0, 0)'] > span");
348 test.ok(selectors);
349 test.equal(selectors.length, 1, "There is only one selector");
350
351 selectors = splitSelector("div:-abp-has(div), [-abp-properties='background-c olor: rgb(0, 0, 0)']");
352 test.ok(selectors);
353 test.equal(selectors.length, 2, "There are two selectors");
354 }).catch(unexpectedError.bind(test)).then(() => test.done());
355 };
356
357 // API testing
358
359 exports.testVerbatimPropertySelector = function(test) 147 exports.testVerbatimPropertySelector = function(test)
360 { 148 {
361 let toHide = createElementWithStyle("{background-color: #000}"); 149 let toHide = createElementWithStyle("{background-color: #000}");
362 applyElemHideEmulation( 150 applyElemHideEmulation(
363 [":-abp-properties(background-color: rgb(0, 0, 0))"] 151 [":-abp-properties(background-color: rgb(0, 0, 0))"]
364 ).then(() => 152 ).then(() =>
365 { 153 {
366 expectHidden(test, toHide); 154 expectHidden(test, toHide);
367 }).catch(unexpectedError.bind(test)).then(() => test.done()); 155 }).catch(unexpectedError.bind(test)).then(() => test.done());
368 }; 156 };
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 { 257 {
470 let toHide = createElementWithStyle("{}"); 258 let toHide = createElementWithStyle("{}");
471 applyElemHideEmulation( 259 applyElemHideEmulation(
472 [":-abp-properties(background-color: rgb(0, 0, 0))"] 260 [":-abp-properties(background-color: rgb(0, 0, 0))"]
473 ).then(() => 261 ).then(() =>
474 { 262 {
475 expectVisible(test, toHide); 263 expectVisible(test, toHide);
476 insertStyleRule("#" + toHide.id + " {background-color: #000}"); 264 insertStyleRule("#" + toHide.id + " {background-color: #000}");
477 return new Promise((resolve, reject) => 265 return new Promise((resolve, reject) =>
478 { 266 {
267 // Re-evaluation will only happen after a few seconds
268 expectVisible(test, toHide);
479 window.setTimeout(() => 269 window.setTimeout(() =>
480 { 270 {
481 expectHidden(test, toHide); 271 expectHidden(test, toHide);
482 resolve(); 272 resolve();
483 }, 0); 273 }, 4000);
484 }); 274 });
275 }).catch(unexpectedError.bind(test)).then(() => test.done());
276 };
277
278 exports.testPseudoClassWithPropBeforeSelector = function(test)
279 {
280 let parent = createElementWithStyle("{}");
281 let child = createElementWithStyle("{background-color: #000}", parent);
282 insertStyleRule(`#${child.id}::before {content: "publicite"}`);
283
284 applyElemHideEmulation(
285 ["div:-abp-properties(content: \"publicite\")"]
286 ).then(() =>
287 {
288 expectHidden(test, child);
289 expectVisible(test, parent);
485 }).catch(unexpectedError.bind(test)).then(() => test.done()); 290 }).catch(unexpectedError.bind(test)).then(() => test.done());
486 }; 291 };
487 292
488 exports.testPseudoClassHasSelector = function(test) 293 exports.testPseudoClassHasSelector = function(test)
489 { 294 {
490 let toHide = createElementWithStyle("{}"); 295 let toHide = createElementWithStyle("{}");
491 applyElemHideEmulation( 296 applyElemHideEmulation(
492 ["div:-abp-has(div)"] 297 ["div:-abp-has(div)"]
493 ).then(() => 298 ).then(() =>
494 { 299 {
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 expectVisible(test, sibling2); 400 expectVisible(test, sibling2);
596 expectHidden(test, toHide); 401 expectHidden(test, toHide);
597 }).catch(unexpectedError.bind(test)).then(() => test.done()); 402 }).catch(unexpectedError.bind(test)).then(() => test.done());
598 } 403 }
599 404
600 exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling = function(test) 405 exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling = function(test)
601 { 406 {
602 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, "div:-abp-has(: -abp-has(div.inside)) + div > div"); 407 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, "div:-abp-has(: -abp-has(div.inside)) + div > div");
603 }; 408 };
604 409
605 exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling2 = function(test) 410 exports.testPseudoClassContains = function(test)
606 { 411 {
607 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, "div:-abp-has(: -abp-has(> div.inside)) + div > div"); 412 document.body.innerHTML = `<div id="parent">
413 <div id="middle">
414 <div id="middle1"><div id="inside" class="inside"></div></div>
415 </div>
416 <div id="sibling">
417 <div id="tohide">to hide</div>
418 </div>
419 <div id="sibling2">
420 <div id="sibling21"><div id="sibling211" class="inside"></div></div>
421 </div>
422 </div>`;
423 let parent = document.getElementById("parent");
424 let middle = document.getElementById("middle");
425 let inside = document.getElementById("inside");
426 let sibling = document.getElementById("sibling");
427 let sibling2 = document.getElementById("sibling2");
428 let toHide = document.getElementById("tohide");
429
430 applyElemHideEmulation(
431 ["#parent div:-abp-contains(to hide)"]
432 ).then(() =>
433 {
434 expectVisible(test, parent);
435 expectVisible(test, middle);
436 expectVisible(test, inside);
437 expectHidden(test, sibling);
438 expectVisible(test, sibling2);
439 expectHidden(test, toHide);
440 }).catch(unexpectedError.bind(test)).then(() => test.done());
608 }; 441 };
609 442
610 exports.testPseudoClassHasSelectorWithPropSelector = function(test) 443 exports.testPseudoClassHasSelectorWithPropSelector = function(test)
611 { 444 {
612 let parent = createElementWithStyle("{}"); 445 let parent = createElementWithStyle("{}");
613 let child = createElementWithStyle("{background-color: #000}", parent); 446 let child = createElementWithStyle("{background-color: #000}", parent);
614 applyElemHideEmulation( 447 applyElemHideEmulation(
615 ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"] 448 ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"]
616 ).then(() => 449 ).then(() =>
617 { 450 {
618 expectVisible(test, child); 451 expectVisible(test, child);
619 expectHidden(test, parent); 452 expectHidden(test, parent);
620 }).catch(unexpectedError.bind(test)).then(() => test.done()); 453 }).catch(unexpectedError.bind(test)).then(() => test.done());
621 }; 454 };
455
456 exports.testPseudoClassHasSelectorWithPropSelector2 = function(test)
457 {
458 let parent = createElementWithStyle("{}");
459 let child = createElementWithStyle("{}", parent);
460 insertStyleRule("body #" + parent.id + " > div { background-color: #000}");
461 applyElemHideEmulation(
462 ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"]
463 ).then(() =>
464 {
465 expectVisible(test, child);
466 expectHidden(test, parent);
467 }).catch(unexpectedError.bind(test)).then(() => test.done());
468 };
LEFTRIGHT

Powered by Google App Engine
This is Rietveld