vendor: 23,523 bytes, lines 1-488
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, value) { 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 } 148 149 // wrap both inner elements into one div 150 $this.wrapInner('<div style="width:100000px" class="js-marquee-wrapper"></div>'); 151 152 // Save the reference of the wrapper 153 $marqueeWrapper = $this.find('.js-marquee-wrapper'); 154 155 // If direction is up or down, get the height of main element 156 if (verticalDir) { 157 var containerHeight = $this.height(); 158 $marqueeWrapper.removeAttr('style'); 159 $this.height(containerHeight); 160 161 // Change the CSS for js-marquee element 162 $this.find('.js-marquee').css({ 163 'float': 'none', 164 'margin-bottom': o.gap, 165 'margin-left': 0 166 }); 167 168 // Remove bottom margin from 2nd element if duplicated 169 if (o.duplicated) $this.find('.js-marquee:last').css({ 170 'margin-bottom': 0 171 }); 172 173 var elHeight = $this.find('.js-marquee:first').height() + o.gap; 174 175 // adjust the animation duration according to the text length 176 if (o.startVisible && !o.duplicated) { 177 // Compute the complete animation duration and save it for later reference 178 // formula is to: (Height of the text node + height of the main container / Height of the main container) * duration; 179 o._completeDuration = ((parseInt(elHeight, 10) + parseInt(containerHeight, 10)) / parseInt(containerHeight, 10)) * o.duration; 180 181 // formula is to: (Height of the text node / height of the main container) * duration 182 o.duration = (parseInt(elHeight, 10) / parseInt(containerHeight, 10)) * o.duration; 183 } else { 184 // formula is to: (Height of the text node + height of the main container / Height of the main container) * duration; 185 o.duration = ((parseInt(elHeight, 10) + parseInt(containerHeight, 10)) / parseInt(containerHeight, 10)) * o.duration; 186 } 187 188 } else { 189 // Save the width of the each element so we can use it in animation 190 elWidth = $this.find('.js-marquee:first').width() + o.gap; 191 192 // container width 193 containerWidth = $this.width(); 194 195 // adjust the animation duration according to the text length 196 if (o.startVisible && !o.duplicated) { 197 // Compute the complete animation duration and save it for later reference 198 // formula is to: (Width of the text node + width of the main container / Width of the main container) * duration; 199 o._completeDuration = ((parseInt(elWidth, 10) + parseInt(containerWidth, 10)) / parseInt(containerWidth, 10)) * o.duration; 200 201 // (Width of the text node / width of the main container) * duration 202 o.duration = (parseInt(elWidth, 10) / parseInt(containerWidth, 10)) * o.duration; 203 } else { 204 // formula is to: (Width of the text node + width of the main container / Width of the main container) * duration; 205 o.duration = ((parseInt(elWidth, 10) + parseInt(containerWidth, 10)) / parseInt(containerWidth, 10)) * o.duration; 206 } 207 } 208 209 // if duplicated then reduce the duration 210 if (o.duplicated) { 211 o.duration = o.duration / 2; 212 } 213 214 if (o.allowCss3Support) { 215 var 216 elm = document.body || document.createElement('div'), 217 animationName = 'marqueeAnimation-' + Math.floor(Math.random() * 10000000), 218 domPrefixes = 'Webkit Moz O ms Khtml'.split(' '), 219 animationString = 'animation', 220 animationCss3Str = '', 221 keyframeString = ''; 222 223 // Check css3 support 224 if (elm.style.animation !== undefined) { 225 keyframeString = '@keyframes ' + animationName + ' '; 226 css3AnimationIsSupported = true; 227 } 228 229 if (css3AnimationIsSupported === false) { 230 for (var i = 0; i < domPrefixes.length; i++) { 231 if (elm.style[domPrefixes[i] + 'AnimationName'] !== undefined) { 232 var prefix = '-' + domPrefixes[i].toLowerCase() + '-'; 233 animationString = prefix + animationString; 234 playState = prefix + playState; 235 keyframeString = '@' + prefix + 'keyframes ' + animationName + ' '; 236 css3AnimationIsSupported = true; 237 break; 238 } 239 } 240 } 241 242 if (css3AnimationIsSupported) { 243 animationCss3Str = animationName + ' ' + o.duration / 1000 + 's ' + o.delayBeforeStart / 1000 + 's infinite ' + o.css3easing; 244 $this.data('css3AnimationIsSupported', true); 245 } 246 } 247 248 var _rePositionVertically = function() { 249 $marqueeWrapper.css('transform', 'translateY(' + (o.direction == 'up' ? containerHeight + 'px' : '-' + elHeight + 'px') + ')'); 250 }, 251 _rePositionHorizontally = function() { 252 $marqueeWrapper.css('transform', 'translateX(' + (o.direction == 'right' ? containerWidth + 'px' : '-' + elWidth + 'px') + ')'); 253 }; 254 255 // if duplicated option is set to true than position the wrapper 256 if (o.duplicated) { 257 if (verticalDir) { 258 if (o.startVisible) { 259 $marqueeWrapper.css('transform', 'translateY(0)'); 260 } else { 261 $marqueeWrapper.css('transform', 'translateY(' + (o.direction == 'up' ? containerHeight + 'px' : '-' + ((elHeight * 2) - o.gap) + 'px') + ')'); 262 } 263 } else { 264 if (o.startVisible) { 265 $marqueeWrapper.css('transform', 'translateX(0)'); 266 } else { 267 $marqueeWrapper.css('transform', 'translateX(' + (o.direction == 'right' ? containerWidth + 'px' : '-' + ((elWidth * 2) - o.gap) + 'px') + ')'); 268 } 269 } 270 271 // If the text starts out visible we can skip the two initial loops 272 if (!o.startVisible) { 273 loopCount = 1; 274 } 275 } else if (o.startVisible) { 276 // We only have two different loops if marquee is duplicated and starts visible 277 loopCount = 2; 278 } else { 279 if (verticalDir) { 280 _rePositionVertically(); 281 } else { 282 _rePositionHorizontally(); 283 } 284 } 285 286 // Animate recursive method 287 var animate = function() { 288 if (o.duplicated) { 289 // When duplicated, the first loop will be scroll longer so double the duration 290 if (loopCount === 1) { 291 o._originalDuration = o.duration; 292 if (verticalDir) { 293 o.duration = o.direction == 'up' ? o.duration + (containerHeight / ((elHeight) / o.duration)) : o.duration * 2; 294 } else { 295 o.duration = o.direction == 'right' ? o.duration + (containerWidth / ((elWidth) / o.duration)) : o.duration * 2; 296 } 297 // Adjust the css3 animation as well 298 if (animationCss3Str) { 299 animationCss3Str = animationName + ' ' + o.duration / 1000 + 's ' + o.delayBeforeStart / 1000 + 's ' + o.css3easing; 300 } 301 loopCount++; 302 } 303 // On 2nd loop things back to normal, normal duration for the rest of animations 304 else if (loopCount === 2) { 305 o.duration = o._originalDuration; 306 // Adjust the css3 animation as well 307 if (animationCss3Str) { 308 animationName = animationName + '0'; 309 keyframeString = $.trim(keyframeString) + '0 '; 310 animationCss3Str = animationName + ' ' + o.duration / 1000 + 's 0s infinite ' + o.css3easing; 311 } 312 loopCount++; 313 } 314 } 315 316 if (verticalDir) { 317 if (o.duplicated) { 318 319 // Adjust the starting point of animation only when first loops finishes 320 if (loopCount > 2) { 321 $marqueeWrapper.css('transform', 'translateY(' + (o.direction == 'up' ? 0 : '-' + elHeight + 'px') + ')'); 322 } 323 324 animationCss = { 325 'transform': 'translateY(' + (o.direction == 'up' ? '-' + elHeight + 'px' : 0) + ')' 326 }; 327 } else if (o.startVisible) { 328 // This loop moves the marquee out of the container 329 if (loopCount === 2) { 330 // Adjust the css3 animation as well 331 if (animationCss3Str) { 332 animationCss3Str = animationName + ' ' + o.duration / 1000 + 's ' + o.delayBeforeStart / 1000 + 's ' + o.css3easing; 333 } 334 animationCss = { 335 'transform': 'translateY(' + (o.direction == 'up' ? '-' + elHeight + 'px' : containerHeight + 'px') + ')' 336 }; 337 loopCount++; 338 } else if (loopCount === 3) { 339 // Set the duration for the animation that will run forever 340 o.duration = o._completeDuration; 341 // Adjust the css3 animation as well 342 if (animationCss3Str) { 343 animationName = animationName + '0'; 344 keyframeString = $.trim(keyframeString) + '0 '; 345 animationCss3Str = animationName + ' ' + o.duration / 1000 + 's 0s infinite ' + o.css3easing; 346 } 347 _rePositionVertically(); 348 } 349 } else { 350 _rePositionVertically(); 351 animationCss = { 352 'transform': 'translateY(' + (o.direction == 'up' ? '-' + ($marqueeWrapper.height()) + 'px' : containerHeight + 'px') + ')' 353 }; 354 } 355 } else { 356 if (o.duplicated) { 357 358 // Adjust the starting point of animation only when first loops finishes 359 if (loopCount > 2) { 360 $marqueeWrapper.css('transform', 'translateX(' + (o.direction == 'right' ? 0 : '-' + elWidth + 'px') + ')'); 361 } 362 363 animationCss = { 364 'transform': 'translateX(' + (o.direction == 'right' ? '-' + elWidth + 'px' : 0) + ')' 365 }; 366 367 } else if (o.startVisible) { 368 // This loop moves the marquee out of the container 369 if (loopCount === 2) { 370 // Adjust the css3 animation as well 371 if (animationCss3Str) { 372 animationCss3Str = animationName + ' ' + o.duration / 1000 + 's ' + o.delayBeforeStart / 1000 + 's ' + o.css3easing; 373 } 374 animationCss = { 375 'transform': 'translateX(' + (o.direction == 'right' ? '-' + elWidth + 'px' : containerWidth + 'px') + ')' 376 }; 377 loopCount++; 378 } else if (loopCount === 3) { 379 // Set the duration for the animation that will run forever 380 o.duration = o._completeDuration; 381 // Adjust the css3 animation as well 382 if (animationCss3Str) { 383 animationName = animationName + '0'; 384 keyframeString = $.trim(keyframeString) + '0 '; 385 animationCss3Str = animationName + ' ' + o.duration / 1000 + 's 0s infinite ' + o.css3easing; 386 } 387 _rePositionHorizontally(); 388 } 389 } else { 390 _rePositionHorizontally(); 391 animationCss = { 392 'transform': 'translateX(' + (o.direction == 'right' ? '-' + elWidth + 'px' : containerWidth + 'px') + ')' 393 }; 394 } 395 } 396 397 // fire event 398 $this.trigger('beforeStarting'); 399 400 // If css3 support is available than do it with css3, otherwise use jQuery as fallback 401 if (css3AnimationIsSupported) { 402 // Add css3 animation to the element 403 $marqueeWrapper.css(animationString, animationCss3Str); 404 var keyframeCss = keyframeString + ' { 100% ' + _objToString(animationCss) + '}', 405 $styles = $marqueeWrapper.find('style'); 406 407 // Now add the keyframe animation to the marquee element 408 if ($styles.length !== 0) { 409 // Bug fixed for jQuery 1.3.x - Instead of using .last(), use following 410 $styles.filter(":last").html(keyframeCss); 411 } else { 412 $('head').append('<style>' + keyframeCss + '</style>'); 413 } 414 415 // Animation iteration event 416 _prefixedEvent($marqueeWrapper[0], "AnimationIteration", function() { 417 $this.trigger('finished'); 418 }); 419 // Animation stopped 420 _prefixedEvent($marqueeWrapper[0], "AnimationEnd", function() { 421 animate(); 422 $this.trigger('finished'); 423 }); 424 425 } else { 426 // Start animating 427 $marqueeWrapper.animate(animationCss, o.duration, o.easing, function() { 428 // fire event 429 $this.trigger('finished'); 430 // animate again 431 if (o.pauseOnCycle) { 432 _startAnimationWithDelay(); 433 } else { 434 animate(); 435 } 436 }); 437 } 438 // save the status 439 $this.data('runningStatus', 'resumed'); 440 }; 441 442 // bind pause and resume events 443 $this.on('pause', methods.pause); 444 $this.on('resume', methods.resume); 445 446 if (o.pauseOnHover) { 447 $this.on('mouseenter', methods.pause); 448 $this.on('mouseleave', methods.resume); 449 } 450 451 // If css3 animation is supported than call animate method at once 452 if (css3AnimationIsSupported && o.allowCss3Support) { 453 animate(); 454 } else { 455 // Starts the recursive method 456 _startAnimationWithDelay(); 457 } 458 459 }); 460 }; // End of Plugin 461 // Public: plugin defaults options 462 $.fn.marquee.defaults = { 463 // If you wish to always animate using jQuery 464 allowCss3Support: true, 465 // works when allowCss3Support is set to true - for full list see http://www.w3.org/TR/2013/WD-css3-transitions-20131119/#transition-timing-function 466 css3easing: 'linear', 467 // requires jQuery easing plugin. Default is 'linear' 468 easing: 'linear', 469 // pause time before the next animation turn in milliseconds 470 delayBeforeStart: 1000, 471 // 'left', 'right', 'up' or 'down' 472 direction: 'left', 473 // true or false - should the marquee be duplicated to show an effect of continues flow 474 duplicated: false, 475 // duration in milliseconds of the marquee in milliseconds 476 duration: 5000, 477 // 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. 478 speed: 0, 479 // gap in pixels between the tickers 480 gap: 20, 481 // on cycle pause the marquee 482 pauseOnCycle: false, 483 // on hover pause the marquee - using jQuery plugin https://github.com/tobia/Pause 484 pauseOnHover: false, 485 // the marquee is visible initially positioned next to the border towards it will be moving 486 startVisible: false 487 }; 488})(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.