fboeller/ngx-elements-router

It seems like `NoopLocationStrategy` doesn't work in certain websites.

Closed this issue · 3 comments

We're currently developing a chrome extension and it works fine on all websites except against dev.to

Is there a way to customize NoopLocationStrategy or a workaround for certain websites?

I was able to create a workaround for dev.to

What i did was override the prepareExternalUrl and just keep on returning the set base href.

import {
  APP_BASE_HREF,
  LocationChangeListener,
  LocationStrategy,
  PlatformLocation,
} from '@angular/common';
import { Inject, Injectable, Optional } from '@angular/core';

@Injectable()
export class CustomNoopLocationStrategy extends LocationStrategy {
  private readonly baseHref: string;

  constructor(
    private platformLocation: PlatformLocation,
    @Optional() @Inject(APP_BASE_HREF) baseHref?: string
  ) {
    super();
    this.baseHref = baseHref || this.platformLocation.getBaseHrefFromDOM();
    if (!this.baseHref) {
      throw new Error(
        `No base href set. Please provide a value for the APP_BASE_HREF token or add a base element to the document.`
      );
    }
  }

  onPopState(fn: LocationChangeListener): void {}

  getBaseHref(): string {
    return this.baseHref;
  }

  path(includeHash: boolean = false): string {
    return '';
  }

  prepareExternalUrl(internal: string): string {
    // if (this.baseHref.endsWith('/') && internal.startsWith('/')) {
    // return this.baseHref.substring(0, this.baseHref.length - 1) + internal;
    // } else if (this.baseHref.endsWith('/') || internal.startsWith('/')) {
    // return this.baseHref + internal;
    // } else {
    // return `${this.baseHref}/${internal}`;
    // }
    return `${this.baseHref}`;
  }

  pushState(
    state: any,
    title: string,
    path: string,
    queryParams: string
  ): void {}

  replaceState(
    state: any,
    title: string,
    path: string,
    queryParams: string
  ): void {}

  forward(): void {}

  back(): void {}

  historyGo(): void {}
}

any reason why we have to keep track of internal path argument from prepareExternalUrl?

Hey @chan-dev!
The internal argument is the part from routerLink like /my-route/abc/efg. prepareExternalUrl is used by Angular to figure out what URL to put on a native a element such that the browser can figure out on its own where to lead the user. By changing it to just the base href, I'd expect that every link now just goes to the application at root itself.

What problems have you seen with the NoopLocationStrategy with dev.to?
The implementation of prepareExternalUrl is in itself derived from the PathLocationStrategy of Angular (https://github.com/angular/angular/blob/0af354ce056c7e6254bd17a52d4199bf86f51c0e/packages/common/src/location/location_strategy.ts#L147)

@fboeller Since we're using Angular routing inside chrome extension, we don't want the extension to change the current page's url. This extension helps us most of the case except in the case of when visiting dev.to, it still changes the dev.to url.

Let's say we're currently visiting dev.to and user has redirected to route /test1 inside chrome extension, then what happens is the browser url will redirect to dev.to/test1 instead of being entirely isolated within the chrome extension.