andrew4582

jquery.history.js

Aug 1st, 2011
271
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. * jQuery history plugin
  3. *
  4. * The MIT License
  5. *
  6. * Copyright (c) 2006-2009 Taku Sano (Mikage Sawatari)
  7. * Copyright (c) 2010 Takayuki Miwa
  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.  
  28. (function ($) {
  29.     var locationWrapper = {
  30.         put: function (hash, win) {
  31.             (win || window).location.hash = this.encoder(hash);
  32.         },
  33.         get: function (win) {
  34.             var hash = ((win || window).location.hash).replace(/^#/, '');
  35.             try {
  36.                 return $.browser.mozilla ? hash : decodeURIComponent(hash);
  37.             }
  38.             catch (error) {
  39.                 return hash;
  40.             }
  41.         },
  42.         encoder: encodeURIComponent
  43.     };
  44.  
  45.     var iframeWrapper = {
  46.         id: "__jQuery_history",
  47.         init: function () {
  48.             var html = '<iframe id="' + this.id + '" style="display:none" src="javascript:false;" />';
  49.             $("body").prepend(html);
  50.             return this;
  51.         },
  52.         _document: function () {
  53.             return $("#" + this.id)[0].contentWindow.document;
  54.         },
  55.         put: function (hash) {
  56.             var doc = this._document();
  57.             doc.open();
  58.             doc.close();
  59.             locationWrapper.put(hash, doc);
  60.         },
  61.         get: function () {
  62.             return locationWrapper.get(this._document());
  63.         }
  64.     };
  65.  
  66.     function initObjects(options) {
  67.         options = $.extend({
  68.             unescape: false
  69.         }, options || {});
  70.  
  71.         locationWrapper.encoder = encoder(options.unescape);
  72.  
  73.         function encoder(unescape_) {
  74.             if (unescape_ === true) {
  75.                 return function (hash) { return hash; };
  76.             }
  77.             if (typeof unescape_ == "string" &&
  78.                (unescape_ = partialDecoder(unescape_.split("")))
  79.                || typeof unescape_ == "function") {
  80.                 return function (hash) { return unescape_(encodeURIComponent(hash)); };
  81.             }
  82.             return encodeURIComponent;
  83.         }
  84.  
  85.         function partialDecoder(chars) {
  86.             var re = new RegExp($.map(chars, encodeURIComponent).join("|"), "ig");
  87.             return function (enc) { return enc.replace(re, decodeURIComponent); };
  88.         }
  89.     }
  90.  
  91.     var implementations = {};
  92.  
  93.     implementations.base = {
  94.         callback: undefined,
  95.         type: undefined,
  96.  
  97.         check: function () { },
  98.         load: function (hash) { },
  99.         init: function (callback, options) {
  100.             initObjects(options);
  101.             self.callback = callback;
  102.             self._options = options;
  103.             self._init();
  104.         },
  105.  
  106.         _init: function () { },
  107.         _options: {}
  108.     };
  109.  
  110.     implementations.timer = {
  111.         _appState: undefined,
  112.         _init: function () {
  113.             var current_hash = locationWrapper.get();
  114.             self._appState = current_hash;
  115.             self.callback(current_hash);
  116.             setInterval(self.check, 100);
  117.         },
  118.         check: function () {
  119.             var current_hash = locationWrapper.get();
  120.             if (current_hash != self._appState) {
  121.                 self._appState = current_hash;
  122.                 self.callback(current_hash);
  123.             }
  124.         },
  125.         load: function (hash) {
  126.             if (hash != self._appState) {
  127.                 locationWrapper.put(hash);
  128.                 self._appState = hash;
  129.                 self.callback(hash);
  130.             }
  131.         }
  132.     };
  133.  
  134.     implementations.iframeTimer = {
  135.         _appState: undefined,
  136.         _init: function () {
  137.             var current_hash = locationWrapper.get();
  138.             self._appState = current_hash;
  139.             iframeWrapper.init().put(current_hash);
  140.             self.callback(current_hash);
  141.             setInterval(self.check, 100);
  142.         },
  143.         check: function () {
  144.             var iframe_hash = iframeWrapper.get(),
  145.                 location_hash = locationWrapper.get();
  146.  
  147.             if (location_hash != iframe_hash) {
  148.                 if (location_hash == self._appState) {    // user used Back or Forward button
  149.                     self._appState = iframe_hash;
  150.                     locationWrapper.put(iframe_hash);
  151.                     self.callback(iframe_hash);
  152.                 } else {                              // user loaded new bookmark
  153.                     self._appState = location_hash;
  154.                     iframeWrapper.put(location_hash);
  155.                     self.callback(location_hash);
  156.                 }
  157.             }
  158.         },
  159.         load: function (hash) {
  160.             if (hash != self._appState) {
  161.                 locationWrapper.put(hash);
  162.                 iframeWrapper.put(hash);
  163.                 self._appState = hash;
  164.                 self.callback(hash);
  165.             }
  166.         }
  167.     };
  168.  
  169.     implementations.hashchangeEvent = {
  170.         _init: function () {
  171.             self.callback(locationWrapper.get());
  172.             $(window).bind('hashchange', self.check);
  173.         },
  174.         check: function () {
  175.             self.callback(locationWrapper.get());
  176.         },
  177.         load: function (hash) {
  178.             locationWrapper.put(hash);
  179.         }
  180.     };
  181.  
  182.     var self = $.extend({}, implementations.base);
  183.  
  184.     if ($.browser.msie && ($.browser.version < 8 || document.documentMode < 8)) {
  185.         self.type = 'iframeTimer';
  186.     } else if ("onhashchange" in window) {
  187.         self.type = 'hashchangeEvent';
  188.     } else {
  189.         self.type = 'timer';
  190.     }
  191.  
  192.     $.extend(self, implementations[self.type]);
  193.     $.history = self;
  194. })(jQuery);
Advertisement
Add Comment
Please, Sign In to add comment