Files
framework/js/forum/src/utils/History.js
Toby Zerner a9ded36b57 Major CSS revamp
- Get rid of Bootstrap (except we still rely on some JS)
- Use BEM class names
- Rework variables/theme config
- Fix various bugs, including some on mobile

The CSS is still not ideal – it needs to be cleaned up some more. But
that can be a focus for after beta.
2015-07-17 14:47:49 +09:30

99 lines
2.5 KiB
JavaScript

/**
* The `History` class keeps track and manages a stack of routes that the user
* has navigated to in their session.
*
* An item can be pushed to the top of the stack using the `push` method. An
* item in the stack has a name and a URL. The name need not be unique; if it is
* the same as the item before it, that will be overwritten with the new URL. In
* this way, if a user visits a discussion, and then visits another discussion,
* popping the history stack will still take them back to the discussion list
* rather than the previous discussion.
*/
export default class History {
constructor() {
/**
* The stack of routes that have been navigated to.
*
* @type {Array}
* @protected
*/
this.stack = [];
// Push the homepage as the first route, so that the user will always be
// able to click on the 'back' button to go home, regardless of which page
// they started on.
this.push('index', '/');
}
/**
* Get the item on the top of the stack.
*
* @return {Object}
* @protected
*/
getTop() {
return this.stack[this.stack.length - 1];
}
/**
* Push an item to the top of the stack.
*
* @param {String} name The name of the route.
* @param {String} [url] The URL of the route. The current URL will be used if
* not provided.
* @public
*/
push(name, url = m.route()) {
// If we're pushing an item with the same name as second-to-top item in the
// stack, we will assume that the user has clicked the 'back' button in
// their browser. In this case, we don't want to push a new item, so we will
// pop off the top item, and then the second-to-top item will be overwritten
// below.
const secondTop = this.stack[this.stack.length - 2];
if (secondTop && secondTop.name === name) {
this.stack.pop();
}
// If we're pushing an item with the same name as the top item in the stack,
// then we'll overwrite it with the new URL.
const top = this.getTop();
if (top && top.name === name) {
top.url = url;
} else {
this.stack.push({name, url});
}
}
/**
* Check whether or not the history stack is able to be popped.
*
* @return {Boolean}
* @public
*/
canGoBack() {
return this.stack.length > 1;
}
/**
* Go back to the previous route in the history stack.
*
* @public
*/
back() {
this.stack.pop();
m.route(this.getTop().url);
}
/**
* Go to the first route in the history stack.
*
* @public
*/
home() {
this.stack.splice(1);
m.route('/');
}
}