3
Copyright 2011 Yahoo! Inc. All rights reserved.
4
Licensed under the BSD License.
5
http://yuilibrary.com/license/
7
YUI.add('cache-offline', function(Y) {
10
* Provides a Cache subclass which uses HTML5 `localStorage` for persistence.
13
* @submodule cache-offline
17
* Extends Cache utility with offline functionality.
22
function CacheOffline() {
23
CacheOffline.superclass.constructor.apply(this, arguments);
26
var localStorage = null,
31
localStorage = Y.config.win.localStorage;
36
/////////////////////////////////////////////////////////////////////////////
38
// CacheOffline events
40
/////////////////////////////////////////////////////////////////////////////
44
* @description Fired when an entry could not be added, most likely due to
45
* exceeded browser quota.
47
* <dt>error (Object)</dt> <dd>The error object.</dd>
51
/////////////////////////////////////////////////////////////////////////////
53
// CacheOffline static
55
/////////////////////////////////////////////////////////////////////////////
64
* @value "cacheOffline"
69
/////////////////////////////////////////////////////////////////////////////
71
// CacheOffline Attributes
73
/////////////////////////////////////////////////////////////////////////////
77
* @description A string that must be passed in via the constructor.
78
* This identifier is used to sandbox one cache instance's entries
79
* from another. Calling the cache instance's flush and length methods
80
* or get("entries") will apply to only these sandboxed entries.
92
* @description Absolute Date when data expires or
93
* relative number of milliseconds. Zero disables expiration.
95
* @default 86400000 (one day)
103
* @description Disabled.
113
* @attribute uniqueKeys
114
* @description Always true for CacheOffline.
128
* Removes all items from all sandboxes. Useful if localStorage has
129
* exceeded quota. Only supported on browsers that implement HTML 5
135
flushAll: function() {
136
var store = localStorage, key;
144
if (store.hasOwnProperty(key)) {
145
store.removeItem(key);
156
Y.extend(CacheOffline, Y.Cache, localStorage ? {
157
/////////////////////////////////////////////////////////////////////////////
159
// Offline is supported
161
/////////////////////////////////////////////////////////////////////////////
163
/////////////////////////////////////////////////////////////////////////////
165
// CacheOffline protected methods
167
/////////////////////////////////////////////////////////////////////////////
169
* Always return null.
174
_setMax: function(value) {
184
_getSize: function() {
187
l=localStorage.length;
190
if(localStorage.key(i).indexOf(this.get("sandbox")) === 0) {
200
* @method _getEntries
203
_getEntries: function() {
206
l=localStorage.length,
207
sandbox = this.get("sandbox");
210
if(localStorage.key(i).indexOf(sandbox) === 0) {
211
entries[i] = JSON.parse(localStorage.key(i).substring(sandbox.length));
218
* Adds entry to cache.
221
* @param e {Event.Facade} Event Facade with the following properties:
223
* <dt>entry (Object)</dt> <dd>The cached entry.</dd>
227
_defAddFn: function(e) {
229
request = entry.request,
230
cached = entry.cached,
231
expires = entry.expires;
233
// Convert Dates to msecs on the way into localStorage
234
entry.cached = cached.getTime();
235
entry.expires = expires ? expires.getTime() : expires;
238
localStorage.setItem(this.get("sandbox")+JSON.stringify({"request":request}), JSON.stringify(entry));
241
this.fire("error", {error:error});
248
* @method _defFlushFn
249
* @param e {Event.Facade} Event Facade object.
252
_defFlushFn: function(e) {
254
i=localStorage.length-1;
257
key = localStorage.key(i);
258
if(key.indexOf(this.get("sandbox")) === 0) {
259
localStorage.removeItem(key);
264
/////////////////////////////////////////////////////////////////////////////
266
// CacheOffline public methods
268
/////////////////////////////////////////////////////////////////////////////
270
* Adds a new entry to the cache of the format
271
* {request:request, response:response, cached:cached, expires: expires}.
274
* @param request {Object} Request value must be a String or JSON.
275
* @param response {Object} Response value must be a String or JSON.
279
* Retrieves cached object for given request, if available.
280
* Returns null if there is no cache match.
283
* @param request {Object} Request object.
284
* @return {Object} Cached object with the properties request, response,
285
* and expires, or null.
287
retrieve: function(request) {
288
this.fire("request", {request: request});
290
var entry, expires, sandboxedrequest;
293
sandboxedrequest = this.get("sandbox")+JSON.stringify({"request":request});
295
entry = JSON.parse(localStorage.getItem(sandboxedrequest));
304
// Convert msecs to Dates on the way out of localStorage
305
entry.cached = new Date(entry.cached);
306
expires = entry.expires;
307
expires = !expires ? null : new Date(expires);
308
entry.expires = expires;
310
if(this._isMatch(request, entry)) {
311
this.fire("retrieve", {entry: entry});
318
/////////////////////////////////////////////////////////////////////////////
320
// Offline is not supported
322
/////////////////////////////////////////////////////////////////////////////
325
* Always return null.
330
_setMax: function(value) {
336
Y.CacheOffline = CacheOffline;
339
}, '3.4.1' ,{requires:['cache-base', 'json']});