123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- /*
- * jQuery history plugin
- *
- * The MIT License
- *
- * Copyright (c) 2006-2009 Taku Sano (Mikage Sawatari)
- * Copyright (c) 2010 Takayuki Miwa
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
- (function($) {
- var locationWrapper = {
- put: function(hash, win) {
- (win || window).location.hash = this.encoder(hash);
- },
- get: function(win) {
- var hash = ((win || window).location.hash).replace(/^#/, '');
- try {
- return $.browser.mozilla ? hash : decodeURIComponent(hash);
- }
- catch (error) {
- return hash;
- }
- },
- encoder: encodeURIComponent
- };
- var iframeWrapper = {
- id: "__jQuery_history",
- init: function() {
- var html = '<iframe id="'+ this.id +'" style="display:none" src="javascript:false;" />';
- $("body").prepend(html);
- return this;
- },
- _document: function() {
- return $("#"+ this.id)[0].contentWindow.document;
- },
- put: function(hash) {
- var doc = this._document();
- doc.open();
- doc.close();
- locationWrapper.put(hash, doc);
- },
- get: function() {
- return locationWrapper.get(this._document());
- }
- };
- function initObjects(options) {
- options = $.extend({
- unescape: false
- }, options || {});
- locationWrapper.encoder = encoder(options.unescape);
- function encoder(unescape_) {
- if(unescape_ === true) {
- return function(hash){ return hash; };
- }
- if(typeof unescape_ == "string" &&
- (unescape_ = partialDecoder(unescape_.split("")))
- || typeof unescape_ == "function") {
- return function(hash) { return unescape_(encodeURIComponent(hash)); };
- }
- return encodeURIComponent;
- }
- function partialDecoder(chars) {
- var re = new RegExp($.map(chars, encodeURIComponent).join("|"), "ig");
- return function(enc) { return enc.replace(re, decodeURIComponent); };
- }
- }
- var implementations = {};
- implementations.base = {
- callback: undefined,
- type: undefined,
- check: function() {},
- load: function(hash) {},
- init: function(callback, options) {
- initObjects(options);
- self.callback = callback;
- self._options = options;
- self._init();
- },
- _init: function() {},
- _options: {}
- };
- implementations.timer = {
- _appState: undefined,
- _init: function() {
- var current_hash = locationWrapper.get();
- self._appState = current_hash;
- self.callback(current_hash);
- setInterval(self.check, 100);
- },
- check: function() {
- var current_hash = locationWrapper.get();
- if(current_hash != self._appState) {
- self._appState = current_hash;
- self.callback(current_hash);
- }
- },
- load: function(hash) {
- if(hash != self._appState) {
- locationWrapper.put(hash);
- self._appState = hash;
- self.callback(hash);
- }
- }
- };
- implementations.iframeTimer = {
- _appState: undefined,
- _init: function() {
- var current_hash = locationWrapper.get();
- self._appState = current_hash;
- iframeWrapper.init().put(current_hash);
- self.callback(current_hash);
- setInterval(self.check, 100);
- },
- check: function() {
- var iframe_hash = iframeWrapper.get(),
- location_hash = locationWrapper.get();
- if (location_hash != iframe_hash) {
- if (location_hash == self._appState) { // user used Back or Forward button
- self._appState = iframe_hash;
- locationWrapper.put(iframe_hash);
- self.callback(iframe_hash);
- } else { // user loaded new bookmark
- self._appState = location_hash;
- iframeWrapper.put(location_hash);
- self.callback(location_hash);
- }
- }
- },
- load: function(hash) {
- if(hash != self._appState) {
- locationWrapper.put(hash);
- iframeWrapper.put(hash);
- self._appState = hash;
- self.callback(hash);
- }
- }
- };
- implementations.hashchangeEvent = {
- _init: function() {
- self.callback(locationWrapper.get());
- $(window).bind('hashchange', self.check);
- },
- check: function() {
- self.callback(locationWrapper.get());
- },
- load: function(hash) {
- locationWrapper.put(hash);
- }
- };
- var self = $.extend({}, implementations.base);
- if($.browser.msie && ($.browser.version < 8 || document.documentMode < 8)) {
- self.type = 'iframeTimer';
- } else if("onhashchange" in window) {
- self.type = 'hashchangeEvent';
- } else {
- self.type = 'timer';
- }
- $.extend(self, implementations[self.type]);
- $.history = self;
- })(jQuery);
|