123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- /*
- * 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);
|