vendor: 23,578 bytes, lines 1-491
1/** 2 * jQuery.marquee - scrolling text like old marquee element 3 * @author Aamir Afridi - aamirafridi(at)gmail(dot)com / http://aamirafridi.com/jquery/jquery-marquee-plugin 4 */; 5(function($) { 6 $.fn.marquee = function(options) { 7 return this.each(function() { 8 // Extend the options if any provided 9 var o = $.extend({}, $.fn.marquee.defaults, options), 10 $this = $(this), 11 $marqueeWrapper, containerWidth, animationCss, verticalDir, elWidth, 12 loopCount = 3, 13 playState = 'animation-play-state', 14 css3AnimationIsSupported = false, 15 16 // Private methods 17 _prefixedEvent = function(element, type, callback) { 18 var pfx = ["webkit", "moz", "MS", "o", ""]; 19 for (var p = 0; p < pfx.length; p++) { 20 if (!pfx[p]) type = type.toLowerCase(); 21 element.addEventListener(pfx[p] + type, callback, false); 22 } 23 }, 24 25 _objToString = function(obj) { 26 var tabjson = []; 27 for (var p in obj) { 28 if (obj.hasOwnProperty(p)) { 29 tabjson.push(p + ':' + obj[p]); 30 } 31 } 32 tabjson.push(); 33 return '{' + tabjson.join(',') + '}'; 34 }, 35 36 _startAnimationWithDelay = function() { 37 $this.timer = setTimeout(animate, o.delayBeforeStart); 38 }, 39 40 // Public methods 41 methods = { 42 pause: function() { 43 if (css3AnimationIsSupported && o.allowCss3Support) { 44 $marqueeWrapper.css(playState, 'paused'); 45 } else { 46 // pause using pause plugin 47 if ($.fn.pause) { 48 $marqueeWrapper.pause(); 49 } 50 } 51 // save the status 52 $this.data('runningStatus', 'paused'); 53 // fire event 54 $this.trigger('paused'); 55 }, 56 57 resume: function() { 58 // resume using css3 59 if (css3AnimationIsSupported && o.allowCss3Support) { 60 $marqueeWrapper.css(playState, 'running'); 61 } else { 62 // resume using pause plugin 63 if ($.fn.resume) { 64 $marqueeWrapper.resume(); 65 } 66 } 67 // save the status 68 $this.data('runningStatus', 'resumed'); 69 // fire event 70 $this.trigger('resumed'); 71 }, 72 73 toggle: function() { 74 methods[$this.data('runningStatus') === 'resumed' ? 'pause' : 'resume'](); 75 }, 76 77 destroy: function() { 78 // Clear timer 79 clearTimeout($this.timer); 80 // Unbind all events 81 $this.find("*").addBack().off(); 82 // Just unwrap the elements that has been added using this plugin 83 $this.html($this.find('.js-marquee:first').html()); 84 } 85 }; 86 87 // Check for methods 88 if (typeof options === 'string') { 89 if ($.isFunction(methods[options])) { 90 // Following two IF statements to support public methods 91 if (!$marqueeWrapper) { 92 $marqueeWrapper = $this.find('.js-marquee-wrapper'); 93 } 94 if ($this.data('css3AnimationIsSupported') === true) { 95 css3AnimationIsSupported = true; 96 } 97 methods[options](); 98 } 99 return; 100 } 101 102 /* Check if element has data attributes. They have top priority 103 For details https://twitter.com/aamirafridi/status/403848044069679104 - Can't find a better solution :/ 104 jQuery 1.3.2 doesn't support $.data().KEY hence writting the following */ 105 var dataAttributes = {}, 106 attr; 107 $.each(o, function(key) { 108 // Check if element has this data attribute 109 attr = $this.attr('data-' + key); 110 if (typeof attr !== 'undefined') { 111 // Now check if value is boolean or not 112 switch (attr) { 113 case 'true': 114 attr = true; 115 break; 116 case 'false': 117 attr = false; 118 break; 119 } 120 o[key] = attr; 121 } 122 }); 123 124 // Reintroduce speed as an option. It calculates duration as a factor of the container width 125 // measured in pixels per second. 126 if (o.speed) { 127 o.duration = parseInt($this.width(), 10) / o.speed * 1000; 128 } 129 130 // Shortcut to see if direction is upward or downward 131 verticalDir = o.direction === 'up' || o.direction === 'down'; 132 133 // no gap if not duplicated 134 o.gap = o.duplicated ? parseInt(o.gap) : 0; 135 136 // wrap inner content into a div 137 $this.wrapInner('<div class="js-marquee"></div>'); 138 139 // Make copy of the element 140 var $el = $this.find('.js-marquee').css({ 141 'margin-right': o.gap, 142 'float': 'left' 143 }); 144 145 if (o.duplicated) { 146 $el.clone(true).appendTo($this); 147 // one more time 148 $el.clone(true).appendTo($this); 149 } 150 151 // wrap both inner elements into one div 152 $this.wrapInner('<div style="width:100000px" class="js-marquee-wrapper"></div>'); 153 154 // Save the reference of the wrapper 155 $marqueeWrapper = $this.find('.js-marquee-wrapper'); 156 157 // If direction is up or down, get the height of main element 158 if (verticalDir) { 159 var containerHeight = $this.height(); 160 $marqueeWrapper.removeAttr('style'); 161 $this.height(containerHeight); 162 163 // Change the CSS for js-marquee element 164 $this.find('.js-marquee').css({ 165 'float': 'none', 166 'margin-bottom': o.gap, 167 'margin-right': 0 168 }); 169 170 // Remove bottom margin from 2nd element if duplicated 171 if (o.duplicated) { 172 $this.find('.js-marquee:last').css({ 173 'margin-bottom': 0 174 }); 175 } 176 177 var elHeight = $this.find('.js-marquee:first').height() + o.gap; 178 179 // adjust the animation duration according to the text length 180 if (o.startVisible && !o.duplicated) { 181 // Compute the complete animation duration and save it for later reference 182 // formula is to: (Height of the text node + height of the main container / Height of the main container) * duration; 183 o._completeDuration = ((parseInt(elHeight, 10) + parseInt(containerHeight, 10)) / parseInt(containerHeight, 10)) * o.duration; 184 185 // formula is to: (Height of the text node / height of the main container) * duration 186 o.duration = (parseInt(elHeight, 10) / parseInt(containerHeight, 10)) * o.duration; 187 } else { 188 // formula is to: (Height of the text node + height of the main container / Height of the main container) * duration; 189 o.duration = ((parseInt(elHeight, 10) + parseInt(containerHeight, 10)) / parseInt(containerHeight, 10)) * o.duration; 190 } 191 192 } else { 193 // Save the width of the each element so we can use it in animation 194 elWidth = $this.find('.js-marquee:first').width() + o.gap; 195 196 // container width 197 containerWidth = $this.width(); 198 199 // adjust the animation duration according to the text length 200 if (o.startVisible && !o.duplicated) { 201 // Compute the complete animation duration and save it for later reference 202 // formula is to: (Width of the text node + width of the main container / Width of the main container) * duration; 203 o._completeDuration = ((parseInt(elWidth, 10) + parseInt(containerWidth, 10)) / parseInt(containerWidth, 10)) * o.duration; 204 205 // (Width of the text node / width of the main container) * duration 206 o.duration = (parseInt(elWidth, 10) / parseInt(containerWidth, 10)) * o.duration; 207 } else { 208 // formula is to: (Width of the text node + width of the main container / Width of the main container) * duration; 209 o.duration = ((parseInt(elWidth, 10) + parseInt(containerWidth, 10)) / parseInt(containerWidth, 10)) * o.duration; 210 } 211 } 212 213 // if duplicated then reduce the duration 214 if (o.duplicated) { 215 o.duration = o.duration / 2; 216 } 217 218 if (o.allowCss3Support) { 219 var elm = document.body || document.createElement('div'), 220 animationName = 'marqueeAnimation-' + Math.floor(Math.random() * 10000000), 221 domPrefixes = 'Webkit Moz O ms Khtml'.split(' '), 222 animationString = 'animation', 223 animationCss3Str = '', 224 keyframeString = ''; 225 226 // Check css3 support 227 if (elm.style.animation !== undefined) { 228 keyframeString = '@keyframes ' + animationName + ' '; 229 css3AnimationIsSupported = true; 230 } 231 232 if (css3AnimationIsSupported === false) { 233 for (var i = 0; i < domPrefixes.length; i++) { 234 if (elm.style[domPrefixes[i] + 'AnimationName'] !== undefined) { 235 var prefix = '-' + domPrefixes[i].toLowerCase() + '-'; 236 animationString = prefix + animationString; 237 playState = prefix + playState; 238 keyframeString = '@' + prefix + 'keyframes ' + animationName + ' '; 239 css3AnimationIsSupported = true; 240 break; 241 } 242 } 243 } 244 245 if (css3AnimationIsSupported) { 246 animationCss3Str = animationName + ' ' + o.duration / 1000 + 's ' + o.delayBeforeStart / 1000 + 's infinite ' + o.css3easing; 247 $this.data('css3AnimationIsSupported', true); 248 } 249 } 250 251 var _rePositionVertically = function() { 252 $marqueeWrapper.css('transform', 'translateY(' + (o.direction === 'up' ? containerHeight + 'px' : '-' + elHeight + 'px') + ')'); 253 }, 254 _rePositionHorizontally = function() { 255 $marqueeWrapper.css('transform', 'translateX(' + (o.direction === 'left' ? containerWidth + 'px' : '-' + elWidth + 'px') + ')'); 256 }; 257 258 // if duplicated option is set to true than position the wrapper 259 if (o.duplicated) { 260 if (verticalDir) { 261 if (o.startVisible) { 262 $marqueeWrapper.css('transform', 'translateY(0)'); 263 } else { 264 $marqueeWrapper.css('transform', 'translateY(' + (o.direction === 'up' ? containerHeight + 'px' : '-' + ((elHeight * 2) - o.gap) + 'px') + ')'); 265 } 266 } else { 267 if (o.startVisible) { 268 $marqueeWrapper.css('transform', 'translateX(0)'); 269 } else { 270 $marqueeWrapper.css('transform', 'translateX(' + (o.direction === 'left' ? containerWidth + 'px' : '-' + ((elWidth * 2) - o.gap) + 'px') + ')'); 271 } 272 } 273 274 // If the text starts out visible we can skip the two initial loops 275 if (!o.startVisible) { 276 loopCount = 1; 277 } 278 } else if (o.startVisible) { 279 // We only have two different loops if marquee is duplicated and starts visible 280 loopCount = 2; 281 } else { 282 if (verticalDir) { 283 _rePositionVertically(); 284 } else { 285 _rePositionHorizontally(); 286 } 287 } 288 289 // Animate recursive method 290 var animate = function() { 291 if (o.duplicated) { 292 // When duplicated, the first loop will be scroll longer so double the duration 293 if (loopCount === 1) { 294 o._originalDuration = o.duration; 295 if (verticalDir) { 296 o.duration = o.direction === 'up' ? o.duration + (containerHeight / ((elHeight) / o.duration)) : o.duration * 2; 297 } else { 298 o.duration = o.direction === 'left' ? o.duration + (containerWidth / ((elWidth) / o.duration)) : o.duration * 2; 299 } 300 // Adjust the css3 animation as well 301 if (animationCss3Str) { 302 animationCss3Str = animationName + ' ' + o.duration / 1000 + 's ' + o.delayBeforeStart / 1000 + 's ' + o.css3easing; 303 } 304 loopCount++; 305 } 306 // On 2nd loop things back to normal, normal duration for the rest of animations 307 else if (loopCount === 2) { 308 o.duration = o._originalDuration; 309 // Adjust the css3 animation as well 310 if (animationCss3Str) { 311 animationName = animationName + '0'; 312 keyframeString = $.trim(keyframeString) + '0 '; 313 animationCss3Str = animationName + ' ' + o.duration / 1000 + 's 0s infinite ' + o.css3easing; 314 } 315 loopCount++; 316 } 317 } 318 319 if (verticalDir) { 320 if (o.duplicated) { 321 322 // Adjust the starting point of animation only when first loops finishes 323 if (loopCount > 2) { 324 $marqueeWrapper.css('transform', 'translateY(' + (o.direction === 'up' ? 0 : '-' + elHeight + 'px') + ')'); 325 } 326 327 animationCss = { 328 'transform': 'translateY(' + (o.direction === 'up' ? '-' + elHeight + 'px' : 0) + ')' 329 }; 330 } else if (o.startVisible) { 331 // This loop moves the marquee out of the container 332 if (loopCount === 2) { 333 // Adjust the css3 animation as well 334 if (animationCss3Str) { 335 animationCss3Str = animationName + ' ' + o.duration / 1000 + 's ' + o.delayBeforeStart / 1000 + 's ' + o.css3easing; 336 } 337 animationCss = { 338 'transform': 'translateY(' + (o.direction === 'up' ? '-' + elHeight + 'px' : containerHeight + 'px') + ')' 339 }; 340 loopCount++; 341 } else if (loopCount === 3) { 342 // Set the duration for the animation that will run forever 343 o.duration = o._completeDuration; 344 // Adjust the css3 animation as well 345 if (animationCss3Str) { 346 animationName = animationName + '0'; 347 keyframeString = $.trim(keyframeString) + '0 '; 348 animationCss3Str = animationName + ' ' + o.duration / 1000 + 's 0s infinite ' + o.css3easing; 349 } 350 _rePositionVertically(); 351 } 352 } else { 353 _rePositionVertically(); 354 animationCss = { 355 'transform': 'translateY(' + (o.direction === 'up' ? '-' + ($marqueeWrapper.height()) + 'px' : containerHeight + 'px') + ')' 356 }; 357 } 358 } else { 359 if (o.duplicated) { 360 361 // Adjust the starting point of animation only when first loops finishes 362 if (loopCount > 2) { 363 $marqueeWrapper.css('transform', 'translateX(' + (o.direction === 'left' ? 0 : '-' + elWidth + 'px') + ')'); 364 } 365 366 animationCss = { 367 'transform': 'translateX(' + (o.direction === 'left' ? '-' + elWidth + 'px' : 0) + ')' 368 }; 369 370 } else if (o.startVisible) { 371 // This loop moves the marquee out of the container 372 if (loopCount === 2) { 373 // Adjust the css3 animation as well 374 if (animationCss3Str) { 375 animationCss3Str = animationName + ' ' + o.duration / 1000 + 's ' + o.delayBeforeStart / 1000 + 's ' + o.css3easing; 376 } 377 animationCss = { 378 'transform': 'translateX(' + (o.direction === 'left' ? '-' + elWidth + 'px' : containerWidth + 'px') + ')' 379 }; 380 loopCount++; 381 } else if (loopCount === 3) { 382 // Set the duration for the animation that will run forever 383 o.duration = o._completeDuration; 384 // Adjust the css3 animation as well 385 if (animationCss3Str) { 386 animationName = animationName + '0'; 387 keyframeString = $.trim(keyframeString) + '0 '; 388 animationCss3Str = animationName + ' ' + o.duration / 1000 + 's 0s infinite ' + o.css3easing; 389 } 390 _rePositionHorizontally(); 391 } 392 } else { 393 _rePositionHorizontally(); 394 animationCss = { 395 'transform': 'translateX(' + (o.direction === 'left' ? '-' + elWidth + 'px' : containerWidth + 'px') + ')' 396 }; 397 } 398 } 399 400 // fire event 401 $this.trigger('beforeStarting'); 402 403 // If css3 support is available than do it with css3, otherwise use jQuery as fallback 404 if (css3AnimationIsSupported) { 405 // Add css3 animation to the element 406 $marqueeWrapper.css(animationString, animationCss3Str); 407 var keyframeCss = keyframeString + ' { 100% ' + _objToString(animationCss) + '}', 408 $styles = $marqueeWrapper.find('style'); 409 410 // Now add the keyframe animation to the marquee element 411 if ($styles.length !== 0) { 412 // Bug fixed for jQuery 1.3.x - Instead of using .last(), use following 413 $styles.filter(":last").html(keyframeCss); 414 } else { 415 $('head').append('<style>' + keyframeCss + '</style>'); 416 } 417 418 // Animation iteration event 419 _prefixedEvent($marqueeWrapper[0], "AnimationIteration", function() { 420 $this.trigger('finished'); 421 }); 422 // Animation stopped 423 _prefixedEvent($marqueeWrapper[0], "AnimationEnd", function() { 424 animate(); 425 $this.trigger('finished'); 426 }); 427 428 } else { 429 // Start animating 430 $marqueeWrapper.animate(animationCss, o.duration, o.easing, function() { 431 // fire event 432 $this.trigger('finished'); 433 // animate again 434 if (o.pauseOnCycle) { 435 _startAnimationWithDelay(); 436 } else { 437 animate(); 438 } 439 }); 440 } 441 // save the status 442 $this.data('runningStatus', 'resumed'); 443 }; 444 445 // bind pause and resume events 446 $this.on('pause', methods.pause); 447 $this.on('resume', methods.resume); 448 449 if (o.pauseOnHover) { 450 $this.on('mouseenter', methods.pause); 451 $this.on('mouseleave', methods.resume); 452 } 453 454 // If css3 animation is supported than call animate method at once 455 if (css3AnimationIsSupported && o.allowCss3Support) { 456 animate(); 457 } else { 458 // Starts the recursive method 459 _startAnimationWithDelay(); 460 } 461 462 }); 463 }; // End of Plugin 464 // Public: plugin defaults options 465 $.fn.marquee.defaults = { 466 // If you wish to always animate using jQuery 467 allowCss3Support: true, 468 // works when allowCss3Support is set to true - for full list see http://www.w3.org/TR/2013/WD-css3-transitions-20131119/#transition-timing-function 469 css3easing: 'linear', 470 // requires jQuery easing plugin. Default is 'linear' 471 easing: 'linear', 472 // pause time before the next animation turn in milliseconds 473 delayBeforeStart: 1000, 474 // 'left', 'right', 'up' or 'down' 475 direction: 'left', 476 // true or false - should the marquee be duplicated to show an effect of continues flow 477 duplicated: false, 478 // duration in milliseconds of the marquee in milliseconds 479 duration: 5000, 480 // Speed allows you to set a relatively constant marquee speed regardless of the width of the containing element. Speed is measured in pixels per second. 481 speed: 0, 482 // gap in pixels between the tickers 483 gap: 20, 484 // on cycle pause the marquee 485 pauseOnCycle: false, 486 // on hover pause the marquee - using jQuery plugin https://github.com/tobia/Pause 487 pauseOnHover: false, 488 // the marquee is visible initially positioned next to the border towards it will be moving 489 startVisible: false 490 }; 491})(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.