1
0
Fork 0
mirror of https://github.com/koalyptus/TableFilter.git synced 2024-05-26 02:22:25 +02:00
TableFilter/src/modules/hash.js

127 lines
2.9 KiB
JavaScript
Raw Permalink Normal View History

2016-06-02 06:13:56 +02:00
import {addEvt, removeEvt} from '../event';
2016-05-08 07:26:52 +02:00
import {root} from '../root';
2016-03-19 15:10:59 +01:00
2016-05-08 07:26:52 +02:00
const JSON = root.JSON;
const location = root.location;
const decodeURIComponent = root.decodeURIComponent;
const encodeURIComponent = root.encodeURIComponent;
2016-03-20 04:51:08 +01:00
/**
* Checks if browser has onhashchange event
*/
2016-03-20 04:51:08 +01:00
export const hasHashChange = () => {
2016-05-15 04:56:12 +02:00
let docMode = root.documentMode;
2016-05-08 07:26:52 +02:00
return ('onhashchange' in root) && (docMode === undefined || docMode > 7);
2016-03-19 15:10:59 +01:00
};
2016-03-20 09:56:18 +01:00
/**
* Manages state via URL hash changes
2016-03-20 09:56:18 +01:00
*
* @export
* @class Hash
*/
2016-03-19 15:10:59 +01:00
export class Hash {
2016-03-20 09:56:18 +01:00
/**
* Creates an instance of Hash
*
* @param {State} state Instance of State
*/
constructor(state) {
/**
* State object
* @type {State}
*/
2016-03-19 15:10:59 +01:00
this.state = state;
/**
* Cached URL hash
* @type {String} Hash string
* @private
*/
2016-03-20 04:51:08 +01:00
this.lastHash = null;
/**
* Application event emitter instance
* @type {Emitter}
*/
2016-03-19 15:10:59 +01:00
this.emitter = state.emitter;
/**
* Bound sync wrapper for future use
* @private
*/
this.boundSync = null;
2016-03-19 15:10:59 +01:00
}
2016-03-20 09:56:18 +01:00
/**
* Initializes the Hash object
*/
2016-03-19 15:10:59 +01:00
init() {
2016-03-20 09:56:18 +01:00
if (!hasHashChange()) {
2016-03-19 15:10:59 +01:00
return;
}
2016-03-20 04:51:08 +01:00
this.lastHash = location.hash;
//Store a bound sync wrapper
this.boundSync = this.sync.bind(this);
2016-03-19 15:10:59 +01:00
this.emitter.on(['state-changed'], (tf, state) => this.update(state));
this.emitter.on(['initialized'], this.boundSync);
addEvt(root, 'hashchange', this.boundSync);
2016-03-19 15:10:59 +01:00
}
2016-03-20 09:56:18 +01:00
/**
* Updates the URL hash based on a state change
*
* @param {State} state Instance of State
*/
2016-03-19 15:10:59 +01:00
update(state) {
let hash = `#${encodeURIComponent(JSON.stringify(state))}`;
2016-03-19 15:10:59 +01:00
if (this.lastHash === hash) {
return;
}
location.hash = hash;
this.lastHash = hash;
}
2016-03-20 09:56:18 +01:00
/**
2019-02-09 14:27:55 +01:00
* Converts a URL hash into a JSON object
2016-03-20 09:56:18 +01:00
*
* @param {String} hash URL hash fragment
* @returns {Object} JSON object
*/
2016-03-19 15:10:59 +01:00
parse(hash) {
if (hash.indexOf('#') === -1) {
return null;
}
hash = hash.substr(1);
2016-03-21 08:36:46 +01:00
return JSON.parse(decodeURIComponent(hash));
2016-03-19 15:10:59 +01:00
}
2016-03-20 09:56:18 +01:00
/**
* Applies current hash state to features
*/
sync() {
2016-03-20 04:51:08 +01:00
let state = this.parse(location.hash);
2016-03-20 09:56:18 +01:00
if (!state) {
2016-03-19 15:10:59 +01:00
return;
}
2016-04-08 17:43:55 +02:00
// override current state with persisted one and sync features
this.state.overrideAndSync(state);
2016-03-19 15:10:59 +01:00
}
2016-03-20 09:56:18 +01:00
/**
2016-04-08 17:43:55 +02:00
* Release Hash event subscriptions and clear fields
2016-03-20 09:56:18 +01:00
*/
2016-03-19 15:10:59 +01:00
destroy() {
this.emitter.off(['state-changed'], (tf, state) => this.update(state));
this.emitter.off(['initialized'], this.boundSync);
removeEvt(root, 'hashchange', this.boundSync);
2016-03-20 12:09:08 +01:00
this.state = null;
this.lastHash = null;
this.emitter = null;
2016-03-19 15:10:59 +01:00
}
}