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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 * | 90 * |
91 * @returns {function} The generated injector. | 91 * @returns {function} The generated injector. |
92 */ | 92 */ |
93 function makeInjector(injectable, ...dependencies) | 93 function makeInjector(injectable, ...dependencies) |
94 { | 94 { |
95 return (...args) => injectCode(stringifyFunctionCall(injectable, ...args), | 95 return (...args) => injectCode(stringifyFunctionCall(injectable, ...args), |
96 dependencies); | 96 dependencies); |
97 } | 97 } |
98 | 98 |
99 /** | 99 /** |
100 * Hides an HTML element by settings its <code>style</code> attribute to | 100 * Hides an HTML element by setting its <code>style</code> attribute to |
101 * <code>display: none !important</code>. | 101 * <code>display: none !important</code>. |
102 * | 102 * |
103 * @param {HTMLElement} element The HTML element to hide. | 103 * @param {HTMLElement} element The HTML element to hide. |
104 */ | 104 */ |
105 function hideElement(element) | 105 function hideElement(element) |
106 { | 106 { |
107 element.style.setProperty("display", "none", "important"); | 107 element.style.setProperty("display", "none", "important"); |
108 | 108 |
109 // Listen for changes to the style property and if our values are unset | 109 // Listen for changes to the style property and if our values are unset |
110 // then reset them. | 110 // then reset them. |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 // Since it's a weak map, it's possible that either the element or its | 210 // Since it's a weak map, it's possible that either the element or its |
211 // shadow has been removed. | 211 // shadow has been removed. |
212 if (!host || !root) | 212 if (!host || !root) |
213 return; | 213 return; |
214 | 214 |
215 // If the shadow contains the given text, check if the host or one of its | 215 // If the shadow contains the given text, check if the host or one of its |
216 // ancestors matches the selector; if a matching element is found, hide | 216 // ancestors matches the selector; if a matching element is found, hide |
217 // it. | 217 // it. |
218 if (root.textContent.includes(search)) | 218 if (root.textContent.includes(search)) |
219 { | 219 { |
220 let element = host; | 220 let closest = host.closest(selector); |
221 | 221 if (closest) |
222 do | 222 hideElement(closest); |
223 { | |
224 if (element.matches(selector)) | |
225 { | |
226 hideElement(element); | |
227 break; | |
228 } | |
229 } | |
230 while (element = element.parentElement); | |
231 } | 223 } |
232 } | 224 } |
233 | 225 |
234 Object.defineProperty(Element.prototype, "attachShadow", { | 226 Object.defineProperty(Element.prototype, "attachShadow", { |
235 value(...args) | 227 value(...args) |
236 { | 228 { |
237 // Create the shadow root first. It doesn't matter if it's a closed | 229 // Create the shadow root first. It doesn't matter if it's a closed |
238 // shadow root, we keep the reference in a weak map. | 230 // shadow root, we keep the reference in a weak map. |
239 let root = originalAttachShadow.apply(this, args); | 231 let root = originalAttachShadow.apply(this, args); |
240 | 232 |
(...skipping 13 matching lines...) Expand all Loading... |
254 | 246 |
255 return root; | 247 return root; |
256 } | 248 } |
257 }); | 249 }); |
258 } | 250 } |
259 | 251 |
260 exports["hide-if-shadow-contains"] = makeInjector(hideIfShadowContains, | 252 exports["hide-if-shadow-contains"] = makeInjector(hideIfShadowContains, |
261 hideElement); | 253 hideElement); |
262 | 254 |
263 /** | 255 /** |
264 * Hides any HTML element if the text content of the element contains a given | 256 * Hides any HTML element or one of its ancestors matching a CSS selector if |
265 * string. | 257 * the text content of the element contains a given string. |
266 * | 258 * |
267 * @param {string} search The string to look for in every HTML element. | 259 * @param {string} search The string to look for in HTML elements. |
268 * @param {string} selector The CSS selector that an HTML element must match | 260 * @param {string} selector The CSS selector that an HTML element must match |
269 * for it to be hidden. | 261 * for it to be hidden. |
| 262 * @param {string?} [searchSelector] The CSS selector that an HTML element |
| 263 * containing the given string must match. Defaults to the value of the |
| 264 * <code>selector</code> argument. |
270 */ | 265 */ |
271 function hideIfContains(search, selector = "*") | 266 function hideIfContains(search, selector = "*", searchSelector = null) |
272 { | 267 { |
| 268 if (searchSelector == null) |
| 269 searchSelector = selector; |
| 270 |
273 new MutationObserver(() => | 271 new MutationObserver(() => |
274 { | 272 { |
275 for (let element of document.querySelectorAll(selector)) | 273 for (let element of document.querySelectorAll(searchSelector)) |
276 { | 274 { |
277 if (element.textContent.includes(search)) | 275 if (element.textContent.includes(search)) |
278 hideElement(element); | 276 { |
| 277 let closest = element.closest(selector); |
| 278 if (closest) |
| 279 hideElement(closest); |
| 280 } |
279 } | 281 } |
280 }) | 282 }) |
281 .observe(document, {childList: true, characterData: true, subtree: true}); | 283 .observe(document, {childList: true, characterData: true, subtree: true}); |
282 } | 284 } |
283 | 285 |
284 exports["hide-if-contains"] = hideIfContains; | 286 exports["hide-if-contains"] = hideIfContains; |
285 | 287 |
286 /** | 288 /** |
287 * Readds to the document any removed HTML elements that match a CSS selector. | 289 * Readds to the document any removed HTML elements that match a CSS selector. |
288 * | 290 * |
(...skipping 17 matching lines...) Expand all Loading... |
306 // We don't have the location of the element in its former parent, | 308 // We don't have the location of the element in its former parent, |
307 // but it's usually OK to just add it at the end. | 309 // but it's usually OK to just add it at the end. |
308 mutation.target.appendChild(node); | 310 mutation.target.appendChild(node); |
309 } | 311 } |
310 } | 312 } |
311 } | 313 } |
312 }); | 314 }); |
313 } | 315 } |
314 | 316 |
315 exports.readd = readd; | 317 exports.readd = readd; |
OLD | NEW |