shosei

* jQuery Offline

Mar 15th, 2012
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
jQuery 7.28 KB | None | 0 0
  1. /*!
  2.  * jQuery Offline
  3.  * Version 1.0.0
  4.  *
  5.  * http://github.com/wycats/jquery-offline
  6.  *
  7.  * Copyright 2010, Yehuda Katz
  8.  *
  9.  * Permission is hereby granted, free of charge, to any person obtaining a copy
  10.  * of this software and associated documentation files (the "Software"), to deal
  11.  * in the Software without restriction, including without limitation the rights
  12.  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13.  * copies of the Software, and to permit persons to whom the Software is
  14.  * furnished to do so, subject to the following conditions:
  15.  *
  16.  * The above copyright notice and this permission notice shall be included in
  17.  * all copies or substantial portions of the Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22.  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25.  * THE SOFTWARE.
  26.  *
  27.  * Date: Fri Jul 9 10:20:00 2010 -0800
  28.  */
  29.  
  30. (function($) {
  31.  
  32.   var prefix = "offline.jquery:",
  33.     mostRecent = null,
  34.     requesting = {};
  35.  
  36.   // Allow the user to explicitly turn off localStorage
  37.   // before loading this plugin
  38.   if (typeof $.support.localStorage === "undefined") {
  39.     $.support.localStorage = !!window.localStorage;
  40.   }
  41.  
  42.   // modified getJSON which uses ifModified: true
  43.   function getJSON(url, data, fn) {
  44.     if (jQuery.isFunction(data)) {
  45.       fn = data;
  46.       data = null;
  47.     }
  48.  
  49.     var requestingKey = url + "?" + $.param(data || {});
  50.     if (requesting[requestingKey]) {
  51.       return false;
  52.     }
  53.  
  54.     requesting[requestingKey] = true;
  55.  
  56.     return jQuery.ajax({
  57.       type: "GET",
  58.       url: url,
  59.       data: data,
  60.       success: function(responseData, text) {
  61.         delete requesting[requestingKey];
  62.  
  63.         // handle lack of response (error callback isn't called in this case)
  64.         if (undefined === responseData) {
  65.           if (!window.navigator.onLine) {
  66.             // requeue the request for the next time we come online
  67.             mostRecent = function() {
  68.               getJSON(url, data, fn);
  69.             };
  70.           }
  71.           return;
  72.         }
  73.  
  74.         fn(responseData, text);
  75.       },
  76.       error: function() {
  77.         delete requesting[requestingKey];
  78.       },
  79.       dataType: "json",
  80.       ifModified: true
  81.     });
  82.   }
  83.  
  84.   if ($.support.localStorage) {
  85.     // If localStorage is available, define jQuery.retrieveJSON
  86.     // and jQuery.clearJSON to operate in terms of the offline
  87.     // cache
  88.     // If the user comes online, run the most recent request
  89.     // that was queued due to the user being offline
  90.     $(window).bind("online", function() {
  91.       if (mostRecent) {
  92.         mostRecent();
  93.       }
  94.     });
  95.  
  96.     // If the user goes offline, hide any loading bar
  97.     // the user may have created
  98.     $(window).bind("offline", function() {
  99.       jQuery.event.trigger("ajaxStop");
  100.     });
  101.  
  102.     $.retrieveJSON = function(url, data, fn) {
  103.       // allow jQuery.retrieveJSON(url, fn)
  104.       if ($.isFunction(data)) {
  105.         fn = data;
  106.         data = {};
  107.       }
  108.  
  109.       // remember when this request started so we can report
  110.       // the time when a follow-up Ajax request completes.
  111.       // this is especially important when the user comes
  112.       // back online, since retrieveDate may be minutes,
  113.       // hours or even days before the Ajax request finally
  114.       // completes
  115.       var retrieveDate = new Date;
  116.  
  117.       // get a String value for the data passed in, and then
  118.       // use it to calculate a cache key
  119.       var param       = $.param(data),
  120.           key         = prefix + url + ":" + param,
  121.           text        = localStorage[key],
  122.           dateString  = localStorage[key + ":date"],
  123.           date        = new Date(Date.parse(dateString));
  124.  
  125.       function cleanupLocalStorage() {
  126.         // take all date keys and remove the oldest half
  127.         var dateKeys = [];
  128.         for (var i = 0; i < localStorage.length; ++i) {
  129.           var key = localStorage.key(i);
  130.           if (/:date$/.test(key)) {
  131.             dateKeys.push(key);
  132.           }
  133.         }
  134.         dateKeys.sort(function(a, b) {
  135.           var date_a = localStorage[a], date_b = localStorage[b];
  136.           return date_a < date_b ? -1 : (date_a > date_b ? +1 : 0);
  137.         });
  138.         for (var i = 0; i < dateKeys.length / 2; ++i) {
  139.           var key = dateKeys[i];
  140.           delete localStorage[key];
  141.           delete localStorage[key.substr(0, key.length - 5)]; // :date
  142.         }
  143.       }
  144.  
  145.       // create a function that will make an Ajax request and
  146.       // store the result in the cache. This function will be
  147.       // deferred until later if the user is offline
  148.       function getData() {
  149.         return getJSON(url, data, function(json, status) {
  150.           if ( status == 'notmodified' ) {
  151.             // Just return if the response has a 304 status code
  152.             return false;
  153.           }
  154.  
  155.           while (true) {
  156.             try {
  157.               localStorage[key] = JSON.stringify(json);
  158.               localStorage[key + ":date"] = new Date;
  159.               break;
  160.             } catch (e) {
  161.                 if (e.name == "QUOTA_EXCEEDED_ERR" || e.name ==
  162.                     "NS_ERROR_DOM_QUOTA_REACHED") {
  163.                   cleanupLocalStorage();
  164.                 }
  165.             }
  166.           }
  167.  
  168.           // If this is a follow-up request, create an object
  169.           // containing both the original time of the cached
  170.           // data and the time that the data was originally
  171.           // retrieved from the cache. With this information,
  172.           // users of jQuery Offline can provide the user
  173.           // with improved feedback if the lag is large
  174.           var data = text && { cachedAt: date, retrievedAt: retrieveDate };
  175.           fn(json, status, data);
  176.         });
  177.       }
  178.  
  179.       // If there is anything in the cache, call the callback
  180.       // right away, with the "cached" status string
  181.       if( text ) {
  182.         var obj = $.parseJSON(text);
  183.         var response = fn( obj, "cached", { cachedAt: date } );
  184.         if( response === false ) {
  185.           var dfd = $.Deferred().promise();
  186.           dfd.done = function(callback) { callback(obj) };
  187.           return dfd;
  188.         }
  189.       }
  190.  
  191.       // If the user is online, make the Ajax request right away;
  192.       // otherwise, make it the most recent callback so it will
  193.       // get triggered when the user comes online
  194.       if (window.navigator.onLine) {
  195.         return getData();
  196.       } else {
  197.         mostRecent = getData;
  198.       }
  199.  
  200.       return true;
  201.     };
  202.  
  203.     // jQuery.clearJSON is simply a wrapper around deleting the
  204.     // localStorage for a URL/data pair
  205.     $.clearJSON = function(url, data) {
  206.       var param = $.param(data || {});
  207.       delete localStorage[prefix + url + ":" + param];
  208.       delete localStorage[prefix + url + ":" + param + ":date"];
  209.     };
  210.   } else {
  211.     // If localStorage is unavailable, just make all requests
  212.     // regular Ajax requests.
  213.     $.retrieveJSON = getJSON;
  214.     $.clearJSON = $.noop;
  215.   }
  216.  
  217. })(jQuery);
Advertisement
Add Comment
Please, Sign In to add comment