Skip to content

Commit 02d77e4

Browse files
refactor(url): Move coreservices.location to router.urlService
1 parent eb12ec8 commit 02d77e4

File tree

5 files changed

+100
-31
lines changed

5 files changed

+100
-31
lines changed

src/common/coreservices.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
/** for typedoc */
88
import {IInjectable, Obj} from "./common";
99

10-
let notImplemented = (fnname: string) => () => {
10+
export let notImplemented = (fnname: string) => () => {
1111
throw new Error(`${fnname}(): No coreservices implementation for UI-Router is loaded.`);
1212
};
1313

src/hooks/lazyLoad.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,16 @@ const lazyLoadHook: TransitionHookFn = (transition: Transition) => {
3636

3737
function retryOriginalTransition() {
3838
if (transitionSource(transition) === 'url') {
39-
let $loc = services.location,
39+
let $loc = transition.router.urlService,
40+
$reg = transition.router.stateRegistry,
4041
path = $loc.path(),
4142
search = $loc.search(),
4243
hash = $loc.hash();
4344

4445
let matchState = state =>
4546
[state, state.url && state.url.exec(path, search, hash)];
4647

47-
let matches = transition.router.stateRegistry.get()
48+
let matches = $reg.get()
4849
.map(s => s.$$state())
4950
.map(matchState)
5051
.filter(([state, params]) => !!params);

src/router.ts

+10
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import { UIRouterGlobals, Globals } from "./globals";
1313
import { UIRouterPlugin, Disposable } from "./interface";
1414
import { values, removeFrom } from "./common/common";
1515
import { isFunction } from "./common/predicates";
16+
import { UrlService } from "./url/urlService";
17+
import { services, LocationServices, LocationConfig } from "./common/coreservices";
1618

1719
/** @hidden */
1820
let _routerInstance = 0;
@@ -48,6 +50,14 @@ export class UIRouter {
4850

4951
stateService = new StateService(this);
5052

53+
get urlService(): LocationServices {
54+
return services.location;
55+
}
56+
57+
get urlConfig(): LocationConfig {
58+
return services.locationConfig;
59+
}
60+
5161
private _disposables: Disposable[] = [];
5262

5363
/** Registers an object to be notified when the router is disposed */

src/url/urlRouter.ts

+23-28
Original file line numberDiff line numberDiff line change
@@ -40,31 +40,6 @@ function appendBasePath(url: string, isHtml5: boolean, absolute: boolean): strin
4040
return url;
4141
}
4242

43-
// TODO: Optimize groups of rules with non-empty prefix into some sort of decision tree
44-
/** @hidden */
45-
function update(rules: Function[], otherwiseFn: Function, evt?: any) {
46-
if (evt && evt.defaultPrevented) return;
47-
let $loc = services.location;
48-
49-
function check(rule: Function) {
50-
let handled = rule(services.$injector, $loc);
51-
52-
if (!handled) return false;
53-
if (isString(handled)) {
54-
$loc.setUrl(handled, true);
55-
}
56-
return true;
57-
}
58-
let n = rules.length;
59-
60-
for (let i = 0; i < n; i++) {
61-
if (check(rules[i])) return;
62-
}
63-
// always check otherwise last to allow dynamic updates to the set of rules
64-
if (otherwiseFn) check(otherwiseFn);
65-
}
66-
67-
6843
/**
6944
* Manages rules for client-side URL
7045
*
@@ -346,8 +321,28 @@ export class UrlRouter implements Disposable {
346321
* });
347322
* ```
348323
*/
349-
sync() {
350-
update(this.urlRouterProvider.rules, this.urlRouterProvider.otherwiseFn);
324+
sync(evt?) {
325+
if (evt && evt.defaultPrevented) return;
326+
let $loc = services.location;
327+
let rules = this.urlRouterProvider.rules;
328+
let otherwiseFn = this.urlRouterProvider.otherwiseFn;
329+
330+
function check(rule: Function) {
331+
let handled = rule(services.$injector, $loc);
332+
333+
if (!handled) return false;
334+
if (isString(handled)) {
335+
$loc.setUrl(handled, true);
336+
}
337+
return true;
338+
}
339+
let n = rules.length;
340+
341+
for (let i = 0; i < n; i++) {
342+
if (check(rules[i])) return;
343+
}
344+
// always check otherwise last to allow dynamic updates to the set of rules
345+
if (otherwiseFn) check(otherwiseFn);
351346
}
352347

353348
/**
@@ -357,7 +352,7 @@ export class UrlRouter implements Disposable {
357352
* This causes [[UrlRouter]] to start listening for changes to the URL, if it wasn't already listening.
358353
*/
359354
listen(): Function {
360-
return this.listener = this.listener || services.location.onChange(evt => update(this.urlRouterProvider.rules, this.urlRouterProvider.otherwiseFn, evt));
355+
return this.listener = this.listener || services.location.onChange(evt => this.sync(evt));
361356
}
362357

363358
/**

src/url/urlService.ts

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/** @module url */ /** */
2+
3+
import { UIRouter } from "../router";
4+
import { LocationServices, notImplemented, LocationConfig } from "../common/coreservices";
5+
import { noop, createProxyFunctions } from "../common/common";
6+
7+
/** @hidden */
8+
const makeStub = (keys: string[]): any =>
9+
keys.reduce((acc, key) => (acc[key] = notImplemented(key), acc), { dispose: noop });
10+
11+
/** @hidden */
12+
const locationServicesFns = ["setUrl", "path", "search", "hash", "onChange"];
13+
/** @hidden */
14+
const locationConfigFns = ["port", "protocol", "host", "baseHref", "html5Mode", "hashPrefix"];
15+
16+
/**
17+
* Service methods related to URL management
18+
*
19+
* This class delegates to other URL services.
20+
*
21+
* - [[LocationService]]: Framework specific code to interact with the browser URL
22+
* - [[LocationConfig]]: Framework specific code to interact with the browser URL
23+
* - [[UrlMatcherFactory]]:
24+
* - [[UrlRouter]]:
25+
*/
26+
export class UrlService implements LocationServices {
27+
/** @hidden */
28+
static locationServiceStub: LocationServices = makeStub(locationServicesFns);
29+
/** @hidden */
30+
static locationConfigStub: LocationConfig = makeStub(locationConfigFns);
31+
32+
/** @inheritdoc */
33+
setUrl(newurl: string, replace?: boolean): void { return };
34+
/** @inheritdoc */
35+
path(): string { return };
36+
/** @inheritdoc */
37+
search(): { [key: string]: any } { return };
38+
/** @inheritdoc */
39+
hash(): string { return };
40+
/** @inheritdoc */
41+
onChange(callback: Function): Function { return };
42+
43+
dispose() { }
44+
45+
/**
46+
* The [[LocationConfig]] service
47+
*
48+
* This object returns information about the location (url) configuration.
49+
* This information can be used to build absolute URLs, such as
50+
* `https://example.com:443/basepath/state/substate?param1=a#hashvalue`;
51+
*/
52+
config: LocationConfig;
53+
54+
constructor(router: UIRouter) {
55+
this.config = {} as any;
56+
// proxy function calls from UrlService to the LocationService/LocationConfig
57+
const svc = () => router.locationService;
58+
createProxyFunctions(svc, this, svc, locationServicesFns);
59+
60+
const cfg = () => router.locationConfig;
61+
createProxyFunctions(cfg, this.config, cfg, locationConfigFns);
62+
}
63+
}

0 commit comments

Comments
 (0)