[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/sites/all/modules/jquery_ui/jquery.ui.old/demos/functional/js/ -> jquery.history_remote.js (source)

   1  /**

   2   * History/Remote - jQuery plugin for enabling history support and bookmarking

   3   * @requires jQuery v1.0.3

   4   *

   5   * http://stilbuero.de/jquery/history/

   6   *

   7   * Copyright (c) 2006 Klaus Hartl (stilbuero.de)

   8   * Dual licensed under the MIT and GPL licenses:

   9   * http://www.opensource.org/licenses/mit-license.php

  10   * http://www.gnu.org/licenses/gpl.html

  11   *

  12   * Version: 0.2.3

  13   */
  14  
  15  (function($) { // block scope
  16  
  17  /**

  18   * Initialize the history manager. Subsequent calls will not result in additional history state change 

  19   * listeners. Should be called soonest when the DOM is ready, because in IE an iframe needs to be added

  20   * to the body to enable history support.

  21   *

  22   * @example $.ajaxHistory.initialize();

  23   *

  24   * @param Function callback A single function that will be executed in case there is no fragment

  25   *                          identifier in the URL, for example after navigating back to the initial

  26   *                          state. Use to restore such an initial application state.

  27   *                          Optional. If specified it will overwrite the default action of 

  28   *                          emptying all containers that are used to load content into.

  29   * @type undefined

  30   *

  31   * @name $.ajaxHistory.initialize()

  32   * @cat Plugins/History

  33   * @author Klaus Hartl/klaus.hartl@stilbuero.de

  34   */
  35  $.ajaxHistory = new function() {
  36  
  37      var RESET_EVENT = 'historyReset';
  38  
  39      var _currentHash = location.hash;
  40      var _intervalId = null;
  41      var _observeHistory; // define outside if/else required by Opera

  42  
  43      this.update = function() { }; // empty function body for graceful degradation

  44  
  45      // create custom event for state reset

  46      var _defaultReset = function() {
  47          $('.remote-output').empty();
  48      };
  49      $(document).bind(RESET_EVENT, _defaultReset);
  50      
  51      // TODO fix for Safari 3

  52      // if ($.browser.msie)

  53      // else if hash != _currentHash

  54      // else check history length

  55  
  56      if ($.browser.msie) {
  57  
  58          var _historyIframe, initialized = false; // for IE

  59  
  60          // add hidden iframe

  61          $(function() {
  62              _historyIframe = $('<iframe style="display: none;"></iframe>').appendTo(document.body).get(0);
  63              var iframe = _historyIframe.contentWindow.document;
  64              // create initial history entry

  65              iframe.open();
  66              iframe.close();
  67              if (_currentHash && _currentHash != '#') {
  68                  iframe.location.hash = _currentHash.replace('#', '');
  69              }
  70          });
  71  
  72          this.update = function(hash) {
  73              _currentHash = hash;
  74              var iframe = _historyIframe.contentWindow.document;
  75              iframe.open();
  76              iframe.close();
  77              iframe.location.hash = hash.replace('#', '');
  78          };
  79  
  80          _observeHistory = function() {
  81              var iframe = _historyIframe.contentWindow.document;
  82              var iframeHash = iframe.location.hash;
  83              if (iframeHash != _currentHash) {
  84                  _currentHash = iframeHash;
  85                  if (iframeHash && iframeHash != '#') {
  86                      // order does matter, set location.hash after triggering the click...

  87                      $('a[@href$="' + iframeHash + '"]').click();
  88                      location.hash = iframeHash;
  89                  } else if (initialized) {
  90                      location.hash = '';
  91                      $(document).trigger(RESET_EVENT);
  92                  }
  93              }
  94              initialized = true;
  95          };
  96  
  97      } else if ($.browser.mozilla || $.browser.opera) {
  98  
  99          this.update = function(hash) {
 100              _currentHash = hash;
 101          };
 102  
 103          _observeHistory = function() {
 104              if (location.hash) {
 105                  if (_currentHash != location.hash) {
 106                      _currentHash = location.hash;
 107                      $('a[@href$="' + _currentHash + '"]').click();
 108                  }
 109              } else if (_currentHash) {
 110                  _currentHash = '';
 111                  $(document).trigger(RESET_EVENT);
 112              }
 113          };
 114  
 115      } else if ($.browser.safari) {
 116  
 117          var _backStack, _forwardStack, _addHistory; // for Safari

 118  
 119          // etablish back/forward stacks

 120          $(function() {
 121              _backStack = [];
 122              _backStack.length = history.length;
 123              _forwardStack = [];
 124  
 125          });
 126          var isFirst = false, initialized = false;
 127          _addHistory = function(hash) {
 128              _backStack.push(hash);
 129              _forwardStack.length = 0; // clear forwardStack (true click occured)

 130              isFirst = false;
 131          };
 132  
 133          this.update = function(hash) {
 134              _currentHash = hash;
 135              _addHistory(_currentHash);
 136          };
 137  
 138          _observeHistory = function() {
 139              var historyDelta = history.length - _backStack.length;
 140              if (historyDelta) { // back or forward button has been pushed
 141                  isFirst = false;
 142                  if (historyDelta < 0) { // back button has been pushed
 143                      // move items to forward stack

 144                      for (var i = 0; i < Math.abs(historyDelta); i++) _forwardStack.unshift(_backStack.pop());
 145                  } else { // forward button has been pushed
 146                      // move items to back stack

 147                      for (var i = 0; i < historyDelta; i++) _backStack.push(_forwardStack.shift());
 148                  }
 149                  var cachedHash = _backStack[_backStack.length - 1];
 150                  $('a[@href$="' + cachedHash + '"]').click();
 151                  _currentHash = location.hash;
 152              } else if (_backStack[_backStack.length - 1] == undefined && !isFirst) {
 153                  // back button has been pushed to beginning and URL already pointed to hash (e.g. a bookmark)

 154                  // document.URL doesn't change in Safari

 155                  if (document.URL.indexOf('#') >= 0) {
 156                      $('a[@href$="' + '#' + document.URL.split('#')[1] + '"]').click();
 157                  } else if (initialized) {
 158                      $(document).trigger(RESET_EVENT);
 159                  }
 160                  isFirst = true;
 161              }
 162              initialized = true;
 163          };
 164  
 165      }
 166  
 167      this.initialize = function(callback) {
 168          // custom callback to reset app state (no hash in url)

 169          if (typeof callback == 'function') {
 170              $(document).unbind(RESET_EVENT, _defaultReset).bind(RESET_EVENT, callback);
 171          }
 172          // look for hash in current URL (not Safari)

 173          if (location.hash && typeof _addHistory == 'undefined') {
 174              $('a[@href$="' + location.hash + '"]').trigger('click');
 175          }
 176          // start observer

 177          if (_observeHistory && _intervalId == null) {
 178              _intervalId = setInterval(_observeHistory, 200); // Safari needs at least 200 ms

 179          }
 180      };
 181  
 182  };
 183  
 184  /**

 185   * Implement Ajax driven links in a completely unobtrusive and accessible manner (also known as "Hijax")

 186   * with support for the browser's back/forward navigation buttons and bookmarking.

 187   *

 188   * The link's href attribute gets altered to a fragment identifier, such as "#remote-1", so that the browser's

 189   * URL gets updated on each click, whereas the former value of that attribute is used to load content via

 190   * XmlHttpRequest from and update the specified element. If no target element is found, a new div element will be

 191   * created and appended to the body to load the content into. The link informs the history manager of the 

 192   * state change on click and adds an entry to the browser's history.

 193   *

 194   * jQuery's Ajax implementation adds a custom request header of the form "X-Requested-With: XmlHttpRequest"

 195   * to any Ajax request so that the called page can distinguish between a standard and an Ajax (XmlHttpRequest)

 196   * request.

 197   *

 198   * @example $('a.remote').remote('#output');

 199   * @before <a class="remote" href="/path/to/content.html">Update</a>

 200   * @result <a class="remote" href="#remote-1">Update</a>

 201   * @desc Alter a link of the class "remote" to an Ajax-enhanced link and let it load content from

 202   *       "/path/to/content.html" via XmlHttpRequest into an element with the id "output".

 203   * @example $('a.remote').remote('#output', {hashPrefix: 'chapter'});

 204   * @before <a class="remote" href="/path/to/content.html">Update</a>

 205   * @result <a class="remote" href="#chapter-1">Update</a>

 206   * @desc Alter a link of the class "remote" to an Ajax-enhanced link and let it load content from

 207   *       "/path/to/content.html" via XmlHttpRequest into an element with the id "output".

 208   *

 209   * @param String expr A string containing a CSS selector or basic XPath specifying the element to load

 210   *                    content into via XmlHttpRequest.

 211   * @param Object settings An object literal containing key/value pairs to provide optional settings.

 212   * @option String hashPrefix A String that is used for constructing the hash the link's href attribute

 213   *                           gets altered to, such as "#remote-1". Default value: "remote-".

 214   * @param Function callback A single function that will be executed when the request is complete. 

 215   * @type jQuery

 216   *

 217   * @name remote

 218   * @cat Plugins/Remote

 219   * @author Klaus Hartl/klaus.hartl@stilbuero.de

 220   */
 221  
 222  /**

 223   * Implement Ajax driven links in a completely unobtrusive and accessible manner (also known as "Hijax")

 224   * with support for the browser's back/forward navigation buttons and bookmarking.

 225   *

 226   * The link's href attribute gets altered to a fragment identifier, such as "#remote-1", so that the browser's

 227   * URL gets updated on each click, whereas the former value of that attribute is used to load content via

 228   * XmlHttpRequest from and update the specified element. If no target element is found, a new div element will be

 229   * created and appended to the body to load the content into. The link informs the history manager of the 

 230   * state change on click and adds an entry to the browser's history.

 231   *

 232   * jQuery's Ajax implementation adds a custom request header of the form "X-Requested-With: XmlHttpRequest"

 233   * to any Ajax request so that the called page can distinguish between a standard and an Ajax (XmlHttpRequest)

 234   * request.

 235   *

 236   * @example $('a.remote').remote( $('#output > div')[0] );

 237   * @before <a class="remote" href="/path/to/content.html">Update</a>

 238   * @result <a class="remote" href="#remote-1">Update</a>

 239   * @desc Alter a link of the class "remote" to an Ajax-enhanced link and let it load content from

 240   *       "/path/to/content.html" via XmlHttpRequest into an element with the id "output".

 241   * @example $('a.remote').remote('#output', {hashPrefix: 'chapter'});

 242   * @before <a class="remote" href="/path/to/content.html">Update</a>

 243   * @result <a class="remote" href="#chapter-1">Update</a>

 244   * @desc Alter a link of the class "remote" to an Ajax-enhanced link and let it load content from

 245   *       "/path/to/content.html" via XmlHttpRequest into an element with the id "output".

 246   *

 247   * @param Element elem A DOM element to load content into via XmlHttpRequest.

 248   * @param Object settings An object literal containing key/value pairs to provide optional settings.

 249   * @option String hashPrefix A String that is used for constructing the hash the link's href attribute

 250   *                           gets altered to, such as "#remote-1". Default value: "remote-".

 251   * @param Function callback A single function that will be executed when the request is complete. 

 252   * @type jQuery

 253   *

 254   * @name remote

 255   * @cat Plugins/Remote

 256   * @author Klaus Hartl/klaus.hartl@stilbuero.de

 257   */
 258  $.fn.remote = function(output, settings, callback) {
 259  
 260      callback = callback || function() {};
 261      if (typeof settings == 'function') { // shift arguments
 262          callback = settings;
 263      }
 264      
 265      settings = $.extend({
 266          hashPrefix: 'remote-'
 267      }, settings || {});
 268  
 269      var target = $(output).size() && $(output) || $('<div></div>').appendTo('body');
 270      target.addClass('remote-output');
 271  
 272      return this.each(function(i) {
 273          var href = this.href, hash = '#' + (this.title && this.title.replace(/\s/g, '_') || settings.hashPrefix + (i + 1)),
 274              a = this;
 275          this.href = hash;
 276          $(this).click(function(e) {
 277              // lock target to prevent double loading in Firefox

 278              if (!target['locked']) {
 279                  // add to history only if true click occured, not a triggered click

 280                  if (e.clientX) {
 281                      $.ajaxHistory.update(hash);
 282                  }
 283                  target.load(href, function() {
 284                      target['locked'] = null;
 285                      callback.apply(a);
 286                  });
 287              }
 288          });
 289      });
 290  
 291  };
 292  
 293  /**

 294   * Provides the ability to use the back/forward navigation buttons in a DHTML application.

 295   * A change of the application state is reflected by a change of the URL fragment identifier.

 296   *

 297   * The link's href attribute needs to point to a fragment identifier within the same resource,

 298   * although that fragment id does not need to exist. On click the link changes the URL fragment

 299   * identifier, informs the history manager of the state change and adds an entry to the browser's

 300   * history.

 301   *

 302   * @param Function callback A single function that will be executed as the click handler of the 

 303   *                          matched element. It will be executed on click (adding an entry to 

 304   *                          the history) as well as in case the history manager needs to trigger 

 305   *                          it depending on the value of the URL fragment identifier, e.g. if its 

 306   *                          current value matches the href attribute of the matched element.

 307   *                           

 308   * @type jQuery

 309   *

 310   * @name history

 311   * @cat Plugins/History

 312   * @author Klaus Hartl/klaus.hartl@stilbuero.de

 313   */
 314  $.fn.history = function(callback) {
 315      return this.click(function(e) {        
 316          // add to history only if true click occured,

 317          // not a triggered click...

 318          if (e.clientX) {
 319              // ...and die if already active

 320              if (this.hash == location.hash) {
 321                  return false;
 322              } 
 323                 $.ajaxHistory.update(this.hash);
 324          }
 325          if (typeof callback == 'function') {
 326              callback.call(this);
 327          }
 328      });
 329  };
 330  
 331  })(jQuery);
 332  
 333  /*

 334  var logger;

 335  $(function() {

 336      logger = $('<div style="position: fixed; top: 0; overflow: hidden; border: 1px solid; padding: 3px; width: 120px; height: 150px; background: #fff; color: red;"></div>').appendTo(document.body);

 337  });

 338  function log(m) {    

 339      logger.prepend(m + '<br />');

 340  };

 341  */
 342  


Generated: Thu Mar 24 11:18:33 2011 Cross-referenced by PHPXref 0.7