1/*! (c) Mat Marquis (@wilto). MIT License. http://wil.to/3a */ 2 3(function( $, undefined ) { 4 var inst = 0; 5 6 $.fn.getPercentage = function() { 7 var oPercent = this.attr('style').match(/margin\-left:(.*[0-9])/i) && parseInt(RegExp.$1); 8 9 return oPercent; 10 }; 11 12 $.fn.adjRounding = function(slide) { 13 var $el = $(this), 14 $slides = $el.find( slide ), 15 diff = $el.parent().width() - $($slides[0]).width(); 16 17 if (diff !== 0) { 18 $($slides).css( "position", "relative" ); 19 20 for (var i = 0; i < $slides.length; i++) { 21 $($slides[i]).css( "left", (diff * i) + "px" ); 22 } 23 } 24 25 return this; 26 }; 27 28 $.fn.carousel = function(config) { 29 30 // Prevent re-init: 31 if( this.data( "carousel-initialized" ) ) { return; } 32 33 // Carousel is being initialized: 34 this.data( "carousel-initialized", true ); 35 36 var defaults = { 37 slider : '.slider', 38 slide : '.slide', 39 prevSlide : null, 40 nextSlide : null, 41 slideHed : null, 42 addPagination : false, 43 addNav : ( config != undefined && ( config.prevSlide || config.nextSlide ) ) ? false : true, 44 namespace : 'carousel', 45 speed : 300 46 }, 47 opt = $.extend(defaults, config), 48 $slidewrap = this, 49 dBody = (document.body || document.documentElement), 50 transitionSupport = function() { 51 // Original code from Modernizr : http://www.modernizr.com/ 52 var prop = 'transitionProperty', 53 modElem = document.createElement('tester'), 54 mStyle = modElem.style, 55 prefixes = ' -webkit- -moz- -o- -ms- -khtml- '.split(' '), 56 domPrefixes = 'Webkit Moz O ms Khtml'.split(' '), 57 ucProp = prop.charAt(0).toUpperCase() + prop.substr(1), 58 props = (prop + ' ' + domPrefixes.join(ucProp + ' ') + ucProp).split(' '); 59 60 for ( var i in props ) { 61 if ( mStyle[ props[i] ] !== undefined ) { 62 return true; 63 } 64 } 65 return false; 66 }, 67 carousel = { 68 init : function() { 69 inst++; 70 71 $slidewrap.each(function(carInt) { 72 var $wrap = $(this), 73 $slider = $wrap.find(opt.slider), 74 $slide = $wrap.find(opt.slide), 75 slidenum = $slide.length, 76 transition = "margin-left " + ( opt.speed / 1000 ) + "s ease", 77 tmp = 'carousel-' + inst + '-' + carInt; 78 79 if( $slide.length <= 1 ) { 80 return; /* No sense running all this code if the carousel functionality is unnecessary. */ 81 } 82 83 $wrap 84 .css({ 85 overflow : "hidden", 86 width : "100.2%" 87 }) 88 .attr('role' , 'application'); 89 90 $slider 91 .attr( 'id', ( $slider[0].id || 'carousel-' + inst + '-' + carInt ) ) 92 .css({ 93 "marginLeft" : "0px", 94 "float" : "left", 95 "width" : 100 * slidenum + "%", 96 "-webkit-transition" : transition, 97 "-moz-transition" : transition, 98 "-ms-transition" : transition, 99 "-o-transition" : transition, 100 "transition" : transition 101 }) 102 .bind( 'carouselmove' , carousel.move ) 103 .bind( 'nextprev' , carousel.nextPrev ) 104 .bind( 'navstate' , carousel.navState ); 105 106 $slide 107 .css({ 108 "float": "left", 109 width: (100 / slidenum) + "%" 110 }) 111 .each(function(i) { 112 var $el = $(this); 113 114 $el.attr({ 115 role : "tabpanel document", 116 id : tmp + '-slide' + i 117 });
118 119 if( opt.addPagination ) { 120 $el.attr('aria-labelledby', tmp + '-tab' + i); 121 } 122 }); 123 124 // Build and insert navigation/pagination, if specified in the options: 125 opt.addPagination && carousel.addPagination(); 126 opt.addNav && carousel.addNav(); 127 128 $slider.trigger( "navstate", { current: 0 }); 129 }); 130 }, 131 addNav : function() { 132 $slidewrap.each(function(i) { 133 var $oEl = $(this), 134 $slider = $oEl.find(opt.slider), 135 currentSlider = $slider[0].id, 136 navMarkup = [ 137 '<ul class="slidecontrols" role="navigation">', 138 ' <li role="presentation"><a href="#' + currentSlider + '" class="' + opt.namespace + '-next">Next</a></li>', 139 ' <li role="presentation"><a href="#' + currentSlider + '" class="' + opt.namespace + '-prev">Prev</a></li>', 140 '</ul>' 141 ].join(''), 142 nextprev = { 143 nextSlide : '.' + opt.namespace + '-next', 144 prevSlide : '.' + opt.namespace + '-prev' 145 }; 146 147 opt = $.extend(opt, nextprev); 148 149 $oEl.prepend(navMarkup); 150 }); 151 }, 152 addPagination : function() { 153 $slidewrap.each(function(i) { 154 var $oEl = $(this), 155 $pagination = $('<ol class="' + opt.namespace + '-tabs" role="tablist navigation" />'), 156 $slider = $oEl.find(opt.slider), 157 $slides = $oEl.find(opt.slide) 158 slideNum = $slides.length, 159 associated = 'carousel-' + inst + '-' + i; 160 161 while( slideNum-- ) { 162 var hed = $( $slides[ slideNum ] ).find( opt.slideHed ).text() || 'Page ' + ( slideNum + 1 ), 163 tabMarkup = [ 164 '<li role="presentation">', 165 '<a href="#' + associated + '-slide' + slideNum +'"', 166 ' aria-controls="' + associated + '-slide' + slideNum +'"', 167 ' id="' + associated + '-tab' + slideNum + '" role="tab">' + hed + '</a>', 168 '</li>' 169 ].join(''); 170 171 $pagination.prepend(tabMarkup); 172 }; 173 174 $pagination 175 .appendTo( $oEl ) 176 .find('li').keydown( function(e) { 177 var $el = $(this), 178 $prevTab = $el.prev().find('a'), 179 $nextTab = $el.next().find('a'); 180 181 switch( e.which ) { 182 case 37: 183 case 38: 184 $prevTab.length && $prevTab.trigger('click').focus(); 185 e.preventDefault(); 186 break; 187 case 39: 188 case 40: 189 $nextTab.length && $nextTab.trigger('click').focus(); 190 e.preventDefault(); 191 break; 192 } 193 }) 194 .find('a').click( function(e) { 195 var $el = $(this); 196 197 if( $el.attr('aria-selected') == 'false' ) { 198 var current = $el.parent().index(), 199 move = -( 100 * ( current ) ), 200 $slider = $oEl.find( opt.slider ); 201 202 $slider.trigger( 'carouselmove', { moveTo: move }); 203 } 204 e.preventDefault(); 205 }); 206 }); 207 }, 208 roundDown : function(oVal) { 209 var val = parseInt(oVal, 10); 210 211 return Math.ceil( (val - (val % 100 ) ) / 100) * 100; 212 }, 213 navState : function(e, ui) { 214 var $el = $(this), 215 $slides = $el.find(opt.slide), 216 ind = -(ui.current / 100), 217 $activeSlide = $($slides[ind]); 218 219 $el.attr('aria-activedescendant', $activeSlide[0].id); 220 221 // Update state of active tabpanel: 222 $activeSlide 223 .addClass( opt.namespace + "-active-slide" ) 224 .attr( 'aria-hidden', false ) 225 .siblings() 226 .removeClass( opt.namespace + "-active-slide" ) 227 .attr( 'aria-hidden', true ); 228 229 // Update state of next/prev navigation: 230 if( ( !!opt.prevSlide || !!opt.nextSlide ) ) { 231 var $target = $('[href*="#' + this.id + '"]'); 232 233 $target.removeClass( opt.namespace + '-disabled' ); 234 235 if( ind == 0 ) { 236 $target.filter(opt.prevSlide).addClass( opt.namespace + '-disabled' ); 237 } else if( ind == $slides.length - 1 ) { 238 $target.filter(opt.nextSlide).addClass( opt.namespace + '-disabled' ); 239 } 240 } 241 242 // Update state of pagination tabs: 243 if( !!opt.addPagination ) { 244 var tabId = $activeSlide.attr('aria-labelledby'), 245 $tab = $('#' + tabId ); 246 247 $tab 248 .parent()
249 .addClass(opt.namespace + '-active-tab') 250 .siblings() 251 .removeClass(opt.namespace + '-active-tab') 252 .find('a') 253 .attr({ 254 'aria-selected' : false, 255 'tabindex' : -1 256 }); 257 258 $tab.attr({ 259 'aria-selected' : true, 260 'tabindex' : 0 261 }); 262 } 263 }, 264 move : function(e, ui) { 265 var $el = $(this); 266 267 $el 268 .trigger(opt.namespace + "-beforemove") 269 .trigger("navstate", { current: ui.moveTo }); 270 271 if( transitionSupport() ) { 272 273 $el 274 .adjRounding( opt.slide ) /* Accounts for browser rounding errors. Lookinâ at you, iOS Safari. */ 275 .css('marginLeft', ui.moveTo + "%") 276 .one("transitionend webkitTransitionEnd OTransitionEnd", function() { 277 $(this).trigger( opt.namespace + "-aftermove" ); 278 }); 279 280 } else { 281 $el 282 .adjRounding( opt.slide ) 283 .animate({ marginLeft: ui.moveTo + "%" }, { duration : opt.speed, queue : false }, function() { 284 $(this).trigger( opt.namespace + "-aftermove" ); 285 }); 286 } 287 }, 288 nextPrev : function(e, ui) { 289 var $el = $(this), 290 left = ( $el ) ? $el.getPercentage() : 0, 291 $slide = $el.find(opt.slide), 292 constrain = ui.dir === 'prev' ? left != 0 : -left < ($slide.length - 1) * 100, 293 $target = $( '[href="#' + this.id + '"]'); 294 295 if (!$el.is(":animated") && constrain ) { 296 297 if ( ui.dir === 'prev' ) { 298 left = ( left % 100 != 0 ) ? carousel.roundDown(left) : left + 100; 299 } else { 300 left = ( ( left % 100 ) != 0 ) ? carousel.roundDown(left) - 100 : left - 100; 301 } 302 303 $el.trigger('carouselmove', { moveTo: left }); 304 305 $target 306 .removeClass( opt.namespace + '-disabled') 307 .removeAttr('aria-disabled'); 308 309 switch( left ) { 310 case ( -($slide.length - 1) * 100 ): 311 $target.filter(opt.nextSlide) 312 .addClass( opt.namespace + '-disabled') 313 .attr('aria-disabled', true); 314 break; 315 case 0: 316 $target.filter(opt.prevSlide) 317 .addClass( opt.namespace + '-disabled') 318 .attr('aria-disabled', true); 319 break; 320 } 321 } else { 322 var reset = carousel.roundDown(left); 323 324 $el.trigger('carouselmove', { moveTo: reset }); 325 } 326 327 } 328 }; 329 330 carousel.init(this); 331 332 $(opt.nextSlide + ',' + opt.prevSlide) 333 .bind('click', function(e) { 334 var $el = $(this), 335 link = this.hash, 336 dir = ( $el.is(opt.prevSlide) ) ? 'prev' : 'next', 337 $slider = $(link); 338 339 if ( $el.is('.' + opt.namespace + '-disabled') ) { 340 return false; 341 } 342 343 $slider.trigger('nextprev', { dir: dir }); 344 345 e.preventDefault(); 346 }) 347 .bind('keydown', function(e) { 348 var $el = $(this), 349 link = this.hash; 350 351 switch (e.which) { 352 case 37: 353 case 38: 354 $('#' + link).trigger('nextprev', { dir: 'next' }); 355 e.preventDefault(); 356 break; 357 case 39: 358 case 40: 359 $('#' + link).trigger('nextprev', { dir: 'prev' }); 360 e.preventDefault(); 361 break; 362 } 363 }); 364 365 var setup = { 366 wrap : this, 367 slider : opt.slider 368 }; 369 $slidewrap.bind( "dragSnap", setup, function(e, ui){ 370 var $slider = $(this).find( opt.slider ), 371 dir = ( ui.direction === "left" ) ? 'next' : 'prev'; 372 373 $slider.trigger("nextprev", { dir: dir }); 374 }); 375 376 377 $slidewrap.filter('[data-autorotate]').each(function() { 378 var auto, 379 $el = $(this), 380 speed = $el.attr('data-autorotate'), 381 slidenum = $el.find(opt.slide).length, 382 autoAdvance = function() { 383 var $slider = $el.find(opt.slider), 384 active = -( $(opt.slider).getPercentage() / 100 ) + 1; 385 386 switch( active ) { 387 case slidenum: 388 clearInterval(auto); 389 390 auto = setInterval(function() { 391 autoAdvance(); 392 $slider.trigger("nextprev", { dir: 'prev' }); 393 }, speed); 394 395 break; 396 case 1: 397 clearInterval(auto); 398 399 auto = setInterval(function() { 400 autoAdvance(); 401 $slider.trigger("nextprev", { dir: 'next' }); 402 }, speed); 403 404 break; 405 } 406 }; 407 408 auto = setInterval(autoAdvance, speed); 409 410 $el 411 .attr('aria-live', 'polite') 412 .bind('mouseenter click touchstart', function() { 413 clearInterval(auto); 414 }); 415 }); 416 417 return this; 418 }; 419})(jQuery); 420 421 422$.event.special.dragSnap = { 423 setup: function(setup) { 424 425 var $el = $(this), 426 transitionSwap = function($el, tog) { 427 var speed = .3, 428 transition = ( tog ) ? "margin-left " + speed + "s ease" : 'none'; 429 430 $el.css({ 431 "-webkit-transition" : transition, 432 "-moz-transition" : transition, 433 "-ms-transition" : transition, 434 "-o-transition" : transition, 435 "transition" : transition 436 }); 437 },
438 roundDown = function(left) { 439 var left = parseInt(left, 10); 440 441 return Math.ceil( (left - (left % 100 ) ) / 100) * 100; 442 }, 443 snapBack = function(e, ui) { 444 var $el = ui.target, 445 currentPos = ( $el.attr('style') != undefined ) ? $el.getPercentage() : 0, 446 left = (ui.left === false) ? roundDown(currentPos) - 100 : roundDown(currentPos), 447 dStyle = document.body.style, 448 transitionSupport = function() { 449 // Original code from Modernizr : http://www.modernizr.com/ 450 var prop = 'transitionProperty', 451 modElem = document.createElement('tester'), 452 mStyle = modElem.style, 453 prefixes = ' -webkit- -moz- -o- -ms- -khtml- '.split(' '), 454 domPrefixes = 'Webkit Moz O ms Khtml'.split(' '), 455 ucProp = prop.charAt(0).toUpperCase() + prop.substr(1), 456 props = (prop + ' ' + domPrefixes.join(ucProp + ' ') + ucProp).split(' '); 457 458 for ( var i in props ) { 459 if ( mStyle[ props[i] ] !== undefined ) { 460 return true; 461 } 462 } 463 return false; 464 }; 465 466 transitionSwap($el, true); 467 468 if( transitionSupport() ) { 469 $el.css('marginLeft', left + "%"); 470 } else { 471 $el.animate({ marginLeft: left + "%" }, opt.speed); 472 } 473 }; 474 475 $el 476 .bind("snapback", snapBack) 477 .bind("touchstart", function(e) { 478 var data = e.originalEvent.touches ? e.originalEvent.touches[0] : e, 479 start = { 480 time: (new Date).getTime(), 481 coords: [ data.pageX, data.pageY ], 482 origin: $(e.target).closest( setup.wrap ) 483 }, 484 stop, 485 $tEl = $(e.target).closest( setup.slider ), 486 currentPos = ( $tEl.attr('style') != undefined ) ? $tEl.getPercentage() : 0; 487 488 transitionSwap($tEl, false); 489 490 function moveHandler(e) { 491 var data = e.originalEvent.touches ? e.originalEvent.touches[0] : e; 492 stop = { 493 time: (new Date).getTime(), 494 coords: [ data.pageX, data.pageY ] 495 }; 496 497 if(!start || Math.abs(start.coords[0] - stop.coords[0]) < Math.abs(start.coords[1] - stop.coords[1]) ) { 498 return; 499 } 500 501 $tEl.css({"margin-left": currentPos + ( ( (stop.coords[0] - start.coords[0]) / start.origin.width() ) * 100 ) + '%' }); 502 503 // prevent scrolling 504 if (Math.abs(start.coords[0] - stop.coords[0]) > 10) { 505 e.preventDefault(); 506 } 507 508 }; 509 510 $el 511 .bind("gesturestart", function(e) { 512 $el 513 .unbind("touchmove", moveHandler) 514 .unbind("touchend", moveHandler); 515 }) 516 .bind("touchmove", moveHandler) 517 .one("touchend", function(e) { 518 519 $el.unbind("touchmove", moveHandler); 520 521 transitionSwap($tEl, true); 522 523 if (start && stop ) { 524 525 if (Math.abs(start.coords[0] - stop.coords[0]) > 10 526 && Math.abs(start.coords[0] - stop.coords[0]) > Math.abs(start.coords[1] - stop.coords[1])) { 527 e.preventDefault(); 528 } else { 529 $el.trigger('snapback', { target: $tEl, left: true }); 530 return; 531 } 532 533 if (Math.abs(start.coords[0] - stop.coords[0]) > 1 && Math.abs(start.coords[1] - stop.coords[1]) < 75) { 534 var left = start.coords[0] > stop.coords[0]; 535 536 if( -( stop.coords[0] - start.coords[0]) > ( start.origin.width() / 4 ) || ( stop.coords[0] - start.coords[0]) > ( start.origin.width() / 4 ) ) { 537 538 start.origin.trigger("dragSnap", {direction: left ? "left" : "right"}); 539 540 } else { 541 $el.trigger('snapback', { target: $tEl, left: left }); 542 } 543 544 } 545 } 546 start = stop = undefined; 547 }); 548 }); 549 } 550};
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.