git commit "feat: create blade layout structure"
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* jquery-blur-area - v1.0.0
|
||||
*
|
||||
* made by @remtsoy
|
||||
*/
|
||||
;( function( $, window, document, undefined ) {
|
||||
|
||||
"use strict";
|
||||
var pluginName = "blurArea",
|
||||
defaults = {
|
||||
sampleAttr: "bg-area",
|
||||
areaAttr: 'blur-area'
|
||||
},
|
||||
_blur = 20,
|
||||
_offsetTop,
|
||||
_offsetBottom,
|
||||
_offsetLeft,
|
||||
_offsetRight,
|
||||
_sampleBg,
|
||||
_blurArea;
|
||||
|
||||
// The actual plugin constructor
|
||||
function Plugin ( element, options ) {
|
||||
this.element = element;
|
||||
this.settings = $.extend( {}, defaults, options );
|
||||
this.$el = $(this.element);
|
||||
this._defaults = defaults;
|
||||
this._name = pluginName;
|
||||
this.init();
|
||||
}
|
||||
|
||||
|
||||
$.extend( Plugin.prototype, {
|
||||
init: function() {
|
||||
_sampleBg = this.$el.data(this.settings.sampleAttr);
|
||||
_blurArea = this.$el.data(this.settings.areaAttr);
|
||||
|
||||
if(this.$el.data('blur')) {
|
||||
_blur = this.$el.data('blur');
|
||||
}
|
||||
|
||||
var parentBg = $(_sampleBg).css('background-image');
|
||||
|
||||
_offsetTop = $(_blurArea).offset().top - $(_sampleBg).offset().top;
|
||||
_offsetBottom = $(_sampleBg).height() - _offsetTop - $(_blurArea).height();
|
||||
_offsetLeft = $(_blurArea).offset().left - $(_sampleBg).offset().left;
|
||||
_offsetRight = $(_sampleBg).width() - _offsetLeft - $(_blurArea).width();
|
||||
|
||||
|
||||
this.$el.css({
|
||||
'-webkit-filter' : 'blur('+_blur+'px)',
|
||||
'background-image' : parentBg,
|
||||
'-webkit-clip-path' : 'inset(' + _offsetTop + 'px ' + _offsetRight + 'px ' + _offsetBottom + 'px ' + _offsetLeft + 'px)'
|
||||
});
|
||||
}
|
||||
} );
|
||||
|
||||
|
||||
$.fn[ pluginName ] = function( options ) {
|
||||
return this.each( function() {
|
||||
if ( !$.data( this, "plugin_" + pluginName ) ) {
|
||||
$.data( this, "plugin_" +
|
||||
pluginName, new Plugin( this, options ) );
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
} )( jQuery, window, document );
|
||||
Vendored
+2378
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,248 @@
|
||||
/*!
|
||||
* The Final Countdown for jQuery v2.2.0 (http://hilios.github.io/jQuery.countdown/)
|
||||
* Copyright (c) 2016 Edson Hilios
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
(function(factory) {
|
||||
"use strict";
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define([ "jquery" ], factory);
|
||||
} else {
|
||||
factory(jQuery);
|
||||
}
|
||||
})(function($) {
|
||||
"use strict";
|
||||
var instances = [], matchers = [], defaultOptions = {
|
||||
precision: 100,
|
||||
elapse: false,
|
||||
defer: false
|
||||
};
|
||||
matchers.push(/^[0-9]*$/.source);
|
||||
matchers.push(/([0-9]{1,2}\/){2}[0-9]{4}( [0-9]{1,2}(:[0-9]{2}){2})?/.source);
|
||||
matchers.push(/[0-9]{4}([\/\-][0-9]{1,2}){2}( [0-9]{1,2}(:[0-9]{2}){2})?/.source);
|
||||
matchers = new RegExp(matchers.join("|"));
|
||||
function parseDateString(dateString) {
|
||||
if (dateString instanceof Date) {
|
||||
return dateString;
|
||||
}
|
||||
if (String(dateString).match(matchers)) {
|
||||
if (String(dateString).match(/^[0-9]*$/)) {
|
||||
dateString = Number(dateString);
|
||||
}
|
||||
if (String(dateString).match(/\-/)) {
|
||||
dateString = String(dateString).replace(/\-/g, "/");
|
||||
}
|
||||
return new Date(dateString);
|
||||
} else {
|
||||
throw new Error("Couldn't cast `" + dateString + "` to a date object.");
|
||||
}
|
||||
}
|
||||
var DIRECTIVE_KEY_MAP = {
|
||||
Y: "years",
|
||||
m: "months",
|
||||
n: "daysToMonth",
|
||||
d: "daysToWeek",
|
||||
w: "weeks",
|
||||
W: "weeksToMonth",
|
||||
H: "hours",
|
||||
M: "minutes",
|
||||
S: "seconds",
|
||||
D: "totalDays",
|
||||
I: "totalHours",
|
||||
N: "totalMinutes",
|
||||
T: "totalSeconds"
|
||||
};
|
||||
function escapedRegExp(str) {
|
||||
var sanitize = str.toString().replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
|
||||
return new RegExp(sanitize);
|
||||
}
|
||||
function strftime(offsetObject) {
|
||||
return function(format) {
|
||||
var directives = format.match(/%(-|!)?[A-Z]{1}(:[^;]+;)?/gi);
|
||||
if (directives) {
|
||||
for (var i = 0, len = directives.length; i < len; ++i) {
|
||||
var directive = directives[i].match(/%(-|!)?([a-zA-Z]{1})(:[^;]+;)?/), regexp = escapedRegExp(directive[0]), modifier = directive[1] || "", plural = directive[3] || "", value = null;
|
||||
directive = directive[2];
|
||||
if (DIRECTIVE_KEY_MAP.hasOwnProperty(directive)) {
|
||||
value = DIRECTIVE_KEY_MAP[directive];
|
||||
value = Number(offsetObject[value]);
|
||||
}
|
||||
if (value !== null) {
|
||||
if (modifier === "!") {
|
||||
value = pluralize(plural, value);
|
||||
}
|
||||
if (modifier === "") {
|
||||
if (value < 10) {
|
||||
value = "0" + value.toString();
|
||||
}
|
||||
}
|
||||
format = format.replace(regexp, value.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
format = format.replace(/%%/, "%");
|
||||
return format;
|
||||
};
|
||||
}
|
||||
function pluralize(format, count) {
|
||||
var plural = "s", singular = "";
|
||||
if (format) {
|
||||
format = format.replace(/(:|;|\s)/gi, "").split(/\,/);
|
||||
if (format.length === 1) {
|
||||
plural = format[0];
|
||||
} else {
|
||||
singular = format[0];
|
||||
plural = format[1];
|
||||
}
|
||||
}
|
||||
if (Math.abs(count) > 1) {
|
||||
return plural;
|
||||
} else {
|
||||
return singular;
|
||||
}
|
||||
}
|
||||
var Countdown = function(el, finalDate, options) {
|
||||
this.el = el;
|
||||
this.$el = $(el);
|
||||
this.interval = null;
|
||||
this.offset = {};
|
||||
this.options = $.extend({}, defaultOptions);
|
||||
this.firstTick = true;
|
||||
this.instanceNumber = instances.length;
|
||||
instances.push(this);
|
||||
this.$el.data("countdown-instance", this.instanceNumber);
|
||||
if (options) {
|
||||
if (typeof options === "function") {
|
||||
this.$el.on("update.countdown", options);
|
||||
this.$el.on("stoped.countdown", options);
|
||||
this.$el.on("finish.countdown", options);
|
||||
} else {
|
||||
this.options = $.extend({}, defaultOptions, options);
|
||||
}
|
||||
}
|
||||
this.setFinalDate(finalDate);
|
||||
if (this.options.defer === false) {
|
||||
this.start();
|
||||
}
|
||||
};
|
||||
$.extend(Countdown.prototype, {
|
||||
start: function() {
|
||||
if (this.interval !== null) {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
var self = this;
|
||||
this.update();
|
||||
this.interval = setInterval(function() {
|
||||
self.update.call(self);
|
||||
}, this.options.precision);
|
||||
},
|
||||
stop: function() {
|
||||
clearInterval(this.interval);
|
||||
this.interval = null;
|
||||
this.dispatchEvent("stoped");
|
||||
},
|
||||
toggle: function() {
|
||||
if (this.interval) {
|
||||
this.stop();
|
||||
} else {
|
||||
this.start();
|
||||
}
|
||||
},
|
||||
pause: function() {
|
||||
this.stop();
|
||||
},
|
||||
resume: function() {
|
||||
this.start();
|
||||
},
|
||||
remove: function() {
|
||||
this.stop.call(this);
|
||||
instances[this.instanceNumber] = null;
|
||||
delete this.$el.data().countdownInstance;
|
||||
},
|
||||
setFinalDate: function(value) {
|
||||
this.finalDate = parseDateString(value);
|
||||
},
|
||||
update: function() {
|
||||
if (this.$el.closest("html").length === 0) {
|
||||
this.remove();
|
||||
return;
|
||||
}
|
||||
var now = new Date(), newTotalSecsLeft;
|
||||
newTotalSecsLeft = this.finalDate.getTime() - now.getTime();
|
||||
newTotalSecsLeft = Math.ceil(newTotalSecsLeft / 1e3);
|
||||
newTotalSecsLeft = !this.options.elapse && newTotalSecsLeft < 0 ? 0 : Math.abs(newTotalSecsLeft);
|
||||
if (this.totalSecsLeft === newTotalSecsLeft || this.firstTick) {
|
||||
this.firstTick = false;
|
||||
return;
|
||||
} else {
|
||||
this.totalSecsLeft = newTotalSecsLeft;
|
||||
}
|
||||
this.elapsed = now >= this.finalDate;
|
||||
this.offset = {
|
||||
seconds: this.totalSecsLeft % 60,
|
||||
minutes: Math.floor(this.totalSecsLeft / 60) % 60,
|
||||
hours: Math.floor(this.totalSecsLeft / 60 / 60) % 24,
|
||||
days: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7,
|
||||
daysToWeek: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7,
|
||||
daysToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 % 30.4368),
|
||||
weeks: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7),
|
||||
weeksToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7) % 4,
|
||||
months: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 30.4368),
|
||||
years: Math.abs(this.finalDate.getFullYear() - now.getFullYear()),
|
||||
totalDays: Math.floor(this.totalSecsLeft / 60 / 60 / 24),
|
||||
totalHours: Math.floor(this.totalSecsLeft / 60 / 60),
|
||||
totalMinutes: Math.floor(this.totalSecsLeft / 60),
|
||||
totalSeconds: this.totalSecsLeft
|
||||
};
|
||||
if (!this.options.elapse && this.totalSecsLeft === 0) {
|
||||
this.stop();
|
||||
this.dispatchEvent("finish");
|
||||
} else {
|
||||
this.dispatchEvent("update");
|
||||
}
|
||||
},
|
||||
dispatchEvent: function(eventName) {
|
||||
var event = $.Event(eventName + ".countdown");
|
||||
event.finalDate = this.finalDate;
|
||||
event.elapsed = this.elapsed;
|
||||
event.offset = $.extend({}, this.offset);
|
||||
event.strftime = strftime(this.offset);
|
||||
this.$el.trigger(event);
|
||||
}
|
||||
});
|
||||
$.fn.countdown = function() {
|
||||
var argumentsArray = Array.prototype.slice.call(arguments, 0);
|
||||
return this.each(function() {
|
||||
var instanceNumber = $(this).data("countdown-instance");
|
||||
if (instanceNumber !== undefined) {
|
||||
var instance = instances[instanceNumber], method = argumentsArray[0];
|
||||
if (Countdown.prototype.hasOwnProperty(method)) {
|
||||
instance[method].apply(instance, argumentsArray.slice(1));
|
||||
} else if (String(method).match(/^[$A-Z_][0-9A-Z_$]*$/i) === null) {
|
||||
instance.setFinalDate.call(instance, method);
|
||||
instance.start();
|
||||
} else {
|
||||
$.error("Method %s does not exist on jQuery.countdown".replace(/\%s/gi, method));
|
||||
}
|
||||
} else {
|
||||
new Countdown(this, argumentsArray[0], argumentsArray[1]);
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,361 @@
|
||||
'use strict';
|
||||
|
||||
var mobileViewport = 992;
|
||||
var isSafari = navigator.userAgent.indexOf("Safari") > -1;
|
||||
var isChrome = navigator.userAgent.indexOf('Chrome') > -1;
|
||||
if((isSafari) && (isChrome)) {
|
||||
isSafari = false;
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
OwlCarousel();
|
||||
|
||||
$('.blur-area').blurArea();
|
||||
$('.ws-action').windowScrollAction();
|
||||
checkboxes();
|
||||
afternavHeight();
|
||||
activeBookmark();
|
||||
magnificLightbox();
|
||||
priceSlider();
|
||||
BSTabsActions();
|
||||
heroSearchSections();
|
||||
$('.quantity-selector').quantitySelector();
|
||||
autocomplete();
|
||||
searchResultsCollapse();
|
||||
comingSoonCountdown();
|
||||
smoothScroll();
|
||||
|
||||
if($(window).width() > mobileViewport) {
|
||||
YouTubeVideo();
|
||||
stickySidebars();
|
||||
}
|
||||
|
||||
if($(window).width() < mobileViewport) {
|
||||
mobileFilters();
|
||||
}
|
||||
});
|
||||
|
||||
googleMaps();
|
||||
|
||||
|
||||
function smoothScroll() {
|
||||
var scroll = new SmoothScroll('a[data-scroll]');
|
||||
}
|
||||
|
||||
|
||||
function YouTubeVideo() {
|
||||
var $video = $('#youtube-video');
|
||||
if($video.length) {
|
||||
|
||||
$video.YTPlayer({
|
||||
fitToBackground: true,
|
||||
videoId: $video.data('video-id'),
|
||||
events: {
|
||||
onReady: function() {
|
||||
$video.data('ytPlayer').player.mute();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('scroll', function(){
|
||||
videoScroll();
|
||||
});
|
||||
|
||||
function videoScroll() {
|
||||
var fraction = 0.75,
|
||||
player = $video.data('ytPlayer').player,
|
||||
videoHeight = $video.height(),
|
||||
videoOffsetTop = $video.offset().top,
|
||||
windowScrollY = window.scrollY;
|
||||
|
||||
if(windowScrollY > (videoHeight + videoOffsetTop) *fraction) {
|
||||
player.pauseVideo();
|
||||
} else {
|
||||
player.playVideo();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function OwlCarousel() {
|
||||
$('.owl-carousel').each( function() {
|
||||
var $carousel = $(this);
|
||||
$carousel.owlCarousel({
|
||||
// dots : false,
|
||||
// items : $carousel.data("items"),
|
||||
slideBy : $carousel.data("slideby"),
|
||||
center : $carousel.data("center"),
|
||||
loop : $carousel.data("loop"),
|
||||
margin : $carousel.data("margin"),
|
||||
|
||||
autoplay : $carousel.data("autoplay"),
|
||||
autoplayTimeout : $carousel.data("autoplay-timeout"),
|
||||
navText : [ '<span class="fa fa-angle-left"><span>', '<span class="fa fa-angle-right"></span>' ],
|
||||
responsive: {
|
||||
0 : {
|
||||
items: 1,
|
||||
dots: true,
|
||||
nav: false
|
||||
},
|
||||
992 : {
|
||||
items: $carousel.data("items"),
|
||||
dots: false,
|
||||
nav : $carousel.data("nav")
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function stickySidebars() {
|
||||
$('.sticky-col').stick_in_parent({
|
||||
parent: $('#sticky-parent')
|
||||
});
|
||||
|
||||
$('.sticky-cols').stick_in_parent({
|
||||
parent: $('.sticky-parent')
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function mobileFilters() {
|
||||
if($('#mobileFilters').length) {
|
||||
$(document).on('scroll', function(){
|
||||
filtersScroll();
|
||||
});
|
||||
}
|
||||
|
||||
function filtersScroll() {
|
||||
|
||||
var filters = $('#mobileFilters');
|
||||
var footer = $('#mainFooter');
|
||||
|
||||
if(filters.offset().top + filters.height() > footer.offset().top - 10 || !$(document).scrollTop()) {
|
||||
filters.removeClass('active');
|
||||
} else {
|
||||
filters.addClass('active');
|
||||
}
|
||||
|
||||
if($(document).scrollTop + window.innerHeight > footer.offset().top) {
|
||||
filters.addClass('active');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkboxes() {
|
||||
$('.icheck, .iradio').iCheck({
|
||||
checkboxClass: 'icheck',
|
||||
radioClass: 'iradio'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function googleMaps() {
|
||||
if($('.google-map').length) {
|
||||
window.initMap = function() {
|
||||
$('.google-map').gmap();
|
||||
}
|
||||
} else {
|
||||
window.initMap = function() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function afternavHeight() {
|
||||
$('.afternav-height').each(function(){
|
||||
var $mainNav = $('#main-nav'),
|
||||
mainNavHeight = $mainNav.height(),
|
||||
height = $(window).height() - mainNavHeight;
|
||||
|
||||
$(this).css('height', height);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function activeBookmark() {
|
||||
$('.theme-search-results-item-bookmark').each(function(index, el){
|
||||
$(el).on('click', function(e){
|
||||
e.preventDefault();
|
||||
$(this).toggleClass('active');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
function magnificLightbox() {
|
||||
$('.magnific-gallery').each(function(index, el){
|
||||
$(el).magnificPopup({
|
||||
delegate: 'a',
|
||||
type: 'image',
|
||||
gallery: {
|
||||
enabled: true,
|
||||
navigateByImgClick: true,
|
||||
preload: [0,1]
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
$('.magnific-gallery-link').each(function(index , value){
|
||||
var gallery = $(this);
|
||||
var galleryImages = $(this).data('items').split(',');
|
||||
var items = [];
|
||||
for(var i=0;i<galleryImages.length; i++){
|
||||
items.push({
|
||||
src:galleryImages[i],
|
||||
title:''
|
||||
});
|
||||
}
|
||||
gallery.magnificPopup({
|
||||
mainClass: 'mfp-fade',
|
||||
items:items,
|
||||
gallery:{
|
||||
enabled:true,
|
||||
tPrev: $(this).data('prev-text'),
|
||||
tNext: $(this).data('next-text')
|
||||
},
|
||||
type: 'image'
|
||||
});
|
||||
});
|
||||
|
||||
$('.magnific-inline').magnificPopup({
|
||||
type: 'inline',
|
||||
fixedContentPos: true
|
||||
});
|
||||
|
||||
$('.magnific-iframe').magnificPopup({
|
||||
type: 'iframe'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function priceSlider() {
|
||||
$("#price-slider").ionRangeSlider({
|
||||
type: "double",
|
||||
prefix: " ت "
|
||||
});
|
||||
|
||||
$("#price-slider-mob").ionRangeSlider({
|
||||
type: "double",
|
||||
prefix: " ت "
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
function BSTabsActions() {
|
||||
$('#sticky-tab').on('shown.bs.tab', function (e) {
|
||||
$('.sticky-tab-col').stick_in_parent({
|
||||
parent: $('#sticky-tab-parent')
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$('#slideTabs a').click(function (e) {
|
||||
e.preventDefault();
|
||||
$(this).tab('show');
|
||||
var control = $(this).attr('aria-controls')
|
||||
var active = $('#slideTabsSlides').find('.active')[0];
|
||||
var target = $('#slideTabsSlides').find("[data-tab='" + control + "']")[0];
|
||||
if(active !== target) {
|
||||
$(active).removeClass('active');
|
||||
$(target).addClass('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function heroSearchSections() {
|
||||
$('.theme-hero-search-section').each(function(){
|
||||
var label,
|
||||
input;
|
||||
|
||||
label = $(this).find('.theme-hero-search-section-label');
|
||||
input = $(this).find('.theme-hero-search-section-input');
|
||||
|
||||
if(input.val()) {
|
||||
label.addClass('active');
|
||||
}
|
||||
|
||||
input.focus(function(){
|
||||
label.addClass('active');
|
||||
});
|
||||
|
||||
input.blur(function(){
|
||||
if(!input.val()) {
|
||||
label.removeClass('active');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function autocomplete() {
|
||||
$('.typeahead').typeahead({
|
||||
minLength: 3,
|
||||
showHintOnFocus: true,
|
||||
source: function(q, cb) {
|
||||
return $.ajax({
|
||||
dataType: 'jsonp',
|
||||
type: 'get',
|
||||
url: 'http://gd.geobytes.com/AutoCompleteCity?callback=?&q=' + q,
|
||||
chache: false,
|
||||
success: function(data) {
|
||||
var res = [];
|
||||
$.each(data, function(index, val){
|
||||
if(val !== "%s") {
|
||||
res.push({
|
||||
id: index,
|
||||
name: val
|
||||
})
|
||||
}
|
||||
})
|
||||
cb(res);
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function searchResultsCollapse() {
|
||||
|
||||
$('.theme-search-results-item-collapse').on('shown.bs.collapse', function(){
|
||||
$(this).parents('.theme-search-results-item').addClass('active');
|
||||
});
|
||||
|
||||
$('.theme-search-results-item-collapse').on('hidden.bs.collapse', function(){
|
||||
$(this).parents('.theme-search-results-item').removeClass('active');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
function comingSoonCountdown() {
|
||||
|
||||
$('#commingSoonCountdown').countdown('1400/10/10', function(e){
|
||||
$(this).html(e.strftime(''
|
||||
+ '<div><p>%D</p><span>روز</span></div>'
|
||||
+ '<div><p>%H</p><span>ساعت</span></div>'
|
||||
+ '<div><p>%M</p><span>دقیه</span></div>'
|
||||
+ '<div><p>%S</p><span>ثانیه</span></div>'
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
$('.mobile-picker').each(function(i, item){
|
||||
if(!isSafari) {
|
||||
$(item).attr('type', 'text');
|
||||
$(item).val($(item).attr('value'));
|
||||
$(item).on('focus', function(){
|
||||
$(item).attr('type', 'date');
|
||||
});
|
||||
$(item).on('blur', function(){
|
||||
$(item).attr('type', 'text');
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,87 @@
|
||||
/*jshint browser:true */
|
||||
/*!
|
||||
* FitVids 1.1
|
||||
*
|
||||
* Copyright 2013, Chris Coyier - http://css-tricks.com + Dave Rupert - http://daverupert.com
|
||||
* Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/
|
||||
* Released under the WTFPL license - http://sam.zoy.org/wtfpl/
|
||||
*
|
||||
*/
|
||||
|
||||
;(function( $ ){
|
||||
|
||||
'use strict';
|
||||
|
||||
$.fn.fitVids = function( options ) {
|
||||
var settings = {
|
||||
customSelector: null,
|
||||
ignore: null
|
||||
};
|
||||
|
||||
if(!document.getElementById('fit-vids-style')) {
|
||||
// appendStyles: https://github.com/toddmotto/fluidvids/blob/master/dist/fluidvids.js
|
||||
var head = document.head || document.getElementsByTagName('head')[0];
|
||||
var css = '.fluid-width-video-wrapper{width:100%;position:relative;padding:0;}.fluid-width-video-wrapper iframe,.fluid-width-video-wrapper object,.fluid-width-video-wrapper embed {position:absolute;top:0;left:0;width:100%;height:100%;}';
|
||||
var div = document.createElement("div");
|
||||
div.innerHTML = '<p>x</p><style id="fit-vids-style">' + css + '</style>';
|
||||
head.appendChild(div.childNodes[1]);
|
||||
}
|
||||
|
||||
if ( options ) {
|
||||
$.extend( settings, options );
|
||||
}
|
||||
|
||||
return this.each(function(){
|
||||
var selectors = [
|
||||
'iframe[src*="player.vimeo.com"]',
|
||||
'iframe[src*="youtube.com"]',
|
||||
'iframe[src*="youtube-nocookie.com"]',
|
||||
'iframe[src*="kickstarter.com"][src*="video.html"]',
|
||||
'object',
|
||||
'embed'
|
||||
];
|
||||
|
||||
if (settings.customSelector) {
|
||||
selectors.push(settings.customSelector);
|
||||
}
|
||||
|
||||
var ignoreList = '.fitvidsignore';
|
||||
|
||||
if(settings.ignore) {
|
||||
ignoreList = ignoreList + ', ' + settings.ignore;
|
||||
}
|
||||
|
||||
var $allVideos = $(this).find(selectors.join(','));
|
||||
$allVideos = $allVideos.not('object object'); // SwfObj conflict patch
|
||||
$allVideos = $allVideos.not(ignoreList); // Disable FitVids on this video.
|
||||
|
||||
$allVideos.each(function(){
|
||||
var $this = $(this);
|
||||
if($this.parents(ignoreList).length > 0) {
|
||||
return; // Disable FitVids on this video.
|
||||
}
|
||||
if (this.tagName.toLowerCase() === 'embed' && $this.parent('object').length || $this.parent('.fluid-width-video-wrapper').length) { return; }
|
||||
if ((!$this.css('height') && !$this.css('width')) && (isNaN($this.attr('height')) || isNaN($this.attr('width'))))
|
||||
{
|
||||
$this.attr('height', 9);
|
||||
$this.attr('width', 16);
|
||||
}
|
||||
var height = ( this.tagName.toLowerCase() === 'object' || ($this.attr('height') && !isNaN(parseInt($this.attr('height'), 10))) ) ? parseInt($this.attr('height'), 10) : $this.height(),
|
||||
width = !isNaN(parseInt($this.attr('width'), 10)) ? parseInt($this.attr('width'), 10) : $this.width(),
|
||||
aspectRatio = height / width;
|
||||
if(!$this.attr('name')){
|
||||
var videoName = 'fitvid' + $.fn.fitVids._count;
|
||||
$this.attr('name', videoName);
|
||||
$.fn.fitVids._count++;
|
||||
}
|
||||
$this.wrap('<div class="fluid-width-video-wrapper"></div>').parent('.fluid-width-video-wrapper').css('padding-top', (aspectRatio * 100)+'%');
|
||||
$this.removeAttr('height').removeAttr('width');
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Internal counter for unique video names.
|
||||
$.fn.fitVids._count = 0;
|
||||
|
||||
// Works with either jQuery or Zepto
|
||||
})( window.jQuery || window.Zepto );
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* google maps wrapper
|
||||
*/
|
||||
;( function( $, window, document, undefined ) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// Create the defaults once
|
||||
var pluginName = "gmap",
|
||||
defaults = {
|
||||
mapStyle: [{"featureType":"water","elementType":"geometry","stylers":[{"color":"#e9e9e9"},{"lightness":17}]},{"featureType":"landscape","elementType":"geometry","stylers":[{"color":"#f5f5f5"},{"lightness":20}]},{"featureType":"road.highway","elementType":"geometry.fill","stylers":[{"color":"#ffffff"},{"lightness":17}]},{"featureType":"road.highway","elementType":"geometry.stroke","stylers":[{"color":"#ffffff"},{"lightness":29},{"weight":0.2}]},{"featureType":"road.arterial","elementType":"geometry","stylers":[{"color":"#ffffff"},{"lightness":18}]},{"featureType":"road.local","elementType":"geometry","stylers":[{"color":"#ffffff"},{"lightness":16}]},{"featureType":"poi","elementType":"geometry","stylers":[{"color":"#f5f5f5"},{"lightness":21}]},{"featureType":"poi.park","elementType":"geometry","stylers":[{"color":"#dedede"},{"lightness":21}]},{"elementType":"labels.text.stroke","stylers":[{"visibility":"on"},{"color":"#ffffff"},{"lightness":16}]},{"elementType":"labels.text.fill","stylers":[{"saturation":36},{"color":"#333333"},{"lightness":40}]},{"elementType":"labels.icon","stylers":[{"visibility":"off"}]},{"featureType":"transit","elementType":"geometry","stylers":[{"color":"#f2f2f2"},{"lightness":19}]},{"featureType":"administrative","elementType":"geometry.fill","stylers":[{"color":"#fefefe"},{"lightness":20}]},{"featureType":"administrative","elementType":"geometry.stroke","stylers":[{"color":"#fefefe"},{"lightness":17},{"weight":1.2}]}],
|
||||
zoom: 14,
|
||||
mapIcon: 'img/map-marker.png',
|
||||
google: null,
|
||||
tabMap: true,
|
||||
nearbySearch: false
|
||||
},
|
||||
mapStyle,
|
||||
service,
|
||||
tabItem,
|
||||
markers,
|
||||
markersExists = false;
|
||||
|
||||
function Plugin ( element, options ) {
|
||||
this.element = element;
|
||||
|
||||
this.settings = $.extend( {}, defaults, options );
|
||||
this._defaults = defaults;
|
||||
this._name = pluginName;
|
||||
this.init();
|
||||
}
|
||||
|
||||
$.extend( Plugin.prototype, {
|
||||
map: null,
|
||||
loc: null,
|
||||
init: function() {
|
||||
|
||||
tabItem = $(this.element).attr('data-tab'),
|
||||
markers = $(this.element).attr('data-markers');
|
||||
|
||||
if(typeof markers !== typeof undefined && markers !== false) {
|
||||
markers = $.parseJSON(markers);
|
||||
markersExists = true;
|
||||
}
|
||||
|
||||
|
||||
this.loc();
|
||||
if(tabItem === 'false') {
|
||||
this.setMap();
|
||||
} else {
|
||||
this.tabBnt();
|
||||
};
|
||||
|
||||
},
|
||||
setMap: function() {
|
||||
this.map = new google.maps.Map(this.element, {
|
||||
zoom: this.settings.zoom,
|
||||
center: this.loc,
|
||||
mapTypeControl: false
|
||||
});
|
||||
|
||||
if(markersExists) {
|
||||
this.setMarkers();
|
||||
} else {
|
||||
this.marker();
|
||||
}
|
||||
|
||||
|
||||
|
||||
this.mapStyle();
|
||||
if(this.settings.nearbySearch) {
|
||||
this.service();
|
||||
}
|
||||
},
|
||||
tabBnt: function() {
|
||||
var parent = $(this.element).closest('.tab-pane'),
|
||||
id = parent.attr('id'),
|
||||
href = '#' + id,
|
||||
$tab = $('a[href="'+href+'"]'),
|
||||
self = this;
|
||||
|
||||
$tab.on('shown.bs.tab', function(e){
|
||||
if(!self.map) {
|
||||
self.setMap();
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
loc: function() {
|
||||
var lng = $(this.element).data('lng'),
|
||||
lat = $(this.element).data('lat');
|
||||
|
||||
this.loc = new google.maps.LatLng(lat, lng);
|
||||
},
|
||||
mapStyle: function() {
|
||||
mapStyle = new google.maps.StyledMapType(this.settings.mapStyle);
|
||||
this.map.mapTypes.set('styled_map', mapStyle);
|
||||
this.map.setMapTypeId('styled_map');
|
||||
},
|
||||
setMarkers: function() {
|
||||
for (var i = markers.length - 1; i >= 0; i--) {
|
||||
new google.maps.Marker({
|
||||
position: new google.maps.LatLng(markers[i].lat, markers[i].lng),
|
||||
map: this.map,
|
||||
icon: {
|
||||
path: google.maps.SymbolPath.CIRCLE,
|
||||
scale: 5,
|
||||
fillColor: '#ff6c2d',
|
||||
fillOpacity: 1,
|
||||
strokeColor: 'white',
|
||||
strokeWeight: 2
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
marker: function() {
|
||||
new google.maps.Marker({
|
||||
position: this.loc,
|
||||
map: this.map,
|
||||
icon: this.settings.mapIcon
|
||||
});
|
||||
},
|
||||
service: function() {
|
||||
service = new google.maps.places.PlacesService(map);
|
||||
service.nearbySearch({
|
||||
location: loc,
|
||||
radius: 300,
|
||||
type: ['store']
|
||||
// this: this
|
||||
}, this.processService);
|
||||
},
|
||||
processService: function(results, status, pagination) {
|
||||
if(status !== google.maps.places.PlacesServiceStatus.OK) {
|
||||
return;
|
||||
} else {
|
||||
self.serviceMarkers(results);
|
||||
}
|
||||
},
|
||||
serviceMarkers: function(places) {
|
||||
var bounds = new google.maps.LatLngBounds();
|
||||
|
||||
for (var i = 0, place; place = places[i]; i++) {
|
||||
var infowindow = new google.maps.InfoWindow;
|
||||
// console.log(map);
|
||||
var infoMarker = new google.maps.Marker({
|
||||
map: map,
|
||||
icon: {
|
||||
path: google.maps.SymbolPath.CIRCLE,
|
||||
strokeOpacity: 0,
|
||||
fillColor: '#0093d2',
|
||||
fillOpacity: 0.5,
|
||||
scale: 2.5
|
||||
},
|
||||
title: place.name,
|
||||
position: place.geometry.location
|
||||
});
|
||||
|
||||
google.maps.event.addListener(infoMarker, 'mouseover', function() {
|
||||
infowindow.setContent(this.title);
|
||||
infowindow.open(map, this);
|
||||
});
|
||||
|
||||
google.maps.event.addListener(infoMarker, 'mouseout', function() {
|
||||
infowindow.close(map, this);
|
||||
});
|
||||
|
||||
bounds.extend(place.geometry.location);
|
||||
}
|
||||
map.fitBounds(bounds);
|
||||
}
|
||||
});
|
||||
|
||||
$.fn[ pluginName ] = function( options ) {
|
||||
return this.each( function() {
|
||||
if ( !$.data( this, "plugin_" + pluginName ) ) {
|
||||
$.data( this, "plugin_" +
|
||||
pluginName, new Plugin( this, options ) );
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
} )( jQuery, window, document );
|
||||
|
||||
@@ -0,0 +1,509 @@
|
||||
/*!
|
||||
* iCheck v1.0.2, http://git.io/arlzeA
|
||||
* ===================================
|
||||
* Powerful jQuery and Zepto plugin for checkboxes and radio buttons customization
|
||||
*
|
||||
* (c) 2013 Damir Sultanov, http://fronteed.com
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
|
||||
// Cached vars
|
||||
var _iCheck = 'iCheck',
|
||||
_iCheckHelper = _iCheck + '-helper',
|
||||
_checkbox = 'checkbox',
|
||||
_radio = 'radio',
|
||||
_checked = 'checked',
|
||||
_unchecked = 'un' + _checked,
|
||||
_disabled = 'disabled',
|
||||
_determinate = 'determinate',
|
||||
_indeterminate = 'in' + _determinate,
|
||||
_update = 'update',
|
||||
_type = 'type',
|
||||
_click = 'click',
|
||||
_touch = 'touchbegin.i touchend.i',
|
||||
_add = 'addClass',
|
||||
_remove = 'removeClass',
|
||||
_callback = 'trigger',
|
||||
_label = 'label',
|
||||
_cursor = 'cursor',
|
||||
_mobile = /ipad|iphone|ipod|android|blackberry|windows phone|opera mini|silk/i.test(navigator.userAgent);
|
||||
|
||||
// Plugin init
|
||||
$.fn[_iCheck] = function(options, fire) {
|
||||
|
||||
// Walker
|
||||
var handle = 'input[type="' + _checkbox + '"], input[type="' + _radio + '"]',
|
||||
stack = $(),
|
||||
walker = function(object) {
|
||||
object.each(function() {
|
||||
var self = $(this);
|
||||
|
||||
if (self.is(handle)) {
|
||||
stack = stack.add(self);
|
||||
} else {
|
||||
stack = stack.add(self.find(handle));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Check if we should operate with some method
|
||||
if (/^(check|uncheck|toggle|indeterminate|determinate|disable|enable|update|destroy)$/i.test(options)) {
|
||||
|
||||
// Normalize method's name
|
||||
options = options.toLowerCase();
|
||||
|
||||
// Find checkboxes and radio buttons
|
||||
walker(this);
|
||||
|
||||
return stack.each(function() {
|
||||
var self = $(this);
|
||||
|
||||
if (options == 'destroy') {
|
||||
tidy(self, 'ifDestroyed');
|
||||
} else {
|
||||
operate(self, true, options);
|
||||
}
|
||||
|
||||
// Fire method's callback
|
||||
if ($.isFunction(fire)) {
|
||||
fire();
|
||||
}
|
||||
});
|
||||
|
||||
// Customization
|
||||
} else if (typeof options == 'object' || !options) {
|
||||
|
||||
// Check if any options were passed
|
||||
var settings = $.extend({
|
||||
checkedClass: _checked,
|
||||
disabledClass: _disabled,
|
||||
indeterminateClass: _indeterminate,
|
||||
labelHover: true
|
||||
}, options),
|
||||
|
||||
selector = settings.handle,
|
||||
hoverClass = settings.hoverClass || 'hover',
|
||||
focusClass = settings.focusClass || 'focus',
|
||||
activeClass = settings.activeClass || 'active',
|
||||
labelHover = !!settings.labelHover,
|
||||
labelHoverClass = settings.labelHoverClass || 'hover',
|
||||
|
||||
// Setup clickable area
|
||||
area = ('' + settings.increaseArea).replace('%', '') | 0;
|
||||
|
||||
// Selector limit
|
||||
if (selector == _checkbox || selector == _radio) {
|
||||
handle = 'input[type="' + selector + '"]';
|
||||
}
|
||||
|
||||
// Clickable area limit
|
||||
if (area < -50) {
|
||||
area = -50;
|
||||
}
|
||||
|
||||
// Walk around the selector
|
||||
walker(this);
|
||||
|
||||
return stack.each(function() {
|
||||
var self = $(this);
|
||||
|
||||
// If already customized
|
||||
tidy(self);
|
||||
|
||||
var node = this,
|
||||
id = node.id,
|
||||
|
||||
// Layer styles
|
||||
offset = -area + '%',
|
||||
size = 100 + (area * 2) + '%',
|
||||
layer = {
|
||||
position: 'absolute',
|
||||
top: offset,
|
||||
left: offset,
|
||||
display: 'block',
|
||||
width: size,
|
||||
height: size,
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
background: '#fff',
|
||||
border: 0,
|
||||
opacity: 0
|
||||
},
|
||||
|
||||
// Choose how to hide input
|
||||
hide = _mobile ? {
|
||||
position: 'absolute',
|
||||
visibility: 'hidden'
|
||||
} : area ? layer : {
|
||||
position: 'absolute',
|
||||
opacity: 0
|
||||
},
|
||||
|
||||
// Get proper class
|
||||
className = node[_type] == _checkbox ? settings.checkboxClass || 'i' + _checkbox : settings.radioClass || 'i' + _radio,
|
||||
|
||||
// Find assigned labels
|
||||
label = $(_label + '[for="' + id + '"]').add(self.closest(_label)),
|
||||
|
||||
// Check ARIA option
|
||||
aria = !!settings.aria,
|
||||
|
||||
// Set ARIA placeholder
|
||||
ariaID = _iCheck + '-' + Math.random().toString(36).substr(2,6),
|
||||
|
||||
// Parent & helper
|
||||
parent = '<div class="' + className + '" ' + (aria ? 'role="' + node[_type] + '" ' : ''),
|
||||
helper;
|
||||
|
||||
// Set ARIA "labelledby"
|
||||
if (aria) {
|
||||
label.each(function() {
|
||||
parent += 'aria-labelledby="';
|
||||
|
||||
if (this.id) {
|
||||
parent += this.id;
|
||||
} else {
|
||||
this.id = ariaID;
|
||||
parent += ariaID;
|
||||
}
|
||||
|
||||
parent += '"';
|
||||
});
|
||||
}
|
||||
|
||||
// Wrap input
|
||||
parent = self.wrap(parent + '/>')[_callback]('ifCreated').parent().append(settings.insert);
|
||||
|
||||
// Layer addition
|
||||
helper = $('<ins class="' + _iCheckHelper + '"/>').css(layer).appendTo(parent);
|
||||
|
||||
// Finalize customization
|
||||
self.data(_iCheck, {o: settings, s: self.attr('style')}).css(hide);
|
||||
!!settings.inheritClass && parent[_add](node.className || '');
|
||||
!!settings.inheritID && id && parent.attr('id', _iCheck + '-' + id);
|
||||
parent.css('position') == 'static' && parent.css('position', 'relative');
|
||||
operate(self, true, _update);
|
||||
|
||||
// Label events
|
||||
if (label.length) {
|
||||
label.on(_click + '.i mouseover.i mouseout.i ' + _touch, function(event) {
|
||||
var type = event[_type],
|
||||
item = $(this);
|
||||
|
||||
// Do nothing if input is disabled
|
||||
if (!node[_disabled]) {
|
||||
|
||||
// Click
|
||||
if (type == _click) {
|
||||
if ($(event.target).is('a')) {
|
||||
return;
|
||||
}
|
||||
operate(self, false, true);
|
||||
|
||||
// Hover state
|
||||
} else if (labelHover) {
|
||||
|
||||
// mouseout|touchend
|
||||
if (/ut|nd/.test(type)) {
|
||||
parent[_remove](hoverClass);
|
||||
item[_remove](labelHoverClass);
|
||||
} else {
|
||||
parent[_add](hoverClass);
|
||||
item[_add](labelHoverClass);
|
||||
}
|
||||
}
|
||||
|
||||
if (_mobile) {
|
||||
event.stopPropagation();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Input events
|
||||
self.on(_click + '.i focus.i blur.i keyup.i keydown.i keypress.i', function(event) {
|
||||
var type = event[_type],
|
||||
key = event.keyCode;
|
||||
|
||||
// Click
|
||||
if (type == _click) {
|
||||
return false;
|
||||
|
||||
// Keydown
|
||||
} else if (type == 'keydown' && key == 32) {
|
||||
if (!(node[_type] == _radio && node[_checked])) {
|
||||
if (node[_checked]) {
|
||||
off(self, _checked);
|
||||
} else {
|
||||
on(self, _checked);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
// Keyup
|
||||
} else if (type == 'keyup' && node[_type] == _radio) {
|
||||
!node[_checked] && on(self, _checked);
|
||||
|
||||
// Focus/blur
|
||||
} else if (/us|ur/.test(type)) {
|
||||
parent[type == 'blur' ? _remove : _add](focusClass);
|
||||
}
|
||||
});
|
||||
|
||||
// Helper events
|
||||
helper.on(_click + ' mousedown mouseup mouseover mouseout ' + _touch, function(event) {
|
||||
var type = event[_type],
|
||||
|
||||
// mousedown|mouseup
|
||||
toggle = /wn|up/.test(type) ? activeClass : hoverClass;
|
||||
|
||||
// Do nothing if input is disabled
|
||||
if (!node[_disabled]) {
|
||||
|
||||
// Click
|
||||
if (type == _click) {
|
||||
operate(self, false, true);
|
||||
|
||||
// Active and hover states
|
||||
} else {
|
||||
|
||||
// State is on
|
||||
if (/wn|er|in/.test(type)) {
|
||||
|
||||
// mousedown|mouseover|touchbegin
|
||||
parent[_add](toggle);
|
||||
|
||||
// State is off
|
||||
} else {
|
||||
parent[_remove](toggle + ' ' + activeClass);
|
||||
}
|
||||
|
||||
// Label hover
|
||||
if (label.length && labelHover && toggle == hoverClass) {
|
||||
|
||||
// mouseout|touchend
|
||||
label[/ut|nd/.test(type) ? _remove : _add](labelHoverClass);
|
||||
}
|
||||
}
|
||||
|
||||
if (_mobile) {
|
||||
event.stopPropagation();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
// Do something with inputs
|
||||
function operate(input, direct, method) {
|
||||
var node = input[0],
|
||||
state = /er/.test(method) ? _indeterminate : /bl/.test(method) ? _disabled : _checked,
|
||||
active = method == _update ? {
|
||||
checked: node[_checked],
|
||||
disabled: node[_disabled],
|
||||
indeterminate: input.attr(_indeterminate) == 'true' || input.attr(_determinate) == 'false'
|
||||
} : node[state];
|
||||
|
||||
// Check, disable or indeterminate
|
||||
if (/^(ch|di|in)/.test(method) && !active) {
|
||||
on(input, state);
|
||||
|
||||
// Uncheck, enable or determinate
|
||||
} else if (/^(un|en|de)/.test(method) && active) {
|
||||
off(input, state);
|
||||
|
||||
// Update
|
||||
} else if (method == _update) {
|
||||
|
||||
// Handle states
|
||||
for (var each in active) {
|
||||
if (active[each]) {
|
||||
on(input, each, true);
|
||||
} else {
|
||||
off(input, each, true);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (!direct || method == 'toggle') {
|
||||
|
||||
// Helper or label was clicked
|
||||
if (!direct) {
|
||||
input[_callback]('ifClicked');
|
||||
}
|
||||
|
||||
// Toggle checked state
|
||||
if (active) {
|
||||
if (node[_type] !== _radio) {
|
||||
off(input, state);
|
||||
}
|
||||
} else {
|
||||
on(input, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add checked, disabled or indeterminate state
|
||||
function on(input, state, keep) {
|
||||
var node = input[0],
|
||||
parent = input.parent(),
|
||||
checked = state == _checked,
|
||||
indeterminate = state == _indeterminate,
|
||||
disabled = state == _disabled,
|
||||
callback = indeterminate ? _determinate : checked ? _unchecked : 'enabled',
|
||||
regular = option(input, callback + capitalize(node[_type])),
|
||||
specific = option(input, state + capitalize(node[_type]));
|
||||
|
||||
// Prevent unnecessary actions
|
||||
if (node[state] !== true) {
|
||||
|
||||
// Toggle assigned radio buttons
|
||||
if (!keep && state == _checked && node[_type] == _radio && node.name) {
|
||||
var form = input.closest('form'),
|
||||
inputs = 'input[name="' + node.name + '"]';
|
||||
|
||||
inputs = form.length ? form.find(inputs) : $(inputs);
|
||||
|
||||
inputs.each(function() {
|
||||
if (this !== node && $(this).data(_iCheck)) {
|
||||
off($(this), state);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Indeterminate state
|
||||
if (indeterminate) {
|
||||
|
||||
// Add indeterminate state
|
||||
node[state] = true;
|
||||
|
||||
// Remove checked state
|
||||
if (node[_checked]) {
|
||||
off(input, _checked, 'force');
|
||||
}
|
||||
|
||||
// Checked or disabled state
|
||||
} else {
|
||||
|
||||
// Add checked or disabled state
|
||||
if (!keep) {
|
||||
node[state] = true;
|
||||
}
|
||||
|
||||
// Remove indeterminate state
|
||||
if (checked && node[_indeterminate]) {
|
||||
off(input, _indeterminate, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger callbacks
|
||||
callbacks(input, checked, state, keep);
|
||||
}
|
||||
|
||||
// Add proper cursor
|
||||
if (node[_disabled] && !!option(input, _cursor, true)) {
|
||||
parent.find('.' + _iCheckHelper).css(_cursor, 'default');
|
||||
}
|
||||
|
||||
// Add state class
|
||||
parent[_add](specific || option(input, state) || '');
|
||||
|
||||
// Set ARIA attribute
|
||||
if (!!parent.attr('role') && !indeterminate) {
|
||||
parent.attr('aria-' + (disabled ? _disabled : _checked), 'true');
|
||||
}
|
||||
|
||||
// Remove regular state class
|
||||
parent[_remove](regular || option(input, callback) || '');
|
||||
}
|
||||
|
||||
// Remove checked, disabled or indeterminate state
|
||||
function off(input, state, keep) {
|
||||
var node = input[0],
|
||||
parent = input.parent(),
|
||||
checked = state == _checked,
|
||||
indeterminate = state == _indeterminate,
|
||||
disabled = state == _disabled,
|
||||
callback = indeterminate ? _determinate : checked ? _unchecked : 'enabled',
|
||||
regular = option(input, callback + capitalize(node[_type])),
|
||||
specific = option(input, state + capitalize(node[_type]));
|
||||
|
||||
// Prevent unnecessary actions
|
||||
if (node[state] !== false) {
|
||||
|
||||
// Toggle state
|
||||
if (indeterminate || !keep || keep == 'force') {
|
||||
node[state] = false;
|
||||
}
|
||||
|
||||
// Trigger callbacks
|
||||
callbacks(input, checked, callback, keep);
|
||||
}
|
||||
|
||||
// Add proper cursor
|
||||
if (!node[_disabled] && !!option(input, _cursor, true)) {
|
||||
parent.find('.' + _iCheckHelper).css(_cursor, 'pointer');
|
||||
}
|
||||
|
||||
// Remove state class
|
||||
parent[_remove](specific || option(input, state) || '');
|
||||
|
||||
// Set ARIA attribute
|
||||
if (!!parent.attr('role') && !indeterminate) {
|
||||
parent.attr('aria-' + (disabled ? _disabled : _checked), 'false');
|
||||
}
|
||||
|
||||
// Add regular state class
|
||||
parent[_add](regular || option(input, callback) || '');
|
||||
}
|
||||
|
||||
// Remove all traces
|
||||
function tidy(input, callback) {
|
||||
if (input.data(_iCheck)) {
|
||||
|
||||
// Remove everything except input
|
||||
input.parent().html(input.attr('style', input.data(_iCheck).s || ''));
|
||||
|
||||
// Callback
|
||||
if (callback) {
|
||||
input[_callback](callback);
|
||||
}
|
||||
|
||||
// Unbind events
|
||||
input.off('.i').unwrap();
|
||||
$(_label + '[for="' + input[0].id + '"]').add(input.closest(_label)).off('.i');
|
||||
}
|
||||
}
|
||||
|
||||
// Get some option
|
||||
function option(input, state, regular) {
|
||||
if (input.data(_iCheck)) {
|
||||
return input.data(_iCheck).o[state + (regular ? '' : 'Class')];
|
||||
}
|
||||
}
|
||||
|
||||
// Capitalize some string
|
||||
function capitalize(string) {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
}
|
||||
|
||||
// Executable handlers
|
||||
function callbacks(input, checked, callback, keep) {
|
||||
if (!keep) {
|
||||
if (checked) {
|
||||
input[_callback]('ifToggled');
|
||||
}
|
||||
|
||||
input[_callback]('ifChanged')[_callback]('if' + capitalize(callback));
|
||||
}
|
||||
}
|
||||
})(window.jQuery || window.Zepto);
|
||||
File diff suppressed because it is too large
Load Diff
Vendored
+2
File diff suppressed because one or more lines are too long
Vendored
+4
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,106 @@
|
||||
|
||||
;( function( $, window, document, undefined ) {
|
||||
|
||||
"use strict";
|
||||
var pluginName = "quantitySelector",
|
||||
defaults = {
|
||||
propertyName: "value"
|
||||
},
|
||||
_qs,
|
||||
_$html;
|
||||
|
||||
|
||||
function Plugin ( element, options ) {
|
||||
// _this = this;
|
||||
_qs = this;
|
||||
_qs.element = element;
|
||||
_qs.$el = $(element);
|
||||
_qs.settings = $.extend( {}, defaults, options );
|
||||
_qs._defaults = defaults;
|
||||
_qs._name = pluginName;
|
||||
|
||||
_qs.init();
|
||||
}
|
||||
|
||||
$.extend( Plugin.prototype, {
|
||||
init: function() {
|
||||
_$html = $('html');
|
||||
_qs.boxClassName = 'quantity-selector-box';
|
||||
_qs.$box = _qs.$el.find('.' + _qs.boxClassName);
|
||||
_qs.$input = _qs.$el.find('input');
|
||||
_qs.title = _qs.$el.data('increment');
|
||||
_qs.$increment = _qs.$el.find('.quantity-selector-increment a');
|
||||
_qs.$decrement = _qs.$el.find('.quantity-selector-decrement a');
|
||||
_qs.$current = _qs.$el.find('.quantity-selector-current');
|
||||
_qs.currentInt = parseInt(_qs.$current.text(), 10),
|
||||
_qs.sTitle = _qs.title.substring(0, _qs.title.length - 1);
|
||||
_qs.setTitle;
|
||||
|
||||
_qs.inputFocus();
|
||||
_qs.increment();
|
||||
_qs.decrement();
|
||||
_qs.boxHide();
|
||||
},
|
||||
inputFocus: function() {
|
||||
_qs.fireEvent(_qs.$input, 'focus', function(e){
|
||||
_qs.$box.addClass('show');
|
||||
// console.log(_qs.$input.val());
|
||||
if(!_qs.$input.val()) {
|
||||
_qs.setTitle = _qs.sTitle;
|
||||
_qs.inputValue();
|
||||
}
|
||||
});
|
||||
},
|
||||
inputValue: function() {
|
||||
_qs.$input.val(_qs.currentInt + ' ' + _qs.setTitle);
|
||||
},
|
||||
writeCurrent: function() {
|
||||
_qs.$current.html(_qs.currentInt);
|
||||
},
|
||||
increment: function() {
|
||||
_qs.fireEvent(_qs.$increment, 'click', function(e){
|
||||
e.preventDefault();
|
||||
_qs.setTitle = _qs.title;
|
||||
_qs.currentInt++;
|
||||
_qs.writeCurrent();
|
||||
_qs.inputValue();
|
||||
});
|
||||
},
|
||||
decrement: function() {
|
||||
_qs.fireEvent(_qs.$decrement, 'click', function(e){
|
||||
e.preventDefault();
|
||||
if(_qs.currentInt > 1) {
|
||||
_qs.setTitle = _qs.title;
|
||||
if(_qs.currentInt === 2) {
|
||||
_qs.setTitle = _qs.sTitle;
|
||||
}
|
||||
_qs.currentInt--;
|
||||
_qs.writeCurrent();
|
||||
_qs.inputValue();
|
||||
}
|
||||
});
|
||||
},
|
||||
boxHide: function() {
|
||||
_qs.fireEvent($('html'), 'click', function(e){
|
||||
if(e.target !== _qs.$input[0] && e.target !== _qs.$box[0] && !$(e.target).parents('.' + _qs.boxClassName).length) {
|
||||
_qs.$box.removeClass('show');
|
||||
}
|
||||
});
|
||||
},
|
||||
fireEvent: function(el, evt, callback) {
|
||||
el.on(evt, {_qs: _qs}, function(e){
|
||||
_qs = e.data._qs;
|
||||
callback(e);
|
||||
});
|
||||
}
|
||||
});
|
||||
$.fn[ pluginName ] = function( options ) {
|
||||
return this.each( function() {
|
||||
if ( !$.data( this, "plugin_" + pluginName ) ) {
|
||||
$.data( this, "plugin_" +
|
||||
pluginName, new Plugin( this, options ) );
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
} )( jQuery, window, document );
|
||||
@@ -0,0 +1,626 @@
|
||||
(function (root, factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define([], function () {
|
||||
return factory(root);
|
||||
});
|
||||
} else if (typeof exports === 'object') {
|
||||
module.exports = factory(root);
|
||||
} else {
|
||||
root.SmoothScroll = factory(root);
|
||||
}
|
||||
})(typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : this, function (window) {
|
||||
|
||||
'use strict';
|
||||
|
||||
//
|
||||
// Default settings
|
||||
//
|
||||
|
||||
var defaults = {
|
||||
// Selectors
|
||||
ignore: '[data-scroll-ignore]',
|
||||
header: null,
|
||||
topOnEmptyHash: true,
|
||||
|
||||
// Speed & Easing
|
||||
speed: 500,
|
||||
clip: true,
|
||||
offset: 0,
|
||||
easing: 'easeInOutCubic',
|
||||
customEasing: null,
|
||||
|
||||
// History
|
||||
updateURL: true,
|
||||
popstate: true,
|
||||
|
||||
// Custom Events
|
||||
emitEvents: true
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Utility Methods
|
||||
//
|
||||
|
||||
/**
|
||||
* Check if browser supports required methods
|
||||
* @return {Boolean} Returns true if all required methods are supported
|
||||
*/
|
||||
var supports = function () {
|
||||
return (
|
||||
'querySelector' in document &&
|
||||
'addEventListener' in window &&
|
||||
'requestAnimationFrame' in window &&
|
||||
'closest' in window.Element.prototype
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Merge two or more objects. Returns a new object.
|
||||
* @param {Object} objects The objects to merge together
|
||||
* @returns {Object} Merged values of defaults and options
|
||||
*/
|
||||
var extend = function () {
|
||||
|
||||
// Variables
|
||||
var extended = {};
|
||||
|
||||
// Merge the object into the extended object
|
||||
var merge = function (obj) {
|
||||
for (var prop in obj) {
|
||||
if (obj.hasOwnProperty(prop)) {
|
||||
extended[prop] = obj[prop];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Loop through each object and conduct a merge
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
merge(arguments[i]);
|
||||
}
|
||||
|
||||
return extended;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Check to see if user prefers reduced motion
|
||||
* @param {Object} settings Script settings
|
||||
*/
|
||||
var reduceMotion = function (settings) {
|
||||
if ('matchMedia' in window && window.matchMedia('(prefers-reduced-motion)').matches) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the height of an element.
|
||||
* @param {Node} elem The element to get the height of
|
||||
* @return {Number} The element's height in pixels
|
||||
*/
|
||||
var getHeight = function (elem) {
|
||||
return parseInt(window.getComputedStyle(elem).height, 10);
|
||||
};
|
||||
|
||||
/**
|
||||
* Decode a URI, with error check
|
||||
* @param {String} hash The URI to decode
|
||||
* @return {String} A decoded URI (or the original string if an error is thrown)
|
||||
*/
|
||||
var decode = function (hash) {
|
||||
var decoded;
|
||||
try {
|
||||
decoded = decodeURIComponent(hash);
|
||||
} catch(e) {
|
||||
decoded = hash;
|
||||
}
|
||||
return decoded;
|
||||
};
|
||||
|
||||
/**
|
||||
* Escape special characters for use with querySelector
|
||||
* @author Mathias Bynens
|
||||
* @link https://github.com/mathiasbynens/CSS.escape
|
||||
* @param {String} id The anchor ID to escape
|
||||
*/
|
||||
var escapeCharacters = function (id) {
|
||||
|
||||
// Remove leading hash
|
||||
if (id.charAt(0) === '#') {
|
||||
id = id.substr(1);
|
||||
}
|
||||
|
||||
var string = String(id);
|
||||
var length = string.length;
|
||||
var index = -1;
|
||||
var codeUnit;
|
||||
var result = '';
|
||||
var firstCodeUnit = string.charCodeAt(0);
|
||||
while (++index < length) {
|
||||
codeUnit = string.charCodeAt(index);
|
||||
// Note: there’s no need to special-case astral symbols, surrogate
|
||||
// pairs, or lone surrogates.
|
||||
|
||||
// If the character is NULL (U+0000), then throw an
|
||||
// `InvalidCharacterError` exception and terminate these steps.
|
||||
if (codeUnit === 0x0000) {
|
||||
throw new InvalidCharacterError(
|
||||
'Invalid character: the input contains U+0000.'
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
// If the character is in the range [\1-\1F] (U+0001 to U+001F) or is
|
||||
// U+007F, […]
|
||||
(codeUnit >= 0x0001 && codeUnit <= 0x001F) || codeUnit == 0x007F ||
|
||||
// If the character is the first character and is in the range [0-9]
|
||||
// (U+0030 to U+0039), […]
|
||||
(index === 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039) ||
|
||||
// If the character is the second character and is in the range [0-9]
|
||||
// (U+0030 to U+0039) and the first character is a `-` (U+002D), […]
|
||||
(
|
||||
index === 1 &&
|
||||
codeUnit >= 0x0030 && codeUnit <= 0x0039 &&
|
||||
firstCodeUnit === 0x002D
|
||||
)
|
||||
) {
|
||||
// http://dev.w3.org/csswg/cssom/#escape-a-character-as-code-point
|
||||
result += '\\' + codeUnit.toString(16) + ' ';
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the character is not handled by one of the above rules and is
|
||||
// greater than or equal to U+0080, is `-` (U+002D) or `_` (U+005F), or
|
||||
// is in one of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to
|
||||
// U+005A), or [a-z] (U+0061 to U+007A), […]
|
||||
if (
|
||||
codeUnit >= 0x0080 ||
|
||||
codeUnit === 0x002D ||
|
||||
codeUnit === 0x005F ||
|
||||
codeUnit >= 0x0030 && codeUnit <= 0x0039 ||
|
||||
codeUnit >= 0x0041 && codeUnit <= 0x005A ||
|
||||
codeUnit >= 0x0061 && codeUnit <= 0x007A
|
||||
) {
|
||||
// the character itself
|
||||
result += string.charAt(index);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise, the escaped character.
|
||||
// http://dev.w3.org/csswg/cssom/#escape-a-character
|
||||
result += '\\' + string.charAt(index);
|
||||
|
||||
}
|
||||
|
||||
// Return sanitized hash
|
||||
var hash;
|
||||
try {
|
||||
hash = decodeURIComponent('#' + result);
|
||||
} catch(e) {
|
||||
hash = '#' + result;
|
||||
}
|
||||
return hash;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate the easing pattern
|
||||
* @link https://gist.github.com/gre/1650294
|
||||
* @param {String} type Easing pattern
|
||||
* @param {Number} time Time animation should take to complete
|
||||
* @returns {Number}
|
||||
*/
|
||||
var easingPattern = function (settings, time) {
|
||||
var pattern;
|
||||
|
||||
// Default Easing Patterns
|
||||
if (settings.easing === 'easeInQuad') pattern = time * time; // accelerating from zero velocity
|
||||
if (settings.easing === 'easeOutQuad') pattern = time * (2 - time); // decelerating to zero velocity
|
||||
if (settings.easing === 'easeInOutQuad') pattern = time < 0.5 ? 2 * time * time : -1 + (4 - 2 * time) * time; // acceleration until halfway, then deceleration
|
||||
if (settings.easing === 'easeInCubic') pattern = time * time * time; // accelerating from zero velocity
|
||||
if (settings.easing === 'easeOutCubic') pattern = (--time) * time * time + 1; // decelerating to zero velocity
|
||||
if (settings.easing === 'easeInOutCubic') pattern = time < 0.5 ? 4 * time * time * time : (time - 1) * (2 * time - 2) * (2 * time - 2) + 1; // acceleration until halfway, then deceleration
|
||||
if (settings.easing === 'easeInQuart') pattern = time * time * time * time; // accelerating from zero velocity
|
||||
if (settings.easing === 'easeOutQuart') pattern = 1 - (--time) * time * time * time; // decelerating to zero velocity
|
||||
if (settings.easing === 'easeInOutQuart') pattern = time < 0.5 ? 8 * time * time * time * time : 1 - 8 * (--time) * time * time * time; // acceleration until halfway, then deceleration
|
||||
if (settings.easing === 'easeInQuint') pattern = time * time * time * time * time; // accelerating from zero velocity
|
||||
if (settings.easing === 'easeOutQuint') pattern = 1 + (--time) * time * time * time * time; // decelerating to zero velocity
|
||||
if (settings.easing === 'easeInOutQuint') pattern = time < 0.5 ? 16 * time * time * time * time * time : 1 + 16 * (--time) * time * time * time * time; // acceleration until halfway, then deceleration
|
||||
|
||||
// Custom Easing Patterns
|
||||
if (!!settings.customEasing) pattern = settings.customEasing(time);
|
||||
|
||||
return pattern || time; // no easing, no acceleration
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine the document's height
|
||||
* @returns {Number}
|
||||
*/
|
||||
var getDocumentHeight = function () {
|
||||
return Math.max(
|
||||
document.body.scrollHeight, document.documentElement.scrollHeight,
|
||||
document.body.offsetHeight, document.documentElement.offsetHeight,
|
||||
document.body.clientHeight, document.documentElement.clientHeight
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate how far to scroll
|
||||
* Clip support added by robjtede - https://github.com/cferdinandi/smooth-scroll/issues/405
|
||||
* @param {Element} anchor The anchor element to scroll to
|
||||
* @param {Number} headerHeight Height of a fixed header, if any
|
||||
* @param {Number} offset Number of pixels by which to offset scroll
|
||||
* @param {Boolean} clip If true, adjust scroll distance to prevent abrupt stops near the bottom of the page
|
||||
* @returns {Number}
|
||||
*/
|
||||
var getEndLocation = function (anchor, headerHeight, offset, clip) {
|
||||
var location = 0;
|
||||
if (anchor.offsetParent) {
|
||||
do {
|
||||
location += anchor.offsetTop;
|
||||
anchor = anchor.offsetParent;
|
||||
} while (anchor);
|
||||
}
|
||||
location = Math.max(location - headerHeight - offset, 0);
|
||||
if (clip) {
|
||||
location = Math.min(location, getDocumentHeight() - window.innerHeight);
|
||||
}
|
||||
return location;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the height of the fixed header
|
||||
* @param {Node} header The header
|
||||
* @return {Number} The height of the header
|
||||
*/
|
||||
var getHeaderHeight = function (header) {
|
||||
return !header ? 0 : (getHeight(header) + header.offsetTop);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the URL
|
||||
* @param {Node} anchor The anchor that was scrolled to
|
||||
* @param {Boolean} isNum If true, anchor is a number
|
||||
* @param {Object} options Settings for Smooth Scroll
|
||||
*/
|
||||
var updateURL = function (anchor, isNum, options) {
|
||||
|
||||
// Bail if the anchor is a number
|
||||
if (isNum) return;
|
||||
|
||||
// Verify that pushState is supported and the updateURL option is enabled
|
||||
if (!history.pushState || !options.updateURL) return;
|
||||
|
||||
// Update URL
|
||||
history.pushState(
|
||||
{
|
||||
smoothScroll: JSON.stringify(options),
|
||||
anchor: anchor.id
|
||||
},
|
||||
document.title,
|
||||
anchor === document.documentElement ? '#top' : '#' + anchor.id
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Bring the anchored element into focus
|
||||
* @param {Node} anchor The anchor element
|
||||
* @param {Number} endLocation The end location to scroll to
|
||||
* @param {Boolean} isNum If true, scroll is to a position rather than an element
|
||||
*/
|
||||
var adjustFocus = function (anchor, endLocation, isNum) {
|
||||
|
||||
// Is scrolling to top of page, blur
|
||||
if (anchor === 0) {
|
||||
document.body.focus();
|
||||
}
|
||||
|
||||
// Don't run if scrolling to a number on the page
|
||||
if (isNum) return;
|
||||
|
||||
// Otherwise, bring anchor element into focus
|
||||
anchor.focus();
|
||||
if (document.activeElement !== anchor) {
|
||||
anchor.setAttribute('tabindex', '-1');
|
||||
anchor.focus();
|
||||
anchor.style.outline = 'none';
|
||||
}
|
||||
window.scrollTo(0 , endLocation);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Emit a custom event
|
||||
* @param {String} type The event type
|
||||
* @param {Object} options The settings object
|
||||
* @param {Node} anchor The anchor element
|
||||
* @param {Node} toggle The toggle element
|
||||
*/
|
||||
var emitEvent = function (type, options, anchor, toggle) {
|
||||
if (!options.emitEvents || typeof window.CustomEvent !== 'function') return;
|
||||
var event = new CustomEvent(type, {
|
||||
bubbles: true,
|
||||
detail: {
|
||||
anchor: anchor,
|
||||
toggle: toggle
|
||||
}
|
||||
});
|
||||
document.dispatchEvent(event);
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// SmoothScroll Constructor
|
||||
//
|
||||
|
||||
var SmoothScroll = function (selector, options) {
|
||||
|
||||
//
|
||||
// Variables
|
||||
//
|
||||
|
||||
var smoothScroll = {}; // Object for public APIs
|
||||
var settings, anchor, toggle, fixedHeader, headerHeight, eventTimeout, animationInterval;
|
||||
|
||||
|
||||
//
|
||||
// Methods
|
||||
//
|
||||
|
||||
/**
|
||||
* Cancel a scroll-in-progress
|
||||
*/
|
||||
smoothScroll.cancelScroll = function (noEvent) {
|
||||
cancelAnimationFrame(animationInterval);
|
||||
animationInterval = null;
|
||||
if (noEvent) return;
|
||||
emitEvent('scrollCancel', settings);
|
||||
};
|
||||
|
||||
/**
|
||||
* Start/stop the scrolling animation
|
||||
* @param {Node|Number} anchor The element or position to scroll to
|
||||
* @param {Element} toggle The element that toggled the scroll event
|
||||
* @param {Object} options
|
||||
*/
|
||||
smoothScroll.animateScroll = function (anchor, toggle, options) {
|
||||
|
||||
// Local settings
|
||||
var animateSettings = extend(settings || defaults, options || {}); // Merge user options with defaults
|
||||
|
||||
// Selectors and variables
|
||||
var isNum = Object.prototype.toString.call(anchor) === '[object Number]' ? true : false;
|
||||
var anchorElem = isNum || !anchor.tagName ? null : anchor;
|
||||
if (!isNum && !anchorElem) return;
|
||||
var startLocation = window.pageYOffset; // Current location on the page
|
||||
if (animateSettings.header && !fixedHeader) {
|
||||
// Get the fixed header if not already set
|
||||
fixedHeader = document.querySelector(animateSettings.header);
|
||||
}
|
||||
if (!headerHeight) {
|
||||
// Get the height of a fixed header if one exists and not already set
|
||||
headerHeight = getHeaderHeight(fixedHeader);
|
||||
}
|
||||
var endLocation = isNum ? anchor : getEndLocation(anchorElem, headerHeight, parseInt((typeof animateSettings.offset === 'function' ? animateSettings.offset(anchor, toggle) : animateSettings.offset), 10), animateSettings.clip); // Location to scroll to
|
||||
var distance = endLocation - startLocation; // distance to travel
|
||||
var documentHeight = getDocumentHeight();
|
||||
var timeLapsed = 0;
|
||||
var start, percentage, position;
|
||||
|
||||
/**
|
||||
* Stop the scroll animation when it reaches its target (or the bottom/top of page)
|
||||
* @param {Number} position Current position on the page
|
||||
* @param {Number} endLocation Scroll to location
|
||||
* @param {Number} animationInterval How much to scroll on this loop
|
||||
*/
|
||||
var stopAnimateScroll = function (position, endLocation) {
|
||||
|
||||
// Get the current location
|
||||
var currentLocation = window.pageYOffset;
|
||||
|
||||
// Check if the end location has been reached yet (or we've hit the end of the document)
|
||||
if (position == endLocation || currentLocation == endLocation || ((startLocation < endLocation && window.innerHeight + currentLocation) >= documentHeight)) {
|
||||
|
||||
// Clear the animation timer
|
||||
smoothScroll.cancelScroll(true);
|
||||
|
||||
// Bring the anchored element into focus
|
||||
adjustFocus(anchor, endLocation, isNum);
|
||||
|
||||
// Emit a custom event
|
||||
emitEvent('scrollStop', animateSettings, anchor, toggle);
|
||||
|
||||
// Reset start
|
||||
start = null;
|
||||
animationInterval = null;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Loop scrolling animation
|
||||
*/
|
||||
var loopAnimateScroll = function (timestamp) {
|
||||
if (!start) { start = timestamp; }
|
||||
timeLapsed += timestamp - start;
|
||||
percentage = (timeLapsed / parseInt(animateSettings.speed, 10));
|
||||
percentage = (percentage > 1) ? 1 : percentage;
|
||||
position = startLocation + (distance * easingPattern(animateSettings, percentage));
|
||||
window.scrollTo(0, Math.floor(position));
|
||||
if (!stopAnimateScroll(position, endLocation)) {
|
||||
animationInterval = window.requestAnimationFrame(loopAnimateScroll);
|
||||
start = timestamp;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Reset position to fix weird iOS bug
|
||||
* @link https://github.com/cferdinandi/smooth-scroll/issues/45
|
||||
*/
|
||||
if (window.pageYOffset === 0) {
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
|
||||
// Update the URL
|
||||
updateURL(anchor, isNum, animateSettings);
|
||||
|
||||
// Emit a custom event
|
||||
emitEvent('scrollStart', animateSettings, anchor, toggle);
|
||||
|
||||
// Start scrolling animation
|
||||
smoothScroll.cancelScroll(true);
|
||||
window.requestAnimationFrame(loopAnimateScroll);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* If smooth scroll element clicked, animate scroll
|
||||
*/
|
||||
var clickHandler = function (event) {
|
||||
|
||||
// Don't run if the user prefers reduced motion
|
||||
if (reduceMotion(settings)) return;
|
||||
|
||||
// Don't run if right-click or command/control + click
|
||||
if (event.button !== 0 || event.metaKey || event.ctrlKey) return;
|
||||
|
||||
// Check if event.target has closest() method
|
||||
// By @totegi - https://github.com/cferdinandi/smooth-scroll/pull/401/
|
||||
if(!('closest' in event.target))return;
|
||||
|
||||
// Check if a smooth scroll link was clicked
|
||||
toggle = event.target.closest(selector);
|
||||
if (!toggle || toggle.tagName.toLowerCase() !== 'a' || event.target.closest(settings.ignore)) return;
|
||||
|
||||
// Only run if link is an anchor and points to the current page
|
||||
if (toggle.hostname !== window.location.hostname || toggle.pathname !== window.location.pathname || !/#/.test(toggle.href)) return;
|
||||
|
||||
// Get an escaped version of the hash
|
||||
var hash = escapeCharacters(decode(toggle.hash));
|
||||
|
||||
// Get the anchored element
|
||||
var anchor = settings.topOnEmptyHash && hash === '#' ? document.documentElement : document.querySelector(hash);
|
||||
anchor = !anchor && hash === '#top' ? document.documentElement : anchor;
|
||||
|
||||
// If anchored element exists, scroll to it
|
||||
if (!anchor) return;
|
||||
event.preventDefault();
|
||||
smoothScroll.animateScroll(anchor, toggle);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Animate scroll on popstate events
|
||||
*/
|
||||
var popstateHandler = function (event) {
|
||||
|
||||
// Only run if state is a popstate record for this instantiation
|
||||
if (!history.state.smoothScroll || history.state.smoothScroll !== JSON.stringify(settings)) return;
|
||||
|
||||
// Only run if state includes an anchor
|
||||
if (!history.state.anchor) return;
|
||||
|
||||
// Get the anchor
|
||||
var anchor = document.querySelector(escapeCharacters(decode(history.state.anchor)));
|
||||
if (!anchor) return;
|
||||
|
||||
// Animate scroll to anchor link
|
||||
smoothScroll.animateScroll(anchor, null, {updateURL: false});
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* On window scroll and resize, only run events at a rate of 15fps for better performance
|
||||
*/
|
||||
var resizeThrottler = function (event) {
|
||||
if (!eventTimeout) {
|
||||
eventTimeout = setTimeout(function() {
|
||||
eventTimeout = null; // Reset timeout
|
||||
headerHeight = getHeaderHeight(fixedHeader); // Get the height of a fixed header if one exists
|
||||
}, 66);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Destroy the current initialization.
|
||||
*/
|
||||
smoothScroll.destroy = function () {
|
||||
|
||||
// If plugin isn't already initialized, stop
|
||||
if (!settings) return;
|
||||
|
||||
// Remove event listeners
|
||||
document.removeEventListener('click', clickHandler, false);
|
||||
window.removeEventListener('resize', resizeThrottler, false);
|
||||
window.removeEventListener('popstate', popstateHandler, false);
|
||||
|
||||
// Cancel any scrolls-in-progress
|
||||
smoothScroll.cancelScroll();
|
||||
|
||||
// Reset variables
|
||||
settings = null;
|
||||
anchor = null;
|
||||
toggle = null;
|
||||
fixedHeader = null;
|
||||
headerHeight = null;
|
||||
eventTimeout = null;
|
||||
animationInterval = null;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize Smooth Scroll
|
||||
* @param {Object} options User settings
|
||||
*/
|
||||
smoothScroll.init = function (options) {
|
||||
|
||||
// feature test
|
||||
if (!supports()) throw 'Smooth Scroll: This browser does not support the required JavaScript methods and browser APIs.';
|
||||
|
||||
// Destroy any existing initializations
|
||||
smoothScroll.destroy();
|
||||
|
||||
// Selectors and variables
|
||||
settings = extend(defaults, options || {}); // Merge user options with defaults
|
||||
fixedHeader = settings.header ? document.querySelector(settings.header) : null; // Get the fixed header
|
||||
headerHeight = getHeaderHeight(fixedHeader);
|
||||
|
||||
// When a toggle is clicked, run the click handler
|
||||
document.addEventListener('click', clickHandler, false);
|
||||
|
||||
// If window is resized and there's a fixed header, recalculate its size
|
||||
if (fixedHeader) {
|
||||
window.addEventListener('resize', resizeThrottler, false);
|
||||
}
|
||||
|
||||
// If updateURL and popState are enabled, listen for pop events
|
||||
if (settings.updateURL && settings.popstate) {
|
||||
window.addEventListener('popstate', popstateHandler, false);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Initialize plugin
|
||||
//
|
||||
|
||||
smoothScroll.init(options);
|
||||
|
||||
|
||||
//
|
||||
// Public APIs
|
||||
//
|
||||
|
||||
return smoothScroll;
|
||||
|
||||
};
|
||||
|
||||
return SmoothScroll;
|
||||
|
||||
});
|
||||
@@ -0,0 +1,270 @@
|
||||
// Generated by CoffeeScript 1.6.2
|
||||
/**
|
||||
@license Sticky-kit v1.1.3 | MIT | Leaf Corcoran 2015 | http://leafo.net
|
||||
*/
|
||||
|
||||
|
||||
(function() {
|
||||
var $, win;
|
||||
|
||||
$ = this.jQuery || window.jQuery;
|
||||
|
||||
win = $(window);
|
||||
|
||||
$.fn.stick_in_parent = function(opts) {
|
||||
var doc, elm, enable_bottoming, inner_scrolling, manual_spacer, offset_top, outer_width, parent_selector, recalc_every, sticky_class, _fn, _i, _len;
|
||||
|
||||
if (opts == null) {
|
||||
opts = {};
|
||||
}
|
||||
sticky_class = opts.sticky_class, inner_scrolling = opts.inner_scrolling, recalc_every = opts.recalc_every, parent_selector = opts.parent, offset_top = opts.offset_top, manual_spacer = opts.spacer, enable_bottoming = opts.bottoming;
|
||||
if (offset_top == null) {
|
||||
offset_top = 0;
|
||||
}
|
||||
if (parent_selector == null) {
|
||||
parent_selector = void 0;
|
||||
}
|
||||
if (inner_scrolling == null) {
|
||||
inner_scrolling = true;
|
||||
}
|
||||
if (sticky_class == null) {
|
||||
sticky_class = "is_stuck";
|
||||
}
|
||||
doc = $(document);
|
||||
if (enable_bottoming == null) {
|
||||
enable_bottoming = true;
|
||||
}
|
||||
outer_width = function(el) {
|
||||
var computed, w, _el;
|
||||
|
||||
if (window.getComputedStyle) {
|
||||
_el = el[0];
|
||||
computed = window.getComputedStyle(el[0]);
|
||||
w = parseFloat(computed.getPropertyValue("width")) + parseFloat(computed.getPropertyValue("margin-left")) + parseFloat(computed.getPropertyValue("margin-right"));
|
||||
if (computed.getPropertyValue("box-sizing") !== "border-box") {
|
||||
w += parseFloat(computed.getPropertyValue("border-left-width")) + parseFloat(computed.getPropertyValue("border-right-width")) + parseFloat(computed.getPropertyValue("padding-left")) + parseFloat(computed.getPropertyValue("padding-right"));
|
||||
}
|
||||
return w;
|
||||
} else {
|
||||
return el.outerWidth(true);
|
||||
}
|
||||
};
|
||||
_fn = function(elm, padding_bottom, parent_top, parent_height, top, height, el_float, detached) {
|
||||
var bottomed, detach, fixed, last_pos, last_scroll_height, offset, parent, recalc, recalc_and_tick, recalc_counter, spacer, tick;
|
||||
|
||||
if (elm.data("sticky_kit")) {
|
||||
return;
|
||||
}
|
||||
elm.data("sticky_kit", true);
|
||||
last_scroll_height = doc.height();
|
||||
parent = elm.parent();
|
||||
if (parent_selector != null) {
|
||||
parent = parent.closest(parent_selector);
|
||||
}
|
||||
if (!parent.length) {
|
||||
throw "failed to find stick parent";
|
||||
}
|
||||
fixed = false;
|
||||
bottomed = false;
|
||||
spacer = manual_spacer != null ? manual_spacer && elm.closest(manual_spacer) : $("<div />");
|
||||
if (spacer) {
|
||||
spacer.css('position', elm.css('position'));
|
||||
}
|
||||
recalc = function() {
|
||||
var border_top, padding_top, restore;
|
||||
|
||||
if (detached) {
|
||||
return;
|
||||
}
|
||||
last_scroll_height = doc.height();
|
||||
border_top = parseInt(parent.css("border-top-width"), 10);
|
||||
padding_top = parseInt(parent.css("padding-top"), 10);
|
||||
padding_bottom = parseInt(parent.css("padding-bottom"), 10);
|
||||
parent_top = parent.offset().top + border_top + padding_top;
|
||||
parent_height = parent.height();
|
||||
if (fixed) {
|
||||
fixed = false;
|
||||
bottomed = false;
|
||||
if (manual_spacer == null) {
|
||||
elm.insertAfter(spacer);
|
||||
spacer.detach();
|
||||
}
|
||||
elm.css({
|
||||
position: "",
|
||||
top: "",
|
||||
width: "",
|
||||
bottom: ""
|
||||
}).removeClass(sticky_class);
|
||||
restore = true;
|
||||
}
|
||||
top = elm.offset().top - (parseInt(elm.css("margin-top"), 10) || 0) - offset_top;
|
||||
height = elm.outerHeight(true);
|
||||
el_float = elm.css("float");
|
||||
if (spacer) {
|
||||
spacer.css({
|
||||
width: outer_width(elm),
|
||||
height: height,
|
||||
display: elm.css("display"),
|
||||
"vertical-align": elm.css("vertical-align"),
|
||||
"float": el_float
|
||||
});
|
||||
}
|
||||
if (restore) {
|
||||
return tick();
|
||||
}
|
||||
};
|
||||
recalc();
|
||||
if (height === parent_height) {
|
||||
return;
|
||||
}
|
||||
last_pos = void 0;
|
||||
offset = offset_top;
|
||||
recalc_counter = recalc_every;
|
||||
tick = function() {
|
||||
var css, delta, recalced, scroll, will_bottom, win_height;
|
||||
|
||||
if (detached) {
|
||||
return;
|
||||
}
|
||||
recalced = false;
|
||||
if (recalc_counter != null) {
|
||||
recalc_counter -= 1;
|
||||
if (recalc_counter <= 0) {
|
||||
recalc_counter = recalc_every;
|
||||
recalc();
|
||||
recalced = true;
|
||||
}
|
||||
}
|
||||
if (!recalced && doc.height() !== last_scroll_height) {
|
||||
recalc();
|
||||
recalced = true;
|
||||
}
|
||||
scroll = win.scrollTop();
|
||||
if (last_pos != null) {
|
||||
delta = scroll - last_pos;
|
||||
}
|
||||
last_pos = scroll;
|
||||
if (fixed) {
|
||||
if (enable_bottoming) {
|
||||
will_bottom = scroll + height + offset > parent_height + parent_top;
|
||||
if (bottomed && !will_bottom) {
|
||||
bottomed = false;
|
||||
elm.css({
|
||||
position: "fixed",
|
||||
bottom: "",
|
||||
top: offset
|
||||
}).trigger("sticky_kit:unbottom");
|
||||
}
|
||||
}
|
||||
if (scroll < top) {
|
||||
fixed = false;
|
||||
offset = offset_top;
|
||||
if (manual_spacer == null) {
|
||||
if (el_float === "left" || el_float === "right") {
|
||||
elm.insertAfter(spacer);
|
||||
}
|
||||
spacer.detach();
|
||||
}
|
||||
css = {
|
||||
position: "",
|
||||
width: "",
|
||||
top: ""
|
||||
};
|
||||
elm.css(css).removeClass(sticky_class).trigger("sticky_kit:unstick");
|
||||
}
|
||||
if (inner_scrolling) {
|
||||
win_height = win.height();
|
||||
if (height + offset_top > win_height) {
|
||||
if (!bottomed) {
|
||||
offset -= delta;
|
||||
offset = Math.max(win_height - height, offset);
|
||||
offset = Math.min(offset_top, offset);
|
||||
if (fixed) {
|
||||
elm.css({
|
||||
top: offset + "px"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (scroll > top) {
|
||||
fixed = true;
|
||||
css = {
|
||||
position: "fixed",
|
||||
top: offset
|
||||
};
|
||||
css.width = elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px";
|
||||
elm.css(css).addClass(sticky_class);
|
||||
if (manual_spacer == null) {
|
||||
elm.after(spacer);
|
||||
if (el_float === "left" || el_float === "right") {
|
||||
spacer.append(elm);
|
||||
}
|
||||
}
|
||||
elm.trigger("sticky_kit:stick");
|
||||
}
|
||||
}
|
||||
if (fixed && enable_bottoming) {
|
||||
if (will_bottom == null) {
|
||||
will_bottom = scroll + height + offset > parent_height + parent_top;
|
||||
}
|
||||
if (!bottomed && will_bottom) {
|
||||
bottomed = true;
|
||||
if (parent.css("position") === "static") {
|
||||
parent.css({
|
||||
position: "relative"
|
||||
});
|
||||
}
|
||||
return elm.css({
|
||||
position: "absolute",
|
||||
bottom: padding_bottom,
|
||||
top: "auto"
|
||||
}).trigger("sticky_kit:bottom");
|
||||
}
|
||||
}
|
||||
};
|
||||
recalc_and_tick = function() {
|
||||
recalc();
|
||||
return tick();
|
||||
};
|
||||
detach = function() {
|
||||
detached = true;
|
||||
win.off("touchmove", tick);
|
||||
win.off("scroll", tick);
|
||||
win.off("resize", recalc_and_tick);
|
||||
$(document.body).off("sticky_kit:recalc", recalc_and_tick);
|
||||
elm.off("sticky_kit:detach", detach);
|
||||
elm.removeData("sticky_kit");
|
||||
elm.css({
|
||||
position: "",
|
||||
bottom: "",
|
||||
top: "",
|
||||
width: ""
|
||||
});
|
||||
parent.position("position", "");
|
||||
if (fixed) {
|
||||
if (manual_spacer == null) {
|
||||
if (el_float === "left" || el_float === "right") {
|
||||
elm.insertAfter(spacer);
|
||||
}
|
||||
spacer.remove();
|
||||
}
|
||||
return elm.removeClass(sticky_class);
|
||||
}
|
||||
};
|
||||
win.on("touchmove", tick);
|
||||
win.on("scroll", tick);
|
||||
win.on("resize", recalc_and_tick);
|
||||
$(document.body).on("sticky_kit:recalc", recalc_and_tick);
|
||||
elm.on("sticky_kit:detach", detach);
|
||||
return setTimeout(tick, 0);
|
||||
};
|
||||
for (_i = 0, _len = this.length; _i < _len; _i++) {
|
||||
elm = this[_i];
|
||||
_fn($(elm));
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
@@ -0,0 +1,611 @@
|
||||
/* =============================================================
|
||||
* bootstrap3-typeahead.js v4.0.2
|
||||
* https://github.com/bassjobsen/Bootstrap-3-Typeahead
|
||||
* =============================================================
|
||||
* Original written by @mdo and @fat
|
||||
* =============================================================
|
||||
* Copyright 2014 Bass Jobsen @bassjobsen
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ============================================================ */
|
||||
|
||||
|
||||
(function (root, factory) {
|
||||
|
||||
'use strict';
|
||||
|
||||
// CommonJS module is defined
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = factory(require('jquery'));
|
||||
}
|
||||
// AMD module is defined
|
||||
else if (typeof define === 'function' && define.amd) {
|
||||
define(['jquery'], function ($) {
|
||||
return factory ($);
|
||||
});
|
||||
} else {
|
||||
factory(root.jQuery);
|
||||
}
|
||||
|
||||
}(this, function ($) {
|
||||
|
||||
'use strict';
|
||||
// jshint laxcomma: true
|
||||
|
||||
|
||||
/* TYPEAHEAD PUBLIC CLASS DEFINITION
|
||||
* ================================= */
|
||||
|
||||
var Typeahead = function (element, options) {
|
||||
this.$element = $(element);
|
||||
this.options = $.extend({}, Typeahead.defaults, options);
|
||||
this.matcher = this.options.matcher || this.matcher;
|
||||
this.sorter = this.options.sorter || this.sorter;
|
||||
this.select = this.options.select || this.select;
|
||||
this.autoSelect = typeof this.options.autoSelect == 'boolean' ? this.options.autoSelect : true;
|
||||
this.highlighter = this.options.highlighter || this.highlighter;
|
||||
this.render = this.options.render || this.render;
|
||||
this.updater = this.options.updater || this.updater;
|
||||
this.displayText = this.options.displayText || this.displayText;
|
||||
this.source = this.options.source;
|
||||
this.delay = this.options.delay;
|
||||
this.$menu = $(this.options.menu);
|
||||
this.$appendTo = this.options.appendTo ? $(this.options.appendTo) : null;
|
||||
this.fitToElement = typeof this.options.fitToElement == 'boolean' ? this.options.fitToElement : false;
|
||||
this.shown = false;
|
||||
this.listen();
|
||||
this.showHintOnFocus = typeof this.options.showHintOnFocus == 'boolean' || this.options.showHintOnFocus === "all" ? this.options.showHintOnFocus : false;
|
||||
this.afterSelect = this.options.afterSelect;
|
||||
this.addItem = false;
|
||||
this.value = this.$element.val() || this.$element.text();
|
||||
this.keyPressed = false;
|
||||
};
|
||||
|
||||
Typeahead.prototype = {
|
||||
|
||||
constructor: Typeahead,
|
||||
|
||||
select: function () {
|
||||
var val = this.$menu.find('.active').data('value');
|
||||
this.$element.data('active', val);
|
||||
if (this.autoSelect || val) {
|
||||
var newVal = this.updater(val);
|
||||
// Updater can be set to any random functions via "options" parameter in constructor above.
|
||||
// Add null check for cases when updater returns void or undefined.
|
||||
if (!newVal) {
|
||||
newVal = '';
|
||||
}
|
||||
this.$element
|
||||
.val(this.displayText(newVal) || newVal)
|
||||
.text(this.displayText(newVal) || newVal)
|
||||
.change();
|
||||
this.afterSelect(newVal);
|
||||
}
|
||||
return this.hide();
|
||||
},
|
||||
|
||||
updater: function (item) {
|
||||
return item;
|
||||
},
|
||||
|
||||
setSource: function (source) {
|
||||
this.source = source;
|
||||
},
|
||||
|
||||
show: function () {
|
||||
var pos = $.extend({}, this.$element.position(), {
|
||||
height: this.$element[0].offsetHeight
|
||||
});
|
||||
|
||||
var scrollHeight = typeof this.options.scrollHeight == 'function' ?
|
||||
this.options.scrollHeight.call() :
|
||||
this.options.scrollHeight;
|
||||
|
||||
var element;
|
||||
if (this.shown) {
|
||||
element = this.$menu;
|
||||
} else if (this.$appendTo) {
|
||||
element = this.$menu.appendTo(this.$appendTo);
|
||||
this.hasSameParent = this.$appendTo.is(this.$element.parent());
|
||||
} else {
|
||||
element = this.$menu.insertAfter(this.$element);
|
||||
this.hasSameParent = true;
|
||||
}
|
||||
|
||||
if (!this.hasSameParent) {
|
||||
// We cannot rely on the element position, need to position relative to the window
|
||||
element.css("position", "fixed");
|
||||
var offset = this.$element.offset();
|
||||
pos.top = offset.top;
|
||||
pos.left = offset.left;
|
||||
}
|
||||
// The rules for bootstrap are: 'dropup' in the parent and 'dropdown-menu-right' in the element.
|
||||
// Note that to get right alignment, you'll need to specify `menu` in the options to be:
|
||||
// '<ul class="typeahead dropdown-menu" role="listbox"></ul>'
|
||||
var dropup = $(element).parent().hasClass('dropup');
|
||||
var newTop = dropup ? 'auto' : (pos.top + pos.height + scrollHeight);
|
||||
var right = $(element).hasClass('dropdown-menu-right');
|
||||
var newLeft = right ? 'auto' : pos.left;
|
||||
// it seems like setting the css is a bad idea (just let Bootstrap do it), but I'll keep the old
|
||||
// logic in place except for the dropup/right-align cases.
|
||||
element.css({ top: newTop, left: newLeft }).show();
|
||||
|
||||
if (this.options.fitToElement === true) {
|
||||
element.css("width", this.$element.outerWidth() + "px");
|
||||
}
|
||||
|
||||
this.shown = true;
|
||||
return this;
|
||||
},
|
||||
|
||||
hide: function () {
|
||||
this.$menu.hide();
|
||||
this.shown = false;
|
||||
return this;
|
||||
},
|
||||
|
||||
lookup: function (query) {
|
||||
var items;
|
||||
if (typeof(query) != 'undefined' && query !== null) {
|
||||
this.query = query;
|
||||
} else {
|
||||
this.query = this.$element.val() || this.$element.text() || '';
|
||||
}
|
||||
|
||||
if (this.query.length < this.options.minLength && !this.options.showHintOnFocus) {
|
||||
return this.shown ? this.hide() : this;
|
||||
}
|
||||
|
||||
var worker = $.proxy(function () {
|
||||
|
||||
// Bloodhound (since 0.11) needs three arguments.
|
||||
// Two of them are callback functions (sync and async) for local and remote data processing
|
||||
// see https://github.com/twitter/typeahead.js/blob/master/src/bloodhound/bloodhound.js#L132
|
||||
if ($.isFunction(this.source) && this.source.length === 3) {
|
||||
this.source(this.query, $.proxy(this.process, this), $.proxy(this.process, this));
|
||||
} else if ($.isFunction(this.source)) {
|
||||
this.source(this.query, $.proxy(this.process, this));
|
||||
} else if (this.source) {
|
||||
this.process(this.source);
|
||||
}
|
||||
}, this);
|
||||
|
||||
clearTimeout(this.lookupWorker);
|
||||
this.lookupWorker = setTimeout(worker, this.delay);
|
||||
},
|
||||
|
||||
process: function (items) {
|
||||
var that = this;
|
||||
|
||||
items = $.grep(items, function (item) {
|
||||
return that.matcher(item);
|
||||
});
|
||||
|
||||
items = this.sorter(items);
|
||||
|
||||
if (!items.length && !this.options.addItem) {
|
||||
return this.shown ? this.hide() : this;
|
||||
}
|
||||
|
||||
if (items.length > 0) {
|
||||
this.$element.data('active', items[0]);
|
||||
} else {
|
||||
this.$element.data('active', null);
|
||||
}
|
||||
|
||||
if (this.options.items != 'all') {
|
||||
items = items.slice(0, this.options.items);
|
||||
}
|
||||
|
||||
// Add item
|
||||
if (this.options.addItem){
|
||||
items.push(this.options.addItem);
|
||||
}
|
||||
|
||||
return this.render(items).show();
|
||||
},
|
||||
|
||||
matcher: function (item) {
|
||||
var it = this.displayText(item);
|
||||
return ~it.toLowerCase().indexOf(this.query.toLowerCase());
|
||||
},
|
||||
|
||||
sorter: function (items) {
|
||||
var beginswith = [];
|
||||
var caseSensitive = [];
|
||||
var caseInsensitive = [];
|
||||
var item;
|
||||
|
||||
while ((item = items.shift())) {
|
||||
var it = this.displayText(item);
|
||||
if (!it.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item);
|
||||
else if (~it.indexOf(this.query)) caseSensitive.push(item);
|
||||
else caseInsensitive.push(item);
|
||||
}
|
||||
|
||||
return beginswith.concat(caseSensitive, caseInsensitive);
|
||||
},
|
||||
|
||||
highlighter: function (item) {
|
||||
var text = this.query;
|
||||
if(text===""){
|
||||
return item;
|
||||
}
|
||||
var matches = item.match(/(>)([^<]*)(<)/g);
|
||||
var first = [];
|
||||
var second = [];
|
||||
var i;
|
||||
if(matches && matches.length){
|
||||
//html
|
||||
for (i = 0; i < matches.length; ++i) {
|
||||
if (matches[i].length > 2) {//escape '><'
|
||||
first.push(matches[i]);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
//text
|
||||
first = [];
|
||||
first.push(item);
|
||||
}
|
||||
text = text.replace((/[\(\)\/\.\*\+\?\[\]]/g), function(mat) {
|
||||
return '\\' + mat;
|
||||
});
|
||||
var reg = new RegExp(text, "g");
|
||||
var m;
|
||||
for (i = 0; i < first.length; ++i) {
|
||||
m = first[i].match(reg);
|
||||
if(m && m.length>0){//find all text nodes matches
|
||||
second.push(first[i]);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < second.length; ++i) {
|
||||
item = item.replace(second[i],second[i].replace(reg, '<strong>تومان&</strong>'));
|
||||
}
|
||||
return item;
|
||||
},
|
||||
|
||||
render: function (items) {
|
||||
var that = this;
|
||||
var self = this;
|
||||
var activeFound = false;
|
||||
var data = [];
|
||||
var _category = that.options.separator;
|
||||
|
||||
$.each(items, function (key,value) {
|
||||
// inject separator
|
||||
if (key > 0 && value[_category] !== items[key - 1][_category]){
|
||||
data.push({
|
||||
__type: 'divider'
|
||||
});
|
||||
}
|
||||
|
||||
// inject category header
|
||||
if (value[_category] && (key === 0 || value[_category] !== items[key - 1][_category])){
|
||||
data.push({
|
||||
__type: 'category',
|
||||
name: value[_category]
|
||||
});
|
||||
}
|
||||
data.push(value);
|
||||
});
|
||||
|
||||
items = $(data).map(function (i, item) {
|
||||
if ((item.__type || false) == 'category'){
|
||||
return $(that.options.headerHtml).text(item.name)[0];
|
||||
}
|
||||
|
||||
if ((item.__type || false) == 'divider'){
|
||||
return $(that.options.headerDivider)[0];
|
||||
}
|
||||
|
||||
var text = self.displayText(item);
|
||||
i = $(that.options.item).data('value', item);
|
||||
i.find('a').html(that.highlighter(text, item));
|
||||
if (text == self.$element.val()) {
|
||||
i.addClass('active');
|
||||
self.$element.data('active', item);
|
||||
activeFound = true;
|
||||
}
|
||||
return i[0];
|
||||
});
|
||||
|
||||
if (this.autoSelect && !activeFound) {
|
||||
items.filter(':not(.dropdown-header)').first().addClass('active');
|
||||
this.$element.data('active', items.first().data('value'));
|
||||
}
|
||||
this.$menu.html(items);
|
||||
return this;
|
||||
},
|
||||
|
||||
displayText: function (item) {
|
||||
return typeof item !== 'undefined' && typeof item.name != 'undefined' ? item.name : item;
|
||||
},
|
||||
|
||||
next: function (event) {
|
||||
var active = this.$menu.find('.active').removeClass('active');
|
||||
var next = active.next();
|
||||
|
||||
if (!next.length) {
|
||||
next = $(this.$menu.find('li')[0]);
|
||||
}
|
||||
|
||||
next.addClass('active');
|
||||
// added for screen reader
|
||||
this.$element.val(next.text());
|
||||
},
|
||||
|
||||
prev: function (event) {
|
||||
var active = this.$menu.find('.active').removeClass('active');
|
||||
var prev = active.prev();
|
||||
|
||||
if (!prev.length) {
|
||||
prev = this.$menu.find('li').last();
|
||||
}
|
||||
|
||||
prev.addClass('active');
|
||||
// added for screen reader
|
||||
this.$element.val(prev.text());
|
||||
},
|
||||
|
||||
listen: function () {
|
||||
this.$element
|
||||
.on('focus', $.proxy(this.focus, this))
|
||||
.on('blur', $.proxy(this.blur, this))
|
||||
.on('keypress', $.proxy(this.keypress, this))
|
||||
.on('propertychange input', $.proxy(this.input, this))
|
||||
.on('keyup', $.proxy(this.keyup, this));
|
||||
|
||||
if (this.eventSupported('keydown')) {
|
||||
this.$element.on('keydown', $.proxy(this.keydown, this));
|
||||
}
|
||||
|
||||
this.$menu
|
||||
.on('click', $.proxy(this.click, this))
|
||||
.on('mouseenter', 'li', $.proxy(this.mouseenter, this))
|
||||
.on('mouseleave', 'li', $.proxy(this.mouseleave, this))
|
||||
.on('mousedown', $.proxy(this.mousedown,this));
|
||||
},
|
||||
|
||||
destroy : function () {
|
||||
this.$element.data('typeahead',null);
|
||||
this.$element.data('active',null);
|
||||
this.$element
|
||||
.off('focus')
|
||||
.off('blur')
|
||||
.off('keypress')
|
||||
.off('propertychange input')
|
||||
.off('keyup');
|
||||
|
||||
if (this.eventSupported('keydown')) {
|
||||
this.$element.off('keydown');
|
||||
}
|
||||
|
||||
this.$menu.remove();
|
||||
this.destroyed = true;
|
||||
},
|
||||
|
||||
eventSupported: function (eventName) {
|
||||
var isSupported = eventName in this.$element;
|
||||
if (!isSupported) {
|
||||
this.$element.setAttribute(eventName, 'return;');
|
||||
isSupported = typeof this.$element[eventName] === 'function';
|
||||
}
|
||||
return isSupported;
|
||||
},
|
||||
|
||||
move: function (e) {
|
||||
if (!this.shown) return;
|
||||
|
||||
switch (e.keyCode) {
|
||||
case 9: // tab
|
||||
case 13: // enter
|
||||
case 27: // escape
|
||||
e.preventDefault();
|
||||
break;
|
||||
|
||||
case 38: // up arrow
|
||||
// with the shiftKey (this is actually the left parenthesis)
|
||||
if (e.shiftKey) return;
|
||||
e.preventDefault();
|
||||
this.prev();
|
||||
break;
|
||||
|
||||
case 40: // down arrow
|
||||
// with the shiftKey (this is actually the right parenthesis)
|
||||
if (e.shiftKey) return;
|
||||
e.preventDefault();
|
||||
this.next();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
keydown: function (e) {
|
||||
this.keyPressed = true;
|
||||
this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27]);
|
||||
if (!this.shown && e.keyCode == 40) {
|
||||
this.lookup();
|
||||
} else {
|
||||
this.move(e);
|
||||
}
|
||||
},
|
||||
|
||||
keypress: function (e) {
|
||||
if (this.suppressKeyPressRepeat) return;
|
||||
this.move(e);
|
||||
},
|
||||
|
||||
input: function (e) {
|
||||
// This is a fixed for IE10/11 that fires the input event when a placehoder is changed
|
||||
// (https://connect.microsoft.com/IE/feedback/details/810538/ie-11-fires-input-event-on-focus)
|
||||
var currentValue = this.$element.val() || this.$element.text();
|
||||
if (this.value !== currentValue) {
|
||||
this.value = currentValue;
|
||||
this.lookup();
|
||||
}
|
||||
},
|
||||
|
||||
keyup: function (e) {
|
||||
if (this.destroyed) {
|
||||
return;
|
||||
}
|
||||
switch (e.keyCode) {
|
||||
case 40: // down arrow
|
||||
case 38: // up arrow
|
||||
case 16: // shift
|
||||
case 17: // ctrl
|
||||
case 18: // alt
|
||||
break;
|
||||
|
||||
case 9: // tab
|
||||
if (!this.shown || (this.showHintOnFocus && !this.keyPressed)) return;
|
||||
this.select();
|
||||
break;
|
||||
case 13: // enter
|
||||
if (!this.shown) return;
|
||||
this.select();
|
||||
break;
|
||||
|
||||
case 27: // escape
|
||||
if (!this.shown) return;
|
||||
this.hide();
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
focus: function (e) {
|
||||
if (!this.focused) {
|
||||
this.focused = true;
|
||||
this.keyPressed = false;
|
||||
if (this.options.showHintOnFocus && this.skipShowHintOnFocus !== true) {
|
||||
if(this.options.showHintOnFocus === "all") {
|
||||
this.lookup("");
|
||||
} else {
|
||||
this.lookup();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.skipShowHintOnFocus) {
|
||||
this.skipShowHintOnFocus = false;
|
||||
}
|
||||
},
|
||||
|
||||
blur: function (e) {
|
||||
if (!this.mousedover && !this.mouseddown && this.shown) {
|
||||
this.hide();
|
||||
this.focused = false;
|
||||
this.keyPressed = false;
|
||||
} else if (this.mouseddown) {
|
||||
// This is for IE that blurs the input when user clicks on scroll.
|
||||
// We set the focus back on the input and prevent the lookup to occur again
|
||||
this.skipShowHintOnFocus = true;
|
||||
this.$element.focus();
|
||||
this.mouseddown = false;
|
||||
}
|
||||
},
|
||||
|
||||
click: function (e) {
|
||||
e.preventDefault();
|
||||
this.skipShowHintOnFocus = true;
|
||||
this.select();
|
||||
this.$element.focus();
|
||||
this.hide();
|
||||
},
|
||||
|
||||
mouseenter: function (e) {
|
||||
this.mousedover = true;
|
||||
this.$menu.find('.active').removeClass('active');
|
||||
$(e.currentTarget).addClass('active');
|
||||
},
|
||||
|
||||
mouseleave: function (e) {
|
||||
this.mousedover = false;
|
||||
if (!this.focused && this.shown) this.hide();
|
||||
},
|
||||
|
||||
/**
|
||||
* We track the mousedown for IE. When clicking on the menu scrollbar, IE makes the input blur thus hiding the menu.
|
||||
*/
|
||||
mousedown: function (e) {
|
||||
this.mouseddown = true;
|
||||
this.$menu.one("mouseup", function(e){
|
||||
// IE won't fire this, but FF and Chrome will so we reset our flag for them here
|
||||
this.mouseddown = false;
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* TYPEAHEAD PLUGIN DEFINITION
|
||||
* =========================== */
|
||||
|
||||
var old = $.fn.typeahead;
|
||||
|
||||
$.fn.typeahead = function (option) {
|
||||
var arg = arguments;
|
||||
if (typeof option == 'string' && option == 'getActive') {
|
||||
return this.data('active');
|
||||
}
|
||||
return this.each(function () {
|
||||
var $this = $(this);
|
||||
var data = $this.data('typeahead');
|
||||
var options = typeof option == 'object' && option;
|
||||
if (!data) $this.data('typeahead', (data = new Typeahead(this, options)));
|
||||
if (typeof option == 'string' && data[option]) {
|
||||
if (arg.length > 1) {
|
||||
data[option].apply(data, Array.prototype.slice.call(arg, 1));
|
||||
} else {
|
||||
data[option]();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Typeahead.defaults = {
|
||||
source: [],
|
||||
items: 8,
|
||||
menu: '<ul class="typeahead dropdown-menu" role="listbox"></ul>',
|
||||
item: '<li><a class="dropdown-item" href="#" role="option"></a></li>',
|
||||
minLength: 1,
|
||||
scrollHeight: 0,
|
||||
autoSelect: true,
|
||||
afterSelect: $.noop,
|
||||
addItem: false,
|
||||
delay: 0,
|
||||
separator: 'category',
|
||||
headerHtml: '<li class="dropdown-header"></li>',
|
||||
headerDivider: '<li class="divider" role="separator"></li>'
|
||||
};
|
||||
|
||||
$.fn.typeahead.Constructor = Typeahead;
|
||||
|
||||
/* TYPEAHEAD NO CONFLICT
|
||||
* =================== */
|
||||
|
||||
$.fn.typeahead.noConflict = function () {
|
||||
$.fn.typeahead = old;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/* TYPEAHEAD DATA-API
|
||||
* ================== */
|
||||
|
||||
$(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
|
||||
var $this = $(this);
|
||||
if ($this.data('typeahead')) return;
|
||||
$this.typeahead($this.data());
|
||||
});
|
||||
|
||||
}));
|
||||
@@ -0,0 +1,197 @@
|
||||
;( function( $, window, document, undefined ) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var pluginName = "windowScrollAction",
|
||||
defaults = {
|
||||
offset: 0.25
|
||||
},
|
||||
_wsa,
|
||||
_$window,
|
||||
_blur = 30,
|
||||
_scale = 1.1,
|
||||
_mob_breakpoint = 992;
|
||||
|
||||
// The actual plugin constructor
|
||||
function Plugin ( element, options ) {
|
||||
_wsa = this;
|
||||
_wsa.element = element;
|
||||
_wsa.$el = $(element);
|
||||
_$window = $(window);
|
||||
_wsa.settings = $.extend( {}, defaults, options );
|
||||
_wsa._defaults = defaults;
|
||||
_wsa._name = pluginName;
|
||||
_wsa.init();
|
||||
}
|
||||
|
||||
$.extend( Plugin.prototype, {
|
||||
|
||||
init: function() {
|
||||
if(_$window.width() > _mob_breakpoint) {
|
||||
_wsa.start();
|
||||
}
|
||||
},
|
||||
|
||||
start: function() {
|
||||
_wsa.$parent = _wsa.$el.parent();
|
||||
_wsa.parentHeight = _wsa.$parent.height();
|
||||
_wsa.elOffset = _wsa.parentHeight * _wsa.settings.offset;
|
||||
_wsa.parentOffset = _wsa.$parent.offset().top;
|
||||
|
||||
_wsa.useScale = false;
|
||||
_wsa.useBlur = false;
|
||||
_wsa.blur = _wsa.$el.data('blur');
|
||||
_wsa.scale = _wsa.$el.data('scale');
|
||||
_wsa.parallax = _wsa.$el.data('parallax');
|
||||
_wsa.initScaleValue = 1.05;
|
||||
|
||||
|
||||
|
||||
if(typeof _wsa.scale !== typeof undefined && _wsa.scale !== false) {
|
||||
_wsa.scale = parseFloat(_wsa.scale);
|
||||
_wsa.scale -= 1;
|
||||
_wsa.useScale = true;
|
||||
}
|
||||
|
||||
if(typeof _wsa.blur !== typeof undefined && _wsa.blur !== false) {
|
||||
_wsa.blur = parseFloat(_wsa.blur);
|
||||
_wsa.useBlur = true;
|
||||
}
|
||||
|
||||
if(_wsa.parallax !== true) {
|
||||
_wsa.parallax = false;
|
||||
}
|
||||
|
||||
if(_wsa.blur && !_wsa.scale) {
|
||||
_wsa.initScale = true;
|
||||
_wsa.initBlurScale();
|
||||
} else {
|
||||
_wsa.initScale = false;
|
||||
}
|
||||
|
||||
|
||||
_wsa.setDefPosision();
|
||||
_wsa.windowScroll();
|
||||
},
|
||||
|
||||
initBlurScale: function() {
|
||||
if(_wsa.parallax) {
|
||||
_wsa.$el.css(_wsa.setTransObj('translate3d(0, ' + -_wsa.elOffset +'px, 0) scale('+_wsa.initScaleValue+')'));
|
||||
} else {
|
||||
_wsa.$el.css(_wsa.setTransObj('translate3d(0, 0, 0) scale('+_wsa.initScaleValue+')'));
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
setDefPosision: function() {
|
||||
if(!_wsa.initScale) {
|
||||
_wsa.$el.css(_wsa.setTransObj('translate3d(0, ' + -_wsa.elOffset +'px, 0)'));
|
||||
}
|
||||
_wsa.$el.css('height', _wsa.parentHeight*(1+_wsa.settings.offset*2));
|
||||
},
|
||||
|
||||
windowScroll: function() {
|
||||
_wsa.fireEvent(_$window, 'scroll', function(e){
|
||||
var scroll = $(document).scrollTop(),
|
||||
scrollPx,
|
||||
scrolledP,
|
||||
blurred,
|
||||
scaled;
|
||||
|
||||
|
||||
if(scroll > _wsa.parentOffset && scroll < _wsa.parentOffset + _wsa.parentHeight) {
|
||||
|
||||
_wsa.scrolledP = 100 - (100*(_wsa.parentOffset + _wsa.parentHeight - scroll)/_wsa.parentHeight);
|
||||
_wsa.scrollPx = (scroll-_wsa.parentOffset)*(_wsa.settings.offset*2)-_wsa.elOffset;
|
||||
// console.log(_wsa.scrollPx);
|
||||
_wsa.blurScroll();
|
||||
_wsa.transformScroll();
|
||||
// _wsa.addParallax();
|
||||
} else {
|
||||
_wsa.removeBlur();
|
||||
// _wsa.removeParallax();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
addParallax: function() {
|
||||
if(_wsa.parallax) {
|
||||
_wsa.$el.addClass('bg-fixed');
|
||||
}
|
||||
},
|
||||
|
||||
removeParallax: function() {
|
||||
if(_wsa.parallax) {
|
||||
_wsa.$el.removeClass('bg-fixed');
|
||||
}
|
||||
},
|
||||
|
||||
blurScroll: function() {
|
||||
var blurred;
|
||||
if(_wsa.useBlur) {
|
||||
blurred = _wsa.blur*_wsa.scrolledP/100;
|
||||
_wsa.$el.css({
|
||||
'filter': 'blur('+blurred+'px)'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
removeBlur: function() {
|
||||
if(_wsa.useBlur) {
|
||||
_wsa.$el.css({
|
||||
'filter': 'blur(0px)'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
transformScroll: function() {
|
||||
var scaled,
|
||||
trans;
|
||||
|
||||
if(_wsa.parallax || _wsa.useScale) {
|
||||
if(_wsa.parallax && _wsa.useScale) {
|
||||
scaled = 1 + ((_wsa.scale)*_wsa.scrolledP/100);
|
||||
|
||||
trans = _wsa.setTransObj('translate3d(0, ' + _wsa.scrollPx +'px, 0) scale('+scaled+')');
|
||||
} else if(_wsa.useScale) {
|
||||
trans = _wsa.setTransObj('translate3d(0, 0, 0) scale('+scaled+')');
|
||||
} else {
|
||||
if(_wsa.initScale) {
|
||||
trans = _wsa.setTransObj('translate3d(0, ' + _wsa.scrollPx +'px, 0) scale('+_wsa.initScaleValue+')');
|
||||
} else {
|
||||
trans = _wsa.setTransObj('translate3d(0, ' + _wsa.scrollPx +'px, 0)');
|
||||
}
|
||||
}
|
||||
_wsa.$el.css(trans);
|
||||
}
|
||||
},
|
||||
|
||||
setTransObj: function(val){
|
||||
var prefixes = ['-ms-', '-webkit-', '-moz-', ''],
|
||||
transObj = {};
|
||||
for (var i = prefixes.length - 1; i >= 0; i--) {
|
||||
transObj[prefixes[i] + 'transform'] = val;
|
||||
}
|
||||
|
||||
return transObj;
|
||||
},
|
||||
|
||||
fireEvent: function(el, evt, callback) {
|
||||
el.on(evt, {_wsa: _wsa}, function(e){
|
||||
_wsa = e.data._wsa;
|
||||
callback(e);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$.fn[ pluginName ] = function( options ) {
|
||||
return this.each( function() {
|
||||
if ( !$.data( this, "plugin_" + pluginName ) ) {
|
||||
$.data( this, "plugin_" +
|
||||
pluginName, new Plugin( this, options ) );
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
} )( jQuery, window, document );
|
||||
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
* YoutubeBackground - A wrapper for the Youtube API - Great for fullscreen background videos or just regular videos.
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
*
|
||||
* Version: 1.0.5
|
||||
*
|
||||
*/
|
||||
|
||||
// Chain of Responsibility pattern. Creates base class that can be overridden.
|
||||
if (typeof Object.create !== "function") {
|
||||
Object.create = function(obj) {
|
||||
function F() {}
|
||||
F.prototype = obj;
|
||||
return new F();
|
||||
};
|
||||
}
|
||||
|
||||
(function($, window, document) {
|
||||
var
|
||||
loadAPI = function loadAPI(callback) {
|
||||
|
||||
// Load Youtube API
|
||||
var tag = document.createElement('script'),
|
||||
head = document.getElementsByTagName('head')[0];
|
||||
|
||||
if(window.location.origin == 'file://') {
|
||||
tag.src = 'https://www.youtube.com/iframe_api';
|
||||
} else {
|
||||
tag.src = '//www.youtube.com/iframe_api';
|
||||
}
|
||||
|
||||
head.appendChild(tag);
|
||||
|
||||
// Clean up Tags.
|
||||
head = null;
|
||||
tag = null;
|
||||
|
||||
iframeIsReady(callback);
|
||||
},
|
||||
iframeIsReady = function iframeIsReady(callback) {
|
||||
// Listen for Gobal YT player callback
|
||||
if (typeof YT === 'undefined' && typeof window.loadingPlayer === 'undefined') {
|
||||
// Prevents Ready Event from being called twice
|
||||
window.loadingPlayer = true;
|
||||
|
||||
|
||||
// Creates deferred so, other players know when to wait.
|
||||
window.dfd = $.Deferred();
|
||||
window.onYouTubeIframeAPIReady = function() {
|
||||
window.onYouTubeIframeAPIReady = null;
|
||||
window.dfd.resolve( "done" );
|
||||
callback();
|
||||
};
|
||||
} else if (typeof YT === 'object') {
|
||||
callback();
|
||||
} else {
|
||||
window.dfd.done(function( name ) {
|
||||
callback();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// YTPlayer Object
|
||||
YTPlayer = {
|
||||
player: null,
|
||||
|
||||
// Defaults
|
||||
defaults: {
|
||||
ratio: 16 / 9,
|
||||
videoId: 'LSmgKRx5pBo',
|
||||
mute: true,
|
||||
repeat: true,
|
||||
width: $(window).width(),
|
||||
playButtonClass: 'YTPlayer-play',
|
||||
pauseButtonClass: 'YTPlayer-pause',
|
||||
muteButtonClass: 'YTPlayer-mute',
|
||||
volumeUpClass: 'YTPlayer-volume-up',
|
||||
volumeDownClass: 'YTPlayer-volume-down',
|
||||
start: 0,
|
||||
pauseOnScroll: false,
|
||||
fitToBackground: true,
|
||||
playerVars: {
|
||||
iv_load_policy: 3,
|
||||
modestbranding: 1,
|
||||
autoplay: 1,
|
||||
controls: 0,
|
||||
showinfo: 0,
|
||||
wmode: 'opaque',
|
||||
branding: 0,
|
||||
autohide: 0
|
||||
},
|
||||
events: null
|
||||
},
|
||||
|
||||
/**
|
||||
* @function init
|
||||
* Intializes YTPlayer object
|
||||
*/
|
||||
init: function init(node, userOptions) {
|
||||
var self = this;
|
||||
|
||||
self.userOptions = userOptions;
|
||||
|
||||
self.$body = $('body'),
|
||||
self.$node = $(node),
|
||||
self.$window = $(window);
|
||||
|
||||
// Setup event defaults with the reference to this
|
||||
self.defaults.events = {
|
||||
'onReady': function(e) {
|
||||
self.onPlayerReady(e);
|
||||
|
||||
// setup up pause on scroll
|
||||
if (self.options.pauseOnScroll) {
|
||||
self.pauseOnScroll();
|
||||
}
|
||||
|
||||
// Callback for when finished
|
||||
if (typeof self.options.callback == 'function') {
|
||||
self.options.callback.call(this);
|
||||
}
|
||||
},
|
||||
'onStateChange': function(e) {
|
||||
if (e.data === 1) {
|
||||
|
||||
self.$node.find('img').fadeOut(400);
|
||||
self.$node.addClass('loaded');
|
||||
} else if (e.data === 0 && self.options.repeat) { // video ended and repeat option is set true
|
||||
self.player.seekTo(self.options.start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
self.options = $.extend(true, {}, self.defaults, self.userOptions);
|
||||
self.options.height = Math.ceil(self.options.width / self.options.ratio);
|
||||
self.ID = (new Date()).getTime();
|
||||
self.holderID = 'YTPlayer-ID-' + self.ID;
|
||||
|
||||
if (self.options.fitToBackground) {
|
||||
self.createBackgroundVideo();
|
||||
} else {
|
||||
self.createContainerVideo();
|
||||
}
|
||||
// Listen for Resize Event
|
||||
self.$window.on('resize.YTplayer' + self.ID, function() {
|
||||
self.resize(self);
|
||||
});
|
||||
|
||||
loadAPI(self.onYouTubeIframeAPIReady.bind(self));
|
||||
|
||||
self.resize(self);
|
||||
|
||||
return self;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @function pauseOnScroll
|
||||
* Adds window events to pause video on scroll.
|
||||
*/
|
||||
pauseOnScroll: function pauseOnScroll() {
|
||||
var self = this;
|
||||
self.$window.on('scroll.YTplayer' + self.ID, function() {
|
||||
var state = self.player.getPlayerState();
|
||||
if (state === 1) {
|
||||
self.player.pauseVideo();
|
||||
}
|
||||
});
|
||||
self.$window.scrollStopped(function(){
|
||||
var state = self.player.getPlayerState();
|
||||
if (state === 2) {
|
||||
self.player.playVideo();
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @function createContainerVideo
|
||||
* Adds HTML for video in a container
|
||||
*/
|
||||
createContainerVideo: function createContainerVideo() {
|
||||
var self = this;
|
||||
|
||||
/*jshint multistr: true */
|
||||
var $YTPlayerString = $('<div id="ytplayer-container' + self.ID + '" >\
|
||||
<div id="' + self.holderID + '" class="ytplayer-player-inline"></div> \
|
||||
</div> \
|
||||
<div id="ytplayer-shield" class="ytplayer-shield"></div>');
|
||||
|
||||
self.$node.append($YTPlayerString);
|
||||
self.$YTPlayerString = $YTPlayerString;
|
||||
$YTPlayerString = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* @function createBackgroundVideo
|
||||
* Adds HTML for video background
|
||||
*/
|
||||
createBackgroundVideo: function createBackgroundVideo() {
|
||||
/*jshint multistr: true */
|
||||
var self = this,
|
||||
$YTPlayerString = $('<div id="ytplayer-container' + self.ID + '" class="ytplayer-container background">\
|
||||
<div id="' + self.holderID + '" class="ytplayer-player"></div>\
|
||||
</div>\
|
||||
<div id="ytplayer-shield" class="ytplayer-shield"></div>');
|
||||
|
||||
self.$node.append($YTPlayerString);
|
||||
self.$YTPlayerString = $YTPlayerString;
|
||||
$YTPlayerString = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* @function resize
|
||||
* Resize event to change video size
|
||||
*/
|
||||
resize: function resize(self) {
|
||||
//var self = this;
|
||||
var container = $(window);
|
||||
|
||||
if (!self.options.fitToBackground) {
|
||||
container = self.$node;
|
||||
}
|
||||
|
||||
var width = container.width(),
|
||||
pWidth, // player width, to be defined
|
||||
height = container.height(),
|
||||
pHeight, // player height, tbd
|
||||
$YTPlayerPlayer = $('#' + self.holderID);
|
||||
|
||||
// when screen aspect ratio differs from video, video must center and underlay one dimension
|
||||
if (width / self.options.ratio < height) {
|
||||
pWidth = Math.ceil(height * self.options.ratio); // get new player width
|
||||
$YTPlayerPlayer.width(pWidth).height(height).css({
|
||||
left: (width - pWidth) / 2,
|
||||
top: 0
|
||||
}); // player width is greater, offset left; reset top
|
||||
} else { // new video width < window width (gap to right)
|
||||
pHeight = Math.ceil(width / self.options.ratio); // get new player height
|
||||
$YTPlayerPlayer.width(width).height(pHeight).css({
|
||||
left: 0,
|
||||
top: (height - pHeight) / 2
|
||||
}); // player height is greater, offset top; reset left
|
||||
}
|
||||
|
||||
$YTPlayerPlayer = null;
|
||||
container = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* @function onYouTubeIframeAPIReady
|
||||
* @ params {object} YTPlayer object for access to options
|
||||
* Youtube API calls this function when the player is ready.
|
||||
*/
|
||||
onYouTubeIframeAPIReady: function onYouTubeIframeAPIReady() {
|
||||
var self = this;
|
||||
self.player = new window.YT.Player(self.holderID, self.options);
|
||||
},
|
||||
|
||||
/**
|
||||
* @function onPlayerReady
|
||||
* @ params {event} window event from youtube player
|
||||
*/
|
||||
onPlayerReady: function onPlayerReady(e) {
|
||||
if (this.options.mute) {
|
||||
e.target.mute();
|
||||
}
|
||||
e.target.playVideo();
|
||||
},
|
||||
|
||||
/**
|
||||
* @function getPlayer
|
||||
* returns youtube player
|
||||
*/
|
||||
getPlayer: function getPlayer() {
|
||||
return this.player;
|
||||
},
|
||||
|
||||
/**
|
||||
* @function destroy
|
||||
* destroys all!
|
||||
*/
|
||||
destroy: function destroy() {
|
||||
var self = this;
|
||||
|
||||
self.$node
|
||||
.removeData('yt-init')
|
||||
.removeData('ytPlayer')
|
||||
.removeClass('loaded');
|
||||
|
||||
self.$YTPlayerString.remove();
|
||||
|
||||
$(window).off('resize.YTplayer' + self.ID);
|
||||
$(window).off('scroll.YTplayer' + self.ID);
|
||||
self.$body = null;
|
||||
self.$node = null;
|
||||
self.$YTPlayerString = null;
|
||||
self.player.destroy();
|
||||
self.player = null;
|
||||
}
|
||||
};
|
||||
|
||||
// Scroll Stopped event.
|
||||
$.fn.scrollStopped = function(callback) {
|
||||
var $this = $(this), self = this;
|
||||
$this.scroll(function(){
|
||||
if ($this.data('scrollTimeout')) {
|
||||
clearTimeout($this.data('scrollTimeout'));
|
||||
}
|
||||
$this.data('scrollTimeout', setTimeout(callback,250,self));
|
||||
});
|
||||
};
|
||||
|
||||
// Create plugin
|
||||
$.fn.YTPlayer = function(options) {
|
||||
|
||||
return this.each(function() {
|
||||
var el = this;
|
||||
|
||||
$(el).data("yt-init", true);
|
||||
var player = Object.create(YTPlayer);
|
||||
player.init(el, options);
|
||||
$.data(el, "ytPlayer", player);
|
||||
});
|
||||
};
|
||||
|
||||
})(jQuery, window, document);
|
||||
Reference in New Issue
Block a user