3593 lines
No EOL
137 KiB
JavaScript
3593 lines
No EOL
137 KiB
JavaScript
// 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 doesn’t 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");} |