-
-
Save munro/7f81bd1657499866f7c2 to your computer and use it in GitHub Desktop.
| from textwrap import dedent | |
| def wait_until_images_loaded(driver, timeout=30): | |
| """Waits for all images & background images to load.""" | |
| driver.set_script_timeout(timeout) | |
| driver.execute_async_script(dedent(''' | |
| // Function to extract URL from CSS 'url()' function | |
| function extractCSSURL(text) { | |
| var url_str = text.replace(/.*url\((.*)\).*/, '$1'); | |
| // If the URL is enclosed with double quotes | |
| if (url_str[0] === '"') { | |
| return JSON.parse(url_str); | |
| } | |
| // If the URL is enclosed with single quotes | |
| if (url_str[0] === "'") { | |
| return JSON.parse( | |
| url_str | |
| .replace(/'/g, '__DOUBLE__QUOTE__HERE__') | |
| .replace(/"/g, "'") | |
| .replace(/__DOUBLE__QUOTE__HERE__/g, '"') | |
| ); | |
| } | |
| // Return the URL as is | |
| return url_str; | |
| } | |
| // Function to create a promise that resolves when the image is loaded | |
| function imageResolved(url) { | |
| return new Promise(function (resolve) { | |
| var img = new Image(); | |
| img.onload = function () { | |
| resolve(url); | |
| }; | |
| img.src = url; | |
| // If the image is already loaded, resolve the promise immediately | |
| if (img.complete) { | |
| resolve(url); | |
| } | |
| }); | |
| } | |
| // The last argument is expected to be a callback function | |
| var callback = arguments[arguments.length - 1]; | |
| Promise.all([ | |
| // Get all img tags, create a promise for each one | |
| ...Array.from(document.querySelectorAll('img[src]'), img => imageResolved(img.src)), | |
| // Get all inline styles with 'url()' and create a promise for each one | |
| ...Array.from(document.querySelectorAll('[style*="url("]'), elem => imageResolved(extractCSSURL(elem.style.cssText))) | |
| ]) | |
| .then(function () { | |
| // After all images are loaded, wait for all fonts to load | |
| return document.fonts.ready; | |
| }) | |
| .then(function() { | |
| // After all fonts are loaded, check for images in CSS stylesheets | |
| let cssImagesPromises = []; | |
| for(let i = 0; i < document.styleSheets.length; i++) { | |
| let rules = document.styleSheets[i].cssRules; | |
| for (let j = 0; j < rules.length; j++) { | |
| let style = rules[j].style; | |
| // Check if a background image is found and if it's a URL | |
| if (style && String(style.backgroundImage).startsWith('url(')) { | |
| let url = extractCSSURL(style.backgroundImage); | |
| cssImagesPromises.push(imageResolved(url)); | |
| } | |
| } | |
| } | |
| return Promise.all(cssImagesPromises); | |
| }) | |
| .then(function () { | |
| // Call the callback function when all promises are resolved | |
| callback(arguments); | |
| }); | |
| return undefined; | |
| ''')) |
@madsheep aw thanks man, Iβm glad it helped!
Bro sorry for the inconvenience but I don't know how the script works can you help me, I'm trying to wait for the visibility of an image on a
It's an incredible job. Thank you for accomplishing this great work 8 years ago.
Awesome yet functional for the poor souls, not for making bad decisions, thank you very much!!!
I haven't fully tested this (which is why I haven't updated the gist) but here's code that works without jQuery dependency:
Let me know if this works and I'll update the gist!!
// Function to extract URL from CSS 'url()' function
function extractCSSURL(text) {
var url_str = text.replace(/.*url\((.*)\).*/, '$1');
// If the URL is enclosed with double quotes
if (url_str[0] === '"') {
return JSON.parse(url_str);
}
// If the URL is enclosed with single quotes
if (url_str[0] === "'") {
return JSON.parse(
url_str
.replace(/'/g, '__DOUBLE__QUOTE__HERE__')
.replace(/"/g, "'")
.replace(/__DOUBLE__QUOTE__HERE__/g, '"')
);
}
// Return the URL as is
return url_str;
}
// Function to create a promise that resolves when the image is loaded
function imageResolved(url) {
return new Promise(function (resolve) {
var img = new Image();
img.onload = function () {
resolve(url);
};
img.src = url;
// If the image is already loaded, resolve the promise immediately
if (img.complete) {
resolve(url);
}
});
}
// The last argument is expected to be a callback function
var callback = arguments[arguments.length - 1];
Promise.all([
// Get all img tags, create a promise for each one
...Array.from(document.querySelectorAll('img[src]'), img => imageResolved(img.src)),
// Get all inline styles with 'url()' and create a promise for each one
...Array.from(document.querySelectorAll('[style*="url("]'), elem => imageResolved(extractCSSURL(elem.style.cssText)))
])
.then(function () {
// After all images are loaded, wait for all fonts to load
return document.fonts.ready;
})
.then(function() {
// After all fonts are loaded, check for images in CSS stylesheets
let cssImagesPromises = [];
for(let i = 0; i < document.styleSheets.length; i++) {
let rules = document.styleSheets[i].cssRules;
for (let j = 0; j < rules.length; j++) {
let style = rules[j].style;
// Check if a background image is found and if it's a URL
if (style && String(style.backgroundImage).startsWith('url(')) {
let url = extractCSSURL(style.backgroundImage);
cssImagesPromises.push(imageResolved(url));
}
}
}
return Promise.all(cssImagesPromises);
})
.then(function () {
// Call the callback function when all promises are resolved
callback(arguments);
});
return undefined;I haven't fully tested this (which is why I haven't updated the gist) but here's code that works without jQuery dependency:
Let me know if this works and I'll update the gist!!
// Function to extract URL from CSS 'url()' function function extractCSSURL(text) { var url_str = text.replace(/.*url\((.*)\).*/, '$1'); // If the URL is enclosed with double quotes if (url_str[0] === '"') { return JSON.parse(url_str); } // If the URL is enclosed with single quotes if (url_str[0] === "'") { return JSON.parse( url_str .replace(/'/g, '__DOUBLE__QUOTE__HERE__') .replace(/"/g, "'") .replace(/__DOUBLE__QUOTE__HERE__/g, '"') ); } // Return the URL as is return url_str; } // Function to create a promise that resolves when the image is loaded function imageResolved(url) { return new Promise(function (resolve) { var img = new Image(); img.onload = function () { resolve(url); }; img.src = url; // If the image is already loaded, resolve the promise immediately if (img.complete) { resolve(url); } }); } // The last argument is expected to be a callback function var callback = arguments[arguments.length - 1]; Promise.all([ // Get all img tags, create a promise for each one ...Array.from(document.querySelectorAll('img[src]'), img => imageResolved(img.src)), // Get all inline styles with 'url()' and create a promise for each one ...Array.from(document.querySelectorAll('[style*="url("]'), elem => imageResolved(extractCSSURL(elem.style.cssText))) ]) .then(function () { // After all images are loaded, wait for all fonts to load return document.fonts.ready; }) .then(function() { // After all fonts are loaded, check for images in CSS stylesheets let cssImagesPromises = []; for(let i = 0; i < document.styleSheets.length; i++) { let rules = document.styleSheets[i].cssRules; for (let j = 0; j < rules.length; j++) { let style = rules[j].style; // Check if a background image is found and if it's a URL if (style && String(style.backgroundImage).startsWith('url(')) { let url = extractCSSURL(style.backgroundImage); cssImagesPromises.push(imageResolved(url)); } } } return Promise.all(cssImagesPromises); }) .then(function () { // Call the callback function when all promises are resolved callback(arguments); }); return undefined;
I can confirm this script works great thanks!
awesome updated π
Hi man - just letting you know, this is pretty cool. I know you did it 5 years ago, but you should know, you saved a poor soul from doing dumb stuff today. Kudos over the internet.