diff --git a/src/common/coreservices.ts b/src/common/coreservices.ts index a7b8134b..8f0c0f04 100644 --- a/src/common/coreservices.ts +++ b/src/common/coreservices.ts @@ -6,6 +6,7 @@ */ /** for typedoc */ import {IInjectable, Obj} from "./common"; +import { Disposable } from "../interface"; export let notImplemented = (fnname: string) => () => { throw new Error(`${fnname}(): No coreservices implementation for UI-Router is loaded.`); @@ -14,17 +15,9 @@ export let notImplemented = (fnname: string) => () => { let services: CoreServices = { $q: undefined, $injector: undefined, - location: {}, - locationConfig: {}, template: {} }; -["setUrl", "path", "search", "hash", "onChange"] - .forEach(key => services.location[key] = notImplemented(key)); - -["port", "protocol", "host", "baseHref", "html5Mode", "hashPrefix" ] - .forEach(key => services.locationConfig[key] = notImplemented(key)); - export interface $QLikeDeferred { resolve: (val?: any) => void; reject: (reason?: any) => void; @@ -51,30 +44,25 @@ export interface $InjectorLike { export interface CoreServices { $q: $QLike; $injector: $InjectorLike; - /** Services related to getting or setting the browser location (url) */ - location: LocationServices; - /** Retrieves configuration for how to construct a URL. */ - locationConfig: LocationConfig; template: TemplateServices; } -export interface LocationServices { +export interface LocationServices extends Disposable { setUrl(newurl: string, replace?: boolean): void; path(): string; search(): { [key: string]: any }; hash(): string; onChange(callback: Function): Function; - html5Mode(): boolean; - hashPrefix(): string; - hashPrefix(newprefix: string): string; } -export interface LocationConfig { +export interface LocationConfig extends Disposable { port(): number; protocol(): string; host(): string; - baseHref(): string; + html5Mode(): boolean; + hashPrefix(): string; + hashPrefix(newprefix: string): string; } export interface TemplateServices { diff --git a/src/vanilla/browserLocationConfig.ts b/src/vanilla/browserLocationConfig.ts index 2f715c54..eb2dd9b3 100644 --- a/src/vanilla/browserLocationConfig.ts +++ b/src/vanilla/browserLocationConfig.ts @@ -9,20 +9,32 @@ import { LocationConfig } from "../common/coreservices"; /** A `LocationConfig` that delegates to the browser's `location` object */ export class BrowserLocationConfig implements LocationConfig { private _baseHref = undefined; + private _hashPrefix = ""; - port() { + constructor(router?, private _isHtml5 = false) { } + + port(): number { return parseInt(location.port); } - protocol () { + protocol(): string { return location.protocol; } - host() { + host(): string { return location.host; } - baseHref(href?: string) { + html5Mode(): boolean { + return this._isHtml5; + } + + hashPrefix(): string; + hashPrefix(newprefix?: string): string { + return isDefined(newprefix) ? this._hashPrefix = newprefix : this._hashPrefix; + }; + + baseHref(href?: string): string { return isDefined(href) ? this._baseHref = href : this._baseHref || this.applyDocumentBaseHref(); } @@ -30,4 +42,6 @@ export class BrowserLocationConfig implements LocationConfig { let baseTags = document.getElementsByTagName("base"); return this._baseHref = baseTags.length ? baseTags[0].href.substr(location.origin.length) : ""; } + + dispose() {} } \ No newline at end of file diff --git a/src/vanilla/hashLocation.ts b/src/vanilla/hashLocation.ts index b0f4f16f..e806e7cd 100644 --- a/src/vanilla/hashLocation.ts +++ b/src/vanilla/hashLocation.ts @@ -14,7 +14,6 @@ import { BrowserLocationConfig } from "./browserLocationConfig"; /** A `LocationServices` that uses the browser hash "#" to get/set the current location */ export class HashLocationService implements LocationServices, Disposable { private _listeners: Function[] = []; - private _hashPrefix = ""; hash() { return splitHash(trimHashVal(location.hash))[1]; @@ -37,17 +36,6 @@ export class HashLocationService implements LocationServices, Disposable { return pushTo(this._listeners, () => window.removeEventListener('hashchange', cb)); } - html5Mode() { - return false; - } - - hashPrefix(newprefix?: string): string { - if(isDefined(newprefix)) { - this._hashPrefix = newprefix; - } - return this._hashPrefix; - } - dispose() { deregAll(this._listeners); } @@ -55,4 +43,4 @@ export class HashLocationService implements LocationServices, Disposable { /** A `UIRouterPlugin` uses the browser hash to get/set the current location */ export const hashLocationPlugin: (router: UIRouter) => LocationPlugin = - locationPluginFactory('vanilla.hashBangLocation', HashLocationService, BrowserLocationConfig); + locationPluginFactory('vanilla.hashBangLocation', false, HashLocationService, BrowserLocationConfig); diff --git a/src/vanilla/memoryLocation.ts b/src/vanilla/memoryLocation.ts index d7ecbd50..f31ab788 100644 --- a/src/vanilla/memoryLocation.ts +++ b/src/vanilla/memoryLocation.ts @@ -5,7 +5,7 @@ import { isDefined } from "../common/index"; import { LocationConfig, LocationServices } from "../common/coreservices"; import { splitQuery, getParams, splitHash, locationPluginFactory } from "./utils"; -import { removeFrom, unnestR, deregAll } from "../common/common"; +import { removeFrom, unnestR, deregAll, noop } from "../common/common"; import { UIRouter } from "../router"; import { LocationPlugin } from "./interface"; import { isArray } from "../common/predicates"; @@ -17,17 +17,20 @@ export class MemoryLocationConfig implements LocationConfig { _port = 80; _protocol = "http"; _host = "localhost"; + _hashPrefix = ""; port = () => this._port; protocol = () => this._protocol; host = () => this._host; baseHref = () => this._baseHref; + html5Mode = () => false; + hashPrefix = (newval?) => isDefined(newval) ? this._hashPrefix = newval : this._hashPrefix; + dispose = noop; } /** A `LocationServices` that gets/sets the current location from an in-memory object */ export class MemoryLocationService implements LocationServices, Disposable { _listeners: Function[] = []; - _hashPrefix = ""; _url = { path: '', search: {}, @@ -65,14 +68,6 @@ export class MemoryLocationService implements LocationServices, Disposable { return this._url.search; } - html5Mode() { - return false; - } - - hashPrefix(newprefix?: string): string { - return isDefined(newprefix) ? this._hashPrefix = newprefix : this._hashPrefix; - } - setUrl(url: string, replace: boolean = false) { if (isDefined(url)) { let path = splitHash(splitQuery(url)[0])[0]; @@ -98,4 +93,4 @@ export class MemoryLocationService implements LocationServices, Disposable { /** A `UIRouterPlugin` that gets/sets the current location from an in-memory object */ export const memoryLocationPlugin: (router: UIRouter) => LocationPlugin = - locationPluginFactory("vanilla.memoryLocation", MemoryLocationService, MemoryLocationConfig); \ No newline at end of file + locationPluginFactory("vanilla.memoryLocation", false, MemoryLocationService, MemoryLocationConfig); \ No newline at end of file diff --git a/src/vanilla/pushStateLocation.ts b/src/vanilla/pushStateLocation.ts index cd2a4a73..ee349f02 100644 --- a/src/vanilla/pushStateLocation.ts +++ b/src/vanilla/pushStateLocation.ts @@ -3,7 +3,7 @@ * @module vanilla */ /** */ import { isDefined } from "../common/index"; -import { LocationServices } from "../common/coreservices"; +import { LocationServices, LocationConfig } from "../common/coreservices"; import { splitQuery, trimHashVal, getParams, locationPluginFactory } from "./utils"; import { LocationPlugin } from "./interface"; import { UIRouter } from "../router"; @@ -18,13 +18,14 @@ import { BrowserLocationConfig } from "./browserLocationConfig"; */ export class PushStateLocationService implements LocationServices, Disposable { private _listeners: Function[] = []; - private _hashPrefix = ""; private _location: Location; private _history: History; + private _config: LocationConfig; - constructor(public router: UIRouter) { + constructor(router: UIRouter) { this._location = location; this._history = history; + this._config = router.urlService.config; }; hash() { @@ -32,7 +33,7 @@ export class PushStateLocationService implements LocationServices, Disposable { } path() { - let base = this.router.urlConfig.baseHref(); + let base = this._config.baseHref(); let path = this._location.pathname; let idx = path.indexOf(base); if (idx !== 0) throw new Error(`current url: ${path} does not start with tag ${base}`); @@ -45,7 +46,7 @@ export class PushStateLocationService implements LocationServices, Disposable { setUrl(url: string, replace: boolean = false) { if (isDefined(url)) { - let fullUrl = this.router.urlConfig.baseHref() + url; + let fullUrl = this._config.baseHref() + url; if (replace) this._history.replaceState(null, null, fullUrl); else this._history.pushState(null, null, fullUrl); } @@ -56,23 +57,12 @@ export class PushStateLocationService implements LocationServices, Disposable { return pushTo(this._listeners, () => window.removeEventListener("popstate", cb)); } - html5Mode() { - return true; - } - - hashPrefix(newprefix?: string): string { - if(isDefined(newprefix)) { - this._hashPrefix = newprefix; - } - return this._hashPrefix; - } - dispose(router: UIRouter) { deregAll(this._listeners); } -}; +} /** A `UIRouterPlugin` that gets/sets the current location using the browser's `location` and `history` apis */ export const pushStateLocationPlugin: (router: UIRouter) => LocationPlugin = - locationPluginFactory("vanilla.pushStateLocation", PushStateLocationService, BrowserLocationConfig); + locationPluginFactory("vanilla.pushStateLocation", true, PushStateLocationService, BrowserLocationConfig);