Left: | ||
Right: |
LEFT | RIGHT |
---|---|
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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
113 if (element.style.getPropertyValue("display") != "none" || | 113 if (element.style.getPropertyValue("display") != "none" || |
114 element.style.getPropertyPriority("display") != "important") | 114 element.style.getPropertyPriority("display") != "important") |
115 { | 115 { |
116 element.style.setProperty("display", "none", "important"); | 116 element.style.setProperty("display", "none", "important"); |
117 } | 117 } |
118 }) | 118 }) |
119 .observe(element, {attributes: true, attributeFilter: ["style"]}); | 119 .observe(element, {attributes: true, attributeFilter: ["style"]}); |
120 } | 120 } |
121 | 121 |
122 /** | 122 /** |
123 * Hides an HTML element or one of its ancestors matching a CSS selector by | |
124 * setting its <code>style</code> attribute to | |
125 * <code>display: none !important</code>. | |
126 * | |
127 * @param {HTMLElement} element The HTML element or a descendant of the HTML | |
128 * element to hide. | |
129 * @param {string} [selector] The CSS selector that the HTML element or one of | |
130 * its ancestors must match for it to be hidden. | |
131 */ | |
132 function hideAncestor(element, selector = "*") | |
133 { | |
134 do | |
135 { | |
136 if (element.matches(selector)) | |
hub
2018/08/10 12:30:41
Wouldn't https://developer.mozilla.org/en-US/docs/
Manish Jethani
2018/08/10 14:57:02
Ah, you're right. Element.closest is perfect.
It'
hub
2018/08/10 19:54:57
We support EdgeHTML 16 and up if I read things cor
| |
137 { | |
138 hideElement(element); | |
139 break; | |
140 } | |
141 } | |
142 while (element = element.parentElement); | |
143 } | |
144 | |
145 /** | |
146 * Observes changes to a DOM node using a <code>MutationObserver</code>. | 123 * Observes changes to a DOM node using a <code>MutationObserver</code>. |
147 * | 124 * |
148 * @param {Node} target The DOM node to observe for changes. | 125 * @param {Node} target The DOM node to observe for changes. |
149 * @param {MutationObserverInit?} [options] Options that describe what DOM | 126 * @param {MutationObserverInit?} [options] Options that describe what DOM |
150 * mutations should be reported to the callback. | 127 * mutations should be reported to the callback. |
151 * @param {function} callback A function that will be called on each DOM | 128 * @param {function} callback A function that will be called on each DOM |
152 * mutation, taking a <code>MutationRecord</code> as its parameter. | 129 * mutation, taking a <code>MutationRecord</code> as its parameter. |
153 */ | 130 */ |
154 function observe(target, options, callback) | 131 function observe(target, options, callback) |
155 { | 132 { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
232 | 209 |
233 // 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 |
234 // shadow has been removed. | 211 // shadow has been removed. |
235 if (!host || !root) | 212 if (!host || !root) |
236 return; | 213 return; |
237 | 214 |
238 // 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 |
239 // ancestors matches the selector; if a matching element is found, hide | 216 // ancestors matches the selector; if a matching element is found, hide |
240 // it. | 217 // it. |
241 if (root.textContent.includes(search)) | 218 if (root.textContent.includes(search)) |
242 hideAncestor(host, selector); | 219 { |
220 let closest = host.closest(selector); | |
221 if (closest) | |
222 hideElement(closest); | |
223 } | |
243 } | 224 } |
244 | 225 |
245 Object.defineProperty(Element.prototype, "attachShadow", { | 226 Object.defineProperty(Element.prototype, "attachShadow", { |
246 value(...args) | 227 value(...args) |
247 { | 228 { |
248 // 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 |
249 // shadow root, we keep the reference in a weak map. | 230 // shadow root, we keep the reference in a weak map. |
250 let root = originalAttachShadow.apply(this, args); | 231 let root = originalAttachShadow.apply(this, args); |
251 | 232 |
252 // Listen for relevant DOM mutations in the shadow. | 233 // Listen for relevant DOM mutations in the shadow. |
253 let observer = new MutationObserver(observeShadow); | 234 let observer = new MutationObserver(observeShadow); |
254 observer.observe(root, { | 235 observer.observe(root, { |
255 childList: true, | 236 childList: true, |
256 characterData: true, | 237 characterData: true, |
257 subtree: true | 238 subtree: true |
258 }); | 239 }); |
259 | 240 |
260 // Keep references to the shadow root and its host in a weak map. If | 241 // Keep references to the shadow root and its host in a weak map. If |
261 // either the shadow is detached or the host itself is removed from the | 242 // either the shadow is detached or the host itself is removed from the |
262 // DOM, the mutation observer too will be freed eventually and the entry | 243 // DOM, the mutation observer too will be freed eventually and the entry |
263 // will be removed. | 244 // will be removed. |
264 shadows.set(observer, {host: this, root}); | 245 shadows.set(observer, {host: this, root}); |
265 | 246 |
266 return root; | 247 return root; |
267 } | 248 } |
268 }); | 249 }); |
269 } | 250 } |
270 | 251 |
271 exports["hide-if-shadow-contains"] = makeInjector(hideIfShadowContains, | 252 exports["hide-if-shadow-contains"] = makeInjector(hideIfShadowContains, |
272 hideAncestor, hideElement); | 253 hideElement); |
273 | 254 |
274 /** | 255 /** |
275 * Hides any HTML element or one of its ancestors matching a CSS selector if | 256 * Hides any HTML element or one of its ancestors matching a CSS selector if |
276 * the text content of the element contains a given string. | 257 * the text content of the element contains a given string. |
277 * | 258 * |
278 * @param {string} search The string to look for in HTML elements. | 259 * @param {string} search The string to look for in HTML elements. |
279 * @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 |
280 * for it to be hidden. | 261 * for it to be hidden. |
281 * @param {string?} [searchSelector] The CSS selector that an HTML element | 262 * @param {string?} [searchSelector] The CSS selector that an HTML element |
282 * containing the given string must match. Defaults to the value of the | 263 * containing the given string must match. Defaults to the value of the |
283 * <code>selector</code> argument. | 264 * <code>selector</code> argument. |
284 */ | 265 */ |
285 function hideIfContains(search, selector = "*", searchSelector = null) | 266 function hideIfContains(search, selector = "*", searchSelector = null) |
286 { | 267 { |
287 if (searchSelector == null) | 268 if (searchSelector == null) |
288 searchSelector = selector; | 269 searchSelector = selector; |
289 | 270 |
290 new MutationObserver(() => | 271 new MutationObserver(() => |
291 { | 272 { |
292 for (let element of document.querySelectorAll(searchSelector)) | 273 for (let element of document.querySelectorAll(searchSelector)) |
293 { | 274 { |
294 if (element.textContent.includes(search)) | 275 if (element.textContent.includes(search)) |
295 hideAncestor(element, selector); | 276 { |
277 let closest = element.closest(selector); | |
278 if (closest) | |
279 hideElement(closest); | |
280 } | |
296 } | 281 } |
297 }) | 282 }) |
298 .observe(document, {childList: true, characterData: true, subtree: true}); | 283 .observe(document, {childList: true, characterData: true, subtree: true}); |
299 } | 284 } |
300 | 285 |
301 exports["hide-if-contains"] = hideIfContains; | 286 exports["hide-if-contains"] = hideIfContains; |
302 | 287 |
303 /** | 288 /** |
304 * 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. |
305 * | 290 * |
(...skipping 17 matching lines...) Expand all Loading... | |
323 // 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, |
324 // 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. |
325 mutation.target.appendChild(node); | 310 mutation.target.appendChild(node); |
326 } | 311 } |
327 } | 312 } |
328 } | 313 } |
329 }); | 314 }); |
330 } | 315 } |
331 | 316 |
332 exports.readd = readd; | 317 exports.readd = readd; |
LEFT | RIGHT |