MOBILE-4290 core: Make waitForImages cancellable
parent
2dbb1f2316
commit
bfe9100879
|
@ -59,6 +59,7 @@ import { CoreUserSupport } from '@features/user/services/support';
|
||||||
import { CoreErrorInfoComponent } from '@components/error-info/error-info';
|
import { CoreErrorInfoComponent } from '@components/error-info/error-info';
|
||||||
import { CorePlatform } from '@services/platform';
|
import { CorePlatform } from '@services/platform';
|
||||||
import { AddonFilterMultilang2Handler } from '@addons/filter/multilang2/services/handlers/multilang2';
|
import { AddonFilterMultilang2Handler } from '@addons/filter/multilang2/services/handlers/multilang2';
|
||||||
|
import { CoreCancellablePromise } from '@classes/cancellable-promise';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "Utils" service with helper functions for UI, DOM elements and HTML code.
|
* "Utils" service with helper functions for UI, DOM elements and HTML code.
|
||||||
|
@ -1918,32 +1919,62 @@ export class CoreDomUtilsProvider {
|
||||||
* @param element The element to search in.
|
* @param element The element to search in.
|
||||||
* @returns Promise resolved with a boolean: whether there was any image to load.
|
* @returns Promise resolved with a boolean: whether there was any image to load.
|
||||||
*/
|
*/
|
||||||
async waitForImages(element: HTMLElement): Promise<boolean> {
|
waitForImages(element: HTMLElement): CoreCancellablePromise<boolean> {
|
||||||
const imgs = Array.from(element.querySelectorAll('img'));
|
const imgs = Array.from(element.querySelectorAll('img'));
|
||||||
const promises: Promise<void>[] = [];
|
|
||||||
let hasImgToLoad = false;
|
|
||||||
|
|
||||||
imgs.forEach((img) => {
|
if (imgs.length === 0) {
|
||||||
if (img && !img.complete) {
|
return CoreCancellablePromise.resolve(false);
|
||||||
hasImgToLoad = true;
|
}
|
||||||
|
|
||||||
// Wait for image to load or fail.
|
let completedImages = 0;
|
||||||
promises.push(new Promise((resolve) => {
|
let waitedForImages = false;
|
||||||
const imgLoaded = (): void => {
|
const listeners: WeakMap<Element, () => unknown> = new WeakMap();
|
||||||
resolve();
|
const imageCompleted = (resolve: (result: boolean) => void) => {
|
||||||
img.removeEventListener('load', imgLoaded);
|
completedImages++;
|
||||||
img.removeEventListener('error', imgLoaded);
|
|
||||||
|
if (completedImages === imgs.length) {
|
||||||
|
resolve(waitedForImages);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return new CoreCancellablePromise<boolean>(
|
||||||
|
resolve => {
|
||||||
|
for (const img of imgs) {
|
||||||
|
if (!img || img.complete) {
|
||||||
|
imageCompleted(resolve);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
waitedForImages = true;
|
||||||
|
|
||||||
|
// Wait for image to load or fail.
|
||||||
|
const imgCompleted = (): void => {
|
||||||
|
img.removeEventListener('load', imgCompleted);
|
||||||
|
img.removeEventListener('error', imgCompleted);
|
||||||
|
|
||||||
|
imageCompleted(resolve);
|
||||||
};
|
};
|
||||||
|
|
||||||
img.addEventListener('load', imgLoaded);
|
img.addEventListener('load', imgCompleted);
|
||||||
img.addEventListener('error', imgLoaded);
|
img.addEventListener('error', imgCompleted);
|
||||||
}));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
await Promise.all(promises);
|
listeners.set(img, imgCompleted);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
imgs.forEach(img => {
|
||||||
|
const listener = listeners.get(img);
|
||||||
|
|
||||||
return hasImgToLoad;
|
if (!listener) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
img.removeEventListener('load', listener);
|
||||||
|
img.removeEventListener('error', listener);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue