You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
2.5 KiB

/**
* Copyright (c) Nicolas Gallagher.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
const dataUriPattern = /^data:/;
declare export class ImageUriCache {
static _maximumEntries: number,
static _entries: any,
static has(uri: string): boolean,
static add(uri: string): any,
static remove(uri: string): any,
static _cleanUpIfNeeded(): any,
}
let id = 0;
const requests = {};
const ImageLoader = {
abort(requestId: number) {
let image = requests[`${requestId}`];
if (image) {
image.onerror = null;
image.onload = null;
image = null;
delete requests[`${requestId}`];
}
},
getSize(uri: string, success: (width: number, height: number) => void, failure: () => void) {
let complete = false;
const interval = setInterval(callback, 16);
const requestId = ImageLoader.load(uri, callback, errorCallback);
declare function callback(): any;
declare function errorCallback(): any;
},
has(uri: string): boolean {
return ImageUriCache.has(uri);
},
load(uri: string, onLoad: Function, onError: Function): number {
id += 1;
const image = new window.Image();
image.onerror = onError;
image.onload = e => {
// avoid blocking the main thread
declare var onDecode: () => any;
if (typeof image.decode === 'function') {
// Safari currently throws exceptions when decoding svgs.
// We want to catch that error and allow the load handler
// to be forwarded to the onLoad handler in this case
image.decode().then(onDecode, onDecode);
} else {
setTimeout(onDecode, 0);
}
};
image.src = uri;
requests[`${id}`] = image;
return id;
},
prefetch(uri: string): Promise<void> {
return new Promise((resolve, reject) => {
ImageLoader.load(uri, () => {
// Add the uri to the cache so it can be immediately displayed when used
// but also immediately remove it to correctly reflect that it has no active references
ImageUriCache.add(uri);
ImageUriCache.remove(uri);
resolve();
}, reject);
});
},
queryCache(uris: Array<string>): Promise<{|
[uri: string]: 'disk/memory'
|}> {
const result = {};
uris.forEach(u => {
if (ImageUriCache.has(u)) {
result[u] = 'disk/memory';
}
});
return Promise.resolve(result);
}
};
export default ImageLoader;