Skip to content

Commit 7a03cac

Browse files
refactor(LocationServices): Create BaseLocationServices class to consolidate code paths
1 parent 7c90911 commit 7a03cac

16 files changed

+254
-222
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"watch": "run-p watch:*",
1111
"watch:buildjs": "tsc -w",
1212
"watch:buildesm": "tsc -w -m es6 --outDir lib-esm",
13+
"watch:dts-downlevel": "npm run fixdts",
1314
"watch:test": "karma start --singleRun=false --autoWatch=true --autoWatchInterval=1",
1415
"debug": "karma start --singleRun=false --autoWatch=true --autoWatchInterval=1 --browsers=Chrome"
1516
},

src/vanilla/$injector.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
/**
22
* @internalapi
33
* @module vanilla
4-
*/ /** */
4+
*/
5+
/** */
56
import {
6-
extend, assertPredicate, isFunction, isArray, isInjectable, $InjectorLike, IInjectable
7+
extend, assertPredicate, isFunction, isArray, isInjectable, $InjectorLike, IInjectable
78
} from "../common/index";
89

910
// globally available injectables

src/vanilla/$q.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/**
22
* @internalapi
33
* @module vanilla
4-
*/ /** */
4+
*/
5+
/** */
56
import { isArray, isObject, $QLike } from "../common/index";
67

78
/**

src/vanilla/baseLocationService.ts

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* @internalapi
3+
* @module vanilla
4+
*/ /** */
5+
6+
import { LocationServices } from "../common/coreservices";
7+
import { Disposable } from "../interface";
8+
import { UIRouter } from "../router";
9+
import { LocationLike, HistoryLike } from "./interface";
10+
import { parseUrl, getParams, buildUrl } from "./utils";
11+
import { isDefined } from "../common/predicates";
12+
import { extend, deregAll, removeFrom } from "../common/common";
13+
/** A base `LocationServices` */
14+
export abstract class BaseLocationServices implements LocationServices, Disposable {
15+
constructor(router: UIRouter, public fireAfterUpdate: boolean) {
16+
this._location = window && window.location;
17+
this._history = window && window.history;
18+
}
19+
20+
_listener = evt => this._listeners.forEach(cb => cb(evt));
21+
22+
private _listeners: Function[] = [];
23+
_location: LocationLike;
24+
_history: HistoryLike;
25+
26+
abstract _get(): string;
27+
abstract _set(state: any, title: string, url: string, replace: boolean);
28+
29+
hash = () => parseUrl(this._get()).hash;
30+
path = () => parseUrl(this._get()).path;
31+
search = () => getParams(parseUrl(this._get()).search);
32+
33+
url(url?: string, replace: boolean = true): string {
34+
if (isDefined(url) && url !== this._get()) {
35+
this._set(null, null, url, replace);
36+
37+
if (this.fireAfterUpdate) {
38+
let evt = extend(new Event("locationchange"), { url });
39+
this._listeners.forEach(cb => cb(evt));
40+
}
41+
}
42+
43+
return buildUrl(this);
44+
}
45+
46+
onChange(cb: EventListener) {
47+
this._listeners.push(cb);
48+
return () => removeFrom(this._listeners, cb);
49+
}
50+
51+
dispose(router: UIRouter) {
52+
deregAll(this._listeners);
53+
}
54+
}

src/vanilla/browserLocationConfig.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/**
22
* @internalapi
33
* @module vanilla
4-
*/ /** */
5-
4+
*/
5+
/** */
66
import { isDefined } from "../common/predicates";
77
import { LocationConfig } from "../common/coreservices";
88

src/vanilla/hashLocation.ts

-43
This file was deleted.

src/vanilla/hashLocationService.ts

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* @internalapi
3+
* @module vanilla
4+
*/
5+
/** */
6+
import { trimHashVal } from "./utils";
7+
import { UIRouter } from "../router";
8+
import { BaseLocationServices } from "./baseLocationService";
9+
10+
/** A `LocationServices` that uses the browser hash "#" to get/set the current location */
11+
export class HashLocationService extends BaseLocationServices {
12+
constructor(router: UIRouter) {
13+
super(router, false);
14+
window.addEventListener('hashchange', this._listener, false);
15+
}
16+
17+
_get() {
18+
return trimHashVal(this._location.hash);
19+
}
20+
_set(state: any, title: string, url: string, replace: boolean) {
21+
this._location.hash = url;
22+
}
23+
24+
dispose (router: UIRouter) {
25+
super.dispose(router);
26+
window.removeEventListener('hashchange', this._listener);
27+
}
28+
}
29+

src/vanilla/index.ts

+11-17
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,17 @@
44
*
55
* @internalapi
66
* @module vanilla
7-
*/ /** */
8-
import { UIRouter } from "../router";
7+
*/
8+
/** */
9+
export * from "./$q";
10+
export * from "./$injector";
911

