2020-10-06 18:03:12 +02:00
|
|
|
/*
|
|
|
|
Copyright 2020 The Matrix.org Foundation C.I.C.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
import {Segment} from "./Navigation.js";
|
|
|
|
|
|
|
|
export class URLRouter {
|
2020-10-09 19:43:11 +02:00
|
|
|
constructor({history, navigation, redirect}) {
|
2020-10-06 18:03:12 +02:00
|
|
|
this._subscription = null;
|
2020-10-08 18:22:36 +02:00
|
|
|
this._history = history;
|
2020-10-06 18:03:12 +02:00
|
|
|
this._navigation = navigation;
|
2020-10-09 19:43:11 +02:00
|
|
|
this._redirect = redirect;
|
2020-10-06 18:03:12 +02:00
|
|
|
}
|
|
|
|
|
2020-10-09 09:56:01 +02:00
|
|
|
attach() {
|
2020-10-08 18:22:36 +02:00
|
|
|
this._subscription = this._history.subscribe(url => {
|
2020-10-09 17:00:19 +02:00
|
|
|
this.applyUrl(url);
|
2020-10-06 18:03:12 +02:00
|
|
|
});
|
2020-10-09 17:00:19 +02:00
|
|
|
this.applyUrl(this._history.get());
|
2020-10-07 09:40:51 +02:00
|
|
|
}
|
|
|
|
|
2020-10-09 17:00:19 +02:00
|
|
|
applyUrl(url) {
|
2020-10-07 09:40:51 +02:00
|
|
|
const segments = this._segmentsFromUrl(url);
|
2020-10-09 19:43:11 +02:00
|
|
|
const path = this._redirect(segments, this._navigation);
|
2020-10-07 09:40:51 +02:00
|
|
|
this._navigation.applyPath(path);
|
2020-10-06 18:03:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
stop() {
|
|
|
|
this._subscription = this._subscription();
|
|
|
|
}
|
|
|
|
|
2020-10-08 18:22:36 +02:00
|
|
|
_segmentsFromUrl(url) {
|
|
|
|
const path = this._history.urlAsPath(url);
|
2020-10-07 09:40:51 +02:00
|
|
|
const parts = path.split("/").filter(p => !!p);
|
2020-10-06 18:03:12 +02:00
|
|
|
let index = 0;
|
|
|
|
const segments = [];
|
|
|
|
while (index < parts.length) {
|
|
|
|
const type = parts[index];
|
|
|
|
if ((index + 1) < parts.length) {
|
|
|
|
index += 1;
|
|
|
|
const value = parts[index];
|
|
|
|
segments.push(new Segment(type, value));
|
|
|
|
} else {
|
|
|
|
segments.push(new Segment(type));
|
|
|
|
}
|
|
|
|
index += 1;
|
|
|
|
}
|
|
|
|
return segments;
|
|
|
|
}
|
|
|
|
|
2020-10-09 17:00:19 +02:00
|
|
|
get history() {
|
|
|
|
return this._history;
|
2020-10-08 18:22:36 +02:00
|
|
|
}
|
|
|
|
|
2020-10-06 18:03:12 +02:00
|
|
|
urlForSegment(type, value) {
|
|
|
|
const path = this._navigation.path.with(new Segment(type, value));
|
|
|
|
if (path) {
|
|
|
|
return this.urlForPath(path);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
urlForPath(path) {
|
2020-10-08 18:22:36 +02:00
|
|
|
let urlPath = "";
|
2020-10-06 18:03:12 +02:00
|
|
|
for (const {type, value} of path.segments) {
|
|
|
|
if (typeof value === "boolean") {
|
2020-10-08 18:22:36 +02:00
|
|
|
urlPath += `/${type}`;
|
2020-10-06 18:03:12 +02:00
|
|
|
} else {
|
2020-10-08 18:22:36 +02:00
|
|
|
urlPath += `/${type}/${value}`;
|
2020-10-06 18:03:12 +02:00
|
|
|
}
|
|
|
|
}
|
2020-10-08 18:22:36 +02:00
|
|
|
return this._history.pathAsUrl(urlPath);
|
2020-10-06 18:03:12 +02:00
|
|
|
}
|
|
|
|
}
|