UNPKG

3.7 kBJavaScriptView Raw
1import Cookie from '../cookie';
2import {root} from '../root';
3
4const JSON = root.JSON;
5const localStorage = root.localStorage;
6const location = root.location;
7
8/**
9 * Checks if browser has Storage feature
10 */
11export const hasStorage = () => {
12 return 'Storage' in root;
13};
14
15/**
16 * Stores the features state in browser's local storage or cookie
17 *
18 * @export
19 * @class Storage
20 */
21export class Storage {
22
23 /**
24 * Creates an instance of Storage
25 *
26 * @param {State} state Instance of State
27 */
28 constructor(state) {
29
30 /**
31 * State object
32 * @type {State}
33 * @private
34 */
35 this.state = state;
36
37 /**
38 * TableFilter object
39 * @type {TableFilter}
40 * @private
41 */
42 this.tf = state.tf;
43
44 /**
45 * Persist with local storage
46 * @type {Boolean}
47 * @private
48 */
49 this.enableLocalStorage = state.enableLocalStorage && hasStorage();
50
51 /**
52 * Persist with cookie
53 * @type {Boolean}
54 * @private
55 */
56 this.enableCookie = state.enableCookie && !this.enableLocalStorage;
57
58 /**
59 * Emitter object
60 * @type {Emitter}
61 * @private
62 */
63 this.emitter = state.emitter;
64
65 /**
66 * Cookie duration in hours from state object
67 * @type {Number}
68 * @private
69 */
70 this.duration = state.cookieDuration;
71 }
72
73
74 /**
75 * Initializes the Storage object
76 */
77 init() {
78 this.emitter.on(['state-changed'], (tf, state) => this.save(state));
79 this.emitter.on(['initialized'], () => this.sync());
80 }
81
82 /**
83 * Persists the features state on state changes
84 *
85 * @param {State} state Instance of State
86 */
87 save(state) {
88 if (this.enableLocalStorage) {
89 localStorage[this.getKey()] = JSON.stringify(state);
90 } else {
91 Cookie.write(this.getKey(), JSON.stringify(state), this.duration);
92 }
93 }
94
95 /**
96 * Turns stored string into a State JSON object
97 *
98 * @returns {Object} JSON object
99 */
100 retrieve() {
101 let state = null;
102 if (this.enableLocalStorage) {
103 state = localStorage[this.getKey()];
104 } else {
105 state = Cookie.read(this.getKey());
106 }
107
108 if (!state) {
109 return null;
110 }
111 return JSON.parse(state);
112 }
113
114 /**
115 * Removes persisted state from storage
116 */
117 remove() {
118 if (this.enableLocalStorage) {
119 localStorage.removeItem(this.getKey());
120 } else {
121 Cookie.remove(this.getKey());
122 }
123 }
124
125 /**
126 * Applies persisted state to features
127 */
128 sync() {
129 let state = this.retrieve();
130 if (!state) {
131 return;
132 }
133 // override current state with persisted one and sync features
134 this.state.overrideAndSync(state);
135 }
136
137 /**
138 * Returns the storage key
139 *
140 * @returns {String} Key
141 */
142 getKey() {
143 return JSON.stringify({
144 key: `${this.tf.prfxTf}_${this.tf.id}`,
145 path: location.pathname
146 });
147 }
148
149 /**
150 * Release Storage event subscriptions and clear fields
151 */
152 destroy() {
153 this.emitter.off(['state-changed'], (tf, state) => this.save(state));
154 this.emitter.off(['initialized'], () => this.sync());
155
156 this.remove();
157
158 this.state = null;
159 this.emitter = null;
160 }
161}