PageRenderTime 63ms CodeModel.GetById 30ms app.highlight 12ms RepoModel.GetById 18ms app.codeStats 0ms

/src/main/webapp/public/js/lib/jquery.history.js

http://thoughtsite.googlecode.com/
JavaScript | 165 lines | 120 code | 17 blank | 28 comment | 41 complexity | d035c1f13f1795e6d739cd045d6dfb9b MD5 | raw file
  1/*
  2 * jQuery history plugin
  3 * 
  4 * sample page: http://www.mikage.to/jquery/jquery_history.html
  5 *
  6 * Copyright (c) 2006-2009 Taku Sano (Mikage Sawatari)
  7 * Licensed under the MIT License:
  8 *   http://www.opensource.org/licenses/mit-license.php
  9 *
 10 * Modified by Lincoln Cooper to add Safari support and only call the callback once during initialization
 11 * for msie when no initial hash supplied.
 12 */
 13
 14
 15jQuery.extend({
 16	historyCurrentHash: undefined,
 17	historyCallback: undefined,
 18	historyIframeSrc: undefined,
 19	historyNeedIframe: jQuery.browser.msie && (jQuery.browser.version < 8 || document.documentMode < 8),
 20	
 21	historyInit: function(callback, src){
 22		jQuery.historyCallback = callback;
 23		if (src) jQuery.historyIframeSrc = src;
 24		var current_hash = location.hash.replace(/\?.*$/, '');
 25		
 26		jQuery.historyCurrentHash = current_hash;
 27		if (jQuery.historyNeedIframe) {
 28			// To stop the callback firing twice during initilization if no hash present
 29			if (jQuery.historyCurrentHash == '') {
 30				jQuery.historyCurrentHash = '#';
 31			}
 32		
 33			// add hidden iframe for IE
 34			jQuery("body").prepend('<iframe id="jQuery_history" style="display: none;"'+
 35				' src="javascript:false;"></iframe>'
 36			);
 37			var ihistory = jQuery("#jQuery_history")[0];
 38			var iframe = ihistory.contentWindow.document;
 39			iframe.open();
 40			iframe.close();
 41			iframe.location.hash = current_hash;
 42		}
 43		else if (jQuery.browser.safari) {
 44			// etablish back/forward stacks
 45			jQuery.historyBackStack = [];
 46			jQuery.historyBackStack.length = history.length;
 47			jQuery.historyForwardStack = [];
 48			jQuery.lastHistoryLength = history.length;
 49			
 50			jQuery.isFirst = true;
 51		}
 52		if(current_hash)
 53			jQuery.historyCallback(current_hash.replace(/^#/, ''));
 54		setInterval(jQuery.historyCheck, 100);
 55	},
 56	
 57	historyAddHistory: function(hash) {
 58		// This makes the looping function do something
 59		jQuery.historyBackStack.push(hash);
 60		
 61		jQuery.historyForwardStack.length = 0; // clear forwardStack (true click occured)
 62		this.isFirst = true;
 63	},
 64	
 65	historyCheck: function(){
 66		if (jQuery.historyNeedIframe) {
 67			// On IE, check for location.hash of iframe
 68			var ihistory = jQuery("#jQuery_history")[0];
 69			var iframe = ihistory.contentDocument || ihistory.contentWindow.document;
 70			var current_hash = iframe.location.hash.replace(/\?.*$/, '');
 71			if(current_hash != jQuery.historyCurrentHash) {
 72			
 73				location.hash = current_hash;
 74				jQuery.historyCurrentHash = current_hash;
 75				jQuery.historyCallback(current_hash.replace(/^#/, ''));
 76				
 77			}
 78		} else if (jQuery.browser.safari) {
 79			if(jQuery.lastHistoryLength == history.length && jQuery.historyBackStack.length > jQuery.lastHistoryLength) {
 80				jQuery.historyBackStack.shift();
 81			}
 82			if (!jQuery.dontCheck) {
 83				var historyDelta = history.length - jQuery.historyBackStack.length;
 84				jQuery.lastHistoryLength = history.length;
 85				
 86				if (historyDelta) { // back or forward button has been pushed
 87					jQuery.isFirst = false;
 88					if (historyDelta < 0) { // back button has been pushed
 89						// move items to forward stack
 90						for (var i = 0; i < Math.abs(historyDelta); i++) jQuery.historyForwardStack.unshift(jQuery.historyBackStack.pop());
 91					} else { // forward button has been pushed
 92						// move items to back stack
 93						for (var i = 0; i < historyDelta; i++) jQuery.historyBackStack.push(jQuery.historyForwardStack.shift());
 94					}
 95					var cachedHash = jQuery.historyBackStack[jQuery.historyBackStack.length - 1];
 96					if (cachedHash != undefined) {
 97						jQuery.historyCurrentHash = location.hash.replace(/\?.*$/, '');
 98						jQuery.historyCallback(cachedHash);
 99					}
100				} else if (jQuery.historyBackStack[jQuery.historyBackStack.length - 1] == undefined && !jQuery.isFirst) {
101					// back button has been pushed to beginning and URL already pointed to hash (e.g. a bookmark)
102					// document.URL doesn't change in Safari
103					if (location.hash) {
104						var current_hash = location.hash;
105						jQuery.historyCallback(location.hash.replace(/^#/, ''));
106					} else {
107						var current_hash = '';
108						jQuery.historyCallback('');
109					}
110					jQuery.isFirst = true;
111				}
112			}
113		} else {
114			// otherwise, check for location.hash
115			var current_hash = location.hash.replace(/\?.*$/, '');
116			if(current_hash != jQuery.historyCurrentHash) {
117				jQuery.historyCurrentHash = current_hash;
118				jQuery.historyCallback(current_hash.replace(/^#/, ''));
119			}
120		}
121	},
122	historyLoad: function(hash){
123		var newhash;
124		hash = decodeURIComponent(hash.replace(/\?.*$/, ''));
125		
126		if (jQuery.browser.safari) {
127			newhash = hash;
128		}
129		else {
130			newhash = '#' + hash;
131			location.hash = newhash;
132		}
133		jQuery.historyCurrentHash = newhash;
134		
135		if (jQuery.historyNeedIframe) {
136			var ihistory = jQuery("#jQuery_history")[0];
137			var iframe = ihistory.contentWindow.document;
138			iframe.open();
139			iframe.close();
140			iframe.location.hash = newhash;
141			jQuery.lastHistoryLength = history.length;
142			jQuery.historyCallback(hash);
143		}
144		else if (jQuery.browser.safari) {
145			jQuery.dontCheck = true;
146			// Manually keep track of the history values for Safari
147			this.historyAddHistory(hash);
148			
149			// Wait a while before allowing checking so that Safari has time to update the "history" object
150			// correctly (otherwise the check loop would detect a false change in hash).
151			var fn = function() {jQuery.dontCheck = false;};
152			window.setTimeout(fn, 200);
153			jQuery.historyCallback(hash);
154			// N.B. "location.hash=" must be the last line of code for Safari as execution stops afterwards.
155			//      By explicitly using the "location.hash" command (instead of using a variable set to "location.hash") the
156			//      URL in the browser and the "history" object are both updated correctly.
157			location.hash = newhash;
158		}
159		else {
160		  jQuery.historyCallback(hash);
161		}
162	}
163});
164
165