Skip to content

Commit

Permalink
Fix for Issue#86
Browse files Browse the repository at this point in the history
  • Loading branch information
metinjakupi committed Jun 20, 2023
1 parent d1c94fd commit 5c7f3e9
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export class JoyrideOptions {
showPrevButton?: boolean;
customTexts?: CustomTexts;
logsEnabled?: boolean;
fixedHeader?: string;
}

export class ICustomTexts {
Expand Down
77 changes: 54 additions & 23 deletions projects/ngx-joyride/src/lib/services/document.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Injectable, ElementRef, Inject, PLATFORM_ID } from '@angular/core';
import { Injectable, ElementRef } from '@angular/core';
import { DomRefService } from './dom.service';
import { isPlatformBrowser } from "@angular/common";

export interface IDocumentService {
getElementFixedTop(elementRef: ElementRef): number;
Expand Down Expand Up @@ -28,15 +27,11 @@ export interface IDocumentService {
export class DocumentService implements IDocumentService {
private documentHeight: number;

constructor(private readonly DOMService: DomRefService, @Inject(PLATFORM_ID) platformId: Object) {
if (!isPlatformBrowser(platformId)) {
return;
}
constructor(private readonly DOMService: DomRefService) {
this.setDocumentHeight();
var doc = DOMService.getNativeDocument();
if (doc && !doc.elementsFromPoint) {
if (!document.elementsFromPoint) {
// IE 11 - Edge browsers
doc.elementsFromPoint = this.elementsFromPoint.bind(this);
document.elementsFromPoint = this.elementsFromPoint.bind(this);
}
}

Expand Down Expand Up @@ -107,33 +102,55 @@ export class DocumentService implements IDocumentService {
if (elements1.length === 0 && elements2.length === 0) return 1;
if (
this.getFirstElementWithoutKeyword(elements1, keywordToDiscard) !==
elementRef.nativeElement ||
elementRef.nativeElement ||
this.getFirstElementWithoutKeyword(elements2, keywordToDiscard) !==
elementRef.nativeElement
elementRef.nativeElement
) {
return 2;
}
return 3;
}

scrollIntoView(elementRef: ElementRef, isElementFixed: boolean): void {
// scrollIntoView(elementRef: ElementRef, isElementFixed: boolean, fixedHeaderHeight?: number): void {
// const firstScrollableParent = this.getFirstScrollableParent(
// elementRef.nativeElement
// );
// const top = isElementFixed
// ? this.getElementFixedTop(elementRef)
// : this.getElementAbsoluteTop(elementRef);
// if (
// firstScrollableParent !== this.DOMService.getNativeDocument().body
// ) {
// if (firstScrollableParent.scrollTo) {
// firstScrollableParent.scrollTo(0, top - fixedHeaderHeight);
// } else {
// // IE 11 - Edge browsers
// firstScrollableParent.scrollTop = top - fixedHeaderHeight;
// }
// } else {
// this.DOMService.getNativeWindow().scrollTo(0, top - fixedHeaderHeight);
// }
// }

scrollIntoView(elementRef: ElementRef, isElementFixed: boolean, fixedHeaderHeight?: number): void {
const firstScrollableParent = this.getFirstScrollableParent(
elementRef.nativeElement
);
const top = isElementFixed
? this.getElementFixedTop(elementRef)
: this.getElementAbsoluteTop(elementRef);
: this.firstScrollableParentScrollOffset(elementRef).y + elementRef.nativeElement.getBoundingClientRect().top;
// : this.getElementAbsoluteTop(elementRef); // Returns incorrect values if body elem doesnt have scroll and some custom child elem of body has scrollbar
if (
firstScrollableParent !== this.DOMService.getNativeDocument().body
) {
if (firstScrollableParent.scrollTo) {
firstScrollableParent.scrollTo(0, top - 150);
firstScrollableParent.scrollTo(0, top - fixedHeaderHeight);
} else {
// IE 11 - Edge browsers
firstScrollableParent.scrollTop = top - 150;
firstScrollableParent.scrollTop = top - fixedHeaderHeight;
}
} else {
this.DOMService.getNativeWindow().scrollTo(0, top - 150);
this.DOMService.getNativeWindow().scrollTo(0, top - fixedHeaderHeight);
}
}

Expand Down Expand Up @@ -192,16 +209,16 @@ export class DocumentService implements IDocumentService {
const scroll = (node: any) =>
regex.test(
style(node, 'overflow') +
style(node, 'overflow-y') +
style(node, 'overflow-x')
style(node, 'overflow-y') +
style(node, 'overflow-x')
);

const scrollparent = (node: any): any => {
return !node || node === this.DOMService.getNativeDocument().body
? this.DOMService.getNativeDocument().body
: scroll(node)
? node
: scrollparent(node.parentNode);
? node
: scrollparent(node.parentNode);
};

return scrollparent(node);
Expand All @@ -219,6 +236,20 @@ export class DocumentService implements IDocumentService {
);
}

private firstScrollableParentScrollOffset(elementRef?: ElementRef) {
if(elementRef) {
const firstScrollableParent = this.getFirstScrollableParent(
elementRef.nativeElement
);
if(firstScrollableParent) {
return {
x: firstScrollableParent.scrollLeft,
y: firstScrollableParent.scrollTop
}
}
}
}

private getScrollOffsets() {
const winReference = this.DOMService.getNativeWindow();
const docReference = this.DOMService.getNativeDocument();
Expand Down Expand Up @@ -257,8 +288,8 @@ export class DocumentService implements IDocumentService {
parent = false;
}
} while (parent);
parents.forEach(function(parent) {
return (parent.style.pointerEvents = 'all');
parents.forEach(function(p) {
return (p.style.pointerEvents = 'all');
});
return parents;
}
Expand All @@ -270,7 +301,7 @@ export class DocumentService implements IDocumentService {
while (
elements[0] &&
elements[0].classList.toString().includes(keyword)
) {
) {
elements.shift();
}
return elements[0];
Expand Down
70 changes: 23 additions & 47 deletions projects/ngx-joyride/src/lib/services/joyride-options.service.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import { Injectable } from '@angular/core';
import {
JoyrideOptions,
CustomTexts,
ICustomTexts
} from '../models/joyride-options.class';
import { JoyrideOptions, CustomTexts, ICustomTexts } from '../models/joyride-options.class';
import { of, Observable } from 'rxjs';

export const DEFAULT_THEME_COLOR = '#3b5560';
Expand Down Expand Up @@ -41,42 +37,26 @@ export interface IJoyrideOptionsService {
export class JoyrideOptionsService implements IJoyrideOptionsService {
private themeColor: string = DEFAULT_THEME_COLOR;
private stepDefaultPosition: string = STEP_DEFAULT_POSITION;
private logsEnabled = false;
private showCounter = true;
private showPrevButton = true;
private logsEnabled: boolean = true;
private showCounter: boolean = true;
private showPrevButton: boolean = true;
private stepsOrder: string[] = [];
private firstStep: string;
private fixedHeader: string;
private waitingTime: number;
private customTexts: ObservableCustomTexts;

setOptions(options: JoyrideOptions) {
this.stepsOrder = options.steps;
this.stepDefaultPosition = options.stepDefaultPosition
? options.stepDefaultPosition
: this.stepDefaultPosition;
this.logsEnabled =
typeof options.logsEnabled !== 'undefined'
? options.logsEnabled
: this.logsEnabled;
this.showCounter =
typeof options.showCounter !== 'undefined'
? options.showCounter
: this.showCounter;
this.showPrevButton =
typeof options.showPrevButton !== 'undefined'
? options.showPrevButton
: this.showPrevButton;
this.themeColor = options.themeColor
? options.themeColor
: this.themeColor;
this.stepDefaultPosition = options.stepDefaultPosition ? options.stepDefaultPosition : this.stepDefaultPosition;
this.logsEnabled = typeof options.logsEnabled !== 'undefined' ? options.logsEnabled : this.logsEnabled;
this.showCounter = typeof options.showCounter !== 'undefined' ? options.showCounter : this.showCounter;
this.showPrevButton = typeof options.showPrevButton !== 'undefined' ? options.showPrevButton : this.showPrevButton;
this.themeColor = options.themeColor ? options.themeColor : this.themeColor;
this.firstStep = options.startWith;
this.waitingTime =
typeof options.waitingTime !== 'undefined'
? options.waitingTime
: DEFAULT_TIMEOUT_BETWEEN_STEPS;
typeof options.customTexts !== 'undefined'
? this.setCustomText(options.customTexts)
: this.setCustomText(DEFAULT_TEXTS);
this.fixedHeader = options.fixedHeader;
this.waitingTime = typeof options.waitingTime !== 'undefined' ? options.waitingTime : DEFAULT_TIMEOUT_BETWEEN_STEPS;
typeof options.customTexts !== 'undefined' ? this.setCustomText(options.customTexts) : this.setCustomText(DEFAULT_TEXTS);
}

getBackdropColor() {
Expand All @@ -99,6 +79,10 @@ export class JoyrideOptionsService implements IJoyrideOptionsService {
return this.firstStep;
}

getFixedHeader() {
return this.fixedHeader;
}

getWaitingTime() {
return this.waitingTime;
}
Expand All @@ -120,38 +104,30 @@ export class JoyrideOptionsService implements IJoyrideOptionsService {
}

private setCustomText(texts: CustomTexts) {
let prev: string | Observable<string>;
let next: string | Observable<string>;
let done;
let close;
let prev, next, done, close: string | Observable<string>;
prev = texts.prev ? texts.prev : DEFAULT_TEXTS.prev;
next = texts.next ? texts.next : DEFAULT_TEXTS.next;
done = texts.done ? texts.done : DEFAULT_TEXTS.done;
close = texts.close ? texts.close : DEFAULT_TEXTS.close;
this.customTexts = {
this.customTexts = <ObservableCustomTexts>{
prev: this.toObservable(prev),
next: this.toObservable(next),
done: this.toObservable(done),
close: this.toObservable(close)
} as ObservableCustomTexts;
};
}

private toObservable(value: string | Observable<string>) {
return value instanceof Observable ? value : of(value);
}

private hexToRgb(hex: any): string {
const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, (m: any, r: any, g: any, b: any) => {
return r + r + g + g + b + b;
});

const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result
? `${parseInt(result[1], 16)}, ${parseInt(
result[2],
16
)}, ${parseInt(result[3], 16)}`
: null;
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? `${parseInt(result[1], 16)}, ${parseInt(result[2], 16)}, ${parseInt(result[3], 16)}` : null;
}
}
23 changes: 17 additions & 6 deletions projects/ngx-joyride/src/lib/services/joyride-step.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class JoyrideStepService implements IJoyrideStepService {
private winTopPosition: number = 0;
private winBottomPosition: number = 0;
private stepsObserver: ReplaySubject<JoyrideStepInfo> = new ReplaySubject<JoyrideStepInfo>();

private fixedHeaderHeight: number = 0;
constructor(
private readonly backDropService: JoyrideBackdropService,
private readonly eventListener: EventListenerService,
Expand Down Expand Up @@ -105,10 +105,10 @@ export class JoyrideStepService implements IJoyrideStepService {
this.tryShowStep(StepActionType.NEXT);
}

private async navigateToStepPage(action: StepActionType) {
private navigateToStepPage(action: StepActionType) {
let stepRoute = this.stepsContainerService.getStepRoute(action);
if (stepRoute) {
return await this.router.navigate([stepRoute]);
this.router.navigate([stepRoute]);
}
}

Expand All @@ -120,9 +120,16 @@ export class JoyrideStepService implements IJoyrideStepService {
});
}

private async tryShowStep(actionType: StepActionType) {
await this.navigateToStepPage(actionType);
private tryShowStep(actionType: StepActionType) {
this.navigateToStepPage(actionType);
const timeout = this.optionsService.getWaitingTime();
const fixedHeader = this.optionsService.getFixedHeader();
if(fixedHeader) {
const fixedHeaderEl = this.DOMService.getNativeDocument().body.querySelector(fixedHeader);
if(fixedHeaderEl) {
this.fixedHeaderHeight = fixedHeaderEl.getBoundingClientRect().height;
}
}
if (timeout > 100) this.backDropService.remove();
setTimeout(() => {
try {
Expand All @@ -144,12 +151,12 @@ export class JoyrideStepService implements IJoyrideStepService {
this.currentStep = this.stepsContainerService.get(actionType);

if (this.currentStep == null) throw new JoyrideStepDoesNotExist('');
this.notifyStepClicked(actionType);
// Scroll the element to get it visible if it's in a scrollable element
this.scrollIfElementBeyondOtherElements();
this.backDropService.draw(this.currentStep);
this.drawStep(this.currentStep);
this.scrollIfStepAndTargetAreNotVisible();
this.notifyStepClicked(actionType);
}

private notifyStepClicked(actionType: StepActionType) {
Expand Down Expand Up @@ -230,6 +237,10 @@ export class JoyrideStepService implements IJoyrideStepService {
if (this.isElementBeyondOthers() === 2) {
this.documentService.scrollToTheBottom(this.currentStep.targetViewContainer.element);
}

if (this.isElementBeyondOthers() === 2 && this.documentService.isParentScrollable(this.currentStep.targetViewContainer.element)) { // Added to handle middle section & with parentscrollable
this.documentService.scrollIntoView(this.currentStep.targetViewContainer.element, this.currentStep.isElementOrAncestorFixed, this.fixedHeaderHeight);
}
if (this.isElementBeyondOthers() === 1 && this.documentService.isParentScrollable(this.currentStep.targetViewContainer.element)) {
this.documentService.scrollIntoView(this.currentStep.targetViewContainer.element, this.currentStep.isElementOrAncestorFixed);
}
Expand Down

0 comments on commit 5c7f3e9

Please sign in to comment.