1
0
mirror of https://github.com/gorhill/uBlock.git synced 2025-02-01 04:31:36 +01:00

Improve interactivity of no-large-media-elements content scripts

Related issue:
- https://github.com/gorhill/uBlock/issues/1390#issuecomment-713174183
This commit is contained in:
Raymond Hill 2020-10-22 08:44:55 -04:00
parent 4d17458baf
commit 0628d2ec9f
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
2 changed files with 64 additions and 90 deletions

View File

@ -27,29 +27,15 @@
/******************************************************************************/ /******************************************************************************/
// For all media resources which have failed to load, trigger a reload. if (
typeof vAPI !== 'object' ||
// <audio> and <video> elements. vAPI.loadAllLargeMedia instanceof Function === false
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement ) {
return;
for ( const elem of document.querySelectorAll('audio,video') ) {
if ( elem.error === null ) { continue; }
elem.load();
} }
// <img> elements. vAPI.loadAllLargeMedia();
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement vAPI.loadAllLargeMedia = undefined;
for ( const elem of document.querySelectorAll('img') ) {
if ( elem.naturalWidth !== 0 && elem.naturalHeight !== 0 ) { continue; }
if ( window.getComputedStyle(elem).getPropertyValue('display') === 'none' ) {
continue;
}
const src = elem.getAttribute('src') || '';
if ( src === '' ) { continue; }
elem.removeAttribute('src');
elem.setAttribute('src', src);
}
/******************************************************************************/ /******************************************************************************/

View File

