Skip to content

Commit cefa3de

Browse files
refactor(common): use transform functions in NgOptimizedImage inputs (#50580)
This commit refactors the code of NgOptimizedImage directive to switch from getter/setter approach to convers inputs to use the `transform` function instead. PR Close #50580
1 parent 307f8ee commit cefa3de

File tree

3 files changed

+36
-82
lines changed

3 files changed

+36
-82
lines changed

goldens/public-api/common/index.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -599,36 +599,36 @@ export abstract class NgLocalization {
599599

600600
// @public
601601
export class NgOptimizedImage implements OnInit, OnChanges, OnDestroy {
602-
set disableOptimizedSrcset(value: string | boolean | undefined);
603-
// (undocumented)
604-
get disableOptimizedSrcset(): boolean;
605-
set fill(value: string | boolean | undefined);
606-
// (undocumented)
607-
get fill(): boolean;
608-
set height(value: string | number | undefined);
609-
// (undocumented)
610-
get height(): number | undefined;
602+
disableOptimizedSrcset: boolean;
603+
fill: boolean;
604+
height: number | undefined;
611605
loaderParams?: {
612606
[key: string]: any;
613607
};
614608
loading?: 'lazy' | 'eager' | 'auto';
615609
// (undocumented)
610+
static ngAcceptInputType_disableOptimizedSrcset: unknown;
611+
// (undocumented)
612+
static ngAcceptInputType_fill: unknown;
613+
// (undocumented)
614+
static ngAcceptInputType_height: unknown;
615+
// (undocumented)
616+
static ngAcceptInputType_priority: unknown;
617+
// (undocumented)
618+
static ngAcceptInputType_width: unknown;
619+
// (undocumented)
616620
ngOnChanges(changes: SimpleChanges): void;
617621
// (undocumented)
618622
ngOnDestroy(): void;
619623
// (undocumented)
620624
ngOnInit(): void;
621625
ngSrc: string;
622626
ngSrcset: string;
623-
set priority(value: string | boolean | undefined);
624-
// (undocumented)
625-
get priority(): boolean;
627+
priority: boolean;
626628
sizes?: string;
627-
set width(value: string | number | undefined);
628-
// (undocumented)
629-
get width(): number | undefined;
629+
width: number | undefined;
630630
// (undocumented)
631-
static ɵdir: i0.ɵɵDirectiveDeclaration<NgOptimizedImage, "img[ngSrc]", never, { "ngSrc": { "alias": "ngSrc"; "required": false; }; "ngSrcset": { "alias": "ngSrcset"; "required": false; }; "sizes": { "alias": "sizes"; "required": false; }; "width": { "alias": "width"; "required": false; }; "height": { "alias": "height"; "required": false; }; "loading": { "alias": "loading"; "required": false; }; "priority": { "alias": "priority"; "required": false; }; "loaderParams": { "alias": "loaderParams"; "required": false; }; "disableOptimizedSrcset": { "alias": "disableOptimizedSrcset"; "required": false; }; "fill": { "alias": "fill"; "required": false; }; "src": { "alias": "src"; "required": false; }; "srcset": { "alias": "srcset"; "required": false; }; }, {}, never, never, true, never, false>;
631+
static ɵdir: i0.ɵɵDirectiveDeclaration<NgOptimizedImage, "img[ngSrc]", never, { "ngSrc": { "alias": "ngSrc"; "required": true; }; "ngSrcset": { "alias": "ngSrcset"; "required": false; }; "sizes": { "alias": "sizes"; "required": false; }; "width": { "alias": "width"; "required": false; }; "height": { "alias": "height"; "required": false; }; "loading": { "alias": "loading"; "required": false; }; "priority": { "alias": "priority"; "required": false; }; "loaderParams": { "alias": "loaderParams"; "required": false; }; "disableOptimizedSrcset": { "alias": "disableOptimizedSrcset"; "required": false; }; "fill": { "alias": "fill"; "required": false; }; "src": { "alias": "src"; "required": false; }; "srcset": { "alias": "srcset"; "required": false; }; }, {}, never, never, true, never, false>;
632632
// (undocumented)
633633
static ɵfac: i0.ɵɵFactoryDeclaration<NgOptimizedImage, never>;
634634
}

packages/common/src/directives/ng_optimized_image/ng_optimized_image.ts

Lines changed: 16 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {Directive, ElementRef, inject, InjectionToken, Injector, Input, NgZone, OnChanges, OnDestroy, OnInit, PLATFORM_ID, Renderer2, SimpleChanges, ɵformatRuntimeError as formatRuntimeError, ɵRuntimeError as RuntimeError} from '@angular/core';
9+
import {booleanAttribute, Directive, ElementRef, inject, InjectionToken, Injector, Input, NgZone, numberAttribute, OnChanges, OnDestroy, OnInit, PLATFORM_ID, Renderer2, SimpleChanges, ɵformatRuntimeError as formatRuntimeError, ɵRuntimeError as RuntimeError} from '@angular/core';
1010

1111
import {RuntimeErrorCode} from '../../errors';
1212
import {isPlatformServer} from '../../platform_id';
@@ -247,7 +247,7 @@ export class NgOptimizedImage implements OnInit, OnChanges, OnDestroy {
247247
* Image name will be processed by the image loader and the final URL will be applied as the `src`
248248
* property of the image.
249249
*/
250-
@Input() ngSrc!: string;
250+
@Input({required: true}) ngSrc!: string;
251251

252252
/**
253253
* A comma separated list of width or density descriptors.
@@ -272,30 +272,14 @@ export class NgOptimizedImage implements OnInit, OnChanges, OnDestroy {
272272
* For responsive images: the intrinsic width of the image in pixels.
273273
* For fixed size images: the desired rendered width of the image in pixels.
274274
*/
275-
@Input()
276-
set width(value: string|number|undefined) {
277-
ngDevMode && assertGreaterThanZero(this, value, 'width');
278-
this._width = inputToInteger(value);
279-
}
280-
get width(): number|undefined {
281-
return this._width;
282-
}
283-
private _width?: number;
275+
@Input({transform: numberAttribute}) width: number|undefined;
284276

285277
/**
286278
* For responsive images: the intrinsic height of the image in pixels.
287279
* For fixed size images: the desired rendered height of the image in pixels.* The intrinsic
288280
* height of the image in pixels.
289281
*/
290-
@Input()
291-
set height(value: string|number|undefined) {
292-
ngDevMode && assertGreaterThanZero(this, value, 'height');
293-
this._height = inputToInteger(value);
294-
}
295-
get height(): number|undefined {
296-
return this._height;
297-
}
298-
private _height?: number;
282+
@Input({transform: numberAttribute}) height: number|undefined;
299283

300284
/**
301285
* The desired loading behavior (lazy, eager, or auto).
@@ -308,14 +292,7 @@ export class NgOptimizedImage implements OnInit, OnChanges, OnDestroy {
308292
/**
309293
* Indicates whether this image should have a high priority.
310294
*/
311-
@Input()
312-
set priority(value: string|boolean|undefined) {
313-
this._priority = inputToBoolean(value);
314-
}
315-
get priority(): boolean {
316-
return this._priority;
317-
}
318-
private _priority = false;
295+
@Input({transform: booleanAttribute}) priority = false;
319296

320297
/**
321298
* Data to pass through to custom loaders.
@@ -325,29 +302,15 @@ export class NgOptimizedImage implements OnInit, OnChanges, OnDestroy {
325302
/**
326303
* Disables automatic srcset generation for this image.
327304
*/
328-
@Input()
329-
set disableOptimizedSrcset(value: string|boolean|undefined) {
330-
this._disableOptimizedSrcset = inputToBoolean(value);
331-
}
332-
get disableOptimizedSrcset(): boolean {
333-
return this._disableOptimizedSrcset;
334-
}
335-
private _disableOptimizedSrcset = false;
305+
@Input({transform: booleanAttribute}) disableOptimizedSrcset = false;
336306

337307
/**
338308
* Sets the image to "fill mode", which eliminates the height/width requirement and adds
339309
* styles such that the image fills its containing element.
340310
*
341311
* @developerPreview
342312
*/
343-
@Input()
344-
set fill(value: string|boolean|undefined) {
345-
this._fill = inputToBoolean(value);
346-
}
347-
get fill(): boolean {
348-
return this._fill;
349-
}
350-
private _fill = false;
313+
@Input({transform: booleanAttribute}) fill = false;
351314

352315
/**
353316
* Value of the `src` attribute if set on the host `<img>` element.
@@ -381,6 +344,12 @@ export class NgOptimizedImage implements OnInit, OnChanges, OnDestroy {
381344
assertNonZeroRenderedHeight(this, this.imgElement, this.renderer);
382345
} else {
383346
assertNonEmptyWidthAndHeight(this);
347+
if (this.height !== undefined) {
348+
assertGreaterThanZero(this, this.height, 'height');
349+
}
350+
if (this.width !== undefined) {
351+
assertGreaterThanZero(this, this.width, 'width');
352+
}
384353
// Only check for distorted images when not in fill mode, where
385354
// images may be intentionally stretched, cropped or letterboxed.
386355
assertNoImageDistortion(this, this.imgElement, this.renderer);
@@ -548,7 +517,7 @@ export class NgOptimizedImage implements OnInit, OnChanges, OnDestroy {
548517
}
549518

550519
private shouldGenerateAutomaticSrcset(): boolean {
551-
return !this._disableOptimizedSrcset && !this.srcset && this.imageLoader !== noopImageLoader &&
520+
return !this.disableOptimizedSrcset && !this.srcset && this.imageLoader !== noopImageLoader &&
552521
!(this.width! > FIXED_SRCSET_WIDTH_LIMIT || this.height! > FIXED_SRCSET_HEIGHT_LIMIT);
553522
}
554523

@@ -568,20 +537,6 @@ export class NgOptimizedImage implements OnInit, OnChanges, OnDestroy {
568537

569538
/***** Helpers *****/
570539

571-
/**
572-
* Convert input value to integer.
573-
*/
574-
function inputToInteger(value: string|number|undefined): number|undefined {
575-
return typeof value === 'string' ? parseInt(value, 10) : value;
576-
}
577-
578-
/**
579-
* Convert input value to boolean.
580-
*/
581-
function inputToBoolean(value: unknown): boolean {
582-
return value != null && `${value}` !== 'false';
583-
}
584-
585540
/**
586541
* Sorts provided config breakpoints and uses defaults.
587542
*/
@@ -778,9 +733,8 @@ function assertGreaterThanZero(dir: NgOptimizedImage, inputValue: unknown, input
778733
if (!validNumber && !validString) {
779734
throw new RuntimeError(
780735
RuntimeErrorCode.INVALID_INPUT,
781-
`${imgDirectiveDetails(dir.ngSrc)} \`${inputName}\` has an invalid value ` +
782-
`(\`${inputValue}\`). To fix this, provide \`${inputName}\` ` +
783-
`as a number greater than 0.`);
736+
`${imgDirectiveDetails(dir.ngSrc)} \`${inputName}\` has an invalid value. ` +
737+
`To fix this, provide \`${inputName}\` as a number greater than 0.`);
784738
}
785739
}
786740

packages/common/test/directives/ng_optimized_image_spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ describe('Image directive', () => {
377377
.toThrowError(
378378
'NG02952: The NgOptimizedImage directive (activated on an <img> ' +
379379
'element with the `ngSrc="img.png"`) has detected that `width` ' +
380-
'has an invalid value (`0`). To fix this, provide `width` as ' +
380+
'has an invalid value. To fix this, provide `width` as ' +
381381
'a number greater than 0.');
382382
});
383383

@@ -392,7 +392,7 @@ describe('Image directive', () => {
392392
.toThrowError(
393393
'NG02952: The NgOptimizedImage directive (activated on an <img> ' +
394394
'element with the `ngSrc="img.png"`) has detected that `width` ' +
395-
'has an invalid value (`10px`). To fix this, provide `width` ' +
395+
'has an invalid value. To fix this, provide `width` ' +
396396
'as a number greater than 0.');
397397
});
398398

@@ -424,7 +424,7 @@ describe('Image directive', () => {
424424
.toThrowError(
425425
'NG02952: The NgOptimizedImage directive (activated on an <img> ' +
426426
'element with the `ngSrc="img.png"`) has detected that `height` ' +
427-
'has an invalid value (`0`). To fix this, provide `height` as a number ' +
427+
'has an invalid value. To fix this, provide `height` as a number ' +
428428
'greater than 0.');
429429
});
430430

@@ -439,7 +439,7 @@ describe('Image directive', () => {
439439
.toThrowError(
440440
'NG02952: The NgOptimizedImage directive (activated on an <img> element ' +
441441
'with the `ngSrc="img.png"`) has detected that `height` has an invalid ' +
442-
'value (`10%`). To fix this, provide `height` as a number greater than 0.');
442+
'value. To fix this, provide `height` as a number greater than 0.');
443443
});
444444

445445
it('should throw if `ngSrc` value is not provided', () => {

0 commit comments

Comments
 (0)