Skip to content

Commit

Permalink
fix(angular-ssr): do not use window and document on server side
Browse files Browse the repository at this point in the history
  • Loading branch information
tnicola committed Aug 18, 2018
1 parent d6d842c commit 4e493ec
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/lib/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
5 changes: 4 additions & 1 deletion src/lib/src/directives/joyride.directive.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand All @@ -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");
Expand Down Expand Up @@ -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 }
]
Expand Down
27 changes: 19 additions & 8 deletions src/lib/src/directives/joyride.directive.ts
Original file line number Diff line number Diff line change
@@ -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";

Expand Down Expand Up @@ -38,13 +40,22 @@ export class JoyrideDirective implements AfterViewInit {
@Output()
done?: EventEmitter<any> = new EventEmitter<any>();

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;
Expand All @@ -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;
}
Expand Down
17 changes: 13 additions & 4 deletions src/lib/src/services/dom.service.ts
Original file line number Diff line number Diff line change
@@ -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 = <Document>{ body: {}, documentElement: {} };
private fakeWindow: Window = <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;
}
}
9 changes: 7 additions & 2 deletions src/lib/src/services/joyride.service.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -13,11 +14,15 @@ export class JoyrideService {
private tour$: Observable<JoyrideStepInfo>;

constructor(
@Inject(PLATFORM_ID) private platformId: Object,
private readonly stepService: JoyrideStepService,
private readonly optionsService: JoyrideOptionsService
) { }

startTour(options?: JoyrideOptions): Observable<JoyrideStepInfo> {
if (!isPlatformBrowser(this.platformId)) {
return of(new JoyrideStepInfo());
}
if (!this.tourInProgress) {
this.tourInProgress = true;
if (options) {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/src/test/fake/dom-fake.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}

0 comments on commit 4e493ec

Please sign in to comment.