@ -28,7 +28,7 @@
/******************************************************************************/ /******************************************************************************/
// This can happen // This can happen
if ( typeof vAPI !== 'object' || vAPI.loadLargeMediaInteractive === true ) { if ( typeof vAPI !== 'object' || vAPI.loadAllLargeMedia instanceof Function ) {
return; return;
} }
@ -45,12 +45,11 @@ const largeMediaElementSelector =
const mediaNotLoaded = function(elem) { const mediaNotLoaded = function(elem) {
const src = elem.getAttribute('src') || ''; const src = elem.getAttribute('src') || '';
if ( src === '' ) { return false; }
switch ( elem.localName ) { switch ( elem.localName ) {
case 'audio': case 'audio':
case 'video': case 'video':
return elem.error !== null; return src === '' || elem.error !== null;
case 'img': case 'img':
if ( elem.naturalWidth !== 0 || elem.naturalHeight !== 0 ) { break; } if ( elem.naturalWidth !== 0 || elem.naturalHeight !== 0 ) { break; }
const style = window.getComputedStyle(elem); const style = window.getComputedStyle(elem);
@ -70,7 +69,6 @@ const mediaNotLoaded = function(elem) {
// <audio> and <video> elements. // <audio> and <video> elements.
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement // https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement
const surveyMissingMediaElements = function() { const surveyMissingMediaElements = function() {
let largeMediaElementCount = 0; let largeMediaElementCount = 0;
@ -94,8 +92,6 @@ const surveyMissingMediaElements = function() {
if ( surveyMissingMediaElements() === 0 ) { return; } if ( surveyMissingMediaElements() === 0 ) { return; }
vAPI.loadLargeMediaInteractive = true;
// Insert CSS to highlight blocked media elements. // Insert CSS to highlight blocked media elements.
if ( vAPI.largeMediaElementStyleSheet === undefined ) { if ( vAPI.largeMediaElementStyleSheet === undefined ) {
vAPI.largeMediaElementStyleSheet = [ vAPI.largeMediaElementStyleSheet = [
@ -119,65 +115,53 @@ if ( vAPI.largeMediaElementStyleSheet === undefined ) {
/******************************************************************************/ /******************************************************************************/
const stayOrLeave = (( ) => { const loadMedia = async function(elem) {
let timer; const src = elem.getAttribute('src') || '';
const timeoutHandler = function(leaveNow) {
timer = undefined;
if ( leaveNow !== true ) {
if (
document.querySelector(largeMediaElementSelector) !== null ||
surveyMissingMediaElements() !== 0
) {
return;
}
}
// Leave
for ( const elem of document.querySelectorAll(largeMediaElementSelector) ) {
elem.removeAttribute(largeMediaElementAttribute);
}
vAPI.loadLargeMediaInteractive = false;
document.removeEventListener('error', onLoadError, true);
document.removeEventListener('click', onMouseClick, true);
};
return function(leaveNow) {
if ( timer !== undefined ) {
clearTimeout(timer);
}
if ( leaveNow ) {
timeoutHandler(true);
} else {
timer = vAPI.setTimeout(timeoutHandler, 5000);
}
};
})();
/******************************************************************************/
const loadImage = async function(elem) {
const src = elem.getAttribute('src');
elem.removeAttribute('src'); elem.removeAttribute('src');
await vAPI.messaging.send('scriptlets', { await vAPI.messaging.send('scriptlets', {
what: 'temporarilyAllowLargeMediaElement', what: 'temporarilyAllowLargeMediaElement',
}); });
if ( src !== '' ) {
elem.setAttribute('src', src); elem.setAttribute('src', src);
elem.removeAttribute(largeMediaElementAttribute); } else {
elem.replaceWith(elem.cloneNode(true));
switch ( elem.localName ) {
case 'img': {
const picture = elem.closest('picture');
if ( picture !== null ) {
picture.removeAttribute(largeMediaElementAttribute);
} }
} break; };
/******************************************************************************/
const loadImage = async function(elem) {
const src = elem.getAttribute('src') || '';
elem.removeAttribute('src');
await vAPI.messaging.send('scriptlets', {
what: 'temporarilyAllowLargeMediaElement',
});
if ( src !== '' ) {
elem.setAttribute('src', src);
}
};
/******************************************************************************/
const loadMany = function(elems) {
for ( const elem of elems ) {
elem.removeAttribute(largeMediaElementAttribute);
switch ( elem.localName ) {
case 'audio':
case 'video':
loadMedia(elem);
break;
case 'img':
loadImage(elem);
break;
default: default:
break; break;
} }
}
stayOrLeave();
}; };
/******************************************************************************/ /******************************************************************************/
@ -190,19 +174,15 @@ const onMouseClick = function(ev) {
? document.elementsFromPoint(ev.clientX, ev.clientY) ? document.elementsFromPoint(ev.clientX, ev.clientY)
: [ ev.target ]; : [ ev.target ];
for ( const elem of elems ) { for ( const elem of elems ) {
if ( elem.matches(largeMediaElementSelector) && mediaNotLoaded(elem) ) { if ( elem.matches(largeMediaElementSelector) === false ) { continue; }
if ( mediaNotLoaded(elem) ) {
toLoad.push(elem); toLoad.push(elem);
} }
} }
if ( toLoad.length === 0 ) { if ( toLoad.length === 0 ) { return; }
stayOrLeave();
return;
}
for ( const elem of toLoad ) { loadMany(toLoad);
loadImage(elem);
}
ev.preventDefault(); ev.preventDefault();
ev.stopPropagation(); ev.stopPropagation();
@ -216,7 +196,6 @@ const onLoad = function(ev) {
const elem = ev.target; const elem = ev.target;
if ( elem.hasAttribute(largeMediaElementAttribute) ) { if ( elem.hasAttribute(largeMediaElementAttribute) ) {
elem.removeAttribute(largeMediaElementAttribute); elem.removeAttribute(largeMediaElementAttribute);
stayOrLeave();
} }
}; };
@ -235,9 +214,18 @@ document.addEventListener('error', onLoadError, true);
/******************************************************************************/ /******************************************************************************/
vAPI.shutdown.add(( ) => { vAPI.loadAllLargeMedia = function() {
stayOrLeave(true); document.removeEventListener('load', onLoad, true);
}); document.removeEventListener('error', onLoadError, true);
const toLoad = [];
for ( const elem of document.querySelectorAll(largeMediaElementSelector) ) {
if ( mediaNotLoaded(elem) ) {
toLoad.push(elem);
}
}
loadMany(toLoad);
};
/******************************************************************************/ /******************************************************************************/