diff --git a/packages/common/src/directives/ng_optimized_image/image_loaders/cloudflare_loader.ts b/packages/common/src/directives/ng_optimized_image/image_loaders/cloudflare_loader.ts index 619cd3bbd2a..7b71b99d89d 100644 --- a/packages/common/src/directives/ng_optimized_image/image_loaders/cloudflare_loader.ts +++ b/packages/common/src/directives/ng_optimized_image/image_loaders/cloudflare_loader.ts @@ -6,13 +6,12 @@ * found in the LICENSE file at https://angular.io/license */ -import {Provider, ɵRuntimeError as RuntimeError} from '@angular/core'; +import {ɵRuntimeError as RuntimeError} from '@angular/core'; import {RuntimeErrorCode} from '../../../errors'; -import {PRECONNECT_CHECK_BLOCKLIST} from '../preconnect_link_checker'; -import {isValidPath, normalizePath, normalizeSrc} from '../util'; +import {normalizeSrc} from '../util'; -import {IMAGE_LOADER, ImageLoaderConfig} from './image_loader'; +import {createImageLoader, ImageLoaderConfig} from './image_loader'; /** * Function that generates a built-in ImageLoader for Cloudflare Image Resizing @@ -24,31 +23,18 @@ import {IMAGE_LOADER, ImageLoaderConfig} from './image_loader'; * e.g. https://mysite.com * @returns Provider that provides an ImageLoader function */ -export function provideCloudflareLoader(path: string, options: {ensurePreconnect?: boolean} = { - ensurePreconnect: true -}) { - if (ngDevMode && !isValidPath(path)) { - throwInvalidPathError(path); - } - path = normalizePath(path); +export const provideCloudflareLoader = + createImageLoader(cloudflareLoaderFactory, throwInvalidPathError); - const providers: Provider[] = [{ - provide: IMAGE_LOADER, - useValue: (config: ImageLoaderConfig) => { - let params = `format=auto`; - if (config.width) { - params += `,width=${config.width.toString()}`; - } - const url = `${path}/cdn-cgi/image/${params}/${normalizeSrc(config.src)}`; - return url; +function cloudflareLoaderFactory(path: string) { + return (config: ImageLoaderConfig) => { + let params = `format=auto`; + if (config.width) { + params += `,width=${config.width.toString()}`; } - }]; - - if (ngDevMode && Boolean(options.ensurePreconnect) === true) { - providers.push({provide: PRECONNECT_CHECK_BLOCKLIST, useValue: [path], multi: true}); - } - - return providers; + const url = `${path}/cdn-cgi/image/${params}/${normalizeSrc(config.src)}`; + return url; + }; } function throwInvalidPathError(path: unknown): never { diff --git a/packages/common/src/directives/ng_optimized_image/image_loaders/cloudinary_loader.ts b/packages/common/src/directives/ng_optimized_image/image_loaders/cloudinary_loader.ts index ee310f41ffd..2f4ce12460e 100644 --- a/packages/common/src/directives/ng_optimized_image/image_loaders/cloudinary_loader.ts +++ b/packages/common/src/directives/ng_optimized_image/image_loaders/cloudinary_loader.ts @@ -6,13 +6,12 @@ * found in the LICENSE file at https://angular.io/license */ -import {Provider, ɵRuntimeError as RuntimeError} from '@angular/core'; +import {ɵRuntimeError as RuntimeError} from '@angular/core'; import {RuntimeErrorCode} from '../../../errors'; -import {PRECONNECT_CHECK_BLOCKLIST} from '../preconnect_link_checker'; -import {isValidPath, normalizePath, normalizeSrc} from '../util'; +import {normalizeSrc} from '../util'; -import {IMAGE_LOADER, ImageLoaderConfig} from './image_loader'; +import {createImageLoader, ImageLoaderConfig} from './image_loader'; /** * Function that generates a built-in ImageLoader for Cloudinary @@ -29,37 +28,20 @@ import {IMAGE_LOADER, ImageLoaderConfig} from './image_loader'; * present in the document's ``. * @returns Set of providers to configure the Cloudinary loader. */ -export function provideCloudinaryLoader(path: string, options: {ensurePreconnect?: boolean} = { - ensurePreconnect: true -}): Provider[] { - if (ngDevMode && !isValidPath(path)) { - throwInvalidPathError(path); - } - path = normalizePath(path); +export const provideCloudinaryLoader = + createImageLoader(cloudinaryLoaderFactory, throwInvalidPathError); - const providers: Provider[] = [{ - provide: IMAGE_LOADER, - useValue: (config: ImageLoaderConfig) => { - // Example of a Cloudinary image URL: - // https://res.cloudinary.com/mysite/image/upload/c_scale,f_auto,q_auto,w_600/marketing/tile-topics-m.png - let params = `f_auto,q_auto`; // sets image format and quality to "auto" - if (config.width) { - params += `,w_${config.width}`; - } - const url = `${path}/image/upload/${params}/${normalizeSrc(config.src)}`; - return url; +function cloudinaryLoaderFactory(path: string) { + return (config: ImageLoaderConfig) => { + // Example of a Cloudinary image URL: + // https://res.cloudinary.com/mysite/image/upload/c_scale,f_auto,q_auto,w_600/marketing/tile-topics-m.png + let params = `f_auto,q_auto`; // sets image format and quality to "auto" + if (config.width) { + params += `,w_${config.width}`; } - }]; - - if (ngDevMode && Boolean(options.ensurePreconnect) === true) { - providers.push({ - provide: PRECONNECT_CHECK_BLOCKLIST, - useValue: [path], - multi: true, - }); - } - - return providers; + const url = `${path}/image/upload/${params}/${normalizeSrc(config.src)}`; + return url; + }; } function throwInvalidPathError(path: unknown): never { diff --git a/packages/common/src/directives/ng_optimized_image/image_loaders/image_loader.ts b/packages/common/src/directives/ng_optimized_image/image_loaders/image_loader.ts index fba4f28c8c5..47d0ed7d0b8 100644 --- a/packages/common/src/directives/ng_optimized_image/image_loaders/image_loader.ts +++ b/packages/common/src/directives/ng_optimized_image/image_loaders/image_loader.ts @@ -6,7 +6,10 @@ * found in the LICENSE file at https://angular.io/license */ -import {InjectionToken} from '@angular/core'; +import {InjectionToken, Provider} from '@angular/core'; + +import {PRECONNECT_CHECK_BLOCKLIST} from '../preconnect_link_checker'; +import {isValidPath, normalizePath, normalizeSrc} from '../util'; /** * Config options recognized by the image loader function. @@ -37,3 +40,24 @@ export const IMAGE_LOADER = new InjectionToken('ImageLoader', { providedIn: 'root', factory: () => noopImageLoader, }); + +export function createImageLoader( + urlFn: (path: string) => ImageLoader, + invalidPathFn: (path: unknown) => void, +) { + return function provideImageLoader( + path: string, options: {ensurePreconnect?: boolean} = {ensurePreconnect: true}) { + if (ngDevMode && !isValidPath(path)) { + invalidPathFn(path); + } + path = normalizePath(path); + + const providers: Provider[] = [{provide: IMAGE_LOADER, useValue: urlFn(path)}]; + + if (ngDevMode && Boolean(options.ensurePreconnect) === true) { + providers.push({provide: PRECONNECT_CHECK_BLOCKLIST, useValue: [path], multi: true}); + } + + return providers; + }; +} diff --git a/packages/common/src/directives/ng_optimized_image/image_loaders/imagekit_loader.ts b/packages/common/src/directives/ng_optimized_image/image_loaders/imagekit_loader.ts index 323ec462bfb..5e8a421cb79 100644 --- a/packages/common/src/directives/ng_optimized_image/image_loaders/imagekit_loader.ts +++ b/packages/common/src/directives/ng_optimized_image/image_loaders/imagekit_loader.ts @@ -6,13 +6,12 @@ * found in the LICENSE file at https://angular.io/license */ -import {Provider, ɵRuntimeError as RuntimeError} from '@angular/core'; +import {ɵRuntimeError as RuntimeError} from '@angular/core'; import {RuntimeErrorCode} from '../../../errors'; -import {PRECONNECT_CHECK_BLOCKLIST} from '../preconnect_link_checker'; -import {isValidPath, normalizePath, normalizeSrc} from '../util'; +import {normalizeSrc} from '../util'; -import {IMAGE_LOADER, ImageLoaderConfig} from './image_loader'; +import {createImageLoader, ImageLoaderConfig} from './image_loader'; /** * Function that generates a built-in ImageLoader for ImageKit @@ -28,37 +27,20 @@ import {IMAGE_LOADER, ImageLoaderConfig} from './image_loader'; * present in the document's ``. * @returns Set of providers to configure the ImageKit loader. */ -export function provideImageKitLoader(path: string, options: {ensurePreconnect?: boolean} = { - ensurePreconnect: true -}): Provider[] { - if (ngDevMode && !isValidPath(path)) { - throwInvalidPathError(path); - } - path = normalizePath(path); +export const provideImageKitLoader = + createImageLoader(imagekitLoaderFactory, throwInvalidPathError); - const providers: Provider[] = [{ - provide: IMAGE_LOADER, - useValue: (config: ImageLoaderConfig) => { - // Example of an ImageKit image URL: - // https://ik.imagekit.io/demo/tr:w-300,h-300/medium_cafe_B1iTdD0C.jpg - let params = `tr:q-auto`; // applies the "auto quality" transformation - if (config.width) { - params += `,w-${config.width?.toString()}`; - } - const url = `${path}/${params}/${normalizeSrc(config.src)}`; - return url; +export function imagekitLoaderFactory(path: string) { + return (config: ImageLoaderConfig) => { + // Example of an ImageKit image URL: + // https://ik.imagekit.io/demo/tr:w-300,h-300/medium_cafe_B1iTdD0C.jpg + let params = `tr:q-auto`; // applies the "auto quality" transformation + if (config.width) { + params += `,w-${config.width?.toString()}`; } - }]; - - if (ngDevMode && Boolean(options.ensurePreconnect) === true) { - providers.push({ - provide: PRECONNECT_CHECK_BLOCKLIST, - useValue: [path], - multi: true, - }); - } - - return providers; + const url = `${path}/${params}/${normalizeSrc(config.src)}`; + return url; + }; } function throwInvalidPathError(path: unknown): never { diff --git a/packages/common/src/directives/ng_optimized_image/image_loaders/imgix_loader.ts b/packages/common/src/directives/ng_optimized_image/image_loaders/imgix_loader.ts index 9dca13529e8..3957342705e 100644 --- a/packages/common/src/directives/ng_optimized_image/image_loaders/imgix_loader.ts +++ b/packages/common/src/directives/ng_optimized_image/image_loaders/imgix_loader.ts @@ -6,13 +6,12 @@ * found in the LICENSE file at https://angular.io/license */ -import {Provider, ɵRuntimeError as RuntimeError} from '@angular/core'; +import {ɵRuntimeError as RuntimeError} from '@angular/core'; import {RuntimeErrorCode} from '../../../errors'; -import {PRECONNECT_CHECK_BLOCKLIST} from '../preconnect_link_checker'; -import {isValidPath, normalizePath, normalizeSrc} from '../util'; +import {normalizeSrc} from '../util'; -import {IMAGE_LOADER, ImageLoaderConfig} from './image_loader'; +import {createImageLoader, ImageLoaderConfig} from './image_loader'; /** * Function that generates a built-in ImageLoader for Imgix and turns it @@ -26,34 +25,16 @@ import {IMAGE_LOADER, ImageLoaderConfig} from './image_loader'; * present in the document's ``. * @returns Set of providers to configure the Imgix loader. */ -export function provideImgixLoader(path: string, options: {ensurePreconnect?: boolean} = { - ensurePreconnect: true -}): Provider[] { - if (ngDevMode && !isValidPath(path)) { - throwInvalidPathError(path); - } - path = normalizePath(path); +export const provideImgixLoader = createImageLoader(imgixLoaderFactory, throwInvalidPathError); - const providers: Provider[] = [{ - provide: IMAGE_LOADER, - useValue: (config: ImageLoaderConfig) => { - const url = new URL(`${path}/${normalizeSrc(config.src)}`); - // This setting ensures the smallest allowable format is set. - url.searchParams.set('auto', 'format'); - config.width && url.searchParams.set('w', config.width.toString()); - return url.href; - } - }]; - - if (ngDevMode && Boolean(options.ensurePreconnect) === true) { - providers.push({ - provide: PRECONNECT_CHECK_BLOCKLIST, - useValue: [path], - multi: true, - }); - } - - return providers; +function imgixLoaderFactory(path: string) { + return (config: ImageLoaderConfig) => { + const url = new URL(`${path}/${normalizeSrc(config.src)}`); + // This setting ensures the smallest allowable format is set. + url.searchParams.set('auto', 'format'); + config.width && url.searchParams.set('w', config.width.toString()); + return url.href; + }; } function throwInvalidPathError(path: unknown): never {