diff --git a/src/create-context.ts b/src/create-context.ts index 81352bf..acf9b82 100644 --- a/src/create-context.ts +++ b/src/create-context.ts @@ -49,6 +49,7 @@ export async function createContext(node: T, options?: Options & bypassingCache: false, ...options?.fetch, }, + fetchFn: null, font: {}, drawImageInterval: 100, workerUrl: null, diff --git a/src/fetch.ts b/src/fetch.ts index 72c6fe8..f021a6f 100644 --- a/src/fetch.ts +++ b/src/fetch.ts @@ -45,6 +45,7 @@ export function contextFetch(context: Context, options: ContextFetchOptions) { timeout, acceptOfImage, requests, + fetchFn, fetch: { requestInit, bypassingCache, @@ -82,16 +83,24 @@ export function contextFetch(context: Context, options: ContextFetchOptions) { response: null as any, } - request.response = ( - !IN_SAFARI && rawUrl.startsWith('http') && workers.length - ? new Promise((resolve, reject) => { + request.response = (async () => { + if (fetchFn && requestType === 'image') { + const result = await fetchFn(rawUrl) + + if (result) return result + } + + if (!IN_SAFARI && rawUrl.startsWith('http') && workers.length) { + return new Promise((resolve, reject) => { const worker = workers[requests.size & (workers.length - 1)] worker.postMessage({ rawUrl, ...baseFetchOptions }) request!.resolve = resolve request!.reject = reject }) - : baseFetch(baseFetchOptions) - ).catch(error => { + } + + return baseFetch(baseFetchOptions) + })().catch(error => { requests.delete(rawUrl) if (requestType === 'image' && placeholderImage) { diff --git a/src/options.ts b/src/options.ts index 8df9e27..4988061 100644 --- a/src/options.ts +++ b/src/options.ts @@ -69,6 +69,23 @@ export interface Options { */ debug?: boolean + /** + * Custom implementation to get image data for a custom URL. + * This can be helpful for Capacitor or Cordova when using + * native fetch to bypass CORS issues. + * + * If returns a string, will completely bypass any `Options.fetch` + * settings with your custom implementation. + * + * If returns false, will fall back to normal fetch implementation + * + * @param url + * @returns A data URL for the image + */ + fetchFn?: (( + url: string, + ) => Promise) | null + /** * The options of fetch resources. */