|
| 1 | +import { ReferrerService } from './referrer.service'; |
| 2 | +import { Observable } from 'rxjs'; |
| 3 | +import { map } from 'rxjs/operators'; |
| 4 | +import { hasNoValue } from '../../shared/empty.util'; |
| 5 | +import { URLCombiner } from '../url-combiner/url-combiner'; |
| 6 | +import { Inject, Injectable } from '@angular/core'; |
| 7 | +import { DOCUMENT } from '@angular/common'; |
| 8 | +import { HardRedirectService } from './hard-redirect.service'; |
| 9 | +import { RouteService } from './route.service'; |
| 10 | + |
| 11 | +/** |
| 12 | + * A service to determine the referrer |
| 13 | + * |
| 14 | + * The browser implementation will get the referrer from document.referrer, in the event that the |
| 15 | + * previous page visited was not an angular URL. If it was, the route history in the store must be |
| 16 | + * used, since document.referrer doesn't get updated on route changes |
| 17 | + */ |
| 18 | +@Injectable() |
| 19 | +export class BrowserReferrerService extends ReferrerService { |
| 20 | + |
| 21 | + constructor( |
| 22 | + @Inject(DOCUMENT) protected document: any, |
| 23 | + protected routeService: RouteService, |
| 24 | + protected hardRedirectService: HardRedirectService, |
| 25 | + ) { |
| 26 | + super(); |
| 27 | + } |
| 28 | + |
| 29 | + /** |
| 30 | + * Return the referrer |
| 31 | + * |
| 32 | + * Return the referrer URL based on the route history in the store. If there is no route history |
| 33 | + * in the store yet, document.referrer will be used |
| 34 | + */ |
| 35 | + public getReferrer(): Observable<string> { |
| 36 | + return this.routeService.getHistory().pipe( |
| 37 | + map((history: string[]) => { |
| 38 | + const currentURL = history[history.length - 1]; |
| 39 | + // if the current URL isn't set yet, or the only URL in the history is the current one, |
| 40 | + // return document.referrer (note that that may be empty too, e.g. if you've just opened a |
| 41 | + // new browser tab) |
| 42 | + if (hasNoValue(currentURL) || history.every((url: string) => url === currentURL)) { |
| 43 | + return this.document.referrer; |
| 44 | + } else { |
| 45 | + // reverse the history |
| 46 | + const reversedHistory = [...history].reverse(); |
| 47 | + // and find the first URL that differs from the current one |
| 48 | + const prevUrl = reversedHistory.find((url: string) => url !== currentURL); |
| 49 | + return new URLCombiner(this.hardRedirectService.getCurrentOrigin(), prevUrl).toString(); |
| 50 | + } |
| 51 | + }) |
| 52 | + ); |
| 53 | + } |
| 54 | +} |
0 commit comments