| OLD | NEW | 
|---|
| 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  Loading... | 
| 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  Loading... | 
| 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) | 
|  | 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 selector = "div:has(span)"; | 
|  | 171     // testing the regexp | 
|  | 172     var match = pseudoClassHasSelectorRegExp.exec(selector); | 
|  | 173     test.ok(match); | 
|  | 174     test.equal(match[1], "span"); | 
|  | 175 | 
|  | 176     selector = ":has(div.inside)"; | 
|  | 177     match = pseudoClassHasSelectorRegExp.exec(selector); | 
|  | 178     test.ok(match); | 
|  | 179     test.equal(match[1], "div.inside"); | 
|  | 180 | 
|  | 181     selector = "div[-abp-selector=':has(div.inside)']"; | 
|  | 182     match = abpSelectorRegExp.exec(selector); | 
|  | 183     test.ok(match); | 
|  | 184     test.equal(match[2], ":has(div.inside)"); | 
|  | 185 | 
|  | 186     selector = "[-abp-selector=':has(div.inside)']"; | 
|  | 187     match = abpSelectorRegExp.exec(selector); | 
|  | 188     test.ok(match); | 
|  | 189     test.equal(match[2], ":has(div.inside)"); | 
|  | 190 | 
|  | 191     selector = "div[-abp-selector=':has(:-abp-properties(\"background-color: rgb
     (0, 0, 0)\"))']"; | 
|  | 192     match = abpSelectorRegExp.exec(selector); | 
|  | 193     test.ok(match); | 
|  | 194     test.equal(match[2], ":has(:-abp-properties(\"background-color: rgb(0, 0, 0)
     \"))"); | 
