1/* 2 * jQuery FlexSlider v2.1 3 * http://www.woothemes.com/flexslider/ 4 * 5 * Copyright 2012 WooThemes 6 * Free to use under the GPLv2 license. 7 * http://www.gnu.org/licenses/gpl-2.0.html 8 * 9 * Contributing author: Tyler Smith (@mbmufffin) 10 */ 11 12;(function ($) { 13 14 //FlexSlider: Object Instance 15 $.flexslider = function(el, options) { 16 var slider = $(el), 17 vars = $.extend({}, $.flexslider.defaults, options), 18 namespace = vars.namespace, 19 touch = ("ontouchstart" in window) || window.DocumentTouch && document instanceof DocumentTouch, 20 eventType = (touch) ? "touchend" : "click", 21 vertical = vars.direction === "vertical", 22 reverse = vars.reverse, 23 carousel = (vars.itemWidth > 0), 24 fade = vars.animation === "fade", 25 asNav = vars.asNavFor !== "", 26 methods = {}; 27 28 // Store a reference to the slider object 29 $.data(el, "flexslider", slider); 30 31 // Privat slider methods 32 methods = { 33 init: function() { 34 slider.animating = false; 35 slider.currentSlide = vars.startAt; 36 slider.animatingTo = slider.currentSlide; 37 slider.atEnd = (slider.currentSlide === 0 || slider.currentSlide === slider.last); 38 slider.containerSelector = vars.selector.substr(0,vars.selector.search(' ')); 39 slider.slides = $(vars.selector, slider); 40 slider.container = $(slider.containerSelector, slider); 41 slider.count = slider.slides.length; 42 // SYNC: 43 slider.syncExists = $(vars.sync).length > 0; 44 // SLIDE: 45 if (vars.animation === "slide") vars.animation = "swing"; 46 slider.prop = (vertical) ? "top" : "marginLeft"; 47 slider.args = {}; 48 // SLIDESHOW: 49 slider.manualPause = false; 50 // TOUCH/USECSS: 51 slider.transitions = !vars.video && !fade && vars.useCSS && (function() { 52 var obj = document.createElement('div'), 53 props = ['perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective']; 54 for (var i in props) { 55 if ( obj.style[ props[i] ] !== undefined ) { 56 slider.pfx = props[i].replace('Perspective','').toLowerCase(); 57 slider.prop = "-" + slider.pfx + "-transform"; 58 return true; 59 } 60 } 61 return false; 62 }()); 63 // CONTROLSCONTAINER: 64 if (vars.controlsContainer !== "") slider.controlsContainer = $(vars.controlsContainer).length > 0 && $(vars.controlsContainer); 65 // MANUAL: 66 if (vars.manualControls !== "") slider.manualControls = $(vars.manualControls).length > 0 && $(vars.manualControls); 67 68 // RANDOMIZE: 69 if (vars.randomize) { 70 slider.slides.sort(function() { return (Math.round(Math.random())-0.5); }); 71 slider.container.empty().append(slider.slides); 72 } 73 74 slider.doMath(); 75 76 // ASNAV: 77 if (asNav) methods.asNav.setup(); 78 79 // INIT 80 slider.setup("init"); 81 82 // CONTROLNAV: 83 if (vars.controlNav) methods.controlNav.setup(); 84 85 // DIRECTIONNAV: 86 if (vars.directionNav) methods.directionNav.setup(); 87 88 // KEYBOARD: 89 if (vars.keyboard && ($(slider.containerSelector).length === 1 || vars.multipleKeyboard)) { 90 $(document).bind('keyup', function(event) { 91 var keycode = event.keyCode; 92 if (!slider.animating && (keycode === 39 || keycode === 37)) { 93 var target = (keycode === 39) ? slider.getTarget('next') : 94 (keycode === 37) ? slider.getTarget('prev') : false; 95 slider.flexAnimate(target, vars.pauseOnAction); 96 } 97 }); 98 } 99 // MOUSEWHEEL: 100 if (vars.mousewheel) { 101 slider.bind('mousewheel', function(event, delta, deltaX, deltaY) { 102 event.preventDefault(); 103 var target = (delta < 0) ? slider.getTarget('next') : slider.getTarget('prev'); 104 slider.flexAnimate(target, vars.pauseOnAction); 105 }); 106 } 107 108 // PAUSEPLAY 109 if (vars.pausePlay) methods.pausePlay.setup(); 110 111 // SLIDSESHOW 112 if (vars.slideshow) { 113 if (vars.pauseOnHover) { 114 slider.hover(function() { 115 if (!slider.manualPlay && !slider.manualPause) slider.pause(); 116 }, function() { 117 if (!slider.manualPause && !slider.manualPlay) slider.play(); 118 }); 119 } 120 // initialize animation 121 (vars.initDelay > 0) ? setTimeout(slider.play, vars.initDelay) : slider.play(); 122 } 123 124 // TOUCH 125 if (touch && vars.touch) methods.touch(); 126 127 // FADE&&SMOOTHHEIGHT || SLIDE: 128 if (!fade || (fade && vars.smoothHeight)) $(window).bind("resize focus", methods.resize); 129 130 131 // API: start() Callback 132 setTimeout(function(){ 133 vars.start(slider); 134 }, 200); 135 }, 136 asNav: { 137 setup: function() { 138 slider.asNav = true; 139 slider.animatingTo = Math.floor(slider.currentSlide/slider.move); 140 slider.currentItem = slider.currentSlide; 141 slider.slides.removeClass(namespace + "active-slide").eq(slider.currentItem).addClass(namespace + "active-slide"); 142 slider.slides.click(function(e){ 143 e.preventDefault(); 144 var $slide = $(this), 145 target = $slide.index(); 146 if (!$(vars.asNavFor).data('flexslider').animating && !$slide.hasClass('active')) { 147 slider.direction = (slider.currentItem < target) ? "next" : "prev"; 148 slider.flexAnimate(target, vars.pauseOnAction, false, true, true); 149 } 150 }); 151 } 152 }, 153 controlNav: { 154 setup: function() { 155 if (!slider.manualControls) {
156 methods.controlNav.setupPaging(); 157 } else { // MANUALCONTROLS: 158 methods.controlNav.setupManual(); 159 } 160 }, 161 setupPaging: function() { 162 var type = (vars.controlNav === "thumbnails") ? 'control-thumbs' : 'control-paging', 163 j = 1, 164 item; 165 166 slider.controlNavScaffold = $('<ol class="'+ namespace + 'control-nav ' + namespace + type + '"></ol>'); 167 168 if (slider.pagingCount > 1) { 169 for (var i = 0; i < slider.pagingCount; i++) { 170 item = (vars.controlNav === "thumbnails") ? '<img src="' + slider.slides.eq(i).attr("data-thumb") + '"/>' : '<a>' + j + '</a>'; 171 slider.controlNavScaffold.append('<li>' + item + '</li>'); 172 j++; 173 } 174 } 175 176 // CONTROLSCONTAINER: 177 (slider.controlsContainer) ? $(slider.controlsContainer).append(slider.controlNavScaffold) : slider.append(slider.controlNavScaffold); 178 methods.controlNav.set(); 179 180 methods.controlNav.active(); 181 182 slider.controlNavScaffold.delegate('a, img', eventType, function(event) { 183 event.preventDefault(); 184 var $this = $(this), 185 target = slider.controlNav.index($this); 186 187 if (!$this.hasClass(namespace + 'active')) { 188 slider.direction = (target > slider.currentSlide) ? "next" : "prev"; 189 slider.flexAnimate(target, vars.pauseOnAction); 190 } 191 }); 192 // Prevent iOS click event bug 193 if (touch) { 194 slider.controlNavScaffold.delegate('a', "click touchstart", function(event) { 195 event.preventDefault(); 196 }); 197 } 198 }, 199 setupManual: function() { 200 slider.controlNav = slider.manualControls; 201 methods.controlNav.active(); 202 203 slider.controlNav.live(eventType, function(event) { 204 event.preventDefault(); 205 var $this = $(this), 206 target = slider.controlNav.index($this); 207 208 if (!$this.hasClass(namespace + 'active')) { 209 (target > slider.currentSlide) ? slider.direction = "next" : slider.direction = "prev"; 210 slider.flexAnimate(target, vars.pauseOnAction); 211 } 212 }); 213 // Prevent iOS click event bug 214 if (touch) { 215 slider.controlNav.live("click touchstart", function(event) { 216 event.preventDefault(); 217 }); 218 } 219 }, 220 set: function() { 221 var selector = (vars.controlNav === "thumbnails") ? 'img' : 'a'; 222 slider.controlNav = $('.' + namespace + 'control-nav li ' + selector, (slider.controlsContainer) ? slider.controlsContainer : slider); 223 }, 224 active: function() { 225 slider.controlNav.removeClass(namespace + "active").eq(slider.animatingTo).addClass(namespace + "active"); 226 }, 227 update: function(action, pos) { 228 if (slider.pagingCount > 1 && action === "add") { 229 slider.controlNavScaffold.append($('<li><a>' + slider.count + '</a></li>')); 230 } else if (slider.pagingCount === 1) { 231 slider.controlNavScaffold.find('li').remove(); 232 } else { 233 slider.controlNav.eq(pos).closest('li').remove(); 234 } 235 methods.controlNav.set(); 236 (slider.pagingCount > 1 && slider.pagingCount !== slider.controlNav.length) ? slider.update(pos, action) : methods.controlNav.active(); 237 } 238 }, 239 directionNav: { 240 setup: function() { 241 var directionNavScaffold = $('<ul class="' + namespace + 'direction-nav"><li><a class="' + namespace + 'prev" href="#">' + vars.prevText + '</a></li><li><a class="' + namespace + 'next" href="#">' + vars.nextText + '</a></li></ul>'); 242 243 // CONTROLSCONTAINER: 244 if (slider.controlsContainer) { 245 $(slider.controlsContainer).append(directionNavScaffold); 246 slider.directionNav = $('.' + namespace + 'direction-nav li a', slider.controlsContainer); 247 } else { 248 slider.append(directionNavScaffold); 249 slider.directionNav = $('.' + namespace + 'direction-nav li a', slider); 250 } 251
252 methods.directionNav.update(); 253 254 slider.directionNav.bind(eventType, function(event) { 255 event.preventDefault(); 256 var target = ($(this).hasClass(namespace + 'next')) ? slider.getTarget('next') : slider.getTarget('prev'); 257 slider.flexAnimate(target, vars.pauseOnAction); 258 }); 259 // Prevent iOS click event bug 260 if (touch) { 261 slider.directionNav.bind("click touchstart", function(event) { 262 event.preventDefault(); 263 }); 264 } 265 }, 266 update: function() { 267 var disabledClass = namespace + 'disabled'; 268 if (slider.pagingCount === 1) { 269 slider.directionNav.addClass(disabledClass); 270 } else if (!vars.animationLoop) { 271 if (slider.animatingTo === 0) { 272 slider.directionNav.removeClass(disabledClass).filter('.' + namespace + "prev").addClass(disabledClass); 273 } else if (slider.animatingTo === slider.last) { 274 slider.directionNav.removeClass(disabledClass).filter('.' + namespace + "next").addClass(disabledClass); 275 } else { 276 slider.directionNav.removeClass(disabledClass); 277 } 278 } else { 279 slider.directionNav.removeClass(disabledClass); 280 } 281 } 282 }, 283 pausePlay: { 284 setup: function() { 285 var pausePlayScaffold = $('<div class="' + namespace + 'pauseplay"><a></a></div>'); 286 287 // CONTROLSCONTAINER: 288 if (slider.controlsContainer) { 289 slider.controlsContainer.append(pausePlayScaffold); 290 slider.pausePlay = $('.' + namespace + 'pauseplay a', slider.controlsContainer); 291 } else { 292 slider.append(pausePlayScaffold); 293 slider.pausePlay = $('.' + namespace + 'pauseplay a', slider); 294 } 295 296 methods.pausePlay.update((vars.slideshow) ? namespace + 'pause' : namespace + 'play'); 297 298 slider.pausePlay.bind(eventType, function(event) { 299 event.preventDefault(); 300 if ($(this).hasClass(namespace + 'pause')) { 301 slider.manualPause = true; 302 slider.manualPlay = false; 303 slider.pause(); 304 } else { 305 slider.manualPause = false; 306 slider.manualPlay = true; 307 slider.play(); 308 } 309 }); 310 // Prevent iOS click event bug 311 if (touch) { 312 slider.pausePlay.bind("click touchstart", function(event) { 313 event.preventDefault(); 314 }); 315 } 316 }, 317 update: function(state) { 318 (state === "play") ? slider.pausePlay.removeClass(namespace + 'pause').addClass(namespace + 'play').text(vars.playText) : slider.pausePlay.removeClass(namespace + 'play').addClass(namespace + 'pause').text(vars.pauseText); 319 } 320 }, 321 touch: function() { 322 var startX, 323 startY, 324 offset, 325 cwidth, 326 dx, 327 startT, 328 scrolling = false; 329 330 el.addEventListener('touchstart', onTouchStart, false); 331 function onTouchStart(e) { 332 if (slider.animating) { 333 e.preventDefault(); 334 } else if (e.touches.length === 1) { 335 slider.pause(); 336 // CAROUSEL: 337 cwidth = (vertical) ? slider.h : slider. w; 338 startT = Number(new Date()); 339 // CAROUSEL: 340 offset = (carousel && reverse && slider.animatingTo === slider.last) ? 0 : 341 (carousel && reverse) ? slider.limit - (((slider.itemW + vars.itemMargin) * slider.move) * slider.animatingTo) : 342 (carousel && slider.currentSlide === slider.last) ? slider.limit : 343 (carousel) ? ((slider.itemW + vars.itemMargin) * slider.move) * slider.currentSlide : 344 (reverse) ? (slider.last - slider.currentSlide + slider.cloneOffset) * cwidth : (slider.currentSlide + slider.cloneOffset) * cwidth; 345 startX = (vertical) ? e.touches[0].pageY : e.touches[0].pageX; 346 startY = (vertical) ? e.touches[0].pageX : e.touches[0].pageY; 347 348 el.addEventListener('touchmove', onTouchMove, false); 349 el.addEventListener('touchend', onTouchEnd, false); 350 } 351 } 352 353 function onTouchMove(e) { 354 dx = (vertical) ? startX - e.touches[0].pageY : startX - e.touches[0].pageX; 355 scrolling = (vertical) ? (Math.abs(dx) < Math.abs(e.touches[0].pageX - startY)) : (Math.abs(dx) < Math.abs(e.touches[0].pageY - startY)); 356 357 if (!scrolling || Number(new Date()) - startT > 500) { 358 e.preventDefault(); 359 if (!fade && slider.transitions) { 360 if (!vars.animationLoop) { 361 dx = dx/((slider.currentSlide === 0 && dx < 0 || slider.currentSlide === slider.last && dx > 0) ? (Math.abs(dx)/cwidth+2) : 1); 362 } 363 slider.setProps(offset + dx, "setTouch"); 364 } 365 } 366 } 367 368 function onTouchEnd(e) { 369 if (slider.animatingTo === slider.currentSlide && !scrolling && !(dx === null)) { 370 var updateDx = (reverse) ? -dx : dx, 371 target = (updateDx > 0) ? slider.getTarget('next') : slider.getTarget('prev'); 372 373 if (slider.canAdvance(target) && (Number(new Date()) - startT < 550 && Math.abs(updateDx) > 50 || Math.abs(updateDx) > cwidth/2)) { 374 slider.flexAnimate(target, vars.pauseOnAction); 375 } else { 376 slider.flexAnimate(slider.currentSlide, vars.pauseOnAction, true); 377 } 378 } 379 // finish the touch by undoing the touch session 380 el.removeEventListener('touchmove', onTouchMove, false); 381 el.removeEventListener('touchend', onTouchEnd, false); 382 startX = null; 383 startY = null; 384 dx = null; 385 offset = null; 386 } 387 }, 388 resize: function() { 389 if (!slider.animating && slider.is(':visible')) { 390 if (!carousel) slider.doMath(); 391 392 if (fade) { 393 // SMOOTH HEIGHT: 394 methods.smoothHeight(); 395 } else if (carousel) { //CAROUSEL: 396 slider.slides.width(slider.computedW); 397 slider.update(slider.pagingCount); 398 slider.setProps(); 399 } 400 else if (vertical) { //VERTICAL: 401 slider.viewport.height(slider.h); 402 slider.setProps(slider.h, "setTotal"); 403 } else { 404 // SMOOTH HEIGHT: 405 if (vars.smoothHeight) methods.smoothHeight(); 406 slider.newSlides.width(slider.computedW); 407 slider.setProps(slider.computedW, "setTotal"); 408 } 409 } 410 }, 411 smoothHeight: function(dur) { 412 if (!vertical || fade) { 413 var $obj = (fade) ? slider : slider.viewport; 414 (dur) ? $obj.animate({"height": slider.slides.eq(slider.animatingTo).height()}, dur) : $obj.height(slider.slides.eq(slider.animatingTo).height()); 415 } 416 }, 417 sync: function(action) { 418 var $obj = $(vars.sync).data("flexslider"), 419 target = slider.animatingTo; 420 421 switch (action) { 422 case "animate": $obj.flexAnimate(target, vars.pauseOnAction, false, true); break; 423 case "play": if (!$obj.playing && !$obj.asNav) { $obj.play(); } break; 424 case "pause": $obj.pause(); break; 425 } 426 } 427 } 428 429 // public methods 430 slider.flexAnimate = function(target, pause, override, withSync, fromNav) { 431 if (asNav && slider.pagingCount === 1) slider.direction = (slider.currentItem < target) ? "next" : "prev"; 432
433 if (!slider.animating && (slider.canAdvance(target, fromNav) || override) && slider.is(":visible")) { 434 if (asNav && withSync) { 435 var master = $(vars.asNavFor).data('flexslider'); 436 slider.atEnd = target === 0 || target === slider.count - 1; 437 master.flexAnimate(target, true, false, true, fromNav); 438 slider.direction = (slider.currentItem < target) ? "next" : "prev"; 439 master.direction = slider.direction; 440 441 if (Math.ceil((target + 1)/slider.visible) - 1 !== slider.currentSlide && target !== 0) { 442 slider.currentItem = target; 443 slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide"); 444 target = Math.floor(target/slider.visible); 445 } else { 446 slider.currentItem = target; 447 slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide"); 448 return false; 449 } 450 } 451 452 slider.animating = true; 453 slider.animatingTo = target; 454 // API: before() animation Callback 455 vars.before(slider); 456 457 // SLIDESHOW: 458 if (pause) slider.pause(); 459 460 // SYNC: 461 if (slider.syncExists && !fromNav) methods.sync("animate"); 462 463 // CONTROLNAV 464 if (vars.controlNav) methods.controlNav.active(); 465 466 // !CAROUSEL: 467 // CANDIDATE: slide active class (for add/remove slide) 468 if (!carousel) slider.slides.removeClass(namespace + 'active-slide').eq(target).addClass(namespace + 'active-slide'); 469 470 // INFINITE LOOP: 471 // CANDIDATE: atEnd 472 slider.atEnd = target === 0 || target === slider.last; 473 474 // DIRECTIONNAV: 475 if (vars.directionNav) methods.directionNav.update(); 476 477 if (target === slider.last) { 478 // API: end() of cycle Callback 479 vars.end(slider); 480 // SLIDESHOW && !INFINITE LOOP: 481 if (!vars.animationLoop) slider.pause(); 482 } 483 484 // SLIDE: 485 if (!fade) { 486 var dimension = (vertical) ? slider.slides.filter(':first').height() : slider.computedW, 487 margin, slideString, calcNext; 488 489 // INFINITE LOOP / REVERSE: 490 if (carousel) { 491 margin = (vars.itemWidth > slider.w) ? vars.itemMargin * 2 : vars.itemMargin; 492 calcNext = ((slider.itemW + margin) * slider.move) * slider.animatingTo; 493 slideString = (calcNext > slider.limit && slider.visible !== 1) ? slider.limit : calcNext; 494 } else if (slider.currentSlide === 0 && target === slider.count - 1 && vars.animationLoop && slider.direction !== "next") { 495 slideString = (reverse) ? (slider.count + slider.cloneOffset) * dimension : 0; 496 } else if (slider.currentSlide === slider.last && target === 0 && vars.animationLoop && slider.direction !== "prev") { 497 slideString = (reverse) ? 0 : (slider.count + 1) * dimension; 498 } else { 499 slideString = (reverse) ? ((slider.count - 1) - target + slider.cloneOffset) * dimension : (target + slider.cloneOffset) * dimension; 500 } 501 slider.setProps(slideString, "", vars.animationSpeed); 502 if (slider.transitions) { 503 if (!vars.animationLoop || !slider.atEnd) { 504 slider.animating = false; 505 slider.currentSlide = slider.animatingTo; 506 } 507 slider.container.unbind("webkitTransitionEnd transitionend"); 508 slider.container.bind("webkitTransitionEnd transitionend", function() { 509 slider.wrapup(dimension); 510 }); 511 } else { 512 slider.container.animate(slider.args, vars.animationSpeed, vars.easing, function(){ 513 slider.wrapup(dimension); 514 }); 515 } 516 } else { // FADE: 517 slider.slides.eq(slider.currentSlide).fadeOut(vars.animationSpeed, vars.easing); 518 slider.slides.eq(target).fadeIn(vars.animationSpeed, vars.easing, slider.wrapup); 519 } 520 // SMOOTH HEIGHT: 521 if (vars.smoothHeight) methods.smoothHeight(vars.animationSpeed); 522 } 523 } 524 slider.wrapup = function(dimension) { 525 // SLIDE: 526 if (!fade && !carousel) { 527 if (slider.currentSlide === 0 && slider.animatingTo === slider.last && vars.animationLoop) { 528 slider.setProps(dimension, "jumpEnd"); 529 } else if (slider.currentSlide === slider.last && slider.animatingTo === 0 && vars.animationLoop) { 530 slider.setProps(dimension, "jumpStart"); 531 } 532 } 533 slider.animating = false;
534 slider.currentSlide = slider.animatingTo; 535 // API: after() animation Callback 536 vars.after(slider); 537 } 538 539 // SLIDESHOW: 540 slider.animateSlides = function() { 541 if (!slider.animating) slider.flexAnimate(slider.getTarget("next")); 542 } 543 // SLIDESHOW: 544 slider.pause = function() { 545 clearInterval(slider.animatedSlides); 546 slider.playing = false; 547 // PAUSEPLAY: 548 if (vars.pausePlay) methods.pausePlay.update("play"); 549 // SYNC: 550 if (slider.syncExists) methods.sync("pause"); 551 } 552 // SLIDESHOW: 553 slider.play = function() { 554 slider.animatedSlides = setInterval(slider.animateSlides, vars.slideshowSpeed); 555 slider.playing = true; 556 // PAUSEPLAY: 557 if (vars.pausePlay) methods.pausePlay.update("pause"); 558 // SYNC: 559 if (slider.syncExists) methods.sync("play"); 560 } 561 slider.canAdvance = function(target, fromNav) { 562 // ASNAV: 563 var last = (asNav) ? slider.pagingCount - 1 : slider.last; 564 return (fromNav) ? true : 565 (asNav && slider.currentItem === slider.count - 1 && target === 0 && slider.direction === "prev") ? true : 566 (asNav && slider.currentItem === 0 && target === slider.pagingCount - 1 && slider.direction !== "next") ? false : 567 (target === slider.currentSlide && !asNav) ? false : 568 (vars.animationLoop) ? true : 569 (slider.atEnd && slider.currentSlide === 0 && target === last && slider.direction !== "next") ? false : 570 (slider.atEnd && slider.currentSlide === last && target === 0 && slider.direction === "next") ? false : 571 true; 572 } 573 slider.getTarget = function(dir) { 574 slider.direction = dir; 575 if (dir === "next") { 576 return (slider.currentSlide === slider.last) ? 0 : slider.currentSlide + 1; 577 } else { 578 return (slider.currentSlide === 0) ? slider.last : slider.currentSlide - 1; 579 } 580 } 581 582 // SLIDE: 583 slider.setProps = function(pos, special, dur) { 584 var target = (function() { 585 var posCheck = (pos) ? pos : ((slider.itemW + vars.itemMargin) * slider.move) * slider.animatingTo, 586 posCalc = (function() { 587 if (carousel) { 588 return (special === "setTouch") ? pos : 589 (reverse && slider.animatingTo === slider.last) ? 0 : 590 (reverse) ? slider.limit - (((slider.itemW + vars.itemMargin) * slider.move) * slider.animatingTo) : 591 (slider.animatingTo === slider.last) ? slider.limit : posCheck; 592 } else { 593 switch (special) { 594 case "setTotal": return (reverse) ? ((slider.count - 1) - slider.currentSlide + slider.cloneOffset) * pos : (slider.currentSlide + slider.cloneOffset) * pos; 595 case "setTouch": return (reverse) ? pos : pos; 596 case "jumpEnd": return (reverse) ? pos : slider.count * pos; 597 case "jumpStart": return (reverse) ? slider.count * pos : pos; 598 default: return pos; 599 } 600 } 601 }()); 602 return (posCalc * -1) + "px"; 603 }()); 604 605 if (slider.transitions) { 606 target = (vertical) ? "translate3d(0," + target + ",0)" : "translate3d(" + target + ",0,0)"; 607 dur = (dur !== undefined) ? (dur/1000) + "s" : "0s"; 608 slider.container.css("-" + slider.pfx + "-transition-duration", dur); 609 } 610 611 slider.args[slider.prop] = target; 612 if (slider.transitions || dur === undefined) slider.container.css(slider.args); 613 } 614 615 slider.setup = function(type) { 616 // SLIDE: 617 if (!fade) { 618 var sliderOffset, arr; 619 620 if (type === "init") { 621 slider.viewport = $('<div class="' + namespace + 'viewport"></div>').css({"overflow": "hidden", "position": "relative"}).appendTo(slider).append(slider.container); 622 // INFINITE LOOP: 623 slider.cloneCount = 0; 624 slider.cloneOffset = 0; 625 // REVERSE: 626 if (reverse) { 627 arr = $.makeArray(slider.slides).reverse(); 628 slider.slides = $(arr); 629 slider.container.empty().append(slider.slides); 630 } 631 } 632 // INFINITE LOOP && !CAROUSEL: 633 if (vars.animationLoop && !carousel) { 634 slider.cloneCount = 2; 635 slider.cloneOffset = 1; 636 // clear out old clones 637 if (type !== "init") slider.container.find('.clone').remove(); 638 slider.container.append(slider.slides.first().clone().addClass('clone')).prepend(sli
638der.slides.last().clone().addClass('clone')); 639 } 640 slider.newSlides = $(vars.selector, slider); 641 642 sliderOffset = (reverse) ? slider.count - 1 - slider.currentSlide + slider.cloneOffset : slider.currentSlide + slider.cloneOffset; 643 // VERTICAL: 644 if (vertical && !carousel) { 645 slider.container.height((slider.count + slider.cloneCount) * 200 + "%").css("position", "absolute").width("100%"); 646 setTimeout(function(){ 647 slider.newSlides.css({"display": "block"}); 648 slider.doMath(); 649 slider.viewport.height(slider.h); 650 slider.setProps(sliderOffset * slider.h, "init"); 651 }, (type === "init") ? 100 : 0); 652 } else { 653 slider.container.width((slider.count + slider.cloneCount) * 200 + "%"); 654 slider.setProps(sliderOffset * slider.computedW, "init"); 655 setTimeout(function(){ 656 slider.doMath(); 657 slider.newSlides.css({"width": slider.computedW, "float": "left", "display": "block"}); 658 // SMOOTH HEIGHT: 659 if (vars.smoothHeight) methods.smoothHeight(); 660 }, (type === "init") ? 100 : 0); 661 } 662 } else { // FADE: 663 slider.slides.css({"width": "100%", "float": "left", "marginRight": "-100%", "position": "relative"}); 664 if (type === "init") slider.slides.eq(slider.currentSlide).fadeIn(vars.animationSpeed, vars.easing); 665 // SMOOTH HEIGHT: 666 if (vars.smoothHeight) methods.smoothHeight(); 667 } 668 // !CAROUSEL: 669 // CANDIDATE: active slide 670 if (!carousel) slider.slides.removeClass(namespace + "active-slide").eq(slider.currentSlide).addClass(namespace + "active-slide"); 671 } 672 673 slider.doMath = function() { 674 var slide = slider.slides.first(), 675 slideMargin = vars.itemMargin, 676 minItems = vars.minItems, 677 maxItems = vars.maxItems; 678 679 slider.w = slider.width(); 680 slider.h = slide.height(); 681 slider.boxPadding = slide.outerWidth() - slide.width(); 682 683 // CAROUSEL: 684 if (carousel) { 685 slider.itemT = vars.itemWidth + slideMargin; 686 slider.minW = (minItems) ? minItems * slider.itemT : slider.w; 687 slider.maxW = (maxItems) ? maxItems * slider.itemT : slider.w; 688 slider.itemW = (slider.minW > slider.w) ? (slider.w - (slideMargin * minItems))/minItems : 689 (slider.maxW < slider.w) ? (slider.w - (slideMargin * maxItems))/maxItems : 690 (vars.itemWidth > slider.w) ? slider.w : vars.itemWidth; 691 slider.visible = Math.floor(slider.w/(slider.itemW + slideMargin)); 692 slider.move = (vars.move > 0 && vars.move < slider.visible ) ? vars.move : slider.visible; 693 slider.pagingCount = Math.ceil(((slider.count - slider.visible)/slider.move) + 1); 694 slider.last = slider.pagingCount - 1; 695 slider.limit = (slider.pagingCount === 1) ? 0 : 696 (vars.itemWidth > slider.w) ? ((slider.itemW + (slideMargin * 2)) * slider.count) - slider.w - slideMargin : ((slider.itemW + slideMargin) * slider.count) - slider.w - slideMargin; 697 } else { 698 slider.itemW = slider.w; 699 slider.pagingCount = slider.count; 700 slider.last = slider.count - 1; 701 } 702 slider.computedW = slider.itemW - slider.boxPadding; 703 } 704 705 slider.update = function(pos, action) { 706 slider.doMath(); 707 708 // update currentSlide and slider.animatingTo if necessary 709 if (!carousel) { 710 if (pos < slider.currentSlide) { 711 slider.currentSlide += 1; 712 } else if (pos <= slider.currentSlide && pos !== 0) { 713 slider.currentSlide -= 1; 714 } 715 slider.animatingTo = slider.currentSlide; 716 } 717 718 // update controlNav 719 if (vars.controlNav && !slider.manualControls) { 720 if ((action === "add" && !carousel) || slider.pagingCount > slider.controlNav.length) { 721 methods.controlNav.update("add"); 722 } else if ((action === "remove" && !carousel) || slider.pagingCount < slider.controlNav.length) { 723 if (carousel && slider.currentSlide > slider.last) { 724 slider.currentSlide -= 1; 725 slider.animatingTo -= 1; 726 } 727 methods.controlNav.update("remove", slider.last); 728 } 729 } 730 // update directionNav
vendor: 4,957 bytes, lines 731-823
731 if (vars.directionNav) methods.directionNav.update(); 732 733 } 734 735 slider.addSlide = function(obj, pos) { 736 var $obj = $(obj); 737 738 slider.count += 1; 739 slider.last = slider.count - 1; 740 741 // append new slide 742 if (vertical && reverse) { 743 (pos !== undefined) ? slider.slides.eq(slider.count - pos).after($obj) : slider.container.prepend($obj); 744 } else { 745 (pos !== undefined) ? slider.slides.eq(pos).before($obj) : slider.container.append($obj); 746 } 747 748 // update currentSlide, animatingTo, controlNav, and directionNav 749 slider.update(pos, "add"); 750 751 // update slider.slides 752 slider.slides = $(vars.selector + ':not(.clone)', slider); 753 // re-setup the slider to accomdate new slide 754 slider.setup(); 755 756 //FlexSlider: added() Callback 757 vars.added(slider); 758 } 759 slider.removeSlide = function(obj) { 760 var pos = (isNaN(obj)) ? slider.slides.index($(obj)) : obj; 761 762 // update count 763 slider.count -= 1; 764 slider.last = slider.count - 1; 765 766 // remove slide 767 if (isNaN(obj)) { 768 $(obj, slider.slides).remove(); 769 } else { 770 (vertical && reverse) ? slider.slides.eq(slider.last).remove() : slider.slides.eq(obj).remove(); 771 } 772 773 // update currentSlide, animatingTo, controlNav, and directionNav 774 slider.doMath(); 775 slider.update(pos, "remove"); 776 777 // update slider.slides 778 slider.slides = $(vars.selector + ':not(.clone)', slider); 779 // re-setup the slider to accomdate new slide 780 slider.setup(); 781 782 // FlexSlider: removed() Callback 783 vars.removed(slider); 784 } 785 786 //FlexSlider: Initialize 787 methods.init(); 788 } 789 790 //FlexSlider: Default Settings 791 $.flexslider.defaults = { 792 namespace: "flex-", //{NEW} String: Prefix string attached to the class of every element generated by the plugin 793 selector: ".slides > li", //{NEW} Selector: Must match a simple pattern. '{container} > {slide}' -- Ignore pattern at your own peril 794 animation: "fade", //String: Select your animation type, "fade" or "slide" 795 easing: "swing", //{NEW} String: Determines the easing method used in jQuery transitions. jQuery easing plugin is supported! 796 direction: "horizontal", //String: Select the sliding direction, "horizontal" or "vertical" 797 reverse: false, //{NEW} Boolean: Reverse the animation direction 798 animationLoop: true, //Boolean: Should the animation loop? If false, directionNav will received "disable" classes at either end 799 smoothHeight: false, //{NEW} Boolean: Allow height of the slider to animate smoothly in horizontal mode 800 startAt: 0, //Integer: The slide that the slider should start on. Array notation (0 = first slide) 801 slideshow: true, //Boolean: Animate slider automatically 802 slideshowSpeed: 7000, //Integer: Set the speed of the slideshow cycling, in milliseconds 803 animationSpeed: 600, //Integer: Set the speed of animations, in milliseconds 804 initDelay: 0, //{NEW} Integer: Set an initialization delay, in milliseconds 805 randomize: false, //Boolean: Randomize slide order 806 807 // Usability features 808 pauseOnAction: true, //Boolean: Pause the slideshow when interacting with control elements, highly recommended. 809 pauseOnHover: false, //Boolean: Pause the slideshow when hovering over slider, then resume when no longer hovering 810 useCSS: true, //{NEW} Boolean: Slider will use CSS3 transitions if available 811 touch: true, //{NEW} Boolean: Allow touch swipe navigation of the slider on touch-enabled devices 812 video: false, //{NEW} Boolean: If using video in the slider, will prevent CSS3 3D Transforms to avoid graphical glitches 813 814 // Primary Controls 815 controlNav: true, //Boolean: Create navigation for paging control of each clide? Note: Leave true for manualControls usage 816 directionNav: true, //Boolean: Create navigation for previous/next navigation? (true/false) 817 prevText: "Previous", //String: Set the text for the "previous" directionNav item 818 nextText: "Next", //String: Set the text for the "next" directionNav item 819 820 // Secondary Navigation 821 keyboard: true, //Boolean: Allow slider navigating via keyboard left/right keys 822 multipleKeyboard: false, //{NEW} Boolean: Allow keyboard navigation to affect multiple sliders. Default behavior cuts out keyboard navigation with more than one slider present. 823 mousewheel: false, //{UPDATED} Boolean: Requires jquery.mousewheel.js (https://github.com/brandonaaron/jquery-mousewheel) - Allows slider navigating via mousewheel
824 pausePlay: false, //Boolean: Create pause/play dynamic element 825 pauseText: "Pause", //String: Set the text for the "pause" pausePlay item 826 playText: "Play", //String: Set the text for the "play" pausePlay item 827 828 // Special properties 829 controlsContainer: "", //{UPDATED} jQuery Object/Selector: Declare which container the navigation elements should be appended too. Default container is the FlexSlider element. Example use would be $(".flexslider-container"). Property is ignored if given element is not found. 830 manualControls: "", //{UPDATED} jQuery Object/Selector: Declare custom control navigation. Examples would be $(".flex-control-nav li") or "#tabs-nav li img", etc. The number of elements in your controlNav should match the number of slides/tabs. 831 sync: "", //{NEW} Selector: Mirror the actions performed on this slider with another slider. Use with care. 832 asNavFor: "", //{NEW} Selector: Internal property exposed for turning the slider into a thumbnail navigation for another slider 833 834 // Carousel Options 835 itemWidth: 0, //{NEW} Integer: Box-model width of individual carousel items, including horizontal borders and padding. 836 itemMargin: 0, //{NEW} Integer: Margin between carousel items. 837 minItems: 0, //{NEW} Integer: Minimum number of carousel items that should be visible. Items will resize fluidly when below this. 838 maxItems: 0, //{NEW} Integer: Maxmimum number of carousel items that should be visible. Items will resize fluidly when above this limit. 839 move: 0, //{NEW} Integer: Number of carousel items that should move on animation. If 0, slider will move all visible items. 840 841 // Callback API 842 start: function(){}, //Callback: function(slider) - Fires when the slider loads the first slide 843 before: function(){}, //Callback: function(slider) - Fires asynchronously with each slider animation 844 after: function(){}, //Callback: function(slider) - Fires after each slider animation completes 845 end: function(){}, //Callback: function(slider) - Fires when the slider reaches the last slide (asynchronous) 846 added: function(){}, //{NEW} Callback: function(slider) - Fires after a slide is added 847 removed: function(){} //{NEW} Callback: function(slider) - Fires after a slide is removed 848 } 849 850 851 //FlexSlider: Plugin Function 852 $.fn.flexslider = function(options) { 853 if (options === undefined) options = {}; 854 855 if (typeof options === "object") { 856 return this.each(function() { 857 var $this = $(this), 858 selector = (options.selector) ? options.selector : ".slides > li", 859 $slides = $this.find(selector); 860 861 if ($slides.length === 1) { 862 $slides.fadeIn(400); 863 if (options.start) options.start($this); 864 } else if ($this.data('flexslider') === undefined) { 865 new $.flexslider(this, options); 866 } 867 }); 868 } else { 869 // Helper strings to quickly perform functions on the slider 870 var $slider = $(this).data('flexslider'); 871 switch (options) { 872 case "play": $slider.play(); break; 873 case "pause": $slider.pause(); break; 874 case "next": $slider.flexAnimate($slider.getTarget("next"), true); break; 875 case "prev": 876 case "previous": $slider.flexAnimate($slider.getTarget("prev"), true); break; 877 default: if (typeof options === "number") $slider.flexAnimate(options, true); 878 } 879 } 880 } 881 882})(jQuery); 883 884/*global jQuery */ 885/*! 886* FitVids 1.0 887* 888* Copyright 2011, Chris Coyier - http://css-tricks.com + Dave Rupert - http://daverupert.com 889* Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/ 890* Released under the WTFPL license - http://sam.zoy.org/wtfpl/ 891* 892* Date: Thu Sept 01 18:00:00 2011 -0500 893*/ 894 895(function( $ ){ 896 897 $.fn.fitVids = function( options ) { 898 var settings = { 899 customSelector: null 900 } 901 902 var div = document.createElement('div'), 903 ref = document.getElementsByTagName('base')[0] || document.getElementsByTagName('script')[0]; 904 905 div.className = 'fit-vids-style'; 906 div.innerHTML = '­<style> \ 907 .fluid-width-video-wrapper { \ 908 width: 100%; \ 909 position: relative; \ 910 padding: 0; \ 911 } \ 912 \ 913 .fluid-width-video-wrapper iframe, \ 914 .fluid-width-video-wrapper object, \ 915 .fluid-width-video-wrapper embed { \ 916 position: absolute; \ 917 top: 0; \ 918 left: 0; \ 919 width: 100%; \ 920 height: 100%; \ 921 } \ 922 </style>'; 923 924 ref.parentNode.insertBefore(div,ref); 925 926 if ( options ) { 927 $.extend( settings, options ); 928 } 929 930 return this.each(function(){ 931 var selectors = [ 932 "iframe[src^='http://player.vimeo.com']", 933 "iframe[src^='http://www.youtube.com']", 934 "iframe[src^='https://www.youtube.com']", 935 "iframe[src^='http://www.kickstarter.com']", 936 "object", 937 "embed" 938 ]; 939 940 if (settings.customSelector) { 941 selectors.push(settings.customSelector); 942 } 943 944 var $allVideos = $(this).find(selectors.join(',')); 945 946 $allVideos.each(function(){ 947 var $this = $(this); 948 if (this.tagName.toLowerCase() == 'embed' && $this.parent('object').length || $this.parent('.fluid-width-video-wrapper').length) { return; } 949 var height = this.tagName.toLowerCase() == 'object' ? $this.attr('height') : $this.height(), 950 aspectRatio = height / $this.width(); 951 if(!$this.attr('id')){ 952 var videoID = 'fitvid' + Math.floor(Math.random()*999999); 953 $this.attr('id', videoID); 954 } 955 $this.wrap('<div class="fluid-width-video-wrapper"></div>').parent('.fluid-width-video-wrapper').css('padding-top', (aspectRatio * 100)+"%"); 956 $this.removeAttr('height').removeAttr('width'); 957 }); 958 }); 959 960 } 961}
961)( jQuery ); 962 963/*! A fix for the iOS orientationchange zoom bug. 964 Script by @scottjehl, rebound by @wilto. 965 MIT License. 966*/ 967(function(w){ 968 969 // This fix addresses an iOS bug, so return early if the UA claims it's something else. 970 if( !( /iPhone|iPad|iPod/.test( navigator.platform ) && navigator.userAgent.indexOf( "AppleWebKit" ) > -1 ) ){ 971 return; 972 } 973 974 var doc = w.document; 975 976 if( !doc.querySelector ){return;} 977 978 var meta = doc.querySelector( "meta[name=viewport]" ), 979 initialContent = meta && meta.getAttribute( "content" ), 980 disabledZoom = initialContent + ",maximum-scale=1", 981 enabledZoom = initialContent + ",maximum-scale=10", 982 enabled = true, 983 x, y, z, aig; 984 985 if( !meta ){return;} 986 987 function restoreZoom(){ 988 meta.setAttribute( "content", enabledZoom ); 989 enabled = true; 990 } 991 992 function disableZoom(){ 993 meta.setAttribute( "content", disabledZoom ); 994 enabled = false; 995 } 996 997 function checkTilt( e ){ 998 aig = e.accelerationIncludingGravity; 999 x = Math.abs( aig.x ); 1000 y = Math.abs( aig.y ); 1001 z = Math.abs( aig.z ); 1002 1003 // If portrait orientation and in one of the danger zones 1004 if( !w.orientation && ( x > 7 || ( ( z > 6 && y < 8 || z < 8 && y > 6 ) && x > 5 ) ) ){ 1005 if( enabled ){ 1006 disableZoom(); 1007 } 1008 } 1009 else if( !enabled ){ 1010 restoreZoom(); 1011 } 1012 } 1013 1014 w.addEventListener( "orientationchange", restoreZoom, false ); 1015 w.addEventListener( "devicemotion", checkTilt, false ); 1016 1017})(this); 1018 1019 1020// make it safe to use console.log always 1021(function(a){function b(){}for(var c="assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,markTimeline,profile,profileEnd,time,timeEnd,trace,warn".split(","),d;!!(d=c.pop());){a[d]=a[d]||b;}}) 1022(function(){try{console.log();return window.console;}catch(a){return (window.console={});}}()); 1023 1024(function($) { 1025 1026 $.scrollToElement = function( $element, speed ) { 1027 1028 speed = speed || 750; 1029 1030 $("html, body").animate({ 1031 scrollTop: $element.offset().top, 1032 scrollLeft: $element.offset().left 1033 }, speed); 1034 return $element; 1035 }; 1036 1037 $.fn.scrollTo = function( speed ) { 1038 speed = speed || "normal"; 1039 return $.scrollToElement( this, speed ); 1040 }; 1041 1042 jQuery.fn.labelify = function(settings) { 1043 settings = jQuery.extend({ 1044 text: "title", 1045 labelledClass: "" 1046 }, settings); 1047 var lookups = { 1048 title: function(input) { 1049 return $(input).attr("title"); 1050 }, 1051 label: function(input) { 1052 return $("label[for=" + input.id +"]").text(); 1053 } 1054 }; 1055 var lookup; 1056 var jQuery_labellified_elements = $(this); 1057 return $(this).each(function() { 1058 if (typeof settings.text === "string") { 1059 lookup = lookups[settings.text]; // what if not there? 1060 } else { 1061 lookup = settings.text; // what if not a fn? 1062 }; 1063 // bail if lookup isn't a function or if it returns undefined 1064 if (typeof lookup !== "function") {return;} 1065 var lookupval = lookup(this); 1066 if (!lookupval) {return;} 1067 1068 // need to strip newlines because the browser strips them 1069 // if you set textbox.value to a string containing them 1070 $(this).data("label",lookup(this).replace(/\n/g,'')); 1071 $(this).focus(function() { 1072 if (this.value === $(this).data("label")) { 1073 this.value = this.defaultValue; 1074 $(this).removeClass(settings.labelledClass); 1075 } 1076 }).blur(function(){ 1077 if (this.value === this.defaultValue) { 1078 this.value = $(this).data("label"); 1079 $(this).addClass(settings.labelledClass); 1080 } 1081 }); 1082 1083 var removeValuesOnExit = function() { 1084 jQuery_labellified_elements.each(function(){ 1085 if (this.value === $(this).data("label")) { 1086 this.value = this.defaultValue; 1087 $(this).removeClass(settings.labelledClass); 1088 } 1089 }) 1090 }; 1091 1092 $(this).parents("form").submit(removeValuesOnExit); 1093 $(window).unload(removeValuesOnExit); 1094 1095 if (this.value !== this.defaultValue) { 1096 // user already started typing; don't overwrite their work! 1097 return; 1098 } 1099 // actually set the value 1100 this.value = $(this).data("label"); 1101 $(this).addClass(settings.labelledClass); 1102 1103 }); 1104 }; 1105})(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.