From 0b138afb4b32f54c2b19d344d171ad49966a862b Mon Sep 17 00:00:00 2001 From: Janne Julkunen Date: Fri, 18 May 2018 19:20:58 +0300 Subject: [PATCH] Turned on strict mode and fixed the compilation errors --- example/src/app/app.component.ts | 8 +- example/src/tsconfig.json | 28 +--- example/tsconfig.json | 32 +++++ src/index.d.ts | 1 + src/lib/swiper.component.html | 4 +- src/lib/swiper.component.ts | 73 ++++++----- src/lib/swiper.directive.ts | 32 +++-- src/lib/swiper.interfaces.ts | 219 ++++++++++++++++--------------- src/tsconfig.json | 3 +- tsconfig.json | 8 +- 10 files changed, 222 insertions(+), 186 deletions(-) create mode 100644 example/tsconfig.json create mode 100644 src/index.d.ts diff --git a/example/src/app/app.component.ts b/example/src/app/app.component.ts index 32cda29..f0399c3 100644 --- a/example/src/app/app.component.ts +++ b/example/src/app/app.component.ts @@ -47,8 +47,8 @@ export class AppComponent { hideOnClick: false }; - @ViewChild(SwiperComponent) componentRef: SwiperComponent; - @ViewChild(SwiperDirective) directiveRef: SwiperDirective; + @ViewChild(SwiperComponent) componentRef?: SwiperComponent; + @ViewChild(SwiperDirective) directiveRef?: SwiperDirective; constructor() {} @@ -90,9 +90,9 @@ export class AppComponent { this.config.navigation = true; } - if (this.type === 'directive') { + if (this.type === 'directive' && this.directiveRef) { this.directiveRef.setIndex(0); - } else { + } else if (this.type === 'component' && this.componentRef && this.componentRef.directiveRef) { this.componentRef.directiveRef.setIndex(0); } } diff --git a/example/src/tsconfig.json b/example/src/tsconfig.json index a903783..0c3f2b3 100644 --- a/example/src/tsconfig.json +++ b/example/src/tsconfig.json @@ -1,29 +1,7 @@ { + "extends": "../tsconfig.json", "compilerOptions": { - "baseUrl": "", - "declaration": false, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "inlineSources": false, - "lib": [ - "es2015", - "dom" - ], - "module": "es2015", - "moduleResolution": "node", - "outDir": "./dist", - "paths": { - "@angular/*": [ - "../node_modules/@angular/*" - ] - }, - "sourceMap": true, - "target": "es5", - "typeRoots": [ - "./node_modules/@types" - ], - "types": [ - "node" - ] + "outDir": "../dist", + "rootDir": "." } } diff --git a/example/tsconfig.json b/example/tsconfig.json new file mode 100644 index 0000000..575041c --- /dev/null +++ b/example/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "baseUrl": "", + "declaration": false, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "inlineSources": false, + "lib": [ + "es2015", + "dom" + ], + "module": "es2015", + "moduleResolution": "node", + "outDir": "./dist", + "paths": { + "@angular/*": [ + "./node_modules/@angular/*" + ] + }, + "rootDir": ".", + "strict": true, + "sourceMap": true, + "target": "es5", + "typeRoots": [ + "./node_modules/@types" + ], + "types": [ + "node" + // Add this when 4.x types available: "swiper" + ] + } +} diff --git a/src/index.d.ts b/src/index.d.ts new file mode 100644 index 0000000..95b9f38 --- /dev/null +++ b/src/index.d.ts @@ -0,0 +1 @@ +declare module 'swiper/dist/js/swiper.js'; diff --git a/src/lib/swiper.component.html b/src/lib/swiper.component.html index 064f19e..9000b31 100644 --- a/src/lib/swiper.component.html +++ b/src/lib/swiper.component.html @@ -5,8 +5,8 @@
-
+
-
+
diff --git a/src/lib/swiper.component.ts b/src/lib/swiper.component.ts index d9c9d54..c8ba7fe 100644 --- a/src/lib/swiper.component.ts +++ b/src/lib/swiper.component.ts @@ -2,13 +2,12 @@ import { PLATFORM_ID } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; import { NgZone, Inject, Optional, ElementRef, Component, AfterViewInit, OnDestroy, Input, Output, EventEmitter, - ViewChild, ViewEncapsulation } from '@angular/core'; - -import { SWIPER_CONFIG } from './swiper.interfaces'; + ViewChild, ViewEncapsulation, ChangeDetectorRef } from '@angular/core'; import { SwiperDirective } from './swiper.directive'; -import { SwiperEvents, SwiperConfig, SwiperConfigInterface } from './swiper.interfaces'; +import { SWIPER_CONFIG, SwiperConfig, SwiperConfigInterface, + SwiperEvent, SwiperEvents } from './swiper.interfaces'; @Component({ selector: 'swiper', @@ -18,34 +17,34 @@ import { SwiperEvents, SwiperConfig, SwiperConfigInterface } from './swiper.inte encapsulation: ViewEncapsulation.None }) export class SwiperComponent implements AfterViewInit, OnDestroy { - private mo: any; + private mo: MutationObserver | null = null; - public swiperConfig: any; - public paginationBackup: any; - public paginationConfig: any; + public swiperConfig: any = null; + public paginationBackup: any = null; + public paginationConfig: any = null; - @Input() index: number = null; + @Input() index: number | null = null; @Input() disabled: boolean = false; - @Input() config: SwiperConfigInterface; + @Input() config?: SwiperConfigInterface; @Input() useSwiperClass: boolean = true; @Output() indexChange = new EventEmitter(); - @ViewChild('swiperSlides') swiperSlides: ElementRef; + @ViewChild('swiperSlides') swiperSlides?: ElementRef; - @ViewChild(SwiperDirective) directiveRef: SwiperDirective; + @ViewChild(SwiperDirective) directiveRef?: SwiperDirective; get isAtLast(): boolean { - return (!this.directiveRef || !this.directiveRef.swiper) ? - false : this.directiveRef.swiper['isEnd']; + return (!this.directiveRef || !this.directiveRef.swiper()) ? + false : this.directiveRef.swiper()['isEnd']; } get isAtFirst(): boolean { - return (!this.directiveRef || !this.directiveRef.swiper) ? - false : this.directiveRef.swiper['isBeginning']; + return (!this.directiveRef || !this.directiveRef.swiper()) ? + false : this.directiveRef.swiper()['isBeginning']; } @Output('init' ) S_INIT = new EventEmitter(); @@ -98,7 +97,8 @@ export class SwiperComponent implements AfterViewInit, OnDestroy { @Output('slideChangeTransitionEnd' ) S_SLIDECHANGETRANSITIONEND = new EventEmitter(); @Output('slideChangeTransitionStart' ) S_SLIDECHANGETRANSITIONSTART = new EventEmitter(); - constructor(private zone: NgZone, @Inject(PLATFORM_ID) private platformId: Object, + constructor(private zone: NgZone, private cdRef: ChangeDetectorRef, + @Inject(PLATFORM_ID) private platformId: Object, @Optional() @Inject(SWIPER_CONFIG) private defaults: SwiperConfigInterface) {} ngAfterViewInit(): void { @@ -109,7 +109,7 @@ export class SwiperComponent implements AfterViewInit, OnDestroy { this.zone.runOutsideAngular(() => { this.updateClasses(); - if (typeof MutationObserver !== 'undefined') { + if (this.swiperSlides && typeof MutationObserver !== 'undefined') { this.mo = new MutationObserver((mutations) => { this.updateClasses(); }); @@ -122,10 +122,15 @@ export class SwiperComponent implements AfterViewInit, OnDestroy { if (this.directiveRef) { this.directiveRef.indexChange = this.indexChange; - SwiperEvents.forEach((eventName: string) => { - eventName = `S_${eventName.replace('swiper', '').toUpperCase()}`; + SwiperEvents.forEach((eventName: SwiperEvent) => { + if (this.directiveRef) { + const output = `S_${eventName.replace('swiper', '').toUpperCase()}`; + + const directiveOutput = output as keyof SwiperDirective; + const componentOutput = output as keyof SwiperComponent; - this.directiveRef[eventName] = this[eventName]; + this.directiveRef[directiveOutput] = this[componentOutput] as EventEmitter; + } }); } }, 0); @@ -160,7 +165,7 @@ export class SwiperComponent implements AfterViewInit, OnDestroy { el: '.swiper-pagination', renderBullet: (index: number, className: string) => { - const children = this.swiperSlides.nativeElement.children; + const children = this.swiperSlides ? this.swiperSlides.nativeElement.children : []; let bullet = ``; @@ -182,24 +187,28 @@ export class SwiperComponent implements AfterViewInit, OnDestroy { } } - return this.config; + return this.config as SwiperConfigInterface; } private updateClasses(): void { - let updateNeeded = false; + if (this.swiperSlides) { + let updateNeeded = false; - const children = this.swiperSlides.nativeElement.children; + const children = this.swiperSlides.nativeElement.children; - for (let i = 0; i < children.length; i++) { - if (!children[i].classList.contains('swiper-slide')) { - updateNeeded = true; + for (let i = 0; i < children.length; i++) { + if (!children[i].classList.contains('swiper-slide')) { + updateNeeded = true; - children[i].classList.add('swiper-slide'); + children[i].classList.add('swiper-slide'); + } } - } - if (updateNeeded) { - this.directiveRef.update(); + if (updateNeeded && this.directiveRef) { + this.directiveRef.update(); + } } + + this.cdRef.detectChanges(); } } diff --git a/src/lib/swiper.directive.ts b/src/lib/swiper.directive.ts index ccbdd63..857d9b4 100644 --- a/src/lib/swiper.directive.ts +++ b/src/lib/swiper.directive.ts @@ -6,9 +6,8 @@ import { NgZone, Inject, Optional, ElementRef, Directive, AfterViewInit, OnDestroy, DoCheck, OnChanges, Input, Output, EventEmitter, SimpleChanges, KeyValueDiffer, KeyValueDiffers } from '@angular/core'; -import { SWIPER_CONFIG } from './swiper.interfaces'; - -import { SwiperEvents, SwiperConfig, SwiperConfigInterface } from './swiper.interfaces'; +import { SWIPER_CONFIG, SwiperConfig, SwiperConfigInterface, + SwiperEvent, SwiperEvents } from './swiper.interfaces'; @Directive({ selector: '[swiper]', @@ -17,9 +16,9 @@ import { SwiperEvents, SwiperConfig, SwiperConfigInterface } from './swiper.inte export class SwiperDirective implements AfterViewInit, OnDestroy, DoCheck, OnChanges { private instance: any; - private configDiff: KeyValueDiffer; + private initialIndex: number | null = null; - private initialIndex: number; + private configDiff: KeyValueDiffer | null = null; @Input() set index(index: number) { @@ -30,7 +29,7 @@ export class SwiperDirective implements AfterViewInit, OnDestroy, DoCheck, OnCha @Input() disabled: boolean = false; - @Input('swiper') config: SwiperConfigInterface; + @Input('swiper') config?: SwiperConfigInterface; @Output() indexChange = new EventEmitter(); @@ -127,7 +126,7 @@ export class SwiperDirective implements AfterViewInit, OnDestroy, DoCheck, OnCha this.initialIndex = null; } - params['on'] = { + params.on = { slideChange: () => { this.zone.run(() => { if (this.instance) { @@ -146,18 +145,23 @@ export class SwiperDirective implements AfterViewInit, OnDestroy, DoCheck, OnCha } // Add native Swiper event handling - SwiperEvents.forEach((eventName) => { - eventName = eventName.replace('swiper', ''); - eventName = eventName.charAt(0).toLowerCase() + eventName.slice(1); + SwiperEvents.forEach((eventName: SwiperEvent) => { + let swiperEvent = eventName.replace('swiper', ''); + + swiperEvent = eventName.charAt(0).toLowerCase() + eventName.slice(1); - this.instance.on(eventName, (...args) => { + this.instance.on(swiperEvent, (...args: any[]) => { if (args.length === 1) { args = args[0]; } - if (this[`S_${eventName.toUpperCase()}`].observers.length > 0) { + const output = `S_${swiperEvent.toUpperCase()}`; + + const emitter = this[output as keyof SwiperDirective] as EventEmitter; + + if (emitter.observers.length > 0) { this.zone.run(() => { - this[`S_${eventName.toUpperCase()}`].emit(args); + emitter.emit(args); }); } }); @@ -240,7 +244,7 @@ export class SwiperDirective implements AfterViewInit, OnDestroy, DoCheck, OnCha public getIndex(real?: boolean): number { if (!this.instance) { - return this.initialIndex; + return this.initialIndex || 0; } else { return real ? this.instance.realIndex : this.instance.activeIndex; } diff --git a/src/lib/swiper.interfaces.ts b/src/lib/swiper.interfaces.ts index 6f02c71..72c278b 100644 --- a/src/lib/swiper.interfaces.ts +++ b/src/lib/swiper.interfaces.ts @@ -2,7 +2,17 @@ import { InjectionToken } from '@angular/core'; export const SWIPER_CONFIG = new InjectionToken('SWIPER_CONFIG'); -export const SwiperEvents = [ +export type SwiperEvent = 'init' | 'beforeDestroy' | 'scroll' | 'progress' | 'keyPress' | + 'beforeResize' | 'afterResize' | 'resize' | 'breakpoint' | 'beforeResize' | 'sliderMove' | + 'slideChange' | 'setTranslate' | 'setTransition' | 'fromEdge' | 'reachEnd' | 'reachBeginning' | + 'autoplay' | 'autoplayStop' | 'autoplayStart' | 'imagesReady' | 'lazyImageLoad' | + 'lazyImageReady' | 'scrollDragEnd' | 'scrollDragMove' | 'scrollDragStart' | 'swiperTap' | + 'swiperClick' | 'swiperDoubleTap' | 'swiperTouchEnd' | 'swiperTouchMove' | 'swiperTouchStart' | + 'swiperTouchMoveOpposite' | 'swiperTransitionEnd' | 'swiperTransitionStart' | + 'slideNextTransitionEnd' | 'slideNextTransitionStart' | 'slidePrevTransitionEnd' | + 'slidePrevTransitionStart' | 'slideChangeTransitionEnd' | 'slideChangeTransitionStart'; + +export const SwiperEvents: SwiperEvent[] = [ 'init', 'beforeDestroy', @@ -17,7 +27,6 @@ export const SwiperEvents = [ 'breakpoint', 'beforeResize', - 'keyPress', 'sliderMove', 'slideChange', @@ -332,139 +341,141 @@ export interface SwiperBreakpointsInterface { } export class SwiperConfig implements SwiperConfigInterface { + public on?: any; + // Swiper parameters - public init: boolean; - public initialSlide: number; - public direction: string; - public speed: number; - public setWrapperSize: boolean; - public virtualTranslate: boolean; - public width: number; - public height: number; - public autoHeight: boolean; - public roundLengths: boolean; - public nested: boolean; - public uniqueNavElements: boolean; - public effect: string; - public runCallbacksOnInit: boolean; - public watchOverflow: boolean; + public init?: boolean; + public initialSlide?: number; + public direction?: string; + public speed?: number; + public setWrapperSize?: boolean; + public virtualTranslate?: boolean; + public width?: number; + public height?: number; + public autoHeight?: boolean; + public roundLengths?: boolean; + public nested?: boolean; + public uniqueNavElements?: boolean; + public effect?: string; + public runCallbacksOnInit?: boolean; + public watchOverflow?: boolean; // Slides grid - public spaceBetween: number; - public slidesPerView: number | 'auto'; - public slidesPerColumn: number; - public slidesPerColumnFill: string; - public slidesPerGroup: number; - public centeredSlides: boolean; - public slidesOffsetBefore: number; - public slidesOffsetAfter: number; - public normalizeSlideIndex: boolean; + public spaceBetween?: number; + public slidesPerView?: number | 'auto'; + public slidesPerColumn?: number; + public slidesPerColumnFill?: string; + public slidesPerGroup?: number; + public centeredSlides?: boolean; + public slidesOffsetBefore?: number; + public slidesOffsetAfter?: number; + public normalizeSlideIndex?: boolean; // Grab cursor - public grabCursor: boolean; + public grabCursor?: boolean; // Touches - public touchEventsTarget: string; - public touchRatio: number; - public touchAngle: number; - public simulateTouch: boolean; - public shortSwipes: boolean; - public longSwipes: boolean; - public longSwipesRatio: number; - public longSwipesMs: number; - public followFinger: boolean; - public allowTouchMove: boolean; - public threshold: number; - public touchMoveStopPropagation: boolean; - public iOSEdgeSwipeDetection: boolean; - public iOSEdgeSwipeThreshold: number; - public touchReleaseOnEdges: boolean; - public passiveListeners: boolean; + public touchEventsTarget?: string; + public touchRatio?: number; + public touchAngle?: number; + public simulateTouch?: boolean; + public shortSwipes?: boolean; + public longSwipes?: boolean; + public longSwipesRatio?: number; + public longSwipesMs?: number; + public followFinger?: boolean; + public allowTouchMove?: boolean; + public threshold?: number; + public touchMoveStopPropagation?: boolean; + public iOSEdgeSwipeDetection?: boolean; + public iOSEdgeSwipeThreshold?: number; + public touchReleaseOnEdges?: boolean; + public passiveListeners?: boolean; // Touch resistance - public resistance: boolean; - public resistanceRatio: number; + public resistance?: boolean; + public resistanceRatio?: number; // Swiping / no swiping - public preventInteractionOnTransition: boolean; - public allowSlidePrev: boolean; - public allowSlideNext: boolean; - public noSwiping: boolean; - public noSwipingClass: string; - public noSwipingSelector: string; - public swipeHandler: string | HTMLElement; + public preventInteractionOnTransition?: boolean; + public allowSlidePrev?: boolean; + public allowSlideNext?: boolean; + public noSwiping?: boolean; + public noSwipingClass?: string; + public noSwipingSelector?: string; + public swipeHandler?: string | HTMLElement; // Clicks - public preventClicks: boolean; - public preventClicksPropagation: boolean; - public slideToClickedSlide: boolean; + public preventClicks?: boolean; + public preventClicksPropagation?: boolean; + public slideToClickedSlide?: boolean; // Freemode - public freeMode: boolean; - public freeModeMomentum: boolean; - public freeModeMomentumRatio: number; - public freeModeMomentumVelocityRatio: number; - public freeModeMomentumBounce: boolean; - public freeModeMomentumBounceRatio: number; - public freeModeMinimumVelocity: number; - public freeModeSticky: boolean; + public freeMode?: boolean; + public freeModeMomentum?: boolean; + public freeModeMomentumRatio?: number; + public freeModeMomentumVelocityRatio?: number; + public freeModeMomentumBounce?: boolean; + public freeModeMomentumBounceRatio?: number; + public freeModeMinimumVelocity?: number; + public freeModeSticky?: boolean; // Progress - public watchSlidesProgress: boolean; - public watchSlidesVisibility: boolean; + public watchSlidesProgress?: boolean; + public watchSlidesVisibility?: boolean; // Images - public preloadImages: boolean; - public updateOnImagesReady: boolean; + public preloadImages?: boolean; + public updateOnImagesReady?: boolean; // Loop - public loop: boolean; - public loopAdditionalSlides: number; - public loopedSlides: number; - public loopFillGroupWithBlank: boolean; + public loop?: boolean; + public loopAdditionalSlides?: number; + public loopedSlides?: number; + public loopFillGroupWithBlank?: boolean; // Breakpoints - public breakpoints: any; + public breakpoints?: any; // Observer - public observer: boolean; - public observeParents: boolean; + public observer?: boolean; + public observeParents?: boolean; // Namespace - public containerModifierClass: string; - public slideClass: string; - public slideActiveClass: string; - public slideDuplicatedActiveClass: string; - public slideVisibleClass: string; - public slideDuplicateClass: string; - public slideNextClass: string; - public slideDuplicatedNextClass: string; - public slidePrevClass: string; - public slideDuplicatedPrevClass: string; - public wrapperClass: string; + public containerModifierClass?: string; + public slideClass?: string; + public slideActiveClass?: string; + public slideDuplicatedActiveClass?: string; + public slideVisibleClass?: string; + public slideDuplicateClass?: string; + public slideNextClass?: string; + public slideDuplicatedNextClass?: string; + public slidePrevClass?: string; + public slideDuplicatedPrevClass?: string; + public wrapperClass?: string; // Effects - public fadeEffect: any; - public flipEffect: any; - public cubeEffect: any; - public coverflowEffect: any; + public fadeEffect?: any; + public flipEffect?: any; + public cubeEffect?: any; + public coverflowEffect?: any; // Components - public parallax: boolean; - - public a11y: boolean | any; - public lazy: boolean | any; - public zoom: boolean | any; - public history: boolean | any; - public virtual: boolean | any; - public autoplay: boolean | any; - public keyboard: boolean | any; - public scrollbar: boolean | any; - public mousewheel: boolean | any; - public controller: boolean | any; - public navigation: boolean | any; - public pagination: boolean | any; - public hashNavigation: boolean | any; + public parallax?: boolean; + + public a11y?: boolean | any; + public lazy?: boolean | any; + public zoom?: boolean | any; + public history?: boolean | any; + public virtual?: boolean | any; + public autoplay?: boolean | any; + public keyboard?: boolean | any; + public scrollbar?: boolean | any; + public mousewheel?: boolean | any; + public controller?: boolean | any; + public navigation?: boolean | any; + public pagination?: boolean | any; + public hashNavigation?: boolean | any; constructor(config: SwiperConfigInterface = {}) { this.assign(config); diff --git a/src/tsconfig.json b/src/tsconfig.json index e9c64bb..46b2259 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../tsconfig.json", "files": [ - "index.ts" + "index.ts", + "index.d.ts" ], "compilerOptions": { "outDir": "../dist", diff --git a/tsconfig.json b/tsconfig.json index 2dd3aff..ef07447 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,17 +11,17 @@ ], "module": "es2015", "moduleResolution": "node", - "outDir": "../dist", + "outDir": "./dist", "rootDir": ".", "skipLibCheck": true, "sourceMap": true, - "strict": false, + "strict": true, "target": "es5", "typeRoots": [ - "../node_modules/@types" + "./node_modules/@types" ], "types": [ - "node", + "node" // Add this when 4.x types available: "swiper" ] }