|  | 195 | 
|  | 196     test.done(); | 
|  | 197   }); | 
|  | 198 }; | 
|  | 199 | 
|  | 200 exports.testSplitStyleRule = function(test) | 
|  | 201 { | 
|  | 202   loadElemHideEmulation(function() | 
|  | 203   { | 
|  | 204     var selectors = splitSelector("div:has(div) > [-abp-properties='background-c
     olor: rgb(0, 0, 0)'] > span"); | 
|  | 205     test.ok(selectors); | 
|  | 206     test.equal(selectors.length, 1, "There is only one selector"); | 
|  | 207 | 
|  | 208     selectors = splitSelector("div:has(div), [-abp-properties='background-color:
      rgb(0, 0, 0)']"); | 
|  | 209     test.ok(selectors); | 
|  | 210     test.equal(selectors.length, 2, "There are two selectors"); | 
|  | 211 | 
|  | 212     test.done(); | 
|  | 213   }); | 
|  | 214 }; | 
|  | 215 | 
|  | 216 exports.testParsePattern = function(test) | 
|  | 217 { | 
|  | 218   loadElemHideEmulation(function() | 
|  | 219   { | 
|  | 220     var pattern = unwrapPattern({selector: "[-abp-properties='background-color: 
     rgb(0, 0, 0)']"}); | 
|  | 221     test.ok(pattern); | 
|  | 222     test.equal(pattern.type, "props"); | 
|  | 223     pattern = parsePattern({selector: "[-abp-properties='background-color: rgb(0
     , 0, 0)']"}, false); | 
|  | 224     test.ok(pattern); | 
|  | 225     test.equal(pattern.type, "props"); | 
|  | 226     pattern = parsePattern({selector: "[-abp-properties='background-color: rgb(0
     , 0, 0)']"}, true); | 
|  | 227     test.ok(pattern); | 
|  | 228     test.equal(pattern.type, "props"); | 
|  | 229 | 
|  | 230     pattern = unwrapPattern({selector: "[-abp-selector=':-abp-properties(\"backg
     round-color: rgb(0, 0, 0)\")']"}); | 
|  | 231     test.ok(pattern); | 
|  | 232     test.equal(pattern.type, "props"); | 
|  | 233     pattern = parsePattern({selector: "[-abp-selector=':-abp-properties(\"backgr
     ound-color: rgb(0, 0, 0)\")']"}, false); | 
|  | 234     test.equal(pattern, undefined); | 
|  | 235     pattern = parsePattern({selector: "[-abp-selector=':-abp-properties(\"backgr
     ound-color: rgb(0, 0, 0)\")']"}, true); | 
|  | 236     test.equal(pattern, undefined); | 
|  | 237 | 
|  | 238     pattern = unwrapPattern({selector: ":has(div)"}); | 
|  | 239     test.equal(pattern, undefined); | 
|  | 240     pattern = parsePattern({selector: ":has(div)"}, false); | 
|  | 241     test.equal(pattern, undefined); | 
|  | 242     pattern = parsePattern({selector: ":has(div)"}, true); | 
|  | 243     test.ok(pattern); | 
|  | 244     test.equal(pattern.type, "has"); | 
|  | 245 | 
|  | 246     pattern = unwrapPattern({selector: ":-abp-properties('background-color: rgb(
     0, 0, 0)')"}); | 
|  | 247     test.equal(pattern, undefined); | 
|  | 248     pattern = parsePattern({selector: ":-abp-properties('background-color: rgb(0
     , 0, 0)')"}, false); | 
|  | 249     test.equal(pattern, undefined); | 
|  | 250     pattern = parsePattern({selector: ":-abp-properties('background-color: rgb(0
     , 0, 0)')"}, true); | 
|  | 251     test.ok(pattern); | 
|  | 252     test.equal(pattern.type, "props"); | 
|  | 253 | 
|  | 254     test.done(); | 
|  | 255   }); | 
|  | 256 }; | 
|  | 257 | 
|  | 258 function runTestVerbatimPropertySelector(test, selector) | 
|  | 259 { | 
|  | 260   var toHide = createElementWithStyle("{background-color: #000}"); | 
|  | 261   applyElemHideEmulation( | 
|  | 262     [selector], | 
|  | 263     function() | 
|  | 264     { | 
|  | 265       expectHidden(test, toHide); | 
|  | 266       test.done(); | 
|  | 267     } | 
|  | 268   ); | 
| 134 } | 269 } | 
| 135 | 270 | 
| 136 exports.testVerbatimPropertySelector = function(test) | 271 exports.testVerbatimPropertySelector = function(test) | 
| 137 { | 272 { | 
|  | 273   runTestVerbatimPropertySelector(test, "[-abp-properties='background-color: rgb
     (0, 0, 0)']"); | 
|  | 274 }; | 
|  | 275 | 
|  | 276 /* Testing the new syntax */ | 
|  | 277 exports.testVerbatimPropertyPseudoSelector = function(test) | 
|  | 278 { | 
|  | 279   runTestVerbatimPropertySelector(test, "[-abp-selector=':-abp-properties(\"back
     ground-color: rgb(0, 0, 0)\")']"); | 
|  | 280 }; | 
|  | 281 | 
|  | 282 function runTestVerbatimPropertySelectorWithPrefix(test, selector) | 
|  | 283 { | 
|  | 284   var parent = createElementWithStyle("{background-color: #000}"); | 
|  | 285   var toHide = createElementWithStyle("{background-color: #000}", parent); | 
|  | 286   applyElemHideEmulation( | 
|  | 287     [selector], | 
|  | 288     function() | 
|  | 289     { | 
|  | 290       expectVisible(test, parent); | 
|  | 291       expectHidden(test, toHide); | 
|  | 292       test.done(); | 
|  | 293     } | 
|  | 294   ); | 
|  | 295 } | 
|  | 296 | 
|  | 297 exports.testVerbatimPropertySelectorWithPrefix = function(test) | 
|  | 298 { | 
|  | 299   runTestVerbatimPropertySelectorWithPrefix(test, "div > [-abp-properties='backg
     round-color: rgb(0, 0, 0)']"); | 
|  | 300 }; | 
|  | 301 | 
|  | 302 // testing the new syntax | 
|  | 303 exports.testVerbatimPropertyPseudoSelectorWithPrefix = function(test) | 
|  | 304 { | 
|  | 305   runTestVerbatimPropertySelectorWithPrefix(test, "div > [-abp-selector=':-abp-p
     roperties(\"background-color: rgb(0, 0, 0)\")']"); | 
|  | 306 }; | 
|  | 307 | 
|  | 308 exports.testVerbatimPropertySelectorWithPrefixNoMatch = function(test) | 
|  | 309 { | 
|  | 310   var parent = createElementWithStyle("{background-color: #000}"); | 
|  | 311   var toHide = createElementWithStyle("{background-color: #fff}", parent); | 
|  | 312   applyElemHideEmulation( | 
|  | 313     ["div > [-abp-properties='background-color: rgb(0, 0, 0)']"], | 
|  | 314     function() | 
|  | 315     { | 
|  | 316       expectVisible(test, parent); | 
|  | 317       expectVisible(test, toHide); | 
|  | 318       test.done(); | 
|  | 319     } | 
|  | 320   ); | 
|  | 321 }; | 
|  | 322 | 
|  | 323 function runTestVerbatimPropertySelectorWithSuffix(test, selector) | 
|  | 324 { | 
|  | 325   var parent = createElementWithStyle("{background-color: #000}"); | 
|  | 326   var toHide = createElementWithStyle("{background-color: #000}", parent); | 
|  | 327   applyElemHideEmulation( | 
|  | 328     [selector], | 
|  | 329     function() | 
|  | 330     { | 
|  | 331       expectVisible(test, parent); | 
|  | 332       expectHidden(test, toHide); | 
|  | 333       test.done(); | 
|  | 334     } | 
|  | 335   ); | 
|  | 336 } | 
|  | 337 | 
|  | 338 exports.testVerbatimPropertySelectorWithSuffix = function(test) | 
|  | 339 { | 
|  | 340   runTestVerbatimPropertySelectorWithSuffix(test, "[-abp-properties='background-
     color: rgb(0, 0, 0)'] > div"); | 
|  | 341 }; | 
|  | 342 | 
|  | 343 exports.testVerbatimPropertyPseudoSelectorWithSuffix = function(test) | 
|  | 344 { | 
|  | 345   runTestVerbatimPropertySelectorWithSuffix(test, "[-abp-selector=':-abp-propert
     ies(\"background-color: rgb(0, 0, 0)\")'] > div"); | 
|  | 346 }; | 
|  | 347 | 
|  | 348 function runTestVerbatimPropertySelectorWithPrefixAndSuffix(test, selector) | 
|  | 349 { | 
|  | 350   var parent = createElementWithStyle("{background-color: #000}"); | 
|  | 351   var middle = createElementWithStyle("{background-color: #000}", parent); | 
|  | 352   var toHide = createElementWithStyle("{background-color: #000}", middle); | 
|  | 353   applyElemHideEmulation( | 
|  | 354     [selector], | 
|  | 355     function() | 
|  | 356     { | 
|  | 357       expectVisible(test, parent); | 
|  | 358       expectVisible(test, middle); | 
|  | 359       expectHidden(test, toHide); | 
|  | 360       test.done(); | 
|  | 361     } | 
|  | 362   ); | 
|  | 363 } | 
|  | 364 | 
|  | 365 exports.testVerbatimPropertySelectorWithPrefixAndSuffix = function(test) | 
|  | 366 { | 
|  | 367   runTestVerbatimPropertySelectorWithPrefixAndSuffix(test, "div > [-abp-properti
     es='background-color: rgb(0, 0, 0)'] > div"); | 
|  | 368 }; | 
|  | 369 | 
|  | 370 exports.testVerbatimPropertyPseudoSelectorWithPrefixAndSuffix = function(test) | 
|  | 371 { | 
|  | 372   runTestVerbatimPropertySelectorWithPrefixAndSuffix(test, "div > [-abp-selector
     =':-abp-properties(\"background-color: rgb(0, 0, 0)\")'] > div"); | 
|  | 373 }; | 
|  | 374 | 
|  | 375 exports.testPropertySelectorWithWildcard = function(test) | 
|  | 376 { | 
| 138   var toHide = createElementWithStyle("{background-color: #000}"); | 377   var toHide = createElementWithStyle("{background-color: #000}"); | 
| 139   applyElemHideEmulation( | 378   applyElemHideEmulation( | 
| 140     ["[-abp-properties='background-color: rgb(0, 0, 0)']"], |  | 
| 141     function() |  | 
| 142     { |  | 
| 143       expectHidden(test, toHide); |  | 
| 144       test.done(); |  | 
| 145     } |  | 
| 146   ); |  | 
| 147 }; |  | 
| 148 |  | 
| 149 exports.testPropertySelectorWithWildcard = function(test) |  | 
| 150 { |  | 
| 151   var toHide = createElementWithStyle("{background-color: #000}"); |  | 
| 152   applyElemHideEmulation( |  | 
| 153     ["[-abp-properties='*color: rgb(0, 0, 0)']"], | 379     ["[-abp-properties='*color: rgb(0, 0, 0)']"], | 
| 154     function() | 380     function() | 
| 155     { | 381     { | 
| 156       expectHidden(test, toHide); | 382       expectHidden(test, toHide); | 
| 157       test.done(); | 383       test.done(); | 
| 158     } | 384     } | 
| 159   ); | 385   ); | 
| 160 }; | 386 }; | 
| 161 | 387 | 
| 162 exports.testPropertySelectorWithRegularExpression = function(test) | 388 exports.testPropertySelectorWithRegularExpression = function(test) | 
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 208       expectVisible(test, toHide); | 434       expectVisible(test, toHide); | 
| 209       insertStyleRule("#" + toHide.id + " {background-color: #000}"); | 435       insertStyleRule("#" + toHide.id + " {background-color: #000}"); | 
| 210       window.setTimeout(function() | 436       window.setTimeout(function() | 
| 211       { | 437       { | 
| 212         expectHidden(test, toHide); | 438         expectHidden(test, toHide); | 
| 213         test.done(); | 439         test.done(); | 
| 214       }, 0); | 440       }, 0); | 
| 215     } | 441     } | 
| 216   ); | 442   ); | 
| 217 }; | 443 }; | 
|  | 444 | 
|  | 445 exports.testPseudoClassHasMatcher = function(test) | 
|  | 446 { | 
|  | 447   var parent = createElementWithStyle("{}"); | 
|  | 448   var child = createElementWithStyle("{}", parent); | 
|  | 449   loadElemHideEmulation(function() | 
|  | 450   { | 
|  | 451     var matcher = new PseudoHasMatcher("div"); | 
|  | 452     test.equal(matcher.match(parent), true, "Parent should contain what is expec
     ted"); | 
|  | 453     test.equal(matcher.match(child), false, "Child shouldn't match"); | 
|  | 454 | 
|  | 455     var matcher2 = new PseudoHasMatcher("span"); | 
|  | 456     test.equal(matcher2.match(parent), false, "Doesn't have a <span> child, shou
     ldn't match"); | 
|  | 457     test.equal(matcher2.match(child), false, "Child shouldn't match"); | 
|  | 458 | 
|  | 459     test.done(); | 
|  | 460   }); | 
|  | 461 }; | 
|  | 462 | 
|  | 463 exports.testPseudoClassHasSelector = function(test) | 
|  | 464 { | 
|  | 465   var toHide = createElementWithStyle("{}"); | 
|  | 466   applyElemHideEmulation( | 
|  | 467     ["div[-abp-selector=':has(div)']"], | 
|  | 468     function() | 
|  | 469     { | 
|  | 470       expectVisible(test, toHide); | 
|  | 471       test.done(); | 
|  | 472     } | 
|  | 473   ); | 
|  | 474 }; | 
|  | 475 | 
|  | 476 exports.testPseudoClassHasSelectorWithPrefix = function(test) | 
|  | 477 { | 
|  | 478   var parent = createElementWithStyle("{}"); | 
|  | 479   var child = createElementWithStyle("{}", parent); | 
|  | 480   applyElemHideEmulation( | 
|  | 481     ["div[-abp-selector=':has(div)']"], | 
|  | 482     function() | 
|  | 483     { | 
|  | 484       expectHidden(test, parent); | 
|  | 485       expectVisible(test, child); | 
|  | 486       test.done(); | 
|  | 487     } | 
|  | 488   ); | 
|  | 489 }; | 
|  | 490 | 
|  | 491 exports.testPseudoClassHasSelectorWithSuffix = function(test) | 
|  | 492 { | 
|  | 493   var parent = createElementWithStyle("{}"); | 
|  | 494   var middle = createElementWithStyle("{}", parent); | 
|  | 495   var child = createElementWithStyle("{}", middle); | 
|  | 496   applyElemHideEmulation( | 
|  | 497     ["div[-abp-selector=':has(div)'] > div"], | 
|  | 498     function() | 
|  | 499     { | 
|  | 500       expectVisible(test, parent); | 
|  | 501       expectHidden(test, middle); | 
|  | 502       expectHidden(test, child); | 
|  | 503       test.done(); | 
|  | 504     } | 
|  | 505   ); | 
|  | 506 }; | 
|  | 507 | 
|  | 508 exports.testPseudoClassHasSelectorWithSuffixSibling = function(test) | 
|  | 509 { | 
|  | 510   var parent = createElementWithStyle("{}"); | 
|  | 511   var middle = createElementWithStyle("{}", parent); | 
|  | 512   var toHide = createElementWithStyle("{}"); | 
|  | 513   applyElemHideEmulation( | 
|  | 514     ["div[-abp-selector=':has(div)'] + div"], | 
|  | 515     function() | 
|  | 516     { | 
|  | 517       expectVisible(test, parent); | 
|  | 518       expectVisible(test, middle); | 
|  | 519       expectHidden(test, toHide); | 
|  | 520       test.done(); | 
|  | 521     } | 
|  | 522   ); | 
|  | 523 }; | 
|  | 524 | 
|  | 525 exports.testPseudoClassHasSelectorWithSuffixSiblingChild = function(test) | 
|  | 526 { | 
|  | 527   //  <div> | 
|  | 528   //    <div></div> | 
|  | 529   //    <div> | 
|  | 530   //      <div>to hide</div> | 
|  | 531   //    </div> | 
|  | 532   //  </div> | 
|  | 533   var parent = createElementWithStyle("{}"); | 
|  | 534   var middle = createElementWithStyle("{}", parent); | 
|  | 535   var sibling = createElementWithStyle("{}"); | 
|  | 536   var toHide = createElementWithStyle("{}", sibling); | 
|  | 537   applyElemHideEmulation( | 
|  | 538     ["div[-abp-selector=':has(div)'] + div > div"], | 
|  | 539     function() | 
|  | 540     { | 
|  | 541       expectVisible(test, parent); | 
|  | 542       expectVisible(test, middle); | 
|  | 543       expectVisible(test, sibling); | 
|  | 544       expectHidden(test, toHide); | 
|  | 545       test.done(); | 
|  | 546     } | 
|  | 547   ); | 
|  | 548 }; | 
|  | 549 | 
|  | 550 function runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, selector
     ) | 
|  | 551 { | 
|  | 552   document.body.innerHTML = '<div id="parent">' + | 
|  | 553     '<div id="middle">' + | 
|  | 554       '<div id="middle.1"><div id="inside" class="inside"></div></div>' + | 
|  | 555     '</div>' + | 
|  | 556     '<div id="sibling">' + | 
|  | 557       '<div id="tohide">to hide</div>' + | 
|  | 558     '</div>' + | 
|  | 559     '<div id="sibling2">' + | 
|  | 560       '<div id="sibling2.1"><div id="sibling2.1.1" class="inside"></div></div>' 
     + | 
|  | 561     '</div>' + | 
|  | 562   '</div>'; | 
|  | 563   var parent = document.getElementById("parent"); | 
|  | 564   var middle = document.getElementById("middle"); | 
|  | 565   var inside = document.getElementById("inside"); | 
|  | 566   var sibling = document.getElementById("sibling"); | 
|  | 567   var sibling2 = document.getElementById("sibling2"); | 
|  | 568   var toHide = document.getElementById("tohide"); | 
|  | 569 | 
|  | 570   applyElemHideEmulation( | 
|  | 571     [selector], | 
|  | 572     function() | 
|  | 573     { | 
|  | 574       expectVisible(test, parent); | 
|  | 575       expectVisible(test, middle); | 
|  | 576       expectVisible(test, inside); | 
|  | 577       expectVisible(test, sibling); | 
|  | 578       expectVisible(test, sibling2); | 
|  | 579       expectHidden(test, toHide); | 
|  | 580       test.done(); | 
|  | 581     } | 
|  | 582   ); | 
|  | 583 } | 
|  | 584 | 
|  | 585 exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling = function(test) | 
|  | 586 { | 
|  | 587   runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, "div[-abp-selec
     tor=':has(:has(div.inside))'] + div > div"); | 
|  | 588 }; | 
|  | 589 | 
|  | 590 exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling2 = function(test) | 
|  | 591 { | 
|  | 592   runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, "div[-abp-selec
     tor=':has(:has(> div.inside))'] + div > div"); | 
|  | 593 }; | 
|  | 594 | 
|  | 595 exports.testPseudoClassHasSelectorWithPropSelector = function(test) | 
|  | 596 { | 
|  | 597   var parent = createElementWithStyle("{}"); | 
|  | 598   var child = createElementWithStyle("{background-color: #000}", parent); | 
|  | 599   applyElemHideEmulation( | 
|  | 600     ["div[-abp-selector=':has(:-abp-properties(\"background-color: rgb(0, 0, 0)\
     "))']"], | 
|  | 601     function() | 
|  | 602     { | 
|  | 603       expectVisible(test, child); | 
|  | 604       expectHidden(test, parent); | 
|  | 605       test.done(); | 
|  | 606     } | 
|  | 607   ); | 
|  | 608 }; | 
| OLD | NEW | 
|---|