more url router work, differentiate between path and url
rename hashobservable to history
This commit is contained in:
parent
547241f577
commit
4fe971775c
3 changed files with 37 additions and 27 deletions
|
@ -17,17 +17,17 @@ limitations under the License.
|
||||||
import {Segment} from "./Navigation.js";
|
import {Segment} from "./Navigation.js";
|
||||||
|
|
||||||
export class URLRouter {
|
export class URLRouter {
|
||||||
constructor(pathObservable, navigation) {
|
constructor(history, navigation) {
|
||||||
this._subscription = null;
|
this._subscription = null;
|
||||||
this._pathObservable = pathObservable;
|
this._history = history;
|
||||||
this._navigation = navigation;
|
this._navigation = navigation;
|
||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
this._subscription = this._pathObservable.subscribe(url => {
|
this._subscription = this._history.subscribe(url => {
|
||||||
this._applyUrl(url);
|
this._applyUrl(url);
|
||||||
});
|
});
|
||||||
this._applyUrl(this._pathObservable.get());
|
this._applyUrl(this._history.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
_applyUrl(url) {
|
_applyUrl(url) {
|
||||||
|
@ -40,7 +40,8 @@ export class URLRouter {
|
||||||
this._subscription = this._subscription();
|
this._subscription = this._subscription();
|
||||||
}
|
}
|
||||||
|
|
||||||
_segmentsFromUrl(path) {
|
_segmentsFromUrl(url) {
|
||||||
|
const path = this._history.urlAsPath(url);
|
||||||
const parts = path.split("/").filter(p => !!p);
|
const parts = path.split("/").filter(p => !!p);
|
||||||
let index = 0;
|
let index = 0;
|
||||||
const segments = [];
|
const segments = [];
|
||||||
|
@ -58,6 +59,10 @@ export class URLRouter {
|
||||||
return segments;
|
return segments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
replaceUrl(url) {
|
||||||
|
this._history.replaceUrl(url);
|
||||||
|
}
|
||||||
|
|
||||||
urlForSegment(type, value) {
|
urlForSegment(type, value) {
|
||||||
const path = this._navigation.path.with(new Segment(type, value));
|
const path = this._navigation.path.with(new Segment(type, value));
|
||||||
if (path) {
|
if (path) {
|
||||||
|
@ -66,14 +71,14 @@ export class URLRouter {
|
||||||
}
|
}
|
||||||
|
|
||||||
urlForPath(path) {
|
urlForPath(path) {
|
||||||
let url = "#";
|
let urlPath = "";
|
||||||
for (const {type, value} of path.segments) {
|
for (const {type, value} of path.segments) {
|
||||||
if (typeof value === "boolean") {
|
if (typeof value === "boolean") {
|
||||||
url += `/${type}`;
|
urlPath += `/${type}`;
|
||||||
} else {
|
} else {
|
||||||
url += `/${type}/${value}`;
|
urlPath += `/${type}/${value}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return url;
|
return this._history.pathAsUrl(urlPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ import {Navigation} from "./domain/navigation/Navigation.js";
|
||||||
import {URLRouter} from "./domain/navigation/URLRouter.js";
|
import {URLRouter} from "./domain/navigation/URLRouter.js";
|
||||||
import {BrawlView} from "./ui/web/BrawlView.js";
|
import {BrawlView} from "./ui/web/BrawlView.js";
|
||||||
import {Clock} from "./ui/web/dom/Clock.js";
|
import {Clock} from "./ui/web/dom/Clock.js";
|
||||||
import {HashObservable} from "./ui/web/dom/HashObservable.js";
|
import {History} from "./ui/web/dom/History.js";
|
||||||
import {OnlineStatus} from "./ui/web/dom/OnlineStatus.js";
|
import {OnlineStatus} from "./ui/web/dom/OnlineStatus.js";
|
||||||
import {CryptoDriver} from "./ui/web/dom/CryptoDriver.js";
|
import {CryptoDriver} from "./ui/web/dom/CryptoDriver.js";
|
||||||
import {WorkerPool} from "./utils/WorkerPool.js";
|
import {WorkerPool} from "./utils/WorkerPool.js";
|
||||||
|
@ -130,7 +130,7 @@ export async function main(container, paths, legacyExtras) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const urlRouter = new URLRouter(new HashObservable(), navigation);
|
const urlRouter = new URLRouter(new History(), navigation);
|
||||||
urlRouter.start();
|
urlRouter.start();
|
||||||
|
|
||||||
const vm = new BrawlViewModel({
|
const vm = new BrawlViewModel({
|
||||||
|
|
|
@ -16,35 +16,40 @@ limitations under the License.
|
||||||
|
|
||||||
import {BaseObservableValue} from "../../../observable/ObservableValue.js";
|
import {BaseObservableValue} from "../../../observable/ObservableValue.js";
|
||||||
|
|
||||||
export class HashObservable extends BaseObservableValue {
|
export class History extends BaseObservableValue {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this._boundOnHashChange = null;
|
this._boundOnHashChange = null;
|
||||||
this._expectSetEcho = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onHashChange() {
|
_onHashChange() {
|
||||||
if (this._expectSetEcho) {
|
|
||||||
this._expectSetEcho = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.emit(this.get());
|
this.emit(this.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
get() {
|
get() {
|
||||||
const hash = document.location.hash;
|
return document.location.hash;
|
||||||
if (hash.length) {
|
|
||||||
// trim '#'
|
|
||||||
return hash.substr(1);
|
|
||||||
}
|
|
||||||
return hash;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set(hash) {
|
replaceUrl(url) {
|
||||||
if (this._boundOnHashChange) {
|
window.history.replaceState(null, null, url);
|
||||||
this._expectSetEcho = true;
|
// replaceState does not cause hashchange
|
||||||
|
this.emit(url);
|
||||||
}
|
}
|
||||||
document.location.hash = hash;
|
|
||||||
|
pushUrl(url) {
|
||||||
|
document.location.hash = this.urlAsPath(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
urlAsPath(url) {
|
||||||
|
if (url.startsWith("#")) {
|
||||||
|
return url.substr(1);
|
||||||
|
} else {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pathAsUrl(path) {
|
||||||
|
return `#${path}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
onSubscribeFirst() {
|
onSubscribeFirst() {
|
Reference in a new issue