1/* 2 * jQuery history plugin 3 * 4 * Copyright (c) 2006 Taku Sano (Mikage Sawatari) 5 * Licensed under the MIT License: 6 * http://www.opensource.org/licenses/mit-license.php 7 * 8 * Modified by Lincoln Cooper to add Safari support and only call the callback once during initialization 9 * for msie when no initial hash supplied. 10 * API rewrite by Lauris Buk�is-Haberkorns 11 */ 12 13(function($) { 14 15function History() 16{ 17 this._curHash = ''; 18 this._callback = function(hash){}; 19}; 20 21$.extend(History.prototype, { 22 23 init: function(callback) { 24 this._callback = callback; 25 this._curHash = location.hash; 26 27 if($.browser.msie) { 28 // To stop the callback firing twice during initilization if no hash present 29 if (this._curHash == '') { 30 this._curHash = '#'; 31 } 32 33 // add hidden iframe for IE 34 $("body").prepend('<iframe id="jQuery_history" style="display: none;"></iframe>'); 35 var iframe = $("#jQuery_history")[0].contentWindow.document; 36 iframe.open(); 37 iframe.close(); 38 iframe.location.hash = this._curHash; 39 } 40 else if ($.browser.safari) { 41 // etablish back/forward stacks 42 this._historyBackStack = []; 43 this._historyBackStack.length = history.length; 44 this._historyForwardStack = []; 45 this._isFirst = true; 46 this._dontCheck = false; 47 } 48 this._callback(this._curHash.replace(/^#/, '')); 49 setInterval(this._check, 100); 50 }, 51 52 add: function(hash) { 53 // This makes the looping function do something 54 this._historyBackStack.push(hash); 55 56 this._historyForwardStack.length = 0; // clear forwardStack (true click occured) 57 this._isFirst = true; 58 }, 59 60 _check: function() { 61 if($.browser.msie) { 62 // On IE, check for location.hash of iframe 63 var ihistory = $("#jQuery_history")[0]; 64 var iframe = ihistory.contentDocument || ihistory.contentWindow.document; 65 var current_hash = iframe.location.hash; 66 if(current_hash != $.history._curHash) { 67 68 location.hash = current_hash; 69 $.history._curHash = current_hash; 70 $.history._callback(current_hash.replace(/^#/, '')); 71 72 } 73 } else if ($.browser.safari) { 74 if (!$.history._dontCheck) { 75 var historyDelta = history.length - $.history._historyBackStack.length; 76 77 if (historyDelta) { // back or forward button has been pushed 78 $.history._isFirst = false; 79 if (historyDelta < 0) { // back button has been pushed 80 // move items to forward stack 81 for (var i = 0; i < Math.abs(historyDelta); i++) $.history._historyForwardStack.unshift($.history._historyBackStack.pop()); 82 } else { // forward button has been pushed 83 // move items to back stack 84 for (var i = 0; i < historyDelta; i++) $.history._historyBackStack.push($.history._historyForwardStack.shift()); 85 } 86 var cachedHash = $.history._historyBackStack[$.history._historyBackStack.length - 1]; 87 if (cachedHash != undefined) { 88 $.history._curHash = location.hash; 89 $.history._callback(cachedHash); 90 } 91 } else if ($.history._historyBackStack[$.history._historyBackStack.length - 1] == undefined && !$.history._isFirst) { 92 // back button has been pushed to beginning and URL already pointed to hash (e.g. a bookmark) 93 // document.URL doesn't change in Safari 94 if (document.URL.indexOf('#') >= 0) { 95 $.history._callback(document.URL.split('#')[1]); 96 } else { 97 $.history._callback(''); 98 } 99 $.history._isFirst = true; 100 } 101 } 102 } else { 103 // otherwise, check for location.hash 104 var current_hash = location.hash; 105 if(current_hash != $.history._curHash) { 106 $.history._curHash = current_hash; 107 $.history._callback(current_hash.replace(/^#/, '')); 108 } 109 } 110 }, 111 112 load: function(hash) { 113 var newhash; 114 115 if ($.browser.safari) { 116 newhash = hash; 117 } else { 118 newhash = '#' + hash; 119 location.hash = newhash; 120 } 121 this._curHash = newhash; 122 123 if ($.browser.msie) { 124 var ihistory = $("#jQuery_history")[0]; // TODO: need contentDocument? 125 var iframe = ihistory.contentWindow.document; 126 iframe.open(); 127 iframe.close(); 128 iframe.location.hash = newhash; 129 this._callback(hash); 130 } 131 else if ($.browser.safari) { 132 this._dontCheck = true; 133 // Manually keep track of the history values for Safari 134 this.add(hash); 135 136 // Wait a while before allowing checking so that Safari has time to update the "history" object
137 // correctly (otherwise the check loop would detect a false change in hash). 138 var fn = function() {$.history._dontCheck = false;}; 139 window.setTimeout(fn, 200); 140 this._callback(hash); 141 // N.B. "location.hash=" must be the last line of code for Safari as execution stops afterwards. 142 // By explicitly using the "location.hash" command (instead of using a variable set to "location.hash") the 143 // URL in the browser and the "history" object are both updated correctly. 144 location.hash = newhash; 145 } 146 else { 147 this._callback(hash); 148 } 149 } 150}); 151 152$(document).ready(function() { 153 $.history = new History(); // singleton instance 154}); 155 156})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.