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