2 Copyright (c) 2010, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.com/yui/license.html
8 YUI.add('cache-offline', function(Y) {
11 * Extends Cache utility with offline functionality.
16 function CacheOffline() {
17 CacheOffline.superclass.constructor.apply(this, arguments);
20 var localStorage = null,
25 localStorage = Y.config.win.localStorage;
30 /////////////////////////////////////////////////////////////////////////////
32 // CacheOffline events
34 /////////////////////////////////////////////////////////////////////////////
38 * @description Fired when an entry could not be added, most likely due to
39 * exceeded browser quota.
41 * <dt>error (Object)</dt> <dd>The error object.</dd>
45 /////////////////////////////////////////////////////////////////////////////
47 // CacheOffline static
49 /////////////////////////////////////////////////////////////////////////////
58 * @value "cacheOffline"
63 /////////////////////////////////////////////////////////////////////////////
65 // CacheOffline Attributes
67 /////////////////////////////////////////////////////////////////////////////
71 * @description A string that must be passed in via the constructor.
72 * This identifier is used to sandbox one cache instance's entries
73 * from another. Calling the cache instance's flush and length methods
74 * or get("entries") will apply to only these sandboxed entries.
86 * @description Absolute Date when data expires or
87 * relative number of milliseconds. Zero disables expiration.
89 * @default 86400000 (one day)
97 * @description Disabled.
107 * @attribute uniqueKeys
108 * @description Always true for CacheOffline.
122 * Removes all items from all sandboxes. Useful if localStorage has
123 * exceeded quota. Only supported on browsers that implement HTML 5
129 flushAll: function() {
130 var store = localStorage, key;
138 if (store.hasOwnProperty(key)) {
139 store.removeItem(key);
150 Y.extend(CacheOffline, Y.Cache, localStorage ? {
151 /////////////////////////////////////////////////////////////////////////////
153 // Offline is supported
155 /////////////////////////////////////////////////////////////////////////////
157 /////////////////////////////////////////////////////////////////////////////
159 // CacheOffline protected methods
161 /////////////////////////////////////////////////////////////////////////////
163 * Always return null.
168 _setMax: function(value) {
178 _getSize: function() {
181 l=localStorage.length;
184 if(localStorage.key(i).indexOf(this.get("sandbox")) === 0) {
194 * @method _getEntries
197 _getEntries: function() {
200 l=localStorage.length,
201 sandbox = this.get("sandbox");
204 if(localStorage.key(i).indexOf(sandbox) === 0) {
205 entries[i] = JSON.parse(localStorage.key(i).substring(sandbox.length));
212 * Adds entry to cache.
215 * @param e {Event.Facade} Event Facade with the following properties:
217 * <dt>entry (Object)</dt> <dd>The cached entry.</dd>
221 _defAddFn: function(e) {
223 request = entry.request,
224 cached = entry.cached,
225 expires = entry.expires;
227 // Convert Dates to msecs on the way into localStorage
228 entry.cached = cached.getTime();
229 entry.expires = expires ? expires.getTime() : expires;
232 localStorage.setItem(this.get("sandbox")+JSON.stringify({"request":request}), JSON.stringify(entry));
235 this.fire("error", {error:error});
242 * @method _defFlushFn
243 * @param e {Event.Facade} Event Facade object.
246 _defFlushFn: function(e) {
248 i=localStorage.length-1;
251 key = localStorage.key(i);
252 if(key.indexOf(this.get("sandbox")) === 0) {
253 localStorage.removeItem(key);
258 /////////////////////////////////////////////////////////////////////////////
260 // CacheOffline public methods
262 /////////////////////////////////////////////////////////////////////////////
264 * Adds a new entry to the cache of the format
265 * {request:request, response:response, cached:cached, expires: expires}.
268 * @param request {Object} Request value must be a String or JSON.
269 * @param response {Object} Response value must be a String or JSON.
273 * Retrieves cached object for given request, if available.
274 * Returns null if there is no cache match.
277 * @param request {Object} Request object.
278 * @return {Object} Cached object with the properties request, response,
279 * and expires, or null.
281 retrieve: function(request) {
282 this.fire("request", {request: request});
284 var entry, expires, sandboxedrequest;
287 sandboxedrequest = this.get("sandbox")+JSON.stringify({"request":request});
289 entry = JSON.parse(localStorage.getItem(sandboxedrequest));
298 // Convert msecs to Dates on the way out of localStorage
299 entry.cached = new Date(entry.cached);
300 expires = entry.expires;
301 expires = !expires ? null : new Date(expires);
302 entry.expires = expires;
304 if(this._isMatch(request, entry)) {
305 this.fire("retrieve", {entry: entry});
312 /////////////////////////////////////////////////////////////////////////////
314 // Offline is not supported
316 /////////////////////////////////////////////////////////////////////////////
319 * Always return null.
324 _setMax: function(value) {
330 Y.CacheOffline = CacheOffline;
334 }, '3.3.0' ,{requires:['cache-base', 'json']});