| 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-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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 }; | 45 }; |
| 46 | 46 |
| 47 function timeout(delay) | 47 function timeout(delay) |
| 48 { | 48 { |
| 49 return new Promise((resolve, reject) => | 49 return new Promise((resolve, reject) => |
| 50 { | 50 { |
| 51 window.setTimeout(resolve, delay); | 51 window.setTimeout(resolve, delay); |
| 52 }); | 52 }); |
| 53 } | 53 } |
| 54 | 54 |
| 55 function unexpectedError(error) | 55 function unexpectedError(test, error) |
| 56 { | 56 { |
| 57 console.error(error); | 57 console.error(error); |
| 58 this.ok(false, "Unexpected error: " + error); | 58 test.ok(false, "Unexpected error: " + error); |
| 59 } | 59 } |
| 60 | 60 |
| 61 function expectHidden(test, element, id) | 61 function expectHidden(test, element, id) |
| 62 { | 62 { |
| 63 let withId = ""; | 63 let withId = ""; |
| 64 if (typeof id != "undefined") | 64 if (typeof id != "undefined") |
| 65 withId = ` with ID '${id}'`; | 65 withId = ` with ID '${id}'`; |
| 66 | 66 |
| 67 test.equal( | 67 test.equal( |
| 68 window.getComputedStyle(element).display, "none", | 68 window.getComputedStyle(element).display, "none", |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 // Insert a <div> with a unique id and a CSS rule | 141 // Insert a <div> with a unique id and a CSS rule |
| 142 // for the the selector matching the id. | 142 // for the the selector matching the id. |
| 143 function createElementWithStyle(styleBlock, parent) | 143 function createElementWithStyle(styleBlock, parent) |
| 144 { | 144 { |
| 145 let element = createElement(parent); | 145 let element = createElement(parent); |
| 146 insertStyleRule("#" + element.id + " " + styleBlock); | 146 insertStyleRule("#" + element.id + " " + styleBlock); |
| 147 return element; | 147 return element; |
| 148 } | 148 } |
| 149 | 149 |
| 150 // Create a new ElemHideEmulation instance with @selectors. | 150 // Create a new ElemHideEmulation instance with @selectors. |
| 151 function applyElemHideEmulation(selectors) | 151 async function applyElemHideEmulation(test, selectors) |
| 152 { | 152 { |
| 153 return Promise.resolve().then(() => | 153 await Promise.resolve(); |
| 154 { | 154 |
| 155 let elemHideEmulation = new ElemHideEmulation( | 155 let elemHideEmulation = null; |
| 156 |
| 157 try |
| 158 { |
| 159 elemHideEmulation = new ElemHideEmulation( |
| 156 elems => | 160 elems => |
| 157 { | 161 { |
| 158 for (let elem of elems) | 162 for (let elem of elems) |
| 159 elem.style.display = "none"; | 163 elem.style.display = "none"; |
| 160 } | 164 } |
| 161 ); | 165 ); |
| 162 | 166 |
| 163 elemHideEmulation.document = testDocument; | 167 elemHideEmulation.document = testDocument; |
| 164 elemHideEmulation.MIN_INVOCATION_INTERVAL = REFRESH_INTERVAL / 2; | 168 elemHideEmulation.MIN_INVOCATION_INTERVAL = REFRESH_INTERVAL / 2; |
| 165 elemHideEmulation.apply(selectors.map( | 169 elemHideEmulation.apply(selectors.map( |
| 166 selector => ({selector, text: selector}) | 170 selector => ({selector, text: selector}) |
| 167 )); | 171 )); |
| 172 |
| 168 return elemHideEmulation; | 173 return elemHideEmulation; |
| 169 }); | 174 } |
| 175 catch (error) |
| 176 { |
| 177 unexpectedError(test, error); |
| 178 } |
| 170 } | 179 } |
| 171 | 180 |
| 172 exports.testVerbatimPropertySelector = function(test) | 181 exports.testVerbatimPropertySelector = async function(test) |
| 173 { | 182 { |
| 174 let toHide = createElementWithStyle("{background-color: #000}"); | 183 let toHide = createElementWithStyle("{background-color: #000}"); |
| 175 applyElemHideEmulation( | 184 let selectors = [":-abp-properties(background-color: rgb(0, 0, 0))"]; |
| 176 [":-abp-properties(background-color: rgb(0, 0, 0))"] | 185 |
| 177 ).then(() => | 186 if (await applyElemHideEmulation(test, selectors)) |
| 178 { | 187 expectHidden(test, toHide); |
| 179 expectHidden(test, toHide); | 188 |
| 180 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 189 test.done(); |
| 181 }; | 190 }; |
| 182 | 191 |
| 183 exports.testVerbatimPropertySelectorWithPrefix = function(test) | 192 exports.testVerbatimPropertySelectorWithPrefix = async function(test) |
| 184 { | 193 { |
| 185 let parent = createElementWithStyle("{background-color: #000}"); | 194 let parent = createElementWithStyle("{background-color: #000}"); |
| 186 let toHide = createElementWithStyle("{background-color: #000}", parent); | 195 let toHide = createElementWithStyle("{background-color: #000}", parent); |
| 187 applyElemHideEmulation( | 196 |
| 188 ["div > :-abp-properties(background-color: rgb(0, 0, 0))"] | 197 let selectors = ["div > :-abp-properties(background-color: rgb(0, 0, 0))"]; |
| 189 ).then(() => | 198 |
| 190 { | 199 if (await applyElemHideEmulation(test, selectors)) |
| 191 expectVisible(test, parent); | 200 { |
| 192 expectHidden(test, toHide); | 201 expectVisible(test, parent); |
| 193 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 202 expectHidden(test, toHide); |
| 194 }; | 203 } |
| 195 | 204 |
| 196 exports.testVerbatimPropertySelectorWithPrefixNoMatch = function(test) | 205 test.done(); |
| 206 }; |
| 207 |
| 208 exports.testVerbatimPropertySelectorWithPrefixNoMatch = async function(test) |
| 197 { | 209 { |
| 198 let parent = createElementWithStyle("{background-color: #000}"); | 210 let parent = createElementWithStyle("{background-color: #000}"); |
| 199 let toHide = createElementWithStyle("{background-color: #fff}", parent); | 211 let toHide = createElementWithStyle("{background-color: #fff}", parent); |
| 200 applyElemHideEmulation( | 212 |
| 201 ["div > :-abp-properties(background-color: rgb(0, 0, 0))"] | 213 let selectors = ["div > :-abp-properties(background-color: rgb(0, 0, 0))"]; |
| 202 ).then(() => | 214 |
| 203 { | 215 if (await applyElemHideEmulation(test, selectors)) |
| 204 expectVisible(test, parent); | 216 { |
| 205 expectVisible(test, toHide); | 217 expectVisible(test, parent); |
| 206 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 218 expectVisible(test, toHide); |
| 207 }; | 219 } |
| 208 | 220 |
| 209 exports.testVerbatimPropertySelectorWithSuffix = function(test) | 221 test.done(); |
| 222 }; |
| 223 |
| 224 exports.testVerbatimPropertySelectorWithSuffix = async function(test) |
| 210 { | 225 { |
| 211 let parent = createElementWithStyle("{background-color: #000}"); | 226 let parent = createElementWithStyle("{background-color: #000}"); |
| 212 let toHide = createElementWithStyle("{background-color: #000}", parent); | 227 let toHide = createElementWithStyle("{background-color: #000}", parent); |
| 213 applyElemHideEmulation( | 228 |
| 214 [":-abp-properties(background-color: rgb(0, 0, 0)) > div"] | 229 let selectors = [":-abp-properties(background-color: rgb(0, 0, 0)) > div"]; |
| 215 ).then(() => | 230 |
| 216 { | 231 if (await applyElemHideEmulation(test, selectors)) |
| 217 expectVisible(test, parent); | 232 { |
| 218 expectHidden(test, toHide); | 233 expectVisible(test, parent); |
| 219 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 234 expectHidden(test, toHide); |
| 220 }; | 235 } |
| 221 | 236 |
| 222 exports.testVerbatimPropertyPseudoSelectorWithPrefixAndSuffix = function(test) | 237 test.done(); |
| 238 }; |
| 239 |
| 240 exports.testVerbatimPropertyPseudoSelectorWithPrefixAndSuffix = async function(t
est) |
| 223 { | 241 { |
| 224 let parent = createElementWithStyle("{background-color: #000}"); | 242 let parent = createElementWithStyle("{background-color: #000}"); |
| 225 let middle = createElementWithStyle("{background-color: #000}", parent); | 243 let middle = createElementWithStyle("{background-color: #000}", parent); |
| 226 let toHide = createElementWithStyle("{background-color: #000}", middle); | 244 let toHide = createElementWithStyle("{background-color: #000}", middle); |
| 227 applyElemHideEmulation( | 245 |
| 228 ["div > :-abp-properties(background-color: rgb(0, 0, 0)) > div"] | 246 let selectors = ["div > :-abp-properties(background-color: rgb(0, 0, 0)) > div
"]; |
| 229 ).then(() => | 247 |
| 248 if (await applyElemHideEmulation(test, selectors)) |
| 230 { | 249 { |
| 231 expectVisible(test, parent); | 250 expectVisible(test, parent); |
| 232 expectVisible(test, middle); | 251 expectVisible(test, middle); |
| 233 expectHidden(test, toHide); | 252 expectHidden(test, toHide); |
| 234 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 253 } |
| 254 |
| 255 test.done(); |
| 235 }; | 256 }; |
| 236 | 257 |
| 237 // Add the style. Then add the element for that style. | 258 // Add the style. Then add the element for that style. |
| 238 // This should retrigger the filtering and hide it. | 259 // This should retrigger the filtering and hide it. |
| 239 exports.testPropertyPseudoSelectorAddStyleAndElement = function(test) | 260 exports.testPropertyPseudoSelectorAddStyleAndElement = async function(test) |
| 240 { | 261 { |
| 241 let styleElement; | 262 let styleElement; |
| 242 let toHide; | 263 let toHide; |
| 243 applyElemHideEmulation( | 264 |
| 244 [":-abp-properties(background-color: rgb(0, 0, 0))"] | 265 let selectors = [":-abp-properties(background-color: rgb(0, 0, 0))"]; |
| 245 ).then(() => | 266 |
| 267 if (await applyElemHideEmulation(test, selectors)) |
| 246 { | 268 { |
| 247 styleElement = testDocument.createElement("style"); | 269 styleElement = testDocument.createElement("style"); |
| 248 testDocument.head.appendChild(styleElement); | 270 testDocument.head.appendChild(styleElement); |
| 249 styleElement.sheet.insertRule("#toHide {background-color: #000}"); | 271 styleElement.sheet.insertRule("#toHide {background-color: #000}"); |
| 250 return timeout(REFRESH_INTERVAL); | 272 await timeout(REFRESH_INTERVAL); |
| 251 }).then(() => | 273 |
| 252 { | |
| 253 toHide = createElement(); | 274 toHide = createElement(); |
| 254 toHide.id = "toHide"; | 275 toHide.id = "toHide"; |
| 255 expectVisible(test, toHide); | 276 expectVisible(test, toHide); |
| 256 return timeout(REFRESH_INTERVAL); | 277 await timeout(REFRESH_INTERVAL); |
| 257 }).then(() => | 278 |
| 258 { | 279 expectHidden(test, toHide); |
| 259 expectHidden(test, toHide); | 280 } |
| 260 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 281 |
| 261 }; | 282 test.done(); |
| 262 | 283 }; |
| 263 exports.testPropertySelectorWithWildcard = function(test) | 284 |
| 264 { | 285 exports.testPropertySelectorWithWildcard = async function(test) |
| 265 let toHide = createElementWithStyle("{background-color: #000}"); | 286 { |
| 266 applyElemHideEmulation( | 287 let toHide = createElementWithStyle("{background-color: #000}"); |
| 267 [":-abp-properties(*color: rgb(0, 0, 0))"] | 288 let selectors = [":-abp-properties(*color: rgb(0, 0, 0))"]; |
| 268 ).then(() => | 289 |
| 269 { | 290 if (await applyElemHideEmulation(test, selectors)) |
| 270 expectHidden(test, toHide); | 291 expectHidden(test, toHide); |
| 271 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 292 |
| 272 }; | 293 test.done(); |
| 273 | 294 }; |
| 274 exports.testPropertySelectorWithRegularExpression = function(test) | 295 |
| 275 { | 296 exports.testPropertySelectorWithRegularExpression = async function(test) |
| 276 let toHide = createElementWithStyle("{background-color: #000}"); | 297 { |
| 277 applyElemHideEmulation( | 298 let toHide = createElementWithStyle("{background-color: #000}"); |
| 278 [":-abp-properties(/.*color: rgb\\(0, 0, 0\\)/)"] | 299 let selectors = [":-abp-properties(/.*color: rgb\\(0, 0, 0\\)/)"]; |
| 279 ).then(() => | 300 |
| 280 { | 301 if (await applyElemHideEmulation(test, selectors)) |
| 281 expectHidden(test, toHide); | 302 expectHidden(test, toHide); |
| 282 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 303 |
| 283 }; | 304 test.done(); |
| 284 | 305 }; |
| 285 exports.testPropertySelectorWithEscapedBrace = function(test) | 306 |
| 286 { | 307 exports.testPropertySelectorWithEscapedBrace = async function(test) |
| 287 let toHide = createElementWithStyle("{background-color: #000}"); | 308 { |
| 288 applyElemHideEmulation( | 309 let toHide = createElementWithStyle("{background-color: #000}"); |
| 289 [":-abp-properties(/background.\\7B 0,6\\7D : rgb\\(0, 0, 0\\)/)"] | 310 let selectors = [":-abp-properties(/background.\\7B 0,6\\7D : rgb\\(0, 0, 0\\)
/)"]; |
| 290 ).then(() => | 311 |
| 291 { | 312 if (await applyElemHideEmulation(test, selectors)) |
| 292 expectHidden(test, toHide); | 313 expectHidden(test, toHide); |
| 293 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 314 |
| 294 }; | 315 test.done(); |
| 295 | 316 }; |
| 296 exports.testPropertySelectorWithImproperlyEscapedBrace = function(test) | 317 |
| 297 { | 318 exports.testPropertySelectorWithImproperlyEscapedBrace = async function(test) |
| 298 let toHide = createElementWithStyle("{background-color: #000}"); | 319 { |
| 299 applyElemHideEmulation( | 320 let toHide = createElementWithStyle("{background-color: #000}"); |
| 300 [":-abp-properties(/background.\\7B0,6\\7D: rgb\\(0, 0, 0\\)/)"] | 321 let selectors = [":-abp-properties(/background.\\7B0,6\\7D: rgb\\(0, 0, 0\\)/)
"]; |
| 301 ).then(() => | 322 |
| 302 { | 323 if (await applyElemHideEmulation(test, selectors)) |
| 303 expectVisible(test, toHide); | 324 expectVisible(test, toHide); |
| 304 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 325 |
| 305 }; | 326 test.done(); |
| 306 | 327 }; |
| 307 exports.testDynamicallyChangedProperty = function(test) | 328 |
| 329 exports.testDynamicallyChangedProperty = async function(test) |
| 308 { | 330 { |
| 309 let toHide = createElementWithStyle("{}"); | 331 let toHide = createElementWithStyle("{}"); |
| 310 applyElemHideEmulation( | 332 let selectors = [":-abp-properties(background-color: rgb(0, 0, 0))"]; |
| 311 [":-abp-properties(background-color: rgb(0, 0, 0))"] | 333 |
| 312 ).then(() => | 334 if (await applyElemHideEmulation(test, selectors)) |
| 313 { | 335 { |
| 314 expectVisible(test, toHide); | 336 expectVisible(test, toHide); |
| 315 insertStyleRule("#" + toHide.id + " {background-color: #000}"); | 337 insertStyleRule("#" + toHide.id + " {background-color: #000}"); |
| 316 | 338 |
| 317 return timeout(0); | 339 await timeout(0); |
| 318 }).then(() => | 340 |
| 319 { | |
| 320 // Re-evaluation will only happen after a delay | 341 // Re-evaluation will only happen after a delay |
| 321 expectVisible(test, toHide); | 342 expectVisible(test, toHide); |
| 322 return timeout(REFRESH_INTERVAL); | 343 await timeout(REFRESH_INTERVAL); |
| 323 }).then(() => | 344 |
| 324 { | 345 expectHidden(test, toHide); |
| 325 expectHidden(test, toHide); | 346 } |
| 326 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 347 |
| 327 }; | 348 test.done(); |
| 328 | 349 }; |
| 329 exports.testPseudoClassWithPropBeforeSelector = function(test) | 350 |
| 351 exports.testPseudoClassWithPropBeforeSelector = async function(test) |
| 330 { | 352 { |
| 331 let parent = createElementWithStyle("{}"); | 353 let parent = createElementWithStyle("{}"); |
| 332 let child = createElementWithStyle("{background-color: #000}", parent); | 354 let child = createElementWithStyle("{background-color: #000}", parent); |
| 355 |
| 356 let selectors = ["div:-abp-properties(content: \"publicite\")"]; |
| 357 |
| 333 insertStyleRule(`#${child.id}::before {content: "publicite"}`); | 358 insertStyleRule(`#${child.id}::before {content: "publicite"}`); |
| 334 | 359 |
| 335 applyElemHideEmulation( | 360 if (await applyElemHideEmulation(test, selectors)) |
| 336 ["div:-abp-properties(content: \"publicite\")"] | |
| 337 ).then(() => | |
| 338 { | 361 { |
| 339 expectHidden(test, child); | 362 expectHidden(test, child); |
| 340 expectVisible(test, parent); | 363 expectVisible(test, parent); |
| 341 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 364 } |
| 342 }; | 365 |
| 343 | 366 test.done(); |
| 344 exports.testPseudoClassHasSelector = function(test) | 367 }; |
| 368 |
| 369 exports.testPseudoClassHasSelector = async function(test) |
| 345 { | 370 { |
| 346 let toHide = createElementWithStyle("{}"); | 371 let toHide = createElementWithStyle("{}"); |
| 347 applyElemHideEmulation( | 372 |
| 348 ["div:-abp-has(div)"] | 373 if (await applyElemHideEmulation(test, ["div:-abp-has(div)"])) |
| 349 ).then(() => | 374 expectVisible(test, toHide); |
| 350 { | 375 |
| 351 expectVisible(test, toHide); | 376 test.done(); |
| 352 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 377 }; |
| 353 }; | 378 |
| 354 | 379 exports.testPseudoClassHasSelectorWithPrefix = async function(test) |
| 355 exports.testPseudoClassHasSelectorWithPrefix = function(test) | |
| 356 { | 380 { |
| 357 let parent = createElementWithStyle("{}"); | 381 let parent = createElementWithStyle("{}"); |
| 358 let child = createElementWithStyle("{}", parent); | 382 let child = createElementWithStyle("{}", parent); |
| 359 applyElemHideEmulation( | 383 |
| 360 ["div:-abp-has(div)"] | 384 if (await applyElemHideEmulation(test, ["div:-abp-has(div)"])) |
| 361 ).then(() => | |
| 362 { | 385 { |
| 363 expectHidden(test, parent); | 386 expectHidden(test, parent); |
| 364 expectVisible(test, child); | 387 expectVisible(test, child); |
| 365 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 388 } |
| 366 }; | 389 |
| 367 | 390 test.done(); |
| 368 exports.testPseudoClassHasSelectorWithSuffix = function(test) | 391 }; |
| 392 |
| 393 exports.testPseudoClassHasSelectorWithSuffix = async function(test) |
| 369 { | 394 { |
| 370 let parent = createElementWithStyle("{}"); | 395 let parent = createElementWithStyle("{}"); |
| 371 let middle = createElementWithStyle("{}", parent); | 396 let middle = createElementWithStyle("{}", parent); |
| 372 let child = createElementWithStyle("{}", middle); | 397 let child = createElementWithStyle("{}", middle); |
| 373 applyElemHideEmulation( | 398 |
| 374 ["div:-abp-has(div) > div"] | 399 if (await applyElemHideEmulation(test, ["div:-abp-has(div) > div"])) |
| 375 ).then(() => | |
| 376 { | 400 { |
| 377 expectVisible(test, parent); | 401 expectVisible(test, parent); |
| 378 expectHidden(test, middle); | 402 expectHidden(test, middle); |
| 379 expectHidden(test, child); | 403 expectHidden(test, child); |
| 380 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 404 } |
| 381 }; | 405 |
| 382 | 406 test.done(); |
| 383 exports.testPseudoClassHasSelectorWithSuffixSibling = function(test) | 407 }; |
| 408 |
| 409 exports.testPseudoClassHasSelectorWithSuffixSibling = async function(test) |
| 384 { | 410 { |
| 385 let parent = createElementWithStyle("{}"); | 411 let parent = createElementWithStyle("{}"); |
| 386 let middle = createElementWithStyle("{}", parent); | 412 let middle = createElementWithStyle("{}", parent); |
| 387 let toHide = createElementWithStyle("{}"); | 413 let toHide = createElementWithStyle("{}"); |
| 388 applyElemHideEmulation( | 414 |
| 389 ["div:-abp-has(div) + div"] | 415 if (await applyElemHideEmulation(test, ["div:-abp-has(div) + div"])) |
| 390 ).then(() => | |
| 391 { | 416 { |
| 392 expectVisible(test, parent); | 417 expectVisible(test, parent); |
| 393 expectVisible(test, middle); | 418 expectVisible(test, middle); |
| 394 expectHidden(test, toHide); | 419 expectHidden(test, toHide); |
| 395 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 420 } |
| 396 }; | 421 |
| 397 | 422 test.done(); |
| 398 exports.testPseudoClassHasSelectorWithSuffixSiblingChild = function(test) | 423 }; |
| 424 |
| 425 exports.testPseudoClassHasSelectorWithSuffixSiblingChild = async function(test) |
| 399 { | 426 { |
| 400 // <div> | 427 // <div> |
| 401 // <div></div> | 428 // <div></div> |
| 402 // <div> | 429 // <div> |
| 403 // <div>to hide</div> | 430 // <div>to hide</div> |
| 404 // </div> | 431 // </div> |
| 405 // </div> | 432 // </div> |
| 406 let parent = createElementWithStyle("{}"); | 433 let parent = createElementWithStyle("{}"); |
| 407 let middle = createElementWithStyle("{}", parent); | 434 let middle = createElementWithStyle("{}", parent); |
| 408 let sibling = createElementWithStyle("{}"); | 435 let sibling = createElementWithStyle("{}"); |
| 409 let toHide = createElementWithStyle("{}", sibling); | 436 let toHide = createElementWithStyle("{}", sibling); |
| 410 applyElemHideEmulation( | 437 |
| 411 ["div:-abp-has(div) + div > div"] | 438 if (await applyElemHideEmulation(test, ["div:-abp-has(div) + div > div"])) |
| 412 ).then(() => | |
| 413 { | 439 { |
| 414 expectVisible(test, parent); | 440 expectVisible(test, parent); |
| 415 expectVisible(test, middle); | 441 expectVisible(test, middle); |
| 416 expectVisible(test, sibling); | 442 expectVisible(test, sibling); |
| 417 expectHidden(test, toHide); | 443 expectHidden(test, toHide); |
| 418 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 444 } |
| 445 |
| 446 test.done(); |
| 419 }; | 447 }; |
| 420 | 448 |
| 421 function compareExpectations(test, elems, expectations) | 449 function compareExpectations(test, elems, expectations) |
| 422 { | 450 { |
| 423 for (let elem in expectations) | 451 for (let elem in expectations) |
| 424 { | 452 { |
| 425 if (elems[elem]) | 453 if (elems[elem]) |
| 426 { | 454 { |
| 427 if (expectations[elem]) | 455 if (expectations[elem]) |
| 428 expectVisible(test, elems[elem], elem); | 456 expectVisible(test, elems[elem], elem); |
| 429 else | 457 else |
| 430 expectHidden(test, elems[elem], elem); | 458 expectHidden(test, elems[elem], elem); |
| 431 } | 459 } |
| 432 } | 460 } |
| 433 } | 461 } |
| 434 | 462 |
| 435 function runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, selector
, expectations) | 463 async function runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, se
lector, expectations) |
| 436 { | 464 { |
| 437 testDocument.body.innerHTML = `<div id="parent"> | 465 testDocument.body.innerHTML = `<div id="parent"> |
| 438 <div id="middle"> | 466 <div id="middle"> |
| 439 <div id="middle1"><div id="inside" class="inside"></div></div> | 467 <div id="middle1"><div id="inside" class="inside"></div></div> |
| 440 </div> | 468 </div> |
| 441 <div id="sibling"> | 469 <div id="sibling"> |
| 442 <div id="tohide"><span>to hide</span></div> | 470 <div id="tohide"><span>to hide</span></div> |
| 443 </div> | 471 </div> |
| 444 <div id="sibling2"> | 472 <div id="sibling2"> |
| 445 <div id="sibling21"><div id="sibling211" class="inside"></div></div> | 473 <div id="sibling21"><div id="sibling211" class="inside"></div></div> |
| 446 </div> | 474 </div> |
| 447 </div>`; | 475 </div>`; |
| 448 let elems = { | 476 let elems = { |
| 449 parent: testDocument.getElementById("parent"), | 477 parent: testDocument.getElementById("parent"), |
| 450 middle: testDocument.getElementById("middle"), | 478 middle: testDocument.getElementById("middle"), |
| 451 inside: testDocument.getElementById("inside"), | 479 inside: testDocument.getElementById("inside"), |
| 452 sibling: testDocument.getElementById("sibling"), | 480 sibling: testDocument.getElementById("sibling"), |
| 453 sibling2: testDocument.getElementById("sibling2"), | 481 sibling2: testDocument.getElementById("sibling2"), |
| 454 toHide: testDocument.getElementById("tohide") | 482 toHide: testDocument.getElementById("tohide") |
| 455 }; | 483 }; |
| 456 | 484 |
| 457 insertStyleRule(".inside {}"); | 485 insertStyleRule(".inside {}"); |
| 458 | 486 |
| 459 applyElemHideEmulation( | 487 if (await applyElemHideEmulation(test, [selector])) |
| 460 [selector] | |
| 461 ).then(() => | |
| 462 { | |
| 463 compareExpectations(test, elems, expectations); | 488 compareExpectations(test, elems, expectations); |
| 464 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 489 |
| 490 test.done(); |
| 465 } | 491 } |
| 466 | 492 |
| 467 exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling = function(test) | 493 exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling = async function(t
est) |
| 468 { | 494 { |
| 469 let expectations = { | 495 let expectations = { |
| 470 parent: true, | 496 parent: true, |
| 471 middile: true, | 497 middile: true, |
| 472 inside: true, | 498 inside: true, |
| 473 sibling: true, | 499 sibling: true, |
| 474 sibling2: true, | 500 sibling2: true, |
| 475 toHide: false | 501 toHide: false |
| 476 }; | 502 }; |
| 477 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling( | 503 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling( |
| 478 test, "div:-abp-has(:-abp-has(div.inside)) + div > div", expectations); | 504 test, "div:-abp-has(:-abp-has(div.inside)) + div > div", expectations); |
| 479 }; | 505 }; |
| 480 | 506 |
| 481 exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling2 = function(test) | 507 exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling2 = async function(
test) |
| 482 { | 508 { |
| 483 let expectations = { | 509 let expectations = { |
| 484 parent: true, | 510 parent: true, |
| 485 middile: true, | 511 middile: true, |
| 486 inside: true, | 512 inside: true, |
| 487 sibling: true, | 513 sibling: true, |
| 488 sibling2: true, | 514 sibling2: true, |
| 489 toHide: false | 515 toHide: false |
| 490 }; | 516 }; |
| 491 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling( | 517 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling( |
| 492 test, "div:-abp-has(:-abp-has(> div.inside)) + div > div", expectations); | 518 test, "div:-abp-has(:-abp-has(> div.inside)) + div > div", expectations); |
| 493 }; | 519 }; |
| 494 | 520 |
| 495 exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling3 = function(test) | 521 exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling3 = async function(
test) |
| 496 { | 522 { |
| 497 let expectations = { | 523 let expectations = { |
| 498 parent: true, | 524 parent: true, |
| 499 middile: true, | 525 middile: true, |
| 500 inside: true, | 526 inside: true, |
| 501 sibling: true, | 527 sibling: true, |
| 502 sibling2: true, | 528 sibling2: true, |
| 503 toHide: false | 529 toHide: false |
| 504 }; | 530 }; |
| 505 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling( | 531 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling( |
| 506 test, "div:-abp-has(> div:-abp-has(div.inside)) + div > div", expectations); | 532 test, "div:-abp-has(> div:-abp-has(div.inside)) + div > div", expectations); |
| 507 }; | 533 }; |
| 508 | 534 |
| 509 exports.testPseudoClassHasSelectorWithSuffixSiblingNoop = function(test) | 535 exports.testPseudoClassHasSelectorWithSuffixSiblingNoop = async function(test) |
| 510 { | 536 { |
| 511 let expectations = { | 537 let expectations = { |
| 512 parent: true, | 538 parent: true, |
| 513 middile: true, | 539 middile: true, |
| 514 inside: true, | 540 inside: true, |
| 515 sibling: true, | 541 sibling: true, |
| 516 sibling2: true, | 542 sibling2: true, |
| 517 toHide: true | 543 toHide: true |
| 518 }; | 544 }; |
| 519 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling( | 545 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling( |
| 520 test, "div:-abp-has(> body div.inside) + div > div", expectations); | 546 test, "div:-abp-has(> body div.inside) + div > div", expectations); |
| 521 }; | 547 }; |
| 522 | 548 |
| 523 exports.testPseudoClassHasSelectorWithSuffixSiblingContains = function(test) | 549 exports.testPseudoClassHasSelectorWithSuffixSiblingContains = async function(tes
t) |
| 524 { | 550 { |
| 525 let expectations = { | 551 let expectations = { |
| 526 parent: true, | 552 parent: true, |
| 527 middile: true, | 553 middile: true, |
| 528 inside: true, | 554 inside: true, |
| 529 sibling: true, | 555 sibling: true, |
| 530 sibling2: true, | 556 sibling2: true, |
| 531 toHide: true | 557 toHide: true |
| 532 }; | 558 }; |
| 533 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling( | 559 runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling( |
| 534 test, "div:-abp-has(> span:-abp-contains(Advertisment))", expectations); | 560 test, "div:-abp-has(> span:-abp-contains(Advertisment))", expectations); |
| 535 }; | 561 }; |
| 536 | 562 |
| 537 function runTestPseudoClassContains(test, selector, expectations) | 563 async function runTestPseudoClassContains(test, selector, expectations) |
| 538 { | 564 { |
| 539 testDocument.body.innerHTML = `<div id="parent"> | 565 testDocument.body.innerHTML = `<div id="parent"> |
| 540 <div id="middle"> | 566 <div id="middle"> |
| 541 <div id="middle1"><div id="inside" class="inside"></div></div> | 567 <div id="middle1"><div id="inside" class="inside"></div></div> |
| 542 </div> | 568 </div> |
| 543 <div id="sibling"> | 569 <div id="sibling"> |
| 544 <div id="tohide">to hide \ud83d\ude42!</div> | 570 <div id="tohide">to hide \ud83d\ude42!</div> |
| 545 </div> | 571 </div> |
| 546 <div id="sibling2"> | 572 <div id="sibling2"> |
| 547 <div id="sibling21"><div id="sibling211" class="inside">Ad*</div></div> | 573 <div id="sibling21"><div id="sibling211" class="inside">Ad*</div></div> |
| 548 </div> | 574 </div> |
| 549 </div>`; | 575 </div>`; |
| 550 let elems = { | 576 let elems = { |
| 551 parent: testDocument.getElementById("parent"), | 577 parent: testDocument.getElementById("parent"), |
| 552 middle: testDocument.getElementById("middle"), | 578 middle: testDocument.getElementById("middle"), |
| 553 inside: testDocument.getElementById("inside"), | 579 inside: testDocument.getElementById("inside"), |
| 554 sibling: testDocument.getElementById("sibling"), | 580 sibling: testDocument.getElementById("sibling"), |
| 555 sibling2: testDocument.getElementById("sibling2"), | 581 sibling2: testDocument.getElementById("sibling2"), |
| 556 toHide: testDocument.getElementById("tohide") | 582 toHide: testDocument.getElementById("tohide") |
| 557 }; | 583 }; |
| 558 | 584 |
| 559 applyElemHideEmulation( | 585 if (await applyElemHideEmulation(test, [selector])) |
| 560 [selector] | 586 compareExpectations(test, elems, expectations); |
| 561 ).then( | 587 |
| 562 () => compareExpectations(test, elems, expectations) | 588 test.done(); |
| 563 ).catch(unexpectedError.bind(test)).then(() => test.done()); | |
| 564 } | 589 } |
| 565 | 590 |
| 566 exports.testPseudoClassContainsText = function(test) | 591 exports.testPseudoClassContainsText = async function(test) |
| 567 { | 592 { |
| 568 let expectations = { | 593 let expectations = { |
| 569 parent: true, | 594 parent: true, |
| 570 middle: true, | 595 middle: true, |
| 571 inside: true, | 596 inside: true, |
| 572 sibling: false, | 597 sibling: false, |
| 573 sibling2: true, | 598 sibling2: true, |
| 574 toHide: true | 599 toHide: true |
| 575 }; | 600 }; |
| 576 runTestPseudoClassContains( | 601 runTestPseudoClassContains( |
| 577 test, "#parent div:-abp-contains(to hide)", expectations); | 602 test, "#parent div:-abp-contains(to hide)", expectations); |
| 578 }; | 603 }; |
| 579 | 604 |
| 580 exports.testPseudoClassContainsRegexp = function(test) | 605 exports.testPseudoClassContainsRegexp = async function(test) |
| 581 { | 606 { |
| 582 let expectations = { | 607 let expectations = { |
| 583 parent: true, | 608 parent: true, |
| 584 middle: true, | 609 middle: true, |
| 585 inside: true, | 610 inside: true, |
| 586 sibling: false, | 611 sibling: false, |
| 587 sibling2: true, | 612 sibling2: true, |
| 588 toHide: true | 613 toHide: true |
| 589 }; | 614 }; |
| 590 runTestPseudoClassContains( | 615 runTestPseudoClassContains( |
| 591 test, "#parent div:-abp-contains(/to\\shide/)", expectations); | 616 test, "#parent div:-abp-contains(/to\\shide/)", expectations); |
| 592 }; | 617 }; |
| 593 | 618 |
| 594 exports.testPseudoClassContainsRegexpIFlag = function(test) | 619 exports.testPseudoClassContainsRegexpIFlag = async function(test) |
| 595 { | 620 { |
| 596 let expectations = { | 621 let expectations = { |
| 597 parent: true, | 622 parent: true, |
| 598 middle: true, | 623 middle: true, |
| 599 inside: true, | 624 inside: true, |
| 600 sibling: false, | 625 sibling: false, |
| 601 sibling2: true, | 626 sibling2: true, |
| 602 toHide: true | 627 toHide: true |
| 603 }; | 628 }; |
| 604 runTestPseudoClassContains( | 629 runTestPseudoClassContains( |
| 605 test, "#parent div:-abp-contains(/to\\sHide/i)", expectations); | 630 test, "#parent div:-abp-contains(/to\\sHide/i)", expectations); |
| 606 }; | 631 }; |
| 607 | 632 |
| 608 exports.testPseudoClassContainsRegexpUFlag = function(test) | 633 exports.testPseudoClassContainsRegexpUFlag = async function(test) |
| 609 { | 634 { |
| 610 let expectations = { | 635 let expectations = { |
| 611 parent: true, | 636 parent: true, |
| 612 middle: true, | 637 middle: true, |
| 613 inside: true, | 638 inside: true, |
| 614 sibling: false, | 639 sibling: false, |
| 615 sibling2: true, | 640 sibling2: true, |
| 616 toHide: true | 641 toHide: true |
| 617 }; | 642 }; |
| 618 runTestPseudoClassContains( | 643 runTestPseudoClassContains( |
| 619 test, "#parent div:-abp-contains(/to\\shide\\s.!/u)", expectations); | 644 test, "#parent div:-abp-contains(/to\\shide\\s.!/u)", expectations); |
| 620 }; | 645 }; |
| 621 | 646 |
| 622 exports.testPseudoClassContainsWildcardNoMatch = function(test) | 647 exports.testPseudoClassContainsWildcardNoMatch = async function(test) |
| 623 { | 648 { |
| 624 let expectations = { | 649 let expectations = { |
| 625 parent: true, | 650 parent: true, |
| 626 middle: true, | 651 middle: true, |
| 627 inside: true, | 652 inside: true, |
| 628 sibling: true, | 653 sibling: true, |
| 629 sibling2: true, | 654 sibling2: true, |
| 630 toHide: true | 655 toHide: true |
| 631 }; | 656 }; |
| 632 // this filter shouldn't match anything as "*" has no meaning. | 657 // this filter shouldn't match anything as "*" has no meaning. |
| 633 runTestPseudoClassContains( | 658 runTestPseudoClassContains( |
| 634 test, "#parent div:-abp-contains(to *hide)", expectations); | 659 test, "#parent div:-abp-contains(to *hide)", expectations); |
| 635 }; | 660 }; |
| 636 | 661 |
| 637 exports.testPseudoClassContainsWildcardMatch = function(test) | 662 exports.testPseudoClassContainsWildcardMatch = async function(test) |
| 638 { | 663 { |
| 639 let expectations = { | 664 let expectations = { |
| 640 parent: true, | 665 parent: true, |
| 641 middle: true, | 666 middle: true, |
| 642 inside: true, | 667 inside: true, |
| 643 sibling: true, | 668 sibling: true, |
| 644 sibling2: false, | 669 sibling2: false, |
| 645 toHide: true | 670 toHide: true |
| 646 }; | 671 }; |
| 647 runTestPseudoClassContains( | 672 runTestPseudoClassContains( |
| 648 test, "#parent div:-abp-contains(Ad*)", expectations); | 673 test, "#parent div:-abp-contains(Ad*)", expectations); |
| 649 }; | 674 }; |
| 650 | 675 |
| 651 exports.testPseudoClassHasSelectorWithPropSelector = function(test) | 676 exports.testPseudoClassHasSelectorWithPropSelector = async function(test) |
| 652 { | 677 { |
| 653 let parent = createElementWithStyle("{}"); | 678 let parent = createElementWithStyle("{}"); |
| 654 let child = createElementWithStyle("{background-color: #000}", parent); | 679 let child = createElementWithStyle("{background-color: #000}", parent); |
| 655 applyElemHideEmulation( | 680 |
| 656 ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"] | 681 let selectors = ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)
))"]; |
| 657 ).then(() => | 682 |
| 658 { | 683 if (await applyElemHideEmulation(test, selectors)) |
| 659 expectVisible(test, child); | 684 { |
| 660 expectHidden(test, parent); | 685 expectVisible(test, child); |
| 661 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 686 expectHidden(test, parent); |
| 662 }; | 687 } |
| 663 | 688 |
| 664 exports.testPseudoClassHasSelectorWithPropSelector2 = function(test) | 689 test.done(); |
| 690 }; |
| 691 |
| 692 exports.testPseudoClassHasSelectorWithPropSelector2 = async function(test) |
| 665 { | 693 { |
| 666 let parent = createElementWithStyle("{}"); | 694 let parent = createElementWithStyle("{}"); |
| 667 let child = createElementWithStyle("{}", parent); | 695 let child = createElementWithStyle("{}", parent); |
| 696 |
| 697 let selectors = ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)
))"]; |
| 698 |
| 668 insertStyleRule("body #" + parent.id + " > div { background-color: #000}"); | 699 insertStyleRule("body #" + parent.id + " > div { background-color: #000}"); |
| 669 applyElemHideEmulation( | 700 |
| 670 ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"] | 701 if (await applyElemHideEmulation(test, selectors)) |
| 671 ).then(() => | 702 { |
| 672 { | 703 expectVisible(test, child); |
| 673 expectVisible(test, child); | 704 expectHidden(test, parent); |
| 674 expectHidden(test, parent); | 705 } |
| 675 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 706 |
| 676 }; | 707 test.done(); |
| 677 | 708 }; |
| 678 exports.testDomUpdatesStyle = function(test) | 709 |
| 710 exports.testDomUpdatesStyle = async function(test) |
| 679 { | 711 { |
| 680 let parent = createElementWithStyle("{}"); | 712 let parent = createElementWithStyle("{}"); |
| 681 let child = createElementWithStyle("{}", parent); | 713 let child = createElementWithStyle("{}", parent); |
| 682 applyElemHideEmulation( | 714 |
| 683 ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"] | 715 let selectors = ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)
))"]; |
| 684 ).then(() => | 716 |
| 717 if (await applyElemHideEmulation(test, selectors)) |
| 685 { | 718 { |
| 686 expectVisible(test, child); | 719 expectVisible(test, child); |
| 687 expectVisible(test, parent); | 720 expectVisible(test, parent); |
| 688 | 721 |
| 689 insertStyleRule("body #" + parent.id + " > div { background-color: #000}"); | 722 insertStyleRule("body #" + parent.id + " > div { background-color: #000}"); |
| 690 return timeout(0); | 723 await timeout(0); |
| 691 }).then(() => | 724 |
| 692 { | 725 expectVisible(test, child); |
| 693 expectVisible(test, child); | 726 expectVisible(test, parent); |
| 694 expectVisible(test, parent); | 727 await timeout(REFRESH_INTERVAL); |
| 695 return timeout(REFRESH_INTERVAL); | 728 |
| 696 }).then(() => | 729 expectVisible(test, child); |
| 697 { | 730 expectHidden(test, parent); |
| 698 expectVisible(test, child); | 731 } |
| 699 expectHidden(test, parent); | 732 |
| 700 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 733 test.done(); |
| 701 }; | 734 }; |
| 702 | 735 |
| 703 exports.testDomUpdatesContent = function(test) | 736 exports.testDomUpdatesContent = async function(test) |
| 704 { | 737 { |
| 705 let parent = createElementWithStyle("{}"); | 738 let parent = createElementWithStyle("{}"); |
| 706 let child = createElementWithStyle("{}", parent); | 739 let child = createElementWithStyle("{}", parent); |
| 707 applyElemHideEmulation( | 740 |
| 708 ["div > div:-abp-contains(hide me)"] | 741 if (await applyElemHideEmulation(test, ["div > div:-abp-contains(hide me)"])) |
| 709 ).then(() => | |
| 710 { | 742 { |
| 711 expectVisible(test, parent); | 743 expectVisible(test, parent); |
| 712 expectVisible(test, child); | 744 expectVisible(test, child); |
| 713 | 745 |
| 714 child.textContent = "hide me"; | 746 child.textContent = "hide me"; |
| 715 return timeout(0); | 747 await timeout(0); |
| 716 }).then(() => | 748 |
| 717 { | 749 expectVisible(test, parent); |
| 718 expectVisible(test, parent); | 750 expectVisible(test, child); |
| 719 expectVisible(test, child); | 751 await timeout(REFRESH_INTERVAL); |
| 720 return timeout(REFRESH_INTERVAL); | 752 |
| 721 }).then(() => | |
| 722 { | |
| 723 expectVisible(test, parent); | 753 expectVisible(test, parent); |
| 724 expectHidden(test, child); | 754 expectHidden(test, child); |
| 725 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 755 } |
| 726 }; | 756 |
| 727 | 757 test.done(); |
| 728 exports.testDomUpdatesNewElement = function(test) | 758 }; |
| 759 |
| 760 exports.testDomUpdatesNewElement = async function(test) |
| 729 { | 761 { |
| 730 let parent = createElementWithStyle("{}"); | 762 let parent = createElementWithStyle("{}"); |
| 731 let child = createElementWithStyle("{ background-color: #000}", parent); | 763 let child = createElementWithStyle("{ background-color: #000}", parent); |
| 732 let sibling; | 764 let sibling; |
| 733 let child2; | 765 let child2; |
| 734 applyElemHideEmulation( | 766 |
| 735 ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)))"] | 767 let selectors = ["div:-abp-has(:-abp-properties(background-color: rgb(0, 0, 0)
))"]; |
| 736 ).then(() => | 768 |
| 769 if (await applyElemHideEmulation(test, selectors)) |
| 737 { | 770 { |
| 738 expectHidden(test, parent); | 771 expectHidden(test, parent); |
| 739 expectVisible(test, child); | 772 expectVisible(test, child); |
| 740 | 773 |
| 741 sibling = createElementWithStyle("{}"); | 774 sibling = createElementWithStyle("{}"); |
| 742 return timeout(0); | 775 await timeout(0); |
| 743 }).then(() => | 776 |
| 744 { | |
| 745 expectHidden(test, parent); | 777 expectHidden(test, parent); |
| 746 expectVisible(test, child); | 778 expectVisible(test, child); |
| 747 expectVisible(test, sibling); | 779 expectVisible(test, sibling); |
| 748 | 780 |
| 749 return timeout(REFRESH_INTERVAL); | 781 await timeout(REFRESH_INTERVAL); |
| 750 }).then(() => | 782 |
| 751 { | |
| 752 expectHidden(test, parent); | 783 expectHidden(test, parent); |
| 753 expectVisible(test, child); | 784 expectVisible(test, child); |
| 754 expectVisible(test, sibling); | 785 expectVisible(test, sibling); |
| 755 | 786 |
| 756 child2 = createElementWithStyle("{ background-color: #000}", | 787 child2 = createElementWithStyle("{ background-color: #000}", |
| 757 sibling); | 788 sibling); |
| 758 return timeout(0); | 789 await timeout(0); |
| 759 }).then(() => | 790 |
| 760 { | |
| 761 expectVisible(test, child2); | 791 expectVisible(test, child2); |
| 762 return timeout(REFRESH_INTERVAL); | 792 await timeout(REFRESH_INTERVAL); |
| 763 }).then(() => | 793 |
| 764 { | |
| 765 expectHidden(test, parent); | 794 expectHidden(test, parent); |
| 766 expectVisible(test, child); | 795 expectVisible(test, child); |
| 767 expectHidden(test, sibling); | 796 expectHidden(test, sibling); |
| 768 expectVisible(test, child2); | 797 expectVisible(test, child2); |
| 769 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 798 } |
| 770 }; | 799 |
| 771 | 800 test.done(); |
| 772 exports.testPseudoClassPropertiesOnStyleSheetLoad = function(test) | 801 }; |
| 802 |
| 803 exports.testPseudoClassPropertiesOnStyleSheetLoad = async function(test) |
| 773 { | 804 { |
| 774 let parent = createElement(); | 805 let parent = createElement(); |
| 775 let child = createElement(parent); | 806 let child = createElement(parent); |
| 776 applyElemHideEmulation( | 807 |
| 777 ["div:-abp-properties(background-color: rgb(0, 0, 0))", | 808 let selectors = [ |
| 778 "div:-abp-contains(hide me)", | 809 "div:-abp-properties(background-color: rgb(0, 0, 0))", |
| 779 "div:-abp-has(> div.hideMe)"] | 810 "div:-abp-contains(hide me)", |
| 780 ).then(() => timeout(REFRESH_INTERVAL) | 811 "div:-abp-has(> div.hideMe)" |
| 781 ).then(() => | 812 ]; |
| 782 { | 813 |
| 814 if (await applyElemHideEmulation(test, selectors)) |
| 815 { |
| 816 await timeout(REFRESH_INTERVAL); |
| 817 |
| 783 expectVisible(test, parent); | 818 expectVisible(test, parent); |
| 784 expectVisible(test, child); | 819 expectVisible(test, child); |
| 785 | 820 |
| 786 // Load a style sheet that targets the parent element. This should run only | 821 // Load a style sheet that targets the parent element. This should run only |
| 787 // the "div:-abp-properties(background-color: rgb(0, 0, 0))" pattern. | 822 // the "div:-abp-properties(background-color: rgb(0, 0, 0))" pattern. |
| 788 insertStyleRule("#" + parent.id + " {background-color: #000}"); | 823 insertStyleRule("#" + parent.id + " {background-color: #000}"); |
| 789 | 824 |
| 790 return timeout(REFRESH_INTERVAL); | 825 await timeout(REFRESH_INTERVAL); |
| 791 }).then(() => | 826 |
| 792 { | 827 expectHidden(test, parent); |
| 793 expectHidden(test, parent); | 828 expectVisible(test, child); |
| 794 expectVisible(test, child); | 829 } |
| 795 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 830 |
| 796 }; | 831 test.done(); |
| 797 | 832 }; |
| 798 exports.testPlainAttributeOnDomMutation = function(test) | 833 |
| 834 exports.testPlainAttributeOnDomMutation = async function(test) |
| 799 { | 835 { |
| 800 let parent = createElement(); | 836 let parent = createElement(); |
| 801 let child = createElement(parent); | 837 let child = createElement(parent); |
| 802 applyElemHideEmulation( | 838 |
| 803 ["div:-abp-properties(background-color: rgb(0, 0, 0))", | 839 let selectors = [ |
| 804 "div[data-hide-me]", | 840 "div:-abp-properties(background-color: rgb(0, 0, 0))", |
| 805 "div:-abp-contains(hide me)", | 841 "div[data-hide-me]", |
| 806 "div:-abp-has(> div.hideMe)"] | 842 "div:-abp-contains(hide me)", |
| 807 ).then(() => timeout(REFRESH_INTERVAL) | 843 "div:-abp-has(> div.hideMe)" |
| 808 ).then(() => | 844 ]; |
| 809 { | 845 |
| 846 if (await applyElemHideEmulation(test, selectors)) |
| 847 { |
| 848 await timeout(REFRESH_INTERVAL); |
| 849 |
| 810 expectVisible(test, parent); | 850 expectVisible(test, parent); |
| 811 expectVisible(test, child); | 851 expectVisible(test, child); |
| 812 | 852 |
| 813 // Set the "data-hide-me" attribute on the child element. | 853 // Set the "data-hide-me" attribute on the child element. |
| 814 // | 854 // |
| 815 // Note: Since the "div[data-hide-me]" pattern has already been processed | 855 // Note: Since the "div[data-hide-me]" pattern has already been processed |
| 816 // and the selector added to the document's style sheet, this will in fact | 856 // and the selector added to the document's style sheet, this will in fact |
| 817 // not do anything at our end, but the browser will just match the selector | 857 // not do anything at our end, but the browser will just match the selector |
| 818 // and hide the element. | 858 // and hide the element. |
| 819 child.setAttribute("data-hide-me", ""); | 859 child.setAttribute("data-hide-me", ""); |
| 820 | 860 |
| 821 return timeout(REFRESH_INTERVAL); | 861 await timeout(REFRESH_INTERVAL); |
| 822 }).then(() => | 862 |
| 823 { | |
| 824 expectVisible(test, parent); | 863 expectVisible(test, parent); |
| 825 expectHidden(test, child); | 864 expectHidden(test, child); |
| 826 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 865 } |
| 827 }; | 866 |
| 828 | 867 test.done(); |
| 829 exports.testPseudoClassContainsOnDomMutation = function(test) | 868 }; |
| 869 |
| 870 exports.testPseudoClassContainsOnDomMutation = async function(test) |
| 830 { | 871 { |
| 831 let parent = createElement(); | 872 let parent = createElement(); |
| 832 let child = createElement(parent); | 873 let child = createElement(parent); |
| 833 | 874 |
| 875 let selectors = [ |
| 876 "div:-abp-properties(background-color: rgb(0, 0, 0))", |
| 877 "div[data-hide-me]", |
| 878 "div:-abp-contains(hide me)", |
| 879 "div:-abp-has(> div.hideMe)" |
| 880 ]; |
| 881 |
| 834 child.innerText = "do nothing"; | 882 child.innerText = "do nothing"; |
| 835 | 883 |
| 836 applyElemHideEmulation( | 884 if (await applyElemHideEmulation(test, selectors)) |
| 837 ["div:-abp-properties(background-color: rgb(0, 0, 0))", | 885 { |
| 838 "div[data-hide-me]", | 886 await timeout(REFRESH_INTERVAL); |
| 839 "div:-abp-contains(hide me)", | 887 |
| 840 "div:-abp-has(> div.hideMe)"] | |
| 841 ).then(() => timeout(REFRESH_INTERVAL) | |
| 842 ).then(() => | |
| 843 { | |
| 844 expectVisible(test, parent); | 888 expectVisible(test, parent); |
| 845 expectVisible(test, child); | 889 expectVisible(test, child); |
| 846 | 890 |
| 847 // Set the child element's text to "hide me". This should run only the | 891 // Set the child element's text to "hide me". This should run only the |
| 848 // "div:-abp-contains(hide me)" pattern. | 892 // "div:-abp-contains(hide me)" pattern. |
| 849 // | 893 // |
| 850 // Note: We need to set Node.innerText here in order to trigger the | 894 // Note: We need to set Node.innerText here in order to trigger the |
| 851 // "characterData" DOM mutation on Chromium. If we set Node.textContent | 895 // "characterData" DOM mutation on Chromium. If we set Node.textContent |
| 852 // instead, it triggers the "childList" DOM mutation instead. | 896 // instead, it triggers the "childList" DOM mutation instead. |
| 853 child.innerText = "hide me"; | 897 child.innerText = "hide me"; |
| 854 | 898 |
| 855 return timeout(REFRESH_INTERVAL); | 899 await timeout(REFRESH_INTERVAL); |
| 856 }).then(() => | 900 |
| 857 { | 901 expectHidden(test, parent); |
| 858 expectHidden(test, parent); | 902 expectVisible(test, child); |
| 859 expectVisible(test, child); | 903 } |
| 860 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 904 |
| 861 }; | 905 test.done(); |
| 862 | 906 }; |
| 863 exports.testPseudoClassHasOnDomMutation = function(test) | 907 |
| 908 exports.testPseudoClassHasOnDomMutation = async function(test) |
| 864 { | 909 { |
| 865 let parent = createElement(); | 910 let parent = createElement(); |
| 866 let child = null; | 911 let child = null; |
| 867 applyElemHideEmulation( | 912 |
| 868 ["div:-abp-properties(background-color: rgb(0, 0, 0))", | 913 let selectors = [ |
| 869 "div[data-hide-me]", | 914 "div:-abp-properties(background-color: rgb(0, 0, 0))", |
| 870 "div:-abp-contains(hide me)", | 915 "div[data-hide-me]", |
| 871 "div:-abp-has(> div)"] | 916 "div:-abp-contains(hide me)", |
| 872 ).then(() => timeout(REFRESH_INTERVAL) | 917 "div:-abp-has(> div)" |
| 873 ).then(() => | 918 ]; |
| 874 { | 919 |
| 920 if (await applyElemHideEmulation(test, selectors)) |
| 921 { |
| 922 await timeout(REFRESH_INTERVAL); |
| 923 |
| 875 expectVisible(test, parent); | 924 expectVisible(test, parent); |
| 876 | 925 |
| 877 // Add the child element. This should run all the DOM-dependent patterns | 926 // Add the child element. This should run all the DOM-dependent patterns |
| 878 // ("div:-abp-contains(hide me)" and "div:-abp-has(> div)"). | 927 // ("div:-abp-contains(hide me)" and "div:-abp-has(> div)"). |
| 879 child = createElement(parent); | 928 child = createElement(parent); |
| 880 | 929 |
| 881 return timeout(REFRESH_INTERVAL); | 930 await timeout(REFRESH_INTERVAL); |
| 882 }).then(() => | 931 |
| 883 { | 932 expectHidden(test, parent); |
| 884 expectHidden(test, parent); | 933 expectVisible(test, child); |
| 885 expectVisible(test, child); | 934 } |
| 886 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 935 |
| 887 }; | 936 test.done(); |
| 888 | 937 }; |
| 889 exports.testPseudoClassHasWithClassOnDomMutation = function(test) | 938 |
| 939 exports.testPseudoClassHasWithClassOnDomMutation = async function(test) |
| 890 { | 940 { |
| 891 let parent = createElement(); | 941 let parent = createElement(); |
| 892 let child = createElement(parent); | 942 let child = createElement(parent); |
| 893 applyElemHideEmulation( | 943 |
| 894 ["div:-abp-properties(background-color: rgb(0, 0, 0))", | 944 let selectors = [ |
| 895 "div[data-hide-me]", | 945 "div:-abp-properties(background-color: rgb(0, 0, 0))", |
| 896 "div:-abp-contains(hide me)", | 946 "div[data-hide-me]", |
| 897 "div:-abp-has(> div.hideMe)"] | 947 "div:-abp-contains(hide me)", |
| 898 ).then(() => timeout(REFRESH_INTERVAL) | 948 "div:-abp-has(> div.hideMe)" |
| 899 ).then(() => | 949 ]; |
| 900 { | 950 |
| 951 if (await applyElemHideEmulation(test, selectors)) |
| 952 { |
| 953 await timeout(REFRESH_INTERVAL); |
| 954 |
| 901 expectVisible(test, parent); | 955 expectVisible(test, parent); |
| 902 expectVisible(test, child); | 956 expectVisible(test, child); |
| 903 | 957 |
| 904 // Set the child element's class to "hideMe". This should run only the | 958 // Set the child element's class to "hideMe". This should run only the |
| 905 // "div:-abp-has(> div.hideMe)" pattern. | 959 // "div:-abp-has(> div.hideMe)" pattern. |
| 906 child.className = "hideMe"; | 960 child.className = "hideMe"; |
| 907 | 961 |
| 908 return timeout(REFRESH_INTERVAL); | 962 await timeout(REFRESH_INTERVAL); |
| 909 }).then(() => | 963 |
| 910 { | 964 expectHidden(test, parent); |
| 911 expectHidden(test, parent); | 965 expectVisible(test, child); |
| 912 expectVisible(test, child); | 966 } |
| 913 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 967 |
| 914 }; | 968 test.done(); |
| 915 | 969 }; |
| 916 exports.testPseudoClassHasWithPseudoClassContainsOnDomMutation = function(test) | 970 |
| 971 exports.testPseudoClassHasWithPseudoClassContainsOnDomMutation = async function(
test) |
| 917 { | 972 { |
| 918 let parent = createElement(); | 973 let parent = createElement(); |
| 919 let child = createElement(parent); | 974 let child = createElement(parent); |
| 920 | 975 |
| 976 let selectors = [ |
| 977 "div:-abp-properties(background-color: rgb(0, 0, 0))", |
| 978 "div[data-hide-me]", |
| 979 "div:-abp-contains(hide me)", |
| 980 "div:-abp-has(> div:-abp-contains(hide me))" |
| 981 ]; |
| 982 |
| 921 child.innerText = "do nothing"; | 983 child.innerText = "do nothing"; |
| 922 | 984 |
| 923 applyElemHideEmulation( | 985 if (await applyElemHideEmulation(test, selectors)) |
| 924 ["div:-abp-properties(background-color: rgb(0, 0, 0))", | 986 { |
| 925 "div[data-hide-me]", | 987 await timeout(REFRESH_INTERVAL); |
| 926 "div:-abp-contains(hide me)", | 988 |
| 927 "div:-abp-has(> div:-abp-contains(hide me))"] | |
| 928 ).then(() => timeout(REFRESH_INTERVAL) | |
| 929 ).then(() => | |
| 930 { | |
| 931 expectVisible(test, parent); | 989 expectVisible(test, parent); |
| 932 expectVisible(test, child); | 990 expectVisible(test, child); |
| 933 | 991 |
| 934 // Set the child element's text to "hide me". This should run only the | 992 // Set the child element's text to "hide me". This should run only the |
| 935 // "div:-abp-contains(hide me)" and | 993 // "div:-abp-contains(hide me)" and |
| 936 // "div:-abp-has(> div:-abp-contains(hide me))" patterns. | 994 // "div:-abp-has(> div:-abp-contains(hide me))" patterns. |
| 937 child.innerText = "hide me"; | 995 child.innerText = "hide me"; |
| 938 | 996 |
| 939 return timeout(REFRESH_INTERVAL); | 997 await timeout(REFRESH_INTERVAL); |
| 940 }).then(() => | 998 |
| 941 { | |
| 942 // Note: Even though it runs both the :-abp-contains() patterns, it only | 999 // Note: Even though it runs both the :-abp-contains() patterns, it only |
| 943 // hides the parent element because of revision d7d51d29aa34. | 1000 // hides the parent element because of revision d7d51d29aa34. |
| 944 expectHidden(test, parent); | 1001 expectHidden(test, parent); |
| 945 expectVisible(test, child); | 1002 expectVisible(test, child); |
| 946 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 1003 } |
| 947 }; | 1004 |
| 948 | 1005 test.done(); |
| 949 exports.testOnlyRelevantElementsProcessed = function(test) | 1006 }; |
| 1007 |
| 1008 exports.testOnlyRelevantElementsProcessed = async function(test) |
| 950 { | 1009 { |
| 951 // <body> | 1010 // <body> |
| 952 // <div id="n1"> | 1011 // <div id="n1"> |
| 953 // <p id="n1_1"></p> | 1012 // <p id="n1_1"></p> |
| 954 // <p id="n1_2"></p> | 1013 // <p id="n1_2"></p> |
| 955 // <p id="n1_4">Hello</p> | 1014 // <p id="n1_4">Hello</p> |
| 956 // </div> | 1015 // </div> |
| 957 // <div id="n2"> | 1016 // <div id="n2"> |
| 958 // <p id="n2_1"></p> | 1017 // <p id="n2_1"></p> |
| 959 // <p id="n2_2"></p> | 1018 // <p id="n2_2"></p> |
| (...skipping 10 matching lines...) Expand all Loading... |
| 970 // <p id="n4_4">Hello</p> | 1029 // <p id="n4_4">Hello</p> |
| 971 // </div> | 1030 // </div> |
| 972 // </body> | 1031 // </body> |
| 973 for (let i of [1, 2, 3, 4]) | 1032 for (let i of [1, 2, 3, 4]) |
| 974 { | 1033 { |
| 975 let n = createElement(null, "div", `n${i}`); | 1034 let n = createElement(null, "div", `n${i}`); |
| 976 for (let [j, text] of [[1], [2], [4, "Hello"]]) | 1035 for (let [j, text] of [[1], [2], [4, "Hello"]]) |
| 977 createElement(n, "p", `n${i}_${j}`, text); | 1036 createElement(n, "p", `n${i}_${j}`, text); |
| 978 } | 1037 } |
| 979 | 1038 |
| 980 applyElemHideEmulation( | 1039 let selectors = [ |
| 981 ["p:-abp-contains(Hello)", | 1040 "p:-abp-contains(Hello)", |
| 982 "div:-abp-contains(Try me!)", | 1041 "div:-abp-contains(Try me!)", |
| 983 "div:-abp-has(p:-abp-contains(This is good))"] | 1042 "div:-abp-has(p:-abp-contains(This is good))" |
| 984 ).then(() => timeout(REFRESH_INTERVAL) | 1043 ]; |
| 985 ).then(() => | 1044 |
| 1045 if (await applyElemHideEmulation(test, selectors)) |
| 986 { | 1046 { |
| 1047 await timeout(REFRESH_INTERVAL); |
| 1048 |
| 987 // This is only a sanity check to make sure everything else is working | 1049 // This is only a sanity check to make sure everything else is working |
| 988 // before we do the actual test. | 1050 // before we do the actual test. |
| 989 for (let i of [1, 2, 3, 4]) | 1051 for (let i of [1, 2, 3, 4]) |
| 990 { | 1052 { |
| 991 for (let j of [1, 2, 4]) | 1053 for (let j of [1, 2, 4]) |
| 992 { | 1054 { |
| 993 let id = `n${i}_${j}`; | 1055 let id = `n${i}_${j}`; |
| 994 if (j == 4) | 1056 if (j == 4) |
| 995 expectHidden(test, testDocument.getElementById(id), id); | 1057 expectHidden(test, testDocument.getElementById(id), id); |
| 996 else | 1058 else |
| 997 expectVisible(test, testDocument.getElementById(id), id); | 1059 expectVisible(test, testDocument.getElementById(id), id); |
| 998 } | 1060 } |
| 999 } | 1061 } |
| 1000 | 1062 |
| 1001 // All <div> and <p> elements should be processed initially. | 1063 // All <div> and <p> elements should be processed initially. |
| 1002 for (let element of [...testDocument.getElementsByTagName("div"), | 1064 for (let element of [...testDocument.getElementsByTagName("div"), |
| 1003 ...testDocument.getElementsByTagName("p")]) | 1065 ...testDocument.getElementsByTagName("p")]) |
| 1004 { | 1066 { |
| 1005 expectProcessed(test, element, element.id); | 1067 expectProcessed(test, element, element.id); |
| 1006 } | 1068 } |
| 1007 | 1069 |
| 1008 // Modify the text in <p id="n4_1"> | 1070 // Modify the text in <p id="n4_1"> |
| 1009 testDocument.getElementById("n4_1").innerText = "Try me!"; | 1071 testDocument.getElementById("n4_1").innerText = "Try me!"; |
| 1010 | 1072 |
| 1011 return timeout(REFRESH_INTERVAL); | 1073 await timeout(REFRESH_INTERVAL); |
| 1012 }).then(() => | 1074 |
| 1013 { | |
| 1014 // When an element's text is modified, only the element or one of its | 1075 // When an element's text is modified, only the element or one of its |
| 1015 // ancestors matching any selector is processed for :-abp-has() and | 1076 // ancestors matching any selector is processed for :-abp-has() and |
| 1016 // :-abp-contains() | 1077 // :-abp-contains() |
| 1017 for (let element of [...testDocument.getElementsByTagName("div"), | 1078 for (let element of [...testDocument.getElementsByTagName("div"), |
| 1018 ...testDocument.getElementsByTagName("p")]) | 1079 ...testDocument.getElementsByTagName("p")]) |
| 1019 { | 1080 { |
| 1020 if (element.id == "n4" || element.id == "n4_1") | 1081 if (element.id == "n4" || element.id == "n4_1") |
| 1021 expectProcessed(test, element, element.id); | 1082 expectProcessed(test, element, element.id); |
| 1022 else | 1083 else |
| 1023 expectNotProcessed(test, element, element.id); | 1084 expectNotProcessed(test, element, element.id); |
| 1024 } | 1085 } |
| 1025 | 1086 |
| 1026 // Create a new <p id="n2_3"> element with no text. | 1087 // Create a new <p id="n2_3"> element with no text. |
| 1027 createElement(testDocument.getElementById("n2"), "p", "n2_3"); | 1088 createElement(testDocument.getElementById("n2"), "p", "n2_3"); |
| 1028 | 1089 |
| 1029 return timeout(REFRESH_INTERVAL); | 1090 await timeout(REFRESH_INTERVAL); |
| 1030 }).then(() => | 1091 |
| 1031 { | |
| 1032 // When a new element is added, only the element or one of its ancestors | 1092 // When a new element is added, only the element or one of its ancestors |
| 1033 // matching any selector is processed for :-abp-has() and :-abp-contains() | 1093 // matching any selector is processed for :-abp-has() and :-abp-contains() |
| 1034 for (let element of [...testDocument.getElementsByTagName("div"), | 1094 for (let element of [...testDocument.getElementsByTagName("div"), |
| 1035 ...testDocument.getElementsByTagName("p")]) | 1095 ...testDocument.getElementsByTagName("p")]) |
| 1036 { | 1096 { |
| 1037 if (element.id == "n2" || element.id == "n2_3") | 1097 if (element.id == "n2" || element.id == "n2_3") |
| 1038 expectProcessed(test, element, element.id); | 1098 expectProcessed(test, element, element.id); |
| 1039 else | 1099 else |
| 1040 expectNotProcessed(test, element, element.id); | 1100 expectNotProcessed(test, element, element.id); |
| 1041 } | 1101 } |
| 1042 }).catch(unexpectedError.bind(test)).then(() => test.done()); | 1102 } |
| 1103 |
| 1104 test.done(); |
| 1043 }; | 1105 }; |
| OLD | NEW |