~ubuntu-branches/ubuntu/saucy/phpmyadmin/saucy-proposed

« back to all changes in this revision

Viewing changes to js/jquery/jquery.ba-hashchange-1.3.js

  • Committer: Package Import Robot
  • Author(s): Thijs Kinkhorst
  • Date: 2013-08-04 13:24:37 UTC
  • mfrom: (1.2.44)
  • Revision ID: package-import@ubuntu.com-20130804132437-jznw8efwy4hr1nms
Tags: 4:4.0.5-1
* New upstream release.
  - Fixes security issue PMASA-2013-10.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
 
1
/*!
2
2
 * jQuery hashchange event - v1.3 - 7/21/2010
3
3
 * http://benalman.com/projects/jquery-hashchange-plugin/
4
4
 * 
6
6
 * Dual licensed under the MIT and GPL licenses.
7
7
 * http://benalman.com/about/license/
8
8
 */
9
 
(function($,e,b){var c="hashchange",h=document,f,g=$.event.special,i=h.documentMode,d="on"+c in e&&(i===b||i>7);function a(j){j=j||location.href;return"#"+j.replace(/^[^#]*#?(.*)$/,"$1")}$.fn[c]=function(j){return j?this.bind(c,j):this.trigger(c)};$.fn[c].delay=50;g[c]=$.extend(g[c],{setup:function(){if(d){return false}$(f.start)},teardown:function(){if(d){return false}$(f.stop)}});f=(function(){var j={},p,m=a(),k=function(q){return q},l=k,o=k;j.start=function(){p||n()};j.stop=function(){p&&clearTimeout(p);p=b};function n(){var r=a(),q=o(m);if(r!==m){l(m=r,q);$(e).trigger(c)}else{if(q!==m){location.href=location.href.replace(/#.*/,"")+q}}p=setTimeout(n,$.fn[c].delay)}$.browser.msie&&!d&&(function(){var q,r;j.start=function(){if(!q){r=$.fn[c].src;r=r&&r+a();q=$('<iframe tabindex="-1" title="empty"/>').hide().one("load",function(){r||l(a());n()}).attr("src",r||"javascript:0").insertAfter("body")[0].contentWindow;h.onpropertychange=function(){try{if(event.propertyName==="title"){q.document.title=h.title}}catch(s){}}}};j.stop=k;o=function(){return a(q.location.href)};l=function(v,s){var u=q.document,t=$.fn[c].domain;if(v!==s){u.title=h.title;u.open();t&&u.write('<script>document.domain="'+t+'"<\/script>');u.close();q.location.hash=v}}})();return j})()})(jQuery,this);
 
 
b'\\ No newline at end of file'
 
9
 
 
10
// Script: jQuery hashchange event
 
11
//
 
12
// *Version: 1.3, Last updated: 7/21/2010*
 
13
// 
 
14
// Project Home - http://benalman.com/projects/jquery-hashchange-plugin/
 
15
// GitHub       - http://github.com/cowboy/jquery-hashchange/
 
16
// Source       - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.js
 
17
// (Minified)   - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.min.js (0.8kb gzipped)
 
18
// 
 
19
// About: License
 
20
// 
 
21
// Copyright (c) 2010 "Cowboy" Ben Alman,
 
22
// Dual licensed under the MIT and GPL licenses.
 
23
// http://benalman.com/about/license/
 
24
// 
 
25
// About: Examples
 
26
// 
 
27
// These working examples, complete with fully commented code, illustrate a few
 
28
// ways in which this plugin can be used.
 
29
// 
 
30
// hashchange event - http://benalman.com/code/projects/jquery-hashchange/examples/hashchange/
 
31
// document.domain - http://benalman.com/code/projects/jquery-hashchange/examples/document_domain/
 
32
// 
 
33
// About: Support and Testing
 
34
// 
 
35
// Information about what version or versions of jQuery this plugin has been
 
36
// tested with, what browsers it has been tested in, and where the unit tests
 
37
// reside (so you can test it yourself).
 
38
// 
 
39
// jQuery Versions - 1.2.6, 1.3.2, 1.4.1, 1.4.2
 
40
// Browsers Tested - Internet Explorer 6-8, Firefox 2-4, Chrome 5-6, Safari 3.2-5,
 
41
//                   Opera 9.6-10.60, iPhone 3.1, Android 1.6-2.2, BlackBerry 4.6-5.
 
42
// Unit Tests      - http://benalman.com/code/projects/jquery-hashchange/unit/
 
43
// 
 
44
// About: Known issues
 
45
// 
 
46
// While this jQuery hashchange event implementation is quite stable and
 
47
// robust, there are a few unfortunate browser bugs surrounding expected
 
48
// hashchange event-based behaviors, independent of any JavaScript
 
49
// window.onhashchange abstraction. See the following examples for more
 
50
// information:
 
51
// 
 
52
// Chrome: Back Button - http://benalman.com/code/projects/jquery-hashchange/examples/bug-chrome-back-button/
 
53
// Firefox: Remote XMLHttpRequest - http://benalman.com/code/projects/jquery-hashchange/examples/bug-firefox-remote-xhr/
 
54
// WebKit: Back Button in an Iframe - http://benalman.com/code/projects/jquery-hashchange/examples/bug-webkit-hash-iframe/
 
55
// Safari: Back Button from a different domain - http://benalman.com/code/projects/jquery-hashchange/examples/bug-safari-back-from-diff-domain/
 
56
// 
 
57
// Also note that should a browser natively support the window.onhashchange 
 
58
// event, but not report that it does, the fallback polling loop will be used.
 
59
// 
 
60
// About: Release History
 
61
// 
 
62
// 1.3   - (7/21/2010) Reorganized IE6/7 Iframe code to make it more
 
63
//         "removable" for mobile-only development. Added IE6/7 document.title
 
64
//         support. Attempted to make Iframe as hidden as possible by using
 
65
//         techniques from http://www.paciellogroup.com/blog/?p=604. Added 
 
66
//         support for the "shortcut" format $(window).hashchange( fn ) and
 
67
//         $(window).hashchange() like jQuery provides for built-in events.
 
68
//         Renamed jQuery.hashchangeDelay to <jQuery.fn.hashchange.delay> and
 
69
//         lowered its default value to 50. Added <jQuery.fn.hashchange.domain>
 
70
//         and <jQuery.fn.hashchange.src> properties plus document-domain.html
 
71
//         file to address access denied issues when setting document.domain in
 
72
//         IE6/7.
 
73
// 1.2   - (2/11/2010) Fixed a bug where coming back to a page using this plugin
 
74
//         from a page on another domain would cause an error in Safari 4. Also,
 
75
//         IE6/7 Iframe is now inserted after the body (this actually works),
 
76
//         which prevents the page from scrolling when the event is first bound.
 
77
//         Event can also now be bound before DOM ready, but it won't be usable
 
78
//         before then in IE6/7.
 
79
// 1.1   - (1/21/2010) Incorporated document.documentMode test to fix IE8 bug
 
80
//         where browser version is incorrectly reported as 8.0, despite
 
81
//         inclusion of the X-UA-Compatible IE=EmulateIE7 meta tag.
 
82
// 1.0   - (1/9/2010) Initial Release. Broke out the jQuery BBQ event.special
 
83
//         window.onhashchange functionality into a separate plugin for users
 
84
//         who want just the basic event & back button support, without all the
 
85
//         extra awesomeness that BBQ provides. This plugin will be included as
 
86
//         part of jQuery BBQ, but also be available separately.
 
87
 
 
88
(function($,window,undefined){
 
89
  '$:nomunge'; // Used by YUI compressor.
 
90
  
 
91
  // Reused string.
 
92
  var str_hashchange = 'hashchange',
 
93
    
 
94
    // Method / object references.
 
95
    doc = document,
 
96
    fake_onhashchange,
 
97
    special = $.event.special,
 
98
    
 
99
    // Does the browser support window.onhashchange? Note that IE8 running in
 
100
    // IE7 compatibility mode reports true for 'onhashchange' in window, even
 
101
    // though the event isn't supported, so also test document.documentMode.
 
102
    doc_mode = doc.documentMode,
 
103
    supports_onhashchange = 'on' + str_hashchange in window && ( doc_mode === undefined || doc_mode > 7 );
 
104
  
 
105
  // Get location.hash (or what you'd expect location.hash to be) sans any
 
106
  // leading #. Thanks for making this necessary, Firefox!
 
107
  function get_fragment( url ) {
 
108
    url = url || location.href;
 
109
    return '#' + url.replace( /^[^#]*#?(.*)$/, '$1' );
 
110
  };
 
111
  
 
112
  // Method: jQuery.fn.hashchange
 
113
  // 
 
114
  // Bind a handler to the window.onhashchange event or trigger all bound
 
115
  // window.onhashchange event handlers. This behavior is consistent with
 
116
  // jQuery's built-in event handlers.
 
117
  // 
 
118
  // Usage:
 
119
  // 
 
120
  // > jQuery(window).hashchange( [ handler ] );
 
121
  // 
 
122
  // Arguments:
 
123
  // 
 
124
  //  handler - (Function) Optional handler to be bound to the hashchange
 
125
  //    event. This is a "shortcut" for the more verbose form:
 
126
  //    jQuery(window).bind( 'hashchange', handler ). If handler is omitted,
 
127
  //    all bound window.onhashchange event handlers will be triggered. This
 
128
  //    is a shortcut for the more verbose
 
129
  //    jQuery(window).trigger( 'hashchange' ). These forms are described in
 
130
  //    the <hashchange event> section.
 
131
  // 
 
132
  // Returns:
 
133
  // 
 
134
  //  (jQuery) The initial jQuery collection of elements.
 
135
  
 
136
  // Allow the "shortcut" format $(elem).hashchange( fn ) for binding and
 
137
  // $(elem).hashchange() for triggering, like jQuery does for built-in events.
 
138
  $.fn[ str_hashchange ] = function( fn ) {
 
139
    return fn ? this.bind( str_hashchange, fn ) : this.trigger( str_hashchange );
 
140
  };
 
141
  
 
142
  // Property: jQuery.fn.hashchange.delay
 
143
  // 
 
144
  // The numeric interval (in milliseconds) at which the <hashchange event>
 
145
  // polling loop executes. Defaults to 50.
 
146
  
 
147
  // Property: jQuery.fn.hashchange.domain
 
148
  // 
 
149
  // If you're setting document.domain in your JavaScript, and you want hash
 
150
  // history to work in IE6/7, not only must this property be set, but you must
 
151
  // also set document.domain BEFORE jQuery is loaded into the page. This
 
152
  // property is only applicable if you are supporting IE6/7 (or IE8 operating
 
153
  // in "IE7 compatibility" mode).
 
154
  // 
 
155
  // In addition, the <jQuery.fn.hashchange.src> property must be set to the
 
156
  // path of the included "document-domain.html" file, which can be renamed or
 
157
  // modified if necessary (note that the document.domain specified must be the
 
158
  // same in both your main JavaScript as well as in this file).
 
159
  // 
 
160
  // Usage:
 
161
  // 
 
162
  // jQuery.fn.hashchange.domain = document.domain;
 
163
  
 
164
  // Property: jQuery.fn.hashchange.src
 
165
  // 
 
166
  // If, for some reason, you need to specify an Iframe src file (for example,
 
167
  // when setting document.domain as in <jQuery.fn.hashchange.domain>), you can
 
168
  // do so using this property. Note that when using this property, history
 
169
  // won't be recorded in IE6/7 until the Iframe src file loads. This property
 
170
  // is only applicable if you are supporting IE6/7 (or IE8 operating in "IE7
 
171
  // compatibility" mode).
 
172
  // 
 
173
  // Usage:
 
174
  // 
 
175
  // jQuery.fn.hashchange.src = 'path/to/file.html';
 
176
  
 
177
  $.fn[ str_hashchange ].delay = 50;
 
178
  /*
 
179
  $.fn[ str_hashchange ].domain = null;
 
180
  $.fn[ str_hashchange ].src = null;
 
181
  */
 
182
  
 
183
  // Event: hashchange event
 
184
  // 
 
185
  // Fired when location.hash changes. In browsers that support it, the native
 
186
  // HTML5 window.onhashchange event is used, otherwise a polling loop is
 
187
  // initialized, running every <jQuery.fn.hashchange.delay> milliseconds to
 
188
  // see if the hash has changed. In IE6/7 (and IE8 operating in "IE7
 
189
  // compatibility" mode), a hidden Iframe is created to allow the back button
 
190
  // and hash-based history to work.
 
191
  // 
 
192
  // Usage as described in <jQuery.fn.hashchange>:
 
193
  // 
 
194
  // > // Bind an event handler.
 
195
  // > jQuery(window).hashchange( function(e) {
 
196
  // >   var hash = location.hash;
 
197
  // >   ...
 
198
  // > });
 
199
  // > 
 
200
  // > // Manually trigger the event handler.
 
201
  // > jQuery(window).hashchange();
 
202
  // 
 
203
  // A more verbose usage that allows for event namespacing:
 
204
  // 
 
205
  // > // Bind an event handler.
 
206
  // > jQuery(window).bind( 'hashchange', function(e) {
 
207
  // >   var hash = location.hash;
 
208
  // >   ...
 
209
  // > });
 
210
  // > 
 
211
  // > // Manually trigger the event handler.
 
212
  // > jQuery(window).trigger( 'hashchange' );
 
213
  // 
 
214
  // Additional Notes:
 
215
  // 
 
216
  // * The polling loop and Iframe are not created until at least one handler
 
217
  //   is actually bound to the 'hashchange' event.
 
218
  // * If you need the bound handler(s) to execute immediately, in cases where
 
219
  //   a location.hash exists on page load, via bookmark or page refresh for
 
220
  //   example, use jQuery(window).hashchange() or the more verbose 
 
221
  //   jQuery(window).trigger( 'hashchange' ).
 
222
  // * The event can be bound before DOM ready, but since it won't be usable
 
223
  //   before then in IE6/7 (due to the necessary Iframe), recommended usage is
 
224
  //   to bind it inside a DOM ready handler.
 
225
  
 
226
  // Override existing $.event.special.hashchange methods (allowing this plugin
 
227
  // to be defined after jQuery BBQ in BBQ's source code).
 
228
  special[ str_hashchange ] = $.extend( special[ str_hashchange ], {
 
229
    
 
230
    // Called only when the first 'hashchange' event is bound to window.
 
231
    setup: function() {
 
232
      // If window.onhashchange is supported natively, there's nothing to do..
 
233
      if ( supports_onhashchange ) { return false; }
 
234
      
 
235
      // Otherwise, we need to create our own. And we don't want to call this
 
236
      // until the user binds to the event, just in case they never do, since it
 
237
      // will create a polling loop and possibly even a hidden Iframe.
 
238
      $( fake_onhashchange.start );
 
239
    },
 
240
    
 
241
    // Called only when the last 'hashchange' event is unbound from window.
 
242
    teardown: function() {
 
243
      // If window.onhashchange is supported natively, there's nothing to do..
 
244
      if ( supports_onhashchange ) { return false; }
 
245
      
 
246
      // Otherwise, we need to stop ours (if possible).
 
247
      $( fake_onhashchange.stop );
 
248
    }
 
249
    
 
250
  });
 
251
  
 
252
  // fake_onhashchange does all the work of triggering the window.onhashchange
 
253
  // event for browsers that don't natively support it, including creating a
 
254
  // polling loop to watch for hash changes and in IE 6/7 creating a hidden
 
255
  // Iframe to enable back and forward.
 
256
  fake_onhashchange = (function(){
 
257
    var self = {},
 
258
      timeout_id,
 
259
      
 
260
      // Remember the initial hash so it doesn't get triggered immediately.
 
261
      last_hash = get_fragment(),
 
262
      
 
263
      fn_retval = function(val){ return val; },
 
264
      history_set = fn_retval,
 
265
      history_get = fn_retval;
 
266
    
 
267
    // Start the polling loop.
 
268
    self.start = function() {
 
269
      timeout_id || poll();
 
270
    };
 
271
    
 
272
    // Stop the polling loop.
 
273
    self.stop = function() {
 
274
      timeout_id && clearTimeout( timeout_id );
 
275
      timeout_id = undefined;
 
276
    };
 
277
    
 
278
    // This polling loop checks every $.fn.hashchange.delay milliseconds to see
 
279
    // if location.hash has changed, and triggers the 'hashchange' event on
 
280
    // window when necessary.
 
281
    function poll() {
 
282
      var hash = get_fragment(),
 
283
        history_hash = history_get( last_hash );
 
284
      
 
285
      if ( hash !== last_hash ) {
 
286
        history_set( last_hash = hash, history_hash );
 
287
        
 
288
        $(window).trigger( str_hashchange );
 
289
        
 
290
      } else if ( history_hash !== last_hash ) {
 
291
        location.href = location.href.replace( /#.*/, '' ) + history_hash;
 
292
      }
 
293
      
 
294
      timeout_id = setTimeout( poll, $.fn[ str_hashchange ].delay );
 
295
    };
 
296
    
 
297
    // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
 
298
    // vvvvvvvvvvvvvvvvvvv REMOVE IF NOT SUPPORTING IE6/7/8 vvvvvvvvvvvvvvvvvvv
 
299
    // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
 
300
    $.browser.msie && !supports_onhashchange && (function(){
 
301
      // Not only do IE6/7 need the "magical" Iframe treatment, but so does IE8
 
302
      // when running in "IE7 compatibility" mode.
 
303
      
 
304
      var iframe,
 
305
        iframe_src;
 
306
      
 
307
      // When the event is bound and polling starts in IE 6/7, create a hidden
 
308
      // Iframe for history handling.
 
309
      self.start = function(){
 
310
        if ( !iframe ) {
 
311
          iframe_src = $.fn[ str_hashchange ].src;
 
312
          iframe_src = iframe_src && iframe_src + get_fragment();
 
313
          
 
314
          // Create hidden Iframe. Attempt to make Iframe as hidden as possible
 
315
          // by using techniques from http://www.paciellogroup.com/blog/?p=604.
 
316
          iframe = $('<iframe tabindex="-1" title="empty"/>').hide()
 
317
            
 
318
            // When Iframe has completely loaded, initialize the history and
 
319
            // start polling.
 
320
            .one( 'load', function(){
 
321
              iframe_src || history_set( get_fragment() );
 
322
              poll();
 
323
            })
 
324
            
 
325
            // Load Iframe src if specified, otherwise nothing.
 
326
            .attr( 'src', iframe_src || 'javascript:0' )
 
327
            
 
328
            // Append Iframe after the end of the body to prevent unnecessary
 
329
            // initial page scrolling (yes, this works).
 
330
            .insertAfter( 'body' )[0].contentWindow;
 
331
          
 
332
          // Whenever `document.title` changes, update the Iframe's title to
 
333
          // prettify the back/next history menu entries. Since IE sometimes
 
334
          // errors with "Unspecified error" the very first time this is set
 
335
          // (yes, very useful) wrap this with a try/catch block.
 
336
          doc.onpropertychange = function(){
 
337
            try {
 
338
              if ( event.propertyName === 'title' ) {
 
339
                iframe.document.title = doc.title;
 
340
              }
 
341
            } catch(e) {}
 
342
          };
 
343
          
 
344
        }
 
345
      };
 
346
      
 
347
      // Override the "stop" method since an IE6/7 Iframe was created. Even
 
348
      // if there are no longer any bound event handlers, the polling loop
 
349
      // is still necessary for back/next to work at all!
 
350
      self.stop = fn_retval;
 
351
      
 
352
      // Get history by looking at the hidden Iframe's location.hash.
 
353
      history_get = function() {
 
354
        return get_fragment( iframe.location.href );
 
355
      };
 
356
      
 
357
      // Set a new history item by opening and then closing the Iframe
 
358
      // document, *then* setting its location.hash. If document.domain has
 
359
      // been set, update that as well.
 
360
      history_set = function( hash, history_hash ) {
 
361
        var iframe_doc = iframe.document,
 
362
          domain = $.fn[ str_hashchange ].domain;
 
363
        
 
364
        if ( hash !== history_hash ) {
 
365
          // Update Iframe with any initial `document.title` that might be set.
 
366
          iframe_doc.title = doc.title;
 
367
          
 
368
          // Opening the Iframe's document after it has been closed is what
 
369
          // actually adds a history entry.
 
370
          iframe_doc.open();
 
371
          
 
372
          // Set document.domain for the Iframe document as well, if necessary.
 
373
          domain && iframe_doc.write( '<script>document.domain="' + domain + '"</script>' );
 
374
          
 
375
          iframe_doc.close();
 
376
          
 
377
          // Update the Iframe's hash, for great justice.
 
378
          iframe.location.hash = hash;
 
379
        }
 
380
      };
 
381
      
 
382
    })();
 
383
    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
384
    // ^^^^^^^^^^^^^^^^^^^ REMOVE IF NOT SUPPORTING IE6/7/8 ^^^^^^^^^^^^^^^^^^^
 
385
    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
386
    
 
387
    return self;
 
388
  })();
 
389
  
 
390
})(jQuery,this);