1/* 2 * jQuery Superfish Menu Plugin 3 * Copyright (c) 2013 Joel Birch 4 * 5 * Dual licensed under the MIT and GPL licenses: 6 * http://www.opensource.org/licenses/mit-license.php 7 * http://www.gnu.org/licenses/gpl.html 8 */ 9 10(function ($) { 11 "use strict"; 12 13 var methods = (function () { 14 // private properties and methods go here 15 var c = { 16 bcClass: 'sf-breadcrumb', 17 menuClass: 'sf-js-enabled', 18 anchorClass: 'sf-with-ul', 19 menuArrowClass: 'sf-arrows' 20 }, 21 ios = (function () { 22 var ios = /iPhone|iPad|iPod/i.test(navigator.userAgent); 23 if (ios) { 24 // iOS clicks only bubble as far as body children 25 $(window).load(function () { 26 $('body').children().on('click', $.noop); 27 }); 28 } 29 return ios; 30 })(), 31 wp7 = (function () { 32 var style = document.documentElement.style; 33 return ('behavior' in style && 'fill' in style && /iemobile/i.test(navigator.userAgent)); 34 })(), 35 toggleMenuClasses = function ($menu, o) { 36 var classes = c.menuClass; 37 if (o.cssArrows) { 38 classes += ' ' + c.menuArrowClass; 39 } 40 $menu.toggleClass(classes); 41 }, 42 setPathToCurrent = function ($menu, o) { 43 return $menu.find('li.' + o.pathClass).slice(0, o.pathLevels) 44 .addClass(o.hoverClass + ' ' + c.bcClass) 45 .filter(function () { 46 return ($(this).children(o.popUpSelector).hide().show().length); 47 }).removeClass(o.pathClass); 48 }, 49 toggleAnchorClass = function ($li) { 50 $li.children('a').toggleClass(c.anchorClass); 51 }, 52 toggleTouchAction = function ($menu) { 53 var touchAction = $menu.css('ms-touch-action'); 54 touchAction = (touchAction === 'pan-y') ? 'auto' : 'pan-y'; 55 $menu.css('ms-touch-action', touchAction); 56 }, 57 applyHandlers = function ($menu, o) { 58 var targets = 'li:has(' + o.popUpSelector + ')'; 59 if ($.fn.hoverIntent && !o.disableHI) { 60 $menu.hoverIntent(over, out, targets); 61 } 62 else { 63 $menu 64 .on('mouseenter.superfish', targets, over) 65 .on('mouseleave.superfish', targets, out); 66 } 67 var touchevent = 'MSPointerDown.superfish'; 68 if (!ios) { 69 touchevent += ' touchend.superfish'; 70 } 71 if (wp7) { 72 touchevent += ' mousedown.superfish'; 73 } 74 $menu 75 .on('focusin.superfish', 'li', over) 76 .on('focusout.superfish', 'li', out) 77 .on(touchevent, 'a', o, touchHandler); 78 }, 79 touchHandler = function (e) { 80 var $this = $(this), 81 $ul = $this.siblings(e.data.popUpSelector); 82 83 if ($ul.length > 0 && $ul.is(':hidden')) { 84 $this.one('click.superfish', false); 85 if (e.type === 'MSPointerDown') { 86 $this.trigger('focus'); 87 } else { 88 $.proxy(over, $this.parent('li'))(); 89 } 90 } 91 }, 92 over = function () { 93 var $this = $(this), 94 o = getOptions($this); 95 clearTimeout(o.sfTimer); 96 $this.siblings().superfish('hide').end().superfish('show'); 97 }, 98 out = function () { 99 var $this = $(this), 100 o = getOptions($this); 101 if (ios) { 102 $.proxy(close, $this, o)(); 103 } 104 else { 105 clearTimeout(o.sfTimer); 106 o.sfTimer = setTimeout($.proxy(close, $this, o), o.delay); 107 } 108 }, 109 close = function (o) { 110 o.retainPath = ($.inArray(this[0], o.$path) > -1); 111 this.superfish('hide'); 112 113 if (!this.parents('.' + o.hoverClass).length) { 114 o.onIdle.call(getMenu(this)); 115 if (o.$path.length) { 116 $.proxy(over, o.$path)(); 117 } 118 } 119 }, 120 getMenu = function ($el) { 121 return $el.closest('.' + c.menuClass); 122 }, 123 getOptions = function ($el) { 124 return getMenu($el).data('sf-options'); 125 }; 126 127 return { 128 // public methods 129 hide: function (instant) { 130 if (this.length) { 131 var $this = this, 132 o = getOptions($this); 133 if (!o) { 134 return this; 135 } 136 var not = (o.retainPath === true) ? o.$path : '', 137 $ul = $this.find('li.' + o.hoverClass).add(this).not(not).removeClass(o.hoverClass).children(o.popUpSelector), 138 speed = o.speedOut; 139 140 if (instant) { 141 $ul.show(); 142 speed = 0; 143 } 144 o.retainPath = false; 145 o.onBeforeHide.call($ul); 146 $ul.stop(true, true).animate(o.animationOut, speed, function () { 147 var $this = $(this); 148 o.onHide.call($this); 149 });
150 } 151 return this; 152 }, 153 show: function () { 154 var o = getOptions(this); 155 if (!o) { 156 return this; 157 } 158 var $this = this.addClass(o.hoverClass), 159 $ul = $this.children(o.popUpSelector); 160 161 o.onBeforeShow.call($ul); 162 $ul.stop(true, true).animate(o.animation, o.speed, function () { 163 o.onShow.call($ul); 164 }); 165 return this; 166 }, 167 destroy: function () { 168 return this.each(function () { 169 var $this = $(this), 170 o = $this.data('sf-options'), 171 $hasPopUp; 172 if (!o) { 173 return false; 174 } 175 $hasPopUp = $this.find(o.popUpSelector).parent('li'); 176 clearTimeout(o.sfTimer); 177 toggleMenuClasses($this, o); 178 toggleAnchorClass($hasPopUp); 179 toggleTouchAction($this); 180 // remove event handlers 181 $this.off('.superfish').off('.hoverIntent'); 182 // clear animation's inline display style 183 $hasPopUp.children(o.popUpSelector).attr('style', function (i, style) { 184 return style.replace(/display[^;]+;?/g, ''); 185 }); 186 // reset 'current' path classes 187 o.$path.removeClass(o.hoverClass + ' ' + c.bcClass).addClass(o.pathClass); 188 $this.find('.' + o.hoverClass).removeClass(o.hoverClass); 189 o.onDestroy.call($this); 190 $this.removeData('sf-options'); 191 }); 192 }, 193 init: function (op) { 194 return this.each(function () { 195 var $this = $(this); 196 if ($this.data('sf-options')) { 197 return false; 198 } 199 var o = $.extend({}, $.fn.superfish.defaults, op), 200 $hasPopUp = $this.find(o.popUpSelector).parent('li'); 201 o.$path = setPathToCurrent($this, o); 202 203 $this.data('sf-options', o); 204 205 toggleMenuClasses($this, o); 206 toggleAnchorClass($hasPopUp); 207 toggleTouchAction($this); 208 applyHandlers($this, o); 209 210 $hasPopUp.not('.' + c.bcClass).superfish('hide', true); 211 212 o.onInit.call(this); 213 }); 214 } 215 }; 216 })(); 217 218 $.fn.superfish = function (method, args) { 219 if (methods[method]) { 220 return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 221 } 222 else if (typeof method === 'object' || ! method) { 223 return methods.init.apply(this, arguments); 224 } 225 else { 226 return $.error('Method ' + method + ' does not exist on jQuery.fn.superfish'); 227 } 228 }; 229 230 $.fn.superfish.defaults = { 231 popUpSelector: 'ul,.sf-mega', // within menu context 232 hoverClass: 'sfHover', 233 pathClass: 'overrideThisToUse', 234 pathLevels: 1, 235 delay: 800, 236 animation: {opacity: 'show'}, 237 animationOut: {opacity: 'hide'}, 238 speed: 'normal', 239 speedOut: 'fast', 240 cssArrows: true, 241 disableHI: false, 242 onInit: $.noop, 243 onBeforeShow: $.noop, 244 onShow: $.noop, 245 onBeforeHide: $.noop, 246 onHide: $.noop, 247 onIdle: $.noop, 248 onDestroy: $.noop 249 }; 250 251 // soon to be deprecated 252 $.fn.extend({ 253 hideSuperfishUl: methods.hide, 254 showSuperfishUl: methods.show 255 }); 256 257})(jQuery); 258 259 260 261/* 262 * jQuery FlexSlider v2.2.0 263 * Copyright 2012 WooThemes 264 * Contributing Author: Tyler Smith 265 */ 266; 267(function ($) { 268 269 //FlexSlider: Object Instance 270 $.flexslider = function(el, options) { 271 var slider = $(el); 272 273 // making variables public 274 slider.vars = $.extend({}, $.flexslider.defaults, options); 275 276 var namespace = slider.vars.namespace, 277 msGesture = window.navigator && window.navigator.msPointerEnabled && window.MSGesture, 278 touch = (( "ontouchstart" in window ) || msGesture || window.DocumentTouch && document instanceof DocumentTouch) && slider.vars.touch, 279 // depricating this idea, as devices are being released with both of these events 280 //eventType = (touch) ? "touchend" : "click", 281 eventType = "click touchend MSPointerUp", 282 watchedEvent = "", 283 watchedEventClearTimer, 284 vertical = slider.vars.direction === "vertical", 285 reverse = slider.vars.reverse, 286 carousel = (slider.vars.itemWidth > 0), 287 fade = slider.vars.animation === "fade", 288 asNav = slider.vars.asNavFor !== "", 289 methods = {}, 290 focused = true; 291 292 // Store a reference to the slider object 293 $.data(el, "flexslider", slider); 294 295 // Private slider methods 296 methods = { 297 init: function() { 298 slider.animating = false; 299 // Get current slide and make sure it is a number 300 slider.currentSlide = parseInt( ( slider.vars.startAt ? slider.vars.startAt : 0) ); 301 if ( isNaN( slider.currentSlide ) ) slider.currentSlide = 0; 302 slider.animatingTo = slider.currentSlide; 303 slider.atEnd = (slider.currentSlide === 0 || slider.currentSlide === slider.last); 304 slider.containerSelector = slider.vars.selector.substr(0,slider.vars.selector.search(' '));
305 slider.slides = $(slider.vars.selector, slider); 306 slider.container = $(slider.containerSelector, slider); 307 slider.count = slider.slides.length; 308 // SYNC: 309 slider.syncExists = $(slider.vars.sync).length > 0; 310 // SLIDE: 311 if (slider.vars.animation === "slide") slider.vars.animation = "swing"; 312 slider.prop = (vertical) ? "top" : "marginLeft"; 313 slider.args = {}; 314 // SLIDESHOW: 315 slider.manualPause = false; 316 slider.stopped = false; 317 //PAUSE WHEN INVISIBLE 318 slider.started = false; 319 slider.startTimeout = null; 320 // TOUCH/USECSS: 321 slider.transitions = !slider.vars.video && !fade && slider.vars.useCSS && (function() { 322 var obj = document.createElement('div'), 323 props = ['perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective']; 324 for (var i in props) { 325 if ( obj.style[ props[i] ] !== undefined ) { 326 slider.pfx = props[i].replace('Perspective','').toLowerCase(); 327 slider.prop = "-" + slider.pfx + "-transform"; 328 return true; 329 } 330 } 331 return false; 332 }()); 333 // CONTROLSCONTAINER: 334 if (slider.vars.controlsContainer !== "") slider.controlsContainer = $(slider.vars.controlsContainer).length > 0 && $(slider.vars.controlsContainer); 335 // MANUAL: 336 if (slider.vars.manualControls !== "") slider.manualControls = $(slider.vars.manualControls).length > 0 && $(slider.vars.manualControls); 337 338 // RANDOMIZE: 339 if (slider.vars.randomize) { 340 slider.slides.sort(function() { return (Math.round(Math.random())-0.5); }); 341 slider.container.empty().append(slider.slides); 342 } 343 344 slider.doMath(); 345 346 // INIT 347 slider.setup("init"); 348 349 // CONTROLNAV: 350 if (slider.vars.controlNav) methods.controlNav.setup(); 351 352 // DIRECTIONNAV: 353 if (slider.vars.directionNav) methods.directionNav.setup(); 354 355 // KEYBOARD: 356 if (slider.vars.keyboard && ($(slider.containerSelector).length === 1 || slider.vars.multipleKeyboard)) { 357 $(document).bind('keyup', function(event) { 358 var keycode = event.keyCode; 359 if (!slider.animating && (keycode === 39 || keycode === 37)) { 360 var target = (keycode === 39) ? slider.getTarget('next') : 361 (keycode === 37) ? slider.getTarget('prev') : false; 362 slider.flexAnimate(target, slider.vars.pauseOnAction); 363 } 364 }); 365 } 366 // MOUSEWHEEL: 367 if (slider.vars.mousewheel) { 368 slider.bind('mousewheel', function(event, delta, deltaX, deltaY) { 369 event.preventDefault(); 370 var target = (delta < 0) ? slider.getTarget('next') : slider.getTarget('prev'); 371 slider.flexAnimate(target, slider.vars.pauseOnAction); 372 }); 373 } 374 375 // PAUSEPLAY 376 if (slider.vars.pausePlay) methods.pausePlay.setup(); 377 378 //PAUSE WHEN INVISIBLE 379 if (slider.vars.slideshow && slider.vars.pauseInvisible) methods.pauseInvisible.init(); 380 381 // SLIDSESHOW 382 if (slider.vars.slideshow) { 383 if (slider.vars.pauseOnHover) { 384 slider.hover(function() { 385 if (!slider.manualPlay && !slider.manualPause) slider.pause(); 386 }, function() { 387 if (!slider.manualPause && !slider.manualPlay && !slider.stopped) slider.play(); 388 }); 389 } 390 // initialize animation 391 //If we're visible, or we don't use PageVisibility API 392 if(!slider.vars.pauseInvisible || !methods.pauseInvisible.isHidden()) { 393 (slider.vars.initDelay > 0) ? slider.startTimeout = setTimeout(slider.play, slider.vars.initDelay) : slider.play(); 394 } 395 } 396 397 // ASNAV: 398 if (asNav) methods.asNav.setup(); 399 400 // TOUCH 401 if (touch && slider.vars.touch) methods.touch(); 402 403 // FADE&&SMOOTHHEIGHT || SLIDE: 404 if (!fade || (fade && slider.vars.smoothHeight)) $(window).bind("resize orientationchange focus", methods.resize); 405 406 slider.find("img").attr("draggable", "false"); 407 408 // API: start() Callback 409 setTimeout(function(){ 410 slider.vars.start(slider); 411 }, 200); 412 }, 413 asNav: { 414 setup: function() { 415 slider.asNav = true; 416 slider.animatingTo = Math.floor(slider.currentSlide/slider.move); 417 slider.currentItem = slider.currentSlide; 418 slider.slides.removeClass(namespace + "active-slide").eq(slider.currentItem).addClass(namespace + "active-slide"); 419 if(!msGesture){ 420 slider.slides.click(function(e){
421 e.preventDefault(); 422 var $slide = $(this), 423 target = $slide.index(); 424 var posFromLeft = $slide.offset().left - $(slider).scrollLeft(); // Find position of slide relative to left of slider container 425 if( posFromLeft <= 0 && $slide.hasClass( namespace + 'active-slide' ) ) { 426 slider.flexAnimate(slider.getTarget("prev"), true); 427 } else if (!$(slider.vars.asNavFor).data('flexslider').animating && !$slide.hasClass(namespace + "active-slide")) { 428 slider.direction = (slider.currentItem < target) ? "next" : "prev"; 429 slider.flexAnimate(target, slider.vars.pauseOnAction, false, true, true); 430 } 431 }); 432 }else{ 433 el._slider = slider; 434 slider.slides.each(function (){ 435 var that = this; 436 that._gesture = new MSGesture(); 437 that._gesture.target = that; 438 that.addEventListener("MSPointerDown", function (e){ 439 e.preventDefault(); 440 if(e.currentTarget._gesture) 441 e.currentTarget._gesture.addPointer(e.pointerId); 442 }, false); 443 that.addEventListener("MSGestureTap", function (e){ 444 e.preventDefault(); 445 var $slide = $(this), 446 target = $slide.index(); 447 if (!$(slider.vars.asNavFor).data('flexslider').animating && !$slide.hasClass('active')) { 448 slider.direction = (slider.currentItem < target) ? "next" : "prev"; 449 slider.flexAnimate(target, slider.vars.pauseOnAction, false, true, true); 450 } 451 }); 452 }); 453 } 454 } 455 }, 456 controlNav: { 457 setup: function() { 458 if (!slider.manualControls) { 459 methods.controlNav.setupPaging(); 460 } else { // MANUALCONTROLS: 461 methods.controlNav.setupManual(); 462 } 463 }, 464 setupPaging: function() { 465 var type = (slider.vars.controlNav === "thumbnails") ? 'control-thumbs' : 'control-paging', 466 j = 1, 467 item, 468 slide; 469 470 slider.controlNavScaffold = $('<ol class="'+ namespace + 'control-nav ' + namespace + type + '"></ol>'); 471 472 if (slider.pagingCount > 1) { 473 for (var i = 0; i < slider.pagingCount; i++) { 474 slide = slider.slides.eq(i); 475 item = (slider.vars.controlNav === "thumbnails") ? '<img src="' + slide.attr( 'data-thumb' ) + '"/>' : '<a>' + j + '</a>'; 476 if ( 'thumbnails' === slider.vars.controlNav && true === slider.vars.thumbCaptions ) { 477 var captn = slide.attr( 'data-thumbcaption' ); 478 if ( '' != captn && undefined != captn ) item += '<span class="' + namespace + 'caption">' + captn + '</span>'; 479 } 480 slider.controlNavScaffold.append('<li>' + item + '</li>'); 481 j++; 482 } 483 } 484 485 // CONTROLSCONTAINER: 486 (slider.controlsContainer) ? $(slider.controlsContainer).append(slider.controlNavScaffold) : slider.append(slider.controlNavScaffold); 487 methods.controlNav.set(); 488 489 methods.controlNav.active(); 490 491 slider.controlNavScaffold.delegate('a, img', eventType, function(event) { 492 event.preventDefault(); 493 494 if (watchedEvent === "" || watchedEvent === event.type) { 495 var $this = $(this), 496 target = slider.controlNav.index($this); 497 498 if (!$this.hasClass(namespace + 'active')) { 499 slider.direction = (target > slider.currentSlide) ? "next" : "prev"; 500 slider.flexAnimate(target, slider.vars.pauseOnAction); 501 } 502 } 503 504 // setup flags to prevent event duplication 505 if (watchedEvent === "") { 506 watchedEvent = event.type; 507 } 508 methods.setToClearWatchedEvent(); 509 510 }); 511 }, 512 setupManual: function() { 513 slider.controlNav = slider.manualControls; 514 methods.controlNav.active(); 515 516 slider.controlNav.bind(eventType, function(event) { 517 event.preventDefault(); 518 519 if (watchedEvent === "" || watchedEvent === event.type) { 520 var $this = $(this), 521 target = slider.controlNav.index($this); 522 523 if (!$this.hasClass(namespace + 'active')) { 524 (target > slider.currentSlide) ? slider.direction = "next" : slider.direction = "prev"; 525 slider.flexAnimate(target, slider.vars.pauseOnAction); 526 } 527 } 528 529 // setup flags to prevent event duplication 530 if (watchedEvent === "") { 531 watchedEvent = event.type; 532 } 533 methods.setToClearWatchedEvent(); 534 }); 535 }, 536 set: function() { 537 var selector = (slider.vars.controlNav === "thumbnails") ? 'img' : 'a'; 538 slider.controlNav = $('.' + namespace + 'control-nav li ' + selector, (slider.controlsContainer) ? slider.controlsContainer : slider); 539 }, 540 active: function() { 541 slider.controlNav.removeClass(namespace + "active").eq(slider.animatingTo).addClass(namespace + "active"); 542 }, 543 update: function(action, pos) { 544 if (slider.pagingCount > 1 && action === "add") { 545 slider.controlNavScaffold.append($('<li><a>' + slider.count + '</a></li>')); 546 } else if (slider.pagingCount === 1) { 547 slider.controlNavScaffold.find('li').remove(); 548 } else { 549 slider.controlNav.eq(pos).closest('li').remove(); 550 } 551 methods.controlNav.set(); 552 (slider.pagingCount > 1 && slider.pagingCount !== slider.controlNav.length) ? slider.update(pos, action) : methods.controlNav.active(); 553 } 554 }, 555 directionNav: { 556 setup: function() { 557 var directionNavScaffold = $('<ul class="' + namespace + 'direction-nav"><li><a class="' + namespace + 'prev" href="#">
vendor: 9,251 bytes, lines 557-760
557' + slider.vars.prevText + '</a></li><li><a class="' + namespace + 'next" href="#">' + slider.vars.nextText + '</a></li></ul>'); 558 559 // CONTROLSCONTAINER: 560 if (slider.controlsContainer) { 561 $(slider.controlsContainer).append(directionNavScaffold); 562 slider.directionNav = $('.' + namespace + 'direction-nav li a', slider.controlsContainer); 563 } else { 564 slider.append(directionNavScaffold); 565 slider.directionNav = $('.' + namespace + 'direction-nav li a', slider); 566 } 567 568 methods.directionNav.update(); 569 570 slider.directionNav.bind(eventType, function(event) { 571 event.preventDefault(); 572 var target; 573 574 if (watchedEvent === "" || watchedEvent === event.type) { 575 target = ($(this).hasClass(namespace + 'next')) ? slider.getTarget('next') : slider.getTarget('prev'); 576 slider.flexAnimate(target, slider.vars.pauseOnAction); 577 } 578 579 // setup flags to prevent event duplication 580 if (watchedEvent === "") { 581 watchedEvent = event.type; 582 } 583 methods.setToClearWatchedEvent(); 584 }); 585 }, 586 update: function() { 587 var disabledClass = namespace + 'disabled'; 588 if (slider.pagingCount === 1) { 589 slider.directionNav.addClass(disabledClass).attr('tabindex', '-1'); 590 } else if (!slider.vars.animationLoop) { 591 if (slider.animatingTo === 0) { 592 slider.directionNav.removeClass(disabledClass).filter('.' + namespace + "prev").addClass(disabledClass).attr('tabindex', '-1'); 593 } else if (slider.animatingTo === slider.last) { 594 slider.directionNav.removeClass(disabledClass).filter('.' + namespace + "next").addClass(disabledClass).attr('tabindex', '-1'); 595 } else { 596 slider.directionNav.removeClass(disabledClass).removeAttr('tabindex'); 597 } 598 } else { 599 slider.directionNav.removeClass(disabledClass).removeAttr('tabindex'); 600 } 601 } 602 }, 603 pausePlay: { 604 setup: function() { 605 var pausePlayScaffold = $('<div class="' + namespace + 'pauseplay"><a></a></div>'); 606 607 // CONTROLSCONTAINER: 608 if (slider.controlsContainer) { 609 slider.controlsContainer.append(pausePlayScaffold); 610 slider.pausePlay = $('.' + namespace + 'pauseplay a', slider.controlsContainer); 611 } else { 612 slider.append(pausePlayScaffold); 613 slider.pausePlay = $('.' + namespace + 'pauseplay a', slider); 614 } 615 616 methods.pausePlay.update((slider.vars.slideshow) ? namespace + 'pause' : namespace + 'play'); 617 618 slider.pausePlay.bind(eventType, function(event) { 619 event.preventDefault(); 620 621 if (watchedEvent === "" || watchedEvent === event.type) { 622 if ($(this).hasClass(namespace + 'pause')) { 623 slider.manualPause = true; 624 slider.manualPlay = false; 625 slider.pause(); 626 } else { 627 slider.manualPause = false; 628 slider.manualPlay = true; 629 slider.play(); 630 } 631 } 632 633 // setup flags to prevent event duplication 634 if (watchedEvent === "") { 635 watchedEvent = event.type; 636 } 637 methods.setToClearWatchedEvent(); 638 }); 639 }, 640 update: function(state) { 641 (state === "play") ? slider.pausePlay.removeClass(namespace + 'pause').addClass(namespace + 'play').html(slider.vars.playText) : slider.pausePlay.removeClass(namespace + 'play').addClass(namespace + 'pause').html(slider.vars.pauseText); 642 } 643 }, 644 touch: function() { 645 var startX, 646 startY, 647 offset, 648 cwidth, 649 dx, 650 startT, 651 scrolling = false, 652 localX = 0, 653 localY = 0, 654 accDx = 0; 655 656 if(!msGesture){ 657 el.addEventListener('touchstart', onTouchStart, false); 658 659 function onTouchStart(e) { 660 if (slider.animating) { 661 e.preventDefault(); 662 } else if ( ( window.navigator.msPointerEnabled ) || e.touches.length === 1 ) { 663 slider.pause(); 664 // CAROUSEL: 665 cwidth = (vertical) ? slider.h : slider. w; 666 startT = Number(new Date()); 667 // CAROUSEL: 668 669 // Local vars for X and Y points. 670 localX = e.touches[0].pageX; 671 localY = e.touches[0].pageY; 672 673 offset = (carousel && reverse && slider.animatingTo === slider.last) ? 0 : 674 (carousel && reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) : 675 (carousel && slider.currentSlide === slider.last) ? slider.limit : 676 (carousel) ? ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.currentSlide : 677 (reverse) ? (slider.last - slider.currentSlide + slider.cloneOffset) * cwidth : (slider.currentSlide + slider.cloneOffset) * cwidth; 678 startX = (vertical) ? localY : localX; 679 startY = (vertical) ? localX : localY; 680 681 el.addEventListener('touchmove', onTouchMove, false); 682 el.addEventListener('touchend', onTouchEnd, false); 683 } 684 } 685 686 function onTouchMove(e) { 687 // Local vars for X and Y points. 688 689 localX = e.touches[0].pageX; 690 localY = e.touches[0].pageY; 691 692 dx = (vertical) ? startX - localY : startX - localX; 693 scrolling = (vertical) ? (Math.abs(dx) < Math.abs(localX - startY)) : (Math.abs(dx) < Math.abs(localY - startY)); 694 695 var fxms = 500; 696 697 if ( ! scrolling || Number( new Date() ) - startT > fxms ) { 698 e.preventDefault(); 699 if (!fade && slider.transitions) { 700 if (!slider.vars.animationLoop) { 701 dx = dx/((slider.currentSlide === 0 && dx < 0 || slider.currentSlide === slider.last && dx > 0) ? (Math.abs(dx)/cwidth+2) : 1); 702 } 703 slider.setProps(offset + dx, "setTouch"); 704 } 705 } 706 } 707 708 function onTouchEnd(e) { 709 // finish the touch by undoing the touch session 710 el.removeEventListener('touchmove', onTouchMove, false); 711 712 if (slider.animatingTo === slider.currentSlide && !scrolling && !(dx === null)) { 713 var updateDx = (reverse) ? -dx : dx, 714 target = (updateDx > 0) ? slider.getTarget('next') : slider.getTarget('prev'); 715 716 if (slider.canAdvance(target) && (Number(new Date()) - startT < 550 && Math.abs(updateDx) > 50 || Math.abs(updateDx) > cwidth/2)) { 717 slider.flexAnimate(target, slider.vars.pauseOnAction); 718 } else { 719 if (!fade) slider.flexAnimate(slider.currentSlide, slider.vars.pauseOnAction, true); 720 } 721 } 722 el.removeEventListener('touchend', onTouchEnd, false); 723 724 startX = null; 725 startY = null; 726 dx = null; 727 offset = null; 728 } 729 }else{ 730 el.style.msTouchAction = "none"; 731 el._gesture = new MSGesture(); 732 el._gesture.target = el; 733 el.addEventListener("MSPointerDown", onMSPointerDown, false); 734 el._slider = slider; 735 el.addEventListener("MSGestureChange", onMSGestureChange, false); 736 el.addEventListener("MSGestureEnd", onMSGestureEnd, false); 737 738 function onMSPointerDown(e){ 739 e.stopPropagation(); 740 if (slider.animating) { 741 e.preventDefault(); 742 }else{ 743 slider.pause(); 744 el._gesture.addPointer(e.pointerId); 745 accDx = 0; 746 cwidth = (vertical) ? slider.h : slider. w; 747 startT = Number(new Date()); 748 // CAROUSEL: 749 750 offset = (carousel && reverse && slider.animatingTo === slider.last) ? 0 : 751 (carousel && reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) : 752 (carousel && slider.currentSlide === slider.last) ? slider.limit : 753 (carousel) ? ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.currentSlide : 754 (reverse) ? (slider.last - slider.currentSlide + slider.cloneOffset) * cwidth : (slider.currentSlide + slider.cloneOffset) * cwidth; 755 } 756 } 757 758 function onMSGestureChange(e) { 759 e.stopPropagation(); 760 var slider = e.target._slider;
761 if(!slider){ 762 return; 763 } 764 var transX = -e.translationX, 765 transY = -e.translationY; 766 767 //Accumulate translations. 768 accDx = accDx + ((vertical) ? transY : transX); 769 dx = accDx; 770 scrolling = (vertical) ? (Math.abs(accDx) < Math.abs(-transX)) : (Math.abs(accDx) < Math.abs(-transY)); 771 772 if(e.detail === e.MSGESTURE_FLAG_INERTIA){ 773 setImmediate(function (){ 774 el._gesture.stop(); 775 }); 776 777 return; 778 } 779 780 if (!scrolling || Number(new Date()) - startT > 500) { 781 e.preventDefault(); 782 if (!fade && slider.transitions) { 783 if (!slider.vars.animationLoop) { 784 dx = accDx / ((slider.currentSlide === 0 && accDx < 0 || slider.currentSlide === slider.last && accDx > 0) ? (Math.abs(accDx) / cwidth + 2) : 1); 785 } 786 slider.setProps(offset + dx, "setTouch"); 787 } 788 } 789 } 790 791 function onMSGestureEnd(e) { 792 e.stopPropagation(); 793 var slider = e.target._slider; 794 if(!slider){ 795 return; 796 } 797 if (slider.animatingTo === slider.currentSlide && !scrolling && !(dx === null)) { 798 var updateDx = (reverse) ? -dx : dx, 799 target = (updateDx > 0) ? slider.getTarget('next') : slider.getTarget('prev'); 800 801 if (slider.canAdvance(target) && (Number(new Date()) - startT < 550 && Math.abs(updateDx) > 50 || Math.abs(updateDx) > cwidth/2)) { 802 slider.flexAnimate(target, slider.vars.pauseOnAction); 803 } else { 804 if (!fade) slider.flexAnimate(slider.currentSlide, slider.vars.pauseOnAction, true); 805 } 806 } 807 808 startX = null; 809 startY = null; 810 dx = null; 811 offset = null; 812 accDx = 0; 813 } 814 } 815 }, 816 resize: function() { 817 if (!slider.animating && slider.is(':visible')) { 818 if (!carousel) slider.doMath(); 819 820 if (fade) { 821 // SMOOTH HEIGHT: 822 methods.smoothHeight(); 823 } else if (carousel) { //CAROUSEL: 824 slider.slides.width(slider.computedW); 825 slider.update(slider.pagingCount); 826 slider.setProps(); 827 } 828 else if (vertical) { //VERTICAL: 829 slider.viewport.height(slider.h); 830 slider.setProps(slider.h, "setTotal"); 831 } else { 832 // SMOOTH HEIGHT: 833 if (slider.vars.smoothHeight) methods.smoothHeight(); 834 slider.newSlides.width(slider.computedW); 835 slider.setProps(slider.computedW, "setTotal"); 836 } 837 } 838 }, 839 smoothHeight: function(dur) { 840 if (!vertical || fade) { 841 var $obj = (fade) ? slider : slider.viewport; 842 (dur) ? $obj.animate({"height": slider.slides.eq(slider.animatingTo).height()}, dur) : $obj.height(slider.slides.eq(slider.animatingTo).height()); 843 } 844 }, 845 sync: function(action) { 846 var $obj = $(slider.vars.sync).data("flexslider"), 847 target = slider.animatingTo; 848 849 switch (action) { 850 case "animate": $obj.flexAnimate(target, slider.vars.pauseOnAction, false, true); break; 851 case "play": if (!$obj.playing && !$obj.asNav) { $obj.play(); } break; 852 case "pause": $obj.pause(); break; 853 } 854 }, 855 pauseInvisible: { 856 visProp: null, 857 init: function() { 858 var prefixes = ['webkit','moz','ms','o']; 859 860 if ('hidden' in document) return 'hidden'; 861 for (var i = 0; i < prefixes.length; i++) { 862 if ((prefixes[i] + 'Hidden') in document) 863 methods.pauseInvisible.visProp = prefixes[i] + 'Hidden'; 864 } 865 if (methods.pauseInvisible.visProp) { 866 var evtname = methods.pauseInvisible.visProp.replace(/[H|h]idden/,'') + 'visibilitychange'; 867 document.addEventListener(evtname, function() { 868 if (methods.pauseInvisible.isHidden()) { 869 if(slider.startTimeout) clearTimeout(slider.startTimeout); //If clock is ticking, stop timer and prevent from starting while invisible 870 else slider.pause(); //Or just pause 871 } 872 else { 873 if(slider.started) slider.play(); //Initiated before, just play 874 else (slider.vars.initDelay > 0) ? setTimeout(slider.play, slider.vars.initDelay) : slider.play(); //Didn't init before: simply init or wait for it 875 } 876 }); 877 } 878 }, 879 isHidden: function() { 880 return document[methods.pauseInvisible.visProp] || false; 881 } 882 }, 883 setToClearWatchedEvent: function() { 884 clearTimeout(watchedEventClearTimer); 885 watchedEventClearTimer = setTimeout(function() { 886 watchedEvent = ""; 887 }, 3000); 888 } 889 } 890 891 // public methods 892 slider.flexAnimate = function(target, pause, override, withSync, fromNav) { 893 if (!slider.vars.animationLoop && target !== slider.currentSlide) { 894 slider.direction = (target > slider.currentSlide) ? "next" : "prev"; 895 } 896 897 if (asNav && slider.pagingCount === 1) slider.direction = (slider.currentItem < target) ? "next" : "prev"; 898
899 if (!slider.animating && (slider.canAdvance(target, fromNav) || override) && slider.is(":visible")) { 900 if (asNav && withSync) { 901 var master = $(slider.vars.asNavFor).data('flexslider'); 902 slider.atEnd = target === 0 || target === slider.count - 1; 903 master.flexAnimate(target, true, false, true, fromNav); 904 slider.direction = (slider.currentItem < target) ? "next" : "prev"; 905 master.direction = slider.direction; 906 907 if (Math.ceil((target + 1)/slider.visible) - 1 !== slider.currentSlide && target !== 0) { 908 slider.currentItem = target; 909 slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide"); 910 target = Math.floor(target/slider.visible); 911 } else { 912 slider.currentItem = target; 913 slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide"); 914 return false; 915 } 916 } 917 918 slider.animating = true; 919 slider.animatingTo = target; 920 921 // SLIDESHOW: 922 if (pause) slider.pause(); 923 924 // API: before() animation Callback 925 slider.vars.before(slider); 926 927 // SYNC: 928 if (slider.syncExists && !fromNav) methods.sync("animate"); 929 930 // CONTROLNAV 931 if (slider.vars.controlNav) methods.controlNav.active(); 932 933 // !CAROUSEL: 934 // CANDIDATE: slide active class (for add/remove slide) 935 if (!carousel) slider.slides.removeClass(namespace + 'active-slide').eq(target).addClass(namespace + 'active-slide'); 936 937 // INFINITE LOOP: 938 // CANDIDATE: atEnd 939 slider.atEnd = target === 0 || target === slider.last; 940 941 // DIRECTIONNAV: 942 if (slider.vars.directionNav) methods.directionNav.update(); 943 944 if (target === slider.last) { 945 // API: end() of cycle Callback 946 slider.vars.end(slider); 947 // SLIDESHOW && !INFINITE LOOP: 948 if (!slider.vars.animationLoop) slider.pause(); 949 } 950 951 // SLIDE: 952 if (!fade) { 953 var dimension = (vertical) ? slider.slides.filter(':first').height() : slider.computedW, 954 margin, slideString, calcNext; 955 956 // INFINITE LOOP / REVERSE: 957 if (carousel) { 958 //margin = (slider.vars.itemWidth > slider.w) ? slider.vars.itemMargin * 2 : slider.vars.itemMargin; 959 margin = slider.vars.itemMargin; 960 calcNext = ((slider.itemW + margin) * slider.move) * slider.animatingTo; 961 slideString = (calcNext > slider.limit && slider.visible !== 1) ? slider.limit : calcNext; 962 } else if (slider.currentSlide === 0 && target === slider.count - 1 && slider.vars.animationLoop && slider.direction !== "next") { 963 slideString = (reverse) ? (slider.count + slider.cloneOffset) * dimension : 0; 964 } else if (slider.currentSlide === slider.last && target === 0 && slider.vars.animationLoop && slider.direction !== "prev") { 965 slideString = (reverse) ? 0 : (slider.count + 1) * dimension; 966 } else { 967 slideString = (reverse) ? ((slider.count - 1) - target + slider.cloneOffset) * dimension : (target + slider.cloneOffset) * dimension; 968 } 969 slider.setProps(slideString, "", slider.vars.animationSpeed); 970 if (slider.transitions) { 971 if (!slider.vars.animationLoop || !slider.atEnd) { 972 slider.animating = false; 973 slider.currentSlide = slider.animatingTo; 974 } 975 slider.container.unbind("webkitTransitionEnd transitionend"); 976 slider.container.bind("webkitTransitionEnd transitionend", function() { 977 slider.wrapup(dimension); 978 }); 979 } else { 980 slider.container.animate(slider.args, slider.vars.animationSpeed, slider.vars.easing, function(){ 981 slider.wrapup(dimension); 982 }); 983 } 984 } else { // FADE: 985 if (!touch) { 986 //slider.slides.eq(slider.currentSlide).fadeOut(slider.vars.animationSpeed, slider.vars.easing); 987 //slider.slides.eq(target).fadeIn(slider.vars.animationSpeed, slider.vars.easing, slider.wrapup); 988 989 slider.slides.eq(slider.currentSlide).css({"zIndex": 1}).animate({"opacity": 0}, slider.vars.animationSpeed, slider.vars.easing); 990 slider.slides.eq(target).css({"zIndex": 2}).animate({"opacity": 1}, slider.vars.animationSpeed, slider.vars.easing, slider.wrapup); 991 992 } else { 993 slider.slides.eq(slider.currentSlide).css({ "opacity": 0, "zIndex": 1 }); 994 slider.slides.eq(target).css({ "opacity": 1, "zIndex": 2 }); 995 slider.wrapup(dimension); 996 } 997 } 998 // SMOOTH HEIGHT: 999 if (slider.vars.smoothHeight) methods.smoothHeight(slider.vars.animationSpeed); 1000 } 1001 } 1002 slider.wrapup = function(dimension) { 1003 // SLIDE: 1004 if (!fade && !carousel) { 1005 if (slider.currentSlide === 0 && slider.animatingTo === slider.last && slider.vars.animationLoop) { 1006 slider.setProps(dimension, "jumpEnd"); 1007 } else if (slider.currentSlide === slider.last && slider.animatingTo === 0 && slider.vars.animationLoop) { 1008 slider.setProps(dimension, "jumpStart"); 1009 } 1010 } 1011 slider.animating = false; 1012 slider.currentSlide = slider.animatingTo; 1013 // API: after() animation Callback 1014 slider.vars.after(slider); 1015 } 1016 1017 // SLIDESHOW: 1018 slider.animateSlides = function() { 1019 if (!slider.animating && focused ) slider.flexAnimate(slider.getTarget("next")); 1020 } 1021 // SLIDESHOW: 1022 slider.pause = function() { 1023 clearInterval(slider.animatedSlides); 1024 slider.animatedSlides = null; 1025 slider.playing = false; 1026 // PAUSEPLAY: 1027 if (slider.vars.pausePlay) methods.pausePlay.update("play"); 1028 // SYNC: 1029 if (slider.syncExists) methods.sync("pause"); 1030 } 1031 // SLIDESHOW: 1032 slider.play = function() { 1033 if (slider.playing) clearInterval(slider.animatedSlides); 1034 slider.animatedSlides = slider.animatedSlides || setInterval(slider.animateSlides, slider.vars.slideshowSpeed); 1035 slider.started = slider.playing = true; 1036 // PAUSEPLAY: 1037 if (slider.vars.pausePlay) methods.pausePlay.update("pause"); 1038 // SYNC: 1039 if (slider.syncExists) methods.sync("play"); 1040 } 1041 // STOP: 1042 slider.stop = function () { 1043 slider.pause(); 1044 slider.stopped = true; 1045 }
1046 slider.canAdvance = function(target, fromNav) { 1047 // ASNAV: 1048 var last = (asNav) ? slider.pagingCount - 1 : slider.last; 1049 return (fromNav) ? true : 1050 (asNav && slider.currentItem === slider.count - 1 && target === 0 && slider.direction === "prev") ? true : 1051 (asNav && slider.currentItem === 0 && target === slider.pagingCount - 1 && slider.direction !== "next") ? false : 1052 (target === slider.currentSlide && !asNav) ? false : 1053 (slider.vars.animationLoop) ? true : 1054 (slider.atEnd && slider.currentSlide === 0 && target === last && slider.direction !== "next") ? false : 1055 (slider.atEnd && slider.currentSlide === last && target === 0 && slider.direction === "next") ? false : 1056 true; 1057 } 1058 slider.getTarget = function(dir) { 1059 slider.direction = dir; 1060 if (dir === "next") { 1061 return (slider.currentSlide === slider.last) ? 0 : slider.currentSlide + 1; 1062 } else { 1063 return (slider.currentSlide === 0) ? slider.last : slider.currentSlide - 1; 1064 } 1065 } 1066 1067 // SLIDE: 1068 slider.setProps = function(pos, special, dur) { 1069 var target = (function() { 1070 var posCheck = (pos) ? pos : ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo, 1071 posCalc = (function() { 1072 if (carousel) { 1073 return (special === "setTouch") ? pos : 1074 (reverse && slider.animatingTo === slider.last) ? 0 : 1075 (reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) : 1076 (slider.animatingTo === slider.last) ? slider.limit : posCheck; 1077 } else { 1078 switch (special) { 1079 case "setTotal": return (reverse) ? ((slider.count - 1) - slider.currentSlide + slider.cloneOffset) * pos : (slider.currentSlide + slider.cloneOffset) * pos; 1080 case "setTouch": return (reverse) ? pos : pos; 1081 case "jumpEnd": return (reverse) ? pos : slider.count * pos; 1082 case "jumpStart": return (reverse) ? slider.count * pos : pos; 1083 default: return pos; 1084 } 1085 } 1086 }()); 1087 1088 return (posCalc * -1) + "px"; 1089 }()); 1090 1091 if (slider.transitions) { 1092 target = (vertical) ? "translate3d(0," + target + ",0)" : "translate3d(" + target + ",0,0)"; 1093 dur = (dur !== undefined) ? (dur/1000) + "s" : "0s"; 1094 slider.container.css("-" + slider.pfx + "-transition-duration", dur); 1095 } 1096 1097 slider.args[slider.prop] = target; 1098 if (slider.transitions || dur === undefined) slider.container.css(slider.args); 1099 } 1100 1101 slider.setup = function(type) { 1102 // SLIDE: 1103 if (!fade) { 1104 var sliderOffset, arr; 1105 1106 if (type === "init") { 1107 slider.viewport = $('<div class="' + namespace + 'viewport"></div>').css({"overflow": "hidden", "position": "relative"}).appendTo(slider).append(slider.container); 1108 // INFINITE LOOP: 1109 slider.cloneCount = 0; 1110 slider.cloneOffset = 0; 1111 // REVERSE: 1112 if (reverse) { 1113 arr = $.makeArray(slider.slides).reverse(); 1114 slider.slides = $(arr); 1115 slider.container.empty().append(slider.slides); 1116 } 1117 } 1118 // INFINITE LOOP && !CAROUSEL: 1119 if (slider.vars.animationLoop && !carousel) { 1120 slider.cloneCount = 2; 1121 slider.cloneOffset = 1; 1122 // clear out old clones 1123 if (type !== "init") slider.container.find('.clone').remove(); 1124 slider.container.append(slider.slides.first().clone().addClass('clone').attr('aria-hidden', 'true')).prepend(slider.slides.last().clone().addClass('clone').attr('aria-hidden', 'true')); 1125 } 1126 slider.newSlides = $(slider.vars.selector, slider); 1127 1128 sliderOffset = (reverse) ? slider.count - 1 - slider.currentSlide + slider.cloneOffset : slider.currentSlide + slider.cloneOffset; 1129 // VERTICAL: 1130 if (vertical && !carousel) { 1131 slider.container.height((slider.count + slider.cloneCount) * 200 + "%").css("position", "absolute").width("100%"); 1132 setTimeout(function(){ 1133 slider.newSlides.css({"display": "block"}); 1134 slider.doMath(); 1135 slider.viewport.height(slider.h); 1136 slider.setProps(sliderOffset * slider.h, "init"); 1137 }, (type === "init") ? 100 : 0); 1138 } else { 1139 slider.container.width((slider.count + slider.cloneCount) * 200 + "%"); 1140 slider.setProps(sliderOffset * slider.computedW, "init"); 1141 setTimeout(function(){ 1142 slider.doMath(); 1143 slider.newSlides.css({"width": slider.computedW, "float": "left", "display": "block"}); 1144 // SMOOTH HEIGHT: 1145 if (slider.vars.smoothHeight) methods.smoothHeight(); 1146 }, (type === "init") ? 100 : 0); 1147 } 1148 } else { // FADE: 1149 slider.slides.css({"width": "100%", "float": "left", "marginRight": "-100%", "position": "relative"}); 1150 if (type === "init") { 1151 if (!touch) { 1152 //slider.slides.eq(slider.currentSlide).fadeIn(slider.vars.animationSpeed, slider.vars.easing); 1153 slider.slides.css({ "opacity": 0, "display": "block", "zIndex": 1 }).eq(slider.currentSlide).css({"zIndex": 2}).animate({"opacity": 1},slider.vars.animationSpeed,slider.vars.easing); 1154 } else { 1155 slider.slides.css({ "opacity": 0, "display": "block", "webkitTransition": "opacity " + slider.vars.animationSpeed / 1000 + "s ease", "zIndex": 1 }).eq(slider.currentSlide).css({ "opacity": 1, "zIndex": 2}); 1156 } 1157 } 1158 // SMOOTH HEIGHT: 1159 if (slider.vars.smoothHeight) methods.smoothHeight(); 1160 } 1161 // !CAROUSEL: 1162 // CANDIDATE: active slide 1163 if (!carousel) slider.slides.removeClass(namespace + "active-slide").eq(slider.currentSlide).addClass(namespace + "active-slide"); 1164 } 1165 1166 1167 slider.doMath = function() { 1168 var slide = slider.slides.first(), 1169 slideMargin = slider.vars.itemMargin, 1170 minItems = slider.vars.minItems, 1171 maxItems = slider.vars.maxItems; 1172
vendor: 8,049 bytes, lines 1173-1328
1173 slider.w = (slider.viewport===undefined) ? slider.width() : slider.viewport.width(); 1174 slider.h = slide.height(); 1175 slider.boxPadding = slide.outerWidth() - slide.width(); 1176 1177 // CAROUSEL: 1178 if (carousel) { 1179 slider.itemT = slider.vars.itemWidth + slideMargin; 1180 slider.minW = (minItems) ? minItems * slider.itemT : slider.w; 1181 slider.maxW = (maxItems) ? (maxItems * slider.itemT) - slideMargin : slider.w; 1182 slider.itemW = (slider.minW > slider.w) ? (slider.w - (slideMargin * (minItems - 1)))/minItems : 1183 (slider.maxW < slider.w) ? (slider.w - (slideMargin * (maxItems - 1)))/maxItems : 1184 (slider.vars.itemWidth > slider.w) ? slider.w : slider.vars.itemWidth; 1185 1186 slider.visible = Math.floor(slider.w/(slider.itemW)); 1187 slider.move = (slider.vars.move > 0 && slider.vars.move < slider.visible ) ? slider.vars.move : slider.visible; 1188 slider.pagingCount = Math.ceil(((slider.count - slider.visible)/slider.move) + 1); 1189 slider.last = slider.pagingCount - 1; 1190 slider.limit = (slider.pagingCount === 1) ? 0 : 1191 (slider.vars.itemWidth > slider.w) ? (slider.itemW * (slider.count - 1)) + (slideMargin * (slider.count - 1)) : ((slider.itemW + slideMargin) * slider.count) - slider.w - slideMargin; 1192 } else { 1193 slider.itemW = slider.w; 1194 slider.pagingCount = slider.count; 1195 slider.last = slider.count - 1; 1196 } 1197 slider.computedW = slider.itemW - slider.boxPadding; 1198 } 1199 1200 1201 slider.update = function(pos, action) { 1202 slider.doMath(); 1203 1204 // update currentSlide and slider.animatingTo if necessary 1205 if (!carousel) { 1206 if (pos < slider.currentSlide) { 1207 slider.currentSlide += 1; 1208 } else if (pos <= slider.currentSlide && pos !== 0) { 1209 slider.currentSlide -= 1; 1210 } 1211 slider.animatingTo = slider.currentSlide; 1212 } 1213 1214 // update controlNav 1215 if (slider.vars.controlNav && !slider.manualControls) { 1216 if ((action === "add" && !carousel) || slider.pagingCount > slider.controlNav.length) { 1217 methods.controlNav.update("add"); 1218 } else if ((action === "remove" && !carousel) || slider.pagingCount < slider.controlNav.length) { 1219 if (carousel && slider.currentSlide > slider.last) { 1220 slider.currentSlide -= 1; 1221 slider.animatingTo -= 1; 1222 } 1223 methods.controlNav.update("remove", slider.last); 1224 } 1225 } 1226 // update directionNav 1227 if (slider.vars.directionNav) methods.directionNav.update(); 1228 1229 } 1230 1231 slider.addSlide = function(obj, pos) { 1232 var $obj = $(obj); 1233 1234 slider.count += 1; 1235 slider.last = slider.count - 1; 1236 1237 // append new slide 1238 if (vertical && reverse) { 1239 (pos !== undefined) ? slider.slides.eq(slider.count - pos).after($obj) : slider.container.prepend($obj); 1240 } else { 1241 (pos !== undefined) ? slider.slides.eq(pos).before($obj) : slider.container.append($obj); 1242 } 1243 1244 // update currentSlide, animatingTo, controlNav, and directionNav 1245 slider.update(pos, "add"); 1246 1247 // update slider.slides 1248 slider.slides = $(slider.vars.selector + ':not(.clone)', slider); 1249 // re-setup the slider to accomdate new slide 1250 slider.setup(); 1251 1252 //FlexSlider: added() Callback 1253 slider.vars.added(slider); 1254 } 1255 slider.removeSlide = function(obj) { 1256 var pos = (isNaN(obj)) ? slider.slides.index($(obj)) : obj; 1257 1258 // update count 1259 slider.count -= 1; 1260 slider.last = slider.count - 1; 1261 1262 // remove slide 1263 if (isNaN(obj)) { 1264 $(obj, slider.slides).remove(); 1265 } else { 1266 (vertical && reverse) ? slider.slides.eq(slider.last).remove() : slider.slides.eq(obj).remove(); 1267 } 1268 1269 // update currentSlide, animatingTo, controlNav, and directionNav 1270 slider.doMath(); 1271 slider.update(pos, "remove"); 1272 1273 // update slider.slides 1274 slider.slides = $(slider.vars.selector + ':not(.clone)', slider); 1275 // re-setup the slider to accomdate new slide 1276 slider.setup(); 1277 1278 // FlexSlider: removed() Callback 1279 slider.vars.removed(slider); 1280 } 1281 1282 //FlexSlider: Initialize 1283 methods.init(); 1284 } 1285 1286 // Ensure the slider isn't focussed if the window loses focus. 1287 $( window ).blur( function ( e ) { 1288 focused = false; 1289 }).focus( function ( e ) { 1290 focused = true; 1291 }); 1292 1293 //FlexSlider: Default Settings 1294 $.flexslider.defaults = { 1295 namespace: "flex-", //{NEW} String: Prefix string attached to the class of every element generated by the plugin 1296 selector: ".slides > li", //{NEW} Selector: Must match a simple pattern. '{container} > {slide}' -- Ignore pattern at your own peril 1297 animation: "fade", //String: Select your animation type, "fade" or "slide" 1298 easing: "swing", //{NEW} String: Determines the easing method used in jQuery transitions. jQuery easing plugin is supported! 1299 direction: "horizontal", //String: Select the sliding direction, "horizontal" or "vertical" 1300 reverse: false, //{NEW} Boolean: Reverse the animation direction 1301 animationLoop: true, //Boolean: Should the animation loop? If false, directionNav will received "disable" classes at either end 1302 smoothHeight: false, //{NEW} Boolean: Allow height of the slider to animate smoothly in horizontal mode 1303 startAt: 0, //Integer: The slide that the slider should start on. Array notation (0 = first slide) 1304 slideshow: true, //Boolean: Animate slider automatically 1305 slideshowSpeed: 7000, //Integer: Set the speed of the slideshow cycling, in milliseconds 1306 animationSpeed: 600, //Integer: Set the speed of animations, in milliseconds 1307 initDelay: 0, //{NEW} Integer: Set an initialization delay, in milliseconds 1308 randomize: false, //Boolean: Randomize slide order 1309 thumbCaptions: false, //Boolean: Whether or not to put captions on thumbnails when using the "thumbnails" controlNav. 1310 1311 // Usability features 1312 pauseOnAction: true, //Boolean: Pause the slideshow when interacting with control elements, highly recommended. 1313 pauseOnHover: false, //Boolean: Pause the slideshow when hovering over slider, then resume when no longer hovering 1314 pauseInvisible: true, //{NEW} Boolean: Pause the slideshow when tab is invisible, resume when visible. Provides better UX, lower CPU usage. 1315 useCSS: true, //{NEW} Boolean: Slider will use CSS3 transitions if available 1316 touch: true, //{NEW} Boolean: Allow touch swipe navigation of the slider on touch-enabled devices 1317 video: false, //{NEW} Boolean: If using video in the slider, will prevent CSS3 3D Transforms to avoid graphical glitches 1318 1319 // Primary Controls 1320 controlNav: true, //Boolean: Create navigation for paging control of each clide? Note: Leave true for manualControls usage 1321 directionNav: true, //Boolean: Create navigation for previous/next navigation? (true/false) 1322 prevText: "Previous", //String: Set the text for the "previous" directionNav item 1323 nextText: "Next", //String: Set the text for the "next" directionNav item 1324 1325 // Secondary Navigation 1326 keyboard: true, //Boolean: Allow slider navigating via keyboard left/right keys 1327 multipleKeyboard: false, //{NEW} Boolean: Allow keyboard navigation to affect multiple sliders. Default behavior cuts out keyboard navigation with more than one slider present. 1328 mousewheel: false, //{UPDATED} Boolean: Requires jquery.mousewheel.js (https://github.com/brandonaaron/jquery-mousewheel) - Allows slider navigating via mousewheel
1329 pausePlay: false, //Boolean: Create pause/play dynamic element 1330 pauseText: "Pause", //String: Set the text for the "pause" pausePlay item 1331 playText: "Play", //String: Set the text for the "play" pausePlay item 1332 1333 // Special properties 1334 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. 1335 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. 1336 sync: "", //{NEW} Selector: Mirror the actions performed on this slider with another slider. Use with care. 1337 asNavFor: "", //{NEW} Selector: Internal property exposed for turning the slider into a thumbnail navigation for another slider 1338 1339 // Carousel Options 1340 itemWidth: 0, //{NEW} Integer: Box-model width of individual carousel items, including horizontal borders and padding. 1341 itemMargin: 0, //{NEW} Integer: Margin between carousel items. 1342 minItems: 1, //{NEW} Integer: Minimum number of carousel items that should be visible. Items will resize fluidly when below this. 1343 maxItems: 0, //{NEW} Integer: Maxmimum number of carousel items that should be visible. Items will resize fluidly when above this limit. 1344 move: 0, //{NEW} Integer: Number of carousel items that should move on animation. If 0, slider will move all visible items. 1345 allowOneSlide: true, //{NEW} Boolean: Whether or not to allow a slider comprised of a single slide 1346 1347 // Callback API 1348 start: function(){}, //Callback: function(slider) - Fires when the slider loads the first slide 1349 before: function(){}, //Callback: function(slider) - Fires asynchronously with each slider animation 1350 after: function(){}, //Callback: function(slider) - Fires after each slider animation completes 1351 end: function(){}, //Callback: function(slider) - Fires when the slider reaches the last slide (asynchronous) 1352 added: function(){}, //{NEW} Callback: function(slider) - Fires after a slide is added 1353 removed: function(){} //{NEW} Callback: function(slider) - Fires after a slide is removed 1354 } 1355 1356 1357 //FlexSlider: Plugin Function 1358 $.fn.flexslider = function(options) { 1359 if (options === undefined) options = {}; 1360 1361 if (typeof options === "object") { 1362 return this.each(function() { 1363 var $this = $(this), 1364 selector = (options.selector) ? options.selector : ".slides > li", 1365 $slides = $this.find(selector); 1366 1367 if ( ( $slides.length === 1 && options.allowOneSlide === true ) || $slides.length === 0 ) { 1368 $slides.fadeIn(400); 1369 if (options.start) options.start($this); 1370 } else if ($this.data('flexslider') === undefined) { 1371 new $.flexslider(this, options); 1372 } 1373 }); 1374 } else { 1375 // Helper strings to quickly perform functions on the slider 1376 var $slider = $(this).data('flexslider'); 1377 switch (options) { 1378 case "play": $slider.play(); break; 1379 case "pause": $slider.pause(); break; 1380 case "stop": $slider.stop(); break; 1381 case "next": $slider.flexAnimate($slider.getTarget("next"), true); break; 1382 case "prev": 1383 case "previous": $slider.flexAnimate($slider.getTarget("prev"), true); break; 1384 default: if (typeof options === "number") $slider.flexAnimate(options, true); 1385 } 1386 } 1387 } 1388})(jQuery); 1389 1390 1391/** 1392 * Tayfun Erbilen - jQuery Slider Plugin (pSlider) 1393 */ 1394jQuery.fn.pSlider = function(settings){ 1395 1396 // eklenti ayarları 1397 var config = jQuery.extend({ 1398 slider: null, 1399 button: { 1400 prev: null, 1401 next: null 1402 }, 1403 visible: 1, 1404 width: null, 1405 height: null, 1406 extra: 0, 1407 direction: 'horizontal', 1408 duration: 1000, 1409 loop: false, 1410 easing: null, 1411 start: null, 1412 animation: true, 1413 skip: 1,
1414 auto: false, 1415 time: 1000, 1416 keyboard: false, 1417 pagination: null, 1418 list: null, 1419 callback: function(){}, 1420 callbackStart: function(){}, 1421 callbackEnd: function(){} 1422 }, settings); 1423 1424 var that = this; 1425 1426 // callback 1427 if ( config.start === 0 || config.start === null ) config.callbackStart(); 1428 1429 // eğer genişlik değeri verilmemiş ise otomatik al 1430 if ( config.direction === 'horizontal' && config.width === null ) 1431 config.width = config.slider.outerWidth() + config.extra; 1432 1433 // eğer yükseklik değeri verilmemiş ise otomatik al 1434 if ( config.direction === 'vertical' && config.height === null ) 1435 config.height = config.slider.outerHeight() + config.extra; 1436 1437 // animasyon çalışırken değeri true, çalışmıyorken değeri false olacak 1438 this.animated = false; 1439 1440 // slider için toplam eleman sayısı 1441 this.total = config.slider.length; 1442 1443 // slider elemanlarının üst nesnesi 1444 this.parent = config.slider.parent(); 1445 1446 // ana slider nesnesini her ihtimale karşı gizleyelim 1447 this.css('overflow', 'hidden'); 1448 1449 // slider nesnelerine genişlik ve ya yükseklik ata 1450 if ( config.direction === 'horizontal' ) config.slider.width( config.width ); 1451 else if ( config.direction === 'vertical' ) config.slider.height( config.height ); 1452 1453 // eğer yatay slider ise 1454 if ( config.direction === 'horizontal' ){ 1455 1456 // slider elemanlarını yan yana getirelim 1457 config.slider.css('float','left'); 1458 1459 // slider elemanlarının üst nesnesine toplam genişliği verelim 1460 this.parent.width( (config.width * this.total) + (config.extra * this.total) ); 1461 1462 } 1463 1464 // eğer dikey slider ise 1465 else if ( config.direction === 'vertical' ){ 1466 1467 // slider elemanlarının üst nesnesine toplam yüksekliği verelim 1468 this.parent.height( (config.height * this.total) + (config.extra * this.total) ); 1469 1470 } 1471 1472 // eğer sayfalama seçilmiş ise 1473 if ( config.pagination ){ 1474 if ( that.total === 1 ){ 1475 config.pagination.hide(); 1476 } else { 1477 1478 for ( var i = 1; i <= that.total; i++ ){ 1479 config.pagination.append('<a href="#"' + (i === 1 ? ' class="active"' : null) + '>' + i + '</a>'); 1480 } 1481 1482 config.pagination.find('a').on('click', function(e){ 1483 config.start = $(this).index(); 1484 that.animation('text'); 1485 e.preventDefault(); 1486 }); 1487 1488 } 1489 } 1490 1491 // eğer liste seçilmiş ise 1492 if ( config.list ){ 1493 config.list.filter(':first').addClass('active'); 1494 config.list.on('click', function(e){ 1495 config.start = $(this).index(); 1496 that.animation('text'); 1497 e.preventDefault(); 1498 }); 1499 } 1500 1501 // animasyon işlemi 1502 this.animation = function(button){ 1503 1504 // eğer animasyon çalışmıyorsa 1505 if ( that.animated === false ){ 1506 1507 // animasyonun çalıştığını söyle 1508 that.animated = true; 1509 1510 if ( button === 'next' ){ 1511 1512 // eğer mevcut değer toplam - görünen elemanlardan küçük ise işleme devam et 1513 if ( config.start < that.total - config.visible ){ 1514 1515 // mevcut değeri hesapla 1516 config.start = config.start + config.skip; 1517 1518 // eğer hesaplanan değer toplam - görünen eleman sayısından büyük ise tekrardan değer ataması yap 1519 if ( config.start > that.total - config.visible ) config.start = that.total - config.visible; 1520 1521 } 1522 // değilse ve döngü var ise mevcut değeri 0'a eşitle 1523 else { 1524 if ( config.loop ) config.start = 0; 1525 else that.animated = false; 1526 } 1527 1528 } else if ( button === 'prev' ){ 1529 1530 // eğer mevcut değer 0'dan büyük ise azaltmaya devam et 1531 if ( config.start > 0 ){ 1532 1533 // mevcut değeri hesapla 1534 config.start = config.start - config.skip; 1535 1536 // eğer hesaplanan değer 0'dan küçük ise değeri tekrar 0'a eşitle 1537 if ( config.start < 0 ) config.start = 0; 1538 1539 } 1540 // değilse ve döngü var ise mevcut değeri toplam eksik görünen eleman sayısıne eşitle 1541 else { 1542 if ( config.loop ) config.start = that.total - config.visible; 1543 else that.animated = false; 1544 } 1545 1546 } 1547 1548 if ( config.direction === 'horizontal' ){ 1549 that.obj = {marginLeft: '-' + ( (config.start * config.width) + (config.extra * config.start) )}; 1550 } 1551 else if ( config.direction === 'vertical' ){ 1552 that.obj = {marginTop: '-' + ( (config.start * config.height) + (config.extra * config.start) )}; 1553 } 1554 1555 that.parent.stop().animate(that.obj, { 1556 duration: config.duration, 1557 complete: function(){ 1558 1559 // animasyonun çalışmadığını söyle 1560 that.animated = false; 1561 1562 // sayfalama aktif ise 1563 if ( config.pagination ){
1564 config.pagination.find('a').removeClass('active').eq(config.start).addClass('active'); 1565 } 1566 1567 // liste aktif ise 1568 if ( config.list ){ 1569 config.list.removeClass('active').eq(config.start).addClass('active'); 1570 } 1571 1572 }, 1573 easing: (config.easing) ? config.easing : null 1574 }); 1575 1576 // callback 1577 if ( config.start === that.total - config.visible ) config.callbackEnd(); 1578 else if ( config.start === 0 || config.start === null ) config.callbackStart(); 1579 else config.callback(); 1580 1581 } 1582 1583 }; 1584 1585 if ( config.button.next ){ 1586 config.button.next.on('click', function(e){ 1587 that.animation('next'); 1588 e.preventDefault(); 1589 }); 1590 } 1591 1592 if ( config.button.prev ){ 1593 config.button.prev.on('click', function(e){ 1594 that.animation('prev'); 1595 e.preventDefault(); 1596 }); 1597 } 1598 1599 // eğer başlangıç değişecek ise kontrol et 1600 if ( config.start > 0 ){ 1601 1602 config.start = config.start - 1; 1603 1604 // eğer girilen başlangıç değeri toplam değerden büyük ise başlangıç değerini otomatik olarak toplam değer yap 1605 if ( config.start > this.total ) config.start = this.total; 1606 1607 // eğer başlangıç değerine animasyonlu şekilde geçiş yapacak ise burayı çalıştır 1608 if ( config.animation ){ 1609 this.animation('next'); 1610 } 1611 // görünmeden yapacak isede burayı çalıştır, dikey ve yataya göre hesapla 1612 else { 1613 1614 config.start = config.start + 1; 1615 1616 if ( config.direction === 'horizontal' ) 1617 this.parent.css('margin-left', '-' + ( (config.start) * config.width ) + 'px'); 1618 else if ( config.direction === 'vertical' ) 1619 this.parent.css('margin-top', '-' + ( (config.start) * config.height ) + 'px'); 1620 1621 // sayfalama aktif ise 1622 if ( config.pagination ){ 1623 config.pagination.find('a').removeClass('active').eq(config.start).addClass('active'); 1624 } 1625 1626 // liste aktif ise 1627 if ( config.list ){ 1628 config.list.removeClass('active').eq(config.start).addClass('active'); 1629 } 1630 1631 } 1632 } 1633 1634 // klavye kontrolü 1635 if ( config.keyboard ){ 1636 this.keyboard = function(event){ 1637 var key = event.which || event.keyCode; 1638 if ( config.direction === 'horizontal' ){ 1639 if ( key === 37 ) that.animation('prev'); 1640 else if ( key === 39 ) that.animation('next'); 1641 } else if ( config.direction === 'vertical' ){ 1642 if ( key === 40 ) that.animation('prev'); 1643 else if ( key === 38 ) that.animation('next'); 1644 } 1645 return false; 1646 }; 1647 this.hover(function(){ 1648 $(document).on('keydown', that.keyboard); 1649 }, function(){ 1650 $(document).off('keydown', that.keyboard); 1651 }); 1652 } 1653 1654 // eğer otomatik dönme var ise 1655 if ( config.auto ){ 1656 1657 // otomatik döngüyü aktif et 1658 config.loop = true; 1659 1660 // otomatik döndürme işlemini başlat 1661 this.interval = setInterval(function(){ 1662 that.animation('next'); 1663 }, config.time); 1664 1665 this.hover(function(){ 1666 clearInterval(that.interval); 1667 that.interval = null; 1668 }, function(){ 1669 that.interval = setInterval(function(){ 1670 that.animation('next'); 1671 }, config.time); 1672 }); 1673 1674 } 1675 1676 // yeniden boyutlandırma 1677 this.bind('resize', function(event, arg){ 1678 that.animated = false; 1679 config.start = config.start + 1; 1680 arg = jQuery.extend(config, arg); 1681 $(this).pSlider(arg); 1682 }); 1683 1684}; 1685 1686 1687 1688/*! 1689 * fancyBox - jQuery Plugin 1690 * version: 2.1.5 (Fri, 14 Jun 2013) 1691 * @requires jQuery v1.6 or later 1692 * 1693 * Examples at http://fancyapps.com/fancybox/ 1694 * License: www.fancyapps.com/fancybox/#license 1695 * 1696 * Copyright 2012 Janis Skarnelis - [email protected] 1697 * 1698 */ 1699 1700(function (window, document, $, undefined) { 1701 "use strict"; 1702 1703 var H = $("html"), 1704 W = $(window), 1705 D = $(document), 1706 F = $.fancybox = function () { 1707 F.open.apply( this, arguments ); 1708 }, 1709 IE = navigator.userAgent.match(/msie/i), 1710 didUpdate = null, 1711 isTouch = document.createTouch !== undefined, 1712 1713 isQuery = function(obj) { 1714 return obj && obj.hasOwnProperty && obj instanceof $; 1715 }, 1716 isString = function(str) { 1717 return str && $.type(str) === "string"; 1718 }, 1719 isPercentage = function(str) { 1720 return isString(str) && str.indexOf('%') > 0;
vendor: 41,558 bytes, lines 1721-3376
1721 }, 1722 isScrollable = function(el) { 1723 return (el && !(el.style.overflow && el.style.overflow === 'hidden') && ((el.clientWidth && el.scrollWidth > el.clientWidth) || (el.clientHeight && el.scrollHeight > el.clientHeight))); 1724 }, 1725 getScalar = function(orig, dim) { 1726 var value = parseInt(orig, 10) || 0; 1727 1728 if (dim && isPercentage(orig)) { 1729 value = F.getViewport()[ dim ] / 100 * value; 1730 } 1731 1732 return Math.ceil(value); 1733 }, 1734 getValue = function(value, dim) { 1735 return getScalar(value, dim) + 'px'; 1736 }; 1737 1738 $.extend(F, { 1739 // The current version of fancyBox 1740 version: '2.1.5', 1741 1742 defaults: { 1743 padding : 15, 1744 margin : 20, 1745 1746 width : 800, 1747 height : 600, 1748 minWidth : 100, 1749 minHeight : 100, 1750 maxWidth : 9999, 1751 maxHeight : 9999, 1752 pixelRatio: 1, // Set to 2 for retina display support 1753 1754 autoSize : true, 1755 autoHeight : false, 1756 autoWidth : false, 1757 1758 autoResize : true, 1759 autoCenter : !isTouch, 1760 fitToView : true, 1761 aspectRatio : false, 1762 topRatio : 0.5, 1763 leftRatio : 0.5, 1764 1765 scrolling : 'auto', // 'auto', 'yes' or 'no' 1766 wrapCSS : '', 1767 1768 arrows : true, 1769 closeBtn : true, 1770 closeClick : false, 1771 nextClick : false, 1772 mouseWheel : true, 1773 autoPlay : false, 1774 playSpeed : 3000, 1775 preload : 3, 1776 modal : false, 1777 loop : true, 1778 1779 ajax : { 1780 dataType : 'html', 1781 headers : { 'X-fancyBox': true } 1782 }, 1783 iframe : { 1784 scrolling : 'auto', 1785 preload : true 1786 }, 1787 swf : { 1788 wmode: 'transparent', 1789 allowfullscreen : 'true', 1790 allowscriptaccess : 'always' 1791 }, 1792 1793 keys : { 1794 next : { 1795 13 : 'left', // enter 1796 34 : 'up', // page down 1797 39 : 'left', // right arrow 1798 40 : 'up' // down arrow 1799 }, 1800 prev : { 1801 8 : 'right', // backspace 1802 33 : 'down', // page up 1803 37 : 'right', // left arrow 1804 38 : 'down' // up arrow 1805 }, 1806 close : [27], // escape key 1807 play : [32], // space - start/stop slideshow 1808 toggle : [70] // letter "f" - toggle fullscreen 1809 }, 1810 1811 direction : { 1812 next : 'left', 1813 prev : 'right' 1814 }, 1815 1816 scrollOutside : true, 1817 1818 // Override some properties 1819 index : 0, 1820 type : null, 1821 href : null, 1822 content : null, 1823 title : null, 1824 1825 // HTML templates 1826 tpl: { 1827 wrap : '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>', 1828 image : '<img class="fancybox-image" src="{href}" alt="" />', 1829 iframe : '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen' + (IE ? ' allowtransparency="true"' : '') + '></iframe>', 1830 error : '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>', 1831 closeBtn : '<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"></a>', 1832 next : '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>', 1833 prev : '<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span></span></a>' 1834 }, 1835 1836 // Properties for each animation type 1837 // Opening fancyBox 1838 openEffect : 'fade', // 'elastic', 'fade' or 'none' 1839 openSpeed : 250, 1840 openEasing : 'swing', 1841 openOpacity : true, 1842 openMethod : 'zoomIn', 1843 1844 // Closing fancyBox 1845 closeEffect : 'fade', // 'elastic', 'fade' or 'none' 1846 closeSpeed : 250, 1847 closeEasing : 'swing', 1848 closeOpacity : true, 1849 closeMethod : 'zoomOut', 1850 1851 // Changing next gallery item 1852 nextEffect : 'elastic', // 'elastic', 'fade' or 'none' 1853 nextSpeed : 250, 1854 nextEasing : 'swing', 1855 nextMethod : 'changeIn', 1856 1857 // Changing previous gallery item 1858 prevEffect : 'elastic', // 'elastic', 'fade' or 'none' 1859 prevSpeed : 250, 1860 prevEasing : 'swing', 1861 prevMethod : 'changeOut', 1862 1863 // Enable default helpers 1864 helpers : { 1865 overlay : true, 1866 title : true 1867 }, 1868 1869 // Callbacks 1870 onCancel : $.noop, // If canceling 1871 beforeLoad : $.noop, // Before loading 1872 afterLoad : $.noop, // After loading 1873 beforeShow : $.noop, // Before changing in current item 1874 afterShow : $.noop, // After opening 1875 beforeChange : $.noop, // Before changing gallery item 1876 beforeClose : $.noop, // Before closing 1877 afterClose : $.noop // After closing 1878 }, 1879 1880 //Current state 1881 group : {}, // Selected group 1882 opts : {}, // Group options 1883 previous : null, // Previous element 1884 coming : null, // Element being loaded 1885 current : null, // Currently loaded element 1886 isActive : false, // Is activated 1887 isOpen : false, // Is currently open 1888 isOpened : false, // Have been fully opened at least once 1889 1890 wrap : null, 1891 skin : null, 1892 outer : null, 1893 inner : null, 1894 1895 player : { 1896 timer : null, 1897 isActive : false 1898 }, 1899 1900 // Loaders 1901 ajaxLoad : null, 1902 imgPreload : null, 1903 1904 // Some collections 1905 transitions : {}, 1906 helpers : {}, 1907 1908 /* 1909 * Static methods 1910 */ 1911 1912 open: function (group, opts) { 1913 if (!group) { 1914 return; 1915 } 1916 1917 if (!$.isPlainObject(opts)) { 1918 opts = {}; 1919 } 1920 1921 // Close if already active 1922 if (false === F.close(true)) { 1923 return; 1924 } 1925 1926 // Normalize group 1927 if (!$.isArray(group)) { 1928 group = isQuery(group) ? $(group).get() : [group]; 1929 } 1930 1931 // Recheck if the type of each element is `object` and set content type (image, ajax, etc) 1932 $.each(group, function(i, element) { 1933 var obj = {}, 1934 href, 1935 title, 1936 content, 1937 type, 1938 rez, 1939 hrefParts, 1940 selector; 1941 1942 if ($.type(element) === "object") { 1943 // Check if is DOM element 1944 if (element.nodeType) { 1945 element = $(element); 1946 } 1947 1948 if (isQuery(element)) { 1949 obj = { 1950 href : element.data('fancybox-href') || element.attr('href'), 1951 title : element.data('fancybox-title') || element.attr('title'), 1952 isDom : true, 1953 element : element 1954 }; 1955 1956 if ($.metadata) { 1957 $.extend(true, obj, element.metadata()); 1958 } 1959 1960 } else { 1961 obj = element; 1962 } 1963 } 1964 1965 href = opts.href || obj.href || (isString(element) ? element : null); 1966 title = opts.title !== undefined ? opts.title : obj.title || ''; 1967 1968 content = opts.content || obj.content; 1969 type = content ? 'html' : (opts.type || obj.type); 1970 1971 if (!type && obj.isDom) { 1972 type = element.data('fancybox-type'); 1973 1974 if (!type) { 1975 rez = element.prop('class').match(/fancybox\.(\w+)/); 1976 type = rez ? rez[1] : null; 1977 } 1978 } 1979 1980 if (isString(href)) { 1981 // Try to guess the content type 1982 if (!type) { 1983 if (F.isImage(href)) { 1984 type = 'image'; 1985 1986 } else if (F.isSWF(href)) { 1987 type = 'swf'; 1988 1989 } else if (href.charAt(0) === '#') { 1990 type = 'inline'; 1991 1992 } else if (isString(element)) { 1993 type = 'html'; 1994 content = element; 1995 } 1996 } 1997 1998 // Split url into two pieces with source url and content selector, e.g, 1999 // "/mypage.html #my_id" will load "/mypage.html" and display element having id "my_id" 2000 if (type === 'ajax') { 2001 hrefParts = href.split(/\s+/, 2); 2002 href = hrefParts.shift(); 2003 selector = hrefParts.shift(); 2004 } 2005 } 2006 2007 if (!content) { 2008 if (type === 'inline') { 2009 if (href) { 2010 content = $( isString(href) ? href.replace(/.*(?=#[^\s]+$)/, '') : href ); //strip for ie7 2011 2012 } else if (obj.isDom) { 2013 content = element; 2014 } 2015 2016 } else if (type === 'html') { 2017 content = href; 2018 2019 } else if (!type && !href && obj.isDom) { 2020 type = 'inline'; 2021 content = element; 2022 } 2023 } 2024 2025 $.extend(obj, { 2026 href : href, 2027 type : type, 2028 content : content, 2029 title : title, 2030 selector : selector 2031 }); 2032 2033 group[ i ] = obj; 2034 }); 2035 2036 // Extend the defaults 2037 F.opts = $.extend(true, {}, F.defaults, opts); 2038 2039 // All options are merged recursive except keys 2040 if (opts.keys !== undefined) { 2041 F.opts.keys = opts.keys ? $.extend({}, F.defaults.keys, opts.keys) : false; 2042 } 2043 2044 F.group = group; 2045 2046 return F._start(F.opts.index); 2047 }, 2048 2049 // Cancel image loading or abort ajax request 2050 cancel: function () { 2051 var coming = F.coming; 2052 2053 if (!coming || false === F.trigger('onCancel')) { 2054 return; 2055 } 2056 2057 F.hideLoading(); 2058 2059 if (F.ajaxLoad) { 2060 F.ajaxLoad.abort(); 2061 } 2062 2063 F.ajaxLoad = null; 2064 2065 if (F.imgPreload) { 2066 F.imgPreload.onload = F.imgPreload.onerror = null; 2067 } 2068 2069 if (coming.wrap) { 2070 coming.wrap.stop(true, true).trigger('onReset').remove(); 2071 } 2072 2073 F.coming = null; 2074 2075 // If the first item has been canceled, then clear everything 2076 if (!F.current) { 2077 F._afterZoomOut( coming ); 2078 } 2079 }, 2080 2081 // Start closing animation if is open; remove immediately if opening/closing 2082 close: function (event) { 2083 F.cancel(); 2084 2085 if (false === F.trigger('beforeClose')) { 2086 return; 2087 } 2088 2089 F.unbindEvents(); 2090 2091 if (!F.isActive) { 2092 return; 2093 } 2094 2095 if (!F.isOpen || event === true) { 2096 $('.fancybox-wrap').stop(true).trigger('onReset').remove(); 2097 2098 F._afterZoomOut(); 2099 2100 } else { 2101 F.isOpen = F.isOpened = false; 2102 F.isClosing = true; 2103 2104 $('.fancybox-item, .fancybox-nav').remove(); 2105 2106 F.wrap.stop(true, true).removeClass('fancybox-opened'); 2107 2108 F.transitions[ F.current.closeMethod ](); 2109 } 2110 }, 2111 2112 // Manage slideshow: 2113 // $.fancybox.play(); - toggle slideshow 2114 // $.fancybox.play( true ); - start 2115 // $.fancybox.play( false ); - stop 2116 play: function ( action ) { 2117 var clear = function () { 2118 clearTimeout(F.player.timer); 2119 }, 2120 set = function () { 2121 clear(); 2122 2123 if (F.current && F.player.isActive) { 2124 F.player.timer = setTimeout(F.next, F.current.playSpeed); 2125 } 2126 }, 2127 stop = function () { 2128 clear(); 2129 2130 D.unbind('.player'); 2131 2132 F.player.isActive = false; 2133 2134 F.trigger('onPlayEnd'); 2135 }, 2136 start = function () { 2137 if (F.current && (F.current.loop || F.current.index < F.group.length - 1)) { 2138 F.player.isActive = true; 2139 2140 D.bind({ 2141 'onCancel.player beforeClose.player' : stop, 2142 'onUpdate.player' : set, 2143 'beforeLoad.player' : clear 2144 }); 2145 2146 set(); 2147 2148 F.trigger('onPlayStart'); 2149 } 2150 }; 2151 2152 if (action === true || (!F.player.isActive && action !== false)) { 2153 start(); 2154 } else { 2155 stop(); 2156 } 2157 }, 2158 2159 // Navigate to next gallery item 2160 next: function ( direction ) { 2161 var current = F.current; 2162 2163 if (current) { 2164 if (!isString(direction)) { 2165 direction = current.direction.next; 2166 } 2167 2168 F.jumpto(current.index + 1, direction, 'next'); 2169 } 2170 }, 2171 2172 // Navigate to previous gallery item 2173 prev: function ( direction ) { 2174 var current = F.current; 2175 2176 if (current) { 2177 if (!isString(direction)) { 2178 direction = current.direction.prev; 2179 } 2180 2181 F.jumpto(current.index - 1, direction, 'prev'); 2182 } 2183 }, 2184 2185 // Navigate to gallery item by index 2186 jumpto: function ( index, direction, router ) { 2187 var current = F.current; 2188 2189 if (!current) { 2190 return; 2191 } 2192 2193 index = getScalar(index); 2194 2195 F.direction = direction || current.direction[ (index >= current.index ? 'next' : 'prev') ]; 2196 F.router = router || 'jumpto'; 2197 2198 if (current.loop) { 2199 if (index < 0) { 2200 index = current.group.length + (index % current.group.length); 2201 } 2202 2203 index = index % current.group.length; 2204 } 2205 2206 if (current.group[ index ] !== undefined) { 2207 F.cancel(); 2208 2209 F._start(index); 2210 } 2211 }, 2212 2213 // Center inside viewport and toggle position type to fixed or absolute if needed 2214 reposition: function (e, onlyAbsolute) { 2215 var current = F.current, 2216 wrap = current ? current.wrap : null, 2217 pos; 2218 2219 if (wrap) { 2220 pos = F._getPosition(onlyAbsolute); 2221 2222 if (e && e.type === 'scroll') { 2223 delete pos.position; 2224 2225 wrap.stop(true, true).animate(pos, 200); 2226 2227 } else { 2228 wrap.css(pos); 2229 2230 current.pos = $.extend({}, current.dim, pos); 2231 } 2232 } 2233 }, 2234 2235 update: function (e) { 2236 var type = (e && e.type), 2237 anyway = !type || type === 'orientationchange'; 2238 2239 if (anyway) { 2240 clearTimeout(didUpdate); 2241 2242 didUpdate = null; 2243 } 2244 2245 if (!F.isOpen || didUpdate) { 2246 return; 2247 } 2248 2249 didUpdate = setTimeout(function() { 2250 var current = F.current; 2251 2252 if (!current || F.isClosing) { 2253 return; 2254 } 2255 2256 F.wrap.removeClass('fancybox-tmp'); 2257 2258 if (anyway || type === 'load' || (type === 'resize' && current.autoResize)) { 2259 F._setDimension(); 2260 } 2261 2262 if (!(type === 'scroll' && current.canShrink)) { 2263 F.reposition(e); 2264 } 2265 2266 F.trigger('onUpdate'); 2267 2268 didUpdate = null; 2269 2270 }, (anyway && !isTouch ? 0 : 300)); 2271 }, 2272 2273 // Shrink content to fit inside viewport or restore if resized 2274 toggle: function ( action ) { 2275 if (F.isOpen) { 2276 F.current.fitToView = $.type(action) === "boolean" ? action : !F.current.fitToView; 2277 2278 // Help browser to restore document dimensions 2279 if (isTouch) { 2280 F.wrap.removeAttr('style').addClass('fancybox-tmp'); 2281 2282 F.trigger('onUpdate'); 2283 } 2284 2285 F.update(); 2286 } 2287 }, 2288 2289 hideLoading: function () { 2290 D.unbind('.loading'); 2291 2292 $('#fancybox-loading').remove(); 2293 }, 2294 2295 showLoading: function () { 2296 var el, viewport; 2297 2298 F.hideLoading(); 2299 2300 el = $('<div id="fancybox-loading"><div></div></div>').click(F.cancel).appendTo('body'); 2301 2302 // If user will press the escape-button, the request will be canceled 2303 D.bind('keydown.loading', function(e) { 2304 if ((e.which || e.keyCode) === 27) { 2305 e.preventDefault(); 2306 2307 F.cancel(); 2308 } 2309 }); 2310 2311 if (!F.defaults.fixed) { 2312 viewport = F.getViewport(); 2313 2314 el.css({ 2315 position : 'absolute', 2316 top : (viewport.h * 0.5) + viewport.y, 2317 left : (viewport.w * 0.5) + viewport.x 2318 }); 2319 } 2320 }, 2321 2322 getViewport: function () { 2323 var locked = (F.current && F.current.locked) || false, 2324 rez = { 2325 x: W.scrollLeft(), 2326 y: W.scrollTop() 2327 }; 2328 2329 if (locked) { 2330 rez.w = locked[0].clientWidth; 2331 rez.h = locked[0].clientHeight; 2332 2333 } else { 2334 // See http://bugs.jquery.com/ticket/6724 2335 rez.w = isTouch && window.innerWidth ? window.innerWidth : W.width(); 2336 rez.h = isTouch && window.innerHeight ? window.innerHeight : W.height(); 2337 } 2338 2339 return rez; 2340 }, 2341 2342 // Unbind the keyboard / clicking actions 2343 unbindEvents: function () { 2344 if (F.wrap && isQuery(F.wrap)) { 2345 F.wrap.unbind('.fb'); 2346 } 2347 2348 D.unbind('.fb'); 2349 W.unbind('.fb'); 2350 }, 2351 2352 bindEvents: function () { 2353 var current = F.current, 2354 keys; 2355 2356 if (!current) { 2357 return; 2358 } 2359 2360 // Changing document height on iOS devices triggers a 'resize' event, 2361 // that can change document height... repeating infinitely 2362 W.bind('orientationchange.fb' + (isTouch ? '' : ' resize.fb') + (current.autoCenter && !current.locked ? ' scroll.fb' : ''), F.update); 2363 2364 keys = current.keys; 2365 2366 if (keys) { 2367 D.bind('keydown.fb', function (e) { 2368 var code = e.which || e.keyCode, 2369 target = e.target || e.srcElement; 2370 2371 // Skip esc key if loading, because showLoading will cancel preloading 2372 if (code === 27 && F.coming) { 2373 return false; 2374 } 2375 2376 // Ignore key combinations and key events within form elements 2377 if (!e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && !(target && (target.type || $(target).is('[contenteditable]')))) { 2378 $.each(keys, function(i, val) { 2379 if (current.group.length > 1 && val[ code ] !== undefined) { 2380 F[ i ]( val[ code ] ); 2381 2382 e.preventDefault(); 2383 return false; 2384 } 2385 2386 if ($.inArray(code, val) > -1) { 2387 F[ i ] (); 2388 2389 e.preventDefault(); 2390 return false; 2391 } 2392 }); 2393 } 2394 }); 2395 } 2396 2397 if ($.fn.mousewheel && current.mouseWheel) { 2398 F.wrap.bind('mousewheel.fb', function (e, delta, deltaX, deltaY) { 2399 var target = e.target || null, 2400 parent = $(target), 2401 canScroll = false; 2402 2403 while (parent.length) { 2404 if (canScroll || parent.is('.fancybox-skin') || parent.is('.fancybox-wrap')) { 2405 break; 2406 } 2407 2408 canScroll = isScrollable( parent[0] ); 2409 parent = $(parent).parent(); 2410 } 2411 2412 if (delta !== 0 && !canScroll) { 2413 if (F.group.length > 1 && !current.canShrink) { 2414 if (deltaY > 0 || deltaX > 0) { 2415 F.prev( deltaY > 0 ? 'down' : 'left' ); 2416 2417 } else if (deltaY < 0 || deltaX < 0) { 2418 F.next( deltaY < 0 ? 'up' : 'right' ); 2419 } 2420 2421 e.preventDefault(); 2422 } 2423 } 2424 }); 2425 } 2426 }, 2427 2428 trigger: function (event, o) { 2429 var ret, obj = o || F.coming || F.current; 2430 2431 if (!obj) { 2432 return; 2433 } 2434 2435 if ($.isFunction( obj[event] )) { 2436 ret = obj[event].apply(obj, Array.prototype.slice.call(arguments, 1)); 2437 } 2438 2439 if (ret === false) { 2440 return false; 2441 } 2442 2443 if (obj.helpers) { 2444 $.each(obj.helpers, function (helper, opts) { 2445 if (opts && F.helpers[helper] && $.isFunction(F.helpers[helper][event])) { 2446 F.helpers[helper][event]($.extend(true, {}, F.helpers[helper].defaults, opts), obj); 2447 } 2448 }); 2449 } 2450 2451 D.trigger(event); 2452 }, 2453 2454 isImage: function (str) { 2455 return isString(str) && str.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i); 2456 }, 2457 2458 isSWF: function (str) { 2459 return isString(str) && str.match(/\.(swf)((\?|#).*)?$/i); 2460 }, 2461 2462 _start: function (index) { 2463 var coming = {}, 2464 obj, 2465 href, 2466 type, 2467 margin, 2468 padding; 2469 2470 index = getScalar( index ); 2471 obj = F.group[ index ] || null; 2472 2473 if (!obj) { 2474 return false; 2475 } 2476 2477 coming = $.extend(true, {}, F.opts, obj); 2478 2479 // Convert margin and padding properties to array - top, right, bottom, left 2480 margin = coming.margin; 2481 padding = coming.padding; 2482 2483 if ($.type(margin) === 'number') { 2484 coming.margin = [margin, margin, margin, margin]; 2485 } 2486 2487 if ($.type(padding) === 'number') { 2488 coming.padding = [padding, padding, padding, padding]; 2489 } 2490 2491 // 'modal' propery is just a shortcut 2492 if (coming.modal) { 2493 $.extend(true, coming, { 2494 closeBtn : false, 2495 closeClick : false, 2496 nextClick : false, 2497 arrows : false, 2498 mouseWheel : false, 2499 keys : null, 2500 helpers: { 2501 overlay : { 2502 closeClick : false 2503 } 2504 } 2505 }); 2506 } 2507 2508 // 'autoSize' property is a shortcut, too 2509 if (coming.autoSize) { 2510 coming.autoWidth = coming.autoHeight = true; 2511 } 2512 2513 if (coming.width === 'auto') { 2514 coming.autoWidth = true; 2515 } 2516 2517 if (coming.height === 'auto') { 2518 coming.autoHeight = true; 2519 } 2520 2521 /* 2522 * Add reference to the group, so it`s possible to access from callbacks, example: 2523 * afterLoad : function() { 2524 * this.title = 'Image ' + (this.index + 1) + ' of ' + this.group.length + (this.title ? ' - ' + this.title : ''); 2525 * } 2526 */ 2527 2528 coming.group = F.group; 2529 coming.index = index; 2530 2531 // Give a chance for callback or helpers to update coming item (type, title, etc) 2532 F.coming = coming; 2533 2534 if (false === F.trigger('beforeLoad')) { 2535 F.coming = null; 2536 2537 return; 2538 } 2539 2540 type = coming.type; 2541 href = coming.href; 2542 2543 if (!type) { 2544 F.coming = null; 2545 2546 //If we can not determine content type then drop silently or display next/prev item if looping through gallery 2547 if (F.current && F.router && F.router !== 'jumpto') { 2548 F.current.index = index; 2549 2550 return F[ F.router ]( F.direction ); 2551 } 2552 2553 return false; 2554 } 2555 2556 F.isActive = true; 2557 2558 if (type === 'image' || type === 'swf') { 2559 coming.autoHeight = coming.autoWidth = false; 2560 coming.scrolling = 'visible'; 2561 } 2562 2563 if (type === 'image') { 2564 coming.aspectRatio = true; 2565 } 2566 2567 if (type === 'iframe' && isTouch) { 2568 coming.scrolling = 'scroll'; 2569 } 2570 2571 // Build the neccessary markup 2572 coming.wrap = $(coming.tpl.wrap).addClass('fancybox-' + (isTouch ? 'mobile' : 'desktop') + ' fancybox-type-' + type + ' fancybox-tmp ' + coming.wrapCSS).appendTo( coming.parent || 'body' ); 2573 2574 $.extend(coming, { 2575 skin : $('.fancybox-skin', coming.wrap), 2576 outer : $('.fancybox-outer', coming.wrap), 2577 inner : $('.fancybox-inner', coming.wrap) 2578 }); 2579 2580 $.each(["Top", "Right", "Bottom", "Left"], function(i, v) { 2581 coming.skin.css('padding' + v, getValue(coming.padding[ i ])); 2582 }); 2583 2584 F.trigger('onReady'); 2585 2586 // Check before try to load; 'inline' and 'html' types need content, others - href 2587 if (type === 'inline' || type === 'html') { 2588 if (!coming.content || !coming.content.length) { 2589 return F._error( 'content' ); 2590 } 2591 2592 } else if (!href) { 2593 return F._error( 'href' ); 2594 } 2595 2596 if (type === 'image') { 2597 F._loadImage(); 2598 2599 } else if (type === 'ajax') { 2600 F._loadAjax(); 2601 2602 } else if (type === 'iframe') { 2603 F._loadIframe(); 2604 2605 } else { 2606 F._afterLoad(); 2607 } 2608 }, 2609 2610 _error: function ( type ) { 2611 $.extend(F.coming, { 2612 type : 'html', 2613 autoWidth : true, 2614 autoHeight : true, 2615 minWidth : 0, 2616 minHeight : 0, 2617 scrolling : 'no', 2618 hasError : type, 2619 content : F.coming.tpl.error 2620 }); 2621 2622 F._afterLoad(); 2623 }, 2624 2625 _loadImage: function () { 2626 // Reset preload image so it is later possible to check "complete" property 2627 var img = F.imgPreload = new Image(); 2628 2629 img.onload = function () { 2630 this.onload = this.onerror = null; 2631 2632 F.coming.width = this.width / F.opts.pixelRatio; 2633 F.coming.height = this.height / F.opts.pixelRatio; 2634 2635 F._afterLoad(); 2636 }; 2637 2638 img.onerror = function () { 2639 this.onload = this.onerror = null; 2640 2641 F._error( 'image' ); 2642 }; 2643 2644 img.src = F.coming.href; 2645 2646 if (img.complete !== true) { 2647 F.showLoading(); 2648 } 2649 }, 2650 2651 _loadAjax: function () { 2652 var coming = F.coming; 2653 2654 F.showLoading(); 2655 2656 F.ajaxLoad = $.ajax($.extend({}, coming.ajax, { 2657 url: coming.href, 2658 error: function (jqXHR, textStatus) { 2659 if (F.coming && textStatus !== 'abort') { 2660 F._error( 'ajax', jqXHR ); 2661 2662 } else { 2663 F.hideLoading(); 2664 } 2665 }, 2666 success: function (data, textStatus) { 2667 if (textStatus === 'success') { 2668 coming.content = data; 2669 2670 F._afterLoad(); 2671 } 2672 } 2673 })); 2674 }, 2675 2676 _loadIframe: function() { 2677 var coming = F.coming, 2678 iframe = $(coming.tpl.iframe.replace(/\{rnd\}/g, new Date().getTime())) 2679 .attr('scrolling', isTouch ? 'auto' : coming.iframe.scrolling) 2680 .attr('src', coming.href); 2681 2682 // This helps IE 2683 $(coming.wrap).bind('onReset', function () { 2684 try { 2685 $(this).find('iframe').hide().attr('src', '//about:blank').end().empty(); 2686 } catch (e) {} 2687 }); 2688 2689 if (coming.iframe.preload) { 2690 F.showLoading(); 2691 2692 iframe.one('load', function() { 2693 $(this).data('ready', 1); 2694 2695 // iOS will lose scrolling if we resize 2696 if (!isTouch) { 2697 $(this).bind('load.fb', F.update); 2698 } 2699 2700 // Without this trick: 2701 // - iframe won't scroll on iOS devices 2702 // - IE7 sometimes displays empty iframe 2703 $(this).parents('.fancybox-wrap').width('100%').removeClass('fancybox-tmp').show(); 2704 2705 F._afterLoad(); 2706 }); 2707 } 2708 2709 coming.content = iframe.appendTo( coming.inner ); 2710 2711 if (!coming.iframe.preload) { 2712 F._afterLoad(); 2713 } 2714 }, 2715 2716 _preloadImages: function() { 2717 var group = F.group, 2718 current = F.current, 2719 len = group.length, 2720 cnt = current.preload ? Math.min(current.preload, len - 1) : 0, 2721 item, 2722 i; 2723 2724 for (i = 1; i <= cnt; i += 1) { 2725 item = group[ (current.index + i ) % len ]; 2726 2727 if (item.type === 'image' && item.href) { 2728 new Image().src = item.href; 2729 } 2730 } 2731 }, 2732 2733 _afterLoad: function () { 2734 var coming = F.coming, 2735 previous = F.current, 2736 placeholder = 'fancybox-placeholder', 2737 current, 2738 content, 2739 type, 2740 scrolling, 2741 href, 2742 embed; 2743 2744 F.hideLoading(); 2745 2746 if (!coming || F.isActive === false) { 2747 return; 2748 } 2749 2750 if (false === F.trigger('afterLoad', coming, previous)) { 2751 coming.wrap.stop(true).trigger('onReset').remove(); 2752 2753 F.coming = null; 2754 2755 return; 2756 } 2757 2758 if (previous) { 2759 F.trigger('beforeChange', previous); 2760 2761 previous.wrap.stop(true).removeClass('fancybox-opened') 2762 .find('.fancybox-item, .fancybox-nav') 2763 .remove(); 2764 } 2765 2766 F.unbindEvents(); 2767 2768 current = coming; 2769 content = coming.content; 2770 type = coming.type; 2771 scrolling = coming.scrolling; 2772 2773 $.extend(F, { 2774 wrap : current.wrap, 2775 skin : current.skin, 2776 outer : current.outer, 2777 inner : current.inner, 2778 current : current, 2779 previous : previous 2780 }); 2781 2782 href = current.href; 2783 2784 switch (type) { 2785 case 'inline': 2786 case 'ajax': 2787 case 'html': 2788 if (current.selector) { 2789 content = $('<div>').html(content).find(current.selector); 2790 2791 } else if (isQuery(content)) { 2792 if (!content.data(placeholder)) { 2793 content.data(placeholder, $('<div class="' + placeholder + '"></div>').insertAfter( content ).hide() ); 2794 } 2795 2796 content = content.show().detach(); 2797 2798 current.wrap.bind('onReset', function () { 2799 if ($(this).find(content).length) { 2800 content.hide().replaceAll( content.data(placeholder) ).data(placeholder, false); 2801 } 2802 }); 2803 } 2804 break; 2805 2806 case 'image': 2807 content = current.tpl.image.replace('{href}', href); 2808 break; 2809 2810 case 'swf': 2811 content = '<object id="fancybox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="' + href + '"></param>'; 2812 embed = ''; 2813 2814 $.each(current.swf, function(name, val) { 2815 content += '<param name="' + name + '" value="' + val + '"></param>'; 2816 embed += ' ' + name + '="' + val + '"'; 2817 }); 2818 2819 content += '<embed src="' + href + '" type="application/x-shockwave-flash" width="100%" height="100%"' + embed + '></embed></object>'; 2820 break; 2821 } 2822 2823 if (!(isQuery(content) && content.parent().is(current.inner))) { 2824 current.inner.append( content ); 2825 } 2826 2827 // Give a chance for helpers or callbacks to update elements 2828 F.trigger('beforeShow'); 2829 2830 // Set scrolling before calculating dimensions 2831 current.inner.css('overflow', scrolling === 'yes' ? 'scroll' : (scrolling === 'no' ? 'hidden' : scrolling)); 2832 2833 // Set initial dimensions and start position 2834 F._setDimension(); 2835 2836 F.reposition(); 2837 2838 F.isOpen = false; 2839 F.coming = null; 2840 2841 F.bindEvents(); 2842 2843 if (!F.isOpened) { 2844 $('.fancybox-wrap').not( current.wrap ).stop(true).trigger('onReset').remove(); 2845 2846 } else if (previous.prevMethod) { 2847 F.transitions[ previous.prevMethod ](); 2848 } 2849 2850 F.transitions[ F.isOpened ? current.nextMethod : current.openMethod ](); 2851 2852 F._preloadImages(); 2853 }, 2854 2855 _setDimension: function () { 2856 var viewport = F.getViewport(), 2857 steps = 0, 2858 canShrink = false, 2859 canExpand = false, 2860 wrap = F.wrap, 2861 skin = F.skin, 2862 inner = F.inner, 2863 current = F.current, 2864 width = current.width, 2865 height = current.height, 2866 minWidth = current.minWidth, 2867 minHeight = current.minHeight, 2868 maxWidth = current.maxWidth, 2869 maxHeight = current.maxHeight, 2870 scrolling = current.scrolling, 2871 scrollOut = current.scrollOutside ? current.scrollbarWidth : 0, 2872 margin = current.margin, 2873 wMargin = getScalar(margin[1] + margin[3]), 2874 hMargin = getScalar(margin[0] + margin[2]), 2875 wPadding, 2876 hPadding, 2877 wSpace, 2878 hSpace, 2879 origWidth, 2880 origHeight, 2881 origMaxWidth, 2882 origMaxHeight, 2883 ratio, 2884 width_, 2885 height_, 2886 maxWidth_, 2887 maxHeight_, 2888 iframe, 2889 body; 2890 2891 // Reset dimensions so we could re-check actual size 2892 wrap.add(skin).add(inner).width('auto').height('auto').removeClass('fancybox-tmp'); 2893 2894 wPadding = getScalar(skin.outerWidth(true) - skin.width()); 2895 hPadding = getScalar(skin.outerHeight(true) - skin.height()); 2896 2897 // Any space between content and viewport (margin, padding, border, title) 2898 wSpace = wMargin + wPadding; 2899 hSpace = hMargin + hPadding; 2900 2901 origWidth = isPercentage(width) ? (viewport.w - wSpace) * getScalar(width) / 100 : width; 2902 origHeight = isPercentage(height) ? (viewport.h - hSpace) * getScalar(height) / 100 : height; 2903 2904 if (current.type === 'iframe') { 2905 iframe = current.content; 2906 2907 if (current.autoHeight && iframe.data('ready') === 1) { 2908 try { 2909 if (iframe[0].contentWindow.document.location) { 2910 inner.width( origWidth ).height(9999); 2911 2912 body = iframe.contents().find('body'); 2913 2914 if (scrollOut) { 2915 body.css('overflow-x', 'hidden'); 2916 } 2917 2918 origHeight = body.outerHeight(true); 2919 } 2920 2921 } catch (e) {} 2922 } 2923 2924 } else if (current.autoWidth || current.autoHeight) { 2925 inner.addClass( 'fancybox-tmp' ); 2926 2927 // Set width or height in case we need to calculate only one dimension 2928 if (!current.autoWidth) { 2929 inner.width( origWidth ); 2930 } 2931 2932 if (!current.autoHeight) { 2933 inner.height( origHeight ); 2934 } 2935 2936 if (current.autoWidth) { 2937 origWidth = inner.width(); 2938 } 2939 2940 if (current.autoHeight) { 2941 origHeight = inner.height(); 2942 } 2943 2944 inner.removeClass( 'fancybox-tmp' ); 2945 } 2946 2947 width = getScalar( origWidth ); 2948 height = getScalar( origHeight ); 2949 2950 ratio = origWidth / origHeight; 2951 2952 // Calculations for the content 2953 minWidth = getScalar(isPercentage(minWidth) ? getScalar(minWidth, 'w') - wSpace : minWidth); 2954 maxWidth = getScalar(isPercentage(maxWidth) ? getScalar(maxWidth, 'w') - wSpace : maxWidth); 2955 2956 minHeight = getScalar(isPercentage(minHeight) ? getScalar(minHeight, 'h') - hSpace : minHeight); 2957 maxHeight = getScalar(isPercentage(maxHeight) ? getScalar(maxHeight, 'h') - hSpace : maxHeight); 2958 2959 // These will be used to determine if wrap can fit in the viewport 2960 origMaxWidth = maxWidth; 2961 origMaxHeight = maxHeight; 2962 2963 if (current.fitToView) { 2964 maxWidth = Math.min(viewport.w - wSpace, maxWidth); 2965 maxHeight = Math.min(viewport.h - hSpace, maxHeight); 2966 } 2967 2968 maxWidth_ = viewport.w - wMargin; 2969 maxHeight_ = viewport.h - hMargin; 2970 2971 if (current.aspectRatio) { 2972 if (width > maxWidth) { 2973 width = maxWidth; 2974 height = getScalar(width / ratio); 2975 } 2976 2977 if (height > maxHeight) { 2978 height = maxHeight; 2979 width = getScalar(height * ratio); 2980 } 2981 2982 if (width < minWidth) { 2983 width = minWidth; 2984 height = getScalar(width / ratio); 2985 } 2986 2987 if (height < minHeight) { 2988 height = minHeight; 2989 width = getScalar(height * ratio); 2990 } 2991 2992 } else { 2993 width = Math.max(minWidth, Math.min(width, maxWidth)); 2994 2995 if (current.autoHeight && current.type !== 'iframe') { 2996 inner.width( width ); 2997 2998 height = inner.height(); 2999 } 3000 3001 height = Math.max(minHeight, Math.min(height, maxHeight)); 3002 } 3003 3004 // Try to fit inside viewport (including the title) 3005 if (current.fitToView) { 3006 inner.width( width ).height( height ); 3007 3008 wrap.width( width + wPadding ); 3009 3010 // Real wrap dimensions 3011 width_ = wrap.width(); 3012 height_ = wrap.height(); 3013 3014 if (current.aspectRatio) { 3015 while ((width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight) { 3016 if (steps++ > 19) { 3017 break; 3018 } 3019 3020 height = Math.max(minHeight, Math.min(maxHeight, height - 10)); 3021 width = getScalar(height * ratio); 3022 3023 if (width < minWidth) { 3024 width = minWidth; 3025 height = getScalar(width / ratio); 3026 } 3027 3028 if (width > maxWidth) { 3029 width = maxWidth; 3030 height = getScalar(width / ratio); 3031 } 3032 3033 inner.width( width ).height( height ); 3034 3035 wrap.width( width + wPadding ); 3036 3037 width_ = wrap.width(); 3038 height_ = wrap.height(); 3039 } 3040 3041 } else { 3042 width = Math.max(minWidth, Math.min(width, width - (width_ - maxWidth_))); 3043 height = Math.max(minHeight, Math.min(height, height - (height_ - maxHeight_))); 3044 } 3045 } 3046 3047 if (scrollOut && scrolling === 'auto' && height < origHeight && (width + wPadding + scrollOut) < maxWidth_) { 3048 width += scrollOut; 3049 } 3050 3051 inner.width( width ).height( height ); 3052 3053 wrap.width( width + wPadding ); 3054 3055 width_ = wrap.width(); 3056 height_ = wrap.height(); 3057 3058 canShrink = (width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight; 3059 canExpand = current.aspectRatio ? (width < origMaxWidth && height < origMaxHeight && width < origWidth && height < origHeight) : ((width < origMaxWidth || height < origMaxHeight) && (width < origWidth || height < origHeight)); 3060 3061 $.extend(current, { 3062 dim : { 3063 width : getValue( width_ ), 3064 height : getValue( height_ ) 3065 }, 3066 origWidth : origWidth, 3067 origHeight : origHeight, 3068 canShrink : canShrink, 3069 canExpand : canExpand, 3070 wPadding : wPadding, 3071 hPadding : hPadding, 3072 wrapSpace : height_ - skin.outerHeight(true), 3073 skinSpace : skin.height() - height 3074 }); 3075 3076 if (!iframe && current.autoHeight && height > minHeight && height < maxHeight && !canExpand) { 3077 inner.height('auto'); 3078 } 3079 }, 3080 3081 _getPosition: function (onlyAbsolute) { 3082 var current = F.current, 3083 viewport = F.getViewport(), 3084 margin = current.margin, 3085 width = F.wrap.width() + margin[1] + margin[3], 3086 height = F.wrap.height() + margin[0] + margin[2], 3087 rez = { 3088 position: 'absolute', 3089 top : margin[0], 3090 left : margin[3] 3091 }; 3092 3093 if (current.autoCenter && current.fixed && !onlyAbsolute && height <= viewport.h && width <= viewport.w) { 3094 rez.position = 'fixed'; 3095 3096 } else if (!current.locked) { 3097 rez.top += viewport.y; 3098 rez.left += viewport.x; 3099 } 3100 3101 rez.top = getValue(Math.max(rez.top, rez.top + ((viewport.h - height) * current.topRatio))); 3102 rez.left = getValue(Math.max(rez.left, rez.left + ((viewport.w - width) * current.leftRatio))); 3103 3104 return rez; 3105 }, 3106 3107 _afterZoomIn: function () { 3108 var current = F.current; 3109 3110 if (!current) { 3111 return; 3112 } 3113 3114 F.isOpen = F.isOpened = true; 3115 3116 F.wrap.css('overflow', 'visible').addClass('fancybox-opened'); 3117 3118 F.update(); 3119 3120 // Assign a click event 3121 if ( current.closeClick || (current.nextClick && F.group.length > 1) ) { 3122 F.inner.css('cursor', 'pointer').bind('click.fb', function(e) { 3123 if (!$(e.target).is('a') && !$(e.target).parent().is('a')) { 3124 e.preventDefault(); 3125 3126 F[ current.closeClick ? 'close' : 'next' ](); 3127 } 3128 }); 3129 } 3130 3131 // Create a close button 3132 if (current.closeBtn) { 3133 $(current.tpl.closeBtn).appendTo(F.skin).bind('click.fb', function(e) { 3134 e.preventDefault(); 3135 3136 F.close(); 3137 }); 3138 } 3139 3140 // Create navigation arrows 3141 if (current.arrows && F.group.length > 1) { 3142 if (current.loop || current.index > 0) { 3143 $(current.tpl.prev).appendTo(F.outer).bind('click.fb', F.prev); 3144 } 3145 3146 if (current.loop || current.index < F.group.length - 1) { 3147 $(current.tpl.next).appendTo(F.outer).bind('click.fb', F.next); 3148 } 3149 } 3150 3151 F.trigger('afterShow'); 3152 3153 // Stop the slideshow if this is the last item 3154 if (!current.loop && current.index === current.group.length - 1) { 3155 F.play( false ); 3156 3157 } else if (F.opts.autoPlay && !F.player.isActive) { 3158 F.opts.autoPlay = false; 3159 3160 F.play(); 3161 } 3162 }, 3163 3164 _afterZoomOut: function ( obj ) { 3165 obj = obj || F.current; 3166 3167 $('.fancybox-wrap').trigger('onReset').remove(); 3168 3169 $.extend(F, { 3170 group : {}, 3171 opts : {}, 3172 router : false, 3173 current : null, 3174 isActive : false, 3175 isOpened : false, 3176 isOpen : false, 3177 isClosing : false, 3178 wrap : null, 3179 skin : null, 3180 outer : null, 3181 inner : null 3182 }); 3183 3184 F.trigger('afterClose', obj); 3185 } 3186 }); 3187 3188 /* 3189 * Default transitions 3190 */ 3191 3192 F.transitions = { 3193 getOrigPosition: function () { 3194 var current = F.current, 3195 element = current.element, 3196 orig = current.orig, 3197 pos = {}, 3198 width = 50, 3199 height = 50, 3200 hPadding = current.hPadding, 3201 wPadding = current.wPadding, 3202 viewport = F.getViewport(); 3203 3204 if (!orig && current.isDom && element.is(':visible')) { 3205 orig = element.find('img:first'); 3206 3207 if (!orig.length) { 3208 orig = element; 3209 } 3210 } 3211 3212 if (isQuery(orig)) { 3213 pos = orig.offset(); 3214 3215 if (orig.is('img')) { 3216 width = orig.outerWidth(); 3217 height = orig.outerHeight(); 3218 } 3219 3220 } else { 3221 pos.top = viewport.y + (viewport.h - height) * current.topRatio; 3222 pos.left = viewport.x + (viewport.w - width) * current.leftRatio; 3223 } 3224 3225 if (F.wrap.css('position') === 'fixed' || current.locked) { 3226 pos.top -= viewport.y; 3227 pos.left -= viewport.x; 3228 } 3229 3230 pos = { 3231 top : getValue(pos.top - hPadding * current.topRatio), 3232 left : getValue(pos.left - wPadding * current.leftRatio), 3233 width : getValue(width + wPadding), 3234 height : getValue(height + hPadding) 3235 }; 3236 3237 return pos; 3238 }, 3239 3240 step: function (now, fx) { 3241 var ratio, 3242 padding, 3243 value, 3244 prop = fx.prop, 3245 current = F.current, 3246 wrapSpace = current.wrapSpace, 3247 skinSpace = current.skinSpace; 3248 3249 if (prop === 'width' || prop === 'height') { 3250 ratio = fx.end === fx.start ? 1 : (now - fx.start) / (fx.end - fx.start); 3251 3252 if (F.isClosing) { 3253 ratio = 1 - ratio; 3254 } 3255 3256 padding = prop === 'width' ? current.wPadding : current.hPadding; 3257 value = now - padding; 3258 3259 F.skin[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) ) ); 3260 F.inner[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) - (skinSpace * ratio) ) ); 3261 } 3262 }, 3263 3264 zoomIn: function () { 3265 var current = F.current, 3266 startPos = current.pos, 3267 effect = current.openEffect, 3268 elastic = effect === 'elastic', 3269 endPos = $.extend({opacity : 1}, startPos); 3270 3271 // Remove "position" property that breaks older IE 3272 delete endPos.position; 3273 3274 if (elastic) { 3275 startPos = this.getOrigPosition(); 3276 3277 if (current.openOpacity) { 3278 startPos.opacity = 0.1; 3279 } 3280 3281 } else if (effect === 'fade') { 3282 startPos.opacity = 0.1; 3283 } 3284 3285 F.wrap.css(startPos).animate(endPos, { 3286 duration : effect === 'none' ? 0 : current.openSpeed, 3287 easing : current.openEasing, 3288 step : elastic ? this.step : null, 3289 complete : F._afterZoomIn 3290 }); 3291 }, 3292 3293 zoomOut: function () { 3294 var current = F.current, 3295 effect = current.closeEffect, 3296 elastic = effect === 'elastic', 3297 endPos = {opacity : 0.1}; 3298 3299 if (elastic) { 3300 endPos = this.getOrigPosition(); 3301 3302 if (current.closeOpacity) { 3303 endPos.opacity = 0.1; 3304 } 3305 } 3306 3307 F.wrap.animate(endPos, { 3308 duration : effect === 'none' ? 0 : current.closeSpeed, 3309 easing : current.closeEasing, 3310 step : elastic ? this.step : null, 3311 complete : F._afterZoomOut 3312 }); 3313 }, 3314 3315 changeIn: function () { 3316 var current = F.current, 3317 effect = current.nextEffect, 3318 startPos = current.pos, 3319 endPos = { opacity : 1 }, 3320 direction = F.direction, 3321 distance = 200, 3322 field; 3323 3324 startPos.opacity = 0.1; 3325 3326 if (effect === 'elastic') { 3327 field = direction === 'down' || direction === 'up' ? 'top' : 'left'; 3328 3329 if (direction === 'down' || direction === 'right') { 3330 startPos[ field ] = getValue(getScalar(startPos[ field ]) - distance); 3331 endPos[ field ] = '+=' + distance + 'px'; 3332 3333 } else { 3334 startPos[ field ] = getValue(getScalar(startPos[ field ]) + distance); 3335 endPos[ field ] = '-=' + distance + 'px'; 3336 } 3337 } 3338 3339 // Workaround for http://bugs.jquery.com/ticket/12273 3340 if (effect === 'none') { 3341 F._afterZoomIn(); 3342 3343 } else { 3344 F.wrap.css(startPos).animate(endPos, { 3345 duration : current.nextSpeed, 3346 easing : current.nextEasing, 3347 complete : F._afterZoomIn 3348 }); 3349 } 3350 }, 3351 3352 changeOut: function () { 3353 var previous = F.previous, 3354 effect = previous.prevEffect, 3355 endPos = { opacity : 0.1 }, 3356 direction = F.direction, 3357 distance = 200; 3358 3359 if (effect === 'elastic') { 3360 endPos[ direction === 'down' || direction === 'up' ? 'top' : 'left' ] = ( direction === 'up' || direction === 'left' ? '-' : '+' ) + '=' + distance + 'px'; 3361 } 3362 3363 previous.wrap.animate(endPos, { 3364 duration : effect === 'none' ? 0 : previous.prevSpeed, 3365 easing : previous.prevEasing, 3366 complete : function () { 3367 $(this).trigger('onReset').remove(); 3368 } 3369 }); 3370 } 3371 }; 3372 3373 /* 3374 * Overlay helper 3375 */ 3376
3377 F.helpers.overlay = { 3378 defaults : { 3379 closeClick : true, // if true, fancyBox will be closed when user clicks on the overlay 3380 speedOut : 200, // duration of fadeOut animation 3381 showEarly : true, // indicates if should be opened immediately or wait until the content is ready 3382 css : {}, // custom CSS properties 3383 locked : !isTouch, // if true, the content will be locked into overlay 3384 fixed : true // if false, the overlay CSS position property will not be set to "fixed" 3385 }, 3386 3387 overlay : null, // current handle 3388 fixed : false, // indicates if the overlay has position "fixed" 3389 el : $('html'), // element that contains "the lock" 3390 3391 // Public methods 3392 create : function(opts) { 3393 opts = $.extend({}, this.defaults, opts); 3394 3395 if (this.overlay) { 3396 this.close(); 3397 } 3398 3399 this.overlay = $('<div class="fancybox-overlay"></div>').appendTo( F.coming ? F.coming.parent : opts.parent ); 3400 this.fixed = false; 3401 3402 if (opts.fixed && F.defaults.fixed) { 3403 this.overlay.addClass('fancybox-overlay-fixed'); 3404 3405 this.fixed = true; 3406 } 3407 }, 3408 3409 open : function(opts) { 3410 var that = this; 3411 3412 opts = $.extend({}, this.defaults, opts); 3413 3414 if (this.overlay) { 3415 this.overlay.unbind('.overlay').width('auto').height('auto'); 3416 3417 } else { 3418 this.create(opts); 3419 } 3420 3421 if (!this.fixed) { 3422 W.bind('resize.overlay', $.proxy( this.update, this) ); 3423 3424 this.update(); 3425 } 3426 3427 if (opts.closeClick) { 3428 this.overlay.bind('click.overlay', function(e) { 3429 if ($(e.target).hasClass('fancybox-overlay')) { 3430 if (F.isActive) { 3431 F.close(); 3432 } else { 3433 that.close(); 3434 } 3435 3436 return false; 3437 } 3438 }); 3439 } 3440 3441 this.overlay.css( opts.css ).show(); 3442 }, 3443 3444 close : function() { 3445 var scrollV, scrollH; 3446 3447 W.unbind('resize.overlay'); 3448 3449 if (this.el.hasClass('fancybox-lock')) { 3450 $('.fancybox-margin').removeClass('fancybox-margin'); 3451 3452 scrollV = W.scrollTop(); 3453 scrollH = W.scrollLeft(); 3454 3455 this.el.removeClass('fancybox-lock'); 3456 3457 W.scrollTop( scrollV ).scrollLeft( scrollH ); 3458 } 3459 3460 $('.fancybox-overlay').remove().hide(); 3461 3462 $.extend(this, { 3463 overlay : null, 3464 fixed : false 3465 }); 3466 }, 3467 3468 // Private, callbacks 3469 3470 update : function () { 3471 var width = '100%', offsetWidth; 3472 3473 // Reset width/height so it will not mess 3474 this.overlay.width(width).height('100%'); 3475 3476 // jQuery does not return reliable result for IE 3477 if (IE) { 3478 offsetWidth = Math.max(document.documentElement.offsetWidth, document.body.offsetWidth); 3479 3480 if (D.width() > offsetWidth) { 3481 width = D.width(); 3482 } 3483 3484 } else if (D.width() > W.width()) { 3485 width = D.width(); 3486 } 3487 3488 this.overlay.width(width).height(D.height()); 3489 }, 3490 3491 // This is where we can manipulate DOM, because later it would cause iframes to reload 3492 onReady : function (opts, obj) { 3493 var overlay = this.overlay; 3494 3495 $('.fancybox-overlay').stop(true, true); 3496 3497 if (!overlay) { 3498 this.create(opts); 3499 } 3500 3501 if (opts.locked && this.fixed && obj.fixed) { 3502 if (!overlay) { 3503 this.margin = D.height() > W.height() ? $('html').css('margin-right').replace("px", "") : false; 3504 } 3505 3506 obj.locked = this.overlay.append( obj.wrap ); 3507 obj.fixed = false; 3508 } 3509 3510 if (opts.showEarly === true) { 3511 this.beforeShow.apply(this, arguments); 3512 } 3513 }, 3514 3515 beforeShow : function(opts, obj) { 3516 var scrollV, scrollH; 3517 3518 if (obj.locked) { 3519 if (this.margin !== false) { 3520 $('*').filter(function(){ 3521 return ($(this).css('position') === 'fixed' && !$(this).hasClass("fancybox-overlay") && !$(this).hasClass("fancybox-wrap") ); 3522 }).addClass('fancybox-margin'); 3523 3524 this.el.addClass('fancybox-margin'); 3525 } 3526 3527 scrollV = W.scrollTop(); 3528 scrollH = W.scrollLeft(); 3529 3530 this.el.addClass('fancybox-lock'); 3531 3532 W.scrollTop( scrollV ).scrollLeft( scrollH ); 3533 } 3534 3535 this.open(opts); 3536 }, 3537 3538 onUpdate : function() { 3539 if (!this.fixed) { 3540 this.update(); 3541 } 3542 }, 3543 3544 afterClose: function (opts) { 3545 // Remove overlay if exists and fancyBox is not opening 3546 // (e.g., it is not being open using afterClose callback) 3547 //if (this.overlay && !F.isActive) { 3548 if (this.overlay && !F.coming) { 3549 this.overlay.fadeOut(opts.speedOut, $.proxy( this.close, this )); 3550 } 3551 } 3552 }; 3553 3554 /* 3555 * Title helper 3556 */ 3557 3558 F.helpers.title = { 3559 defaults : { 3560 type : 'float', // 'float', 'inside', 'outside' or 'over', 3561 position : 'bottom' // 'top' or 'bottom' 3562 }, 3563 3564 beforeShow: function (opts) { 3565 var current = F.current, 3566 text = current.title, 3567 type = opts.type, 3568 title, 3569 target; 3570 3571 if ($.isFunction(text)) { 3572 text = text.call(current.element, current); 3573 } 3574 3575 if (!isString(text) || $.trim(text) === '') { 3576 return; 3577 } 3578 3579 title = $('<div class="fancybox-title fancybox-title-' + type + '-wrap">
3579' + text + '</div>'); 3580 3581 switch (type) { 3582 case 'inside': 3583 target = F.skin; 3584 break; 3585 3586 case 'outside': 3587 target = F.wrap; 3588 break; 3589 3590 case 'over': 3591 target = F.inner; 3592 break; 3593 3594 default: // 'float' 3595 target = F.skin; 3596 3597 title.appendTo('body'); 3598 3599 if (IE) { 3600 title.width( title.width() ); 3601 } 3602 3603 title.wrapInner('<span class="child"></span>'); 3604 3605 //Increase bottom margin so this title will also fit into viewport 3606 F.current.margin[2] += Math.abs( getScalar(title.css('margin-bottom')) ); 3607 break; 3608 } 3609 3610 title[ (opts.position === 'top' ? 'prependTo' : 'appendTo') ](target); 3611 } 3612 }; 3613 3614 // jQuery plugin initialization 3615 $.fn.fancybox = function (options) { 3616 var index, 3617 that = $(this), 3618 selector = this.selector || '', 3619 run = function(e) { 3620 var what = $(this).blur(), idx = index, relType, relVal; 3621 3622 if (!(e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) && !what.is('.fancybox-wrap')) { 3623 relType = options.groupAttr || 'data-fancybox-group'; 3624 relVal = what.attr(relType); 3625 3626 if (!relVal) { 3627 relType = 'rel'; 3628 relVal = what.get(0)[ relType ]; 3629 } 3630 3631 if (relVal && relVal !== '' && relVal !== 'nofollow') { 3632 what = selector.length ? $(selector) : that; 3633 what = what.filter('[' + relType + '="' + relVal + '"]'); 3634 idx = what.index(this); 3635 } 3636 3637 options.index = idx; 3638 3639 // Stop an event from bubbling if everything is fine 3640 if (F.open(what, options) !== false) { 3641 e.preventDefault(); 3642 } 3643 } 3644 }; 3645 3646 options = options || {}; 3647 index = options.index || 0; 3648 3649 if (!selector || options.live === false) { 3650 that.unbind('click.fb-start').bind('click.fb-start', run); 3651 3652 } else { 3653 D.undelegate(selector, 'click.fb-start').delegate(selector + ":not('.fancybox-item, .fancybox-nav')", 'click.fb-start', run); 3654 } 3655 3656 this.filter('[data-fancybox-start=1]').trigger('click'); 3657 3658 return this; 3659 }; 3660 3661 // Tests that need a body at doc ready 3662 D.ready(function() { 3663 var w1, w2; 3664 3665 if ( $.scrollbarWidth === undefined ) { 3666 // http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth 3667 $.scrollbarWidth = function() { 3668 var parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body'), 3669 child = parent.children(), 3670 width = child.innerWidth() - child.height( 99 ).innerWidth(); 3671 3672 parent.remove(); 3673 3674 return width; 3675 }; 3676 } 3677 3678 if ( $.support.fixedPosition === undefined ) { 3679 $.support.fixedPosition = (function() { 3680 var elem = $('<div style="position:fixed;top:20px;"></div>').appendTo('body'), 3681 fixed = ( elem[0].offsetTop === 20 || elem[0].offsetTop === 15 ); 3682 3683 elem.remove(); 3684 3685 return fixed; 3686 }()); 3687 } 3688 3689 $.extend(F.defaults, { 3690 scrollbarWidth : $.scrollbarWidth(), 3691 fixed : $.support.fixedPosition, 3692 parent : $('body') 3693 }); 3694 3695 //Get real width of page scroll-bar 3696 w1 = $(window).width(); 3697 3698 H.addClass('fancybox-lock-test'); 3699 3700 w2 = $(window).width(); 3701 3702 H.removeClass('fancybox-lock-test'); 3703 3704 $("<style type='text/css'>.fancybox-margin{margin-right:" + (w2 - w1) + "px;}</style>").appendTo("head"); 3705 }); 3706 3707}(window, document, jQuery)); 3708 3709 3710 3711/* 3712* MIXITUP - A CSS3 and JQuery Filter & Sort Plugin 3713* Version: 1.5.5 3714* License: Creative Commons Attribution-NoDerivs 3.0 Unported - CC BY-ND 3.0 3715* http://creativecommons.org/licenses/by-nd/3.0/ 3716* This software may be used freely on commercial and non-commercial projects with attribution to the author/copyright holder. 3717* Author: Patrick Kunka 3718* Copyright 2012-2013 Patrick Kunka, Barrel LLC, All Rights Reserved 3719* 3720* http://mixitup.io 3721*/ 3722 3723(function($){ 3724 3725 // DECLARE METHODS 3726 3727 var methods = { 3728 3729 // "INIT" METHOD 3730 3731 init: function(settings){ 3732 3733 return this.each(function(){ 3734 3735 var browser = window.navigator.appVersion.match(/Chrome\/(\d+)\./), 3736 ver = browser ? parseInt(browser[1], 10) : false, 3737 chromeFix = function(id){ 3738 var grid = document.getElementById(id), 3739 parent = grid.parentElement, 3740 placeholder = document.createElement('div'), 3741 frag = document.createDocumentFragment(); 3742 3743 parent.insertBefore(placeholder, grid); 3744 frag.appendChild(grid); 3745 parent.replaceChild(grid, placeholder); 3746 frag = null; 3747 placeholder = null; 3748 }; 3749 3750 if(ver && ver == 31 || ver == 32){ 3751 chromeFix(this.id); 3752 }; 3753 3754 // BUILD CONFIG OBJECT 3755 3756 var config = { 3757 3758 // PUBLIC PROPERTIES 3759 3760 targetSelector : '.mix', 3761 filterSelector : '.filter', 3762 sortSelector : '.sort', 3763 buttonEvent: 'click', 3764 effects : ['fade', 'scale'],
3765 listEffects : null, 3766 easing : 'smooth', 3767 layoutMode: 'grid', 3768 targetDisplayGrid : 'inline-block', 3769 targetDisplayList: 'block', 3770 listClass : '', 3771 gridClass : '', 3772 transitionSpeed : 600, 3773 showOnLoad : 'all', 3774 sortOnLoad : false, 3775 multiFilter : false, 3776 filterLogic : 'or', 3777 resizeContainer : true, 3778 minHeight : 0, 3779 failClass : 'fail', 3780 perspectiveDistance : '3000', 3781 perspectiveOrigin : '50% 50%', 3782 animateGridList : true, 3783 onMixLoad: null, 3784 onMixStart : null, 3785 onMixEnd : null, 3786 3787 // MISC 3788 3789 container : null, 3790 origOrder : [], 3791 startOrder : [], 3792 newOrder : [], 3793 origSort: [], 3794 checkSort: [], 3795 filter : '', 3796 mixing : false, 3797 origDisplay : '', 3798 origLayout: '', 3799 origHeight : 0, 3800 newHeight : 0, 3801 isTouch : false, 3802 resetDelay : 0, 3803 failsafe : null, 3804 3805 // CSS 3806 3807 prefix : '', 3808 easingFallback : 'ease-in-out', 3809 transition : {}, 3810 perspective : {}, 3811 clean : {}, 3812 fade : '1', 3813 scale : '', 3814 rotateX : '', 3815 rotateY : '', 3816 rotateZ : '', 3817 blur : '', 3818 grayscale : '' 3819 }; 3820 3821 if(settings){ 3822 $.extend(config, settings); 3823 }; 3824 3825 // ADD CONFIG OBJECT TO CONTAINER OBJECT PER INSTANTIATION 3826 3827 this.config = config; 3828 3829 // DETECT TOUCH 3830 3831 $.support.touch = 'ontouchend' in document; 3832 3833 if ($.support.touch) { 3834 config.isTouch = true; 3835 config.resetDelay = 350; 3836 }; 3837 3838 // LOCALIZE CONTAINER 3839 3840 config.container = $(this); 3841 var $cont = config.container; 3842 3843 // GET VENDOR PREFIX 3844 3845 config.prefix = prefix($cont[0]); 3846 config.prefix = config.prefix ? '-'+config.prefix.toLowerCase()+'-' : ''; 3847 3848 // CACHE 'DEFAULT' SORTING ORDER 3849 3850 $cont.find(config.targetSelector).each(function(){ 3851 config.origOrder.push($(this)); 3852 }); 3853 3854 // PERFORM SORT ON LOAD 3855 3856 if(config.sortOnLoad){ 3857 var sortby, order; 3858 if($.isArray(config.sortOnLoad)){ 3859 sortby = config.sortOnLoad[0], order = config.sortOnLoad[1]; 3860 $(config.sortSelector+'[data-sort='+config.sortOnLoad[0]+'][data-order='+config.sortOnLoad[1]+']').addClass('active'); 3861 } else { 3862 $(config.sortSelector+'[data-sort='+config.sortOnLoad+']').addClass('active'); 3863 sortby = config.sortOnLoad, config.sortOnLoad = 'desc'; 3864 }; 3865 sort(sortby, order, $cont, config); 3866 }; 3867 3868 // BUILD TRANSITION AND PERSPECTIVE OBJECTS 3869 3870 for(var i = 0; i<2; i++){ 3871 var a = i==0 ? a = config.prefix : ''; 3872 config.transition[a+'transition'] = 'all '+config.transitionSpeed+'ms ease-in-out'; 3873 config.perspective[a+'perspective'] = config.perspectiveDistance+'px'; 3874 config.perspective[a+'perspective-origin'] = config.perspectiveOrigin; 3875 }; 3876 3877 // BUILD TRANSITION CLEANER 3878 3879 for(var i = 0; i<2; i++){ 3880 var a = i==0 ? a = config.prefix : ''; 3881 config.clean[a+'transition'] = 'none'; 3882 }; 3883 3884 // CHOOSE GRID OR LIST 3885 3886 if(config.layoutMode == 'list'){ 3887 $cont.addClass(config.listClass); 3888 config.origDisplay = config.targetDisplayList; 3889 } else { 3890 $cont.addClass(config.gridClass); 3891 config.origDisplay = config.targetDisplayGrid; 3892 }; 3893 config.origLayout = config.layoutMode; 3894 3895 // PARSE 'SHOWONLOAD' 3896 3897 var showOnLoadArray = config.showOnLoad.split(' '); 3898 3899 // GIVE ACTIVE FILTER ACTIVE CLASS 3900 3901 $.each(showOnLoadArray, function(){ 3902 $(config.filterSelector+'[data-filter="'+this+'"]').addClass('active'); 3903 }); 3904 3905 // RENAME "ALL" CATEGORY TO "MIX_ALL" 3906 3907 $cont.find(config.targetSelector).addClass('mix_all'); 3908 if(showOnLoadArray[0] == 'all'){ 3909 showOnLoadArray[0] = 'mix_all', 3910 config.showOnLoad = 'mix_all'; 3911 }; 3912 3913 // FADE IN 'SHOWONLOAD' 3914 3915 var $showOnLoad = $(); 3916 $.each(showOnLoadArray, function(){ 3917 $showOnLoad = $showOnLoad.add($('.'+this)) 3918 }); 3919 3920 $showOnLoad.each(function(){ 3921 var $t = $(this); 3922 if(config.layoutMode == 'list'){ 3923 $t.css('display',config.targetDisplayList); 3924 } else { 3925 $t.css('display',config.targetDisplayGrid); 3926 }; 3927 $t.css(config.transition); 3928 }); 3929 3930 // WRAP FADE-IN TO PREVENT RACE CONDITION 3931
3932 var delay = setTimeout(function(){ 3933 3934 config.mixing = true; 3935 3936 $showOnLoad.css('opacity','1'); 3937 3938 // CLEAN UP 3939 3940 var reset = setTimeout(function(){ 3941 if(config.layoutMode == 'list'){ 3942 $showOnLoad.removeStyle(config.prefix+'transition, transition').css({ 3943 display: config.targetDisplayList, 3944 opacity: 1 3945 }); 3946 } else { 3947 $showOnLoad.removeStyle(config.prefix+'transition, transition').css({ 3948 display: config.targetDisplayGrid, 3949 opacity: 1 3950 }); 3951 }; 3952 3953 // FIRE "ONMIXLOAD" CALLBACK 3954 3955 config.mixing = false; 3956 3957 if(typeof config.onMixLoad == 'function') { 3958 var output = config.onMixLoad.call(this, config); 3959 3960 // UPDATE CONFIG IF DATA RETURNED 3961 3962 config = output ? output : config; 3963 }; 3964 3965 },config.transitionSpeed); 3966 },10); 3967 3968 // PRESET ACTIVE FILTER 3969 3970 config.filter = config.showOnLoad; 3971 3972 // BIND SORT CLICK HANDLERS 3973 3974 $(config.sortSelector).bind(config.buttonEvent,function(){ 3975 3976 if(!config.mixing){ 3977 3978 // PARSE SORT ARGUMENTS FROM BUTTON CLASSES 3979 3980 var $t = $(this), 3981 sortby = $t.attr('data-sort'), 3982 order = $t.attr('data-order'); 3983 3984 if(!$t.hasClass('active')){ 3985 $(config.sortSelector).removeClass('active'); 3986 $t.addClass('active'); 3987 } else { 3988 if(sortby != 'random')return false; 3989 }; 3990 3991 $cont.find(config.targetSelector).each(function(){ 3992 config.startOrder.push($(this)); 3993 }); 3994 3995 goMix(config.filter,sortby,order,$cont, config); 3996 3997 }; 3998 3999 }); 4000 4001 // BIND FILTER CLICK HANDLERS 4002 4003 $(config.filterSelector).bind(config.buttonEvent,function(){ 4004 4005 if(!config.mixing){ 4006 4007 var $t = $(this); 4008 4009 // PARSE FILTER ARGUMENTS FROM BUTTON CLASSES 4010 4011 if(config.multiFilter == false){ 4012 4013 // SINGLE ACTIVE BUTTON 4014 4015 $(config.filterSelector).removeClass('active'); 4016 $t.addClass('active'); 4017 4018 config.filter = $t.attr('data-filter'); 4019 4020 $(config.filterSelector+'[data-filter="'+config.filter+'"]').addClass('active'); 4021 4022 } else { 4023 4024 // MULTIPLE ACTIVE BUTTONS 4025 4026 var thisFilter = $t.attr('data-filter'); 4027 4028 if($t.hasClass('active')){ 4029 $t.removeClass('active'); 4030 4031 // REMOVE FILTER FROM SPACE-SEPERATED STRING 4032 4033 var re = new RegExp('(\\s|^)'+thisFilter); 4034 config.filter = config.filter.replace(re,''); 4035 } else { 4036 4037 // ADD FILTER TO SPACE-SEPERATED STRING 4038 4039 $t.addClass('active'); 4040 config.filter = config.filter+' '+thisFilter; 4041 4042 }; 4043 }; 4044 4045 // GO MIX 4046 4047 goMix(config.filter, null, null, $cont, config); 4048 4049 }; 4050 4051 }); 4052 4053 }); 4054 }, 4055 4056 // "TOGRID" METHOD 4057 4058 toGrid: function(){ 4059 return this.each(function(){ 4060 var config = this.config; 4061 if(config.layoutMode != 'grid'){ 4062 config.layoutMode = 'grid'; 4063 goMix(config.filter, null, null, $(this), config); 4064 }; 4065 }); 4066 }, 4067 4068 // "TOLIST" METHOD 4069 4070 toList: function(){ 4071 return this.each(function(){ 4072 var config = this.config; 4073 if(config.layoutMode != 'list'){ 4074 config.layoutMode = 'list'; 4075 goMix(config.filter, null, null, $(this), config); 4076 }; 4077 }); 4078 }, 4079 4080 // "FILTER" METHOD 4081 4082 filter: function(arg){ 4083 return this.each(function(){ 4084 var config = this.config; 4085 if(!config.mixing){ 4086 $(config.filterSelector).removeClass('active'); 4087 $(config.filterSelector+'[data-filter="'+arg+'"]').addClass('active'); 4088 goMix(arg, null, null, $(this), config); 4089 }; 4090 }); 4091 }, 4092 4093 // "SORT" METHOD 4094 4095 sort: function(args){ 4096 return this.each(function(){ 4097 var config = this.config, 4098 $t = $(this); 4099 if(!config.mixing){ 4100 $(config.sortSelector).removeClass('active'); 4101 if($.isArray(args)){ 4102 var sortby = args[0], order = args[1]; 4103 $(config.sortSelector+'[data-sort="'+args[0]+'"][data-order="'+args[1]+'"]').addClass('active'); 4104 } else { 4105 $(config.sortSelector+'[data-sort="'+args+'"]').addClass('active'); 4106 var sortby = args, order = 'desc'; 4107 }; 4108 $t.find(config.targetSelector).each(function(){ 4109 config.startOrder.push($(this)); 4110 });
4111 4112 goMix(config.filter,sortby,order, $t, config); 4113 4114 }; 4115 }); 4116 }, 4117 4118 // "MULTIMIX" METHOD 4119 4120 multimix: function(args){ 4121 return this.each(function(){ 4122 var config = this.config, 4123 $t = $(this); 4124 multiOut = { 4125 filter: config.filter, 4126 sort: null, 4127 order: 'desc', 4128 layoutMode: config.layoutMode 4129 }; 4130 $.extend(multiOut, args); 4131 if(!config.mixing){ 4132 $(config.filterSelector).add(config.sortSelector).removeClass('active'); 4133 $(config.filterSelector+'[data-filter="'+multiOut.filter+'"]').addClass('active'); 4134 if(typeof multiOut.sort !== 'undefined'){ 4135 $(config.sortSelector+'[data-sort="'+multiOut.sort+'"][data-order="'+multiOut.order+'"]').addClass('active'); 4136 $t.find(config.targetSelector).each(function(){ 4137 config.startOrder.push($(this)); 4138 }); 4139 }; 4140 config.layoutMode = multiOut.layoutMode; 4141 goMix(multiOut.filter,multiOut.sort,multiOut.order, $t, config); 4142 }; 4143 }); 4144 }, 4145 4146 // "REMIX" METHOD 4147 4148 remix: function(arg){ 4149 return this.each(function(){ 4150 var config = this.config, 4151 $t = $(this); 4152 config.origOrder = []; 4153 $t.find(config.targetSelector).each(function(){ 4154 var $th = $(this); 4155 $th.addClass('mix_all'); 4156 config.origOrder.push($th); 4157 }); 4158 if(!config.mixing && typeof arg !== 'undefined'){ 4159 $(config.filterSelector).removeClass('active'); 4160 $(config.filterSelector+'[data-filter="'+arg+'"]').addClass('active'); 4161 goMix(arg, null, null, $t, config); 4162 }; 4163 }); 4164 } 4165 }; 4166 4167 // DECLARE PLUGIN 4168 4169 $.fn.mixitup = function(method, arg){ 4170 if (methods[method]) { 4171 return methods[method].apply( this, Array.prototype.slice.call(arguments,1)); 4172 } else if (typeof method === 'object' || ! method){ 4173 return methods.init.apply( this, arguments ); 4174 }; 4175 }; 4176 4177 /* ==== THE MAGIC ==== */ 4178 4179 function goMix(filter, sortby, order, $cont, config){ 4180 4181 // WE ARE NOW MIXING 4182 4183 clearInterval(config.failsafe); 4184 config.mixing = true; 4185 4186 // APPLY ARGS TO CONFIG 4187 4188 config.filter = filter; 4189 4190 // FIRE "ONMIXSTART" CALLBACK 4191 4192 if(typeof config.onMixStart == 'function') { 4193 var output = config.onMixStart.call(this, config); 4194 4195 // UPDATE CONFIG IF DATA RETURNED 4196 4197 config = output ? output : config; 4198 }; 4199 4200 // SHORT LOCAL VARS 4201 4202 var speed = config.transitionSpeed; 4203 4204 // REBUILD TRANSITION AND PERSPECTIVE OBJECTS 4205 4206 for(var i = 0; i<2; i++){ 4207 var a = i==0 ? a = config.prefix : ''; 4208 config.transition[a+'transition'] = 'all '+speed+'ms linear'; 4209 config.transition[a+'transform'] = a+'translate3d(0,0,0)'; 4210 config.perspective[a+'perspective'] = config.perspectiveDistance+'px'; 4211 config.perspective[a+'perspective-origin'] = config.perspectiveOrigin; 4212 }; 4213 4214 // CACHE TARGET ELEMENTS FOR QUICK ACCESS 4215 4216 var mixSelector = config.targetSelector, 4217 $targets = $cont.find(mixSelector); 4218 4219 // ADD DATA OBJECT TO EACH TARGET 4220 4221 $targets.each(function(){ 4222 this.data = {}; 4223 }); 4224 4225 // RE-DEFINE CONTAINER INCASE NOT IMMEDIATE PARENT OF TARGET ELEMENTS 4226 4227 var $par = $targets.parent(); 4228
4229 // ADD PERSPECTIVE TO CONTAINER 4230 4231 $par.css(config.perspective); 4232 4233 // SETUP EASING 4234 4235 config.easingFallback = 'ease-in-out'; 4236 if(config.easing == 'smooth')config.easing = 'cubic-bezier(0.25, 0.46, 0.45, 0.94)'; 4237 if(config.easing == 'snap')config.easing = 'cubic-bezier(0.77, 0, 0.175, 1)'; 4238 if(config.easing == 'windback'){ 4239 config.easing = 'cubic-bezier(0.175, 0.885, 0.320, 1.275)', 4240 config.easingFallback = 'cubic-bezier(0.175, 0.885, 0.320, 1)'; // Fall-back for old webkit, with no values > 1 or < 1 4241 }; 4242 if(config.easing == 'windup'){ 4243 config.easing = 'cubic-bezier(0.6, -0.28, 0.735, 0.045)', 4244 config.easingFallback = 'cubic-bezier(0.6, 0.28, 0.735, 0.045)'; 4245 }; 4246 4247 // USE LIST SPECIFIC EFFECTS IF DECLARED 4248 4249 var effectsOut = config.layoutMode == 'list' && config.listEffects != null ? config.listEffects : config.effects; 4250 4251 // BUILD EFFECTS STRINGS & SKIP IF IE8 4252 4253 if (Array.prototype.indexOf){ 4254 config.fade = effectsOut.indexOf('fade') > -1 ? '0' : ''; 4255 config.scale = effectsOut.indexOf('scale') > -1 ? 'scale(.01)' : ''; 4256 config.rotateZ = effectsOut.indexOf('rotateZ') > -1 ? 'rotate(180deg)' : ''; 4257 config.rotateY = effectsOut.indexOf('rotateY') > -1 ? 'rotateY(90deg)' : ''; 4258 config.rotateX = effectsOut.indexOf('rotateX') > -1 ? 'rotateX(90deg)' : ''; 4259 config.blur = effectsOut.indexOf('blur') > -1 ? 'blur(8px)' : ''; 4260 config.grayscale = effectsOut.indexOf('grayscale') > -1 ? 'grayscale(100%)' : ''; 4261 }; 4262 4263 // DECLARE NEW JQUERY OBJECTS FOR GROUPING 4264 4265 var $show = $(), 4266 $hide = $(), 4267 filterArray = [], 4268 multiDimensional = false; 4269 4270 // BUILD FILTER ARRAY(S) 4271 4272 if(typeof filter === 'string'){ 4273 4274 // SINGLE DIMENSIONAL FILTERING 4275 4276 filterArray = buildFilterArray(filter); 4277 4278 } else { 4279 4280 // MULTI DIMENSIONAL FILTERING 4281 4282 multiDimensional = true; 4283 4284 $.each(filter,function(i){ 4285 filterArray[i] = buildFilterArray(this); 4286 }); 4287 }; 4288 4289 // "OR" LOGIC (DEFAULT) 4290 4291 if(config.filterLogic == 'or'){ 4292 4293 if(filterArray[0] == '') filterArray.shift(); // IF FIRST ITEM IN ARRAY IS AN EMPTY SPACE, DELETE 4294 4295 // IF NO ELEMENTS ARE DESIRED THEN HIDE ALL VISIBLE ELEMENTS 4296 4297 if(filterArray.length < 1){ 4298 4299 $hide = $hide.add($cont.find(mixSelector+':visible')); 4300 4301 } else { 4302 4303 // ELSE CHECK EACH TARGET ELEMENT FOR ANY FILTER CATEGORY: 4304 4305 $targets.each(function(){ 4306 var $t = $(this); 4307 if(!multiDimensional){ 4308 // IF HAS ANY FILTER, ADD TO "SHOW" OBJECT 4309 if($t.is('.'+filterArray.join(', .'))){ 4310 $show = $show.add($t); 4311 // ELSE IF HAS NO FILTERS, ADD TO "HIDE" OBJECT 4312 } else { 4313 $hide = $hide.add($t); 4314 }; 4315 } else { 4316 4317 var pass = 0; 4318 // FOR EACH DIMENSION 4319 4320 $.each(filterArray,function(i){ 4321 if(this.length){ 4322 if($t.is('.'+this.join(', .'))){ 4323 pass++ 4324 }; 4325 } else if(pass > 0){ 4326 pass++; 4327 }; 4328 }); 4329 // IF PASSES ALL DIMENSIONS, SHOW 4330 if(pass == filterArray.length){ 4331 $show = $show.add($t); 4332 // ELSE HIDE 4333 } else { 4334 $hide = $hide.add($t); 4335 }; 4336 }; 4337 }); 4338 4339 }; 4340 4341 } else { 4342 4343 // "AND" LOGIC 4344 4345 // ADD "MIX_SHOW" CLASS TO ELEMENTS THAT HAVE ALL FILTERS 4346 4347 $show = $show.add($par.find(mixSelector+'.'+filterArray.join('.'))); 4348 4349 // ADD "MIX_HIDE" CLASS TO EVERYTHING ELSE 4350 4351 $hide = $hide.add($par.find(mixSelector+':not(.'+filterArray.join('.')+'):visible')); 4352 }; 4353 4354 // GET TOTAL NUMBER OF ELEMENTS TO SHOW 4355 4356 var total = $show.length; 4357 4358 // DECLARE NEW JQUERY OBJECTS 4359 4360 var $tohide = $(), 4361 $toshow = $(), 4362 $pre = $(); 4363
4364 // FOR ELEMENTS TO BE HIDDEN, IF NOT ALREADY HIDDEN THEN ADD TO OBJECTS "TOHIDE" AND "PRE" 4365 // TO INDICATE PRE-EXISTING ELEMENTS TO BE HIDDEN 4366 4367 $hide.each(function(){ 4368 var $t = $(this); 4369 if($t.css('display') != 'none'){ 4370 $tohide = $tohide.add($t); 4371 $pre = $pre.add($t); 4372 }; 4373 }); 4374 4375 // IF ALL ELEMENTS ARE ALREADY SHOWN AND THERE IS NOTHING TO HIDE, AND NOT PERFORMING A LAYOUT CHANGE OR SORT: 4376 4377 if($show.filter(':visible').length == total && !$tohide.length && !sortby){ 4378 4379 if(config.origLayout == config.layoutMode){ 4380 4381 // THEN CLEAN UP AND GO HOME 4382 4383 resetFilter(); 4384 return false; 4385 } else { 4386 4387 // IF ONLY ONE ITEM AND CHANGING FORM GRID TO LIST, MOST LIKELY POSITION WILL NOT CHANGE SO WE'RE DONE 4388 4389 if($show.length == 1){ 4390 4391 if(config.layoutMode == 'list'){ 4392 $cont.addClass(config.listClass); 4393 $cont.removeClass(config.gridClass); 4394 $pre.css('display',config.targetDisplayList); 4395 } else { 4396 $cont.addClass(config.gridClass); 4397 $cont.removeClass(config.listClass); 4398 $pre.css('display',config.targetDisplayGrid); 4399 }; 4400 4401 // THEN CLEAN UP AND GO HOME 4402 4403 resetFilter(); 4404 return false; 4405 } 4406 }; 4407 }; 4408 4409 // GET CONTAINER'S STARTING HEIGHT 4410 4411 config.origHeight = $par.height(); 4412 4413 // IF THERE IS SOMETHING TO BE SHOWN: 4414 4415 if($show.length){ 4416 4417 // REMOVE "FAIL CLASS" FROM CONTAINER IF EXISTS 4418 4419 $cont.removeClass(config.failClass); 4420 4421 4422 // FOR ELEMENTS TO BE SHOWN, IF NOT ALREADY SHOWN THEN ADD TO OBJECTS "TOSHOW" ELSE ADD CLASS "MIX_PRE" 4423 // TO INDICATE PRE-EXISTING ELEMENT 4424 4425 $show.each(function(){ 4426 var $t = $(this); 4427 if($t.css('display') == 'none'){ 4428 $toshow = $toshow.add($t) 4429 } else { 4430 $pre = $pre.add($t); 4431 }; 4432 }); 4433 4434 // IF NON-ANIMATED LAYOUT MODE TRANSITION: 4435 4436 if((config.origLayout != config.layoutMode) && config.animateGridList == false){ 4437 4438 // ADD NEW DISPLAY TYPES, CLEAN UP AND GO HOME 4439 4440 if(config.layoutMode == 'list'){ 4441 $cont.addClass(config.listClass); 4442 $cont.removeClass(config.gridClass); 4443 $pre.css('display',config.targetDisplayList); 4444 } else { 4445 $cont.addClass(config.gridClass); 4446 $cont.removeClass(config.listClass); 4447 $pre.css('display',config.targetDisplayGrid); 4448 }; 4449 4450 resetFilter(); 4451 return false; 4452 }; 4453 4454 // IF IE, FUCK OFF, AND THEN CLEAN UP AND GO HOME 4455 4456 if(!window.atob){ 4457 resetFilter(); 4458 return false; 4459 }; 4460 4461 // OVERRIDE ANY EXISTING TRANSITION TIMING FOR CALCULATIONS 4462 4463 $targets.css(config.clean); 4464 4465 // FOR EACH PRE-EXISTING ELEMENT, ADD STARTING POSITION TO 'ORIGPOS' ARRAY 4466 4467 $pre.each(function(){ 4468 this.data.origPos = $(this).offset(); 4469 }); 4470 4471 // TEMPORARILY SHOW ALL ELEMENTS TO SHOW (THAT ARE NOT ALREADY SHOWN), WITHOUT HIDING ELEMENTS TO HIDE 4472 // AND ADD/REMOVE GRID AND LIST CLASSES FROM CONTAINER 4473 4474 if(config.layoutMode == 'list'){ 4475 $cont.addClass(config.listClass); 4476 $cont.removeClass(config.gridClass); 4477 $toshow.css('display',config.targetDisplayList); 4478 } else { 4479 $cont.addClass(config.gridClass); 4480 $cont.removeClass(config.listClass); 4481 $toshow.css('display',config.targetDisplayGrid); 4482 }; 4483 4484 // FOR EACH ELEMENT NOW SHOWN, ADD ITS INTERMEDIATE POSITION TO 'SHOWINTERPOS' ARRAY 4485 4486 $toshow.each(function(){ 4487 this.data.showInterPos = $(this).offset(); 4488 }); 4489 4490 // FOR EACH ELEMENT TO BE HIDDEN, BUT NOT YET HIDDEN, AND NOW MOVED DUE TO SHOWN ELEMENTS, 4491 // ADD ITS INTERMEDIATE POSITION TO 'HIDEINTERPOS' ARRAY 4492 4493 $tohide.each(function(){ 4494 this.data.hideInterPos = $(this).offset(); 4495 }); 4496 4497 // FOR EACH PRE-EXISTING ELEMENT, NOW MOVED DUE TO SHOWN ELEMENTS, ADD ITS POSITION TO 'PREINTERPOS' ARRAY 4498 4499 $pre.each(function(){ 4500 this.data.preInterPos = $(this).offset(); 4501 }); 4502 4503 // SET DISPLAY PROPERTY OF PRE-EXISTING ELEMENTS INCASE WE ARE CHANGING LAYOUT MODE 4504 4505 if(config.layoutMode == 'list'){ 4506 $pre.css('display',config.targetDisplayList); 4507 } else { 4508 $pre.css('display',config.targetDisplayGrid); 4509 }; 4510 4511 // IF A SORT ARGUMENT HAS BEEN SENT, RUN SORT FUNCTION SO OBJECTS WILL MOVE TO THEIR FINAL ORDER 4512 4513 if(sortby){ 4514 sort(sortby, order, $cont, config); 4515 }; 4516 4517 // IF VISIBLE SORT ORDER IS THE SAME (WHICH WOULD NOT TRIGGER A TRANSITION EVENT) 4518 4519 if(sortby && compareArr(config.origSort, config.checkSort)){ 4520 4521 // THEN CLEAN UP AND GO HOME 4522 resetFilter(); 4523 return false; 4524 }; 4525 4526 // TEMPORARILY HIDE ALL SHOWN ELEMENTS TO HIDE 4527 4528 $tohide.hide(); 4529
4530 // FOR EACH ELEMENT TO SHOW, AND NOW MOVED DUE TO HIDDEN ELEMENTS BEING REMOVED, 4531 // ADD ITS POSITION TO 'FINALPOS' ARRAY 4532 4533 $toshow.each(function(i){ 4534 this.data.finalPos = $(this).offset(); 4535 }); 4536 4537 // FOR EACH PRE-EXISTING ELEMENT NOW MOVED DUE TO HIDDEN ELEMENTS BEING REMOVED, 4538 // ADD ITS POSITION TO 'FINALPREPOS' ARRAY 4539 4540 $pre.each(function(){ 4541 this.data.finalPrePos = $(this).offset(); 4542 }); 4543 4544 // SINCE WE ARE IN OUT FINAL STATE, GET NEW HEIGHT OF CONTAINER 4545 4546 config.newHeight = $par.height(); 4547 4548 // IF A SORT ARGUMENT AS BEEN SENT, RUN SORT FUNCTION 'RESET' TO MOVE ELEMENTS BACK TO THEIR STARTING ORDER 4549 4550 if(sortby){ 4551 sort('reset', null, $cont, config); 4552 }; 4553 4554 // RE-HIDE ALL ELEMENTS TEMPORARILY SHOWN 4555 4556 $toshow.hide(); 4557 4558 // SET DISPLAY PROPERTY OF PRE-EXISTING ELEMENTS BACK TO THEIR 4559 // ORIGINAL PROPERTY, INCASE WE ARE CHANGING LAYOUT MODE 4560 4561 $pre.css('display',config.origDisplay); 4562 4563 // ADD/REMOVE GRID AND LIST CLASSES FROM CONTAINER 4564 4565 if(config.origDisplay == 'block'){ 4566 $cont.addClass(config.listClass); 4567 $toshow.css('display', config.targetDisplayList); 4568 } else { 4569 $cont.removeClass(config.listClass); 4570 $toshow.css('display', config.targetDisplayGrid); 4571 }; 4572 4573 // IF WE ARE ANIMATING CONTAINER, RESET IT TO ITS STARTING HEIGHT 4574 4575 if(config.resizeContainer)$par.css('height', config.origHeight+'px'); 4576 4577 // ADD TRANSFORMS TO ALL ELEMENTS TO SHOW 4578 4579 var toShowCSS = {}; 4580 4581 for(var i = 0; i<2; i++){ 4582 var a = i==0 ? a = config.prefix : ''; 4583 toShowCSS[a+'transform'] = config.scale+' '+config.rotateX+' '+config.rotateY+' '+config.rotateZ; 4584 toShowCSS[a+'filter'] = config.blur+' '+config.grayscale; 4585 }; 4586 4587 $toshow.css(toShowCSS); 4588 4589 // FOR EACH PRE-EXISTING ELEMENT, SUBTRACT ITS INTERMEDIATE POSITION FROM ITS ORIGINAL POSITION 4590 // TO GET ITS STARTING OFFSET 4591 4592 $pre.each(function(){ 4593 var data = this.data, 4594 $t = $(this); 4595 4596 if ($t.hasClass('mix_tohide')){ 4597 data.preTX = data.origPos.left - data.hideInterPos.left; 4598 data.preTY = data.origPos.top - data.hideInterPos.top; 4599 } else { 4600 data.preTX = data.origPos.left - data.preInterPos.left; 4601 data.preTY = data.origPos.top - data.preInterPos.top; 4602 }; 4603 var preCSS = {}; 4604 for(var i = 0; i<2; i++){ 4605 var a = i==0 ? a = config.prefix : ''; 4606 preCSS[a+'transform'] = 'translate('+data.preTX+'px,'+data.preTY+'px)'; 4607 }; 4608 4609 $t.css(preCSS); 4610 }); 4611 4612 // ADD/REMOVE GRID AND LIST CLASSES FROM CONTAINER 4613 4614 if(config.layoutMode == 'list'){ 4615 $cont.addClass(config.listClass); 4616 $cont.removeClass(config.gridClass); 4617 } else { 4618 $cont.addClass(config.gridClass); 4619 $cont.removeClass(config.listClass); 4620 }; 4621 4622 // WRAP ANIMATION FUNCTIONS IN 10ms TIMEOUT TO PREVENT RACE CONDITION 4623 4624 var delay = setTimeout(function(){ 4625 4626 // APPLY TRANSITION TIMING TO CONTAINER, AND BEGIN ANIMATION TO NEW HEIGHT 4627 4628 if(config.resizeContainer){ 4629 var containerCSS = {}; 4630 for(var i = 0; i<2; i++){ 4631 var a = i==0 ? a = config.prefix : ''; 4632 containerCSS[a+'transition'] = 'all '+speed+'ms ease-in-out'; 4633 containerCSS['height'] = config.newHeight+'px'; 4634 }; 4635 $par.css(containerCSS); 4636 }; 4637 4638 // BEGIN FADING IN/OUT OF ALL ELEMENTS TO SHOW/HIDE 4639 $tohide.css('opacity',config.fade); 4640 $toshow.css('opacity',1); 4641 4642 // FOR EACH ELEMENT BEING SHOWN, CALCULATE ITS TRAJECTORY BY SUBTRACTING 4643 // ITS INTERMEDIATE POSITION FROM ITS FINAL POSITION. 4644 // ALSO ADD SPEED AND EASING 4645 4646 $toshow.each(function(){ 4647 var data = this.data; 4648 data.tX = data.finalPos.left - data.showInterPos.left; 4649 data.tY = data.finalPos.top - data.showInterPos.top; 4650 4651 var toShowCSS = {}; 4652 for(var i = 0; i<2; i++){ 4653 var a = i==0 ? a = config.prefix : ''; 4654 toShowCSS[a+'transition-property'] = a+'transform, '+a+'filter, opacity'; 4655 toShowCSS[a+'transition-timing-function'] = config.easing+', linear, linear'; 4656 toShowCSS[a+'transition-duration'] = speed+'ms'; 4657 toShowCSS[a+'transition-delay'] = '0'; 4658 toShowCSS[a+'transform'] = 'translate('+data.tX+'px,'+data.tY+'px)'; 4659 toShowCSS[a+'filter'] = 'none'; 4660 }; 4661 4662 $(this).css('-webkit-transition', 'all '+speed+'ms '+config.easingFallback).css(toS
4662howCSS); 4663 }); 4664 4665 // FOR EACH PRE-EXISTING ELEMENT, IF IT HAS A FINAL POSITION, CALCULATE 4666 // ITS TRAJETORY BY SUBTRACTING ITS INTERMEDIATE POSITION FROM ITS FINAL POSITION. 4667 // ALSO ADD SPEED AND EASING 4668 4669 $pre.each(function(){ 4670 var data = this.data 4671 data.tX = data.finalPrePos.left != 0 ? data.finalPrePos.left - data.preInterPos.left : 0; 4672 data.tY = data.finalPrePos.left != 0 ? data.finalPrePos.top - data.preInterPos.top : 0; 4673 4674 var preCSS = {}; 4675 for(var i = 0; i<2; i++){ 4676 var a = i==0 ? a = config.prefix : ''; 4677 preCSS[a+'transition'] = 'all '+speed+'ms '+config.easing; 4678 preCSS[a+'transform'] = 'translate('+data.tX+'px,'+data.tY+'px)'; 4679 }; 4680 4681 $(this).css('-webkit-transition', 'all '+speed+'ms '+config.easingFallback).css(preCSS); 4682 }); 4683 4684 // BEGIN TRANSFORMS ON ALL ELEMENTS TO BE HIDDEN 4685 4686 var toHideCSS = {}; 4687 for(var i = 0; i<2; i++){ 4688 var a = i==0 ? a = config.prefix : ''; 4689 toHideCSS[a+'transition'] = 'all '+speed+'ms '+config.easing+', '+a+'filter '+speed+'ms linear, opacity '+speed+'ms linear'; 4690 toHideCSS[a+'transform'] = config.scale+' '+config.rotateX+' '+config.rotateY+' '+config.rotateZ; 4691 toHideCSS[a+'filter'] = config.blur+' '+config.grayscale; 4692 toHideCSS['opacity'] = config.fade; 4693 }; 4694 4695 $tohide.css(toHideCSS); 4696 4697 // ALL ANIMATIONS HAVE NOW BEEN STARTED, NOW LISTEN FOR TRANSITION END: 4698 4699 $par.bind('webkitTransitionEnd transitionend otransitionend oTransitionEnd',function(e){ 4700 4701 if (e.originalEvent.propertyName.indexOf('transform') > -1 || e.originalEvent.propertyName.indexOf('opacity') > -1){ 4702 4703 if(mixSelector.indexOf('.') > -1){ 4704 4705 // IF MIXSELECTOR IS A CLASS NAME 4706 4707 if($(e.target).hasClass(mixSelector.replace('.',''))){ 4708 resetFilter(); 4709 }; 4710 4711 } else { 4712 4713 // IF MIXSELECTOR IS A TAG 4714 4715 if($(e.target).is(mixSelector)){ 4716 resetFilter(); 4717 }; 4718 4719 }; 4720 4721 }; 4722 }); 4723 4724 },10); 4725 4726 // LAST RESORT EMERGENCY FAILSAFE 4727 4728 config.failsafe = setTimeout(function(){ 4729 if(config.mixing){ 4730 resetFilter(); 4731 }; 4732 }, speed + 400); 4733 4734 } else { 4735 4736 // ELSE IF NOTHING TO SHOW, AND EVERYTHING TO BE HIDDEN 4737 4738 // IF WE ARE RESIZING CONTAINER, SET ITS STARTING HEIGHT 4739 4740 if(config.resizeContainer)$par.css('height', config.origHeight+'px'); 4741 4742 // IF IE, FUCK OFF, AND THEN GO HOME 4743 4744 if(!window.atob){ 4745 resetFilter(); 4746 return false; 4747 }; 4748 4749 // GROUP ALL ELEMENTS TO HIDE INTO JQUERY OBJECT 4750 4751 $tohide = $hide; 4752 4753 // WRAP ANIMATION FUNCTIONS IN A 10ms DELAY TO PREVENT RACE CONDITION 4754 4755 var delay = setTimeout(function(){ 4756 4757 // APPLY PERSPECTIVE TO CONTAINER 4758 4759 $par.css(config.perspective); 4760 4761 // APPLY TRANSITION TIMING TO CONTAINER, AND BEGIN ANIMATION TO NEW HEIGHT 4762 4763 if(config.resizeContainer){ 4764 var containerCSS = {}; 4765 for(var i = 0; i<2; i++){ 4766 var a = i==0 ? a = config.prefix : ''; 4767 containerCSS[a+'transition'] = 'height '+speed+'ms ease-in-out'; 4768 containerCSS['height'] = config.minHeight+'px'; 4769 }; 4770 $par.css(containerCSS); 4771 }; 4772 4773 // APPLY TRANSITION TIMING TO ALL TARGET ELEMENTS 4774 4775 $targets.css(config.transition); 4776 4777 // GET TOTAL NUMBER OF ELEMENTS TO HIDE 4778 4779 var totalHide = $hide.length; 4780 4781 // IF SOMETHING TO HIDE: 4782 4783 if(totalHide){ 4784 4785 // BEGIN TRANSFORMS ON ALL ELEMENTS TO BE HIDDEN 4786 4787 var toHideCSS = {}; 4788 for(var i = 0; i<2; i++){ 4789 var a = i==0 ? a = config.prefix : ''; 4790 toHideCSS[a+'transform'] = config.scale+' '+config.rotateX+' '+config.rotateY+' '+config.rotateZ; 4791 toHideCSS[a+'filter'] = config.blur+' '+config.grayscale; 4792 toHideCSS['opacity'] = config.fade; 4793 }; 4794 4795 $tohide.css(toHideCSS); 4796 4797 // ALL ANIMATIONS HAVE NOW BEEN STARTED, NOW LISTEN FOR TRANSITION END: 4798 4799 $par.bind('webkitTransitionEnd transitionend otransitionend oTransitionEnd',function(e){
4800 if (e.originalEvent.propertyName.indexOf('transform') > -1 || e.originalEvent.propertyName.indexOf('opacity') > -1){ 4801 $cont.addClass(config.failClass); 4802 resetFilter(); 4803 }; 4804 }); 4805 4806 } else { 4807 4808 // ELSE, WE'RE DONE MIXING 4809 4810 config.mixing = false; 4811 }; 4812 4813 }, 10); 4814 }; 4815 4816 // CLEAN UP AND RESET FUNCTION 4817 4818 function resetFilter(){ 4819 4820 // UNBIND TRANSITION END EVENTS FROM CONTAINER 4821 4822 $par.unbind('webkitTransitionEnd transitionend otransitionend oTransitionEnd'); 4823 4824 // IF A SORT ARGUMENT HAS BEEN SENT, SORT ELEMENTS TO THEIR FINAL ORDER 4825 4826 if(sortby){ 4827 sort(sortby, order, $cont, config); 4828 }; 4829 4830 // EMPTY SORTING ARRAYS 4831 4832 config.startOrder = [], config.newOrder = [], config.origSort = [], config.checkSort = []; 4833 4834 // REMOVE INLINE STYLES FROM ALL TARGET ELEMENTS AND SLAM THE BRAKES ON 4835 4836 $targets.removeStyle( 4837 config.prefix+'filter, filter, '+config.prefix+'transform, transform, opacity, display' 4838 ).css(config.clean).removeAttr('data-checksum'); 4839 4840 // BECAUSE IE SUCKS 4841 4842 if(!window.atob){ 4843 $targets.css({ 4844 display: 'none', 4845 opacity: '0' 4846 }); 4847 }; 4848 4849 // REMOVE HEIGHT FROM CONTAINER ONLY IF RESIZING 4850 4851 var remH = config.resizeContainer ? 'height' : ''; 4852 4853 // REMOVE INLINE STYLES FROM CONTAINER 4854 4855 $par.removeStyle( 4856 config.prefix+'transition, transition, '+config.prefix+'perspective, perspective, '+config.prefix+'perspective-origin, perspective-origin, '+remH 4857 ); 4858 4859 // ADD FINAL DISPLAY PROPERTIES AND OPACITY TO ALL SHOWN ELEMENTS 4860 // CACHE CURRENT LAYOUT MODE & SORT FOR NEXT MIX 4861 4862 if(config.layoutMode == 'list'){ 4863 $show.css({display:config.targetDisplayList, opacity:'1'}); 4864 config.origDisplay = config.targetDisplayList; 4865 } else { 4866 $show.css({display:config.targetDisplayGrid, opacity:'1'}); 4867 config.origDisplay = config.targetDisplayGrid; 4868 }; 4869 config.origLayout = config.layoutMode; 4870 4871 var wait = setTimeout(function(){ 4872 4873 // LET GO OF THE BRAKES 4874 4875 $targets.removeStyle(config.prefix+'transition, transition'); 4876 4877 // WE'RE DONE MIXING 4878 4879 config.mixing = false; 4880 4881 // FIRE "ONMIXEND" CALLBACK 4882 4883 if(typeof config.onMixEnd == 'function') { 4884 var output = config.onMixEnd.call(this, config); 4885 4886 // UPDATE CONFIG IF DATA RETURNED 4887 4888 config = output ? output : config; 4889 }; 4890 }); 4891 }; 4892 }; 4893 4894 // SORT FUNCTION 4895 4896 function sort(sortby, order, $cont, config){ 4897 4898 // COMPARE BY ATTRIBUTE 4899 4900 function compare(a,b) { 4901 var sortAttrA = isNaN(a.attr(sortby) * 1) ? a.attr(sortby).toLowerCase() : a.attr(sortby) * 1, 4902 sortAttrB = isNaN(b.attr(sortby) * 1) ? b.attr(sortby).toLowerCase() : b.attr(sortby) * 1; 4903 if (sortAttrA < sortAttrB) 4904 return -1; 4905 if (sortAttrA > sortAttrB) 4906 return 1; 4907 return 0; 4908 }; 4909 4910 // REBUILD DOM 4911 4912 function rebuild(element){ 4913 if(order == 'asc'){ 4914 $sortWrapper.prepend(element).prepend(' '); 4915 } else { 4916 $sortWrapper.append(element).append(' '); 4917 }; 4918 }; 4919 4920 // RANDOMIZE ARRAY 4921 4922 function arrayShuffle(oldArray){ 4923 var newArray = oldArray.slice(); 4924 var len = newArray.length; 4925 var i = len; 4926 while (i--){ 4927 var p = parseInt(Math.random()*len); 4928 var t = newArray[i]; 4929 newArray[i] = newArray[p]; 4930 newArray[p] = t; 4931 }; 4932 return newArray; 4933 }; 4934 4935 // SORT 4936 4937 $cont.find(config.targetSelector).wrapAll('<div class="mix_sorter"/>'); 4938 4939 var $sortWrapper = $cont.find('.mix_sorter'); 4940 4941 if(!config.origSort.length){ 4942 $sortWrapper.find(config.targetSelector+':visible').each(function(){ 4943 $(this).wrap('<s/>'); 4944 config.origSort.push($(this).parent().html().replace(/\s+/g, '')); 4945 $(this).unwrap(); 4946 }); 4947 }; 4948 4949 4950 4951 $sortWrapper.empty(); 4952 4953 if(sortby == 'reset'){ 4954 $.each(config.startOrder,function(){ 4955 $sortWrapper.append(this).append(' '); 4956 }); 4957 } else if(sortby == 'default'){ 4958 $.each(config.origOrder,function(){ 4959 rebuild(this); 4960 }); 4961 } else if(sortby == 'random'){ 4962 if(!config.newOrder.length){ 4963 config.newOrder = arrayShuffle(config.startOrder); 4964 }; 4965 $.each(config.newOrder,function(){ 4966 $sortWrapper.append(this).append(' '); 4967 }); 4968 } else if(sortby == 'custom'){ 4969 $.each(order, function(){ 4970 rebuild(this); 4971 }); 4972 } else { 4973 // SORT BY ATTRIBUTE 4974 4975 if(typeof config.origOrder[0].attr(sortby) === 'undefined'){ 4976 console.log('No such attribute found. Terminating'); 4977 return false; 4978 }; 4979 4980 if(!config.newOrder.length){ 4981 $.each(config.origOrder,function(){ 4982 config.newOrder.push($(this)); 4983 }); 4984 config.newOrder.sort(compare); 4985 }; 4986 $.each(config.newOrder,function(){ 4987 rebuild(this); 4988 }); 4989 4990 }; 4991 config.checkSort = []; 4992 $sortWrapper.find(config.targetSelector+':visible').each(function(i){ 4993 var $t = $(this); 4994 if(i == 0){ 4995 4996 // PREVENT COMPARE RETURNING FALSE POSITIVES ON ELEMENTS WITH NO CLASS/ATTRIBUTES 4997 4998 $t.attr('data-checksum','1'); 4999 }; 5000 $t.wrap('<s/>');
5001 config.checkSort.push($t.parent().html().replace(/\s+/g, '')); 5002 $t.unwrap(); 5003 }); 5004 5005 $cont.find(config.targetSelector).unwrap(); 5006 }; 5007 5008 // FIND VENDOR PREFIX 5009 5010 function prefix(el) { 5011 var prefixes = ["Webkit", "Moz", "O", "ms"]; 5012 for (var i = 0; i < prefixes.length; i++){ 5013 if (prefixes[i] + "Transition" in el.style){ 5014 return prefixes[i]; 5015 }; 5016 }; 5017 return "transition" in el.style ? "" : false; 5018 }; 5019 5020 // REMOVE SPECIFIC STYLES 5021 5022 $.fn.removeStyle = function(style){ 5023 return this.each(function(){ 5024 var obj = $(this); 5025 style = style.replace(/\s+/g, ''); 5026 var styles = style.split(','); 5027 $.each(styles,function(){ 5028 5029 var search = new RegExp(this.toString() + '[^;]+;?', 'g'); 5030 obj.attr('style', function(i, style){ 5031 if(style) return style.replace(search, ''); 5032 }); 5033 }); 5034 }); 5035 }; 5036 5037 // COMPARE ARRAYS 5038 5039 function compareArr(a,b){ 5040 if (a.length != b.length) return false; 5041 for (var i = 0; i < b.length; i++){ 5042 if (a[i].compare) { 5043 if (!a[i].compare(b[i])) return false; 5044 }; 5045 if (a[i] !== b[i]) return false; 5046 }; 5047 return true; 5048 }; 5049 5050 // BUILD FILTER ARRAY(S) 5051 5052 function buildFilterArray(str){ 5053 // CLEAN FILTER STRING 5054 str = str.replace(/\s{2,}/g, ' '); 5055 // FOR EACH PEROID SEPERATED CLASS NAME, ADD STRING TO FILTER ARRAY 5056 var arr = str.split(' '); 5057 // IF ALL, REPLACE WITH MIX_ALL 5058 $.each(arr,function(i){ 5059 if(this == 'all')arr[i] = 'mix_all'; 5060 }); 5061 if(arr[0] == "")arr.shift(); 5062 return arr; 5063 }; 5064 5065 5066})(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.