mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-24 23:01:57 +08:00
hash url state manager
This commit is contained in:
105
ionic/routing/hash-url-state.ts
Normal file
105
ionic/routing/hash-url-state.ts
Normal file
@ -0,0 +1,105 @@
|
||||
import {IonicRouter} from './router';
|
||||
import * as util from '../util/util';
|
||||
|
||||
|
||||
class HashUrlStateManager {
|
||||
|
||||
constructor(router, ionicApp, ionicConfig, window) {
|
||||
this.router = router;
|
||||
this.ionicApp = ionicApp;
|
||||
this.ionicConfig = ionicConfig;
|
||||
this.location = window.location;
|
||||
this.history = window.history;
|
||||
|
||||
window.addEventListener('popstate', ev => {
|
||||
this.onPopState(ev);
|
||||
});
|
||||
}
|
||||
|
||||
stateChange(path, type, activeView) {
|
||||
if (type == 'pop') {
|
||||
// if the popstate came from the browser's back button (and not Ionic)
|
||||
// then we shouldn't force another browser history.back()
|
||||
// only do a history.back() if the URL hasn't been updated yet
|
||||
if (this.isDifferentPath(path)) {
|
||||
this.history.back();
|
||||
}
|
||||
|
||||
} else {
|
||||
// push state change
|
||||
let enteringState = {
|
||||
path: path,
|
||||
backPath: this.router.lastPath(),
|
||||
forwardPath: null
|
||||
};
|
||||
|
||||
if (this._hasInit) {
|
||||
// update the leaving state to know what it's forward state will be
|
||||
let leavingState = util.extend(this.history.state, {
|
||||
forwardPath: enteringState.path
|
||||
});
|
||||
if (leavingState.path !== enteringState.path) {
|
||||
this.history.replaceState(leavingState, '', '#' + leavingState.path);
|
||||
}
|
||||
|
||||
if (this.isDifferentPath(path)) {
|
||||
// push the new state to the history stack since the path
|
||||
// isn't already in the location hash
|
||||
this.history.pushState(enteringState, '', '#' + enteringState.path);
|
||||
}
|
||||
|
||||
} else {
|
||||
// replace the very first load with the correct entering state info
|
||||
this.history.replaceState(enteringState, '', '#' + enteringState.path);
|
||||
this._hasInit = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onPopState(ev) {
|
||||
let newState = ev.state || {};
|
||||
let newStatePath = newState.path;
|
||||
let newStateBackPath = newState.backPath;
|
||||
let newStateForwardPath = newState.forwardPath;
|
||||
let lastLoadedStatePath = this.router.lastPath();
|
||||
|
||||
if (newStatePath === lastLoadedStatePath) {
|
||||
// do nothing if the last path is the same
|
||||
// as the "new" current state
|
||||
return;
|
||||
}
|
||||
|
||||
let activeViewCtrl = this.router.activeViewController();
|
||||
if (activeViewCtrl) {
|
||||
|
||||
if (newStateForwardPath === lastLoadedStatePath) {
|
||||
// if the last loaded state path is the same as the new
|
||||
// state's forward path then the user is moving back
|
||||
activeViewCtrl.pop();
|
||||
|
||||
} else if (newStateBackPath === lastLoadedStatePath) {
|
||||
// if the last loaded state path is the new state's
|
||||
// back path, then the user is moving forward
|
||||
this.loadByPath(newStatePath);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
getCurrentPath() {
|
||||
// Grab the path without the leading hash
|
||||
return {
|
||||
path: this.location.hash.slice(1),
|
||||
priority: 0
|
||||
}
|
||||
}
|
||||
|
||||
isDifferentPath(path) {
|
||||
// check if the given path is different than the current location
|
||||
return (this.location.hash !== ('#' + path));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
IonicRouter.registerStateManager('hashurl', HashUrlStateManager);
|
Reference in New Issue
Block a user