2016-04-08 12:13:29 +02:00
|
|
|
import Cookie from '../cookie';
|
2016-05-08 07:26:52 +02:00
|
|
|
import {root} from '../root';
|
2016-04-08 12:13:29 +02:00
|
|
|
|
2016-05-08 07:26:52 +02:00
|
|
|
const JSON = root.JSON;
|
|
|
|
const localStorage = root.localStorage;
|
|
|
|
const location = root.location;
|
2016-04-07 12:13:54 +02:00
|
|
|
|
2016-08-08 09:22:25 +02:00
|
|
|
/**
|
|
|
|
* Checks if browser has Storage feature
|
|
|
|
*/
|
2016-04-07 12:13:54 +02:00
|
|
|
export const hasStorage = () => {
|
2016-05-08 07:26:52 +02:00
|
|
|
return 'Storage' in root;
|
2016-04-07 12:13:54 +02:00
|
|
|
};
|
|
|
|
|
2016-04-08 17:43:55 +02:00
|
|
|
/**
|
|
|
|
* Stores the features state in browser's local storage or cookie
|
|
|
|
*
|
|
|
|
* @export
|
|
|
|
* @class Storage
|
|
|
|
*/
|
2016-04-07 12:13:54 +02:00
|
|
|
export class Storage {
|
|
|
|
|
2016-04-08 17:43:55 +02:00
|
|
|
/**
|
|
|
|
* Creates an instance of Storage
|
|
|
|
*
|
|
|
|
* @param {State} state Instance of State
|
|
|
|
*/
|
|
|
|
constructor(state) {
|
2016-08-08 09:22:25 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* State object
|
|
|
|
* @type {State}
|
|
|
|
* @private
|
|
|
|
*/
|
2016-04-07 12:13:54 +02:00
|
|
|
this.state = state;
|
2016-08-08 09:22:25 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* TableFilter object
|
|
|
|
* @type {TableFilter}
|
|
|
|
* @private
|
|
|
|
*/
|
2016-04-07 18:34:25 +02:00
|
|
|
this.tf = state.tf;
|
2016-08-08 09:22:25 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Persist with local storage
|
|
|
|
* @type {Boolean}
|
|
|
|
* @private
|
|
|
|
*/
|
2016-04-07 12:13:54 +02:00
|
|
|
this.enableLocalStorage = state.enableLocalStorage && hasStorage();
|
2016-08-08 09:22:25 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Persist with cookie
|
|
|
|
* @type {Boolean}
|
|
|
|
* @private
|
|
|
|
*/
|
2016-04-08 12:13:29 +02:00
|
|
|
this.enableCookie = state.enableCookie && !this.enableLocalStorage;
|
2016-08-08 09:22:25 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Emitter object
|
|
|
|
* @type {Emitter}
|
|
|
|
* @private
|
|
|
|
*/
|
2016-04-07 12:13:54 +02:00
|
|
|
this.emitter = state.emitter;
|
2016-08-08 09:22:25 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Cookie duration in hours from state object
|
|
|
|
* @type {Number}
|
|
|
|
* @private
|
|
|
|
*/
|
2016-04-08 12:13:29 +02:00
|
|
|
this.duration = state.cookieDuration;
|
2016-04-07 12:13:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-04-08 17:43:55 +02:00
|
|
|
/**
|
|
|
|
* Initializes the Storage object
|
|
|
|
*/
|
|
|
|
init() {
|
2016-04-07 18:34:25 +02:00
|
|
|
this.emitter.on(['state-changed'], (tf, state) => this.save(state));
|
|
|
|
this.emitter.on(['initialized'], () => this.sync());
|
2016-04-07 12:13:54 +02:00
|
|
|
}
|
|
|
|
|
2016-04-08 17:43:55 +02:00
|
|
|
/**
|
|
|
|
* Persists the features state on state changes
|
|
|
|
*
|
2016-08-08 09:22:25 +02:00
|
|
|
* @param {State} state Instance of State
|
2016-04-08 17:43:55 +02:00
|
|
|
*/
|
|
|
|
save(state) {
|
|
|
|
if (this.enableLocalStorage) {
|
2016-04-07 18:34:25 +02:00
|
|
|
localStorage[this.getKey()] = JSON.stringify(state);
|
2016-04-08 12:13:29 +02:00
|
|
|
} else {
|
|
|
|
Cookie.write(this.getKey(), JSON.stringify(state), this.duration);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-08 17:43:55 +02:00
|
|
|
/**
|
|
|
|
* Turns stored string into a State JSON object
|
|
|
|
*
|
|
|
|
* @returns {Object} JSON object
|
|
|
|
*/
|
|
|
|
retrieve() {
|
2016-04-08 12:13:29 +02:00
|
|
|
let state = null;
|
2016-04-08 17:43:55 +02:00
|
|
|
if (this.enableLocalStorage) {
|
2016-04-08 12:13:29 +02:00
|
|
|
state = localStorage[this.getKey()];
|
|
|
|
} else {
|
|
|
|
state = Cookie.read(this.getKey());
|
|
|
|
}
|
|
|
|
|
2016-04-08 17:43:55 +02:00
|
|
|
if (!state) {
|
2016-04-08 12:13:29 +02:00
|
|
|
return null;
|
2016-04-07 18:34:25 +02:00
|
|
|
}
|
2016-04-08 12:13:29 +02:00
|
|
|
return JSON.parse(state);
|
2016-04-07 12:13:54 +02:00
|
|
|
}
|
|
|
|
|
2016-04-08 17:43:55 +02:00
|
|
|
/**
|
|
|
|
* Removes persisted state from storage
|
|
|
|
*/
|
|
|
|
remove() {
|
|
|
|
if (this.enableLocalStorage) {
|
2016-04-07 18:34:25 +02:00
|
|
|
localStorage.removeItem(this.getKey());
|
2016-04-08 12:13:29 +02:00
|
|
|
} else {
|
|
|
|
Cookie.remove(this.getKey());
|
2016-04-07 18:34:25 +02:00
|
|
|
}
|
|
|
|
}
|
2016-04-07 12:13:54 +02:00
|
|
|
|
2016-04-08 17:43:55 +02:00
|
|
|
/**
|
|
|
|
* Applies persisted state to features
|
|
|
|
*/
|
2016-04-07 18:34:25 +02:00
|
|
|
sync() {
|
2016-04-08 17:43:55 +02:00
|
|
|
let state = this.retrieve();
|
2016-04-07 18:34:25 +02:00
|
|
|
if (!state) {
|
|
|
|
return;
|
|
|
|
}
|
2016-04-08 17:43:55 +02:00
|
|
|
// override current state with persisted one and sync features
|
|
|
|
this.state.overrideAndSync(state);
|
2016-04-07 18:34:25 +02:00
|
|
|
}
|
|
|
|
|
2016-04-08 17:43:55 +02:00
|
|
|
/**
|
|
|
|
* Returns the storage key
|
|
|
|
*
|
|
|
|
* @returns {String} Key
|
|
|
|
*/
|
|
|
|
getKey() {
|
|
|
|
return JSON.stringify({
|
|
|
|
key: `${this.tf.prfxTf}_${this.tf.id}`,
|
|
|
|
path: location.pathname
|
|
|
|
});
|
2016-04-07 18:34:25 +02:00
|
|
|
}
|
|
|
|
|
2016-04-08 17:43:55 +02:00
|
|
|
/**
|
|
|
|
* Release Storage event subscriptions and clear fields
|
|
|
|
*/
|
|
|
|
destroy() {
|
2016-04-07 18:34:25 +02:00
|
|
|
this.emitter.off(['state-changed'], (tf, state) => this.save(state));
|
|
|
|
this.emitter.off(['initialized'], () => this.sync());
|
|
|
|
|
2016-04-08 12:13:29 +02:00
|
|
|
this.remove();
|
2016-04-07 18:34:25 +02:00
|
|
|
|
|
|
|
this.state = null;
|
|
|
|
this.emitter = null;
|
|
|
|
}
|
2016-04-07 12:13:54 +02:00
|
|
|
}
|