OSDN Git Service

fix: op upload and destroy
[pettanr/pettanr.git] / app / assets / javascripts / backbone.fetch-cache.js
index 7bff9aa..ead7c11 100644 (file)
@@ -11,7 +11,7 @@
     define(['underscore', 'backbone', 'jquery'], function (_, Backbone, $) {
       return (root.Backbone = factory(_, Backbone, $));
     });
-  } else if (typeof exports !== 'undefined') {
+  } else if (typeof exports !== 'undefined' && typeof require !== 'undefined') {
     module.exports = factory(require('underscore'), require('backbone'), require('jquery'));
   } else {
     // Browser globals
   }
 
   // Shared methods
-  function getCacheKey(instance, opts) {
-    var url;
-
-    if(opts && opts.url) {
-      url = opts.url;
-    } else {
-      url = _.isFunction(instance.url) ? instance.url() : instance.url;
+  function getCacheKey(key, opts) {
+    if (key && _.isObject(key)) {
+      // If the model has its own, custom, cache key function, use it.
+      if (_.isFunction(key.getCacheKey)) {
+        return key.getCacheKey(opts);
+      }
+      // else, use the URL
+      if (opts && opts.url) {
+        key = opts.url;
+      } else {
+        key = _.isFunction(key.url) ? key.url() : key.url;
+      }
+    } else if (_.isFunction(key)) {
+      return key(opts);
     }
-
-    // Need url to use as cache key so return if we can't get it
-    if(!url) { return; }
-
-    if(opts && opts.data) {
+    if (opts && opts.data) {
       if(typeof opts.data === 'string') {
-        return url + '?' + opts.data;
+        return key + '?' + opts.data;
       } else {
-        return url + '?' + $.param(opts.data);
+        return key + '?' + $.param(opts.data);
       }
     }
-    return url;
+    return key;
   }
 
   function setCache(instance, opts, attrs) {
     opts = (opts || {});
     var key = Backbone.fetchCache.getCacheKey(instance, opts),
-        expires = false;
+        expires = false,
+        lastSync = (opts.lastSync || (new Date()).getTime()),
+        prefillExpires = false;
 
     // Need url to use as cache key so return if we can't get it
     if (!key) { return; }
       expires = (new Date()).getTime() + ((opts.expires || 5 * 60) * 1000);
     }
 
+    if (opts.prefillExpires !== false) {
+      prefillExpires = (new Date()).getTime() + ((opts.prefillExpires || 5 * 60) * 1000);
+    }
+
     Backbone.fetchCache._cache[key] = {
       expires: expires,
+      lastSync : lastSync,
+      prefillExpires: prefillExpires,
       value: attrs
     };
 
     Backbone.fetchCache.setLocalStorage();
   }
 
-  function clearItem(key) {
-    if (_.isFunction(key)) { key = key(); }
+  function getCache(key, opts) {
+    if (_.isFunction(key)) {
+      key = key();
+    } else if (key && _.isObject(key)) {
+      key = getCacheKey(key, opts);
+    }
+
+    return Backbone.fetchCache._cache[key];
+  }
+
+  function getLastSync(key, opts) {
+    return getCache(key).lastSync;
+  }
+
+  function clearItem(key, opts) {
+    if (_.isFunction(key)) {
+      key = key();
+    } else if (key && _.isObject(key)) {
+      key = getCacheKey(key, opts);
+    }
     delete Backbone.fetchCache._cache[key];
     Backbone.fetchCache.setLocalStorage();
   }
+  
+  function reset() {
+    // Clearing all cache items
+    Backbone.fetchCache._cache = {};
+  }
 
   function setLocalStorage() {
     if (!supportLocalStorage || !Backbone.fetchCache.localStorage) { return; }
       localStorage.setItem(Backbone.fetchCache.getLocalStorageKey(), JSON.stringify(Backbone.fetchCache._cache));
     } catch (err) {
       var code = err.code || err.number || err.message;
-      if (code === 22) {
+      if (code === 22 || code === 1014) {
         this._deleteCacheWithPriority();
       } else {
         throw(err);
     }
     opts = _.defaults(opts || {}, { parse: true });
     var key = Backbone.fetchCache.getCacheKey(this, opts),
-        data = Backbone.fetchCache._cache[key],
+        data = getCache(key),
         expired = false,
+        prefillExpired = false,
         attributes = false,
         deferred = new $.Deferred(),
         self = this;
 
+    function isPrefilling() {
+      return opts.prefill && (!opts.prefillExpires || prefillExpired);
+    }
+
     function setData() {
       if (opts.parse) {
         attributes = self.parse(attributes, opts);
       self.trigger('sync', self, attributes, opts);
 
       // Notify progress if we're still waiting for an AJAX call to happen...
-      if (opts.prefill) { deferred.notify(self); }
+      if (isPrefilling()) { deferred.notify(self); }
       // ...finish and return if we're not
       else {
         if (_.isFunction(opts.success)) { opts.success(self, attributes, opts); }
     if (data) {
       expired = data.expires;
       expired = expired && data.expires < (new Date()).getTime();
+      prefillExpired = data.prefillExpires;
+      prefillExpired = prefillExpired && data.prefillExpires < (new Date()).getTime();
       attributes = data.value;
     }
 
         setData();
       }
 
-      if (!opts.prefill) {
+      if (!isPrefilling()) {
         return deferred;
       }
     }
 
     opts = _.defaults(opts || {}, { parse: true });
     var key = Backbone.fetchCache.getCacheKey(this, opts),
-        data = Backbone.fetchCache._cache[key],
+        data = getCache(key),
         expired = false,
+        prefillExpired = false,
         attributes = false,
         deferred = new $.Deferred(),
         self = this;
 
+    function isPrefilling() {
+      return opts.prefill && (!opts.prefillExpires || prefillExpired);
+    }
+
     function setData() {
       self[opts.reset ? 'reset' : 'set'](attributes, opts);
       if (_.isFunction(opts.prefillSuccess)) { opts.prefillSuccess(self); }
       self.trigger('sync', self, attributes, opts);
 
       // Notify progress if we're still waiting for an AJAX call to happen...
-      if (opts.prefill) { deferred.notify(self); }
+      if (isPrefilling()) { deferred.notify(self); }
       // ...finish and return if we're not
       else {
         if (_.isFunction(opts.success)) { opts.success(self, attributes, opts); }
     if (data) {
       expired = data.expires;
       expired = expired && data.expires < (new Date()).getTime();
+      prefillExpired = data.prefillExpires;
+      prefillExpired = prefillExpired && data.prefillExpires < (new Date()).getTime();
       attributes = data.value;
     }
 
         setData();
       }
 
-      if (!opts.prefill) {
+      if (!isPrefilling()) {
         return deferred;
       }
     }
 
   Backbone.fetchCache._superMethods = superMethods;
   Backbone.fetchCache.setCache = setCache;
+  Backbone.fetchCache.getCache = getCache;
   Backbone.fetchCache.getCacheKey = getCacheKey;
+  Backbone.fetchCache.getLastSync = getLastSync;
   Backbone.fetchCache.clearItem = clearItem;
+  Backbone.fetchCache.reset = reset;
   Backbone.fetchCache.setLocalStorage = setLocalStorage;
   Backbone.fetchCache.getLocalStorage = getLocalStorage;