1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// github.com/paulirish/jquery-ajax-localstorage-cache
// dependent on Modernizr's localStorage test
var storage,
fail,
uid;
try {
uid = new Date;
(storage = window.localStorage).setItem(uid, uid);
fail = storage.getItem(uid) != uid;
storage.removeItem(uid);
fail && (storage = false);
} catch(e) {}
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
if (!storage && options.localCache) {
window.localStorage = new customStorage();
}
// Cache it ?
if (!options.localCache) return;
// do some cleanup first
cleanOldStorage();
var lifetl = options.cacheTTL || 1;
var cacheKey = options.cacheKey ||
options.url.replace(/jQuery.*/, '') + options.type + (options.data || '');
if(options.url.match('/delete/i'))
// isCacheValid is a function to validate cache
if (options.isCacheValid && !options.isCacheValid()) {
window.localStorage.removeItem(cacheKey);
}
// if there's a TTL that's expired, flush this item
var ttl = window.localStorage.getItem(cacheKey + 'cachettl');
if (ttl && ttl < +new Date()) {
window.localStorage.removeItem(cacheKey);
window.localStorage.removeItem(cacheKey + 'cachettl');
ttl = 'expired';
}
var value = window.localStorage.getItem(cacheKey);
if (value) {
//In the cache? So get it, apply success callback & abort the XHR request
// parse back to JSON if we can.
if (options.dataType.indexOf('json') === 0) value = JSON.parse(value);
options.success(value);
// Abort is broken on JQ 1.5 :(
jqXHR.abort();
} else {
//If it not in the cache, we change the success callback, just put data on localstorage and after that apply the initial callback
if (options.success) {
options.realsuccess = options.success;
}
options.success = function (data) {
var strdata = data;
if (this.dataType.indexOf('json') === 0) strdata = JSON.stringify(data);
window.localStorage.setItem(cacheKey, strdata);
if (options.realsuccess) options.realsuccess(data);
};
// store timestamp
if (!ttl || ttl === 'expired') {
lifespan = options.cacheTTLType || 's';
switch (lifespan)
{
case 'm':
lifetl *= 60; // minutes
break;
case 'h':
lifetl *= 3600; // hours
break;
}
window.localStorage.setItem(cacheKey + 'cachettl', +new Date() + 1000 * lifetl);
}
}
});
function cleanOldStorage(){
if(window.localStorage.toString()=='[object Storage]')
{
for(i=window.localStorage.length-1; i >=0; i--)
{
key = window.localStorage.key(i);
if(key && key.match(/cachettl/i)){
value = window.localStorage.getItem(key);
if(value < +new Date())
{
window.localStorage.removeItem(key); console.log(key + ' removed');
window.localStorage.removeItem(key.replace('cachettl','')); console.log(key + 'cachettl removed');
}
}
}
}
else if(window.localStorage.items) {
for(var key in window.localStorage.items){
if(key && key.match(/cachettl/i)){
value = window.localStorage.items[key];
if(value < +new Date())
{
window.localStorage.removeItem(key); console.log(key + ' removed');
window.localStorage.removeItem(key.replace('cachettl',''));
}
}
}
}
}
function customStorage() {}
customStorage.prototype.items = Object();
customStorage.prototype.setItem = function (key, response) {
this.items[key] = Object();
this.items[key].response = response;
return true;
}
customStorage.prototype.removeItem = function (key)
{
if(this.items[key])
{
this.items[key] = null;
}
}
customStorage.prototype.getItem = function (key) {
// if cache does not exist
if (this.items[key] == null)
return false;
// everything is passed - lets return the response
return this.items[key].response;
}
customStorage.prototype.clear = function () {
// flush all cache
this.items = Object();
return true;
}