clipbucket/upload/plugins/social_beast/admin/styles/js/main.js
2017-03-23 11:12:09 +05:00

3593 lines
No EOL
137 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// page init
jQuery(function(){
jcf.customForms.replaceAll('.custom-elements');
initCarousel();
initSlideShow();
initRating();
jQuery('input, textarea').placeholder();
});
// scroll gallery init
function initCarousel() {
jQuery('.slider').scrollGallery({
mask: '.mask',
slider: '.slideset',
slides: '.slide',
btnPrev: 'a.btn-prev',
btnNext: 'a.btn-next',
pagerLinks: '.slider-pagination li',
stretchSlideToMask: true,
maskAutoSize: true,
autoRotation: true,
switchTime: 3000,
animSpeed: 500,
step: 1
});
}
// fade galleries init
function initSlideShow() {
jQuery('.slideshow').fadeGallery({
slides: '.slide',
btnPrev: 'a.btn-prev',
btnNext: 'a.btn-next',
pagerLinks: '.slideshow-pagination li',
event: 'click',
useSwipe: true,
autoRotation: true,
autoHeight: true,
switchTime: 6000,
animSpeed: 5000
});
jQuery('.visual').fadeGallery({
slides: '.slide',
btnPrev: 'a.btn-prev',
btnNext: 'a.btn-next',
pagerLinks: '.visual-pagination li',
event: 'click',
useSwipe: true,
autoRotation: true,
autoHeight: true,
switchTime: 3000,
animSpeed: 500
});
}
// star rating init
function initRating() {
lib.each(lib.queryElementsBySelector('ul.star-rating'), function(){
new StarRating({
element:this,
onselect:function(num) {
// rating setted event
}
});
});
}
/*
* jQuery Carousel plugin
*/
;(function($){
function ScrollGallery(options) {
this.options = $.extend({
mask: 'div.mask',
slider: '>*',
slides: '>*',
activeClass:'active',
disabledClass:'disabled',
btnPrev: 'a.btn-prev',
btnNext: 'a.btn-next',
generatePagination: false,
pagerList: '<ul>',
pagerListItem: '<li><a href="#"></a></li>',
pagerListItemText: 'a',
pagerLinks: '.pagination li',
currentNumber: 'span.current-num',
totalNumber: 'span.total-num',
btnPlay: '.btn-play',
btnPause: '.btn-pause',
btnPlayPause: '.btn-play-pause',
galleryReadyClass: 'gallery-js-ready',
autorotationActiveClass: 'autorotation-active',
autorotationDisabledClass: 'autorotation-disabled',
stretchSlideToMask: false,
circularRotation: true,
disableWhileAnimating: false,
autoRotation: false,
pauseOnHover: isTouchDevice ? false : true,
maskAutoSize: false,
switchTime: 4000,
animSpeed: 600,
event:'click',
swipeThreshold: 15,
handleTouch: true,
vertical: false,
useTranslate3D: false,
step: false
}, options);
this.init();
}
ScrollGallery.prototype = {
init: function() {
if(this.options.holder) {
this.findElements();
this.attachEvents();
this.refreshPosition();
this.refreshState(true);
this.resumeRotation();
this.makeCallback('onInit', this);
}
},
findElements: function() {
// define dimensions proporties
this.fullSizeFunction = this.options.vertical ? 'outerHeight' : 'outerWidth';
this.innerSizeFunction = this.options.vertical ? 'height' : 'width';
this.slideSizeFunction = 'outerHeight';
this.maskSizeProperty = 'height';
this.animProperty = this.options.vertical ? 'marginTop' : 'marginLeft';
// control elements
this.gallery = $(this.options.holder).addClass(this.options.galleryReadyClass);
this.mask = this.gallery.find(this.options.mask);
this.slider = this.mask.find(this.options.slider);
this.slides = this.slider.find(this.options.slides);
this.btnPrev = this.gallery.find(this.options.btnPrev);
this.btnNext = this.gallery.find(this.options.btnNext);
this.currentStep = 0; this.stepsCount = 0;
// get start index
if(this.options.step === false) {
var activeSlide = this.slides.filter('.'+this.options.activeClass);
if(activeSlide.length) {
this.currentStep = this.slides.index(activeSlide);
}
}
// calculate offsets
this.calculateOffsets();
// create gallery pagination
if(typeof this.options.generatePagination === 'string') {
this.pagerLinks = $();
this.buildPagination();
} else {
this.pagerLinks = this.gallery.find(this.options.pagerLinks);
this.attachPaginationEvents();
}
// autorotation control buttons
this.btnPlay = this.gallery.find(this.options.btnPlay);
this.btnPause = this.gallery.find(this.options.btnPause);
this.btnPlayPause = this.gallery.find(this.options.btnPlayPause);
// misc elements
this.curNum = this.gallery.find(this.options.currentNumber);
this.allNum = this.gallery.find(this.options.totalNumber);
},
attachEvents: function() {
// bind handlers scope
var self = this;
this.bindHandlers(['onWindowResize']);
$(window).bind('load resize orientationchange', this.onWindowResize);
// previous and next button handlers
if(this.btnPrev.length) {
this.prevSlideHandler = function(e) {
e.preventDefault();
self.prevSlide();
};
this.btnPrev.bind(this.options.event, this.prevSlideHandler);
}
if(this.btnNext.length) {
this.nextSlideHandler = function(e) {
e.preventDefault();
self.nextSlide();
};
this.btnNext.bind(this.options.event, this.nextSlideHandler);
}
// pause on hover handling
if(this.options.pauseOnHover && !isTouchDevice) {
this.hoverHandler = function() {
if(self.options.autoRotation) {
self.galleryHover = true;
self.pauseRotation();
}
};
this.leaveHandler = function() {
if(self.options.autoRotation) {
self.galleryHover = false;
self.resumeRotation();
}
};
this.gallery.bind({mouseenter: this.hoverHandler, mouseleave: this.leaveHandler});
}
// autorotation buttons handler
if(this.btnPlay.length) {
this.btnPlayHandler = function(e) {
e.preventDefault();
self.startRotation();
};
this.btnPlay.bind(this.options.event, this.btnPlayHandler);
}
if(this.btnPause.length) {
this.btnPauseHandler = function(e) {
e.preventDefault();
self.stopRotation();
};
this.btnPause.bind(this.options.event, this.btnPauseHandler);
}
if(this.btnPlayPause.length) {
this.btnPlayPauseHandler = function(e) {
e.preventDefault();
if(!self.gallery.hasClass(self.options.autorotationActiveClass)) {
self.startRotation();
} else {
self.stopRotation();
}
};
this.btnPlayPause.bind(this.options.event, this.btnPlayPauseHandler);
}
// enable hardware acceleration
if(isTouchDevice && this.options.useTranslate3D) {
this.slider.css({'-webkit-transform': 'translate3d(0px, 0px, 0px)'});
}
// swipe event handling
if(isTouchDevice && this.options.handleTouch && window.Hammer && this.mask.length) {
this.swipeHandler = new Hammer.Manager(this.mask[0]);
this.swipeHandler.add(new Hammer.Pan({
direction: self.options.vertical ? Hammer.DIRECTION_VERTICAL : Hammer.DIRECTION_HORIZONTAL,
threshold: self.options.swipeThreshold
}));
this.swipeHandler.on('panstart', function() {
if(self.galleryAnimating) {
self.swipeHandler.stop();
} else {
self.pauseRotation();
self.originalOffset = parseFloat(self.slider.css(self.animProperty));
}
}).on('panmove', function(e) {
var tmpOffset = self.originalOffset + e[self.options.vertical ? 'deltaY' : 'deltaX'];
tmpOffset = Math.max(Math.min(0, tmpOffset), self.maxOffset);
self.slider.css(self.animProperty, tmpOffset);
}).on('panend', function(e) {
self.resumeRotation();
if(e.distance > self.options.swipeThreshold) {
if(e.offsetDirection === Hammer.DIRECTION_RIGHT || e.offsetDirection === Hammer.DIRECTION_DOWN) {
self.nextSlide();
} else {
self.prevSlide();
}
} else {
self.switchSlide();
}
});
}
},
onWindowResize: function() {
if(!this.galleryAnimating) {
this.calculateOffsets();
this.refreshPosition();
this.buildPagination();
this.refreshState();
this.resizeQueue = false;
} else {
this.resizeQueue = true;
}
},
refreshPosition: function() {
this.currentStep = Math.min(this.currentStep, this.stepsCount - 1);
this.tmpProps = {};
this.tmpProps[this.animProperty] = this.getStepOffset();
this.slider.stop().css(this.tmpProps);
},
calculateOffsets: function() {
var self = this, tmpOffset, tmpStep;
if(this.options.stretchSlideToMask) {
var tmpObj = {};
tmpObj[this.innerSizeFunction] = this.mask[this.innerSizeFunction]();
this.slides.css(tmpObj);
}
this.maskSize = this.mask[this.innerSizeFunction]();
this.sumSize = this.getSumSize();
this.maxOffset = this.maskSize - this.sumSize;
// vertical gallery with single size step custom behavior
if(this.options.vertical && this.options.maskAutoSize) {
this.options.step = 1;
this.stepsCount = this.slides.length;
this.stepOffsets = [0];
tmpOffset = 0;
for(var i = 0; i < this.slides.length; i++) {
tmpOffset -= $(this.slides[i])[this.fullSizeFunction](true);
this.stepOffsets.push(tmpOffset);
}
this.maxOffset = tmpOffset;
return;
}
// scroll by slide size
if(typeof this.options.step === 'number' && this.options.step > 0) {
this.slideDimensions = [];
this.slides.each($.proxy(function(ind, obj){
self.slideDimensions.push( $(obj)[self.fullSizeFunction](true) );
},this));
// calculate steps count
this.stepOffsets = [0];
this.stepsCount = 1;
tmpOffset = tmpStep = 0;
while(tmpOffset > this.maxOffset) {
tmpOffset -= this.getSlideSize(tmpStep, tmpStep + this.options.step);
tmpStep += this.options.step;
this.stepOffsets.push(Math.max(tmpOffset, this.maxOffset));
this.stepsCount++;
}
}
// scroll by mask size
else {
// define step size
this.stepSize = this.maskSize;
// calculate steps count
this.stepsCount = 1;
tmpOffset = 0;
while(tmpOffset > this.maxOffset) {
tmpOffset -= this.stepSize;
this.stepsCount++;
}
}
},
getSumSize: function() {
var sum = 0;
this.slides.each($.proxy(function(ind, obj){
sum += $(obj)[this.fullSizeFunction](true);
},this));
this.slider.css(this.innerSizeFunction, sum);
return sum;
},
getStepOffset: function(step) {
step = step || this.currentStep;
if(typeof this.options.step === 'number') {
return this.stepOffsets[this.currentStep];
} else {
return Math.min(0, Math.max(-this.currentStep * this.stepSize, this.maxOffset));
}
},
getSlideSize: function(i1, i2) {
var sum = 0;
for(var i = i1; i < Math.min(i2, this.slideDimensions.length); i++) {
sum += this.slideDimensions[i];
}
return sum;
},
buildPagination: function() {
if(typeof this.options.generatePagination === 'string') {
if(!this.pagerHolder) {
this.pagerHolder = this.gallery.find(this.options.generatePagination);
}
if(this.pagerHolder.length && this.oldStepsCount != this.stepsCount) {
this.oldStepsCount = this.stepsCount;
this.pagerHolder.empty();
this.pagerList = $(this.options.pagerList).appendTo(this.pagerHolder);
for(var i = 0; i < this.stepsCount; i++) {
$(this.options.pagerListItem).appendTo(this.pagerList).find(this.options.pagerListItemText).text(i+1);
}
this.pagerLinks = this.pagerList.children();
this.attachPaginationEvents();
}
}
},
attachPaginationEvents: function() {
var self = this;
this.pagerLinksHandler = function(e) {
e.preventDefault();
self.numSlide(self.pagerLinks.index(e.currentTarget));
};
this.pagerLinks.bind(this.options.event, this.pagerLinksHandler);
},
prevSlide: function() {
if(!(this.options.disableWhileAnimating && this.galleryAnimating)) {
if(this.currentStep > 0) {
this.currentStep--;
this.switchSlide();
} else if(this.options.circularRotation) {
this.currentStep = this.stepsCount - 1;
this.switchSlide();
}
}
},
nextSlide: function(fromAutoRotation) {
if(!(this.options.disableWhileAnimating && this.galleryAnimating)) {
if(this.currentStep < this.stepsCount - 1) {
this.currentStep++;
this.switchSlide();
} else if(this.options.circularRotation || fromAutoRotation === true) {
this.currentStep = 0;
this.switchSlide();
}
}
},
numSlide: function(c) {
if(this.currentStep != c) {
this.currentStep = c;
this.switchSlide();
}
},
switchSlide: function() {
var self = this;
this.galleryAnimating = true;
this.tmpProps = {};
this.tmpProps[this.animProperty] = this.getStepOffset();
this.slider.stop().animate(this.tmpProps, {duration: this.options.animSpeed, complete: function(){
// animation complete
self.galleryAnimating = false;
if(self.resizeQueue) {
self.onWindowResize();
}
// onchange callback
self.makeCallback('onChange', self);
self.autoRotate();
}});
this.refreshState();
// onchange callback
this.makeCallback('onBeforeChange', this);
},
refreshState: function(initial) {
if(this.options.step === 1 || this.stepsCount === this.slides.length) {
this.slides.removeClass(this.options.activeClass).eq(this.currentStep).addClass(this.options.activeClass);
}
this.pagerLinks.removeClass(this.options.activeClass).eq(this.currentStep).addClass(this.options.activeClass);
this.curNum.html(this.currentStep+1);
this.allNum.html(this.stepsCount);
// initial refresh
if(this.options.maskAutoSize && typeof this.options.step === 'number') {
this.tmpProps = {};
this.tmpProps[this.maskSizeProperty] = this.slides.eq(Math.min(this.currentStep,this.slides.length-1))[this.slideSizeFunction](true);
this.mask.stop()[initial ? 'css' : 'animate'](this.tmpProps);
}
// disabled state
if(!this.options.circularRotation) {
this.btnPrev.add(this.btnNext).removeClass(this.options.disabledClass);
if(this.currentStep === 0) this.btnPrev.addClass(this.options.disabledClass);
if(this.currentStep === this.stepsCount - 1) this.btnNext.addClass(this.options.disabledClass);
}
// add class if not enough slides
this.gallery.toggleClass('not-enough-slides', this.sumSize <= this.maskSize);
},
startRotation: function() {
this.options.autoRotation = true;
this.galleryHover = false;
this.autoRotationStopped = false;
this.resumeRotation();
},
stopRotation: function() {
this.galleryHover = true;
this.autoRotationStopped = true;
this.pauseRotation();
},
pauseRotation: function() {
this.gallery.addClass(this.options.autorotationDisabledClass);
this.gallery.removeClass(this.options.autorotationActiveClass);
clearTimeout(this.timer);
},
resumeRotation: function() {
if(!this.autoRotationStopped) {
this.gallery.addClass(this.options.autorotationActiveClass);
this.gallery.removeClass(this.options.autorotationDisabledClass);
this.autoRotate();
}
},
autoRotate: function() {
var self = this;
clearTimeout(this.timer);
if(this.options.autoRotation && !this.galleryHover && !this.autoRotationStopped) {
this.timer = setTimeout(function(){
self.nextSlide(true);
}, this.options.switchTime);
} else {
this.pauseRotation();
}
},
bindHandlers: function(handlersList) {
var self = this;
$.each(handlersList, function(index, handler) {
var origHandler = self[handler];
self[handler] = function() {
return origHandler.apply(self, arguments);
};
});
},
makeCallback: function(name) {
if(typeof this.options[name] === 'function') {
var args = Array.prototype.slice.call(arguments);
args.shift();
this.options[name].apply(this, args);
}
},
destroy: function() {
// destroy handler
$(window).unbind('load resize orientationchange', this.onWindowResize);
this.btnPrev.unbind(this.options.event, this.prevSlideHandler);
this.btnNext.unbind(this.options.event, this.nextSlideHandler);
this.pagerLinks.unbind(this.options.event, this.pagerLinksHandler);
this.gallery.unbind('mouseenter', this.hoverHandler);
this.gallery.unbind('mouseleave', this.leaveHandler);
// autorotation buttons handlers
this.stopRotation();
this.btnPlay.unbind(this.options.event, this.btnPlayHandler);
this.btnPause.unbind(this.options.event, this.btnPauseHandler);
this.btnPlayPause.unbind(this.options.event, this.btnPlayPauseHandler);
// destroy swipe handler
if(this.swipeHandler) {
this.swipeHandler.destroy();
}
// remove inline styles, classes and pagination
var unneededClasses = [this.options.galleryReadyClass, this.options.autorotationActiveClass, this.options.autorotationDisabledClass];
this.gallery.removeClass(unneededClasses.join(' '));
this.slider.add(this.slides).removeAttr('style');
if(typeof this.options.generatePagination === 'string') {
this.pagerHolder.empty();
}
}
};
// detect device type
var isTouchDevice = /Windows Phone/.test(navigator.userAgent) || ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;
// jquery plugin
$.fn.scrollGallery = function(opt){
return this.each(function(){
$(this).data('ScrollGallery', new ScrollGallery($.extend(opt,{holder:this})));
});
};
}(jQuery));
/*
* jQuery SlideShow plugin
*/
;(function($){
function FadeGallery(options) {
this.options = $.extend({
slides: 'ul.slideset > li',
activeClass:'active',
disabledClass:'disabled',
btnPrev: 'a.btn-prev',
btnNext: 'a.btn-next',
generatePagination: false,
pagerList: '<ul>',
pagerListItem: '<li><a href="#"></a></li>',
pagerListItemText: 'a',
pagerLinks: '.pagination li',
currentNumber: 'span.current-num',
totalNumber: 'span.total-num',
btnPlay: '.btn-play',
btnPause: '.btn-pause',
btnPlayPause: '.btn-play-pause',
galleryReadyClass: 'gallery-js-ready',
autorotationActiveClass: 'autorotation-active',
autorotationDisabledClass: 'autorotation-disabled',
autorotationStopAfterClick: false,
circularRotation: true,
switchSimultaneously: true,
disableWhileAnimating: false,
disableFadeIE: false,
autoRotation: false,
pauseOnHover: true,
autoHeight: false,
useSwipe: false,
swipeThreshold: 15,
switchTime: 4000,
animSpeed: 600,
event:'click'
}, options);
this.init();
}
FadeGallery.prototype = {
init: function() {
if(this.options.holder) {
this.findElements();
this.attachEvents();
this.refreshState(true);
this.autoRotate();
this.makeCallback('onInit', this);
}
},
findElements: function() {
// control elements
this.gallery = $(this.options.holder).addClass(this.options.galleryReadyClass);
this.slides = this.gallery.find(this.options.slides);
this.slidesHolder = this.slides.eq(0).parent();
this.stepsCount = this.slides.length;
this.btnPrev = this.gallery.find(this.options.btnPrev);
this.btnNext = this.gallery.find(this.options.btnNext);
this.currentIndex = 0;
// disable fade effect in old IE
if(this.options.disableFadeIE && !$.support.opacity) {
this.options.animSpeed = 0;
}
// create gallery pagination
if(typeof this.options.generatePagination === 'string') {
this.pagerHolder = this.gallery.find(this.options.generatePagination).empty();
this.pagerList = $(this.options.pagerList).appendTo(this.pagerHolder);
for(var i = 0; i < this.stepsCount; i++) {
$(this.options.pagerListItem).appendTo(this.pagerList).find(this.options.pagerListItemText).text(i+1);
}
this.pagerLinks = this.pagerList.children();
} else {
this.pagerLinks = this.gallery.find(this.options.pagerLinks);
}
// get start index
var activeSlide = this.slides.filter('.'+this.options.activeClass);
if(activeSlide.length) {
this.currentIndex = this.slides.index(activeSlide);
}
this.prevIndex = this.currentIndex;
// autorotation control buttons
this.btnPlay = this.gallery.find(this.options.btnPlay);
this.btnPause = this.gallery.find(this.options.btnPause);
this.btnPlayPause = this.gallery.find(this.options.btnPlayPause);
// misc elements
this.curNum = this.gallery.find(this.options.currentNumber);
this.allNum = this.gallery.find(this.options.totalNumber);
// handle flexible layout
this.slides.css({display:'block',opacity:0}).eq(this.currentIndex).css({
opacity:''
});
},
attachEvents: function() {
var self = this;
// flexible layout handler
this.resizeHandler = function() {
self.onWindowResize();
};
$(window).bind('load resize orientationchange', this.resizeHandler);
if(this.btnPrev.length) {
this.btnPrevHandler = function(e){
e.preventDefault();
self.prevSlide();
if(self.options.autorotationStopAfterClick) {
self.stopRotation();
}
};
this.btnPrev.bind(this.options.event, this.btnPrevHandler);
}
if(this.btnNext.length) {
this.btnNextHandler = function(e) {
e.preventDefault();
self.nextSlide();
if(self.options.autorotationStopAfterClick) {
self.stopRotation();
}
};
this.btnNext.bind(this.options.event, this.btnNextHandler);
}
if(this.pagerLinks.length) {
this.pagerLinksHandler = function(e) {
e.preventDefault();
self.numSlide(self.pagerLinks.index(e.currentTarget));
if(self.options.autorotationStopAfterClick) {
self.stopRotation();
}
};
this.pagerLinks.bind(self.options.event, this.pagerLinksHandler);
}
// autorotation buttons handler
if(this.btnPlay.length) {
this.btnPlayHandler = function(e) {
e.preventDefault();
self.startRotation();
};
this.btnPlay.bind(this.options.event, this.btnPlayHandler);
}
if(this.btnPause.length) {
this.btnPauseHandler = function(e) {
e.preventDefault();
self.stopRotation();
};
this.btnPause.bind(this.options.event, this.btnPauseHandler);
}
if(this.btnPlayPause.length) {
this.btnPlayPauseHandler = function(e){
e.preventDefault();
if(!self.gallery.hasClass(self.options.autorotationActiveClass)) {
self.startRotation();
} else {
self.stopRotation();
}
};
this.btnPlayPause.bind(this.options.event, this.btnPlayPauseHandler);
}
// swipe gestures handler
if(this.options.useSwipe && window.Hammer && isTouchDevice) {
this.swipeHandler = new Hammer.Manager(this.gallery[0]);
this.swipeHandler.add(new Hammer.Swipe({
direction: Hammer.DIRECTION_HORIZONTAL,
threshold: self.options.swipeThreshold
}));
this.swipeHandler.on('swipeleft', function() {
self.nextSlide();
}).on('swiperight', function() {
self.prevSlide();
});
}
// pause on hover handling
if(this.options.pauseOnHover) {
this.hoverHandler = function() {
if(self.options.autoRotation) {
self.galleryHover = true;
self.pauseRotation();
}
};
this.leaveHandler = function() {
if(self.options.autoRotation) {
self.galleryHover = false;
self.resumeRotation();
}
};
this.gallery.bind({mouseenter: this.hoverHandler, mouseleave: this.leaveHandler});
}
},
onWindowResize: function(){
if(this.options.autoHeight) {
this.slidesHolder.css({height: this.slides.eq(this.currentIndex).outerHeight(true) });
}
},
prevSlide: function() {
if(!(this.options.disableWhileAnimating && this.galleryAnimating)) {
this.prevIndex = this.currentIndex;
if(this.currentIndex > 0) {
this.currentIndex--;
this.switchSlide();
} else if(this.options.circularRotation) {
this.currentIndex = this.stepsCount - 1;
this.switchSlide();
}
}
},
nextSlide: function(fromAutoRotation) {
if(!(this.options.disableWhileAnimating && this.galleryAnimating)) {
this.prevIndex = this.currentIndex;
if(this.currentIndex < this.stepsCount - 1) {
this.currentIndex++;
this.switchSlide();
} else if(this.options.circularRotation || fromAutoRotation === true) {
this.currentIndex = 0;
this.switchSlide();
}
}
},
numSlide: function(c) {
if(this.currentIndex != c) {
this.prevIndex = this.currentIndex;
this.currentIndex = c;
this.switchSlide();
}
},
switchSlide: function() {
var self = this;
if(this.slides.length > 1) {
this.galleryAnimating = true;
if(!this.options.animSpeed) {
this.slides.eq(this.prevIndex).css({opacity:0});
} else {
this.slides.eq(this.prevIndex).stop().animate({opacity:0},{duration: this.options.animSpeed});
}
this.switchNext = function() {
if(!self.options.animSpeed) {
self.slides.eq(self.currentIndex).css({opacity:''});
} else {
self.slides.eq(self.currentIndex).stop().animate({opacity:1},{duration: self.options.animSpeed});
}
clearTimeout(this.nextTimer);
this.nextTimer = setTimeout(function() {
self.slides.eq(self.currentIndex).css({opacity:''});
self.galleryAnimating = false;
self.autoRotate();
// onchange callback
self.makeCallback('onChange', self);
}, self.options.animSpeed);
};
if(this.options.switchSimultaneously) {
self.switchNext();
} else {
clearTimeout(this.switchTimer);
this.switchTimer = setTimeout(function(){
self.switchNext();
}, this.options.animSpeed);
}
this.refreshState();
// onchange callback
this.makeCallback('onBeforeChange', this);
}
},
refreshState: function(initial) {
this.slides.removeClass(this.options.activeClass).eq(this.currentIndex).addClass(this.options.activeClass);
this.pagerLinks.removeClass(this.options.activeClass).eq(this.currentIndex).addClass(this.options.activeClass);
this.curNum.html(this.currentIndex+1);
this.allNum.html(this.stepsCount);
// initial refresh
if(this.options.autoHeight) {
if(initial) {
this.slidesHolder.css({height: this.slides.eq(this.currentIndex).outerHeight(true) });
} else {
this.slidesHolder.stop().animate({height: this.slides.eq(this.currentIndex).outerHeight(true)}, {duration: this.options.animSpeed});
}
}
// disabled state
if(!this.options.circularRotation) {
this.btnPrev.add(this.btnNext).removeClass(this.options.disabledClass);
if(this.currentIndex === 0) this.btnPrev.addClass(this.options.disabledClass);
if(this.currentIndex === this.stepsCount - 1) this.btnNext.addClass(this.options.disabledClass);
}
// add class if not enough slides
this.gallery.toggleClass('not-enough-slides', this.stepsCount === 1);
},
startRotation: function() {
this.options.autoRotation = true;
this.galleryHover = false;
this.autoRotationStopped = false;
this.resumeRotation();
},
stopRotation: function() {
this.galleryHover = true;
this.autoRotationStopped = true;
this.pauseRotation();
},
pauseRotation: function() {
this.gallery.addClass(this.options.autorotationDisabledClass);
this.gallery.removeClass(this.options.autorotationActiveClass);
clearTimeout(this.timer);
},
resumeRotation: function() {
if(!this.autoRotationStopped) {
this.gallery.addClass(this.options.autorotationActiveClass);
this.gallery.removeClass(this.options.autorotationDisabledClass);
this.autoRotate();
}
},
autoRotate: function() {
var self = this;
clearTimeout(this.timer);
if(this.options.autoRotation && !this.galleryHover && !this.autoRotationStopped) {
this.gallery.addClass(this.options.autorotationActiveClass);
this.timer = setTimeout(function(){
self.nextSlide(true);
}, this.options.switchTime);
} else {
this.pauseRotation();
}
},
makeCallback: function(name) {
if(typeof this.options[name] === 'function') {
var args = Array.prototype.slice.call(arguments);
args.shift();
this.options[name].apply(this, args);
}
},
destroy: function() {
// navigation buttons handler
this.btnPrev.unbind(this.options.event, this.btnPrevHandler);
this.btnNext.unbind(this.options.event, this.btnNextHandler);
this.pagerLinks.unbind(this.options.event, this.pagerLinksHandler);
$(window).unbind('load resize orientationchange', this.resizeHandler);
// remove autorotation handlers
this.stopRotation();
this.btnPlay.unbind(this.options.event, this.btnPlayHandler);
this.btnPause.unbind(this.options.event, this.btnPauseHandler);
this.btnPlayPause.unbind(this.options.event, this.btnPlayPauseHandler);
this.gallery.unbind('mouseenter', this.hoverHandler);
this.gallery.unbind('mouseleave', this.leaveHandler);
// remove swipe handler if used
if(this.swipeHandler) {
this.swipeHandler.destroy();
}
if(typeof this.options.generatePagination === 'string') {
this.pagerHolder.empty();
}
// remove unneeded classes and styles
var unneededClasses = [this.options.galleryReadyClass, this.options.autorotationActiveClass, this.options.autorotationDisabledClass];
this.gallery.removeClass(unneededClasses.join(' '));
this.slidesHolder.add(this.slides).removeAttr('style');
}
};
// detect device type
var isTouchDevice = /Windows Phone/.test(navigator.userAgent) || ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;
// jquery plugin
$.fn.fadeGallery = function(opt){
return this.each(function(){
$(this).data('FadeGallery', new FadeGallery($.extend(opt,{holder:this})));
});
};
}(jQuery));
/*! http://mths.be/placeholder v2.0.7 by @mathias */
;(function(window, document, $) {
// Opera Mini v7 doesnt support placeholder although its DOM seems to indicate so
var isOperaMini = Object.prototype.toString.call(window.operamini) == '[object OperaMini]';
var isInputSupported = 'placeholder' in document.createElement('input') && !isOperaMini;
var isTextareaSupported = 'placeholder' in document.createElement('textarea') && !isOperaMini;
var prototype = $.fn;
var valHooks = $.valHooks;
var propHooks = $.propHooks;
var hooks;
var placeholder;
if (isInputSupported && isTextareaSupported) {
placeholder = prototype.placeholder = function() {
return this;
};
placeholder.input = placeholder.textarea = true;
} else {
placeholder = prototype.placeholder = function() {
var $this = this;
$this
.filter((isInputSupported ? 'textarea' : ':input') + '[placeholder]')
.not('.placeholder')
.bind({
'focus.placeholder': clearPlaceholder,
'blur.placeholder': setPlaceholder
})
.data('placeholder-enabled', true)
.trigger('blur.placeholder');
return $this;
};
placeholder.input = isInputSupported;
placeholder.textarea = isTextareaSupported;
hooks = {
'get': function(element) {
var $element = $(element);
var $passwordInput = $element.data('placeholder-password');
if ($passwordInput) {
return $passwordInput[0].value;
}
return $element.data('placeholder-enabled') && $element.hasClass('placeholder') ? '' : element.value;
},
'set': function(element, value) {
var $element = $(element);
var $passwordInput = $element.data('placeholder-password');
if ($passwordInput) {
return $passwordInput[0].value = value;
}
if (!$element.data('placeholder-enabled')) {
return element.value = value;
}
if (value == '') {
element.value = value;
// Issue #56: Setting the placeholder causes problems if the element continues to have focus.
if (element != safeActiveElement()) {
// We can't use `triggerHandler` here because of dummy text/password inputs :(
setPlaceholder.call(element);
}
} else if ($element.hasClass('placeholder')) {
clearPlaceholder.call(element, true, value) || (element.value = value);
} else {
element.value = value;
}
// `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363
return $element;
}
};
if (!isInputSupported) {
valHooks.input = hooks;
propHooks.value = hooks;
}
if (!isTextareaSupported) {
valHooks.textarea = hooks;
propHooks.value = hooks;
}
$(function() {
// Look for forms
$(document).delegate('form', 'submit.placeholder', function() {
// Clear the placeholder values so they don't get submitted
var $inputs = $('.placeholder', this).each(clearPlaceholder);
setTimeout(function() {
$inputs.each(setPlaceholder);
}, 10);
});
});
// Clear placeholder values upon page reload
$(window).bind('beforeunload.placeholder', function() {
$('.placeholder').each(function() {
this.value = '';
});
});
}
function args(elem) {
// Return an object of element attributes
var newAttrs = {};
var rinlinejQuery = /^jQuery\d+$/;
$.each(elem.attributes, function(i, attr) {
if (attr.specified && !rinlinejQuery.test(attr.name)) {
newAttrs[attr.name] = attr.value;
}
});
return newAttrs;
}
function clearPlaceholder(event, value) {
var input = this;
var $input = $(input);
if (input.value == $input.attr('placeholder') && $input.hasClass('placeholder')) {
if ($input.data('placeholder-password')) {
$input = $input.hide().next().show().attr('id', $input.removeAttr('id').data('placeholder-id'));
// If `clearPlaceholder` was called from `$.valHooks.input.set`
if (event === true) {
return $input[0].value = value;
}
$input.focus();
} else {
input.value = '';
$input.removeClass('placeholder');
input == safeActiveElement() && input.select();
}
}
}
function setPlaceholder() {
var $replacement;
var input = this;
var $input = $(input);
var id = this.id;
if (input.value == '') {
if (input.type == 'password') {
if (!$input.data('placeholder-textinput')) {
try {
$replacement = $input.clone().attr({ 'type': 'text' });
} catch(e) {
$replacement = $('<input>').attr($.extend(args(this), { 'type': 'text' }));
}
$replacement
.removeAttr('name')
.data({
'placeholder-password': $input,
'placeholder-id': id
})
.bind('focus.placeholder', clearPlaceholder);
$input
.data({
'placeholder-textinput': $replacement,
'placeholder-id': id
})
.before($replacement);
}
$input = $input.removeAttr('id').hide().prev().attr('id', id).show();
// Note: `$input[0] != input` now!
}
$input.addClass('placeholder');
$input[0].value = $input.attr('placeholder');
} else {
$input.removeClass('placeholder');
}
}
function safeActiveElement() {
// Avoid IE9 `document.activeElement` of death
// https://github.com/mathiasbynens/jquery-placeholder/pull/99
try {
return document.activeElement;
} catch (err) {}
}
}(this, document, jQuery));
/*
* JavaScript Custom Forms Module
*/
jcf = {
// global options
modules: {},
plugins: {},
baseOptions: {
unselectableClass:'jcf-unselectable',
labelActiveClass:'jcf-label-active',
labelDisabledClass:'jcf-label-disabled',
classPrefix: 'jcf-class-',
hiddenClass:'jcf-hidden',
focusClass:'jcf-focus',
wrapperTag: 'div'
},
// replacer function
customForms: {
setOptions: function(obj) {
for(var p in obj) {
if(obj.hasOwnProperty(p) && typeof obj[p] === 'object') {
jcf.lib.extend(jcf.modules[p].prototype.defaultOptions, obj[p]);
}
}
},
replaceAll: function(context) {
for(var k in jcf.modules) {
var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector, context);
for(var i = 0; i<els.length; i++) {
if(els[i].jcf) {
// refresh form element state
els[i].jcf.refreshState();
} else {
// replace form element
if(!jcf.lib.hasClass(els[i], 'default') && jcf.modules[k].prototype.checkElement(els[i])) {
new jcf.modules[k]({
replaces:els[i]
});
}
}
}
}
},
refreshAll: function(context) {
for(var k in jcf.modules) {
var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector, context);
for(var i = 0; i<els.length; i++) {
if(els[i].jcf) {
// refresh form element state
els[i].jcf.refreshState();
}
}
}
},
refreshElement: function(obj) {
if(obj && obj.jcf) {
obj.jcf.refreshState();
}
},
destroyAll: function() {
for(var k in jcf.modules) {
var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector);
for(var i = 0; i<els.length; i++) {
if(els[i].jcf) {
els[i].jcf.destroy();
}
}
}
}
},
// detect device type
isTouchDevice: ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch,
isWinPhoneDevice: /Windows Phone/.test(navigator.userAgent),
// define base module
setBaseModule: function(obj) {
jcf.customControl = function(opt){
this.options = jcf.lib.extend({}, jcf.baseOptions, this.defaultOptions, opt);
this.init();
};
for(var p in obj) {
jcf.customControl.prototype[p] = obj[p];
}
},
// add module to jcf.modules
addModule: function(obj) {
if(obj.name){
// create new module proto class
jcf.modules[obj.name] = function(){
jcf.modules[obj.name].superclass.constructor.apply(this, arguments);
}
jcf.lib.inherit(jcf.modules[obj.name], jcf.customControl);
for(var p in obj) {
jcf.modules[obj.name].prototype[p] = obj[p]
}
// on create module
jcf.modules[obj.name].prototype.onCreateModule();
// make callback for exciting modules
for(var mod in jcf.modules) {
if(jcf.modules[mod] != jcf.modules[obj.name]) {
jcf.modules[mod].prototype.onModuleAdded(jcf.modules[obj.name]);
}
}
}
},
// add plugin to jcf.plugins
addPlugin: function(obj) {
if(obj && obj.name) {
jcf.plugins[obj.name] = function() {
this.init.apply(this, arguments);
}
for(var p in obj) {
jcf.plugins[obj.name].prototype[p] = obj[p];
}
}
},
// miscellaneous init
init: function(){
if(navigator.pointerEnabled || navigator.msPointerEnabled) {
// use pointer events instead of mouse events
this.eventPress = navigator.pointerEnabled ? 'pointerdown' : 'MSPointerDown';
this.eventMove = navigator.pointerEnabled ? 'pointermove' : 'MSPointerMove';
this.eventRelease = navigator.pointerEnabled ? 'pointerup' : 'MSPointerUp';
} else {
// handle default desktop mouse events
this.eventPress = 'mousedown';
this.eventMove = 'mousemove';
this.eventRelease = 'mouseup';
}
if(this.isTouchDevice) {
// handle touch events also
this.eventPress += ' touchstart';
this.eventMove += ' touchmove';
this.eventRelease += ' touchend';
}
setTimeout(function(){
jcf.lib.domReady(function(){
jcf.initStyles();
});
},1);
return this;
},
initStyles: function() {
// create <style> element and rules
var head = document.getElementsByTagName('head')[0],
style = document.createElement('style'),
rules = document.createTextNode('.'+jcf.baseOptions.unselectableClass+'{'+
'-moz-user-select:none;'+
'-webkit-tap-highlight-color:rgba(255,255,255,0);'+
'-webkit-user-select:none;'+
'user-select:none;'+
'}');
// append style element
style.type = 'text/css';
if(style.styleSheet) {
style.styleSheet.cssText = rules.nodeValue;
} else {
style.appendChild(rules);
}
head.appendChild(style);
}
}.init();
/*
* Custom Form Control prototype
*/
jcf.setBaseModule({
init: function(){
if(this.options.replaces) {
this.realElement = this.options.replaces;
this.realElement.jcf = this;
this.replaceObject();
}
},
defaultOptions: {
// default module options (will be merged with base options)
},
checkElement: function(el){
return true; // additional check for correct form element
},
replaceObject: function(){
this.createWrapper();
this.attachEvents();
this.fixStyles();
this.setupWrapper();
},
createWrapper: function(){
this.fakeElement = jcf.lib.createElement(this.options.wrapperTag);
this.labelFor = jcf.lib.getLabelFor(this.realElement);
jcf.lib.disableTextSelection(this.fakeElement);
jcf.lib.addClass(this.fakeElement, jcf.lib.getAllClasses(this.realElement.className, this.options.classPrefix));
jcf.lib.addClass(this.realElement, jcf.baseOptions.hiddenClass);
},
attachEvents: function(){
jcf.lib.event.add(this.realElement, 'focus', this.onFocusHandler, this);
jcf.lib.event.add(this.realElement, 'blur', this.onBlurHandler, this);
jcf.lib.event.add(this.fakeElement, 'click', this.onFakeClick, this);
jcf.lib.event.add(this.fakeElement, jcf.eventPress, this.onFakePressed, this);
jcf.lib.event.add(this.fakeElement, jcf.eventRelease, this.onFakeReleased, this);
if(this.labelFor) {
this.labelFor.jcf = this;
jcf.lib.event.add(this.labelFor, 'click', this.onFakeClick, this);
jcf.lib.event.add(this.labelFor, jcf.eventPress, this.onFakePressed, this);
jcf.lib.event.add(this.labelFor, jcf.eventRelease, this.onFakeReleased, this);
}
},
fixStyles: function() {
// hide mobile webkit tap effect
if(jcf.isTouchDevice) {
var tapStyle = 'rgba(255,255,255,0)';
this.realElement.style.webkitTapHighlightColor = tapStyle;
this.fakeElement.style.webkitTapHighlightColor = tapStyle;
if(this.labelFor) {
this.labelFor.style.webkitTapHighlightColor = tapStyle;
}
}
},
setupWrapper: function(){
// implement in subclass
},
refreshState: function(){
// implement in subclass
},
destroy: function() {
if(this.fakeElement && this.fakeElement.parentNode) {
this.fakeElement.parentNode.insertBefore(this.realElement, this.fakeElement);
this.fakeElement.parentNode.removeChild(this.fakeElement);
}
jcf.lib.removeClass(this.realElement, jcf.baseOptions.hiddenClass);
this.realElement.jcf = null;
},
onFocus: function(){
// emulated focus event
jcf.lib.addClass(this.fakeElement,this.options.focusClass);
},
onBlur: function(cb){
// emulated blur event
jcf.lib.removeClass(this.fakeElement,this.options.focusClass);
},
onFocusHandler: function() {
// handle focus loses
if(this.focused) return;
this.focused = true;
// handle touch devices also
if(jcf.isTouchDevice) {
if(jcf.focusedInstance && jcf.focusedInstance.realElement != this.realElement) {
jcf.focusedInstance.onBlur();
jcf.focusedInstance.realElement.blur();
}
jcf.focusedInstance = this;
}
this.onFocus.apply(this, arguments);
},
onBlurHandler: function() {
// handle focus loses
if(!this.pressedFlag) {
this.focused = false;
this.onBlur.apply(this, arguments);
}
},
onFakeClick: function(){
if(jcf.isTouchDevice) {
this.onFocus();
} else if(!this.realElement.disabled) {
this.realElement.focus();
}
},
onFakePressed: function(e){
this.pressedFlag = true;
},
onFakeReleased: function(){
this.pressedFlag = false;
},
onCreateModule: function(){
// implement in subclass
},
onModuleAdded: function(module) {
// implement in subclass
},
onControlReady: function() {
// implement in subclass
}
});
/*
* JCF Utility Library
*/
jcf.lib = {
bind: function(func, scope){
return function() {
return func.apply(scope, arguments);
};
},
browser: (function() {
var ua = navigator.userAgent.toLowerCase(), res = {},
match = /(webkit)[ \/]([\w.]+)/.exec(ua) || /(opera)(?:.*version)?[ \/]([\w.]+)/.exec(ua) ||
/(msie) ([\w.]+)/.exec(ua) || ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+))?/.exec(ua) || [];
res[match[1]] = true;
res.version = match[2] || "0";
res.safariMac = ua.indexOf('mac') != -1 && ua.indexOf('safari') != -1;
return res;
})(),
getOffset: function (obj) {
if (obj.getBoundingClientRect && !jcf.isWinPhoneDevice) {
var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft;
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
var clientLeft = document.documentElement.clientLeft || document.body.clientLeft || 0;
var clientTop = document.documentElement.clientTop || document.body.clientTop || 0;
return {
top:Math.round(obj.getBoundingClientRect().top + scrollTop - clientTop),
left:Math.round(obj.getBoundingClientRect().left + scrollLeft - clientLeft)
};
} else {
var posLeft = 0, posTop = 0;
while (obj.offsetParent) {posLeft += obj.offsetLeft; posTop += obj.offsetTop; obj = obj.offsetParent;}
return {top:posTop,left:posLeft};
}
},
getScrollTop: function() {
return window.pageYOffset || document.documentElement.scrollTop;
},
getScrollLeft: function() {
return window.pageXOffset || document.documentElement.scrollLeft;
},
getWindowWidth: function(){
return document.compatMode=='CSS1Compat' ? document.documentElement.clientWidth : document.body.clientWidth;
},
getWindowHeight: function(){
return document.compatMode=='CSS1Compat' ? document.documentElement.clientHeight : document.body.clientHeight;
},
getStyle: function(el, prop) {
if (document.defaultView && document.defaultView.getComputedStyle) {
return document.defaultView.getComputedStyle(el, null)[prop];
} else if (el.currentStyle) {
return el.currentStyle[prop];
} else {
return el.style[prop];
}
},
getParent: function(obj, selector) {
while(obj.parentNode && obj.parentNode != document.body) {
if(obj.parentNode.tagName.toLowerCase() == selector.toLowerCase()) {
return obj.parentNode;
}
obj = obj.parentNode;
}
return false;
},
isParent: function(parent, child) {
while(child.parentNode) {
if(child.parentNode === parent) {
return true;
}
child = child.parentNode;
}
return false;
},
getLabelFor: function(object) {
var parentLabel = jcf.lib.getParent(object,'label');
if(parentLabel) {
return parentLabel;
} else if(object.id) {
return jcf.lib.queryBySelector('label[for="' + object.id + '"]')[0];
}
},
disableTextSelection: function(el){
if (typeof el.onselectstart !== 'undefined') {
el.onselectstart = function() {return false;};
} else if(window.opera) {
el.setAttribute('unselectable', 'on');
} else {
jcf.lib.addClass(el, jcf.baseOptions.unselectableClass);
}
},
enableTextSelection: function(el) {
if (typeof el.onselectstart !== 'undefined') {
el.onselectstart = null;
} else if(window.opera) {
el.removeAttribute('unselectable');
} else {
jcf.lib.removeClass(el, jcf.baseOptions.unselectableClass);
}
},
queryBySelector: function(selector, scope){
if(typeof scope === 'string') {
var result = [];
var holders = this.getElementsBySelector(scope);
for (var i = 0, contextNodes; i < holders.length; i++) {
contextNodes = Array.prototype.slice.call(this.getElementsBySelector(selector, holders[i]));
result = result.concat(contextNodes);
}
return result;
} else {
return this.getElementsBySelector(selector, scope);
}
},
prevSibling: function(node) {
while(node = node.previousSibling) if(node.nodeType == 1) break;
return node;
},
nextSibling: function(node) {
while(node = node.nextSibling) if(node.nodeType == 1) break;
return node;
},
fireEvent: function(element,event) {
if(element.dispatchEvent){
var evt = document.createEvent('HTMLEvents');
evt.initEvent(event, true, true );
return !element.dispatchEvent(evt);
}else if(document.createEventObject){
var evt = document.createEventObject();
return element.fireEvent('on'+event,evt);
}
},
inherit: function(Child, Parent) {
var F = function() { }
F.prototype = Parent.prototype
Child.prototype = new F()
Child.prototype.constructor = Child
Child.superclass = Parent.prototype
},
extend: function(obj) {
for(var i = 1; i < arguments.length; i++) {
for(var p in arguments[i]) {
if(arguments[i].hasOwnProperty(p)) {
obj[p] = arguments[i][p];
}
}
}
return obj;
},
hasClass: function (obj,cname) {
return (obj.className ? obj.className.match(new RegExp('(\\s|^)'+cname+'(\\s|$)')) : false);
},
addClass: function (obj,cname) {
if (!this.hasClass(obj,cname)) obj.className += (!obj.className.length || obj.className.charAt(obj.className.length - 1) === ' ' ? '' : ' ') + cname;
},
removeClass: function (obj,cname) {
if (this.hasClass(obj,cname)) obj.className=obj.className.replace(new RegExp('(\\s|^)'+cname+'(\\s|$)'),' ').replace(/\s+$/, '');
},
toggleClass: function(obj, cname, condition) {
if(condition) this.addClass(obj, cname); else this.removeClass(obj, cname);
},
createElement: function(tagName, options) {
var el = document.createElement(tagName);
for(var p in options) {
if(options.hasOwnProperty(p)) {
switch (p) {
case 'class': el.className = options[p]; break;
case 'html': el.innerHTML = options[p]; break;
case 'style': this.setStyles(el, options[p]); break;
default: el.setAttribute(p, options[p]);
}
}
}
return el;
},
setStyles: function(el, styles) {
for(var p in styles) {
if(styles.hasOwnProperty(p)) {
switch (p) {
case 'float': el.style.cssFloat = styles[p]; break;
case 'opacity': el.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity='+styles[p]*100+')'; el.style.opacity = styles[p]; break;
default: el.style[p] = (typeof styles[p] === 'undefined' ? 0 : styles[p]) + (typeof styles[p] === 'number' ? 'px' : '');
}
}
}
return el;
},
getInnerWidth: function(el) {
return el.offsetWidth - (parseInt(this.getStyle(el,'paddingLeft')) || 0) - (parseInt(this.getStyle(el,'paddingRight')) || 0);
},
getInnerHeight: function(el) {
return el.offsetHeight - (parseInt(this.getStyle(el,'paddingTop')) || 0) - (parseInt(this.getStyle(el,'paddingBottom')) || 0);
},
getAllClasses: function(cname, prefix, skip) {
if(!skip) skip = '';
if(!prefix) prefix = '';
return cname ? cname.replace(new RegExp('(\\s|^)'+skip+'(\\s|$)'),' ').replace(/[\s]*([\S]+)+[\s]*/gi,prefix+"$1 ") : '';
},
getElementsBySelector: function(selector, scope) {
if(typeof document.querySelectorAll === 'function') {
return (scope || document).querySelectorAll(selector);
}
var selectors = selector.split(',');
var resultList = [];
for(var s = 0; s < selectors.length; s++) {
var currentContext = [scope || document];
var tokens = selectors[s].replace(/^\s+/,'').replace(/\s+$/,'').split(' ');
for (var i = 0; i < tokens.length; i++) {
token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');
if (token.indexOf('#') > -1) {
var bits = token.split('#'), tagName = bits[0], id = bits[1];
var element = document.getElementById(id);
if (tagName && element.nodeName.toLowerCase() != tagName) {
return [];
}
currentContext = [element];
continue;
}
if (token.indexOf('.') > -1) {
var bits = token.split('.'), tagName = bits[0] || '*', className = bits[1], found = [], foundCount = 0;
for (var h = 0; h < currentContext.length; h++) {
var elements;
if (tagName == '*') {
elements = currentContext[h].getElementsByTagName('*');
} else {
elements = currentContext[h].getElementsByTagName(tagName);
}
for (var j = 0; j < elements.length; j++) {
found[foundCount++] = elements[j];
}
}
currentContext = [];
var currentContextIndex = 0;
for (var k = 0; k < found.length; k++) {
if (found[k].className && found[k].className.match(new RegExp('(\\s|^)'+className+'(\\s|$)'))) {
currentContext[currentContextIndex++] = found[k];
}
}
continue;
}
if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^"]*)"?\]$/)) {
var tagName = RegExp.$1 || '*', attrName = RegExp.$2, attrOperator = RegExp.$3, attrValue = RegExp.$4;
if(attrName.toLowerCase() == 'for' && this.browser.msie && this.browser.version < 8) {
attrName = 'htmlFor';
}
var found = [], foundCount = 0;
for (var h = 0; h < currentContext.length; h++) {
var elements;
if (tagName == '*') {
elements = currentContext[h].getElementsByTagName('*');
} else {
elements = currentContext[h].getElementsByTagName(tagName);
}
for (var j = 0; elements[j]; j++) {
found[foundCount++] = elements[j];
}
}
currentContext = [];
var currentContextIndex = 0, checkFunction;
switch (attrOperator) {
case '=': checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue) }; break;
case '~': checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('(\\s|^)'+attrValue+'(\\s|$)'))) }; break;
case '|': checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))) }; break;
case '^': checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0) }; break;
case '$': checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length) }; break;
case '*': checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1) }; break;
default : checkFunction = function(e) { return e.getAttribute(attrName) };
}
currentContext = [];
var currentContextIndex = 0;
for (var k = 0; k < found.length; k++) {
if (checkFunction(found[k])) {
currentContext[currentContextIndex++] = found[k];
}
}
continue;
}
tagName = token;
var found = [], foundCount = 0;
for (var h = 0; h < currentContext.length; h++) {
var elements = currentContext[h].getElementsByTagName(tagName);
for (var j = 0; j < elements.length; j++) {
found[foundCount++] = elements[j];
}
}
currentContext = found;
}
resultList = [].concat(resultList,currentContext);
}
return resultList;
},
scrollSize: (function(){
var content, hold, sizeBefore, sizeAfter;
function buildSizer(){
if(hold) removeSizer();
content = document.createElement('div');
hold = document.createElement('div');
hold.style.cssText = 'position:absolute;overflow:hidden;width:100px;height:100px';
hold.appendChild(content);
document.body.appendChild(hold);
}
function removeSizer(){
document.body.removeChild(hold);
hold = null;
}
function calcSize(vertical) {
buildSizer();
content.style.cssText = 'height:'+(vertical ? '100%' : '200px');
sizeBefore = (vertical ? content.offsetHeight : content.offsetWidth);
hold.style.overflow = 'scroll'; content.innerHTML = 1;
sizeAfter = (vertical ? content.offsetHeight : content.offsetWidth);
if(vertical && hold.clientHeight) sizeAfter = hold.clientHeight;
removeSizer();
return sizeBefore - sizeAfter;
}
return {
getWidth:function(){
return calcSize(false);
},
getHeight:function(){
return calcSize(true)
}
}
}()),
domReady: function (handler){
var called = false
function ready() {
if (called) return;
called = true;
handler();
}
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", ready, false);
} else if (document.attachEvent) {
if (document.documentElement.doScroll && window == window.top) {
function tryScroll(){
if (called) return
if (!document.body) return
try {
document.documentElement.doScroll("left")
ready()
} catch(e) {
setTimeout(tryScroll, 0)
}
}
tryScroll()
}
document.attachEvent("onreadystatechange", function(){
if (document.readyState === "complete") {
ready()
}
})
}
if (window.addEventListener) window.addEventListener('load', ready, false)
else if (window.attachEvent) window.attachEvent('onload', ready)
},
event: (function(){
var guid = 0;
function fixEvent(e) {
e = e || window.event;
if (e.isFixed) {
return e;
}
e.isFixed = true;
e.preventDefault = e.preventDefault || function(){this.returnValue = false}
e.stopPropagation = e.stopPropagation || function(){this.cancelBubble = true}
if (!e.target) {
e.target = e.srcElement
}
if (!e.relatedTarget && e.fromElement) {
e.relatedTarget = e.fromElement == e.target ? e.toElement : e.fromElement;
}
if (e.pageX == null && e.clientX != null) {
var html = document.documentElement, body = document.body;
e.pageX = e.clientX + (html && html.scrollLeft || body && body.scrollLeft || 0) - (html.clientLeft || 0);
e.pageY = e.clientY + (html && html.scrollTop || body && body.scrollTop || 0) - (html.clientTop || 0);
}
if (!e.which && e.button) {
e.which = e.button & 1 ? 1 : (e.button & 2 ? 3 : (e.button & 4 ? 2 : 0));
}
if(e.type === "DOMMouseScroll" || e.type === 'mousewheel') {
e.mWheelDelta = 0;
if (e.wheelDelta) {
e.mWheelDelta = e.wheelDelta/120;
} else if (e.detail) {
e.mWheelDelta = -e.detail/3;
}
}
return e;
}
function commonHandle(event, customScope) {
event = fixEvent(event);
var handlers = this.events[event.type];
for (var g in handlers) {
var handler = handlers[g];
var ret = handler.call(customScope || this, event);
if (ret === false) {
event.preventDefault()
event.stopPropagation()
}
}
}
var publicAPI = {
add: function(elem, type, handler, forcedScope) {
// handle multiple events
if(type.indexOf(' ') > -1) {
var eventList = type.split(' ');
for(var i = 0; i < eventList.length; i++) {
publicAPI.add(elem, eventList[i], handler, forcedScope);
}
return;
}
if (elem.setInterval && (elem != window && !elem.frameElement)) {
elem = window;
}
if (!handler.guid) {
handler.guid = ++guid;
}
if (!elem.events) {
elem.events = {};
elem.handle = function(event) {
return commonHandle.call(elem, event);
}
}
if (!elem.events[type]) {
elem.events[type] = {};
if (elem.addEventListener) elem.addEventListener(type, elem.handle, false);
else if (elem.attachEvent) elem.attachEvent("on" + type, elem.handle);
if(type === 'mousewheel') {
publicAPI.add(elem, 'DOMMouseScroll', handler, forcedScope);
}
}
var fakeHandler = jcf.lib.bind(handler, forcedScope);
fakeHandler.guid = handler.guid;
elem.events[type][handler.guid] = forcedScope ? fakeHandler : handler;
},
remove: function(elem, type, handler) {
// handle multiple events
if(type.indexOf(' ') > -1) {
var eventList = type.split(' ');
for(var i = 0; i < eventList.length; i++) {
publicAPI.remove(elem, eventList[i], handler);
}
return;
}
var handlers = elem.events && elem.events[type];
if (!handlers) return;
delete handlers[handler.guid];
for(var any in handlers) return;
if (elem.removeEventListener) elem.removeEventListener(type, elem.handle, false);
else if (elem.detachEvent) elem.detachEvent("on" + type, elem.handle);
delete elem.events[type];
for (var any in elem.events) return;
try {
delete elem.handle;
delete elem.events;
} catch(e) {
if(elem.removeAttribute) {
elem.removeAttribute("handle");
elem.removeAttribute("events");
}
}
if(type === 'mousewheel') {
publicAPI.remove(elem, 'DOMMouseScroll', handler);
}
}
}
return publicAPI;
}())
}
// custom select module
jcf.addModule({
name:'select',
selector:'select',
defaultOptions: {
useNativeDropOnMobileDevices: true,
hideDropOnScroll: true,
showNativeDrop: false,
handleDropPosition: false,
selectDropPosition: 'bottom', // or 'top'
wrapperClass:'select-area',
focusClass:'select-focus',
dropActiveClass:'select-active',
selectedClass:'item-selected',
currentSelectedClass:'current-selected',
disabledClass:'select-disabled',
valueSelector:'span.center',
optGroupClass:'optgroup',
openerSelector:'a.select-opener',
selectStructure:'<span class="left"></span><span class="center"></span><a class="select-opener"></a>',
wrapperTag: 'span',
classPrefix:'select-',
dropMaxHeight: 200,
dropFlippedClass: 'select-options-flipped',
dropHiddenClass:'options-hidden',
dropScrollableClass:'options-overflow',
dropClass:'select-options',
dropClassPrefix:'drop-',
dropStructure:'<div class="drop-holder"><div class="drop-list"></div></div>',
dropSelector:'div.drop-list'
},
checkElement: function(el){
return (!el.size && !el.multiple);
},
setupWrapper: function(){
jcf.lib.addClass(this.fakeElement, this.options.wrapperClass);
this.realElement.parentNode.insertBefore(this.fakeElement, this.realElement.nextSibling);
this.fakeElement.innerHTML = this.options.selectStructure;
this.fakeElement.style.width = (this.realElement.offsetWidth > 0 ? this.realElement.offsetWidth + 'px' : 'auto');
// show native drop if specified in options
if(this.options.useNativeDropOnMobileDevices && (jcf.isTouchDevice || jcf.isWinPhoneDevice)) {
this.options.showNativeDrop = true;
}
if(this.options.showNativeDrop) {
this.fakeElement.appendChild(this.realElement);
jcf.lib.removeClass(this.realElement, this.options.hiddenClass);
jcf.lib.setStyles(this.realElement, {
top:0,
left:0,
margin:0,
padding:0,
opacity:0,
border:'none',
position:'absolute',
width: jcf.lib.getInnerWidth(this.fakeElement) - 1,
height: jcf.lib.getInnerHeight(this.fakeElement) - 1
});
jcf.lib.event.add(this.realElement, jcf.eventPress, function(){
this.realElement.title = '';
}, this)
}
// create select body
this.opener = jcf.lib.queryBySelector(this.options.openerSelector, this.fakeElement)[0];
this.valueText = jcf.lib.queryBySelector(this.options.valueSelector, this.fakeElement)[0];
jcf.lib.disableTextSelection(this.valueText);
this.opener.jcf = this;
if(!this.options.showNativeDrop) {
this.createDropdown();
this.refreshState();
this.onControlReady(this);
this.hideDropdown();
} else {
this.refreshState();
}
this.addEvents();
},
addEvents: function(){
if(this.options.showNativeDrop) {
jcf.lib.event.add(this.realElement, 'click', this.onChange, this);
} else {
jcf.lib.event.add(this.fakeElement, 'click', this.toggleDropdown, this);
}
jcf.lib.event.add(this.realElement, 'change', this.onChange, this);
},
onFakeClick: function() {
// do nothing (drop toggles by toggleDropdown method)
},
onFocus: function(){
jcf.modules[this.name].superclass.onFocus.apply(this, arguments);
if(!this.options.showNativeDrop) {
// Mac Safari Fix
if(jcf.lib.browser.safariMac) {
this.realElement.setAttribute('size','2');
}
jcf.lib.event.add(this.realElement, 'keydown', this.onKeyDown, this);
if(jcf.activeControl && jcf.activeControl != this) {
jcf.activeControl.hideDropdown();
jcf.activeControl = this;
}
}
},
onBlur: function(){
if(!this.options.showNativeDrop) {
// Mac Safari Fix
if(jcf.lib.browser.safariMac) {
this.realElement.removeAttribute('size');
}
if(!this.isActiveDrop() || !this.isOverDrop()) {
jcf.modules[this.name].superclass.onBlur.apply(this);
if(jcf.activeControl === this) jcf.activeControl = null;
if(!jcf.isTouchDevice) {
this.hideDropdown();
}
}
jcf.lib.event.remove(this.realElement, 'keydown', this.onKeyDown);
} else {
jcf.modules[this.name].superclass.onBlur.apply(this);
}
},
onChange: function() {
this.refreshState();
},
onKeyDown: function(e){
this.dropOpened = true;
jcf.tmpFlag = true;
setTimeout(function(){jcf.tmpFlag = false},100);
var context = this;
context.keyboardFix = true;
setTimeout(function(){
context.refreshState();
},10);
if(e.keyCode == 13) {
context.toggleDropdown.apply(context);
return false;
}
},
onResizeWindow: function(e){
if(this.isActiveDrop()) {
this.hideDropdown();
}
},
onScrollWindow: function(e){
if(this.options.hideDropOnScroll) {
this.hideDropdown();
} else if(this.isActiveDrop()) {
this.positionDropdown();
}
},
onOptionClick: function(e){
var opener = e.target && e.target.tagName && e.target.tagName.toLowerCase() == 'li' ? e.target : jcf.lib.getParent(e.target, 'li');
if(opener && !jcf.lib.hasClass(opener, 'opt-disabled')) {
this.dropOpened = true;
this.realElement.selectedIndex = parseInt(opener.getAttribute('rel'));
if(jcf.isTouchDevice) {
this.onFocus();
} else {
this.realElement.focus();
}
this.refreshState();
this.hideDropdown();
jcf.lib.fireEvent(this.realElement, 'change');
}
return false;
},
onClickOutside: function(e){
if(jcf.tmpFlag) {
jcf.tmpFlag = false;
return;
}
if(!jcf.lib.isParent(this.fakeElement, e.target) && !jcf.lib.isParent(this.selectDrop, e.target)) {
this.hideDropdown();
}
},
onDropHover: function(e){
if(!this.keyboardFix) {
this.hoverFlag = true;
var opener = e.target && e.target.tagName && e.target.tagName.toLowerCase() == 'li' ? e.target : jcf.lib.getParent(e.target, 'li');
if(opener) {
this.realElement.selectedIndex = parseInt(opener.getAttribute('rel'));
this.refreshSelectedClass(parseInt(opener.getAttribute('rel')));
}
} else {
this.keyboardFix = false;
}
},
onDropLeave: function(){
this.hoverFlag = false;
},
isActiveDrop: function(){
return !jcf.lib.hasClass(this.selectDrop, this.options.dropHiddenClass);
},
isOverDrop: function(){
return this.hoverFlag;
},
createDropdown: function(){
// remove old dropdown if exists
if(this.selectDrop && this.selectDrop.parentNode) {
this.selectDrop.parentNode.removeChild(this.selectDrop);
}
// create dropdown holder
this.selectDrop = document.createElement('div');
this.selectDrop.className = this.options.dropClass;
this.selectDrop.innerHTML = this.options.dropStructure;
jcf.lib.setStyles(this.selectDrop, {position:'absolute'});
this.selectList = jcf.lib.queryBySelector(this.options.dropSelector,this.selectDrop)[0];
jcf.lib.addClass(this.selectDrop, this.options.dropHiddenClass);
document.body.appendChild(this.selectDrop);
this.selectDrop.jcf = this;
jcf.lib.event.add(this.selectDrop, 'click', this.onOptionClick, this);
jcf.lib.event.add(this.selectDrop, 'mouseover', this.onDropHover, this);
jcf.lib.event.add(this.selectDrop, 'mouseout', this.onDropLeave, this);
this.buildDropdown();
},
buildDropdown: function() {
// build select options / optgroups
this.buildDropdownOptions();
// position and resize dropdown
this.positionDropdown();
// cut dropdown if height exceedes
this.buildDropdownScroll();
},
buildDropdownOptions: function() {
this.resStructure = '';
this.optNum = 0;
for(var i = 0; i < this.realElement.children.length; i++) {
this.resStructure += this.buildElement(this.realElement.children[i], i) +'\n';
}
this.selectList.innerHTML = this.resStructure;
},
buildDropdownScroll: function() {
jcf.lib.addClass(this.selectDrop, jcf.lib.getAllClasses(this.realElement.className, this.options.dropClassPrefix, jcf.baseOptions.hiddenClass));
if(this.options.dropMaxHeight) {
if(this.selectDrop.offsetHeight > this.options.dropMaxHeight) {
this.selectList.style.height = this.options.dropMaxHeight+'px';
this.selectList.style.overflow = 'auto';
this.selectList.style.overflowX = 'hidden';
jcf.lib.addClass(this.selectDrop, this.options.dropScrollableClass);
}
}
},
parseOptionTitle: function(optTitle) {
return (typeof optTitle === 'string' && /\.(jpg|gif|png|bmp|jpeg)(.*)?$/i.test(optTitle)) ? optTitle : '';
},
buildElement: function(obj, index){
// build option
var res = '', optImage;
if(obj.tagName.toLowerCase() == 'option') {
if(!jcf.lib.prevSibling(obj) || jcf.lib.prevSibling(obj).tagName.toLowerCase() != 'option') {
res += '<ul>';
}
optImage = this.parseOptionTitle(obj.title);
res += '<li rel="'+(this.optNum++)+'" class="'+(obj.className? obj.className + ' ' : '')+(obj.disabled? 'opt-disabled ' : '')+(index % 2 ? 'option-even ' : '')+'jcfcalc"><a href="#">'+(optImage ? '<img src="'+optImage+'" alt="" />' : '')+'<span>' + obj.innerHTML + '</span></a></li>';
if(!jcf.lib.nextSibling(obj) || jcf.lib.nextSibling(obj).tagName.toLowerCase() != 'option') {
res += '</ul>';
}
return res;
}
// build option group with options
else if(obj.tagName.toLowerCase() == 'optgroup' && obj.label) {
res += '<div class="'+this.options.optGroupClass+'">';
res += '<strong class="jcfcalc"><em>'+(obj.label)+'</em></strong>';
for(var i = 0; i < obj.children.length; i++) {
res += this.buildElement(obj.children[i], i);
}
res += '</div>';
return res;
}
},
positionDropdown: function(){
var ofs = jcf.lib.getOffset(this.fakeElement), selectAreaHeight = this.fakeElement.offsetHeight, selectDropHeight = this.selectDrop.offsetHeight;
var fitInTop = ofs.top - selectDropHeight >= jcf.lib.getScrollTop() && jcf.lib.getScrollTop() + jcf.lib.getWindowHeight() < ofs.top + selectAreaHeight + selectDropHeight;
if((this.options.handleDropPosition && fitInTop) || this.options.selectDropPosition === 'top') {
this.selectDrop.style.top = (ofs.top - selectDropHeight)+'px';
jcf.lib.addClass(this.selectDrop, this.options.dropFlippedClass);
jcf.lib.addClass(this.fakeElement, this.options.dropFlippedClass);
} else {
this.selectDrop.style.top = (ofs.top + selectAreaHeight)+'px';
jcf.lib.removeClass(this.selectDrop, this.options.dropFlippedClass);
jcf.lib.removeClass(this.fakeElement, this.options.dropFlippedClass);
}
this.selectDrop.style.left = ofs.left+'px';
this.selectDrop.style.width = this.fakeElement.offsetWidth+'px';
},
showDropdown: function(){
document.body.appendChild(this.selectDrop);
jcf.lib.removeClass(this.selectDrop, this.options.dropHiddenClass);
jcf.lib.addClass(this.fakeElement,this.options.dropActiveClass);
this.positionDropdown();
// highlight current active item
var activeItem = this.getFakeActiveOption();
this.removeClassFromItems(this.options.currentSelectedClass);
jcf.lib.addClass(activeItem, this.options.currentSelectedClass);
// show current dropdown
jcf.lib.event.add(window, 'resize', this.onResizeWindow, this);
jcf.lib.event.add(window, 'scroll', this.onScrollWindow, this);
jcf.lib.event.add(document, jcf.eventPress, this.onClickOutside, this);
this.positionDropdown();
},
hideDropdown: function(){
if(this.selectDrop.parentNode) {
this.selectDrop.parentNode.removeChild(this.selectDrop);
}
if(typeof this.origSelectedIndex === 'number') {
this.realElement.selectedIndex = this.origSelectedIndex;
}
jcf.lib.removeClass(this.fakeElement,this.options.dropActiveClass);
jcf.lib.addClass(this.selectDrop, this.options.dropHiddenClass);
jcf.lib.event.remove(window, 'resize', this.onResizeWindow);
jcf.lib.event.remove(window, 'scroll', this.onScrollWindow);
jcf.lib.event.remove(document.documentElement, jcf.eventPress, this.onClickOutside);
if(jcf.isTouchDevice) {
this.onBlur();
}
},
toggleDropdown: function(){
if(!this.realElement.disabled && this.realElement.options.length) {
if(jcf.isTouchDevice) {
this.onFocus();
} else {
this.realElement.focus();
}
if(this.isActiveDrop()) {
this.hideDropdown();
} else {
this.showDropdown();
}
this.refreshState();
}
},
scrollToItem: function(){
if(this.isActiveDrop()) {
var dropHeight = this.selectList.offsetHeight;
var offsetTop = this.calcOptionOffset(this.getFakeActiveOption());
var sTop = this.selectList.scrollTop;
var oHeight = this.getFakeActiveOption().offsetHeight;
//offsetTop+=sTop;
if(offsetTop >= sTop + dropHeight) {
this.selectList.scrollTop = offsetTop - dropHeight + oHeight;
} else if(offsetTop < sTop) {
this.selectList.scrollTop = offsetTop;
}
}
},
getFakeActiveOption: function(c) {
return jcf.lib.queryBySelector('li[rel="'+(typeof c === 'number' ? c : this.realElement.selectedIndex) +'"]',this.selectList)[0];
},
calcOptionOffset: function(fake) {
var h = 0;
var els = jcf.lib.queryBySelector('.jcfcalc',this.selectList);
for(var i = 0; i < els.length; i++) {
if(els[i] == fake) break;
h+=els[i].offsetHeight;
}
return h;
},
childrenHasItem: function(hold,item) {
var items = hold.getElementsByTagName('*');
for(i = 0; i < items.length; i++) {
if(items[i] == item) return true;
}
return false;
},
removeClassFromItems: function(className){
var children = jcf.lib.queryBySelector('li',this.selectList);
for(var i = children.length - 1; i >= 0; i--) {
jcf.lib.removeClass(children[i], className);
}
},
setSelectedClass: function(c){
var activeOption = this.getFakeActiveOption(c);
if(activeOption) {
jcf.lib.addClass(activeOption, this.options.selectedClass);
}
},
refreshSelectedClass: function(c){
if(!this.options.showNativeDrop) {
this.removeClassFromItems(this.options.selectedClass);
this.setSelectedClass(c);
}
if(this.realElement.disabled) {
jcf.lib.addClass(this.fakeElement, this.options.disabledClass);
if(this.labelFor) {
jcf.lib.addClass(this.labelFor, this.options.labelDisabledClass);
}
} else {
jcf.lib.removeClass(this.fakeElement, this.options.disabledClass);
if(this.labelFor) {
jcf.lib.removeClass(this.labelFor, this.options.labelDisabledClass);
}
}
},
refreshSelectedText: function() {
if(!this.dropOpened && this.realElement.title) {
this.valueText.innerHTML = this.realElement.title;
} else {
var activeOption = this.realElement.options[this.realElement.selectedIndex];
if(activeOption) {
if(activeOption.title) {
var optImage = this.parseOptionTitle(this.realElement.options[this.realElement.selectedIndex].title);
this.valueText.innerHTML = (optImage ? '<img src="'+optImage+'" alt="" />' : '') + this.realElement.options[this.realElement.selectedIndex].innerHTML;
} else {
this.valueText.innerHTML = this.realElement.options[this.realElement.selectedIndex].innerHTML;
}
}
}
var selectedOption = this.realElement.options[this.realElement.selectedIndex];
if(selectedOption && selectedOption.className) {
this.fakeElement.setAttribute('data-option-class', jcf.lib.getAllClasses(selectedOption.className, 'option-').replace(/^\s+|\s+$/g, ''));
} else {
this.fakeElement.removeAttribute('data-option-class');
}
},
refreshState: function(){
this.origSelectedIndex = this.realElement.selectedIndex;
this.refreshSelectedClass();
this.refreshSelectedText();
if(!this.options.showNativeDrop) {
this.positionDropdown();
if(this.selectDrop.offsetWidth) {
this.scrollToItem();
}
}
}
});
// custom radio module
jcf.addModule({
name:'radio',
selector: 'input[type="radio"]',
defaultOptions: {
wrapperClass:'rad-area',
focusClass:'rad-focus',
checkedClass:'rad-checked',
uncheckedClass:'rad-unchecked',
disabledClass:'rad-disabled',
radStructure:'<span></span>'
},
getRadioGroup: function(item){
var name = item.getAttribute('name');
if(name) {
return jcf.lib.queryBySelector('input[name="'+name+'"]', jcf.lib.getParent('form'));
} else {
return [item];
}
},
setupWrapper: function(){
jcf.lib.addClass(this.fakeElement, this.options.wrapperClass);
this.fakeElement.innerHTML = this.options.radStructure;
this.realElement.parentNode.insertBefore(this.fakeElement, this.realElement);
this.refreshState();
this.addEvents();
},
addEvents: function(){
jcf.lib.event.add(this.fakeElement, 'click', this.toggleRadio, this);
if(this.labelFor) {
jcf.lib.event.add(this.labelFor, 'click', this.toggleRadio, this);
}
},
onFocus: function(e) {
jcf.modules[this.name].superclass.onFocus.apply(this, arguments);
setTimeout(jcf.lib.bind(function(){
this.refreshState();
},this),10);
},
toggleRadio: function(){
if(!this.realElement.disabled && !this.realElement.checked) {
this.realElement.checked = true;
jcf.lib.fireEvent(this.realElement, 'change');
}
this.refreshState();
},
refreshState: function(){
var els = this.getRadioGroup(this.realElement);
for(var i = 0; i < els.length; i++) {
var curEl = els[i].jcf;
if(curEl) {
if(curEl.realElement.checked) {
jcf.lib.addClass(curEl.fakeElement, curEl.options.checkedClass);
jcf.lib.removeClass(curEl.fakeElement, curEl.options.uncheckedClass);
if(curEl.labelFor) {
jcf.lib.addClass(curEl.labelFor, curEl.options.labelActiveClass);
}
} else {
jcf.lib.removeClass(curEl.fakeElement, curEl.options.checkedClass);
jcf.lib.addClass(curEl.fakeElement, curEl.options.uncheckedClass);
if(curEl.labelFor) {
jcf.lib.removeClass(curEl.labelFor, curEl.options.labelActiveClass);
}
}
if(curEl.realElement.disabled) {
jcf.lib.addClass(curEl.fakeElement, curEl.options.disabledClass);
if(curEl.labelFor) {
jcf.lib.addClass(curEl.labelFor, curEl.options.labelDisabledClass);
}
} else {
jcf.lib.removeClass(curEl.fakeElement, curEl.options.disabledClass);
if(curEl.labelFor) {
jcf.lib.removeClass(curEl.labelFor, curEl.options.labelDisabledClass);
}
}
}
}
}
});
// custom checkbox module
jcf.addModule({
name:'checkbox',
selector:'input[type="checkbox"]',
defaultOptions: {
wrapperClass:'chk-area',
focusClass:'chk-focus',
checkedClass:'chk-checked',
labelActiveClass:'chk-label-active',
uncheckedClass:'chk-unchecked',
disabledClass:'chk-disabled',
chkStructure:'<span></span>'
},
setupWrapper: function(){
jcf.lib.addClass(this.fakeElement, this.options.wrapperClass);
this.fakeElement.innerHTML = this.options.chkStructure;
this.realElement.parentNode.insertBefore(this.fakeElement, this.realElement);
jcf.lib.event.add(this.realElement, 'click', this.onRealClick, this);
this.refreshState();
},
isLinkTarget: function(target, limitParent) {
while(target.parentNode || target === limitParent) {
if(target.tagName.toLowerCase() === 'a') {
return true;
}
target = target.parentNode;
}
},
onFakePressed: function() {
jcf.modules[this.name].superclass.onFakePressed.apply(this, arguments);
if(!this.realElement.disabled) {
this.realElement.focus();
}
},
onFakeClick: function(e) {
jcf.modules[this.name].superclass.onFakeClick.apply(this, arguments);
this.tmpTimer = setTimeout(jcf.lib.bind(function(){
this.toggle();
},this),10);
if(!this.isLinkTarget(e.target, this.labelFor)) {
return false;
}
},
onRealClick: function(e) {
setTimeout(jcf.lib.bind(function(){
this.refreshState();
},this),10);
e.stopPropagation();
},
toggle: function(e){
if(!this.realElement.disabled) {
if(this.realElement.checked) {
this.realElement.checked = false;
} else {
this.realElement.checked = true;
}
}
this.refreshState();
jcf.lib.fireEvent(this.realElement, 'change');
return false;
},
refreshState: function(){
if(this.realElement.checked) {
jcf.lib.addClass(this.fakeElement, this.options.checkedClass);
jcf.lib.removeClass(this.fakeElement, this.options.uncheckedClass);
if(this.labelFor) {
jcf.lib.addClass(this.labelFor, this.options.labelActiveClass);
}
} else {
jcf.lib.removeClass(this.fakeElement, this.options.checkedClass);
jcf.lib.addClass(this.fakeElement, this.options.uncheckedClass);
if(this.labelFor) {
jcf.lib.removeClass(this.labelFor, this.options.labelActiveClass);
}
}
if(this.realElement.disabled) {
jcf.lib.addClass(this.fakeElement, this.options.disabledClass);
if(this.labelFor) {
jcf.lib.addClass(this.labelFor, this.options.labelDisabledClass);
}
} else {
jcf.lib.removeClass(this.fakeElement, this.options.disabledClass);
if(this.labelFor) {
jcf.lib.removeClass(this.labelFor, this.options.labelDisabledClass);
}
}
}
});
// custom scrollbars module
jcf.addModule({
name:'customscroll',
selector:'div.scrollable-area',
defaultOptions: {
alwaysPreventWheel: false,
enableMouseWheel: true,
captureFocus: false,
handleNested: true,
alwaysKeepScrollbars: false,
autoDetectWidth: false,
scrollbarOptions: {},
focusClass:'scrollable-focus',
wrapperTag: 'div',
autoDetectWidthClass: 'autodetect-width',
noHorizontalBarClass:'noscroll-horizontal',
noVerticalBarClass:'noscroll-vertical',
innerWrapperClass:'scrollable-inner-wrapper',
outerWrapperClass:'scrollable-area-wrapper',
horizontalClass: 'hscrollable',
verticalClass: 'vscrollable',
bothClass: 'anyscrollable'
},
replaceObject: function(){
this.initStructure();
this.refreshState();
this.addEvents();
},
initStructure: function(){
// set scroll type
this.realElement.jcf = this;
if(jcf.lib.hasClass(this.realElement, this.options.bothClass) ||
jcf.lib.hasClass(this.realElement, this.options.horizontalClass) && jcf.lib.hasClass(this.realElement, this.options.verticalClass)) {
this.scrollType = 'both';
} else if(jcf.lib.hasClass(this.realElement, this.options.horizontalClass)) {
this.scrollType = 'horizontal';
} else {
this.scrollType = 'vertical';
}
// autodetect horizontal width
if(jcf.lib.hasClass(this.realElement,this.options.autoDetectWidthClass)) {
this.options.autoDetectWidth = true;
}
// init dimensions and build structure
this.realElement.style.position = 'relative';
this.realElement.style.overflow = 'hidden';
// build content wrapper and scrollbar(s)
this.buildWrapper();
this.buildScrollbars();
},
buildWrapper: function() {
this.outerWrapper = document.createElement(this.options.wrapperTag);
this.outerWrapper.className = this.options.outerWrapperClass;
this.realElement.parentNode.insertBefore(this.outerWrapper, this.realElement);
this.outerWrapper.appendChild(this.realElement);
// autosize content if single child
if(this.options.autoDetectWidth && (this.scrollType === 'both' || this.scrollType === 'horizontal') && this.realElement.children.length === 1) {
var tmpWidth = 0;
this.realElement.style.width = '99999px';
tmpWidth = this.realElement.children[0].offsetWidth;
this.realElement.style.width = '';
if(tmpWidth) {
this.realElement.children[0].style.width = tmpWidth+'px';
}
}
},
buildScrollbars: function() {
if(this.scrollType === 'horizontal' || this.scrollType === 'both') {
this.hScrollBar = new jcf.plugins.scrollbar(jcf.lib.extend(this.options.scrollbarOptions,{
vertical: false,
spawnClass: this,
holder: this.outerWrapper,
range: this.realElement.scrollWidth - this.realElement.offsetWidth,
size: this.realElement.offsetWidth,
onScroll: jcf.lib.bind(function(v) {
this.realElement.scrollLeft = v;
},this)
}));
}
if(this.scrollType === 'vertical' || this.scrollType === 'both') {
this.vScrollBar = new jcf.plugins.scrollbar(jcf.lib.extend(this.options.scrollbarOptions,{
vertical: true,
spawnClass: this,
holder: this.outerWrapper,
range: this.realElement.scrollHeight - this.realElement.offsetHeight,
size: this.realElement.offsetHeight,
onScroll: jcf.lib.bind(function(v) {
this.realElement.scrollTop = v;
},this)
}));
}
this.outerWrapper.style.width = this.realElement.offsetWidth + 'px';
this.outerWrapper.style.height = this.realElement.offsetHeight + 'px';
this.resizeScrollContent();
},
resizeScrollContent: function() {
var diffWidth = this.realElement.offsetWidth - jcf.lib.getInnerWidth(this.realElement);
var diffHeight = this.realElement.offsetHeight - jcf.lib.getInnerHeight(this.realElement);
this.realElement.style.width = Math.max(0, this.outerWrapper.offsetWidth - diffWidth - (this.vScrollBar ? this.vScrollBar.getScrollBarSize() : 0)) + 'px';
this.realElement.style.height = Math.max(0, this.outerWrapper.offsetHeight - diffHeight - (this.hScrollBar ? this.hScrollBar.getScrollBarSize() : 0)) + 'px';
},
addEvents: function() {
// enable mouse wheel handling
if(!jcf.isTouchDevice && this.options.enableMouseWheel) {
jcf.lib.event.add(this.outerWrapper, 'mousewheel', this.onMouseWheel, this);
}
// add touch scroll on block body
if(jcf.isTouchDevice || navigator.msPointerEnabled || navigator.pointerEnabled) {
this.outerWrapper.style.msTouchAction = 'none';
jcf.lib.event.add(this.realElement, jcf.eventPress, this.onScrollablePress, this);
}
// handle nested scrollbars
if(this.options.handleNested) {
var el = this.realElement, name = this.name;
while(el.parentNode) {
if(el.parentNode.jcf && el.parentNode.jcf.name == name) {
el.parentNode.jcf.refreshState();
}
el = el.parentNode;
}
}
},
isTouchPointerEvent: function(e) {
return (e.type.indexOf('touch') > -1) ||
(navigator.pointerEnabled && e.pointerType === 'touch') ||
(navigator.msPointerEnabled && e.pointerType === e.MSPOINTER_TYPE_TOUCH);
},
onMouseWheel: function(e) {
if(this.scrollType === 'vertical' || this.scrollType === 'both') {
return this.vScrollBar.doScrollWheelStep(e.mWheelDelta) === false ? false : !this.options.alwaysPreventWheel;
} else {
return this.hScrollBar.doScrollWheelStep(e.mWheelDelta) === false ? false : !this.options.alwaysPreventWheel;
}
},
onScrollablePress: function(e) {
if(!this.isTouchPointerEvent(e)) {
return;
}
this.preventFlag = true;
this.origWindowScrollTop = jcf.lib.getScrollTop();
this.origWindowScrollLeft = jcf.lib.getScrollLeft();
this.scrollableOffset = jcf.lib.getOffset(this.realElement);
if(this.hScrollBar) {
this.scrollableTouchX = (e.changedTouches ? e.changedTouches[0] : e).pageX;
this.origValueX = this.hScrollBar.getScrollValue();
}
if(this.vScrollBar) {
this.scrollableTouchY = (e.changedTouches ? e.changedTouches[0] : e).pageY;
this.origValueY = this.vScrollBar.getScrollValue();
}
jcf.lib.event.add(this.realElement, jcf.eventMove, this.onScrollableMove, this);
jcf.lib.event.add(this.realElement, jcf.eventRelease, this.onScrollableRelease, this);
},
onScrollableMove: function(e) {
if(this.vScrollBar) {
var difY = (e.changedTouches ? e.changedTouches[0] : e).pageY - this.scrollableTouchY;
var valY = this.origValueY-difY;
this.vScrollBar.scrollTo(valY);
if(valY < 0 || valY > this.vScrollBar.options.range) {
this.preventFlag = false;
}
}
if(this.hScrollBar) {
var difX = (e.changedTouches ? e.changedTouches[0] : e).pageX - this.scrollableTouchX;
var valX = this.origValueX-difX;
this.hScrollBar.scrollTo(valX);
if(valX < 0 || valX > this.hScrollBar.options.range) {
this.preventFlag = false;
}
}
if(this.preventFlag) {
e.preventDefault();
}
},
onScrollableRelease: function() {
jcf.lib.event.remove(this.realElement, jcf.eventMove, this.onScrollableMove);
jcf.lib.event.remove(this.realElement, jcf.eventRelease, this.onScrollableRelease);
},
refreshState: function() {
if(this.options.alwaysKeepScrollbars) {
if(this.hScrollBar) this.hScrollBar.scrollBar.style.display = 'block';
if(this.vScrollBar) this.vScrollBar.scrollBar.style.display = 'block';
} else {
if(this.hScrollBar) {
if(this.getScrollRange(false)) {
this.hScrollBar.scrollBar.style.display = 'block';
this.resizeScrollContent();
this.hScrollBar.setRange(this.getScrollRange(false));
} else {
this.hScrollBar.scrollBar.style.display = 'none';
this.realElement.style.width = this.outerWrapper.style.width;
}
jcf.lib.toggleClass(this.outerWrapper, this.options.noHorizontalBarClass, this.hScrollBar.options.range === 0);
}
if(this.vScrollBar) {
if(this.getScrollRange(true) > 0) {
this.vScrollBar.scrollBar.style.display = 'block';
this.resizeScrollContent();
this.vScrollBar.setRange(this.getScrollRange(true));
} else {
this.vScrollBar.scrollBar.style.display = 'none';
this.realElement.style.width = this.outerWrapper.style.width;
}
jcf.lib.toggleClass(this.outerWrapper, this.options.noVerticalBarClass, this.vScrollBar.options.range === 0);
}
}
if(this.vScrollBar) {
this.vScrollBar.setRange(this.realElement.scrollHeight - this.realElement.offsetHeight);
this.vScrollBar.setSize(this.realElement.offsetHeight);
this.vScrollBar.scrollTo(this.realElement.scrollTop);
}
if(this.hScrollBar) {
this.hScrollBar.setRange(this.realElement.scrollWidth - this.realElement.offsetWidth);
this.hScrollBar.setSize(this.realElement.offsetWidth);
this.hScrollBar.scrollTo(this.realElement.scrollLeft);
}
},
getScrollRange: function(isVertical) {
if(isVertical) {
return this.realElement.scrollHeight - this.realElement.offsetHeight;
} else {
return this.realElement.scrollWidth - this.realElement.offsetWidth;
}
},
getCurrentRange: function(scrollInstance) {
return this.getScrollRange(scrollInstance.isVertical);
},
onCreateModule: function(){
if(jcf.modules.select) {
this.extendSelect();
}
if(jcf.modules.selectmultiple) {
this.extendSelectMultiple();
}
if(jcf.modules.textarea) {
this.extendTextarea();
}
},
onModuleAdded: function(module){
if(module.prototype.name == 'select') {
this.extendSelect();
}
if(module.prototype.name == 'selectmultiple') {
this.extendSelectMultiple();
}
if(module.prototype.name == 'textarea') {
this.extendTextarea();
}
},
extendSelect: function() {
// add scrollable if needed on control ready
jcf.modules.select.prototype.onControlReady = function(obj){
if(obj.selectList.scrollHeight > obj.selectList.offsetHeight) {
obj.jcfScrollable = new jcf.modules.customscroll({
alwaysPreventWheel: true,
replaces:obj.selectList
});
}
}
// update scroll function
var orig = jcf.modules.select.prototype.scrollToItem;
jcf.modules.select.prototype.scrollToItem = function(){
orig.apply(this);
if(this.jcfScrollable) {
this.jcfScrollable.refreshState();
}
}
},
extendTextarea: function() {
// add scrollable if needed on control ready
jcf.modules.textarea.prototype.onControlReady = function(obj){
obj.jcfScrollable = new jcf.modules.customscroll({
alwaysKeepScrollbars: true,
alwaysPreventWheel: true,
replaces: obj.realElement
});
}
// update scroll function
var orig = jcf.modules.textarea.prototype.refreshState;
jcf.modules.textarea.prototype.refreshState = function(){
orig.apply(this);
if(this.jcfScrollable) {
this.jcfScrollable.refreshState();
}
}
},
extendSelectMultiple: function(){
// add scrollable if needed on control ready
jcf.modules.selectmultiple.prototype.onControlReady = function(obj){
//if(obj.optionsHolder.scrollHeight > obj.optionsHolder.offsetHeight) {
obj.jcfScrollable = new jcf.modules.customscroll({
alwaysPreventWheel: true,
replaces:obj.optionsHolder
});
//}
}
// update scroll function
var orig = jcf.modules.selectmultiple.prototype.scrollToItem;
jcf.modules.selectmultiple.prototype.scrollToItem = function(){
orig.apply(this);
if(this.jcfScrollable) {
this.jcfScrollable.refreshState();
}
}
// update scroll size?
var orig2 = jcf.modules.selectmultiple.prototype.rebuildOptions;
jcf.modules.selectmultiple.prototype.rebuildOptions = function(){
orig2.apply(this);
if(this.jcfScrollable) {
this.jcfScrollable.refreshState();
}
}
}
});
// scrollbar plugin
jcf.addPlugin({
name: 'scrollbar',
defaultOptions: {
size: 0,
range: 0,
moveStep: 6,
moveDistance: 50,
moveInterval: 10,
trackHoldDelay: 900,
holder: null,
vertical: true,
scrollTag: 'div',
onScroll: function(){},
onScrollEnd: function(){},
onScrollStart: function(){},
disabledClass: 'btn-disabled',
VscrollBarClass:'vscrollbar',
VscrollStructure: '<div class="vscroll-up"></div><div class="vscroll-line"><div class="vscroll-slider"><div class="scroll-bar-top"></div><div class="scroll-bar-bottom"></div></div></div></div><div class="vscroll-down"></div>',
VscrollTrack: 'div.vscroll-line',
VscrollBtnDecClass:'div.vscroll-up',
VscrollBtnIncClass:'div.vscroll-down',
VscrollSliderClass:'div.vscroll-slider',
HscrollBarClass:'hscrollbar',
HscrollStructure: '<div class="hscroll-left"></div><div class="hscroll-line"><div class="hscroll-slider"><div class="scroll-bar-left"></div><div class="scroll-bar-right"></div></div></div></div><div class="hscroll-right"></div>',
HscrollTrack: 'div.hscroll-line',
HscrollBtnDecClass:'div.hscroll-left',
HscrollBtnIncClass:'div.hscroll-right',
HscrollSliderClass:'div.hscroll-slider'
},
init: function(userOptions) {
this.setOptions(userOptions);
this.createScrollBar();
this.attachEvents();
this.setSize();
},
setOptions: function(extOptions) {
// merge options
this.options = jcf.lib.extend({}, this.defaultOptions, extOptions);
this.isVertical = this.options.vertical;
this.prefix = this.isVertical ? 'V' : 'H';
this.eventPageOffsetProperty = this.isVertical ? 'pageY' : 'pageX';
this.positionProperty = this.isVertical ? 'top' : 'left';
this.sizeProperty = this.isVertical ? 'height' : 'width';
this.dimenionsProperty = this.isVertical ? 'offsetHeight' : 'offsetWidth';
this.invertedDimenionsProperty = !this.isVertical ? 'offsetHeight' : 'offsetWidth';
// set corresponding classes
for(var p in this.options) {
if(p.indexOf(this.prefix) == 0) {
this.options[p.substr(1)] = this.options[p];
}
}
},
createScrollBar: function() {
// create dimensions
this.scrollBar = document.createElement(this.options.scrollTag);
this.scrollBar.className = this.options.scrollBarClass;
this.scrollBar.innerHTML = this.options.scrollStructure;
// get elements
this.track = jcf.lib.queryBySelector(this.options.scrollTrack,this.scrollBar)[0];
this.btnDec = jcf.lib.queryBySelector(this.options.scrollBtnDecClass,this.scrollBar)[0];
this.btnInc = jcf.lib.queryBySelector(this.options.scrollBtnIncClass,this.scrollBar)[0];
this.slider = jcf.lib.queryBySelector(this.options.scrollSliderClass,this.scrollBar)[0];
this.slider.style.position = 'absolute';
this.track.style.position = 'relative';
},
attachEvents: function() {
// append scrollbar to holder if provided
if(this.options.holder) {
this.options.holder.appendChild(this.scrollBar);
}
// attach listeners for slider and buttons
jcf.lib.event.add(this.slider, jcf.eventPress, this.onSliderPressed, this);
jcf.lib.event.add(this.btnDec, jcf.eventPress, this.onBtnDecPressed, this);
jcf.lib.event.add(this.btnInc, jcf.eventPress, this.onBtnIncPressed, this);
jcf.lib.event.add(this.track, jcf.eventPress, this.onTrackPressed, this);
},
setSize: function(value) {
if(typeof value === 'number') {
this.options.size = value;
}
this.scrollOffset = this.scrollValue = this.sliderOffset = 0;
this.scrollBar.style[this.sizeProperty] = this.options.size + 'px';
this.resizeControls();
this.refreshSlider();
},
setRange: function(r) {
this.options.range = Math.max(r,0);
this.resizeControls();
},
doScrollWheelStep: function(direction) {
// 1 - scroll up, -1 scroll down
this.startScroll();
if((direction < 0 && !this.isEndPosition()) || (direction > 0 && !this.isStartPosition())) {
this.scrollTo(this.getScrollValue()-this.options.moveDistance * direction);
this.moveScroll();
this.endScroll();
return false;
}
},
resizeControls: function() {
// calculate dimensions
this.barSize = this.scrollBar[this.dimenionsProperty];
this.btnDecSize = this.btnDec[this.dimenionsProperty];
this.btnIncSize = this.btnInc[this.dimenionsProperty];
this.trackSize = Math.max(0, this.barSize - this.btnDecSize - this.btnIncSize);
// resize and reposition elements
this.track.style[this.sizeProperty] = this.trackSize + 'px';
this.trackSize = this.track[this.dimenionsProperty];
this.sliderSize = this.getSliderSize();
this.slider.style[this.sizeProperty] = this.sliderSize + 'px';
this.sliderSize = this.slider[this.dimenionsProperty];
},
refreshSlider: function(complete) {
// refresh dimensions
if(complete) {
this.resizeControls();
}
// redraw slider and classes
this.sliderOffset = isNaN(this.sliderOffset) ? 0 : this.sliderOffset;
this.slider.style[this.positionProperty] = this.sliderOffset + 'px';
},
startScroll: function() {
// refresh range if possible
if(this.options.spawnClass && typeof this.options.spawnClass.getCurrentRange === 'function') {
this.setRange(this.options.spawnClass.getCurrentRange(this));
}
this.resizeControls();
this.scrollBarOffset = jcf.lib.getOffset(this.track)[this.positionProperty];
this.options.onScrollStart();
},
moveScroll: function() {
this.options.onScroll(this.scrollValue);
// add disabled classes
jcf.lib.removeClass(this.btnDec, this.options.disabledClass);
jcf.lib.removeClass(this.btnInc, this.options.disabledClass);
if(this.scrollValue === 0) {
jcf.lib.addClass(this.btnDec, this.options.disabledClass);
}
if(this.scrollValue === this.options.range) {
jcf.lib.addClass(this.btnInc, this.options.disabledClass);
}
},
endScroll: function() {
this.options.onScrollEnd();
},
startButtonMoveScroll: function(direction) {
this.startScroll();
clearInterval(this.buttonScrollTimer);
this.buttonScrollTimer = setInterval(jcf.lib.bind(function(){
this.scrollValue += this.options.moveStep * direction
if(this.scrollValue > this.options.range) {
this.scrollValue = this.options.range;
this.endButtonMoveScroll();
} else if(this.scrollValue < 0) {
this.scrollValue = 0;
this.endButtonMoveScroll();
}
this.scrollTo(this.scrollValue);
},this),this.options.moveInterval);
},
endButtonMoveScroll: function() {
clearInterval(this.buttonScrollTimer);
this.endScroll();
},
isStartPosition: function() {
return this.scrollValue === 0;
},
isEndPosition: function() {
return this.scrollValue === this.options.range;
},
getSliderSize: function() {
return Math.round(this.getSliderSizePercent() * this.trackSize / 100);
},
getSliderSizePercent: function() {
return this.options.range === 0 ? 0 : this.barSize * 100 / (this.barSize + this.options.range);
},
getSliderOffsetByScrollValue: function() {
return (this.scrollValue * 100 / this.options.range) * (this.trackSize - this.sliderSize) / 100;
},
getSliderOffsetPercent: function() {
return this.sliderOffset * 100 / (this.trackSize - this.sliderSize);
},
getScrollValueBySliderOffset: function() {
return this.getSliderOffsetPercent() * this.options.range / 100;
},
getScrollBarSize: function() {
return this.scrollBar[this.invertedDimenionsProperty];
},
getScrollValue: function() {
return this.scrollValue || 0;
},
scrollOnePage: function(direction) {
this.scrollTo(this.scrollValue + direction*this.barSize);
},
scrollTo: function(x) {
this.scrollValue = x < 0 ? 0 : x > this.options.range ? this.options.range : x;
this.sliderOffset = this.getSliderOffsetByScrollValue();
this.refreshSlider();
this.moveScroll();
},
onSliderPressed: function(e){
jcf.lib.event.add(document.body, jcf.eventRelease, this.onSliderRelease, this);
jcf.lib.event.add(document.body, jcf.eventMove, this.onSliderMove, this);
jcf.lib.disableTextSelection(this.slider);
// calculate offsets once
this.sliderInnerOffset = (e.changedTouches ? e.changedTouches[0] : e)[this.eventPageOffsetProperty] - jcf.lib.getOffset(this.slider)[this.positionProperty];
this.startScroll();
return false;
},
onSliderRelease: function(){
jcf.lib.event.remove(document.body, jcf.eventRelease, this.onSliderRelease);
jcf.lib.event.remove(document.body, jcf.eventMove, this.onSliderMove);
},
onSliderMove: function(e) {
e.preventDefault();
this.sliderOffset = (e.changedTouches ? e.changedTouches[0] : e)[this.eventPageOffsetProperty] - this.scrollBarOffset - this.sliderInnerOffset;
if(this.sliderOffset < 0) {
this.sliderOffset = 0;
} else if(this.sliderOffset + this.sliderSize > this.trackSize) {
this.sliderOffset = this.trackSize - this.sliderSize;
}
if(this.previousOffset != this.sliderOffset) {
this.previousOffset = this.sliderOffset;
this.scrollTo(this.getScrollValueBySliderOffset());
}
},
onBtnIncPressed: function() {
jcf.lib.event.add(document.body, jcf.eventRelease, this.onBtnIncRelease, this);
jcf.lib.disableTextSelection(this.btnInc);
this.startButtonMoveScroll(1);
return false;
},
onBtnIncRelease: function() {
jcf.lib.event.remove(document.body, jcf.eventRelease, this.onBtnIncRelease);
this.endButtonMoveScroll();
},
onBtnDecPressed: function() {
jcf.lib.event.add(document.body, jcf.eventRelease, this.onBtnDecRelease, this);
jcf.lib.disableTextSelection(this.btnDec);
this.startButtonMoveScroll(-1);
return false;
},
onBtnDecRelease: function() {
jcf.lib.event.remove(document.body, jcf.eventRelease, this.onBtnDecRelease);
this.endButtonMoveScroll();
},
onTrackPressed: function(e) {
var position = e[this.eventPageOffsetProperty] - jcf.lib.getOffset(this.track)[this.positionProperty];
var direction = position < this.sliderOffset ? -1 : position > this.sliderOffset + this.sliderSize ? 1 : 0;
if(direction) {
this.scrollOnePage(direction);
}
}
});
// custom upload field module
jcf.addModule({
name: 'file',
selector: 'input[type="file"]',
defaultOptions: {
buttonWidth: 30,
bigFontSize: 1,
buttonText:'Select Subtitle File',
wrapperClass:'file-area',
focusClass:'file-focus',
disabledClass:'file-disabled',
opacityClass:'file-input-opacity',
noFileClass:'no-file',
extPrefixClass:'extension-',
uploadStructure:'<div class="jcf-input-wrapper"><div class="jcf-wrap"></div><label class="jcf-fake-input"><span><em></em></span></label><a class="jcf-upload-button"><span></span></a></div>',
uploadFileNameSelector:'label.jcf-fake-input span em',
uploadButtonSelector:'a.jcf-upload-button span',
inputWrapper: 'div.jcf-wrap'
},
setupWrapper: function(){
jcf.lib.addClass(this.fakeElement, this.options.wrapperClass);
this.fakeElement.innerHTML = this.options.uploadStructure;
this.realElement.parentNode.insertBefore(this.fakeElement, this.realElement);
this.fileNameInput = jcf.lib.queryBySelector(this.options.uploadFileNameSelector ,this.fakeElement)[0];
this.uploadButton = jcf.lib.queryBySelector(this.options.uploadButtonSelector ,this.fakeElement)[0];
this.inputWrapper = jcf.lib.queryBySelector(this.options.inputWrapper ,this.fakeElement)[0];
this.origElem = jcf.lib.nextSibling(this.realElement);
if(this.origElem && this.origElem.className.indexOf('file-input-text') > -1) {
this.origElem.parentNode.removeChild(this.origElem);
this.origTitle = this.origElem.innerHTML;
this.fileNameInput.innerHTML = this.origTitle;
}
this.uploadButton.innerHTML = this.realElement.title || this.options.buttonText;
this.realElement.removeAttribute('title');
this.fakeElement.style.position = 'relative';
this.realElement.style.position = 'absolute';
this.realElement.style.zIndex = 100;
this.inputWrapper.appendChild(this.realElement);
this.oTop = this.oLeft = this.oWidth = this.oHeight = 0;
jcf.lib.addClass(this.realElement, this.options.opacityClass);
jcf.lib.removeClass(this.realElement, jcf.baseOptions.hiddenClass);
this.inputWrapper.style.width = this.inputWrapper.parentNode.offsetWidth+'px';
this.shakeInput();
this.refreshState();
this.addEvents();
},
addEvents: function(){
jcf.lib.event.add(this.realElement, 'change', this.onChange, this);
if(!jcf.isTouchDevice) {
jcf.lib.event.add(this.fakeElement, 'mousemove', this.onMouseMove, this);
jcf.lib.event.add(this.fakeElement, 'mouseover', this.recalcDimensions, this);
}
},
onMouseMove: function(e){
this.realElement.style.top = Math.round(e.pageY - this.oTop - this.oHeight/2) + 'px';
this.realElement.style.left = (e.pageX - this.oLeft - this.oWidth + this.options.buttonWidth) + 'px';
},
onChange: function(){
this.refreshState();
},
getFileName: function(){
return this.realElement.value.replace(/^[\s\S]*(?:\\|\/)([\s\S^\\\/]*)$/g, "$1");
},
getFileExtension: function(){
return this.realElement.value.lastIndexOf('.') < 0 ? false : this.realElement.value.substring(this.realElement.value.lastIndexOf('.')+1).toLowerCase();
},
updateExtensionClass: function(){
var currentExtension = this.getFileExtension();
if(currentExtension) {
this.fakeElement.className = this.fakeElement.className.replace(new RegExp('(\\s|^)'+this.options.extPrefixClass+'[^ ]+','gi'),'')
jcf.lib.addClass(this.fakeElement, this.options.extPrefixClass+currentExtension)
}
},
shakeInput: function() {
// make input bigger
jcf.lib.setStyles(this.realElement, {
fontSize: this.options.bigFontSize,
lineHeight: this.options.bigFontSize,
heigth: 'auto',
top: 0,
left: this.inputWrapper.offsetWidth - this.realElement.offsetWidth
});
// IE styling fix
if((/(MSIE)/gi).test(navigator.userAgent)) {
this.tmpElement = document.createElement('span');
this.inputWrapper.insertBefore(this.tmpElement,this.realElement);
this.inputWrapper.insertBefore(this.realElement,this.tmpElement);
this.inputWrapper.removeChild(this.tmpElement);
}
},
recalcDimensions: function() {
var o = jcf.lib.getOffset(this.fakeElement);
this.oTop = o.top;
this.oLeft = o.left;
this.oWidth = this.realElement.offsetWidth;
this.oHeight = this.realElement.offsetHeight;
},
refreshState: function(){
jcf.lib.setStyles(this.realElement, {opacity: 0});
this.fileNameInput.innerHTML = this.getFileName() || this.origTitle || '';
if(this.realElement.disabled) {
jcf.lib.addClass(this.fakeElement, this.options.disabledClass);
if(this.labelFor) {
jcf.lib.addClass(this.labelFor, this.options.labelDisabledClass);
}
} else {
jcf.lib.removeClass(this.fakeElement, this.options.disabledClass);
if(this.labelFor) {
jcf.lib.removeClass(this.labelFor, this.options.labelDisabledClass);
}
}
if(this.realElement.value.length) {
jcf.lib.removeClass(this.fakeElement, this.options.noFileClass);
} else {
jcf.lib.addClass(this.fakeElement, this.options.noFileClass);
}
this.updateExtensionClass();
}
});
// custom textarea module
jcf.addModule({
name:'textarea',
selector: 'textarea',
defaultOptions: {
wrapperClass:'textarea-wrapper',
focusClass:'textarea-wrapper-focus',
cropMaskClass: 'scroll-cropper',
txtStructure:'<div class="control-wrapper"><div class="ctop"><div class="cleft"></div><div class="cright"></div></div><div class="cmid"><div class="chold"></div></div><div class="cbot"><div class="cleft"></div><div class="cright"></div></div></div>',
txtHolder: 'div.chold',
refreshInterval: 100
},
setupWrapper: function(){
jcf.lib.removeClass(this.realElement, jcf.baseOptions.hiddenClass);
jcf.lib.addClass(this.fakeElement, this.options.wrapperClass);
// create structure
this.realElement.parentNode.insertBefore(this.fakeElement, this.realElement);
this.fakeElement.innerHTML = this.options.txtStructure;
this.textareaHolder = jcf.lib.queryBySelector(this.options.txtHolder, this.fakeElement)[0];
this.textareaHolder.appendChild(this.realElement);
jcf.lib.enableTextSelection(this.fakeElement);
// init object and events
this.prepareElement();
this.refreshState();
this.addEvents();
this.addCustomScroll();
},
prepareElement: function() {
jcf.lib.setStyles(this.realElement, {
resize:'none',
overflow:'hidden',
verticalAlign:'top',
width: jcf.lib.getInnerWidth(this.realElement),
height: jcf.lib.getInnerHeight(this.realElement)
});
jcf.lib.setStyles(this.textareaHolder, {
width:this.realElement.offsetWidth
});
},
addCustomScroll: function() {
// call ready state, so scrollbars can attach here
this.onControlReady(this);
var origWidth = jcf.lib.getInnerWidth(this.realElement);
var barWidth = jcf.lib.scrollSize.getWidth();
// change text area size by scrollbar width
jcf.lib.setStyles(this.realElement, {
width: origWidth + barWidth,
overflowX: 'hidden',
overflowY: 'scroll',
direction: 'ltr'
});
// create crop mask
this.scrollCropper = jcf.lib.createElement('div',{
'class': this.options.cropMaskClass,
style: {
width: origWidth,
overflow: 'hidden'
}
});
this.realElement.parentNode.insertBefore(this.scrollCropper, this.realElement);
this.scrollCropper.appendChild(this.realElement);
},
addEvents: function(){
this.delayedRefresh = jcf.lib.bind(this.delayedRefresh, this);
jcf.lib.event.add(this.realElement, 'keydown', this.delayedRefresh);
jcf.lib.event.add(this.realElement, 'keyup', this.delayedRefresh);
},
onFocus: function(e) {
jcf.modules[this.name].superclass.onFocus.apply(this, arguments);
clearInterval(this.refreshTimer);
this.delayedRefresh();
this.refreshTimer = setInterval(this.delayedRefresh, this.options.refreshInterval);
},
onBlur: function() {
jcf.modules[this.name].superclass.onBlur.apply(this, arguments);
clearInterval(this.refreshTimer);
},
delayedRefresh: function() {
clearTimeout(this.delayTimer);
this.delayTimer = setTimeout(jcf.lib.bind(this.refreshState, this),10);
},
refreshState: function() {
if(this.scrollCropper) {
this.scrollCropper.scrollTop = this.scrollCropper.scrollLeft = 0;
this.scrollCropper.parentNode.scrollTop = 0;
}
// custom scrollbars will call this method before refreshing themself
}
});
/*
* Simple star rating module
*/
function StarRating() {
this.options = {
activeClass:'active',
settedClass:'setted',
element:null,
items:null,
onselect:null
};
this.init.apply(this,arguments);
}
StarRating.prototype = {
init: function(opt){
this.setOptions(opt);
if(this.element) {
this.getElements();
this.addEvents();
}
},
setOptions: function(opt) {
for(var p in opt) {
if(opt.hasOwnProperty(p)) {
this.options[p] = opt[p];
}
}
if(this.options.element) {
this.element = this.options.element;
}
},
getElements: function() {
// get switch objects
if(this.options.items === null) {
this.items = this.element.children;
} else {
if(typeof this.options.items === 'string') {
this.items = this.element.getElementsByTagName(this.options.items);
} else if(typeof this.options.items === 'object') {
this.items = this.options.items;
}
}
// find default active index
for(var i = 0; i < this.items.length; i++) {
if(lib.hasClass(this.items[i],this.options.activeClass)) {
this.activeIndex = i;
}
if(lib.hasClass(this.items[i],this.options.settedClass)) {
this.settedIndex = i;
}
}
},
addEvents: function() {
for(var i = 0; i < this.items.length; i++) {
this.items[i].onmouseover = lib.bind(this.overHandler, this, i);
this.items[i].onmouseout = lib.bind(this.outHandler, this, i);
this.items[i].onclick = lib.bind(this.clickHandler, this, i);
}
},
overHandler: function(ind) {
this.hovering = true;
this.hoverIndex = ind;
this.refreshClasses();
},
outHandler: function(ind) {
this.hovering = false;
this.refreshClasses();
},
clickHandler: function(ind) {
this.hovering = false;
this.settedIndex = ind;
if(typeof this.options.onselect === 'function') {
this.options.onselect(ind);
}
this.refreshClasses();
return false;
},
refreshClasses: function() {
for(var i = 0; i < this.items.length; i++) {
lib.removeClass(this.items[i],this.options.activeClass);
lib.removeClass(this.items[i],this.options.settedClass);
}
if(this.hovering) {
lib.addClass(this.items[this.hoverIndex],this.options.activeClass);
} else {
if(typeof this.settedIndex === 'number') {
lib.addClass(this.items[this.settedIndex],this.options.settedClass);
} else {
if(typeof this.activeIndex === 'number') {
lib.addClass(this.items[this.activeIndex],this.options.activeClass);
}
}
}
}
};
/*
* Utility module
*/
lib = {
hasClass: function(el,cls) {
return el && el.className ? el.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)')) : false;
},
addClass: function(el,cls) {
if (el && !this.hasClass(el,cls)) el.className += " "+cls;
},
removeClass: function(el,cls) {
if (el && this.hasClass(el,cls)) {el.className=el.className.replace(new RegExp('(\\s|^)'+cls+'(\\s|$)'),' ');}
},
extend: function(obj) {
for(var i = 1; i < arguments.length; i++) {
for(var p in arguments[i]) {
if(arguments[i].hasOwnProperty(p)) {
obj[p] = arguments[i][p];
}
}
}
return obj;
},
each: function(obj, callback) {
var property, len;
if(typeof obj.length === 'number') {
for(property = 0, len = obj.length; property < len; property++) {
if(callback.call(obj[property], property, obj[property]) === false) {
break;
}
}
} else {
for(property in obj) {
if(obj.hasOwnProperty(property)) {
if(callback.call(obj[property], property, obj[property]) === false) {
break;
}
}
}
}
},
event: (function() {
var fixEvent = function(e) {
e = e || window.event;
if(e.isFixed) return e; else e.isFixed = true;
if(!e.target) e.target = e.srcElement;
e.preventDefault = e.preventDefault || function() {this.returnValue = false;};
e.stopPropagation = e.stopPropagation || function() {this.cancelBubble = true;};
return e;
};
return {
add: function(elem, event, handler) {
if(!elem.events) {
elem.events = {};
elem.handle = function(e) {
var ret, handlers = elem.events[e.type];
e = fixEvent(e);
for(var i = 0, len = handlers.length; i < len; i++) {
if(handlers[i]) {
ret = handlers[i].call(elem, e);
if(ret === false) {
e.preventDefault();
e.stopPropagation();
}
}
}
};
}
if(!elem.events[event]) {
elem.events[event] = [];
if(elem.addEventListener) elem.addEventListener(event, elem.handle, false);
else if(elem.attachEvent) elem.attachEvent('on'+event, elem.handle);
}
elem.events[event].push(handler);
},
remove: function(elem, event, handler) {
var handlers = elem.events[event];
for(var i = handlers.length - 1; i >= 0; i--) {
if(handlers[i] === handler) {
handlers.splice(i,1);
}
}
if(!handlers.length) {
delete elem.events[event];
if(elem.removeEventListener) elem.removeEventListener(event, elem.handle, false);
else if(elem.detachEvent) elem.detachEvent('on'+event, elem.handle);
}
}
};
}()),
queryElementsBySelector: function(selector, scope) {
scope = scope || document;
if(!selector) return [];
if(selector === '>*') return scope.children;
if(typeof document.querySelectorAll === 'function') {
return scope.querySelectorAll(selector);
}
var selectors = selector.split(',');
var resultList = [];
for(var s = 0; s < selectors.length; s++) {
var currentContext = [scope || document];
var tokens = selectors[s].replace(/^\s+/,'').replace(/\s+$/,'').split(' ');
for (var i = 0; i < tokens.length; i++) {
token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');
if (token.indexOf('#') > -1) {
var bits = token.split('#'), tagName = bits[0], id = bits[1];
var element = document.getElementById(id);
if (element && tagName && element.nodeName.toLowerCase() != tagName) {
return [];
}
currentContext = element ? [element] : [];
continue;
}
if (token.indexOf('.') > -1) {
var bits = token.split('.'), tagName = bits[0] || '*', className = bits[1], found = [], foundCount = 0;
for (var h = 0; h < currentContext.length; h++) {
var elements;
if (tagName == '*') {
elements = currentContext[h].getElementsByTagName('*');
} else {
elements = currentContext[h].getElementsByTagName(tagName);
}
for (var j = 0; j < elements.length; j++) {
found[foundCount++] = elements[j];
}
}
currentContext = [];
var currentContextIndex = 0;
for (var k = 0; k < found.length; k++) {
if (found[k].className && found[k].className.match(new RegExp('(\\s|^)'+className+'(\\s|$)'))) {
currentContext[currentContextIndex++] = found[k];
}
}
continue;
}
if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
var tagName = RegExp.$1 || '*', attrName = RegExp.$2, attrOperator = RegExp.$3, attrValue = RegExp.$4;
if(attrName.toLowerCase() == 'for' && this.browser.msie && this.browser.version < 8) {
attrName = 'htmlFor';
}
var found = [], foundCount = 0;
for (var h = 0; h < currentContext.length; h++) {
var elements;
if (tagName == '*') {
elements = currentContext[h].getElementsByTagName('*');
} else {
elements = currentContext[h].getElementsByTagName(tagName);
}
for (var j = 0; elements[j]; j++) {
found[foundCount++] = elements[j];
}
}
currentContext = [];
var currentContextIndex = 0, checkFunction;
switch (attrOperator) {
case '=': checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue) }; break;
case '~': checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('(\\s|^)'+attrValue+'(\\s|$)'))) }; break;
case '|': checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))) }; break;
case '^': checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0) }; break;
case '$': checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length) }; break;
case '*': checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1) }; break;
default : checkFunction = function(e) { return e.getAttribute(attrName) };
}
currentContext = [];
var currentContextIndex = 0;
for (var k = 0; k < found.length; k++) {
if (checkFunction(found[k])) {
currentContext[currentContextIndex++] = found[k];
}
}
continue;
}
tagName = token;
var found = [], foundCount = 0;
for (var h = 0; h < currentContext.length; h++) {
var elements = currentContext[h].getElementsByTagName(tagName);
for (var j = 0; j < elements.length; j++) {
found[foundCount++] = elements[j];
}
}
currentContext = found;
}
resultList = [].concat(resultList,currentContext);
}
return resultList;
},
trim: function (str) {
return str.replace(/^\s+/, '').replace(/\s+$/, '');
},
bind: function(f, scope, forceArgs){
return function() {return f.apply(scope, typeof forceArgs !== 'undefined' ? [forceArgs] : arguments);};
}
};
/*! Hammer.JS - v2.0.4 - 2014-09-28
* http://hammerjs.github.io/
*
* Copyright (c) 2014 Jorik Tangelder;
* Licensed under the MIT license */
if(Object.create){!function(a,b,c,d){"use strict";function e(a,b,c){return setTimeout(k(a,c),b)}function f(a,b,c){return Array.isArray(a)?(g(a,c[b],c),!0):!1}function g(a,b,c){var e;if(a)if(a.forEach)a.forEach(b,c);else if(a.length!==d)for(e=0;e<a.length;)b.call(c,a[e],e,a),e++;else for(e in a)a.hasOwnProperty(e)&&b.call(c,a[e],e,a)}function h(a,b,c){for(var e=Object.keys(b),f=0;f<e.length;)(!c||c&&a[e[f]]===d)&&(a[e[f]]=b[e[f]]),f++;return a}function i(a,b){return h(a,b,!0)}function j(a,b,c){var d,e=b.prototype;d=a.prototype=Object.create(e),d.constructor=a,d._super=e,c&&h(d,c)}function k(a,b){return function(){return a.apply(b,arguments)}}function l(a,b){return typeof a==kb?a.apply(b?b[0]||d:d,b):a}function m(a,b){return a===d?b:a}function n(a,b,c){g(r(b),function(b){a.addEventListener(b,c,!1)})}function o(a,b,c){g(r(b),function(b){a.removeEventListener(b,c,!1)})}function p(a,b){for(;a;){if(a==b)return!0;a=a.parentNode}return!1}function q(a,b){return a.indexOf(b)>-1}function r(a){return a.trim().split(/\s+/g)}function s(a,b,c){if(a.indexOf&&!c)return a.indexOf(b);for(var d=0;d<a.length;){if(c&&a[d][c]==b||!c&&a[d]===b)return d;d++}return-1}function t(a){return Array.prototype.slice.call(a,0)}function u(a,b,c){for(var d=[],e=[],f=0;f<a.length;){var g=b?a[f][b]:a[f];s(e,g)<0&&d.push(a[f]),e[f]=g,f++}return c&&(d=b?d.sort(function(a,c){return a[b]>c[b]}):d.sort()),d}function v(a,b){for(var c,e,f=b[0].toUpperCase()+b.slice(1),g=0;g<ib.length;){if(c=ib[g],e=c?c+f:b,e in a)return e;g++}return d}function w(){return ob++}function x(a){var b=a.ownerDocument;return b.defaultView||b.parentWindow}function y(a,b){var c=this;this.manager=a,this.callback=b,this.element=a.element,this.target=a.options.inputTarget,this.domHandler=function(b){l(a.options.enable,[a])&&c.handler(b)},this.init()}function z(a){var b,c=a.options.inputClass;return new(b=c?c:rb?N:sb?Q:qb?S:M)(a,A)}function A(a,b,c){var d=c.pointers.length,e=c.changedPointers.length,f=b&yb&&d-e===0,g=b&(Ab|Bb)&&d-e===0;c.isFirst=!!f,c.isFinal=!!g,f&&(a.session={}),c.eventType=b,B(a,c),a.emit("hammer.input",c),a.recognize(c),a.session.prevInput=c}function B(a,b){var c=a.session,d=b.pointers,e=d.length;c.firstInput||(c.firstInput=E(b)),e>1&&!c.firstMultiple?c.firstMultiple=E(b):1===e&&(c.firstMultiple=!1);var f=c.firstInput,g=c.firstMultiple,h=g?g.center:f.center,i=b.center=F(d);b.timeStamp=nb(),b.deltaTime=b.timeStamp-f.timeStamp,b.angle=J(h,i),b.distance=I(h,i),C(c,b),b.offsetDirection=H(b.deltaX,b.deltaY),b.scale=g?L(g.pointers,d):1,b.rotation=g?K(g.pointers,d):0,D(c,b);var j=a.element;p(b.srcEvent.target,j)&&(j=b.srcEvent.target),b.target=j}function C(a,b){var c=b.center,d=a.offsetDelta||{},e=a.prevDelta||{},f=a.prevInput||{};(b.eventType===yb||f.eventType===Ab)&&(e=a.prevDelta={x:f.deltaX||0,y:f.deltaY||0},d=a.offsetDelta={x:c.x,y:c.y}),b.deltaX=e.x+(c.x-d.x),b.deltaY=e.y+(c.y-d.y)}function D(a,b){var c,e,f,g,h=a.lastInterval||b,i=b.timeStamp-h.timeStamp;if(b.eventType!=Bb&&(i>xb||h.velocity===d)){var j=h.deltaX-b.deltaX,k=h.deltaY-b.deltaY,l=G(i,j,k);e=l.x,f=l.y,c=mb(l.x)>mb(l.y)?l.x:l.y,g=H(j,k),a.lastInterval=b}else c=h.velocity,e=h.velocityX,f=h.velocityY,g=h.direction;b.velocity=c,b.velocityX=e,b.velocityY=f,b.direction=g}function E(a){for(var b=[],c=0;c<a.pointers.length;)b[c]={clientX:lb(a.pointers[c].clientX),clientY:lb(a.pointers[c].clientY)},c++;return{timeStamp:nb(),pointers:b,center:F(b),deltaX:a.deltaX,deltaY:a.deltaY}}function F(a){var b=a.length;if(1===b)return{x:lb(a[0].clientX),y:lb(a[0].clientY)};for(var c=0,d=0,e=0;b>e;)c+=a[e].clientX,d+=a[e].clientY,e++;return{x:lb(c/b),y:lb(d/b)}}function G(a,b,c){return{x:b/a||0,y:c/a||0}}function H(a,b){return a===b?Cb:mb(a)>=mb(b)?a>0?Db:Eb:b>0?Fb:Gb}function I(a,b,c){c||(c=Kb);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return Math.sqrt(d*d+e*e)}function J(a,b,c){c||(c=Kb);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return 180*Math.atan2(e,d)/Math.PI}function K(a,b){return J(b[1],b[0],Lb)-J(a[1],a[0],Lb)}function L(a,b){return I(b[0],b[1],Lb)/I(a[0],a[1],Lb)}function M(){this.evEl=Nb,this.evWin=Ob,this.allow=!0,this.pressed=!1,y.apply(this,arguments)}function N(){this.evEl=Rb,this.evWin=Sb,y.apply(this,arguments),this.store=this.manager.session.pointerEvents=[]}function O(){this.evTarget=Ub,this.evWin=Vb,this.started=!1,y.apply(this,arguments)}function P(a,b){var c=t(a.touches),d=t(a.changedTouches);return b&(Ab|Bb)&&(c=u(c.concat(d),"identifier",!0)),[c,d]}function Q(){this.evTarget=Xb,this.targetIds={},y.apply(this,arguments)}function R(a,b){var c=t(a.touches),d=this.targetIds;if(b&(yb|zb)&&1===c.length)return d[c[0].identifier]=!0,[c,c];var e,f,g=t(a.changedTouches),h=[],i=this.target;if(f=c.filter(function(a){return p(a.target,i)}),b===yb)for(e=0;e<f.length;)d[f[e].identifier]=!0,e++;for(e=0;e<g.length;)d[g[e].identifier]&&h.push(g[e]),b&(Ab|Bb)&&delete d[g[e].identifier],e++;return h.length?[u(f.concat(h),"identifier",!0),h]:void 0}function S(){y.apply(this,arguments);var a=k(this.handler,this);this.touch=new Q(this.manager,a),this.mouse=new M(this.manager,a)}function T(a,b){this.manager=a,this.set(b)}function U(a){if(q(a,bc))return bc;var b=q(a,cc),c=q(a,dc);return b&&c?cc+" "+dc:b||c?b?cc:dc:q(a,ac)?ac:_b}function V(a){this.id=w(),this.manager=null,this.options=i(a||{},this.defaults),this.options.enable=m(this.options.enable,!0),this.state=ec,this.simultaneous={},this.requireFail=[]}function W(a){return a&jc?"cancel":a&hc?"end":a&gc?"move":a&fc?"start":""}function X(a){return a==Gb?"down":a==Fb?"up":a==Db?"left":a==Eb?"right":""}function Y(a,b){var c=b.manager;return c?c.get(a):a}function Z(){V.apply(this,arguments)}function $(){Z.apply(this,arguments),this.pX=null,this.pY=null}function _(){Z.apply(this,arguments)}function ab(){V.apply(this,arguments),this._timer=null,this._input=null}function bb(){Z.apply(this,arguments)}function cb(){Z.apply(this,arguments)}function db(){V.apply(this,arguments),this.pTime=!1,this.pCenter=!1,this._timer=null,this._input=null,this.count=0}function eb(a,b){return b=b||{},b.recognizers=m(b.recognizers,eb.defaults.preset),new fb(a,b)}function fb(a,b){b=b||{},this.options=i(b,eb.defaults),this.options.inputTarget=this.options.inputTarget||a,this.handlers={},this.session={},this.recognizers=[],this.element=a,this.input=z(this),this.touchAction=new T(this,this.options.touchAction),gb(this,!0),g(b.recognizers,function(a){var b=this.add(new a[0](a[1]));a[2]&&b.recognizeWith(a[2]),a[3]&&b.requireFailure(a[3])},this)}function gb(a,b){var c=a.element;g(a.options.cssProps,function(a,d){c.style[v(c.style,d)]=b?a:""})}function hb(a,c){var d=b.createEvent("Event");d.initEvent(a,!0,!0),d.gesture=c,c.target.dispatchEvent(d)}var ib=["","webkit","moz","MS","ms","o"],jb=b.createElement("div"),kb="function",lb=Math.round,mb=Math.abs,nb=Date.now,ob=1,pb=/mobile|tablet|ip(ad|hone|od)|android/i,qb="ontouchstart"in a,rb=v(a,"PointerEvent")!==d,sb=qb&&pb.test(navigator.userAgent),tb="touch",ub="pen",vb="mouse",wb="kinect",xb=25,yb=1,zb=2,Ab=4,Bb=8,Cb=1,Db=2,Eb=4,Fb=8,Gb=16,Hb=Db|Eb,Ib=Fb|Gb,Jb=Hb|Ib,Kb=["x","y"],Lb=["clientX","clientY"];y.prototype={handler:function(){},init:function(){this.evEl&&n(this.element,this.evEl,this.domHandler),this.evTarget&&n(this.target,this.evTarget,this.domHandler),this.evWin&&n(x(this.element),this.evWin,this.domHandler)},destroy:function(){this.evEl&&o(this.element,this.evEl,this.domHandler),this.evTarget&&o(this.target,this.evTarget,this.domHandler),this.evWin&&o(x(this.element),this.evWin,this.domHandler)}};var Mb={mousedown:yb,mousemove:zb,mouseup:Ab},Nb="mousedown",Ob="mousemove mouseup";j(M,y,{handler:function(a){var b=Mb[a.type];b&yb&&0===a.button&&(this.pressed=!0),b&zb&&1!==a.which&&(b=Ab),this.pressed&&this.allow&&(b&Ab&&(this.pressed=!1),this.callback(this.manager,b,{pointers:[a],changedPointers:[a],pointerType:vb,srcEvent:a}))}});var Pb={pointerdown:yb,pointermove:zb,pointerup:Ab,pointercancel:Bb,pointerout:Bb},Qb={2:tb,3:ub,4:vb,5:wb},Rb="pointerdown",Sb="pointermove pointerup pointercancel";a.MSPointerEvent&&(Rb="MSPointerDown",Sb="MSPointerMove MSPointerUp MSPointerCancel"),j(N,y,{handler:function(a){var b=this.store,c=!1,d=a.type.toLowerCase().replace("ms",""),e=Pb[d],f=Qb[a.pointerType]||a.pointerType,g=f==tb,h=s(b,a.pointerId,"pointerId");e&yb&&(0===a.button||g)?0>h&&(b.push(a),h=b.length-1):e&(Ab|Bb)&&(c=!0),0>h||(b[h]=a,this.callback(this.manager,e,{pointers:b,changedPointers:[a],pointerType:f,srcEvent:a}),c&&b.splice(h,1))}});var Tb={touchstart:yb,touchmove:zb,touchend:Ab,touchcancel:Bb},Ub="touchstart",Vb="touchstart touchmove touchend touchcancel";j(O,y,{handler:function(a){var b=Tb[a.type];if(b===yb&&(this.started=!0),this.started){var c=P.call(this,a,b);b&(Ab|Bb)&&c[0].length-c[1].length===0&&(this.started=!1),this.callback(this.manager,b,{pointers:c[0],changedPointers:c[1],pointerType:tb,srcEvent:a})}}});var Wb={touchstart:yb,touchmove:zb,touchend:Ab,touchcancel:Bb},Xb="touchstart touchmove touchend touchcancel";j(Q,y,{handler:function(a){var b=Wb[a.type],c=R.call(this,a,b);c&&this.callback(this.manager,b,{pointers:c[0],changedPointers:c[1],pointerType:tb,srcEvent:a})}}),j(S,y,{handler:function(a,b,c){var d=c.pointerType==tb,e=c.pointerType==vb;if(d)this.mouse.allow=!1;else if(e&&!this.mouse.allow)return;b&(Ab|Bb)&&(this.mouse.allow=!0),this.callback(a,b,c)},destroy:function(){this.touch.destroy(),this.mouse.destroy()}});var Yb=v(jb.style,"touchAction"),Zb=Yb!==d,$b="compute",_b="auto",ac="manipulation",bc="none",cc="pan-x",dc="pan-y";T.prototype={set:function(a){a==$b&&(a=this.compute()),Zb&&(this.manager.element.style[Yb]=a),this.actions=a.toLowerCase().trim()},update:function(){this.set(this.manager.options.touchAction)},compute:function(){var a=[];return g(this.manager.recognizers,function(b){l(b.options.enable,[b])&&(a=a.concat(b.getTouchAction()))}),U(a.join(" "))},preventDefaults:function(a){if(!Zb){var b=a.srcEvent,c=a.offsetDirection;if(this.manager.session.prevented)return void b.preventDefault();var d=this.actions,e=q(d,bc),f=q(d,dc),g=q(d,cc);return e||f&&c&Hb||g&&c&Ib?this.preventSrc(b):void 0}},preventSrc:function(a){this.manager.session.prevented=!0,a.preventDefault()}};var ec=1,fc=2,gc=4,hc=8,ic=hc,jc=16,kc=32;V.prototype={defaults:{},set:function(a){return h(this.options,a),this.manager&&this.manager.touchAction.update(),this},recognizeWith:function(a){if(f(a,"recognizeWith",this))return this;var b=this.simultaneous;return a=Y(a,this),b[a.id]||(b[a.id]=a,a.recognizeWith(this)),this},dropRecognizeWith:function(a){return f(a,"dropRecognizeWith",this)?this:(a=Y(a,this),delete this.simultaneous[a.id],this)},requireFailure:function(a){if(f(a,"requireFailure",this))return this;var b=this.requireFail;return a=Y(a,this),-1===s(b,a)&&(b.push(a),a.requireFailure(this)),this},dropRequireFailure:function(a){if(f(a,"dropRequireFailure",this))return this;a=Y(a,this);var b=s(this.requireFail,a);return b>-1&&this.requireFail.splice(b,1),this},hasRequireFailures:function(){return this.requireFail.length>0},canRecognizeWith:function(a){return!!this.simultaneous[a.id]},emit:function(a){function b(b){c.manager.emit(c.options.event+(b?W(d):""),a)}var c=this,d=this.state;hc>d&&b(!0),b(),d>=hc&&b(!0)},tryEmit:function(a){return this.canEmit()?this.emit(a):void(this.state=kc)},canEmit:function(){for(var a=0;a<this.requireFail.length;){if(!(this.requireFail[a].state&(kc|ec)))return!1;a++}return!0},recognize:function(a){var b=h({},a);return l(this.options.enable,[this,b])?(this.state&(ic|jc|kc)&&(this.state=ec),this.state=this.process(b),void(this.state&(fc|gc|hc|jc)&&this.tryEmit(b))):(this.reset(),void(this.state=kc))},process:function(){},getTouchAction:function(){},reset:function(){}},j(Z,V,{defaults:{pointers:1},attrTest:function(a){var b=this.options.pointers;return 0===b||a.pointers.length===b},process:function(a){var b=this.state,c=a.eventType,d=b&(fc|gc),e=this.attrTest(a);return d&&(c&Bb||!e)?b|jc:d||e?c&Ab?b|hc:b&fc?b|gc:fc:kc}}),j($,Z,{defaults:{event:"pan",threshold:10,pointers:1,direction:Jb},getTouchAction:function(){var a=this.options.direction,b=[];return a&Hb&&b.push(dc),a&Ib&&b.push(cc),b},directionTest:function(a){var b=this.options,c=!0,d=a.distance,e=a.direction,f=a.deltaX,g=a.deltaY;return e&b.direction||(b.direction&Hb?(e=0===f?Cb:0>f?Db:Eb,c=f!=this.pX,d=Math.abs(a.deltaX)):(e=0===g?Cb:0>g?Fb:Gb,c=g!=this.pY,d=Math.abs(a.deltaY))),a.direction=e,c&&d>b.threshold&&e&b.direction},attrTest:function(a){return Z.prototype.attrTest.call(this,a)&&(this.state&fc||!(this.state&fc)&&this.directionTest(a))},emit:function(a){this.pX=a.deltaX,this.pY=a.deltaY;var b=X(a.direction);b&&this.manager.emit(this.options.event+b,a),this._super.emit.call(this,a)}}),j(_,Z,{defaults:{event:"pinch",threshold:0,pointers:2},getTouchAction:function(){return[bc]},attrTest:function(a){return this._super.attrTest.call(this,a)&&(Math.abs(a.scale-1)>this.options.threshold||this.state&fc)},emit:function(a){if(this._super.emit.call(this,a),1!==a.scale){var b=a.scale<1?"in":"out";this.manager.emit(this.options.event+b,a)}}}),j(ab,V,{defaults:{event:"press",pointers:1,time:500,threshold:5},getTouchAction:function(){return[_b]},process:function(a){var b=this.options,c=a.pointers.length===b.pointers,d=a.distance<b.threshold,f=a.deltaTime>b.time;if(this._input=a,!d||!c||a.eventType&(Ab|Bb)&&!f)this.reset();else if(a.eventType&yb)this.reset(),this._timer=e(function(){this.state=ic,this.tryEmit()},b.time,this);else if(a.eventType&Ab)return ic;return kc},reset:function(){clearTimeout(this._timer)},emit:function(a){this.state===ic&&(a&&a.eventType&Ab?this.manager.emit(this.options.event+"up",a):(this._input.timeStamp=nb(),this.manager.emit(this.options.event,this._input)))}}),j(bb,Z,{defaults:{event:"rotate",threshold:0,pointers:2},getTouchAction:function(){return[bc]},attrTest:function(a){return this._super.attrTest.call(this,a)&&(Math.abs(a.rotation)>this.options.threshold||this.state&fc)}}),j(cb,Z,{defaults:{event:"swipe",threshold:10,velocity:.65,direction:Hb|Ib,pointers:1},getTouchAction:function(){return $.prototype.getTouchAction.call(this)},attrTest:function(a){var b,c=this.options.direction;return c&(Hb|Ib)?b=a.velocity:c&Hb?b=a.velocityX:c&Ib&&(b=a.velocityY),this._super.attrTest.call(this,a)&&c&a.direction&&a.distance>this.options.threshold&&mb(b)>this.options.velocity&&a.eventType&Ab},emit:function(a){var b=X(a.direction);b&&this.manager.emit(this.options.event+b,a),this.manager.emit(this.options.event,a)}}),j(db,V,{defaults:{event:"tap",pointers:1,taps:1,interval:300,time:250,threshold:2,posThreshold:10},getTouchAction:function(){return[ac]},process:function(a){var b=this.options,c=a.pointers.length===b.pointers,d=a.distance<b.threshold,f=a.deltaTime<b.time;if(this.reset(),a.eventType&yb&&0===this.count)return this.failTimeout();if(d&&f&&c){if(a.eventType!=Ab)return this.failTimeout();var g=this.pTime?a.timeStamp-this.pTime<b.interval:!0,h=!this.pCenter||I(this.pCenter,a.center)<b.posThreshold;this.pTime=a.timeStamp,this.pCenter=a.center,h&&g?this.count+=1:this.count=1,this._input=a;var i=this.count%b.taps;if(0===i)return this.hasRequireFailures()?(this._timer=e(function(){this.state=ic,this.tryEmit()},b.interval,this),fc):ic}return kc},failTimeout:function(){return this._timer=e(function(){this.state=kc},this.options.interval,this),kc},reset:function(){clearTimeout(this._timer)},emit:function(){this.state==ic&&(this._input.tapCount=this.count,this.manager.emit(this.options.event,this._input))}}),eb.VERSION="2.0.4",eb.defaults={domEvents:!1,touchAction:$b,enable:!0,inputTarget:null,inputClass:null,preset:[[bb,{enable:!1}],[_,{enable:!1},["rotate"]],[cb,{direction:Hb}],[$,{direction:Hb},["swipe"]],[db],[db,{event:"doubletap",taps:2},["tap"]],[ab]],cssProps:{userSelect:"none",touchSelect:"none",touchCallout:"none",contentZooming:"none",userDrag:"none",tapHighlightColor:"rgba(0,0,0,0)"}};var lc=1,mc=2;fb.prototype={set:function(a){return h(this.options,a),a.touchAction&&this.touchAction.update(),a.inputTarget&&(this.input.destroy(),this.input.target=a.inputTarget,this.input.init()),this},stop:function(a){this.session.stopped=a?mc:lc},recognize:function(a){var b=this.session;if(!b.stopped){this.touchAction.preventDefaults(a);var c,d=this.recognizers,e=b.curRecognizer;(!e||e&&e.state&ic)&&(e=b.curRecognizer=null);for(var f=0;f<d.length;)c=d[f],b.stopped===mc||e&&c!=e&&!c.canRecognizeWith(e)?c.reset():c.recognize(a),!e&&c.state&(fc|gc|hc)&&(e=b.curRecognizer=c),f++}},get:function(a){if(a instanceof V)return a;for(var b=this.recognizers,c=0;c<b.length;c++)if(b[c].options.event==a)return b[c];return null},add:function(a){if(f(a,"add",this))return this;var b=this.get(a.options.event);return b&&this.remove(b),this.recognizers.push(a),a.manager=this,this.touchAction.update(),a},remove:function(a){if(f(a,"remove",this))return this;var b=this.recognizers;return a=this.get(a),b.splice(s(b,a),1),this.touchAction.update(),this},on:function(a,b){var c=this.handlers;return g(r(a),function(a){c[a]=c[a]||[],c[a].push(b)}),this},off:function(a,b){var c=this.handlers;return g(r(a),function(a){b?c[a].splice(s(c[a],b),1):delete c[a]}),this},emit:function(a,b){this.options.domEvents&&hb(a,b);var c=this.handlers[a]&&this.handlers[a].slice();if(c&&c.length){b.type=a,b.preventDefault=function(){b.srcEvent.preventDefault()};for(var d=0;d<c.length;)c[d](b),d++}},destroy:function(){this.element&&gb(this,!1),this.handlers={},this.session={},this.input.destroy(),this.element=null}},h(eb,{INPUT_START:yb,INPUT_MOVE:zb,INPUT_END:Ab,INPUT_CANCEL:Bb,STATE_POSSIBLE:ec,STATE_BEGAN:fc,STATE_CHANGED:gc,STATE_ENDED:hc,STATE_RECOGNIZED:ic,STATE_CANCELLED:jc,STATE_FAILED:kc,DIRECTION_NONE:Cb,DIRECTION_LEFT:Db,DIRECTION_RIGHT:Eb,DIRECTION_UP:Fb,DIRECTION_DOWN:Gb,DIRECTION_HORIZONTAL:Hb,DIRECTION_VERTICAL:Ib,DIRECTION_ALL:Jb,Manager:fb,Input:y,TouchAction:T,TouchInput:Q,MouseInput:M,PointerEventInput:N,TouchMouseInput:S,SingleTouchInput:O,Recognizer:V,AttrRecognizer:Z,Tap:db,Pan:$,Swipe:cb,Pinch:_,Rotate:bb,Press:ab,on:n,off:o,each:g,merge:i,extend:h,inherit:j,bindFn:k,prefixed:v}),typeof define==kb&&define.amd?define(function(){return eb}):"undefined"!=typeof module&&module.exports?module.exports=eb:a[c]=eb}(window,document,"Hammer");}