diff --git a/src/lib/package.json b/src/lib/package.json index 2290c578..500c4a92 100644 --- a/src/lib/package.json +++ b/src/lib/package.json @@ -1,6 +1,6 @@ { "name": "ngx-joyride", - "version": "2.1.0", + "version": "2.1.1", "description": "Angular Joyride Library", "main": "./bundles/ngx-joyride.umd.js", "jsnext:main": "./esm5/ngx-joyride.esm.js", diff --git a/src/lib/src/directives/joyride.directive.spec.ts b/src/lib/src/directives/joyride.directive.spec.ts index 5c17a12a..dedb359c 100644 --- a/src/lib/src/directives/joyride.directive.spec.ts +++ b/src/lib/src/directives/joyride.directive.spec.ts @@ -8,6 +8,8 @@ import { Router } from '@angular/router'; import { RouterFake } from '../test/fake/router-fake.service'; import { JoyrideError } from '../models/joyride-error.class'; import { JoyrideStep } from '../models/joyride-step.class'; +import { DomRefService } from '../services/dom.service'; +import { DomRefServiceFake } from '../test/fake/dom-fake.service'; @Component({ @@ -21,7 +23,7 @@ import { JoyrideStep } from '../models/joyride-step.class'; ` }) -class HostComponent { +class HostComponent { onPrev: jasmine.Spy = jasmine.createSpy("onPrev"); onNext: jasmine.Spy = jasmine.createSpy("onNext"); onDone: jasmine.Spy = jasmine.createSpy("onDone"); @@ -54,6 +56,7 @@ describe('JorideDirective', () => { TestBed.configureTestingModule({ declarations: [JoyrideDirective, HostComponent, HostComponentFixed, HostComponentNotFixed], providers: [ + { provide: DomRefService, useClass: DomRefServiceFake }, { provide: JoyrideStepsContainerService, useClass: JoyrideStepsContainerServiceFake }, { provide: Router, useClass: RouterFake } ] diff --git a/src/lib/src/directives/joyride.directive.ts b/src/lib/src/directives/joyride.directive.ts index 2812e1ab..c43072ac 100644 --- a/src/lib/src/directives/joyride.directive.ts +++ b/src/lib/src/directives/joyride.directive.ts @@ -1,8 +1,10 @@ -import { Directive, ElementRef, AfterViewInit, Input, ViewContainerRef, ViewChild, Renderer2, TemplateRef, Output, EventEmitter } from '@angular/core'; +import { Directive, ElementRef, AfterViewInit, Input, ViewContainerRef, ViewChild, Renderer2, TemplateRef, Output, EventEmitter, Inject, PLATFORM_ID } from '@angular/core'; import { JoyrideStep } from "../models/joyride-step.class"; import { JoyrideStepsContainerService } from "../services/joyride-steps-container.service"; import { JoyrideError } from "../models/joyride-error.class"; import { Router } from '@angular/router'; +import { DomRefService } from '../services/dom.service'; +import { isPlatformBrowser } from '@angular/common'; export const NO_POSITION = "NO_POSITION"; @@ -38,13 +40,22 @@ export class JoyrideDirective implements AfterViewInit { @Output() done?: EventEmitter = new EventEmitter(); + private windowRef: Window; + + constructor( private readonly joyrideStepsContainer: JoyrideStepsContainerService, private readonly viewContainerRef: ViewContainerRef, - private readonly router: Router - ) { } + private readonly domService: DomRefService, + private readonly router: Router, + @Inject(PLATFORM_ID) private platformId: Object + + ) { + this.windowRef = this.domService.getNativeWindow() + } ngAfterViewInit() { + if (!isPlatformBrowser(this.platformId)) return; let step = new JoyrideStep(); step.position = this.stepPosition; step.targetViewContainer = this.viewContainerRef; @@ -57,19 +68,19 @@ export class JoyrideDirective implements AfterViewInit { if (!this.name) throw new JoyrideError("All the steps should have the 'joyrideStep' property set with a custom name."); step.name = this.name; step.route = this.router.url.substr(0, 1) === '/' ? this.router.url.substr(1) : this.router.url; - step.transformCssStyle = window.getComputedStyle(this.viewContainerRef.element.nativeElement).transform; + step.transformCssStyle = this.windowRef.getComputedStyle(this.viewContainerRef.element.nativeElement).transform; step.isElementOrAncestorFixed = this.isElementFixed(this.viewContainerRef.element) || this.isAncestorsFixed(this.viewContainerRef.element.nativeElement.parentElement); - + this.joyrideStepsContainer.addStep(step); } private isElementFixed(element: ElementRef) { - return window.getComputedStyle(element.nativeElement).position === 'fixed'; + return this.windowRef.getComputedStyle(element.nativeElement).position === 'fixed'; } private isAncestorsFixed(nativeElement: any): boolean { - if(!nativeElement.parentElement) return false; - let isElementFixed = window.getComputedStyle(nativeElement.parentElement).position === 'fixed'; + if (!nativeElement.parentElement) return false; + let isElementFixed = this.windowRef.getComputedStyle(nativeElement.parentElement).position === 'fixed'; if (nativeElement.nodeName === 'BODY') { return isElementFixed; } diff --git a/src/lib/src/services/dom.service.ts b/src/lib/src/services/dom.service.ts index 88d0fbe5..f693acf5 100644 --- a/src/lib/src/services/dom.service.ts +++ b/src/lib/src/services/dom.service.ts @@ -1,12 +1,21 @@ -import { Injectable } from '@angular/core'; +import { Injectable, Inject, PLATFORM_ID } from '@angular/core'; +import { isPlatformBrowser } from '@angular/common'; @Injectable() export class DomRefService { - getNativeWindow(): any { - return window; + + private fakeDocument: Document = { body: {}, documentElement: {} }; + private fakeWindow: Window = { document: this.fakeDocument}; + constructor( + @Inject(PLATFORM_ID) private platformId: Object + ) { } + getNativeWindow(): Window { + if (isPlatformBrowser(this.platformId)) return window; + else return this.fakeWindow; } getNativeDocument() { - return document; + if (isPlatformBrowser(this.platformId)) return document; + else return this.fakeDocument; } } \ No newline at end of file diff --git a/src/lib/src/services/joyride.service.ts b/src/lib/src/services/joyride.service.ts index ab649e56..35663115 100644 --- a/src/lib/src/services/joyride.service.ts +++ b/src/lib/src/services/joyride.service.ts @@ -1,10 +1,11 @@ -import { Injectable } from '@angular/core'; +import { Injectable, Inject, PLATFORM_ID } from '@angular/core'; import { JoyrideStepService } from "./joyride-step.service"; import { JoyrideOptionsService } from './joyride-options.service'; import { JoyrideOptions } from '../models/joyride-options.class'; -import { Observable } from 'rxjs'; +import { Observable, of } from 'rxjs'; import { finalize } from "rxjs/operators"; import { JoyrideStepInfo } from '../models/joyride-step-info.class'; +import { isPlatformBrowser } from '@angular/common'; @Injectable() export class JoyrideService { @@ -13,11 +14,15 @@ export class JoyrideService { private tour$: Observable; constructor( + @Inject(PLATFORM_ID) private platformId: Object, private readonly stepService: JoyrideStepService, private readonly optionsService: JoyrideOptionsService ) { } startTour(options?: JoyrideOptions): Observable { + if (!isPlatformBrowser(this.platformId)) { + return of(new JoyrideStepInfo()); + } if (!this.tourInProgress) { this.tourInProgress = true; if (options) { diff --git a/src/lib/src/test/fake/dom-fake.service.ts b/src/lib/src/test/fake/dom-fake.service.ts index 2dc57013..1c6ef67e 100644 --- a/src/lib/src/test/fake/dom-fake.service.ts +++ b/src/lib/src/test/fake/dom-fake.service.ts @@ -2,6 +2,6 @@ import { Injectable } from '@angular/core'; @Injectable() export class DomRefServiceFake { - getNativeWindow: jasmine.Spy = jasmine.createSpy("getNativeWindow"); + getNativeWindow: jasmine.Spy = jasmine.createSpy("getNativeWindow").and.returnValue(window); getNativeDocument: jasmine.Spy = jasmine.createSpy("getNativeDocument"); } \ No newline at end of file