10-
import { services } from "../common/coreservices";
11-
import { ServicesPlugin } from "./interface";
12-
import { $q } from "./$q";
13-
import { $injector } from "./$injector";
12+
export * from "./baseLocationService";
13+
export * from "./hashLocationService";
14+
export * from "./memoryLocationService";
15+
export * from "./pushStateLocationService";
1416

15-
export { $q, $injector };
17+
export * from "./memoryLocationConfig";
18+
export * from "./browserLocationConfig";
1619

17-
export function servicesPlugin(router: UIRouter): ServicesPlugin {
18-
services.$injector = $injector;
19-
services.$q = $q;
20-
21-
return { name: "vanilla.services", $q, $injector, dispose: () => null };
22-
}
23-
24-
export * from "./hashLocation";
25-
export * from "./memoryLocation";
26-
export * from "./pushStateLocation";
20+
export * from "./plugins";

src/vanilla/interface.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
/**
22
* @internalapi
33
* @module vanilla
4-
*/ /** */
5-
import { LocationConfig, LocationServices } from '../common/coreservices';
4+
*/
5+
/** */
6+
import { LocationConfig, LocationServices } from "../common/coreservices";
67
import { UIRouterPlugin } from "../interface";
78
import { $InjectorLike, $QLike } from "../common/index";
89

src/vanilla/memoryLocation.ts

-77
This file was deleted.

src/vanilla/memoryLocationConfig.ts

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* @internalapi
3+
* @module vanilla
4+
*/
5+
/** */
6+
import { LocationConfig } from "../common/coreservices";
7+
import { isDefined } from "../common/predicates";
8+
import { noop } from "../common/common";
9+
10+
/** A `LocationConfig` mock that gets/sets all config from an in-memory object */
11+
export class MemoryLocationConfig implements LocationConfig {
12+
_baseHref = '';
13+
_port = 80;
14+
_protocol = "http";
15+
_host = "localhost";
16+
_hashPrefix = "";
17+
18+
port = () => this._port;
19+
protocol = () => this._protocol;
20+
host = () => this._host;
21+
baseHref = () => this._baseHref;
22+
html5Mode = () => false;
23+
hashPrefix = (newval?) => isDefined(newval) ? this._hashPrefix = newval : this._hashPrefix;
24+
dispose = noop;
25+
}

src/vanilla/memoryLocationService.ts

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* @internalapi
3+
* @module vanilla
4+
*/
5+
/** */
6+
import { BaseLocationServices } from "./baseLocationService";
7+
import { UIRouter } from "../router";
8+
9+
/** A `LocationServices` that gets/sets the current location from an in-memory object */
10+
export class MemoryLocationService extends BaseLocationServices {
11+
_url: string;
12+
13+
constructor(router: UIRouter) {
14+
super(router, true);
15+
}
16+
17+
_get() {
18+
return this._url;
19+
}
20+
21+
_set(state: any, title: string, url: string, replace: boolean) {
22+
this._url = url;
23+
}
24+
}

src/vanilla/plugins.ts

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* @internalapi
3+
* @module vanilla
4+
*/
5+
/** */
6+
import { BrowserLocationConfig } from "./browserLocationConfig";
7+
import { HashLocationService } from "./hashLocationService";
8+
import { locationPluginFactory } from "./utils";
9+
import { LocationPlugin, ServicesPlugin } from "./interface";
10+
import { UIRouter } from "../router";
11+
import { PushStateLocationService } from "./pushStateLocationService";
12+
import { MemoryLocationService } from "./memoryLocationService";
13+
import { MemoryLocationConfig } from "./memoryLocationConfig";
14+
import { $injector } from "./$injector";
15+
import { $q } from "./$q";
16+
import { services } from "../common/coreservices";
17+
18+
export function servicesPlugin(router: UIRouter): ServicesPlugin {
19+
services.$injector = $injector;
20+
services.$q = $q;
21+
22+
return { name: "vanilla.services", $q, $injector, dispose: () => null };
23+
}
24+
25+
/** A `UIRouterPlugin` uses the browser hash to get/set the current location */
26+
export const hashLocationPlugin: (router: UIRouter) => LocationPlugin =
27+
locationPluginFactory('vanilla.hashBangLocation', false, HashLocationService, BrowserLocationConfig);
28+
29+
/** A `UIRouterPlugin` that gets/sets the current location using the browser's `location` and `history` apis */
30+
export const pushStateLocationPlugin: (router: UIRouter) => LocationPlugin =
31+
locationPluginFactory("vanilla.pushStateLocation", true, PushStateLocationService, BrowserLocationConfig);
32+
33+
/** A `UIRouterPlugin` that gets/sets the current location from an in-memory object */
34+
export const memoryLocationPlugin: (router: UIRouter) => LocationPlugin =
35+
locationPluginFactory("vanilla.memoryLocation", false, MemoryLocationService, MemoryLocationConfig);

0 commit comments

Comments
 (0)