UNPKG

@angular/common

Version:

Angular - commonly needed directives and services

74 lines 12.5 kB
/** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import { InjectionToken, ɵRuntimeError as RuntimeError } from '@angular/core'; import { isAbsoluteUrl, isValidPath, normalizePath, normalizeSrc } from '../url'; /** * Noop image loader that does no transformation to the original src and just returns it as is. * This loader is used as a default one if more specific logic is not provided in an app config. * * @see {@link ImageLoader} * @see {@link NgOptimizedImage} */ export const noopImageLoader = (config) => config.src; /** * Injection token that configures the image loader function. * * @see {@link ImageLoader} * @see {@link NgOptimizedImage} * @publicApi */ export const IMAGE_LOADER = new InjectionToken(ngDevMode ? 'ImageLoader' : '', { providedIn: 'root', factory: () => noopImageLoader, }); /** * Internal helper function that makes it easier to introduce custom image loaders for the * `NgOptimizedImage` directive. It is enough to specify a URL builder function to obtain full DI * configuration for a given loader: a DI token corresponding to the actual loader function, plus DI * tokens managing preconnect check functionality. * @param buildUrlFn a function returning a full URL based on loader's configuration * @param exampleUrls example of full URLs for a given loader (used in error messages) * @returns a set of DI providers corresponding to the configured image loader */ export function createImageLoader(buildUrlFn, exampleUrls) { return function provideImageLoader(path) { if (!isValidPath(path)) { throwInvalidPathError(path, exampleUrls || []); } // The trailing / is stripped (if provided) to make URL construction (concatenation) easier in // the individual loader functions. path = normalizePath(path); const loaderFn = (config) => { if (isAbsoluteUrl(config.src)) { // Image loader functions expect an image file name (e.g. `my-image.png`) // or a relative path + a file name (e.g. `/a/b/c/my-image.png`) as an input, // so the final absolute URL can be constructed. // When an absolute URL is provided instead - the loader can not // build a final URL, thus the error is thrown to indicate that. throwUnexpectedAbsoluteUrlError(path, config.src); } return buildUrlFn(path, { ...config, src: normalizeSrc(config.src) }); }; const providers = [{ provide: IMAGE_LOADER, useValue: loaderFn }]; return providers; }; } function throwInvalidPathError(path, exampleUrls) { throw new RuntimeError(2959 /* RuntimeErrorCode.INVALID_LOADER_ARGUMENTS */, ngDevMode && `Image loader has detected an invalid path (\`${path}\`). ` + `To fix this, supply a path using one of the following formats: ${exampleUrls.join(' or ')}`); } function throwUnexpectedAbsoluteUrlError(path, url) { throw new RuntimeError(2959 /* RuntimeErrorCode.INVALID_LOADER_ARGUMENTS */, ngDevMode && `Image loader has detected a \`<img>\` tag with an invalid \`ngSrc\` attribute: ${url}. ` + `This image loader expects \`ngSrc\` to be a relative URL - ` + `however the provided value is an absolute URL. ` + `To fix this, provide \`ngSrc\` as a path relative to the base URL ` + `configured for this loader (\`${path}\`).`); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2VfbG9hZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tbW9uL3NyYy9kaXJlY3RpdmVzL25nX29wdGltaXplZF9pbWFnZS9pbWFnZV9sb2FkZXJzL2ltYWdlX2xvYWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSCxPQUFPLEVBQUMsY0FBYyxFQUFZLGFBQWEsSUFBSSxZQUFZLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFHdEYsT0FBTyxFQUFDLGFBQWEsRUFBRSxXQUFXLEVBQUUsYUFBYSxFQUFFLFlBQVksRUFBQyxNQUFNLFFBQVEsQ0FBQztBQXFDL0U7Ozs7OztHQU1HO0FBQ0gsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUFHLENBQUMsTUFBeUIsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQztBQVV6RTs7Ozs7O0dBTUc7QUFDSCxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUcsSUFBSSxjQUFjLENBQWMsU0FBUyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtJQUMxRixVQUFVLEVBQUUsTUFBTTtJQUNsQixPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsZUFBZTtDQUMvQixDQUFDLENBQUM7QUFFSDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sVUFBVSxpQkFBaUIsQ0FDL0IsVUFBK0QsRUFDL0QsV0FBc0I7SUFFdEIsT0FBTyxTQUFTLGtCQUFrQixDQUFDLElBQVk7UUFDN0MsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ3ZCLHFCQUFxQixDQUFDLElBQUksRUFBRSxXQUFXLElBQUksRUFBRSxDQUFDLENBQUM7UUFDakQsQ0FBQztRQUVELDhGQUE4RjtRQUM5RixtQ0FBbUM7UUFDbkMsSUFBSSxHQUFHLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUUzQixNQUFNLFFBQVEsR0FBRyxDQUFDLE1BQXlCLEVBQUUsRUFBRTtZQUM3QyxJQUFJLGFBQWEsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDOUIseUVBQXlFO2dCQUN6RSw2RUFBNkU7Z0JBQzdFLGdEQUFnRDtnQkFDaEQsZ0VBQWdFO2dCQUNoRSxnRUFBZ0U7Z0JBQ2hFLCtCQUErQixDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDcEQsQ0FBQztZQUVELE9BQU8sVUFBVSxDQUFDLElBQUksRUFBRSxFQUFDLEdBQUcsTUFBTSxFQUFFLEdBQUcsRUFBRSxZQUFZLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFDLENBQUMsQ0FBQztRQUN0RSxDQUFDLENBQUM7UUFFRixNQUFNLFNBQVMsR0FBZSxDQUFDLEVBQUMsT0FBTyxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFDLENBQUMsQ0FBQztRQUM1RSxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDLENBQUM7QUFDSixDQUFDO0FBRUQsU0FBUyxxQkFBcUIsQ0FBQyxJQUFhLEVBQUUsV0FBcUI7SUFDakUsTUFBTSxJQUFJLFlBQVksdURBRXBCLFNBQVM7UUFDUCxnREFBZ0QsSUFBSSxPQUFPO1lBQ3pELGtFQUFrRSxXQUFXLENBQUMsSUFBSSxDQUNoRixNQUFNLENBQ1AsRUFBRSxDQUNSLENBQUM7QUFDSixDQUFDO0FBRUQsU0FBUywrQkFBK0IsQ0FBQyxJQUFZLEVBQUUsR0FBVztJQUNoRSxNQUFNLElBQUksWUFBWSx1REFFcEIsU0FBUztRQUNQLGtGQUFrRixHQUFHLElBQUk7WUFDdkYsNkRBQTZEO1lBQzdELGlEQUFpRDtZQUNqRCxvRUFBb0U7WUFDcEUsaUNBQWlDLElBQUksTUFBTSxDQUNoRCxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge0luamVjdGlvblRva2VuLCBQcm92aWRlciwgybVSdW50aW1lRXJyb3IgYXMgUnVudGltZUVycm9yfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHtSdW50aW1lRXJyb3JDb2RlfSBmcm9tICcuLi8uLi8uLi9lcnJvcnMnO1xuaW1wb3J0IHtpc0Fic29sdXRlVXJsLCBpc1ZhbGlkUGF0aCwgbm9ybWFsaXplUGF0aCwgbm9ybWFsaXplU3JjfSBmcm9tICcuLi91cmwnO1xuXG4vKipcbiAqIENvbmZpZyBvcHRpb25zIHJlY29nbml6ZWQgYnkgdGhlIGltYWdlIGxvYWRlciBmdW5jdGlvbi5cbiAqXG4gKiBAc2VlIHtAbGluayBJbWFnZUxvYWRlcn1cbiAqIEBzZWUge0BsaW5rIE5nT3B0aW1pemVkSW1hZ2V9XG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSW1hZ2VMb2FkZXJDb25maWcge1xuICAvKipcbiAgICogSW1hZ2UgZmlsZSBuYW1lIHRvIGJlIGFkZGVkIHRvIHRoZSBpbWFnZSByZXF1ZXN0IFVSTC5cbiAgICovXG4gIHNyYzogc3RyaW5nO1xuICAvKipcbiAgICogV2lkdGggb2YgdGhlIHJlcXVlc3RlZCBpbWFnZSAodG8gYmUgdXNlZCB3aGVuIGdlbmVyYXRpbmcgc3Jjc2V0KS5cbiAgICovXG4gIHdpZHRoPzogbnVtYmVyO1xuICAvKipcbiAgICogV2hldGhlciB0aGUgbG9hZGVyIHNob3VsZCBnZW5lcmF0ZSBhIFVSTCBmb3IgYSBzbWFsbCBpbWFnZSBwbGFjZWhvbGRlciBpbnN0ZWFkIG9mIGEgZnVsbC1zaXplZFxuICAgKiBpbWFnZS5cbiAgICovXG4gIGlzUGxhY2Vob2xkZXI/OiBib29sZWFuO1xuICAvKipcbiAgICogQWRkaXRpb25hbCB1c2VyLXByb3ZpZGVkIHBhcmFtZXRlcnMgZm9yIHVzZSBieSB0aGUgSW1hZ2VMb2FkZXIuXG4gICAqL1xuICBsb2FkZXJQYXJhbXM/OiB7W2tleTogc3RyaW5nXTogYW55fTtcbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIGFuIGltYWdlIGxvYWRlciBmdW5jdGlvbi4gSW1hZ2UgbG9hZGVyIGZ1bmN0aW9ucyBhcmUgdXNlZCBieSB0aGVcbiAqIE5nT3B0aW1pemVkSW1hZ2UgZGlyZWN0aXZlIHRvIHByb2R1Y2UgZnVsbCBpbWFnZSBVUkwgYmFzZWQgb24gdGhlIGltYWdlIG5hbWUgYW5kIGl0cyB3aWR0aC5cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCB0eXBlIEltYWdlTG9hZGVyID0gKGNvbmZpZzogSW1hZ2VMb2FkZXJDb25maWcpID0+IHN0cmluZztcblxuLyoqXG4gKiBOb29wIGltYWdlIGxvYWRlciB0aGF0IGRvZXMgbm8gdHJhbnNmb3JtYXRpb24gdG8gdGhlIG9yaWdpbmFsIHNyYyBhbmQganVzdCByZXR1cm5zIGl0IGFzIGlzLlxuICogVGhpcyBsb2FkZXIgaXMgdXNlZCBhcyBhIGRlZmF1bHQgb25lIGlmIG1vcmUgc3BlY2lmaWMgbG9naWMgaXMgbm90IHByb3ZpZGVkIGluIGFuIGFwcCBjb25maWcuXG4gKlxuICogQHNlZSB7QGxpbmsgSW1hZ2VMb2FkZXJ9XG4gKiBAc2VlIHtAbGluayBOZ09wdGltaXplZEltYWdlfVxuICovXG5leHBvcnQgY29uc3Qgbm9vcEltYWdlTG9hZGVyID0gKGNvbmZpZzogSW1hZ2VMb2FkZXJDb25maWcpID0+IGNvbmZpZy5zcmM7XG5cbi8qKlxuICogTWV0YWRhdGEgYWJvdXQgdGhlIGltYWdlIGxvYWRlci5cbiAqL1xuZXhwb3J0IHR5cGUgSW1hZ2VMb2FkZXJJbmZvID0ge1xuICBuYW1lOiBzdHJpbmc7XG4gIHRlc3RVcmw6ICh1cmw6IHN0cmluZykgPT4gYm9vbGVhbjtcbn07XG5cbi8qKlxuICogSW5qZWN0aW9uIHRva2VuIHRoYXQgY29uZmlndXJlcyB0aGUgaW1hZ2UgbG9hZGVyIGZ1bmN0aW9uLlxuICpcbiAqIEBzZWUge0BsaW5rIEltYWdlTG9hZGVyfVxuICogQHNlZSB7QGxpbmsgTmdPcHRpbWl6ZWRJbWFnZX1cbiAqIEBwdWJsaWNBcGlcbiAqL1xuZXhwb3J0IGNvbnN0IElNQUdFX0xPQURFUiA9IG5ldyBJbmplY3Rpb25Ub2tlbjxJbWFnZUxvYWRlcj4obmdEZXZNb2RlID8gJ0ltYWdlTG9hZGVyJyA6ICcnLCB7XG4gIHByb3ZpZGVkSW46ICdyb290JyxcbiAgZmFjdG9yeTogKCkgPT4gbm9vcEltYWdlTG9hZGVyLFxufSk7XG5cbi8qKlxuICogSW50ZXJuYWwgaGVscGVyIGZ1bmN0aW9uIHRoYXQgbWFrZXMgaXQgZWFzaWVyIHRvIGludHJvZHVjZSBjdXN0b20gaW1hZ2UgbG9hZGVycyBmb3IgdGhlXG4gKiBgTmdPcHRpbWl6ZWRJbWFnZWAgZGlyZWN0aXZlLiBJdCBpcyBlbm91Z2ggdG8gc3BlY2lmeSBhIFVSTCBidWlsZGVyIGZ1bmN0aW9uIHRvIG9idGFpbiBmdWxsIERJXG4gKiBjb25maWd1cmF0aW9uIGZvciBhIGdpdmVuIGxvYWRlcjogYSBESSB0b2tlbiBjb3JyZXNwb25kaW5nIHRvIHRoZSBhY3R1YWwgbG9hZGVyIGZ1bmN0aW9uLCBwbHVzIERJXG4gKiB0b2tlbnMgbWFuYWdpbmcgcHJlY29ubmVjdCBjaGVjayBmdW5jdGlvbmFsaXR5LlxuICogQHBhcmFtIGJ1aWxkVXJsRm4gYSBmdW5jdGlvbiByZXR1cm5pbmcgYSBmdWxsIFVSTCBiYXNlZCBvbiBsb2FkZXIncyBjb25maWd1cmF0aW9uXG4gKiBAcGFyYW0gZXhhbXBsZVVybHMgZXhhbXBsZSBvZiBmdWxsIFVSTHMgZm9yIGEgZ2l2ZW4gbG9hZGVyICh1c2VkIGluIGVycm9yIG1lc3NhZ2VzKVxuICogQHJldHVybnMgYSBzZXQgb2YgREkgcHJvdmlkZXJzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGNvbmZpZ3VyZWQgaW1hZ2UgbG9hZGVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVJbWFnZUxvYWRlcihcbiAgYnVpbGRVcmxGbjogKHBhdGg6IHN0cmluZywgY29uZmlnOiBJbWFnZUxvYWRlckNvbmZpZykgPT4gc3RyaW5nLFxuICBleGFtcGxlVXJscz86IHN0cmluZ1tdLFxuKSB7XG4gIHJldHVybiBmdW5jdGlvbiBwcm92aWRlSW1hZ2VMb2FkZXIocGF0aDogc3RyaW5nKSB7XG4gICAgaWYgKCFpc1ZhbGlkUGF0aChwYXRoKSkge1xuICAgICAgdGhyb3dJbnZhbGlkUGF0aEVycm9yKHBhdGgsIGV4YW1wbGVVcmxzIHx8IFtdKTtcbiAgICB9XG5cbiAgICAvLyBUaGUgdHJhaWxpbmcgLyBpcyBzdHJpcHBlZCAoaWYgcHJvdmlkZWQpIHRvIG1ha2UgVVJMIGNvbnN0cnVjdGlvbiAoY29uY2F0ZW5hdGlvbikgZWFzaWVyIGluXG4gICAgLy8gdGhlIGluZGl2aWR1YWwgbG9hZGVyIGZ1bmN0aW9ucy5cbiAgICBwYXRoID0gbm9ybWFsaXplUGF0aChwYXRoKTtcblxuICAgIGNvbnN0IGxvYWRlckZuID0gKGNvbmZpZzogSW1hZ2VMb2FkZXJDb25maWcpID0+IHtcbiAgICAgIGlmIChpc0Fic29sdXRlVXJsKGNvbmZpZy5zcmMpKSB7XG4gICAgICAgIC8vIEltYWdlIGxvYWRlciBmdW5jdGlvbnMgZXhwZWN0IGFuIGltYWdlIGZpbGUgbmFtZSAoZS5nLiBgbXktaW1hZ2UucG5nYClcbiAgICAgICAgLy8gb3IgYSByZWxhdGl2ZSBwYXRoICsgYSBmaWxlIG5hbWUgKGUuZy4gYC9hL2IvYy9teS1pbWFnZS5wbmdgKSBhcyBhbiBpbnB1dCxcbiAgICAgICAgLy8gc28gdGhlIGZpbmFsIGFic29sdXRlIFVSTCBjYW4gYmUgY29uc3RydWN0ZWQuXG4gICAgICAgIC8vIFdoZW4gYW4gYWJzb2x1dGUgVVJMIGlzIHByb3ZpZGVkIGluc3RlYWQgLSB0aGUgbG9hZGVyIGNhbiBub3RcbiAgICAgICAgLy8gYnVpbGQgYSBmaW5hbCBVUkwsIHRodXMgdGhlIGVycm9yIGlzIHRocm93biB0byBpbmRpY2F0ZSB0aGF0LlxuICAgICAgICB0aHJvd1VuZXhwZWN0ZWRBYnNvbHV0ZVVybEVycm9yKHBhdGgsIGNvbmZpZy5zcmMpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYnVpbGRVcmxGbihwYXRoLCB7Li4uY29uZmlnLCBzcmM6IG5vcm1hbGl6ZVNyYyhjb25maWcuc3JjKX0pO1xuICAgIH07XG5cbiAgICBjb25zdCBwcm92aWRlcnM6IFByb3ZpZGVyW10gPSBbe3Byb3ZpZGU6IElNQUdFX0xPQURFUiwgdXNlVmFsdWU6IGxvYWRlckZufV07XG4gICAgcmV0dXJuIHByb3ZpZGVycztcbiAgfTtcbn1cblxuZnVuY3Rpb24gdGhyb3dJbnZhbGlkUGF0aEVycm9yKHBhdGg6IHVua25vd24sIGV4YW1wbGVVcmxzOiBzdHJpbmdbXSk6IG5ldmVyIHtcbiAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcihcbiAgICBSdW50aW1lRXJyb3JDb2RlLklOVkFMSURfTE9BREVSX0FSR1VNRU5UUyxcbiAgICBuZ0Rldk1vZGUgJiZcbiAgICAgIGBJbWFnZSBsb2FkZXIgaGFzIGRldGVjdGVkIGFuIGludmFsaWQgcGF0aCAoXFxgJHtwYXRofVxcYCkuIGAgK1xuICAgICAgICBgVG8gZml4IHRoaXMsIHN1cHBseSBhIHBhdGggdXNpbmcgb25lIG9mIHRoZSBmb2xsb3dpbmcgZm9ybWF0czogJHtleGFtcGxlVXJscy5qb2luKFxuICAgICAgICAgICcgb3IgJyxcbiAgICAgICAgKX1gLFxuICApO1xufVxuXG5mdW5jdGlvbiB0aHJvd1VuZXhwZWN0ZWRBYnNvbHV0ZVVybEVycm9yKHBhdGg6IHN0cmluZywgdXJsOiBzdHJpbmcpOiBuZXZlciB7XG4gIHRocm93IG5ldyBSdW50aW1lRXJyb3IoXG4gICAgUnVudGltZUVycm9yQ29kZS5JTlZBTElEX0xPQURFUl9BUkdVTUVOVFMsXG4gICAgbmdEZXZNb2RlICYmXG4gICAgICBgSW1hZ2UgbG9hZGVyIGhhcyBkZXRlY3RlZCBhIFxcYDxpbWc+XFxgIHRhZyB3aXRoIGFuIGludmFsaWQgXFxgbmdTcmNcXGAgYXR0cmlidXRlOiAke3VybH0uIGAgK1xuICAgICAgICBgVGhpcyBpbWFnZSBsb2FkZXIgZXhwZWN0cyBcXGBuZ1NyY1xcYCB0byBiZSBhIHJlbGF0aXZlIFVSTCAtIGAgK1xuICAgICAgICBgaG93ZXZlciB0aGUgcHJvdmlkZWQgdmFsdWUgaXMgYW4gYWJzb2x1dGUgVVJMLiBgICtcbiAgICAgICAgYFRvIGZpeCB0aGlzLCBwcm92aWRlIFxcYG5nU3JjXFxgIGFzIGEgcGF0aCByZWxhdGl2ZSB0byB0aGUgYmFzZSBVUkwgYCArXG4gICAgICAgIGBjb25maWd1cmVkIGZvciB0aGlzIGxvYWRlciAoXFxgJHtwYXRofVxcYCkuYCxcbiAgKTtcbn1cbiJdfQ==