diff --git a/example/src/app/pages/onload.component.ts b/example/src/app/pages/onload.component.ts index 3fd19cc..5c490db 100644 --- a/example/src/app/pages/onload.component.ts +++ b/example/src/app/pages/onload.component.ts @@ -31,7 +31,7 @@ export class OnLoadComponent { constructor(private cd: ChangeDetectorRef) {} - onLoadImage(success) { + onLoadImage(success: boolean) { if (success) { this.isLoading = false; this.cd.detectChanges(); diff --git a/example/src/app/pages/scroll-container.component.ts b/example/src/app/pages/scroll-container.component.ts index 83ede2b..4ef242b 100644 --- a/example/src/app/pages/scroll-container.component.ts +++ b/example/src/app/pages/scroll-container.component.ts @@ -49,7 +49,7 @@ import { Component, ChangeDetectionStrategy, ElementRef } from '@angular/core'; changeDetection: ChangeDetectionStrategy.OnPush }) export class ScrollContainerComponent { - myScrollContainer; + myScrollContainer!: HTMLElement; images = [ 'https://images.unsplash.com/photo-1467932760935-519284fc87fa?dpr=2&auto=compress,format&fit=crop&w=1199&h=800&q=80', 'https://images.unsplash.com/photo-1468103933896-2c34a78104c2?dpr=2&auto=compress,format&fit=crop&w=1199&h=799&q=80', diff --git a/src/hooks-factory.ts b/src/hooks-factory.ts index 1c49b3c..9c08a11 100644 --- a/src/hooks-factory.ts +++ b/src/hooks-factory.ts @@ -2,19 +2,19 @@ import { scrollPreset } from './scroll-preset'; import { HookSet, ModuleOptions } from './types'; export function cretateHooks(options?: ModuleOptions): HookSet { - if (!options) { - return scrollPreset; - } - const hooks = {}; - if (options.preset) { - Object.assign(hooks, options.preset); - } else { - Object.assign(hooks, scrollPreset); - } - Object.keys(options) - .filter(key => key !== 'preset') - .forEach(key => { - hooks[key] = options[key]; - }); - return hooks as HookSet; + if (!options) { + return scrollPreset; + } + const hooks = {}; + if (options.preset) { + Object.assign(hooks, options.preset); + } else { + Object.assign(hooks, scrollPreset); + } + Object.keys(options) + .filter(key => key !== 'preset') + .forEach(key => { + hooks[key] = options[key]; + }); + return hooks as HookSet; } diff --git a/src/intersection-observer-preset/index.ts b/src/intersection-observer-preset/index.ts index 9eb8d5f..12bbc34 100644 --- a/src/intersection-observer-preset/index.ts +++ b/src/intersection-observer-preset/index.ts @@ -1 +1 @@ -export { intersectionObserverPreset } from './preset' +export { intersectionObserverPreset } from './preset'; diff --git a/src/intersection-observer-preset/intersection-listener.ts b/src/intersection-observer-preset/intersection-listener.ts index 68e84ec..7b713b6 100644 --- a/src/intersection-observer-preset/intersection-listener.ts +++ b/src/intersection-observer-preset/intersection-listener.ts @@ -16,7 +16,7 @@ function loadingCallback(entrys: IntersectionObserverEntry[]) { entrys.forEach(entry => intersectionSubject.next(entry)); } -export const getIntersectionObserver = (attributes: Attributes) => { +export const getIntersectionObserver = (attributes: Attributes): Observable => { if (!attributes.scrollContainer && !isWindowDefined()) { return empty(); } @@ -39,11 +39,11 @@ export const getIntersectionObserver = (attributes: Attributes) => { observer.observe(attributes.element); - return Observable.create(obs => { + return Observable.create((obs: Subject) => { const subscription = intersectionSubject.pipe(filter(entry => entry.target === attributes.element)).subscribe(obs); return () => { subscription.unsubscribe(); - observer.unobserve(attributes.element); + observer!.unobserve(attributes.element); }; }); }; diff --git a/src/lazyload-image.directive.ts b/src/lazyload-image.directive.ts index 2d67e7d..9e477f1 100644 --- a/src/lazyload-image.directive.ts +++ b/src/lazyload-image.directive.ts @@ -1,17 +1,5 @@ -import { - AfterContentInit, - Directive, - ElementRef, - EventEmitter, - Inject, - Input, - NgZone, - OnChanges, - OnDestroy, - Optional, - Output -} from '@angular/core'; -import { ReplaySubject } from 'rxjs'; +import { AfterContentInit, Directive, ElementRef, EventEmitter, Inject, Input, NgZone, OnChanges, OnDestroy, Optional, Output } from '@angular/core'; +import { ReplaySubject, Observable, Subscription } from 'rxjs'; import { switchMap, tap } from 'rxjs/operators'; import { cretateHooks } from './hooks-factory'; import { lazyLoadImage } from './lazyload-image'; @@ -19,21 +7,21 @@ import { Attributes, HookSet, ModuleOptions } from './types'; import { isWindowDefined } from './util'; @Directive({ - selector: '[lazyLoad]' + selector: '[lazyLoad]' }) export class LazyLoadImageDirective implements OnChanges, AfterContentInit, OnDestroy { - @Input('lazyLoad') lazyImage; // The image to be lazy loaded - @Input() defaultImage: string; // The image to be displayed before lazyImage is loaded - @Input() errorImage: string; // The image to be displayed if lazyImage load fails - @Input() scrollTarget: any; // Scroll container that contains the image and emits scoll events - @Input() scrollObservable; // Pass your own scroll emitter - @Input() offset: number; // The number of px a image should be loaded before it is in view port - @Input() useSrcset: boolean; // Whether srcset attribute should be used instead of src + @Input('lazyLoad') lazyImage!: string; // The image to be lazy loaded + @Input() defaultImage?: string; // The image to be displayed before lazyImage is loaded + @Input() errorImage?: string; // The image to be displayed if lazyImage load fails + @Input() scrollTarget?: any; // Scroll container that contains the image and emits scoll events + @Input() scrollObservable?: Observable; // Pass your own scroll emitter + @Input() offset?: number; // The number of px a image should be loaded before it is in view port + @Input() useSrcset?: boolean; // Whether srcset attribute should be used instead of src @Output() onLoad: EventEmitter = new EventEmitter(); // Callback when an image is loaded private propertyChanges$: ReplaySubject; private elementRef: ElementRef; private ngZone: NgZone; - private scrollSubscription; + private scrollSubscription?: Subscription; private hooks: HookSet; constructor(el: ElementRef, ngZone: NgZone, @Optional() @Inject('options') options?: ModuleOptions) { @@ -50,7 +38,7 @@ export class LazyLoadImageDirective implements OnChanges, AfterContentInit, OnDe defaultImagePath: this.defaultImage, errorImagePath: this.errorImage, useSrcset: this.useSrcset, - offset: this.offset | 0, + offset: this.offset ? this.offset | 0 : 0, scrollContainer: this.scrollTarget, scrollObservable: this.scrollObservable }); @@ -63,16 +51,18 @@ export class LazyLoadImageDirective implements OnChanges, AfterContentInit, OnDe } this.ngZone.runOutsideAngular(() => { - this.scrollSubscription = this.propertyChanges$.pipe( - tap(attributes => this.hooks.setup(attributes)), - switchMap(attributes => this.hooks.getObservable(attributes).pipe(lazyLoadImage(this.hooks, attributes))) - ).subscribe(success => this.onLoad.emit(success)); + this.scrollSubscription = this.propertyChanges$ + .pipe( + tap(attributes => this.hooks.setup(attributes)), + switchMap(attributes => this.hooks.getObservable(attributes).pipe(lazyLoadImage(this.hooks, attributes))) + ) + .subscribe(success => this.onLoad.emit(success)); }); } ngOnDestroy() { - [this.scrollSubscription] - .filter(subscription => subscription && !subscription.isUnsubscribed) - .forEach(subscription => subscription.unsubscribe()); + if (this.scrollSubscription) { + this.scrollSubscription.unsubscribe(); + } } } diff --git a/src/scroll-preset/__test__/preset.test.ts b/src/scroll-preset/__test__/preset.test.ts index e79301a..466acba 100644 --- a/src/scroll-preset/__test__/preset.test.ts +++ b/src/scroll-preset/__test__/preset.test.ts @@ -18,7 +18,7 @@ describe('isVisible', () => { it('Should be vissible when top is inside viewport and no offset', () => { const attribute = { - event: undefined, + event: undefined as any, element: generateElement(999, 100), offset: 0 }; @@ -30,7 +30,7 @@ describe('isVisible', () => { it('Should not be vissible when the image is outside viewport', () => { const attribute = { - event: undefined, + event: undefined as any, element: generateElement(1001, 100), offset: 0 }; @@ -42,7 +42,7 @@ describe('isVisible', () => { it('Should be vissible when the image is outside viewport but have a offset', () => { const attribute = { - event: undefined, + event: undefined as any, element: generateElement(-399, 100), offset: 100 }; @@ -54,7 +54,7 @@ describe('isVisible', () => { it('Should not be vissible when the image is inside viewport but have a offset', () => { const attribute = { - event: undefined, + event: undefined as any, element: generateElement(901, 100), offset: -100 }; @@ -65,7 +65,7 @@ describe('isVisible', () => { it('Should be vissible when the image is inside viewport and have a offset', () => { const attribute = { - event: undefined, + event: undefined as any, element: generateElement(899, 100), offset: -100 }; @@ -77,7 +77,7 @@ describe('isVisible', () => { it('Should not be vissible when the bottom of the image is inside viewport but have a offset', () => { const attribute = { - event: undefined, + event: undefined as any, element: generateElement(-201, 100), offset: -100 }; @@ -89,7 +89,7 @@ describe('isVisible', () => { it('Should be vissible when the bottom of the image is inside viewport and have a offset', () => { const attribute = { - event: undefined, + event: undefined as any, element: generateElement(-199, 100), offset: -100 }; @@ -100,7 +100,7 @@ describe('isVisible', () => { it('Should be vissible when the image is larger than the viewport', () => { const attribute = { - event: undefined, + event: undefined as any, element: generateElement(-100, -100, 1200, 1200), offset: 0 }; @@ -111,7 +111,7 @@ describe('isVisible', () => { it('Should not be vissible when the image is to the left of the viewport', () => { const attribute = { - event: undefined, + event: undefined as any, element: generateElement(100, -301), offset: 0 }; @@ -122,7 +122,7 @@ describe('isVisible', () => { it('Should not be vissible when the image is to the right of the viewport', () => { const attribute = { - event: undefined, + event: undefined as any, element: generateElement(100, 1001), offset: 0 }; @@ -133,7 +133,7 @@ describe('isVisible', () => { it('Should be vissible when the left side is in viewport', () => { const attribute = { - event: undefined, + event: undefined as any, element: generateElement(200, 899), offset: -100 }; @@ -144,7 +144,7 @@ describe('isVisible', () => { it('Should be vissible when the right side is in viewport', () => { const attribute = { - event: undefined, + event: undefined as any, element: generateElement(200, -199), offset: -100 }; @@ -155,7 +155,7 @@ describe('isVisible', () => { it('Should be vissible when only left side with no corners is in the viewport', () => { const attribute = { - event: undefined, + event: undefined as any, element: generateElement(-100, 500, 1200, 1200), offset: 0 }; @@ -166,7 +166,7 @@ describe('isVisible', () => { it('Should be vissible when only top side with no corners is in the viewport', () => { const attribute = { - event: undefined, + event: undefined as any, element: generateElement(500, -100, 1200, 1200), offset: 0 }; @@ -177,7 +177,7 @@ describe('isVisible', () => { it('Should be vissible when only right side with no corners is in the viewport', () => { const attribute = { - event: undefined, + event: undefined as any, element: generateElement(-100, -500, 1200, 1200), offset: 0 }; @@ -188,7 +188,7 @@ describe('isVisible', () => { it('Should be vissible when only bottom side with no corners is in the viewport', () => { const attribute = { - event: undefined, + event: undefined as any, element: generateElement(-500, -100, 1200, 1200), offset: 0 }; @@ -199,7 +199,7 @@ describe('isVisible', () => { it("Should not be visible when image is horizontally in window's view, but not in scroll-container's", () => { const attribute = { - event: undefined, + event: undefined as any, element: generateElement(800, 0, 1200, 1200), offset: 0, scrollContainer: generateElement(0, 0, 700, 1200) @@ -211,7 +211,7 @@ describe('isVisible', () => { it("Should not be visible when image is vertically in window's view, but not in scroll-container's", () => { const attribute = { - event: undefined, + event: undefined as any, element: generateElement(0, 800, 1200, 1200), offset: 0, scrollContainer: generateElement(0, 0, 1200, 700) @@ -223,7 +223,7 @@ describe('isVisible', () => { it("Should not be visible when image is not in window's view, but is in scroll-container's", () => { const attribute = { - event: undefined, + event: undefined as any, element: generateElement(1400, 0, 1200, 1200), offset: 0, scrollContainer: generateElement(1300, 0, 1200, 1200) @@ -235,7 +235,7 @@ describe('isVisible', () => { it("Should be visible when image is in window's and scroll-container's view", () => { const attribute = { - event: undefined, + event: undefined as any, element: generateElement(100, 0, 1200, 1200), offset: 0, scrollContainer: generateElement(0, 0, 700, 1200) @@ -247,7 +247,7 @@ describe('isVisible', () => { it("Should not be visible when image's rect is empty", () => { const attribute = { - event: undefined, + event: undefined as any, element: generateElement(0, 0, 0, 0), offset: 0 }; @@ -258,7 +258,7 @@ describe('isVisible', () => { it("Should not be visible when image's rect is empty and has an offset", () => { const attribute = { - event: undefined, + event: undefined as any, element: generateElement(0, 0, 0, 0), offset: 100 }; diff --git a/src/scroll-preset/__test__/scroll-listener.test.ts b/src/scroll-preset/__test__/scroll-listener.test.ts index f4ab019..3ca5938 100644 --- a/src/scroll-preset/__test__/scroll-listener.test.ts +++ b/src/scroll-preset/__test__/scroll-listener.test.ts @@ -23,7 +23,7 @@ describe('Scroll listener', () => { const expected = '|'; // Act - const listener = getScrollListener(element); + const listener = getScrollListener(element as any); // Assert scheduler.expectObservable(listener).toBe(expected); @@ -37,8 +37,8 @@ describe('Scroll listener', () => { }; // Act - const listener1 = getScrollListener(element); - const listener2 = getScrollListener(element); + const listener1 = getScrollListener(element as any); + const listener2 = getScrollListener(element as any); // Assert expect(listener1).toBe(listener2); @@ -54,8 +54,8 @@ describe('Scroll listener', () => { }; // Act - const listener1 = getScrollListener(element1); - const listener2 = getScrollListener(element2); + const listener1 = getScrollListener(element1 as any); + const listener2 = getScrollListener(element2 as any); // Assert expect(listener1).not.toBe(listener2); @@ -67,16 +67,16 @@ describe('Scroll listener', () => { eventName: '', handler: null, options: null - }; + } as any; const element = { - addEventListener(eventName, handler, options) { + addEventListener(eventName: any, handler: any, options: any) { argumants = { eventName, handler, options }; }, removeEventListener: noop }; // Act - const subscription = getScrollListener(element).subscribe(); + const subscription = getScrollListener(element as any).subscribe(); // Assert expect(argumants.eventName).toBe('scroll'); @@ -92,9 +92,9 @@ describe('Scroll listener', () => { eventName: '', handler: null, options: null - }; + } as any; const element = { - addEventListener(eventName, handler, options) { + addEventListener(eventName: any, handler: any, options: any) { argumants = { eventName, handler, options }; }, removeEventListener: spy((eventName, handler, options) => { @@ -106,7 +106,7 @@ describe('Scroll listener', () => { }; // Act - const subscription = getScrollListener(element).subscribe(); + const subscription = getScrollListener(element as any).subscribe(); subscription.unsubscribe(); // Assert @@ -121,7 +121,7 @@ describe('Scroll listener', () => { }; // Act and assert - const subscriber = getScrollListener(element).subscribe(d => { + const subscriber = getScrollListener(element as any).subscribe(d => { expect(d).toBe(''); done(); }); @@ -140,8 +140,8 @@ describe('Scroll listener', () => { }; // Act - const subscriber1 = getScrollListener(element).subscribe(); - const subscriber2 = getScrollListener(element).subscribe(); + const subscriber1 = getScrollListener(element as any).subscribe(); + const subscriber2 = getScrollListener(element as any).subscribe(); // Assert expect(subscriptionCounter).toBe(1); @@ -153,10 +153,7 @@ describe('Scroll listener', () => { // Arrange const scheduler = createRxTestScheduler(); const values = { a: '', b: 'b' }; - const e1 = scheduler.createHotObservable( - '----b-^----b----------------------|', - values - ); + const e1 = scheduler.createHotObservable('----b-^----b----------------------|', values); const expected = 'a---------b-----------------|'; // timer ----------!----------!--------- @@ -170,17 +167,17 @@ describe('Scroll listener', () => { it(`Should emit event through the handler`, done => { // Arrange - let eventHandler = null; - const events = []; + let eventHandler: any = null; + const events: any[] = []; const element = { - addEventListener: (eventName, handler, options) => { + addEventListener: (eventName: any, handler: any, options: any) => { eventHandler = handler; }, removeEventListener: noop }; // Act and assert - const subscriber = getScrollListener(element).subscribe(d => { + const subscriber = getScrollListener(element as any).subscribe(d => { events.push(d); if (events.length === 2) { expect(events[0]).toBe(''); diff --git a/src/scroll-preset/index.ts b/src/scroll-preset/index.ts index 17a9126..93a69c4 100644 --- a/src/scroll-preset/index.ts +++ b/src/scroll-preset/index.ts @@ -1 +1 @@ -export { scrollPreset } from './preset' +export { scrollPreset } from './preset'; diff --git a/src/scroll-preset/preset.ts b/src/scroll-preset/preset.ts index 68ae08f..bee1690 100644 --- a/src/scroll-preset/preset.ts +++ b/src/scroll-preset/preset.ts @@ -5,7 +5,7 @@ import { isWindowDefined } from '../util'; import { Rect } from './rect'; import { getScrollListener } from './scroll-listener'; -export const isVisible: IsVisibleFn = ({ element, offset, scrollContainer }, getWindow = () => window) => { +export const isVisible: IsVisibleFn = ({ element, offset, scrollContainer }, getWindow = () => window) => { const elementBounds = Rect.fromElement(element); if (elementBounds === Rect.empty) { return false; @@ -22,7 +22,7 @@ export const isVisible: IsVisibleFn = ({ element, offset, scrollContainer } }; -const getObservable: GetObservableFn = (attributes: Attributes) => { +const getObservable: GetObservableFn = (attributes: Attributes) => { if (attributes.scrollObservable) { return attributes.scrollObservable.pipe(startWith('')); } @@ -32,7 +32,7 @@ const getObservable: GetObservableFn = (attributes: Attributes) return getScrollListener(isWindowDefined() ? window : undefined); }; -export const scrollPreset: HookSet = Object.assign({}, sharedPreset, { +export const scrollPreset: HookSet = Object.assign({}, sharedPreset, { isVisible, getObservable }); diff --git a/src/scroll-preset/scroll-listener.ts b/src/scroll-preset/scroll-listener.ts index 22654fa..6f783eb 100644 --- a/src/scroll-preset/scroll-listener.ts +++ b/src/scroll-preset/scroll-listener.ts @@ -1,10 +1,10 @@ -import { empty, Observable } from 'rxjs'; +import { empty, Observable, Subject } from 'rxjs'; import { sampleTime, share, startWith } from 'rxjs/operators'; import { isWindowDefined } from '../util'; const scrollListeners = new WeakMap>(); -export function sampleObservable(obs: Observable, scheduler?: any) { +export function sampleObservable(obs: Observable, scheduler?: any): Observable { return obs.pipe( sampleTime(100, scheduler), share(), @@ -14,20 +14,21 @@ export function sampleObservable(obs: Observable, scheduler?: any) { // Only create one scroll listener per target and share the observable. // Typical, there will only be one observable per application -export const getScrollListener = (scrollTarget): Observable => { +export const getScrollListener = (scrollTarget?: HTMLElement | Window): Observable => { if (!scrollTarget || typeof scrollTarget.addEventListener !== 'function') { if (isWindowDefined()) { console.warn('`addEventListener` on ' + scrollTarget + ' (scrollTarget) is not a function. Skipping this target'); } return empty(); } - if (scrollListeners.has(scrollTarget)) { - return scrollListeners.get(scrollTarget); + const scrollListener = scrollListeners.get(scrollTarget); + if (scrollListener) { + return scrollListener; } - const srollEvent = Observable.create(observer => { + const srollEvent: Observable = Observable.create((observer: Subject) => { const eventName = 'scroll'; - const handler = event => observer.next(event); + const handler = (event: Event) => observer.next(event); const options = { passive: true, capture: false }; scrollTarget.addEventListener(eventName, handler, options); return () => scrollTarget.removeEventListener(eventName, handler, options); diff --git a/src/shared-preset/preset.ts b/src/shared-preset/preset.ts index 9414da2..f9985e2 100644 --- a/src/shared-preset/preset.ts +++ b/src/shared-preset/preset.ts @@ -1,4 +1,4 @@ -import { Observable } from 'rxjs'; +import { Observable, Subject } from 'rxjs'; import { cssClassNames, hasCssClassName, @@ -10,22 +10,16 @@ import { setImage, setImageAndSourcesToError, setImageAndSourcesToLazy, - setImageAndSourcesToDefault, + setImageAndSourcesToDefault } from '../util'; -import { - FinallyFn, - LoadImageFn, - SetErrorImageFn, - SetLoadedImageFn, - SetupFn -} from '../types'; +import { FinallyFn, LoadImageFn, SetErrorImageFn, SetLoadedImageFn, SetupFn } from '../types'; const end: FinallyFn = ({ element }) => addCssClassName(element, cssClassNames.loaded); export const loadImage: LoadImageFn = ({ element, useSrcset, imagePath }) => { let img: HTMLImageElement; if (isImageElement(element) && isChildOfPicture(element)) { - const parentClone = element.parentNode.cloneNode(true) as HTMLPictureElement; + const parentClone = element.parentNode!.cloneNode(true) as HTMLPictureElement; img = parentClone.getElementsByTagName('img')[0]; setSourcesToLazy(img); setImage(img, imagePath, useSrcset); @@ -41,7 +35,7 @@ export const loadImage: LoadImageFn = ({ element, useSrcset, imagePath }) => { } } - return Observable.create(observer => { + return Observable.create((observer: Subject) => { img.onload = () => { observer.next(imagePath); observer.complete(); diff --git a/src/types.ts b/src/types.ts index 0c13ae3..927a812 100644 --- a/src/types.ts +++ b/src/types.ts @@ -10,27 +10,27 @@ export type IsVisibleProps = { export type SetLoadedImageProps = { element: HTMLImageElement | HTMLDivElement; imagePath: string; - useSrcset: boolean; + useSrcset?: boolean; }; export type SetErrorImageProps = { element: HTMLImageElement | HTMLDivElement; - errorImagePath: string; - useSrcset: boolean; + errorImagePath?: string; + useSrcset?: boolean; }; export type LoadImageProps = { element: HTMLImageElement | HTMLDivElement; imagePath: string; - useSrcset: boolean; + useSrcset?: boolean; }; export type Attributes = { element: HTMLImageElement | HTMLDivElement; imagePath: string; - defaultImagePath: string; - errorImagePath: string; - useSrcset: boolean; + defaultImagePath?: string; + errorImagePath?: string; + useSrcset?: boolean; offset: number; scrollContainer?: HTMLElement; scrollObservable?: Observable; @@ -41,10 +41,7 @@ export type ObsEvent = { attributes: Attributes; }; -export type IsVisibleFn = ( - args: IsVisibleProps, - getWindow?: () => Window -) => boolean; +export type IsVisibleFn = (args: IsVisibleProps, getWindow?: () => Window) => boolean; export type LoadImageFn = (args: LoadImageProps) => ObservableInput; export type SetLoadedImageFn = (args: SetLoadedImageProps) => void; diff --git a/src/util/__test__/css.util.test.ts b/src/util/__test__/css.util.test.ts index 3de1efe..52972e1 100644 --- a/src/util/__test__/css.util.test.ts +++ b/src/util/__test__/css.util.test.ts @@ -1,46 +1,42 @@ -import { - addCssClassName, - hasCssClassName, - removeCssClassName -} from '../css.util'; +import { addCssClassName, hasCssClassName, removeCssClassName } from '../css.util'; describe('Utils function', () => { - const element = {} as HTMLImageElement; + const element = {} as HTMLImageElement; - beforeEach(() => { - element.className = 'test1 test2'; - }); + beforeEach(() => { + element.className = 'test1 test2'; + }); - it('Should remove css class name', () => { - const expectCssClassName = 'test1 '; - removeCssClassName(element, 'test2'); + it('Should remove css class name', () => { + const expectCssClassName = 'test1 '; + removeCssClassName(element, 'test2'); - expect(element.className).toBe(expectCssClassName); - }); + expect(element.className).toBe(expectCssClassName); + }); - it('Should add css class name', () => { - const expectCssClassName = 'test1 test2 test3'; - addCssClassName(element, 'test3'); + it('Should add css class name', () => { + const expectCssClassName = 'test1 test2 test3'; + addCssClassName(element, 'test3'); - expect(element.className).toBe(expectCssClassName); - }); + expect(element.className).toBe(expectCssClassName); + }); - it('Should not add css class name, because it already exists', () => { - const expectCssClassName = 'test1 test2'; - addCssClassName(element, 'test2'); + it('Should not add css class name, because it already exists', () => { + const expectCssClassName = 'test1 test2'; + addCssClassName(element, 'test2'); - expect(element.className).toBe(expectCssClassName); - }); + expect(element.className).toBe(expectCssClassName); + }); - it('Should return true when element contains the class name', () => { - const result = hasCssClassName(element, 'test2'); + it('Should return true when element contains the class name', () => { + const result = hasCssClassName(element, 'test2'); - expect(result).toBe(true); - }); + expect(result).toBe(true); + }); - it(`Should return false when element don't contains the class name`, () => { - const result = hasCssClassName(element, 'test3'); + it(`Should return false when element don't contains the class name`, () => { + const result = hasCssClassName(element, 'test3'); - expect(result).toBe(false); - }); + expect(result).toBe(false); + }); }); diff --git a/src/util/css.util.ts b/src/util/css.util.ts index 1534f8f..5005c23 100644 --- a/src/util/css.util.ts +++ b/src/util/css.util.ts @@ -1,19 +1,19 @@ export const cssClassNames = { - loaded: 'ng-lazyloaded', - loading: 'ng-lazyloading', - failed: 'ng-failed-lazyloaded', + loaded: 'ng-lazyloaded', + loading: 'ng-lazyloading', + failed: 'ng-failed-lazyloaded' }; export function removeCssClassName(element: HTMLImageElement | HTMLDivElement, cssClassName: string) { - element.className = element.className.replace(cssClassName, ''); + element.className = element.className.replace(cssClassName, ''); } export function addCssClassName(element: HTMLImageElement | HTMLDivElement, cssClassName: string) { - if (!element.className.includes(cssClassName)) { - element.className += ` ${cssClassName}`; - } + if (!element.className.includes(cssClassName)) { + element.className += ` ${cssClassName}`; + } } export function hasCssClassName(element: HTMLImageElement | HTMLDivElement, cssClassName: string) { - return element.className && element.className.includes(cssClassName); + return element.className && element.className.includes(cssClassName); } diff --git a/src/util/index.ts b/src/util/index.ts index 500df42..04b3bc4 100644 --- a/src/util/index.ts +++ b/src/util/index.ts @@ -1,2 +1,2 @@ -export * from './css.util' -export * from './util' +export * from './css.util'; +export * from './util'; diff --git a/src/util/util.ts b/src/util/util.ts index 20dc527..592a24b 100644 --- a/src/util/util.ts +++ b/src/util/util.ts @@ -10,7 +10,7 @@ export function isImageElement(element: HTMLImageElement | HTMLDivElement): elem return element.nodeName.toLowerCase() === 'img'; } -export function setImage(element: HTMLImageElement | HTMLDivElement, imagePath: string, useSrcset: boolean) { +export function setImage(element: HTMLImageElement | HTMLDivElement, imagePath: string, useSrcset?: boolean) { if (isImageElement(element)) { if (useSrcset) { element.srcset = imagePath; @@ -25,7 +25,7 @@ export function setImage(element: HTMLImageElement | HTMLDivElement, imagePath: function setSources(attrName: string) { return (image: HTMLImageElement) => { - const sources = image.parentElement.getElementsByTagName('source'); + const sources = image.parentElement!.getElementsByTagName('source'); for (let i = 0; i < sources.length; i++) { const attrValue = sources[i].getAttribute(attrName); if (attrValue) { @@ -40,7 +40,7 @@ export const setSourcesToLazy = setSources('lazyLoad'); const setSourcesToError = setSources('errorImage'); function setImageAndSources(setSourcesFn: (image: HTMLImageElement) => void) { - return (element: HTMLImageElement | HTMLDivElement, imagePath: string, useSrcset: boolean) => { + return (element: HTMLImageElement | HTMLDivElement, imagePath?: string, useSrcset?: boolean) => { if (isImageElement(element) && isChildOfPicture(element)) { setSourcesFn(element); } diff --git a/tsconfig.json b/tsconfig.json index 90b508a..826dba1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,11 +7,12 @@ "noEmit": true, "noEmitOnError": true, "esModuleInterop": true, - "noImplicitAny": false, + "noImplicitAny": true, "removeComments": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "sourceMap": true, + "strict": true, "rootDir": ".", "outDir": "dist", "lib": [