Browse Source

- New implementation of the n-n link edition widget... in progress.

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@657 a333f486-631f-4898-b8df-5754b55c2be0
dflaven 15 years ago
parent
commit
34c65d4d0d
1 changed files with 156 additions and 0 deletions
  1. 156 0
      js/jquery.history.js

+ 156 - 0
js/jquery.history.js

@@ -0,0 +1,156 @@
+/*
+ * jQuery history plugin
+ *
+ * Copyright (c) 2006 Taku Sano (Mikage Sawatari)
+ * Licensed under the MIT License:
+ *   http://www.opensource.org/licenses/mit-license.php
+ *
+ * Modified by Lincoln Cooper to add Safari support and only call the callback once during initialization
+ * for msie when no initial hash supplied.
+ * API rewrite by Lauris Bukðis-Haberkorns
+ */
+
+(function($) {
+
+function History()
+{
+	this._curHash = '';
+	this._callback = function(hash){};
+};
+
+$.extend(History.prototype, {
+
+	init: function(callback) {
+		this._callback = callback;
+		this._curHash = location.hash;
+
+		if($.browser.msie) {
+			// To stop the callback firing twice during initilization if no hash present
+			if (this._curHash == '') {
+				this._curHash = '#';
+			}
+
+			// add hidden iframe for IE
+			$("body").prepend('<iframe id="jQuery_history" style="display: none;"></iframe>');
+			var iframe = $("#jQuery_history")[0].contentWindow.document;
+			iframe.open();
+			iframe.close();
+			iframe.location.hash = this._curHash;
+		}
+		else if ($.browser.safari) {
+			// etablish back/forward stacks
+			this._historyBackStack = [];
+			this._historyBackStack.length = history.length;
+			this._historyForwardStack = [];
+			this._isFirst = true;
+			this._dontCheck = false;
+		}
+		this._callback(this._curHash.replace(/^#/, ''));
+		setInterval(this._check, 100);
+	},
+
+	add: function(hash) {
+		// This makes the looping function do something
+		this._historyBackStack.push(hash);
+		
+		this._historyForwardStack.length = 0; // clear forwardStack (true click occured)
+		this._isFirst = true;
+	},
+	
+	_check: function() {
+		if($.browser.msie) {
+			// On IE, check for location.hash of iframe
+			var ihistory = $("#jQuery_history")[0];
+			var iframe = ihistory.contentDocument || ihistory.contentWindow.document;
+			var current_hash = iframe.location.hash;
+			if(current_hash != $.history._curHash) {
+			
+				location.hash = current_hash;
+				$.history._curHash = current_hash;
+				$.history._callback(current_hash.replace(/^#/, ''));
+				
+			}
+		} else if ($.browser.safari) {
+			if (!$.history._dontCheck) {
+				var historyDelta = history.length - $.history._historyBackStack.length;
+				
+				if (historyDelta) { // back or forward button has been pushed
+					$.history._isFirst = false;
+					if (historyDelta < 0) { // back button has been pushed
+						// move items to forward stack
+						for (var i = 0; i < Math.abs(historyDelta); i++) $.history._historyForwardStack.unshift($.history._historyBackStack.pop());
+					} else { // forward button has been pushed
+						// move items to back stack
+						for (var i = 0; i < historyDelta; i++) $.history._historyBackStack.push($.history._historyForwardStack.shift());
+					}
+					var cachedHash = $.history._historyBackStack[$.history._historyBackStack.length - 1];
+					if (cachedHash != undefined) {
+						$.history._curHash = location.hash;
+						$.history._callback(cachedHash);
+					}
+				} else if ($.history._historyBackStack[$.history._historyBackStack.length - 1] == undefined && !$.history._isFirst) {
+					// back button has been pushed to beginning and URL already pointed to hash (e.g. a bookmark)
+					// document.URL doesn't change in Safari
+					if (document.URL.indexOf('#') >= 0) {
+						$.history._callback(document.URL.split('#')[1]);
+					} else {
+						$.history._callback('');
+					}
+					$.history._isFirst = true;
+				}
+			}
+		} else {
+			// otherwise, check for location.hash
+			var current_hash = location.hash;
+			if(current_hash != $.history._curHash) {
+				$.history._curHash = current_hash;
+				$.history._callback(current_hash.replace(/^#/, ''));
+			}
+		}
+	},
+
+	load: function(hash) {
+		var newhash;
+		
+		if ($.browser.safari) {
+			newhash = hash;
+		} else {
+			newhash = '#' + hash;
+			location.hash = newhash;
+		}
+		this._curHash = newhash;
+		
+		if ($.browser.msie) {
+			var ihistory = $("#jQuery_history")[0]; // TODO: need contentDocument?
+			var iframe = ihistory.contentWindow.document;
+			iframe.open();
+			iframe.close();
+			iframe.location.hash = newhash;
+			this._callback(hash);
+		}
+		else if ($.browser.safari) {
+			this._dontCheck = true;
+			// Manually keep track of the history values for Safari
+			this.add(hash);
+			
+			// Wait a while before allowing checking so that Safari has time to update the "history" object
+			// correctly (otherwise the check loop would detect a false change in hash).
+			var fn = function() {$.history._dontCheck = false;};
+			window.setTimeout(fn, 200);
+			this._callback(hash);
+			// N.B. "location.hash=" must be the last line of code for Safari as execution stops afterwards.
+			//      By explicitly using the "location.hash" command (instead of using a variable set to "location.hash") the
+			//      URL in the browser and the "history" object are both updated correctly.
+			location.hash = newhash;
+		}
+		else {
+		  this._callback(hash);
+		}
+	}
+});
+
+$(document).ready(function() {
+	$.history = new History(); // singleton instance
+});
+
+})(jQuery);