8ea97692f1ad0b9128809ab832aa4b4b8f1cbb04
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Resources / Public / JavaScript / Storage.js
1 /*
2 * This file is part of the TYPO3 CMS project.
3 *
4 * It is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License, either version 2
6 * of the License, or any later version.
7 *
8 * For the full copyright and license information, please read the
9 * LICENSE.txt file that was distributed with this source code.
10 *
11 * The TYPO3 project - inspiring people to share!
12 */
13
14 /**
15 * Module: TYPO3/CMS/Backend/Storage
16 * Adds a public API for the browsers' localStorage called
17 * TYPO3.Storage.Client and the Backend Users "uc",
18 * available via TYPO3.Storage.Persistent
19 */
20 define(['jquery'], function ($) {
21 'use strict';
22
23 try {
24 // fetch from opening window
25 if (window.opener && window.opener.TYPO3 && window.opener.TYPO3.Storage) {
26 return window.opener.TYPO3.Storage;
27 }
28
29 // fetch from parent
30 if (parent && parent.window.TYPO3 && parent.window.TYPO3.Storage) {
31 return parent.window.TYPO3.Storage;
32 }
33
34 // fetch object from outer frame
35 if (top && top.TYPO3.Storage) {
36 return top.TYPO3.Storage;
37 }
38 } catch (e) {
39 // This only happens if the opener, parent or top is some other url (eg a local file)
40 // which loaded the current window. Then the browser's cross domain policy jumps in
41 // and raises an exception.
42 // For this case we are safe and we can create our global object below.
43 }
44
45 // we didn't find an existing object, so create it
46 /**
47 *
48 * @type {{Client: {}, Persistent: {_data: boolean}}}
49 * @exports TYPO3/CMS/Backend/Storage
50 */
51 var Storage = {
52 Client: {},
53 Persistent: {
54 _data: false
55 }
56 };
57
58 /**
59 * Simple localStorage wrapper, to get value from localStorage
60 * @param {String} key
61 * @return {String}
62 */
63 Storage.Client.get = function(key) {
64 return localStorage.getItem('t3-' + key);
65 };
66
67 /**
68 * Simple localStorage wrapper, to set value from localStorage
69 * @param {String} key
70 * @param {String} value
71 */
72 Storage.Client.set = function(key, value) {
73 localStorage.setItem('t3-' + key, value);
74 };
75
76 /**
77 * Simple localStorage wrapper, to unset value from localStorage
78 * @param {String} key
79 */
80 Storage.Client.unset = function(key) {
81 localStorage.removeItem('t3-' + key);
82 };
83
84 /**
85 * Simple localStorage wrapper, to clear localStorage
86 */
87 Storage.Client.clear = function() {
88 localStorage.clear();
89 };
90
91 /**
92 * Checks if a key was set before, useful to not do all the undefined checks all the time
93 *
94 * @param {String} key
95 * @returns {Boolean}
96 */
97 Storage.Client.isset = function(key) {
98 var value = this.get(key);
99 return (typeof value !== 'undefined' && value !== null);
100 };
101
102 /**
103 * Persistent storage, stores everything on the server via AJAX, does a greedy load on read
104 * common functions get/set/clear
105 *
106 * @param {String} key
107 * @returns {*}
108 */
109 Storage.Persistent.get = function(key) {
110 if (this._data === false) {
111 var value;
112 this._loadFromServer().done(function() {
113 value = Storage.Persistent._getRecursiveDataByDeepKey(Storage.Persistent._data, key.split('.'));
114 });
115 return value;
116 } else {
117 return this._getRecursiveDataByDeepKey(this._data, key.split('.'));
118 }
119 };
120
121 /**
122 * Store data persistent on server
123 *
124 * @param {String} key
125 * @param {String} value
126 * @returns {jQuery}
127 */
128 Storage.Persistent.set = function(key, value) {
129 if (this._data !== false) {
130 this._data = this._setRecursiveDataByDeepKey(this._data, key.split('.'), value);
131 }
132 return this._storeOnServer(key, value);
133 };
134
135 /**
136 *
137 * @param {String} key
138 * @param {String} value
139 * @returns {*}
140 */
141 Storage.Persistent.addToList = function(key, value) {
142 return $.ajax(TYPO3.settings.ajaxUrls['usersettings_process'], {method: 'post', data: {'action': 'addToList', key: key, value: value}}).done(function(data) {
143 Storage.Persistent._data = data;
144 });
145 };
146
147 /**
148 *
149 * @param {String} key
150 * @param {String} value
151 * @returns {*}
152 */
153 Storage.Persistent.removeFromList = function(key, value) {
154 return $.ajax(TYPO3.settings.ajaxUrls['usersettings_process'], {method: 'post', data: {'action': 'removeFromList', key: key, value: value}}).done(function(data) {
155 Storage.Persistent._data = data;
156 });
157 };
158
159 /**
160 *
161 * @param {String} key
162 * @returns {*}
163 */
164 Storage.Persistent.unset = function(key) {
165 return $.ajax(TYPO3.settings.ajaxUrls['usersettings_process'], {method: 'post', data: {'action': 'unset', key: key}}).done(function(data) {
166 Storage.Persistent._data = data;
167 });
168 };
169
170 /**
171 *
172 */
173 Storage.Persistent.clear = function() {
174 $.ajax(TYPO3.settings.ajaxUrls['usersettings_process'], {data: {'action': 'clear'}});
175 this._data = false;
176 };
177
178 /**
179 * Checks if a key was set before, useful to not do all the undefined checks all the time
180 *
181 * @param {String} key
182 * @returns {Boolean}
183 */
184 Storage.Persistent.isset = function(key) {
185 var value = this.get(key);
186 return (typeof value !== 'undefined' && typeof value !== 'null' && value != 'undefined');
187 };
188
189 /**
190 * Loads the data from outside, only used for the initial call from BackendController
191 *
192 * @param {String} data
193 */
194 Storage.Persistent.load = function(data) {
195 this._data = data;
196 };
197
198 /**
199 * Loads all data from the server
200 *
201 * @returns {*}
202 * @private
203 */
204 Storage.Persistent._loadFromServer = function() {
205 return $.ajax(TYPO3.settings.ajaxUrls['usersettings_process'], {data: {'action': 'getAll'}, async: false}).done(function(data) {
206 Storage.Persistent._data = data;
207 });
208 };
209
210 /**
211 * Stores data on the server, and gets the updated data on return
212 * to always be up-to-date inside the browser
213 *
214 * @param {String} key
215 * @param {String} value
216 * @returns {*}
217 * @private
218 */
219 Storage.Persistent._storeOnServer = function(key, value) {
220 return $.ajax(TYPO3.settings.ajaxUrls['usersettings_process'], {method: 'post', data: {'action': 'set', key: key, value: value}}).done(function(data) {
221 Storage.Persistent._data = data;
222 });
223 };
224
225 /**
226 * helper function used to set a value which could have been a flat object key data["my.foo.bar"] to
227 * data[my][foo][bar]
228 * is called recursively by itself
229 *
230 * @param {Object} data the data to be uased as base
231 * @param {String} keyParts the keyParts for the subtree
232 * @param {String} value the value to be set
233 * @returns {Object} the data object
234 * @private
235 */
236 Storage.Persistent._setRecursiveDataByDeepKey = function(data, keyParts, value) {
237 if (keyParts.length === 1) {
238 data = data || {};
239 data[keyParts[0]] = value;
240 } else {
241 var firstKey = keyParts.shift();
242 data[firstKey] = this._setRecursiveDataByDeepKey(data[firstKey] || {}, keyParts, value);
243 }
244 return data;
245 };
246
247 /**
248 * Helper function used to set a value which could have been a flat object key data["my.foo.bar"] to
249 * data[my][foo][bar] is called recursively by itself
250 *
251 * @param {Object} data the data to be uased as base
252 * @param {String} keyParts the keyParts for the subtree
253 * @returns {Object}
254 * @private
255 */
256 Storage.Persistent._getRecursiveDataByDeepKey = function(data, keyParts) {
257 if (keyParts.length === 1) {
258 return (data || {})[keyParts[0]];
259 } else {
260 var firstKey = keyParts.shift();
261 return this._getRecursiveDataByDeepKey(data[firstKey] || {}, keyParts);
262 }
263 };
264
265 // attach to global frame
266 TYPO3.Storage = Storage;
267
268 return Storage;
269 });