MDL-52127 js: check amd files with eslint grunt task
[moodle.git] / lib / amd / src / localstorage.js
CommitLineData
4b9e5326
DW
1// This file is part of Moodle - http://moodle.org/
2//
3// Moodle is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// (at your option) any later version.
7//
8// Moodle is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
15
16/**
17 * Simple API for set/get to localstorage, with cacherev expiration.
18 *
19 * @module core/localstorage
20 * @package core
21 * @class localstorage
22 * @copyright 2015 Damyon Wiese <damyon@moodle.com>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 * @since 2.9
25 */
26define(['core/config'], function(config) {
27
28 // Private functions and variables.
29 /** @var {boolean} supported - Is localstorage supported in this browser? */
30 var supported = false;
31 /** @var {string} prefix - Prefix to use on all cache keys */
32 var prefix = '';
33 /** @var {jsrevPrefix} jsrevPrefix - Key to store the current jsrev version for the cache */
34 var jsrevPrefix = '';
35 /** @var {Object} localStorage - Browsers localStorage object */
36 var localStorage = null;
37
38 /**
39 * Check if the browser supports local storage.
40 *
41 * @method detectSupport
42 * @return {boolean} True if the browser supports local storage.
43 */
44 var detectSupport = function() {
45 if (config.jsrev == -1) {
46 // Disable cache if debugging.
47 return false;
48 }
e56e7c16
AH
49 if (typeof(window.localStorage) === "undefined") {
50 return false;
51 }
52 var testKey = 'test';
53 try {
54 localStorage = window.localStorage;
55 if (localStorage === null) {
4b9e5326
DW
56 return false;
57 }
0e30fbd1
AN
58 // MDL-51461 - Some browsers misreport availability of local storage
59 // so check it is actually usable.
e56e7c16
AH
60 localStorage.setItem(testKey, '1');
61 localStorage.removeItem(testKey);
62 return true;
63 } catch (ex) {
64 return false;
4b9e5326
DW
65 }
66 };
67
68 /**
69 * Add a unique prefix to all keys so multiple moodle sites do not share caches.
70 *
71 * @method prefixKey
72 * @param {string} key The cache key to prefix.
73 * @return {string} The new key
74 */
75 var prefixKey = function(key) {
76 return prefix + key;
77 };
78
79 /**
80 * Check the current jsrev version and clear the cache if it has been bumped.
81 *
82 * @method validateCache
83 */
84 var validateCache = function() {
85 var cacheVersion = localStorage.getItem(jsrevPrefix);
86 if (cacheVersion === null) {
87 localStorage.setItem(jsrevPrefix, config.jsrev);
88 return;
89 }
90 var moodleVersion = config.jsrev;
91
92 if (moodleVersion != cacheVersion) {
93 localStorage.clear();
94 localStorage.setItem(jsrevPrefix, config.jsrev);
95 }
96 };
97
98 /**
99 * Hash a string, used to make shorter key prefixes.
100 *
101 * @method hashString
102 * @param string source The string to hash
103 * @return int The int hash
104 */
105 var hashString = function(source) {
106 // From http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery.
107 /* jshint bitwise: false */
3adb62b7 108 /* eslint no-bitwise: "off" */
4b9e5326
DW
109 var hash = 0, i, chr, len;
110 if (source.length === 0) {
111 return hash;
112 }
113 for (i = 0, len = source.length; i < len; i++) {
114 chr = source.charCodeAt(i);
115 hash = ((hash << 5) - hash) + chr;
116 hash |= 0; // Convert to 32bit integer
117 }
118 return hash;
119 };
120
121 /**
122 * Init this module.
123 *
124 * This computes the hash prefixes from jsrev and friends.
125 */
126 var init = function() {
127 supported = detectSupport();
128 var hashSource = config.wwwroot + '/' + config.jsrev;
129
130 var hash = hashString(hashSource);
131 prefix = hash + '/';
132 hashSource = config.wwwroot + '/';
133 hash = hashString(hashSource);
134 jsrevPrefix = hash + '/jsrev';
135 };
136
137 // Run the module init.
138 init();
139
140 return /** @alias module:core/localstorage */ {
141 /**
142 * Get a value from local storage. Remember - all values must be strings.
143 *
144 * @method get
145 * @param {string} key The cache key to check.
146 * @return {boolean|string} False if the value is not in the cache, or some other error - a string otherwise.
147 */
148 get: function(key) {
149 if (!supported) {
150 return false;
151 }
152 validateCache();
153 key = prefixKey(key);
154
155 return localStorage.getItem(key);
156 },
157
158 /**
159 * Set a value to local storage. Remember - all values must be strings.
160 *
161 * @method set
162 * @param {string} key The cache key to set.
163 * @param {string} value The value to set.
164 * @return {boolean} False if the value can't be saved in the cache, or some other error - true otherwise.
165 */
166 set: function(key, value) {
167 if (!supported) {
168 return false;
169 }
170 validateCache();
171 key = prefixKey(key);
172 // This can throw exceptions when the storage limit is reached.
173 try {
174 localStorage.setItem(key, value);
175 } catch (e) {
176 return false;
177 }
178 return true;
179 }
180
181 };
182});