Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
YUI.add('cache-offline', function (Y, NAME) {
2
 
3
/**
4
 * Provides a Cache subclass which uses HTML5 `localStorage` for persistence.
5
 *
6
 * @module cache
7
 * @submodule cache-offline
8
 */
9
 
10
/**
11
 * Extends Cache utility with offline functionality.
12
 * @class CacheOffline
13
 * @extends Cache
14
 * @constructor
15
 */
16
function CacheOffline() {
17
    CacheOffline.superclass.constructor.apply(this, arguments);
18
}
19
 
20
var localStorage = null,
21
    JSON = Y.JSON;
22
 
23
// Bug 2529572
24
try {
25
    localStorage = Y.config.win.localStorage;
26
}
27
catch(e) {
28
    Y.log("Could not access localStorage.", "warn", "cache");
29
}
30
 
31
/////////////////////////////////////////////////////////////////////////////
32
//
33
// CacheOffline events
34
//
35
/////////////////////////////////////////////////////////////////////////////
36
 
37
/**
38
* @event error
39
* @description Fired when an entry could not be added, most likely due to
40
* exceeded browser quota.
41
* <dl>
42
* <dt>error (Object)</dt> <dd>The error object.</dd>
43
* </dl>
44
*/
45
 
46
/////////////////////////////////////////////////////////////////////////////
47
//
48
// CacheOffline static
49
//
50
/////////////////////////////////////////////////////////////////////////////
51
Y.mix(CacheOffline, {
52
    /**
53
     * Class name.
54
     *
55
     * @property NAME
56
     * @type String
57
     * @static
58
     * @final
59
     * @value "cacheOffline"
60
     */
61
    NAME: "cacheOffline",
62
 
63
    ATTRS: {
64
        /////////////////////////////////////////////////////////////////////////////
65
        //
66
        // CacheOffline Attributes
67
        //
68
        /////////////////////////////////////////////////////////////////////////////
69
 
70
        /**
71
        * @attribute sandbox
72
        * @description A string that must be passed in via the constructor.
73
        * This identifier is used to sandbox one cache instance's entries
74
        * from another. Calling the cache instance's flush and length methods
75
        * or get("entries") will apply to only these sandboxed entries.
76
        * @type String
77
        * @default "default"
78
        * @initOnly
79
        */
80
        sandbox: {
81
            value: "default",
82
            writeOnce: "initOnly"
83
        },
84
 
85
        /**
86
        * @attribute expires
87
        * @description Absolute Date when data expires or
88
        * relative number of milliseconds. Zero disables expiration.
89
        * @type Date | Number
90
        * @default 86400000 (one day)
91
        */
92
        expires: {
93
            value: 86400000
94
        },
95
 
96
        /**
97
        * @attribute max
98
        * @description Disabled.
99
        * @readOnly
100
        * @default null
101
        */
102
        max: {
103
            value: null,
104
            readOnly: true
105
        },
106
 
107
        /**
108
        * @attribute uniqueKeys
109
        * @description Always true for CacheOffline.
110
        * @readOnly
111
        * @default true
112
        */
113
        uniqueKeys: {
114
            value: true,
115
            readOnly: true,
116
            setter: function() {
117
                return true;
118
            }
119
        }
120
    },
121
 
122
    /**
123
     * Removes all items from all sandboxes. Useful if localStorage has
124
     * exceeded quota. Only supported on browsers that implement HTML 5
125
     * localStorage.
126
     *
127
     * @method flushAll
128
     * @static
129
     */
130
    flushAll: function() {
131
        var store = localStorage, key;
132
        if(store) {
133
            if(store.clear) {
134
                store.clear();
135
            }
136
            // FF2.x and FF3.0.x
137
            else {
138
                for (key in store) {
139
                    if (store.hasOwnProperty(key)) {
140
                        store.removeItem(key);
141
                        delete store[key];
142
                    }
143
                }
144
            }
145
            Y.log("All sandboxes of OfflineCache flushed", "info", "cache");
146
        }
147
        else {
148
            Y.log("Could not flush all OfflineCache sandboxes.", "warn", "cache");
149
        }
150
    }
151
});
152
 
153
Y.extend(CacheOffline, Y.Cache, localStorage ? {
154
/////////////////////////////////////////////////////////////////////////////
155
//
156
// Offline is supported
157
//
158
/////////////////////////////////////////////////////////////////////////////
159
 
160
    /////////////////////////////////////////////////////////////////////////////
161
    //
162
    // CacheOffline protected methods
163
    //
164
    /////////////////////////////////////////////////////////////////////////////
165
    /**
166
     * Always return null.
167
     *
168
     * @method _setMax
169
     * @protected
170
     */
171
    _setMax: function(value) {
172
        return null;
173
    },
174
 
175
    /**
176
     * Gets size.
177
     *
178
     * @method _getSize
179
     * @protected
180
     */
181
    _getSize: function() {
182
        var count = 0,
183
            i=0,
184
            l=localStorage.length;
185
        for(; i<l; ++i) {
186
            // Match sandbox id
187
            if(localStorage.key(i).indexOf(this.get("sandbox")) === 0) {
188
                count++;
189
            }
190
        }
191
        return count;
192
    },
193
 
194
    /**
195
     * Gets all entries.
196
     *
197
     * @method _getEntries
198
     * @protected
199
     */
200
    _getEntries: function() {
201
        var entries = [],
202
            i=0,
203
            l=localStorage.length,
204
            sandbox = this.get("sandbox");
205
        for(; i<l; ++i) {
206
            // Match sandbox id
207
            if(localStorage.key(i).indexOf(sandbox) === 0) {
208
                entries[i] = JSON.parse(localStorage.key(i).substring(sandbox.length));
209
            }
210
        }
211
        return entries;
212
    },
213
 
214
    /**
215
     * Adds entry to cache.
216
     *
217
     * @method _defAddFn
218
     * @param e {EventFacade} Event Facade with the following properties:
219
     * <dl>
220
     * <dt>entry (Object)</dt> <dd>The cached entry.</dd>
221
     * </dl>
222
     * @protected
223
     */
224
    _defAddFn: function(e) {
225
        var entry = e.entry,
226
            request = entry.request,
227
            cached = entry.cached,
228
            expires = entry.expires;
229
 
230
        // Convert Dates to msecs on the way into localStorage
231
        entry.cached = cached.getTime();
232
        entry.expires = expires ? expires.getTime() : expires;
233
 
234
        try {
235
            localStorage.setItem(this.get("sandbox")+JSON.stringify({"request":request}), JSON.stringify(entry));
236
            Y.log("Cached offline entry: " + Y.dump(entry), "info", "cache");
237
        }
238
        catch(error) {
239
            this.fire("error", {error:error});
240
            Y.log("Could not cache offline entry: " + Y.dump(entry) +
241
            " due to error: " + Y.dump(error), "warn", "cache");
242
        }
243
    },
244
 
245
    /**
246
     * Flushes cache.
247
     *
248
     * @method _defFlushFn
249
     * @param e {EventFacade} Event Facade object.
250
     * @protected
251
     */
252
    _defFlushFn: function(e) {
253
        var key,
254
            i=localStorage.length-1;
255
        for(; i>-1; --i) {
256
            // Match sandbox id
257
            key = localStorage.key(i);
258
            if(key.indexOf(this.get("sandbox")) === 0) {
259
                localStorage.removeItem(key);
260
            }
261
        }
262
    },
263
 
264
    /////////////////////////////////////////////////////////////////////////////
265
    //
266
    // CacheOffline public methods
267
    //
268
    /////////////////////////////////////////////////////////////////////////////
269
    /**
270
     * Adds a new entry to the cache of the format
271
     * {request:request, response:response, cached:cached, expires: expires}.
272
     *
273
     * @method add
274
     * @param request {Object} Request value must be a String or JSON.
275
     * @param response {Object} Response value must be a String or JSON.
276
     */
277
 
278
    /**
279
     * Retrieves cached object for given request, if available.
280
     * Returns null if there is no cache match.
281
     *
282
     * @method retrieve
283
     * @param request {Object} Request object.
284
     * @return {Object} Cached object with the properties request, response,
285
     * and expires, or null.
286
     */
287
    retrieve: function(request) {
288
        this.fire("request", {request: request});
289
 
290
        var entry, expires, sandboxedrequest;
291
 
292
        try {
293
            sandboxedrequest = this.get("sandbox")+JSON.stringify({"request":request});
294
            try {
295
                entry = JSON.parse(localStorage.getItem(sandboxedrequest));
296
            }
297
            catch(e) {
298
            }
299
        }
300
        catch(e2) {
301
        }
302
 
303
        if(entry) {
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;
309
 
310
            if(this._isMatch(request, entry)) {
311
                this.fire("retrieve", {entry: entry});
312
                Y.log("Retrieved offlinecached response: " + Y.dump(entry) +
313
                        " for request: " + Y.dump(request), "info", "cache");
314
                return entry;
315
            }
316
        }
317
        return null;
318
    }
319
} :
320
/////////////////////////////////////////////////////////////////////////////
321
//
322
// Offline is not supported
323
//
324
/////////////////////////////////////////////////////////////////////////////
325
{
326
    /**
327
     * Always return null.
328
     *
329
     * @method _setMax
330
     * @protected
331
     */
332
    _setMax: function(value) {
333
        return null;
334
    }
335
});
336
 
337
 
338
Y.CacheOffline = CacheOffline;
339
 
340
 
341
}, '3.18.1', {"requires": ["cache-base", "json"]});