Improve `prevent-element-src-loading` — inline `onerror` support?
Hi,
This aims to improve the prevent-element-src-loading scriptlet (see this comment — and the issue) and is based on a concrete example. (Example which in this case can be resolved differently but that's not what interests us here.)
Concerned code
Click to reveal …
view-source:https://www.leconomiste.com/
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js" onerror="showPopup();"></script>
<script>
function showPopup() {
document.getElementById('boxes').style.display='block';
}
</script>
<div id='boxes' style='display:none;'>
<div style='top: 199.5px; left: 450px; display: none;z-index: 99999; background:#fff;height:350px' id='dialog' class='window'>
<div style="text-align:center;">
<img src='sites/all/themes/eco7_vf/images/adblock1.jpg' />
<h1>Vous utilisez un bloqueur de publicité</h1>
<p>Merci de désactiver le bloqueur de publicité avant de naviguer sur notre site.</p>
</div>
</div>
<div style='width: 1478px; height: 1002px; display: none; opacity: 0.8;top: -72px;' id='mask'></div>
</div>
Steps to reproduce
Click to reveal …
Steps
-
Add this DNS user rule (in the way you like):
||pagead2.googlesyndication.com^ -
Only if you use AdGuard for Windows/Mac/Android, add this user rule first (just to avoid deletion of the concerned script tag in the HTML code due to existing rules):
@@||pagead2.googlesyndication.com/pagead/js/adsbygoogle.js$domain=leconomiste.com -
Add this user rule:
leconomiste.com#%#//scriptlet('prevent-element-src-loading', 'script', 'adsbygoogle')
Expected behavior
Inline onerror code used by the website:
onerror="showPopup();"
is not executed. In the same way as if this had been used instead:
[…]
script.onerror = () => {
showPopup();
};
script.src = '//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
[…]
Actual behavior
Inline onerror code is executed.
Additional information
Click to reveal …
Remark:
- Make sure it's OK too if this is done later by the website:
[…]
script.setAttribute('onerror', '[…]');
script.setAttribute('src', '//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js');
[…]
Related link:
- https://www.webtips.dev/how-to-reliably-check-if-adblocker-is-enabled (search
adsbygoogleon the page)
If I'm not wrong, something like this:
Code
function preventError(src) {
window.addEventListener('error', function (event) {
/* or event.target */
if (!event.srcElement || !event.srcElement.src) {
return;
}
const regex = new RegExp(src);
if (!regex.test(event.srcElement.src)) {
return;
}
if (typeof event.srcElement.onload === 'function') {
return event.srcElement.onerror = event.srcElement.onload;
}
return event.srcElement.onerror = function () {};
}, true);
};
preventError("adsbygoogle");
Rule:
leconomiste.com#%#function preventError(a){window.addEventListener("error",function(b){if(b.srcElement&&b.srcElement.src){const c=new RegExp(a);return c.test(b.srcElement.src)?"function"==typeof b.srcElement.onload?b.srcElement.onerror=b.srcElement.onload:b.srcElement.onerror=function(){}:void 0}},!0)};preventError("adsbygoogle");
should fixes it and other similar cases with onerror attribute.
I guess that it may requires more improvements/tweaks, but perhaps it will be helpful to improve a current scriptlet or create a new one, maybe there is a better way to fix it, just an idea.
:heavy_check_mark: Nice work. The above rule allows, indeed, to fix this case on my side too.
(Tested both on AdGuard for Windows 7.10.1 and on AdGuard Browser extension 4.0.181.)
Let's wait and see what @slavaleleka and/or @stanislav-atr think of this solution! :wink: