1/*! 2 * jQuery doTimeout: Like setTimeout, but better! - v1.0 - 3/3/2010 3 * http://benalman.com/projects/jquery-dotimeout-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 10// Script: jQuery doTimeout: Like setTimeout, but better! 11// 12// *Version: 1.0, Last updated: 3/3/2010* 13// 14// Project Home - http://benalman.com/projects/jquery-dotimeout-plugin/ 15// GitHub - http://github.com/cowboy/jquery-dotimeout/ 16// Source - http://github.com/cowboy/jquery-dotimeout/raw/master/jquery.ba-dotimeout.js 17// (Minified) - http://github.com/cowboy/jquery-dotimeout/raw/master/jquery.ba-dotimeout.min.js (1.0kb) 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// Debouncing - http://benalman.com/code/projects/jquery-dotimeout/examples/debouncing/ 31// Delays, Polling - http://benalman.com/code/projects/jquery-dotimeout/examples/delay-poll/ 32// Hover Intent - http://benalman.com/code/projects/jquery-dotimeout/examples/hoverintent/ 33// 34// About: Support and Testing 35// 36// Information about what version or versions of jQuery this plugin has been 37// tested with, what browsers it has been tested in, and where the unit tests 38// reside (so you can test it yourself). 39// 40// jQuery Versions - 1.3.2, 1.4.2 41// Browsers Tested - Internet Explorer 6-8, Firefox 2-3.6, Safari 3-4, Chrome 4-5, Opera 9.6-10.1. 42// Unit Tests - http://benalman.com/code/projects/jquery-dotimeout/unit/ 43// 44// About: Release History 45// 46// 1.0 - (3/3/2010) Callback can now be a string, in which case it will call 47// the appropriate $.method or $.fn.method, depending on where .doTimeout 48// was called. Callback must now return `true` (not just a truthy value) 49// to poll. 50// 0.4 - (7/15/2009) Made the "id" argument optional, some other minor tweaks 51// 0.3 - (6/25/2009) Initial release 52 53(function($){ 54 '$:nomunge'; // Used by YUI compressor. 55 56 var cache = {}, 57 58 // Reused internal string. 59 doTimeout = 'doTimeout', 60 61 // A convenient shortcut. 62 aps = Array.prototype.slice; 63 64 // Method: jQuery.doTimeout 65 // 66 // Initialize, cancel, or force execution of a callback after a delay. 67 // 68 // If delay and callback are specified, a doTimeout is initialized. The 69 // callback will execute, asynchronously, after the delay. If an id is 70 // specified, this doTimeout will override and cancel any existing doTimeout 71 // with the same id. Any additional arguments will be passed into callback 72 // when it is executed. 73 // 74 // If the callback returns true, the doTimeout loop will execute again, after 75 // the delay, creating a polling loop until the callback returns a non-true 76 // value. 77 // 78 // Note that if an id is not passed as the first argument, this doTimeout will 79 // NOT be able to be manually canceled or forced. (for debouncing, be sure to 80 // specify an id). 81 // 82 // If id is specified, but delay and callback are not, the doTimeout will be 83 // canceled without executing the callback. If force_mode is specified, the 84 // callback will be executed, synchronously, but will only be allowed to 85 // continue a polling loop if force_mode is true (provided the callback 86 // returns true, of course). If force_mode is false, no polling loop will 87 // continue, even if the callback returns true. 88 // 89 // Usage: 90 // 91 // > jQuery.doTimeout( [ id, ] delay, callback [, arg ... ] ); 92 // > jQuery.doTimeout( id [, force_mode ] ); 93 // 94 // Arguments: 95 // 96 // id - (String) An optional unique identifier for this doTimeout. If id is 97 // not specified, the doTimeout will NOT be able to be manually canceled or 98 // forced. 99 // delay - (Number) A zero-or-greater delay in milliseconds after which 100 // callback will be executed. 101 // callback - (Function) A function to be executed after delay milliseconds. 102 // callback - (String) A jQuery method to be executed after delay 103 // milliseconds. This method will only poll if it explicitly returns 104 // true. 105 // force_mode - (Boolean) If true, execute that id's doTimeout callback 106 // immediately and synchronously, continuing any callback return-true 107 // polling loop. If false, execute the callback immediately and 108 // synchronously but do NOT continue a callback return-true polling loop. 109 // If omitted, cancel that id's doTimeout. 110 // 111 // Returns: 112 // 113 // If force_mode is true, false or undefined and there is a 114 // yet-to-be-executed callback to cancel, true is returned, but if no 115 // callback remains to be executed, undefined is returned. 116 117 $[doTimeout] = function() { 118 return p_doTimeout.apply( window, [ 0 ].concat( aps.call( arguments ) ) ); 119 }; 120 121 // Method: jQuery.fn.doTimeout 122 // 123 // Initialize, cancel, or force execution of a callback after a delay. 124 // Operates like <jQuery.doTimeout>, but the passed callback executes in the 125 // context of the jQuery collection of elements, and the id is stored as data 126 // on the first element in that collection. 127 // 128 // If delay and callback are specified, a doTimeout is initialized. The 129 // callback will execute, asynchronously, after the delay. If an id is 130 // specified, this doTimeout will override and cancel any existing doTimeout 131 // with the same id. Any additional arguments will be passed into callback 132 // when it is executed. 133 // 134 // If the callback returns true, the doTimeout loop will execute again, after 135 // the delay, creating a polling loop until the callback returns a non-true 136 // value. 137 // 138 // Note that if an id is not passed as the first argument, this doTimeout will 139 // NOT be able to be manually canceled or forced (for debouncing, be sure to 140 // specify an id). 141 // 142 // If id is specified, but delay and callback are not, the doTimeout will be 143 // canceled without executing the callback. If force_mode is specified, the 144 // callback will be executed, synchronously, but will only be allowed to 145 // continue a polling loop if force_mode is true (provided the callback 146 // returns true, of course). If force_mode is false, no polling loop will 147 // continue, even if the callback returns true. 148 // 149 // Usage: 150 // 151 // > jQuery('selector').doTimeout( [ id, ] delay, callback [, arg ... ] ); 152 // > jQuery('selector').doTimeout( id [, force_mode ] ); 153 // 154 // Arguments: 155 // 156 // id - (String) An optional unique identifier for this doTimeout, stored as 157 // jQuery data on the element. If id is not specified, the doTimeout will 158 // NOT be able to be manually canceled or forced. 159 // delay - (Number) A zero-or-greater delay in milliseconds after which 160 // callback will be executed. 161 // callback - (Function) A function to be executed after delay milliseconds. 162 // callback - (String) A jQuery.fn method to be executed after delay 163 // milliseconds. This method will only poll if it explicitly returns 164 // true (most jQuery.fn methods return a jQuery object, and not `true`, 165 // which allows them to be chained and prevents polling). 166 // force_mode - (Boolean) If true, execute that id's doTimeout callback 167 // immediately and synchronously, continuing any callback return-true 168 // polling loop. If false, execute the callback immediately and 169 // synchronously but do NOT continue a callback return-true polling loop. 170 // If omitted, cancel that id's doTimeout. 171 // 172 // Returns: 173 // 174 // When creating a <jQuery.fn.doTimeout>, the initial jQuery collection of 175 // elements is returned. Otherwise, if force_mode is true, false or undefined 176 // and there is a yet-to-be-executed callback to cancel, true is returned, 177 // but if no callback remains to be executed, undefined is returned. 178 179 $.fn[doTimeout] = function() { 180 var args = aps.call( arguments ), 181 result = p_doTimeout.apply( this, [ doTimeout + args[0] ].concat( args ) ); 182 183 return typeof args[0] === 'number' || typeof args[1] === 'number' 184 ? this 185 : result; 186 }; 187 188 function p_doTimeout( jquery_data_key ) { 189 var that = this, 190 elem, 191 data = {}, 192 193 // Allows the plugin to call a string callback method. 194 method_base = jquery_data_key ? $.fn : $, 195 196 // Any additional arguments will be passed to the callback. 197 args = arguments, 198 slice_args = 4, 199 200 id = args[1], 201 delay = args[2], 202 callback = args[3]; 203 204 if ( typeof id !== 'string' ) { 205 slice_args--; 206 207 id = jquery_data_key = 0; 208 delay = args[1]; 209 callback = args[2]; 210 } 211 212 // If id is passed, store a data reference either as .data on the first
213 // element in a jQuery collection, or in the internal cache. 214 if ( jquery_data_key ) { // Note: key is 'doTimeout' + id 215 216 // Get id-object from the first element's data, otherwise initialize it to {}. 217 elem = that.eq(0); 218 elem.data( jquery_data_key, data = elem.data( jquery_data_key ) || {} ); 219 220 } else if ( id ) { 221 // Get id-object from the cache, otherwise initialize it to {}. 222 data = cache[ id ] || ( cache[ id ] = {} ); 223 } 224 225 // Clear any existing timeout for this id. 226 data.id && clearTimeout( data.id ); 227 delete data.id; 228 229 // Clean up when necessary. 230 function cleanup() { 231 if ( jquery_data_key ) { 232 elem.removeData( jquery_data_key ); 233 } else if ( id ) { 234 delete cache[ id ]; 235 } 236 }; 237 238 // Yes, there actually is a setTimeout call in here! 239 function actually_setTimeout() { 240 data.id = setTimeout( function(){ data.fn(); }, delay ); 241 }; 242 243 if ( callback ) { 244 // A callback (and delay) were specified. Store the callback reference for 245 // possible later use, and then setTimeout. 246 data.fn = function( no_polling_loop ) { 247 248 // If the callback value is a string, it is assumed to be the name of a 249 // method on $ or $.fn depending on where doTimeout was executed. 250 if ( typeof callback === 'string' ) { 251 callback = method_base[ callback ]; 252 } 253 254 callback.apply( that, aps.call( args, slice_args ) ) === true && !no_polling_loop 255 256 // Since the callback returned true, and we're not specifically 257 // canceling a polling loop, do it again! 258 ? actually_setTimeout() 259 260 // Otherwise, clean up and quit. 261 : cleanup(); 262 }; 263 264 // Set that timeout! 265 actually_setTimeout(); 266 267 } else if ( data.fn ) { 268 // No callback passed. If force_mode (delay) is true, execute the data.fn 269 // callback immediately, continuing any callback return-true polling loop. 270 // If force_mode is false, execute the data.fn callback immediately but do 271 // NOT continue a callback return-true polling loop. If force_mode is 272 // undefined, simply clean up. Since data.fn was still defined, whatever 273 // was supposed to happen hadn't yet, so return true. 274 delay === undefined ? cleanup() : data.fn( delay === false ); 275 return true; 276 277 } else { 278 // Since no callback was passed, and data.fn isn't defined, it looks like 279 // whatever was supposed to happen already did. Clean up and quit! 280 cleanup(); 281 } 282 283 }; 284 285})(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.