76 lines
2.5 KiB
JavaScript
76 lines
2.5 KiB
JavaScript
|
function getContentFromDataUrl(dataURL) {
|
||
|
return dataURL.split(/,/)[1];
|
||
|
}
|
||
|
export function isDataUrl(url) {
|
||
|
return url.search(/^(data:)/) !== -1;
|
||
|
}
|
||
|
export function makeDataUrl(content, mimeType) {
|
||
|
return `data:${mimeType};base64,${content}`;
|
||
|
}
|
||
|
export async function fetchAsDataURL(url, init, process) {
|
||
|
const res = await fetch(url, init);
|
||
|
if (res.status === 404) {
|
||
|
throw new Error(`Resource "${res.url}" not found`);
|
||
|
}
|
||
|
const blob = await res.blob();
|
||
|
return new Promise((resolve, reject) => {
|
||
|
const reader = new FileReader();
|
||
|
reader.onerror = reject;
|
||
|
reader.onloadend = () => {
|
||
|
try {
|
||
|
resolve(process({ res, result: reader.result }));
|
||
|
}
|
||
|
catch (error) {
|
||
|
reject(error);
|
||
|
}
|
||
|
};
|
||
|
reader.readAsDataURL(blob);
|
||
|
});
|
||
|
}
|
||
|
const cache = {};
|
||
|
function getCacheKey(url, contentType, includeQueryParams) {
|
||
|
let key = url.replace(/\?.*/, '');
|
||
|
if (includeQueryParams) {
|
||
|
key = url;
|
||
|
}
|
||
|
// font resource
|
||
|
if (/ttf|otf|eot|woff2?/i.test(key)) {
|
||
|
key = key.replace(/.*\//, '');
|
||
|
}
|
||
|
return contentType ? `[${contentType}]${key}` : key;
|
||
|
}
|
||
|
export async function resourceToDataURL(resourceUrl, contentType, options) {
|
||
|
const cacheKey = getCacheKey(resourceUrl, contentType, options.includeQueryParams);
|
||
|
if (cache[cacheKey] != null) {
|
||
|
return cache[cacheKey];
|
||
|
}
|
||
|
// ref: https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Bypassing_the_cache
|
||
|
if (options.cacheBust) {
|
||
|
// eslint-disable-next-line no-param-reassign
|
||
|
resourceUrl += (/\?/.test(resourceUrl) ? '&' : '?') + new Date().getTime();
|
||
|
}
|
||
|
let dataURL;
|
||
|
try {
|
||
|
const content = await fetchAsDataURL(resourceUrl, options.fetchRequestInit, ({ res, result }) => {
|
||
|
if (!contentType) {
|
||
|
// eslint-disable-next-line no-param-reassign
|
||
|
contentType = res.headers.get('Content-Type') || '';
|
||
|
}
|
||
|
return getContentFromDataUrl(result);
|
||
|
});
|
||
|
dataURL = makeDataUrl(content, contentType);
|
||
|
}
|
||
|
catch (error) {
|
||
|
dataURL = options.imagePlaceholder || '';
|
||
|
let msg = `Failed to fetch resource: ${resourceUrl}`;
|
||
|
if (error) {
|
||
|
msg = typeof error === 'string' ? error : error.message;
|
||
|
}
|
||
|
if (msg) {
|
||
|
console.warn(msg);
|
||
|
}
|
||
|
}
|
||
|
cache[cacheKey] = dataURL;
|
||
|
return dataURL;
|
||
|
}
|
||
|
//# sourceMappingURL=dataurl.js.map
|