first commit
This commit is contained in:
+3045
File diff suppressed because it is too large
Load Diff
+207
@@ -0,0 +1,207 @@
|
||||
//@global sekFrontLocalized
|
||||
var czrapp = czrapp || {};
|
||||
/*************************
|
||||
* ADD BASE CLASS METHODS
|
||||
*************************/
|
||||
(function($, czrapp) {
|
||||
var _methods = {
|
||||
/**
|
||||
* Cache properties on Dom Ready
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
cacheProp : function() {
|
||||
if ( "undefined" === typeof( sekFrontLocalized ) || ! sekFrontLocalized ) {
|
||||
throw new Error( 'czrapp => cacheProp => missing global sekFrontLocalized ');
|
||||
}
|
||||
var self = this;
|
||||
$.extend( czrapp, {
|
||||
//cache various jQuery el in czrapp obj
|
||||
$_window : $(window),
|
||||
$_html : $('html'),
|
||||
$_body : $('body'),
|
||||
$_wpadminbar : $('#wpadminbar'),
|
||||
|
||||
//cache various jQuery body inner el in czrapp obj
|
||||
$_header : $('.tc-header'),
|
||||
|
||||
//various properties definition
|
||||
localized : "undefined" != typeof( sekFrontLocalized ) && sekFrontLocalized ? sekFrontLocalized : { _disabled: [] },
|
||||
is_responsive : self.isResponsive(),//store the initial responsive state of the window
|
||||
current_device : self.getDevice(),//store the initial device
|
||||
isRTL : $('html').attr('dir') == 'rtl'//is rtl?
|
||||
});
|
||||
},
|
||||
|
||||
//bool
|
||||
isResponsive : function() {
|
||||
return this.matchMedia(991);
|
||||
},
|
||||
|
||||
//@return string of current device
|
||||
getDevice : function() {
|
||||
var _devices = {
|
||||
desktop : 991,
|
||||
tablet : 767,
|
||||
smartphone : 575
|
||||
},
|
||||
_current_device = 'desktop',
|
||||
that = this;
|
||||
|
||||
|
||||
_.map( _devices, function( max_width, _dev ){
|
||||
if ( that.matchMedia( max_width ) )
|
||||
_current_device = _dev;
|
||||
} );
|
||||
|
||||
return _current_device;
|
||||
},
|
||||
|
||||
matchMedia : function( _maxWidth ) {
|
||||
if ( window.matchMedia )
|
||||
return ( window.matchMedia("(max-width: "+_maxWidth+"px)").matches );
|
||||
|
||||
//old browsers compatibility
|
||||
var $_window = czrapp.$_window || $(window);
|
||||
return $_window.width() <= ( _maxWidth - 15 );
|
||||
},
|
||||
|
||||
emit : function( cbs, args ) {
|
||||
cbs = _.isArray(cbs) ? cbs : [cbs];
|
||||
var self = this;
|
||||
_.map( cbs, function(cb) {
|
||||
if ( 'function' == typeof(self[cb]) ) {
|
||||
args = 'undefined' == typeof( args ) ? [] : args ;
|
||||
self[cb].apply(self, args );
|
||||
czrapp.trigger( cb, _.object( _.keys(args), args ) );
|
||||
}
|
||||
});//_.map
|
||||
},
|
||||
|
||||
triggerSimpleLoad : function( $_imgs ) {
|
||||
if ( 0 === $_imgs.length )
|
||||
return;
|
||||
|
||||
$_imgs.map( function( _ind, _img ) {
|
||||
$(_img).load( function () {
|
||||
$(_img).trigger('simple_load');
|
||||
});//end load
|
||||
if ( $(_img)[0] && $(_img)[0].complete )
|
||||
$(_img).load();
|
||||
} );//end map
|
||||
},//end of fn
|
||||
|
||||
isUserLogged : function() {
|
||||
return czrapp.$_body.hasClass('logged-in') || 0 !== czrapp.$_wpadminbar.length;
|
||||
},
|
||||
|
||||
isSelectorAllowed : function( $_el, skip_selectors, requested_sel_type ) {
|
||||
var sel_type = 'ids' == requested_sel_type ? 'id' : 'class',
|
||||
_selsToSkip = skip_selectors[requested_sel_type];
|
||||
|
||||
//check if option is well formed
|
||||
if ( 'object' != typeof(skip_selectors) || ! skip_selectors[requested_sel_type] || ! $.isArray( skip_selectors[requested_sel_type] ) || 0 === skip_selectors[requested_sel_type].length )
|
||||
return true;
|
||||
|
||||
//has a forbidden parent?
|
||||
if ( $_el.parents( _selsToSkip.map( function( _sel ){ return 'id' == sel_type ? '#' + _sel : '.' + _sel; } ).join(',') ).length > 0 )
|
||||
return false;
|
||||
|
||||
//has requested sel ?
|
||||
if ( ! $_el.attr( sel_type ) )
|
||||
return true;
|
||||
|
||||
var _elSels = $_el.attr( sel_type ).split(' '),
|
||||
_filtered = _elSels.filter( function(classe) { return -1 != $.inArray( classe , _selsToSkip ) ;});
|
||||
|
||||
//check if the filtered selectors array with the non authorized selectors is empty or not
|
||||
//if empty => all selectors are allowed
|
||||
//if not, at least one is not allowed
|
||||
return 0 === _filtered.length;
|
||||
},
|
||||
|
||||
|
||||
//@return bool
|
||||
_isMobile : function() {
|
||||
return ( _.isFunction( window.matchMedia ) && matchMedia( 'only screen and (max-width: 768px)' ).matches ) || ( this._isCustomizing() && 'desktop' != this.previewDevice() );
|
||||
},
|
||||
|
||||
//@return bool
|
||||
_isCustomizing : function() {
|
||||
return czrapp.$_body.hasClass('is-customizing') || ( 'undefined' !== typeof wp && 'undefined' !== typeof wp.customize );
|
||||
},
|
||||
|
||||
//Helpers
|
||||
//Check if the passed element(s) contains an iframe
|
||||
//@return list of containers
|
||||
//@param $_elements = mixed
|
||||
_has_iframe : function ( $_elements ) {
|
||||
var to_return = [];
|
||||
_.each( $_elements, function( $_el, container ){
|
||||
if ( $_el.length > 0 && $_el.find('IFRAME').length > 0 )
|
||||
to_return.push(container);
|
||||
});
|
||||
return to_return;
|
||||
},
|
||||
|
||||
//Simple Utility telling if a given Dom element is currently in the window <=> visible.
|
||||
//Useful to mimic a very basic WayPoint
|
||||
elOrFirstVisibleParentIsInWindow : function( $_el, threshold ) {
|
||||
if ( ! ( $_el instanceof $ ) )
|
||||
return;
|
||||
if ( threshold && ! _.isNumber( threshold ) )
|
||||
return;
|
||||
|
||||
var wt = $(window).scrollTop(),
|
||||
wb = wt + $(window).height(),
|
||||
it = $_el.offset().top,
|
||||
ib = it + $_el.height(),
|
||||
th = threshold || 0;
|
||||
|
||||
return ib >= wt - th && it <= wb + th;
|
||||
},
|
||||
|
||||
//params :
|
||||
//{
|
||||
// delay : 3000,
|
||||
// func : fn,
|
||||
// instance : {},
|
||||
// args : []
|
||||
//}
|
||||
fireMeWhenStoppedScrolling : function( params ) {
|
||||
params = _.extend( {
|
||||
delay : 3000,
|
||||
func : '',
|
||||
instance : {},
|
||||
args : []
|
||||
}, params );
|
||||
|
||||
if ( ! _.isFunction( params.func ) )
|
||||
return;
|
||||
var _timer_ = function() {
|
||||
$.Deferred( function() {
|
||||
var dfd = this;
|
||||
_.delay( function() {
|
||||
dfd.resolve();
|
||||
}, params.delay );
|
||||
}).done( function() {
|
||||
//user has stopped scrolling since params.delay seconds, or last we check was params.delay seconds ago
|
||||
//what do we do ?
|
||||
if ( czrapp.userXP.isScrolling() ) {
|
||||
//still scrolling, fire me again
|
||||
_timer_();
|
||||
} else {
|
||||
//not scrolling anymore
|
||||
params.func.apply( params.instance, params.args );
|
||||
}
|
||||
});
|
||||
};
|
||||
_timer_();
|
||||
},
|
||||
//Will store the status of the script to load dynamically
|
||||
scriptLoadingStatus : {},
|
||||
};//_methods{}
|
||||
|
||||
czrapp.methods.Base = czrapp.methods.Base || {};
|
||||
$.extend( czrapp.methods.Base , _methods );//$.extend
|
||||
|
||||
})(jQuery, czrapp);
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
var czrapp = czrapp || {};
|
||||
/***************************
|
||||
* ADD JQUERY PLUGINS METHODS
|
||||
****************************/
|
||||
(function($, czrapp, Waypoint ) {
|
||||
var _methods = {
|
||||
centerImagesWithDelay : function( delay ) {
|
||||
var self = this;
|
||||
//fire the center images plugin
|
||||
//setTimeout( function(){ self.emit('centerImages'); }, delay || 300 );
|
||||
setTimeout( function(){ self.emit('centerImages'); }, delay || 50 );
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* CENTER VARIOUS IMAGES
|
||||
* @return {void}
|
||||
*/
|
||||
centerImages : function() {
|
||||
var $wrappersOfCenteredImagesCandidates = $('.sek-fp-widget .sek-fp-thumb-wrapper, .js-centering.entry-media__holder, .js-centering.entry-media__wrapper');
|
||||
|
||||
//Featured pages and classical grid are always centered
|
||||
// $('.tc-grid-figure, .widget-front .tc-thumbnail').centerImages( {
|
||||
// enableCentering : 1,
|
||||
// oncustom : ['smartload', 'refresh-height', 'simple_load'],
|
||||
// zeroTopAdjust: 0,
|
||||
// enableGoldenRatio : false,
|
||||
// } );
|
||||
var _css_loader = '<div class="czr-css-loader czr-mr-loader" style="display:none"><div></div><div></div><div></div></div>';
|
||||
$wrappersOfCenteredImagesCandidates.each( function() {
|
||||
$( this ).append( _css_loader ).find('.czr-css-loader').fadeIn( 'slow');
|
||||
});
|
||||
$wrappersOfCenteredImagesCandidates.centerImages({
|
||||
onInit : true,
|
||||
enableCentering : 1,
|
||||
oncustom : ['smartload', 'refresh-height', 'simple_load'],
|
||||
enableGoldenRatio : false, //true
|
||||
zeroTopAdjust: 0,
|
||||
setOpacityWhenCentered : false,//will set the opacity to 1
|
||||
addCenteredClassWithDelay : 50,
|
||||
opacity : 1
|
||||
});
|
||||
_.delay( function() {
|
||||
$wrappersOfCenteredImagesCandidates.find('.czr-css-loader').fadeOut( {
|
||||
duration: 500,
|
||||
done : function() { $(this).remove();}
|
||||
} );
|
||||
}, 300 );
|
||||
|
||||
|
||||
// if for any reasons, the centering did not happen, the imgs will not be displayed because opacity will stay at 0
|
||||
// => the opacity is set to 1 as soon as v-centered or h-centered has been added to a img element candidate for centering
|
||||
// @see css
|
||||
var _mayBeForceOpacity = function( params ) {
|
||||
params = _.extend( {
|
||||
el : {},
|
||||
delay : 0
|
||||
}, _.isObject( params ) ? params : {} );
|
||||
|
||||
if ( 1 !== params.el.length || ( params.el.hasClass( 'h-centered') || params.el.hasClass( 'v-centered') ) )
|
||||
return;
|
||||
|
||||
_.delay( function() {
|
||||
params.el.addClass( 'opacity-forced');
|
||||
}, params.delay );
|
||||
|
||||
};
|
||||
//For smartloaded image, let's wait for the smart load to happen, for the others, let's do it now without delay
|
||||
if ( czrapp.localized.imgSmartLoadEnabled ) {
|
||||
$wrappersOfCenteredImagesCandidates.on( 'smartload', 'img' , function( ev ) {
|
||||
if ( 1 != $( ev.target ).length )
|
||||
return;
|
||||
_mayBeForceOpacity( { el : $( ev.target ), delay : 200 } );
|
||||
});
|
||||
} else {
|
||||
$wrappersOfCenteredImagesCandidates.find('img').each( function() {
|
||||
_mayBeForceOpacity( { el : $(this), delay : 100 } );
|
||||
});
|
||||
}
|
||||
|
||||
//then last check
|
||||
_.delay( function() {
|
||||
$wrappersOfCenteredImagesCandidates.find('img').each( function() {
|
||||
_mayBeForceOpacity( { el : $(this), delay : 0 } );
|
||||
});
|
||||
}, 1000 );
|
||||
|
||||
}//center_images
|
||||
};//_methods{}
|
||||
|
||||
czrapp.methods.JQPlugins = {};
|
||||
$.extend( czrapp.methods.JQPlugins , _methods );
|
||||
|
||||
|
||||
})(jQuery, czrapp, Waypoint);
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
var czrapp = czrapp || {};
|
||||
//@global sekFrontLocalized
|
||||
/************************************************
|
||||
* LET'S DANCE
|
||||
*************************************************/
|
||||
( function ( czrapp ) {
|
||||
//adds the server params to the app now
|
||||
//czrapp.localized = window.sekFrontLocalized || {};
|
||||
|
||||
//THE DEFAULT MAP
|
||||
//Other methods can be hooked. @see czrapp.customMap
|
||||
var appMap = {
|
||||
base : {
|
||||
ctor : czrapp.Base,
|
||||
ready : [
|
||||
'cacheProp'
|
||||
]
|
||||
},
|
||||
// browserDetect : {
|
||||
// ctor : czrapp.Base.extend( czrapp.methods.BrowserDetect ),
|
||||
// ready : [ 'addBrowserClassToBody' ]
|
||||
// },
|
||||
jqPlugins : {
|
||||
ctor : czrapp.Base.extend( czrapp.methods.JQPlugins ),
|
||||
ready : [
|
||||
'centerImagesWithDelay',
|
||||
// 'imgSmartLoad',
|
||||
//'dropCaps',
|
||||
//'extLinks',
|
||||
// 'lightBox',
|
||||
// 'parallax'
|
||||
]
|
||||
},
|
||||
// userXP : {
|
||||
// ctor : czrapp.Base.extend( czrapp.methods.UserXP ),
|
||||
// ready : [
|
||||
// 'setupUIListeners',//<= setup various observable values like this.isScrolling, this.scrollPosition, ...
|
||||
|
||||
// 'variousHoverActions',
|
||||
// 'formFocusAction',
|
||||
|
||||
// 'smoothScroll',
|
||||
|
||||
// 'attachmentsFadeEffect',
|
||||
|
||||
// 'onEscapeKeyPressed',
|
||||
|
||||
// 'featuredPagesAlignment',
|
||||
|
||||
// 'anchorSmoothScroll',
|
||||
|
||||
// 'mayBePrintFrontNote',
|
||||
// ]
|
||||
// }
|
||||
};//map
|
||||
|
||||
//set the observable value
|
||||
//listened to by _instantianteAndFireOnDomReady = function( newMap, previousMap, isInitial )
|
||||
czrapp.appMap( appMap , true );//true for isInitial map
|
||||
|
||||
})( czrapp );
|
||||
+2366
File diff suppressed because it is too large
Load Diff
+1
File diff suppressed because one or more lines are too long
+859
@@ -0,0 +1,859 @@
|
||||
/*!
|
||||
* Bootstrap v4.0.0 (https://getbootstrap.com)
|
||||
* Copyright 2011-2018 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('jquery')) :
|
||||
typeof define === 'function' && define.amd ? define(['exports', 'jquery'], factory) :
|
||||
(factory((global.bootstrap = {}),global.jQuery));
|
||||
}(this, (function (exports,$) { 'use strict';
|
||||
|
||||
$ = $ && $.hasOwnProperty('default') ? $['default'] : $;
|
||||
|
||||
function _defineProperties(target, props) {
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
var descriptor = props[i];
|
||||
descriptor.enumerable = descriptor.enumerable || false;
|
||||
descriptor.configurable = true;
|
||||
if ("value" in descriptor) descriptor.writable = true;
|
||||
Object.defineProperty(target, descriptor.key, descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
function _createClass(Constructor, protoProps, staticProps) {
|
||||
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
||||
if (staticProps) _defineProperties(Constructor, staticProps);
|
||||
return Constructor;
|
||||
}
|
||||
|
||||
function _extends() {
|
||||
_extends = Object.assign || function (target) {
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
var source = arguments[i];
|
||||
|
||||
for (var key in source) {
|
||||
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
};
|
||||
|
||||
return _extends.apply(this, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v4.0.0): util.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
var Util = function ($$$1) {
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Private TransitionEnd Helpers
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
var transition = false;
|
||||
var MAX_UID = 1000000; // Shoutout AngusCroll (https://goo.gl/pxwQGp)
|
||||
|
||||
function toType(obj) {
|
||||
return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();
|
||||
}
|
||||
|
||||
function getSpecialTransitionEndEvent() {
|
||||
return {
|
||||
bindType: transition.end,
|
||||
delegateType: transition.end,
|
||||
handle: function handle(event) {
|
||||
if ($$$1(event.target).is(this)) {
|
||||
return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params
|
||||
}
|
||||
|
||||
return undefined; // eslint-disable-line no-undefined
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function transitionEndTest() {
|
||||
if (typeof window !== 'undefined' && window.QUnit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return {
|
||||
end: 'transitionend'
|
||||
};
|
||||
}
|
||||
|
||||
function transitionEndEmulator(duration) {
|
||||
var _this = this;
|
||||
|
||||
var called = false;
|
||||
$$$1(this).one(Util.TRANSITION_END, function () {
|
||||
called = true;
|
||||
});
|
||||
setTimeout(function () {
|
||||
if (!called) {
|
||||
Util.triggerTransitionEnd(_this);
|
||||
}
|
||||
}, duration);
|
||||
return this;
|
||||
}
|
||||
|
||||
function setTransitionEndSupport() {
|
||||
transition = transitionEndTest();
|
||||
$$$1.fn.emulateTransitionEnd = transitionEndEmulator;
|
||||
|
||||
if (Util.supportsTransitionEnd()) {
|
||||
$$$1.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Public Util Api
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
var Util = {
|
||||
TRANSITION_END: 'bsTransitionEnd',
|
||||
getUID: function getUID(prefix) {
|
||||
do {
|
||||
// eslint-disable-next-line no-bitwise
|
||||
prefix += ~~(Math.random() * MAX_UID); // "~~" acts like a faster Math.floor() here
|
||||
} while (document.getElementById(prefix));
|
||||
|
||||
return prefix;
|
||||
},
|
||||
getSelectorFromElement: function getSelectorFromElement(element) {
|
||||
var selector = element.getAttribute('data-target');
|
||||
|
||||
if (!selector || selector === '#') {
|
||||
selector = element.getAttribute('href') || '';
|
||||
}
|
||||
|
||||
try {
|
||||
var $selector = $$$1(document).find(selector);
|
||||
return $selector.length > 0 ? selector : null;
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
reflow: function reflow(element) {
|
||||
return element.offsetHeight;
|
||||
},
|
||||
triggerTransitionEnd: function triggerTransitionEnd(element) {
|
||||
$$$1(element).trigger(transition.end);
|
||||
},
|
||||
supportsTransitionEnd: function supportsTransitionEnd() {
|
||||
return Boolean(transition);
|
||||
},
|
||||
isElement: function isElement(obj) {
|
||||
return (obj[0] || obj).nodeType;
|
||||
},
|
||||
typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) {
|
||||
for (var property in configTypes) {
|
||||
if (Object.prototype.hasOwnProperty.call(configTypes, property)) {
|
||||
var expectedTypes = configTypes[property];
|
||||
var value = config[property];
|
||||
var valueType = value && Util.isElement(value) ? 'element' : toType(value);
|
||||
|
||||
if (!new RegExp(expectedTypes).test(valueType)) {
|
||||
throw new Error(componentName.toUpperCase() + ": " + ("Option \"" + property + "\" provided type \"" + valueType + "\" ") + ("but expected type \"" + expectedTypes + "\"."));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
setTransitionEndSupport();
|
||||
return Util;
|
||||
}($);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v4.0.0): collapse.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
/**
|
||||
* @czr-addon: scope Collapse plugin to avoid bootstrap based plugin conflicts
|
||||
* see https://github.com/presscustomizr/customizr/issues/1373
|
||||
* this is easily done by:
|
||||
* 1) changing the plugin NAME from Collapse to czrCollapse
|
||||
* 2) changing the DATA_KEY from bs.collapse to czr.czrCollapse (namespace event)
|
||||
* 3) changing the DATA_TOGGLE from [data-toggle="collapse"] to '[data-toggle="czr-collapse"]
|
||||
* 4) changing the CLASSNAME (css elements classes) from
|
||||
{
|
||||
SHOW: 'show',
|
||||
COLLAPSE: 'collapse',
|
||||
COLLAPSING: 'collapsing',
|
||||
COLLAPSED: 'collapsed'
|
||||
}
|
||||
to
|
||||
{
|
||||
SHOW: 'show',
|
||||
COLLAPSE: 'czr-collapse',
|
||||
COLLAPSING: 'czr-collapsing',
|
||||
COLLAPSED: 'czr-collapsed'
|
||||
};
|
||||
*/
|
||||
var Collapse = function ($$$1) {
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
var NAME = 'czrCollapse';
|
||||
//var VERSION = '4.0.0';
|
||||
var VERSION = '1.0.1';
|
||||
var DATA_KEY = 'czr.czrCollapse';
|
||||
var EVENT_KEY = "." + DATA_KEY;
|
||||
var DATA_API_KEY = '.data-api';
|
||||
var JQUERY_NO_CONFLICT = $$$1.fn[NAME];
|
||||
var TRANSITION_DURATION = 600;
|
||||
var Default = {
|
||||
toggle: true,
|
||||
parent: ''
|
||||
};
|
||||
var DefaultType = {
|
||||
toggle: 'boolean',
|
||||
parent: '(string|element)'
|
||||
};
|
||||
var Event = {
|
||||
SHOW: "show" + EVENT_KEY,
|
||||
SHOWN: "shown" + EVENT_KEY,
|
||||
HIDE: "hide" + EVENT_KEY,
|
||||
HIDDEN: "hidden" + EVENT_KEY,
|
||||
CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY
|
||||
};
|
||||
var ClassName = {
|
||||
SHOW: 'show',
|
||||
COLLAPSE: 'czr-collapse',
|
||||
COLLAPSING: 'czr-collapsing',
|
||||
COLLAPSED: 'czr-collapsed'
|
||||
};
|
||||
var Dimension = {
|
||||
WIDTH: 'width',
|
||||
HEIGHT: 'height'
|
||||
};
|
||||
var Selector = {
|
||||
ACTIVES: '.show, .czr-collapsing',
|
||||
DATA_TOGGLE: '[data-toggle="czr-collapse"]'
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Class Definition
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
};
|
||||
|
||||
var Collapse =
|
||||
/*#__PURE__*/
|
||||
function () {
|
||||
function Collapse(element, config) {
|
||||
this._isTransitioning = false;
|
||||
this._element = element;
|
||||
this._config = this._getConfig(config);
|
||||
this._triggerArray = $$$1.makeArray($$$1("[data-toggle=\"czr-collapse\"][href=\"#" + element.id + "\"]," + ("[data-toggle=\"czr-collapse\"][data-target=\"#" + element.id + "\"]")));
|
||||
var tabToggles = $$$1(Selector.DATA_TOGGLE);
|
||||
|
||||
for (var i = 0; i < tabToggles.length; i++) {
|
||||
var elem = tabToggles[i];
|
||||
var selector = Util.getSelectorFromElement(elem);
|
||||
|
||||
if (selector !== null && $$$1(selector).filter(element).length > 0) {
|
||||
this._selector = selector;
|
||||
|
||||
this._triggerArray.push(elem);
|
||||
}
|
||||
}
|
||||
|
||||
this._parent = this._config.parent ? this._getParent() : null;
|
||||
|
||||
if (!this._config.parent) {
|
||||
this._addAriaAndCollapsedClass(this._element, this._triggerArray);
|
||||
}
|
||||
|
||||
if (this._config.toggle) {
|
||||
this.toggle();
|
||||
}
|
||||
} // Getters
|
||||
|
||||
|
||||
var _proto = Collapse.prototype;
|
||||
|
||||
// Public
|
||||
_proto.toggle = function toggle() {
|
||||
if ($$$1(this._element).hasClass(ClassName.SHOW)) {
|
||||
this.hide();
|
||||
} else {
|
||||
this.show();
|
||||
}
|
||||
};
|
||||
|
||||
_proto.show = function show() {
|
||||
var _this = this;
|
||||
|
||||
if (this._isTransitioning || $$$1(this._element).hasClass(ClassName.SHOW)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var actives;
|
||||
var activesData;
|
||||
|
||||
if (this._parent) {
|
||||
actives = $$$1.makeArray($$$1(this._parent).find(Selector.ACTIVES).filter("[data-parent=\"" + this._config.parent + "\"]"));
|
||||
|
||||
if (actives.length === 0) {
|
||||
actives = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (actives) {
|
||||
activesData = $$$1(actives).not(this._selector).data(DATA_KEY);
|
||||
|
||||
if (activesData && activesData._isTransitioning) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var startEvent = $$$1.Event(Event.SHOW);
|
||||
$$$1(this._element).trigger(startEvent);
|
||||
|
||||
if (startEvent.isDefaultPrevented()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (actives) {
|
||||
Collapse._jQueryInterface.call($$$1(actives).not(this._selector), 'hide');
|
||||
|
||||
if (!activesData) {
|
||||
$$$1(actives).data(DATA_KEY, null);
|
||||
}
|
||||
}
|
||||
|
||||
var dimension = this._getDimension();
|
||||
|
||||
$$$1(this._element).removeClass(ClassName.COLLAPSE).addClass(ClassName.COLLAPSING);
|
||||
this._element.style[dimension] = 0;
|
||||
|
||||
if (this._triggerArray.length > 0) {
|
||||
$$$1(this._triggerArray).removeClass(ClassName.COLLAPSED).attr('aria-expanded', true);
|
||||
}
|
||||
|
||||
this.setTransitioning(true);
|
||||
|
||||
var complete = function complete() {
|
||||
$$$1(_this._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).addClass(ClassName.SHOW);
|
||||
_this._element.style[dimension] = '';
|
||||
|
||||
_this.setTransitioning(false);
|
||||
|
||||
$$$1(_this._element).trigger(Event.SHOWN);
|
||||
};
|
||||
|
||||
if (!Util.supportsTransitionEnd()) {
|
||||
complete();
|
||||
return;
|
||||
}
|
||||
|
||||
var capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);
|
||||
var scrollSize = "scroll" + capitalizedDimension;
|
||||
$$$1(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
|
||||
this._element.style[dimension] = this._element[scrollSize] + "px";
|
||||
};
|
||||
|
||||
_proto.hide = function hide() {
|
||||
var _this2 = this;
|
||||
|
||||
if (this._isTransitioning || !$$$1(this._element).hasClass(ClassName.SHOW)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var startEvent = $$$1.Event(Event.HIDE);
|
||||
$$$1(this._element).trigger(startEvent);
|
||||
|
||||
if (startEvent.isDefaultPrevented()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var dimension = this._getDimension();
|
||||
|
||||
this._element.style[dimension] = this._element.getBoundingClientRect()[dimension] + "px";
|
||||
Util.reflow(this._element);
|
||||
$$$1(this._element).addClass(ClassName.COLLAPSING).removeClass(ClassName.COLLAPSE).removeClass(ClassName.SHOW);
|
||||
|
||||
if (this._triggerArray.length > 0) {
|
||||
for (var i = 0; i < this._triggerArray.length; i++) {
|
||||
var trigger = this._triggerArray[i];
|
||||
var selector = Util.getSelectorFromElement(trigger);
|
||||
|
||||
if (selector !== null) {
|
||||
var $elem = $$$1(selector);
|
||||
|
||||
if (!$elem.hasClass(ClassName.SHOW)) {
|
||||
$$$1(trigger).addClass(ClassName.COLLAPSED).attr('aria-expanded', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.setTransitioning(true);
|
||||
|
||||
var complete = function complete() {
|
||||
_this2.setTransitioning(false);
|
||||
|
||||
$$$1(_this2._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).trigger(Event.HIDDEN);
|
||||
};
|
||||
|
||||
this._element.style[dimension] = '';
|
||||
|
||||
if (!Util.supportsTransitionEnd()) {
|
||||
complete();
|
||||
return;
|
||||
}
|
||||
|
||||
$$$1(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
|
||||
};
|
||||
|
||||
_proto.setTransitioning = function setTransitioning(isTransitioning) {
|
||||
this._isTransitioning = isTransitioning;
|
||||
};
|
||||
|
||||
_proto.dispose = function dispose() {
|
||||
$$$1.removeData(this._element, DATA_KEY);
|
||||
this._config = null;
|
||||
this._parent = null;
|
||||
this._element = null;
|
||||
this._triggerArray = null;
|
||||
this._isTransitioning = null;
|
||||
}; // Private
|
||||
|
||||
|
||||
_proto._getConfig = function _getConfig(config) {
|
||||
config = _extends({}, Default, config);
|
||||
config.toggle = Boolean(config.toggle); // Coerce string values
|
||||
|
||||
Util.typeCheckConfig(NAME, config, DefaultType);
|
||||
return config;
|
||||
};
|
||||
|
||||
_proto._getDimension = function _getDimension() {
|
||||
var hasWidth = $$$1(this._element).hasClass(Dimension.WIDTH);
|
||||
return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT;
|
||||
};
|
||||
|
||||
_proto._getParent = function _getParent() {
|
||||
var _this3 = this;
|
||||
|
||||
var parent = null;
|
||||
|
||||
if (Util.isElement(this._config.parent)) {
|
||||
parent = this._config.parent; // It's a jQuery object
|
||||
|
||||
if (typeof this._config.parent.jquery !== 'undefined') {
|
||||
parent = this._config.parent[0];
|
||||
}
|
||||
} else {
|
||||
parent = $$$1(this._config.parent)[0];
|
||||
}
|
||||
|
||||
var selector = "[data-toggle=\"czr-collapse\"][data-parent=\"" + this._config.parent + "\"]";
|
||||
$$$1(parent).find(selector).each(function (i, element) {
|
||||
_this3._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]);
|
||||
});
|
||||
return parent;
|
||||
};
|
||||
|
||||
_proto._addAriaAndCollapsedClass = function _addAriaAndCollapsedClass(element, triggerArray) {
|
||||
if (element) {
|
||||
var isOpen = $$$1(element).hasClass(ClassName.SHOW);
|
||||
|
||||
if (triggerArray.length > 0) {
|
||||
$$$1(triggerArray).toggleClass(ClassName.COLLAPSED, !isOpen).attr('aria-expanded', isOpen);
|
||||
}
|
||||
}
|
||||
}; // Static
|
||||
|
||||
|
||||
Collapse._getTargetFromElement = function _getTargetFromElement(element) {
|
||||
var selector = Util.getSelectorFromElement(element);
|
||||
return selector ? $$$1(selector)[0] : null;
|
||||
};
|
||||
|
||||
Collapse._jQueryInterface = function _jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
var $this = $$$1(this);
|
||||
var data = $this.data(DATA_KEY);
|
||||
|
||||
var _config = _extends({}, Default, $this.data(), typeof config === 'object' && config);
|
||||
|
||||
if (!data && _config.toggle && /show|hide/.test(config)) {
|
||||
_config.toggle = false;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
data = new Collapse(this, _config);
|
||||
$this.data(DATA_KEY, data);
|
||||
}
|
||||
|
||||
if (typeof config === 'string') {
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError("No method named \"" + config + "\"");
|
||||
}
|
||||
|
||||
data[config]();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
_createClass(Collapse, null, [{
|
||||
key: "VERSION",
|
||||
get: function get() {
|
||||
return VERSION;
|
||||
}
|
||||
}, {
|
||||
key: "Default",
|
||||
get: function get() {
|
||||
return Default;
|
||||
}
|
||||
}]);
|
||||
return Collapse;
|
||||
}();
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Data Api implementation
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
$$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
|
||||
// preventDefault only for <a> elements (which change the URL) not inside the collapsible element
|
||||
if (event.currentTarget.tagName === 'A') {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
var $trigger = $$$1(this);
|
||||
var selector = Util.getSelectorFromElement(this);
|
||||
$$$1(selector).each(function () {
|
||||
var $target = $$$1(this);
|
||||
var data = $target.data(DATA_KEY);
|
||||
var config = data ? 'toggle' : $trigger.data();
|
||||
|
||||
Collapse._jQueryInterface.call($target, config);
|
||||
});
|
||||
});
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
$$$1.fn[NAME] = Collapse._jQueryInterface;
|
||||
$$$1.fn[NAME].Constructor = Collapse;
|
||||
|
||||
$$$1.fn[NAME].noConflict = function () {
|
||||
$$$1.fn[NAME] = JQUERY_NO_CONFLICT;
|
||||
return Collapse._jQueryInterface;
|
||||
};
|
||||
|
||||
return Collapse;
|
||||
}($);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v4.0.0): tab.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
/**
|
||||
* @czr-addon: scope Tab plugin to avoid bootstrap based plugin conflicts
|
||||
* see https://github.com/presscustomizr/customizr/issues/1373
|
||||
* this is easily done by:
|
||||
* 1) changing the plugin NAME from Tab to czrTab
|
||||
* 2) changing the DATA_KEY from bs.tab to czr.czrTab (namespace event)
|
||||
* 3) changing the DATA_TOGGLE from '[data-toggle="tab"], [data-toggle="pill"]', [data-toggle="list"] to '[data-toggle="czr-tab"], [data-toggle="czr-pill"]', [data-toggle="czr-list"]
|
||||
*/
|
||||
var Tab = function ($$$1) {
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
var NAME = 'czrTab';
|
||||
var VERSION = '1.0.1';
|
||||
//var VERSION = '4.0.0';
|
||||
var DATA_KEY = 'czr.czrTab';
|
||||
var EVENT_KEY = "." + DATA_KEY;
|
||||
var DATA_API_KEY = '.data-api';
|
||||
var JQUERY_NO_CONFLICT = $$$1.fn[NAME];
|
||||
var TRANSITION_DURATION = 150;
|
||||
var Event = {
|
||||
HIDE: "hide" + EVENT_KEY,
|
||||
HIDDEN: "hidden" + EVENT_KEY,
|
||||
SHOW: "show" + EVENT_KEY,
|
||||
SHOWN: "shown" + EVENT_KEY,
|
||||
CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY
|
||||
};
|
||||
var ClassName = {
|
||||
DROPDOWN_MENU: 'dropdown-menu',
|
||||
ACTIVE: 'active',
|
||||
DISABLED: 'disabled',
|
||||
FADE: 'fade',
|
||||
SHOW: 'show'
|
||||
};
|
||||
var Selector = {
|
||||
DROPDOWN: '.dropdown',
|
||||
NAV_LIST_GROUP: '.nav, .list-group',
|
||||
ACTIVE: '.active',
|
||||
ACTIVE_UL: '> li > .active',
|
||||
DATA_TOGGLE: '[data-toggle="czr-tab"], [data-toggle="czr-pill"], [data-toggle="czr-list"]',
|
||||
DROPDOWN_TOGGLE: '.dropdown-toggle',
|
||||
DROPDOWN_ACTIVE_CHILD: '> .dropdown-menu .active'
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Class Definition
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
};
|
||||
|
||||
var Tab =
|
||||
/*#__PURE__*/
|
||||
function () {
|
||||
function Tab(element) {
|
||||
this._element = element;
|
||||
} // Getters
|
||||
|
||||
|
||||
var _proto = Tab.prototype;
|
||||
|
||||
// Public
|
||||
_proto.show = function show() {
|
||||
var _this = this;
|
||||
|
||||
if (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && $$$1(this._element).hasClass(ClassName.ACTIVE) || $$$1(this._element).hasClass(ClassName.DISABLED)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var target;
|
||||
var previous;
|
||||
var listElement = $$$1(this._element).closest(Selector.NAV_LIST_GROUP)[0];
|
||||
var selector = Util.getSelectorFromElement(this._element);
|
||||
|
||||
if (listElement) {
|
||||
var itemSelector = listElement.nodeName === 'UL' ? Selector.ACTIVE_UL : Selector.ACTIVE;
|
||||
previous = $$$1.makeArray($$$1(listElement).find(itemSelector));
|
||||
previous = previous[previous.length - 1];
|
||||
}
|
||||
|
||||
var hideEvent = $$$1.Event(Event.HIDE, {
|
||||
relatedTarget: this._element
|
||||
});
|
||||
var showEvent = $$$1.Event(Event.SHOW, {
|
||||
relatedTarget: previous
|
||||
});
|
||||
|
||||
if (previous) {
|
||||
$$$1(previous).trigger(hideEvent);
|
||||
}
|
||||
|
||||
$$$1(this._element).trigger(showEvent);
|
||||
|
||||
if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (selector) {
|
||||
target = $$$1(selector)[0];
|
||||
}
|
||||
|
||||
this._activate(this._element, listElement);
|
||||
|
||||
var complete = function complete() {
|
||||
var hiddenEvent = $$$1.Event(Event.HIDDEN, {
|
||||
relatedTarget: _this._element
|
||||
});
|
||||
var shownEvent = $$$1.Event(Event.SHOWN, {
|
||||
relatedTarget: previous
|
||||
});
|
||||
$$$1(previous).trigger(hiddenEvent);
|
||||
$$$1(_this._element).trigger(shownEvent);
|
||||
};
|
||||
|
||||
if (target) {
|
||||
this._activate(target, target.parentNode, complete);
|
||||
} else {
|
||||
complete();
|
||||
}
|
||||
};
|
||||
|
||||
_proto.dispose = function dispose() {
|
||||
$$$1.removeData(this._element, DATA_KEY);
|
||||
this._element = null;
|
||||
}; // Private
|
||||
|
||||
|
||||
_proto._activate = function _activate(element, container, callback) {
|
||||
var _this2 = this;
|
||||
|
||||
var activeElements;
|
||||
|
||||
if (container.nodeName === 'UL') {
|
||||
activeElements = $$$1(container).find(Selector.ACTIVE_UL);
|
||||
} else {
|
||||
activeElements = $$$1(container).children(Selector.ACTIVE);
|
||||
}
|
||||
|
||||
var active = activeElements[0];
|
||||
var isTransitioning = callback && Util.supportsTransitionEnd() && active && $$$1(active).hasClass(ClassName.FADE);
|
||||
|
||||
var complete = function complete() {
|
||||
return _this2._transitionComplete(element, active, callback);
|
||||
};
|
||||
|
||||
if (active && isTransitioning) {
|
||||
$$$1(active).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
|
||||
} else {
|
||||
complete();
|
||||
}
|
||||
};
|
||||
|
||||
_proto._transitionComplete = function _transitionComplete(element, active, callback) {
|
||||
if (active) {
|
||||
$$$1(active).removeClass(ClassName.SHOW + " " + ClassName.ACTIVE);
|
||||
var dropdownChild = $$$1(active.parentNode).find(Selector.DROPDOWN_ACTIVE_CHILD)[0];
|
||||
|
||||
if (dropdownChild) {
|
||||
$$$1(dropdownChild).removeClass(ClassName.ACTIVE);
|
||||
}
|
||||
|
||||
if (active.getAttribute('role') === 'tab') {
|
||||
active.setAttribute('aria-selected', false);
|
||||
}
|
||||
}
|
||||
|
||||
$$$1(element).addClass(ClassName.ACTIVE);
|
||||
|
||||
if (element.getAttribute('role') === 'tab') {
|
||||
element.setAttribute('aria-selected', true);
|
||||
}
|
||||
|
||||
Util.reflow(element);
|
||||
$$$1(element).addClass(ClassName.SHOW);
|
||||
|
||||
if (element.parentNode && $$$1(element.parentNode).hasClass(ClassName.DROPDOWN_MENU)) {
|
||||
var dropdownElement = $$$1(element).closest(Selector.DROPDOWN)[0];
|
||||
|
||||
if (dropdownElement) {
|
||||
$$$1(dropdownElement).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE);
|
||||
}
|
||||
|
||||
element.setAttribute('aria-expanded', true);
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
}; // Static
|
||||
|
||||
|
||||
Tab._jQueryInterface = function _jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
var $this = $$$1(this);
|
||||
var data = $this.data(DATA_KEY);
|
||||
|
||||
if (!data) {
|
||||
data = new Tab(this);
|
||||
$this.data(DATA_KEY, data);
|
||||
}
|
||||
|
||||
if (typeof config === 'string') {
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError("No method named \"" + config + "\"");
|
||||
}
|
||||
|
||||
data[config]();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
_createClass(Tab, null, [{
|
||||
key: "VERSION",
|
||||
get: function get() {
|
||||
return VERSION;
|
||||
}
|
||||
}]);
|
||||
return Tab;
|
||||
}();
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Data Api implementation
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
$$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
Tab._jQueryInterface.call($$$1(this), 'show');
|
||||
});
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
$$$1.fn[NAME] = Tab._jQueryInterface;
|
||||
$$$1.fn[NAME].Constructor = Tab;
|
||||
|
||||
$$$1.fn[NAME].noConflict = function () {
|
||||
$$$1.fn[NAME] = JQUERY_NO_CONFLICT;
|
||||
return Tab._jQueryInterface;
|
||||
};
|
||||
|
||||
return Tab;
|
||||
}($);
|
||||
|
||||
// import Button from './button'
|
||||
// import Carousel from './carousel'
|
||||
|
||||
// import Modal from './modal'
|
||||
// import Popover from './popover'
|
||||
// import Scrollspy from './scrollspy'
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v4.0.0-alpha.6): index.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
(function ($$$1) {
|
||||
if (typeof $$$1 === 'undefined') {
|
||||
throw new TypeError('Bootstrap\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\'s JavaScript.');
|
||||
}
|
||||
|
||||
var version = $$$1.fn.jquery.split(' ')[0].split('.');
|
||||
var minMajor = 1;
|
||||
var ltMajor = 2;
|
||||
var minMinor = 9;
|
||||
var minPatch = 1;
|
||||
var maxMajor = 4;
|
||||
|
||||
if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) {
|
||||
throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0');
|
||||
}
|
||||
})($);
|
||||
|
||||
exports.czrUtil = Util;
|
||||
exports.czrCollapse = Collapse;
|
||||
exports.czrTab = Tab;
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
})));
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
(function($, czrapp, _ ) {
|
||||
//czrapp.localized = CZRParams
|
||||
czrapp.ready.then( function() {
|
||||
//PLACEHOLDER NOTICES
|
||||
//two types of notices here :
|
||||
//=> the ones that remove the notice only : thumbnails, smartload, sidenav, secondMenu, mainMenu
|
||||
//=> and others that removes notices + an html block ( slider, fp ) or have additional treatments ( widget )
|
||||
|
||||
// a placeholder element looks like this:
|
||||
//<aside class="tc-placeholder-wrap col-12" data-nonce_handle="027a33be64" data-nonce_id="czrHelpBlockNonce" data-dismiss_action="dismiss_widget_notice" data-position="footer">
|
||||
//we retrieve the data attributes from the element
|
||||
var _placeholder_wrapper_selector = '.tc-placeholder-wrap',
|
||||
_defaults = { //default params
|
||||
remove_action : null,//for slider and fp
|
||||
dismiss_action : null,
|
||||
remove_selector : '',
|
||||
nonce_handle : '',
|
||||
nonce_id : '',
|
||||
position : null,//for widgets
|
||||
},
|
||||
//get params from element
|
||||
_getData = function( $_el ) {
|
||||
_defaults_keys = _.keys( _defaults );
|
||||
return _.object( _.chain(_defaults_keys ).map( function( key ) {
|
||||
var _data = $_el.data( key );
|
||||
return _data ? [ key, _data ] : '';
|
||||
})
|
||||
.compact()
|
||||
.value()
|
||||
);
|
||||
},
|
||||
_doAjax = function( _query_ ) {
|
||||
var ajaxUrl = czrapp.localized.adminAjaxUrl, dfd = $.Deferred();
|
||||
$.post( ajaxUrl, _query_ )
|
||||
.done( function( _r ) {
|
||||
// Check if the user is logged out.
|
||||
if ( '0' === _r || '-1' === _r )
|
||||
czrapp.errorLog( 'placeHolder dismiss : ajax error for : ', _query_.action, _r );
|
||||
})
|
||||
.fail( function( _r ) {
|
||||
czrapp.errorLog( 'placeHolder dismiss : ajax error for : ', _query_.action, _r );
|
||||
})
|
||||
.always( function() {
|
||||
dfd.resolve();
|
||||
});
|
||||
return dfd.promise();
|
||||
},
|
||||
// Attempt to fire an ajax call
|
||||
//@string _what_ : 'remove' or 'dismiss'
|
||||
//@object _params_
|
||||
//@remove_action optional removal action server side. Ex : 'remove_slider'
|
||||
_ajaxActionDo = function( _what_, _params_ ) {
|
||||
|
||||
var _query = {},
|
||||
dfd = $.Deferred();
|
||||
|
||||
if ( ! _.isObject( _params_ ) ) {
|
||||
czrapp.errorLog( 'placeHolder dismiss : wrong params' );
|
||||
return;
|
||||
}
|
||||
|
||||
//normalizes
|
||||
_params_ = _.extend( _defaults, _params_ );
|
||||
|
||||
//set query params
|
||||
_query.action = _params_.dismiss_action;
|
||||
|
||||
//for slider and fp
|
||||
if ( 'remove' == _what_ && ! _.isNull( _params_.remove_action ) )
|
||||
_query.action = _params_.remove_action;
|
||||
|
||||
//for widgets
|
||||
if ( ! _.isNull( _params_.position ) )
|
||||
_query.position = _params_.position;
|
||||
|
||||
_query[ _params_.nonce_id ] = _params_.nonce_handle;
|
||||
|
||||
//fires and resolve promise
|
||||
_doAjax( _query ).done( function() { dfd.resolve(); });
|
||||
return dfd.promise();
|
||||
};
|
||||
|
||||
|
||||
czrapp.$_body
|
||||
.on( 'click', '.tc-inline-remove', function( ev ) {
|
||||
ev.preventDefault();
|
||||
var $_wrapper = $(this).closest( _placeholder_wrapper_selector );
|
||||
|
||||
if ( $_wrapper.length < 1 ) {
|
||||
return;
|
||||
}
|
||||
var _data = _getData( $_wrapper );
|
||||
_ajaxActionDo( 'remove', _data ).done( function() {
|
||||
//normalizes
|
||||
_data = _.extend( _defaults, _data );
|
||||
$( _data.remove_selector ).fadeOut('slow');
|
||||
});
|
||||
|
||||
})
|
||||
.on( 'click', '.tc-dismiss-notice', function( ev ) {
|
||||
ev.preventDefault();
|
||||
var $_wrapper = $(this).closest( _placeholder_wrapper_selector );
|
||||
|
||||
if ( $_wrapper.length < 1 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
_ajaxActionDo( 'dismiss', _getData( $_wrapper ) ).done( function() {
|
||||
$_wrapper.slideToggle( 'fast' );
|
||||
});
|
||||
} );
|
||||
});
|
||||
})(jQuery, czrapp, _ );
|
||||
+4629
File diff suppressed because it is too large
Load Diff
+2
File diff suppressed because one or more lines are too long
Vendored
+44
File diff suppressed because one or more lines are too long
+1990
File diff suppressed because it is too large
Load Diff
Vendored
+1
File diff suppressed because one or more lines are too long
+9
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* HTML5 Shiv v3.7.0 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
|
||||
*/
|
||||
|
||||
(function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag();
|
||||
a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/[\w\-]+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x<style>article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}</style>";
|
||||
c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="<xyz></xyz>";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode||
|
||||
"undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:"3.7.0",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);
|
||||
if(g)return a.createDocumentFragment();for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d<h;d++)c.createElement(e[d]);return c}};l.html5=e;q(f)})(this,document);
|
||||
+2458
File diff suppressed because it is too large
Load Diff
+2
File diff suppressed because one or more lines are too long
+50
@@ -0,0 +1,50 @@
|
||||
/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license */
|
||||
|
||||
window.matchMedia || (window.matchMedia = function() {
|
||||
"use strict";
|
||||
|
||||
// For browsers that support matchMedium api such as IE 9 and webkit
|
||||
var styleMedia = (window.styleMedia || window.media);
|
||||
|
||||
// For those that don't support matchMedium
|
||||
if (!styleMedia) {
|
||||
var style = document.createElement('style'),
|
||||
script = document.getElementsByTagName('script')[0],
|
||||
info = null;
|
||||
|
||||
style.type = 'text/css';
|
||||
style.id = 'matchmediajs-test';
|
||||
|
||||
if (!script) {
|
||||
document.head.appendChild(style);
|
||||
} else {
|
||||
script.parentNode.insertBefore(style, script);
|
||||
}
|
||||
|
||||
// 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers
|
||||
info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle;
|
||||
|
||||
styleMedia = {
|
||||
matchMedium: function(media) {
|
||||
var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }';
|
||||
|
||||
// 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers
|
||||
if (style.styleSheet) {
|
||||
style.styleSheet.cssText = text;
|
||||
} else {
|
||||
style.textContent = text;
|
||||
}
|
||||
|
||||
// Test if media query is true or false
|
||||
return info.width === '1px';
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return function(media) {
|
||||
return {
|
||||
matches: styleMedia.matchMedium(media || 'all'),
|
||||
media: media || 'all'
|
||||
};
|
||||
};
|
||||
}());
|
||||
+824
@@ -0,0 +1,824 @@
|
||||
/* Modernizr 2.8.3 (Custom Build) | MIT & BSD
|
||||
* Build: http://modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradius-boxshadow-flexbox-flexboxlegacy-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-applicationcache-canvas-canvastext-draganddrop-hashchange-history-audio-video-indexeddb-input-inputtypes-localstorage-postmessage-sessionstorage-websockets-websqldatabase-webworkers-geolocation-inlinesvg-smil-svg-svgclippaths-touch-webgl-shiv-cssclasses-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-load
|
||||
*/
|
||||
;
|
||||
|
||||
window.Modernizr = (function( window, document, undefined ) {
|
||||
|
||||
var version = '2.8.3',
|
||||
|
||||
Modernizr = {},
|
||||
|
||||
enableClasses = true,
|
||||
|
||||
docElement = document.documentElement,
|
||||
|
||||
mod = 'modernizr',
|
||||
modElem = document.createElement(mod),
|
||||
mStyle = modElem.style,
|
||||
|
||||
inputElem = document.createElement('input') ,
|
||||
|
||||
smile = ':)',
|
||||
|
||||
toString = {}.toString,
|
||||
|
||||
prefixes = ' -webkit- -moz- -o- -ms- '.split(' '),
|
||||
|
||||
|
||||
|
||||
omPrefixes = 'Webkit Moz O ms',
|
||||
|
||||
cssomPrefixes = omPrefixes.split(' '),
|
||||
|
||||
domPrefixes = omPrefixes.toLowerCase().split(' '),
|
||||
|
||||
ns = {'svg': 'http://www.w3.org/2000/svg'},
|
||||
|
||||
tests = {},
|
||||
inputs = {},
|
||||
attrs = {},
|
||||
|
||||
classes = [],
|
||||
|
||||
slice = classes.slice,
|
||||
|
||||
featureName,
|
||||
|
||||
|
||||
injectElementWithStyles = function( rule, callback, nodes, testnames ) {
|
||||
|
||||
var style, ret, node, docOverflow,
|
||||
div = document.createElement('div'),
|
||||
body = document.body,
|
||||
fakeBody = body || document.createElement('body');
|
||||
|
||||
if ( parseInt(nodes, 10) ) {
|
||||
while ( nodes-- ) {
|
||||
node = document.createElement('div');
|
||||
node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
|
||||
div.appendChild(node);
|
||||
}
|
||||
}
|
||||
|
||||
style = ['­','<style id="s', mod, '">', rule, '</style>'].join('');
|
||||
div.id = mod;
|
||||
(body ? div : fakeBody).innerHTML += style;
|
||||
fakeBody.appendChild(div);
|
||||
if ( !body ) {
|
||||
fakeBody.style.background = '';
|
||||
fakeBody.style.overflow = 'hidden';
|
||||
docOverflow = docElement.style.overflow;
|
||||
docElement.style.overflow = 'hidden';
|
||||
docElement.appendChild(fakeBody);
|
||||
}
|
||||
|
||||
ret = callback(div, rule);
|
||||
if ( !body ) {
|
||||
fakeBody.parentNode.removeChild(fakeBody);
|
||||
docElement.style.overflow = docOverflow;
|
||||
} else {
|
||||
div.parentNode.removeChild(div);
|
||||
}
|
||||
|
||||
return !!ret;
|
||||
|
||||
},
|
||||
|
||||
|
||||
|
||||
isEventSupported = (function() {
|
||||
|
||||
var TAGNAMES = {
|
||||
'select': 'input', 'change': 'input',
|
||||
'submit': 'form', 'reset': 'form',
|
||||
'error': 'img', 'load': 'img', 'abort': 'img'
|
||||
};
|
||||
|
||||
function isEventSupported( eventName, element ) {
|
||||
|
||||
element = element || document.createElement(TAGNAMES[eventName] || 'div');
|
||||
eventName = 'on' + eventName;
|
||||
|
||||
var isSupported = eventName in element;
|
||||
|
||||
if ( !isSupported ) {
|
||||
if ( !element.setAttribute ) {
|
||||
element = document.createElement('div');
|
||||
}
|
||||
if ( element.setAttribute && element.removeAttribute ) {
|
||||
element.setAttribute(eventName, '');
|
||||
isSupported = is(element[eventName], 'function');
|
||||
|
||||
if ( !is(element[eventName], 'undefined') ) {
|
||||
element[eventName] = undefined;
|
||||
}
|
||||
element.removeAttribute(eventName);
|
||||
}
|
||||
}
|
||||
|
||||
element = null;
|
||||
return isSupported;
|
||||
}
|
||||
return isEventSupported;
|
||||
})(),
|
||||
|
||||
|
||||
_hasOwnProperty = ({}).hasOwnProperty, hasOwnProp;
|
||||
|
||||
if ( !is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined') ) {
|
||||
hasOwnProp = function (object, property) {
|
||||
return _hasOwnProperty.call(object, property);
|
||||
};
|
||||
}
|
||||
else {
|
||||
hasOwnProp = function (object, property) {
|
||||
return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
if (!Function.prototype.bind) {
|
||||
Function.prototype.bind = function bind(that) {
|
||||
|
||||
var target = this;
|
||||
|
||||
if (typeof target != "function") {
|
||||
throw new TypeError();
|
||||
}
|
||||
|
||||
var args = slice.call(arguments, 1),
|
||||
bound = function () {
|
||||
|
||||
if (this instanceof bound) {
|
||||
|
||||
var F = function(){};
|
||||
F.prototype = target.prototype;
|
||||
var self = new F();
|
||||
|
||||
var result = target.apply(
|
||||
self,
|
||||
args.concat(slice.call(arguments))
|
||||
);
|
||||
if (Object(result) === result) {
|
||||
return result;
|
||||
}
|
||||
return self;
|
||||
|
||||
} else {
|
||||
|
||||
return target.apply(
|
||||
that,
|
||||
args.concat(slice.call(arguments))
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return bound;
|
||||
};
|
||||
}
|
||||
|
||||
function setCss( str ) {
|
||||
mStyle.cssText = str;
|
||||
}
|
||||
|
||||
function setCssAll( str1, str2 ) {
|
||||
return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));
|
||||
}
|
||||
|
||||
function is( obj, type ) {
|
||||
return typeof obj === type;
|
||||
}
|
||||
|
||||
function contains( str, substr ) {
|
||||
return !!~('' + str).indexOf(substr);
|
||||
}
|
||||
|
||||
function testProps( props, prefixed ) {
|
||||
for ( var i in props ) {
|
||||
var prop = props[i];
|
||||
if ( !contains(prop, "-") && mStyle[prop] !== undefined ) {
|
||||
return prefixed == 'pfx' ? prop : true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function testDOMProps( props, obj, elem ) {
|
||||
for ( var i in props ) {
|
||||
var item = obj[props[i]];
|
||||
if ( item !== undefined) {
|
||||
|
||||
if (elem === false) return props[i];
|
||||
|
||||
if (is(item, 'function')){
|
||||
return item.bind(elem || obj);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function testPropsAll( prop, prefixed, elem ) {
|
||||
|
||||
var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
|
||||
props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
|
||||
|
||||
if(is(prefixed, "string") || is(prefixed, "undefined")) {
|
||||
return testProps(props, prefixed);
|
||||
|
||||
} else {
|
||||
props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
|
||||
return testDOMProps(props, prefixed, elem);
|
||||
}
|
||||
} tests['flexbox'] = function() {
|
||||
return testPropsAll('flexWrap');
|
||||
};
|
||||
|
||||
|
||||
tests['flexboxlegacy'] = function() {
|
||||
return testPropsAll('boxDirection');
|
||||
};
|
||||
|
||||
|
||||
tests['canvas'] = function() {
|
||||
var elem = document.createElement('canvas');
|
||||
return !!(elem.getContext && elem.getContext('2d'));
|
||||
};
|
||||
|
||||
tests['canvastext'] = function() {
|
||||
return !!(Modernizr['canvas'] && is(document.createElement('canvas').getContext('2d').fillText, 'function'));
|
||||
};
|
||||
|
||||
|
||||
|
||||
tests['webgl'] = function() {
|
||||
return !!window.WebGLRenderingContext;
|
||||
};
|
||||
|
||||
|
||||
tests['touch'] = function() {
|
||||
var bool;
|
||||
|
||||
if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
|
||||
bool = true;
|
||||
} else {
|
||||
injectElementWithStyles(['@media (',prefixes.join('touch-enabled),('),mod,')','{#modernizr{top:9px;position:absolute}}'].join(''), function( node ) {
|
||||
bool = node.offsetTop === 9;
|
||||
});
|
||||
}
|
||||
|
||||
return bool;
|
||||
};
|
||||
|
||||
|
||||
|
||||
tests['geolocation'] = function() {
|
||||
return 'geolocation' in navigator;
|
||||
};
|
||||
|
||||
|
||||
tests['postmessage'] = function() {
|
||||
return !!window.postMessage;
|
||||
};
|
||||
|
||||
|
||||
tests['websqldatabase'] = function() {
|
||||
return !!window.openDatabase;
|
||||
};
|
||||
|
||||
tests['indexedDB'] = function() {
|
||||
return !!testPropsAll("indexedDB", window);
|
||||
};
|
||||
|
||||
tests['hashchange'] = function() {
|
||||
return isEventSupported('hashchange', window) && (document.documentMode === undefined || document.documentMode > 7);
|
||||
};
|
||||
|
||||
tests['history'] = function() {
|
||||
return !!(window.history && history.pushState);
|
||||
};
|
||||
|
||||
tests['draganddrop'] = function() {
|
||||
var div = document.createElement('div');
|
||||
return ('draggable' in div) || ('ondragstart' in div && 'ondrop' in div);
|
||||
};
|
||||
|
||||
tests['websockets'] = function() {
|
||||
return 'WebSocket' in window || 'MozWebSocket' in window;
|
||||
};
|
||||
|
||||
|
||||
tests['rgba'] = function() {
|
||||
setCss('background-color:rgba(150,255,150,.5)');
|
||||
|
||||
return contains(mStyle.backgroundColor, 'rgba');
|
||||
};
|
||||
|
||||
tests['hsla'] = function() {
|
||||
setCss('background-color:hsla(120,40%,100%,.5)');
|
||||
|
||||
return contains(mStyle.backgroundColor, 'rgba') || contains(mStyle.backgroundColor, 'hsla');
|
||||
};
|
||||
|
||||
tests['multiplebgs'] = function() {
|
||||
setCss('background:url(https://),url(https://),red url(https://)');
|
||||
|
||||
return (/(url\s*\(.*?){3}/).test(mStyle.background);
|
||||
}; tests['backgroundsize'] = function() {
|
||||
return testPropsAll('backgroundSize');
|
||||
};
|
||||
|
||||
tests['borderimage'] = function() {
|
||||
return testPropsAll('borderImage');
|
||||
};
|
||||
|
||||
|
||||
|
||||
tests['borderradius'] = function() {
|
||||
return testPropsAll('borderRadius');
|
||||
};
|
||||
|
||||
tests['boxshadow'] = function() {
|
||||
return testPropsAll('boxShadow');
|
||||
};
|
||||
|
||||
tests['textshadow'] = function() {
|
||||
return document.createElement('div').style.textShadow === '';
|
||||
};
|
||||
|
||||
|
||||
tests['opacity'] = function() {
|
||||
setCssAll('opacity:.55');
|
||||
|
||||
return (/^0.55$/).test(mStyle.opacity);
|
||||
};
|
||||
|
||||
|
||||
tests['cssanimations'] = function() {
|
||||
return testPropsAll('animationName');
|
||||
};
|
||||
|
||||
|
||||
tests['csscolumns'] = function() {
|
||||
return testPropsAll('columnCount');
|
||||
};
|
||||
|
||||
|
||||
tests['cssgradients'] = function() {
|
||||
var str1 = 'background-image:',
|
||||
str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));',
|
||||
str3 = 'linear-gradient(left top,#9f9, white);';
|
||||
|
||||
setCss(
|
||||
(str1 + '-webkit- '.split(' ').join(str2 + str1) +
|
||||
prefixes.join(str3 + str1)).slice(0, -str1.length)
|
||||
);
|
||||
|
||||
return contains(mStyle.backgroundImage, 'gradient');
|
||||
};
|
||||
|
||||
|
||||
tests['cssreflections'] = function() {
|
||||
return testPropsAll('boxReflect');
|
||||
};
|
||||
|
||||
|
||||
tests['csstransforms'] = function() {
|
||||
return !!testPropsAll('transform');
|
||||
};
|
||||
|
||||
|
||||
tests['csstransforms3d'] = function() {
|
||||
|
||||
var ret = !!testPropsAll('perspective');
|
||||
|
||||
if ( ret && 'webkitPerspective' in docElement.style ) {
|
||||
|
||||
injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}', function( node, rule ) {
|
||||
ret = node.offsetLeft === 9 && node.offsetHeight === 3;
|
||||
});
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
tests['csstransitions'] = function() {
|
||||
return testPropsAll('transition');
|
||||
};
|
||||
|
||||
|
||||
|
||||
tests['fontface'] = function() {
|
||||
var bool;
|
||||
|
||||
injectElementWithStyles('@font-face {font-family:"font";src:url("https://")}', function( node, rule ) {
|
||||
var style = document.getElementById('smodernizr'),
|
||||
sheet = style.sheet || style.styleSheet,
|
||||
cssText = sheet ? (sheet.cssRules && sheet.cssRules[0] ? sheet.cssRules[0].cssText : sheet.cssText || '') : '';
|
||||
|
||||
bool = /src/i.test(cssText) && cssText.indexOf(rule.split(' ')[0]) === 0;
|
||||
});
|
||||
|
||||
return bool;
|
||||
};
|
||||
|
||||
tests['generatedcontent'] = function() {
|
||||
var bool;
|
||||
|
||||
injectElementWithStyles(['#',mod,'{font:0/0 a}#',mod,':after{content:"',smile,'";visibility:hidden;font:3px/1 a}'].join(''), function( node ) {
|
||||
bool = node.offsetHeight >= 3;
|
||||
});
|
||||
|
||||
return bool;
|
||||
};
|
||||
tests['video'] = function() {
|
||||
var elem = document.createElement('video'),
|
||||
bool = false;
|
||||
|
||||
try {
|
||||
if ( bool = !!elem.canPlayType ) {
|
||||
bool = new Boolean(bool);
|
||||
bool.ogg = elem.canPlayType('video/ogg; codecs="theora"') .replace(/^no$/,'');
|
||||
|
||||
bool.h264 = elem.canPlayType('video/mp4; codecs="avc1.42E01E"') .replace(/^no$/,'');
|
||||
|
||||
bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,'');
|
||||
}
|
||||
|
||||
} catch(e) { }
|
||||
|
||||
return bool;
|
||||
};
|
||||
|
||||
tests['audio'] = function() {
|
||||
var elem = document.createElement('audio'),
|
||||
bool = false;
|
||||
|
||||
try {
|
||||
if ( bool = !!elem.canPlayType ) {
|
||||
bool = new Boolean(bool);
|
||||
bool.ogg = elem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,'');
|
||||
bool.mp3 = elem.canPlayType('audio/mpeg;') .replace(/^no$/,'');
|
||||
|
||||
bool.wav = elem.canPlayType('audio/wav; codecs="1"') .replace(/^no$/,'');
|
||||
bool.m4a = ( elem.canPlayType('audio/x-m4a;') ||
|
||||
elem.canPlayType('audio/aac;')) .replace(/^no$/,'');
|
||||
}
|
||||
} catch(e) { }
|
||||
|
||||
return bool;
|
||||
};
|
||||
|
||||
|
||||
tests['localstorage'] = function() {
|
||||
try {
|
||||
localStorage.setItem(mod, mod);
|
||||
localStorage.removeItem(mod);
|
||||
return true;
|
||||
} catch(e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
tests['sessionstorage'] = function() {
|
||||
try {
|
||||
sessionStorage.setItem(mod, mod);
|
||||
sessionStorage.removeItem(mod);
|
||||
return true;
|
||||
} catch(e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
tests['webworkers'] = function() {
|
||||
return !!window.Worker;
|
||||
};
|
||||
|
||||
|
||||
tests['applicationcache'] = function() {
|
||||
return !!window.applicationCache;
|
||||
};
|
||||
|
||||
|
||||
tests['svg'] = function() {
|
||||
return !!document.createElementNS && !!document.createElementNS(ns.svg, 'svg').createSVGRect;
|
||||
};
|
||||
|
||||
tests['inlinesvg'] = function() {
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = '<svg/>';
|
||||
return (div.firstChild && div.firstChild.namespaceURI) == ns.svg;
|
||||
};
|
||||
|
||||
tests['smil'] = function() {
|
||||
return !!document.createElementNS && /SVGAnimate/.test(toString.call(document.createElementNS(ns.svg, 'animate')));
|
||||
};
|
||||
|
||||
|
||||
tests['svgclippaths'] = function() {
|
||||
return !!document.createElementNS && /SVGClipPath/.test(toString.call(document.createElementNS(ns.svg, 'clipPath')));
|
||||
};
|
||||
|
||||
function webforms() {
|
||||
Modernizr['input'] = (function( props ) {
|
||||
for ( var i = 0, len = props.length; i < len; i++ ) {
|
||||
attrs[ props[i] ] = !!(props[i] in inputElem);
|
||||
}
|
||||
if (attrs.list){
|
||||
attrs.list = !!(document.createElement('datalist') && window.HTMLDataListElement);
|
||||
}
|
||||
return attrs;
|
||||
})('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' '));
|
||||
Modernizr['inputtypes'] = (function(props) {
|
||||
|
||||
for ( var i = 0, bool, inputElemType, defaultView, len = props.length; i < len; i++ ) {
|
||||
|
||||
inputElem.setAttribute('type', inputElemType = props[i]);
|
||||
bool = inputElem.type !== 'text';
|
||||
|
||||
if ( bool ) {
|
||||
|
||||
inputElem.value = smile;
|
||||
inputElem.style.cssText = 'position:absolute;visibility:hidden;';
|
||||
|
||||
if ( /^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined ) {
|
||||
|
||||
docElement.appendChild(inputElem);
|
||||
defaultView = document.defaultView;
|
||||
|
||||
bool = defaultView.getComputedStyle &&
|
||||
defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' &&
|
||||
(inputElem.offsetHeight !== 0);
|
||||
|
||||
docElement.removeChild(inputElem);
|
||||
|
||||
} else if ( /^(search|tel)$/.test(inputElemType) ){
|
||||
} else if ( /^(url|email)$/.test(inputElemType) ) {
|
||||
bool = inputElem.checkValidity && inputElem.checkValidity() === false;
|
||||
|
||||
} else {
|
||||
bool = inputElem.value != smile;
|
||||
}
|
||||
}
|
||||
|
||||
inputs[ props[i] ] = !!bool;
|
||||
}
|
||||
return inputs;
|
||||
})('search tel url email datetime date month week time datetime-local number range color'.split(' '));
|
||||
}
|
||||
for ( var feature in tests ) {
|
||||
if ( hasOwnProp(tests, feature) ) {
|
||||
featureName = feature.toLowerCase();
|
||||
Modernizr[featureName] = tests[feature]();
|
||||
|
||||
classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);
|
||||
}
|
||||
}
|
||||
|
||||
Modernizr.input || webforms();
|
||||
|
||||
|
||||
Modernizr.addTest = function ( feature, test ) {
|
||||
if ( typeof feature == 'object' ) {
|
||||
for ( var key in feature ) {
|
||||
if ( hasOwnProp( feature, key ) ) {
|
||||
Modernizr.addTest( key, feature[ key ] );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
feature = feature.toLowerCase();
|
||||
|
||||
if ( Modernizr[feature] !== undefined ) {
|
||||
return Modernizr;
|
||||
}
|
||||
|
||||
test = typeof test == 'function' ? test() : test;
|
||||
|
||||
if (typeof enableClasses !== "undefined" && enableClasses) {
|
||||
docElement.className += ' ' + (test ? '' : 'no-') + feature;
|
||||
}
|
||||
Modernizr[feature] = test;
|
||||
|
||||
}
|
||||
|
||||
return Modernizr;
|
||||
};
|
||||
|
||||
|
||||
setCss('');
|
||||
modElem = inputElem = null;
|
||||
|
||||
;(function(window, document) {
|
||||
var version = '3.7.0';
|
||||
|
||||
var options = window.html5 || {};
|
||||
|
||||
var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
|
||||
|
||||
var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
|
||||
|
||||
var supportsHtml5Styles;
|
||||
|
||||
var expando = '_html5shiv';
|
||||
|
||||
var expanID = 0;
|
||||
|
||||
var expandoData = {};
|
||||
|
||||
var supportsUnknownElements;
|
||||
|
||||
(function() {
|
||||
try {
|
||||
var a = document.createElement('a');
|
||||
a.innerHTML = '<xyz></xyz>';
|
||||
supportsHtml5Styles = ('hidden' in a);
|
||||
|
||||
supportsUnknownElements = a.childNodes.length == 1 || (function() {
|
||||
(document.createElement)('a');
|
||||
var frag = document.createDocumentFragment();
|
||||
return (
|
||||
typeof frag.cloneNode == 'undefined' ||
|
||||
typeof frag.createDocumentFragment == 'undefined' ||
|
||||
typeof frag.createElement == 'undefined'
|
||||
);
|
||||
}());
|
||||
} catch(e) {
|
||||
supportsHtml5Styles = true;
|
||||
supportsUnknownElements = true;
|
||||
}
|
||||
|
||||
}());
|
||||
|
||||
function addStyleSheet(ownerDocument, cssText) {
|
||||
var p = ownerDocument.createElement('p'),
|
||||
parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
|
||||
|
||||
p.innerHTML = 'x<style>' + cssText + '</style>';
|
||||
return parent.insertBefore(p.lastChild, parent.firstChild);
|
||||
}
|
||||
|
||||
function getElements() {
|
||||
var elements = html5.elements;
|
||||
return typeof elements == 'string' ? elements.split(' ') : elements;
|
||||
}
|
||||
|
||||
function getExpandoData(ownerDocument) {
|
||||
var data = expandoData[ownerDocument[expando]];
|
||||
if (!data) {
|
||||
data = {};
|
||||
expanID++;
|
||||
ownerDocument[expando] = expanID;
|
||||
expandoData[expanID] = data;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function createElement(nodeName, ownerDocument, data){
|
||||
if (!ownerDocument) {
|
||||
ownerDocument = document;
|
||||
}
|
||||
if(supportsUnknownElements){
|
||||
return ownerDocument.createElement(nodeName);
|
||||
}
|
||||
if (!data) {
|
||||
data = getExpandoData(ownerDocument);
|
||||
}
|
||||
var node;
|
||||
|
||||
if (data.cache[nodeName]) {
|
||||
node = data.cache[nodeName].cloneNode();
|
||||
} else if (saveClones.test(nodeName)) {
|
||||
node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
|
||||
} else {
|
||||
node = data.createElem(nodeName);
|
||||
}
|
||||
|
||||
return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node;
|
||||
}
|
||||
|
||||
function createDocumentFragment(ownerDocument, data){
|
||||
if (!ownerDocument) {
|
||||
ownerDocument = document;
|
||||
}
|
||||
if(supportsUnknownElements){
|
||||
return ownerDocument.createDocumentFragment();
|
||||
}
|
||||
data = data || getExpandoData(ownerDocument);
|
||||
var clone = data.frag.cloneNode(),
|
||||
i = 0,
|
||||
elems = getElements(),
|
||||
l = elems.length;
|
||||
for(;i<l;i++){
|
||||
clone.createElement(elems[i]);
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
function shivMethods(ownerDocument, data) {
|
||||
if (!data.cache) {
|
||||
data.cache = {};
|
||||
data.createElem = ownerDocument.createElement;
|
||||
data.createFrag = ownerDocument.createDocumentFragment;
|
||||
data.frag = data.createFrag();
|
||||
}
|
||||
|
||||
|
||||
ownerDocument.createElement = function(nodeName) {
|
||||
if (!html5.shivMethods) {
|
||||
return data.createElem(nodeName);
|
||||
}
|
||||
return createElement(nodeName, ownerDocument, data);
|
||||
};
|
||||
|
||||
ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
|
||||
'var n=f.cloneNode(),c=n.createElement;' +
|
||||
'h.shivMethods&&(' +
|
||||
getElements().join().replace(/[\w\-]+/g, function(nodeName) {
|
||||
data.createElem(nodeName);
|
||||
data.frag.createElement(nodeName);
|
||||
return 'c("' + nodeName + '")';
|
||||
}) +
|
||||
');return n}'
|
||||
)(html5, data.frag);
|
||||
}
|
||||
|
||||
function shivDocument(ownerDocument) {
|
||||
if (!ownerDocument) {
|
||||
ownerDocument = document;
|
||||
}
|
||||
var data = getExpandoData(ownerDocument);
|
||||
|
||||
if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
|
||||
data.hasCSS = !!addStyleSheet(ownerDocument,
|
||||
'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' +
|
||||
'mark{background:#FF0;color:#000}' +
|
||||
'template{display:none}'
|
||||
);
|
||||
}
|
||||
if (!supportsUnknownElements) {
|
||||
shivMethods(ownerDocument, data);
|
||||
}
|
||||
return ownerDocument;
|
||||
}
|
||||
|
||||
var html5 = {
|
||||
|
||||
'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video',
|
||||
|
||||
'version': version,
|
||||
|
||||
'shivCSS': (options.shivCSS !== false),
|
||||
|
||||
'supportsUnknownElements': supportsUnknownElements,
|
||||
|
||||
'shivMethods': (options.shivMethods !== false),
|
||||
|
||||
'type': 'default',
|
||||
|
||||
'shivDocument': shivDocument,
|
||||
|
||||
createElement: createElement,
|
||||
|
||||
createDocumentFragment: createDocumentFragment
|
||||
};
|
||||
|
||||
window.html5 = html5;
|
||||
|
||||
shivDocument(document);
|
||||
|
||||
}(this, document));
|
||||
|
||||
Modernizr._version = version;
|
||||
|
||||
Modernizr._prefixes = prefixes;
|
||||
Modernizr._domPrefixes = domPrefixes;
|
||||
Modernizr._cssomPrefixes = cssomPrefixes;
|
||||
|
||||
|
||||
Modernizr.hasEvent = isEventSupported;
|
||||
|
||||
Modernizr.testProp = function(prop){
|
||||
return testProps([prop]);
|
||||
};
|
||||
|
||||
Modernizr.testAllProps = testPropsAll;
|
||||
|
||||
|
||||
Modernizr.testStyles = injectElementWithStyles; docElement.className = docElement.className.replace(/(^|\s)no-js(\s|$)/, '$1$2') +
|
||||
|
||||
(enableClasses ? ' js ' + classes.join(' ') : '');
|
||||
|
||||
return Modernizr;
|
||||
|
||||
})(this, this.document);
|
||||
/*yepnope1.5.4|WTFPL*/
|
||||
(function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f<d;f++)g=a[f].split("="),(e=z[g.shift()])&&(c=e(c,g));for(f=0;f<b;f++)c=x[f](c);return c}function g(a,e,f,g,h){var i=b(a),j=i.autoCallback;i.url.split(".").pop().split("?").shift(),i.bypass||(e&&(e=d(e)?e:e[a]||e[g]||e[a.split("/").pop().split("?")[0]]),i.instead?i.instead(a,e,f,g,h):(y[i.url]?i.noexec=!0:y[i.url]=1,f.load(i.url,i.forceCSS||!i.forceJS&&"css"==i.url.split(".").pop().split("?").shift()?"c":c,i.noexec,i.attrs,i.timeout),(d(e)||d(j))&&f.load(function(){k(),e&&e(i.origUrl,h,g),j&&j(i.origUrl,h,g),y[i.url]=2})))}function h(a,b){function c(a,c){if(a){if(e(a))c||(j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}),g(a,j,b,0,h);else if(Object(a)===a)for(n in m=function(){var b=0,c;for(c in a)a.hasOwnProperty(c)&&b++;return b}(),a)a.hasOwnProperty(n)&&(!c&&!--m&&(d(j)?j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}:j[n]=function(a){return function(){var b=[].slice.call(arguments);a&&a.apply(this,b),l()}}(k[n])),g(a[n],j,b,n,h))}else!c&&l()}var h=!!a.test,i=a.load||a.both,j=a.callback||f,k=j,l=a.complete||f,m,n;c(h?a.yep:a.nope,!!i),i&&c(i)}var i,j,l=this.yepnope.loader;if(e(a))g(a,0,l,0);else if(w(a))for(i=0;i<a.length;i++)j=a[i],e(j)?g(j,0,l,0):w(j)?B(j):Object(j)===j&&h(j,l);else Object(a)===a&&h(a,l)},B.addPrefix=function(a,b){z[a]=b},B.addFilter=function(a){x.push(a)},B.errorTimeout=1e4,null==b.readyState&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",A=function(){b.removeEventListener("DOMContentLoaded",A,0),b.readyState="complete"},0)),a.yepnope=k(),a.yepnope.executeStack=h,a.yepnope.injectJs=function(a,c,d,e,i,j){var k=b.createElement("script"),l,o,e=e||B.errorTimeout;k.src=a;for(o in d)k.setAttribute(o,d[o]);c=j?h:c||f,k.onreadystatechange=k.onload=function(){!l&&g(k.readyState)&&(l=1,c(),k.onload=k.onreadystatechange=null)},m(function(){l||(l=1,c(1))},e),i?k.onload():n.parentNode.insertBefore(k,n)},a.yepnope.injectCss=function(a,c,d,e,g,i){var e=b.createElement("link"),j,c=i?h:c||f;e.href=a,e.rel="stylesheet",e.type="text/css";for(j in d)e.setAttribute(j,d[j]);g||(n.parentNode.insertBefore(e,n),m(c,0))}})(this,document);
|
||||
Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0));};
|
||||
;
|
||||
wp-content/plugins/nimble-builder/assets/front/js/__FRONT_JS_FMK_TO_BE_UPDATED/libs/modernizr.min.js
Vendored
+1
File diff suppressed because one or more lines are too long
+157
@@ -0,0 +1,157 @@
|
||||
// addEventListener Polyfill ie9- http://stackoverflow.com/a/27790212
|
||||
window.addEventListener = window.addEventListener || function (e, f) { window.attachEvent('on' + e, f); };
|
||||
|
||||
|
||||
// Datenow Polyfill ie9- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now
|
||||
if (!Date.now) {
|
||||
Date.now = function now() {
|
||||
return new Date().getTime();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// Object.create monkey patch ie8 http://stackoverflow.com/a/18020326
|
||||
if ( ! Object.create ) {
|
||||
Object.create = function(proto, props) {
|
||||
if (typeof props !== "undefined") {
|
||||
throw "The multiple-argument version of Object.create is not provided by this browser and cannot be shimmed.";
|
||||
}
|
||||
function ctor() { }
|
||||
|
||||
ctor.prototype = proto;
|
||||
return new ctor();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
|
||||
// filter() was added to the ECMA-262 standard in the 5th edition; as such it may not be present in all implementations of the standard.
|
||||
// You can work around this by inserting the following code at the beginning of your scripts, allowing use of filter() in ECMA-262 implementations which do not natively support it.
|
||||
// This algorithm is exactly the one specified in ECMA-262, 5th edition, assuming that fn.call evaluates to the original value of Function.prototype.call(), and that Array.prototype.push() has its original value.
|
||||
if ( ! Array.prototype.filter ) {
|
||||
Array.prototype.filter = function(fun/*, thisArg*/) {
|
||||
'use strict';
|
||||
|
||||
if (this === void 0 || this === null) {
|
||||
throw new TypeError();
|
||||
}
|
||||
|
||||
var t = Object(this);
|
||||
var len = t.length >>> 0;
|
||||
if (typeof fun !== 'function') {
|
||||
throw new TypeError();
|
||||
}
|
||||
|
||||
var res = [];
|
||||
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (i in t) {
|
||||
var val = t[i];
|
||||
|
||||
// NOTE: Technically this should Object.defineProperty at
|
||||
// the next index, as push can be affected by
|
||||
// properties on Object.prototype and Array.prototype.
|
||||
// But that method's new, and collisions should be
|
||||
// rare, so use the more-compatible alternative.
|
||||
if (fun.call(thisArg, val, i, t)) {
|
||||
res.push(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
//map was added to the ECMA-262 standard in the 5th edition; as such it may not be present in all implementations of the standard. You can work around this by inserting the following code at the beginning of your scripts, allowing use of map in implementations which do not natively support it. This algorithm is exactly the one specified in ECMA-262, 5th edition, assuming Object, TypeError, and Array have their original values and that callback.call evaluates to the original value of Function.prototype.call.
|
||||
// Production steps of ECMA-262, Edition 5, 15.4.4.19
|
||||
// Reference: http://es5.github.io/#x15.4.4.19
|
||||
if (!Array.prototype.map) {
|
||||
|
||||
Array.prototype.map = function(callback, thisArg) {
|
||||
|
||||
var T, A, k;
|
||||
|
||||
if (this == null) {
|
||||
throw new TypeError(' this is null or not defined');
|
||||
}
|
||||
|
||||
// 1. Let O be the result of calling ToObject passing the |this|
|
||||
// value as the argument.
|
||||
var O = Object(this);
|
||||
|
||||
// 2. Let lenValue be the result of calling the Get internal
|
||||
// method of O with the argument "length".
|
||||
// 3. Let len be ToUint32(lenValue).
|
||||
var len = O.length >>> 0;
|
||||
|
||||
// 4. If IsCallable(callback) is false, throw a TypeError exception.
|
||||
// See: http://es5.github.com/#x9.11
|
||||
if (typeof callback !== 'function') {
|
||||
throw new TypeError(callback + ' is not a function');
|
||||
}
|
||||
|
||||
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
|
||||
if (arguments.length > 1) {
|
||||
T = thisArg;
|
||||
}
|
||||
|
||||
// 6. Let A be a new array created as if by the expression new Array(len)
|
||||
// where Array is the standard built-in constructor with that name and
|
||||
// len is the value of len.
|
||||
A = new Array(len);
|
||||
|
||||
// 7. Let k be 0
|
||||
k = 0;
|
||||
|
||||
// 8. Repeat, while k < len
|
||||
while (k < len) {
|
||||
|
||||
var kValue, mappedValue;
|
||||
|
||||
// a. Let Pk be ToString(k).
|
||||
// This is implicit for LHS operands of the in operator
|
||||
// b. Let kPresent be the result of calling the HasProperty internal
|
||||
// method of O with argument Pk.
|
||||
// This step can be combined with c
|
||||
// c. If kPresent is true, then
|
||||
if (k in O) {
|
||||
|
||||
// i. Let kValue be the result of calling the Get internal
|
||||
// method of O with argument Pk.
|
||||
kValue = O[k];
|
||||
|
||||
// ii. Let mappedValue be the result of calling the Call internal
|
||||
// method of callback with T as the this value and argument
|
||||
// list containing kValue, k, and O.
|
||||
mappedValue = callback.call(T, kValue, k, O);
|
||||
|
||||
// iii. Call the DefineOwnProperty internal method of A with arguments
|
||||
// Pk, Property Descriptor
|
||||
// { Value: mappedValue,
|
||||
// Writable: true,
|
||||
// Enumerable: true,
|
||||
// Configurable: true },
|
||||
// and false.
|
||||
|
||||
// In browsers that support Object.defineProperty, use the following:
|
||||
// Object.defineProperty(A, k, {
|
||||
// value: mappedValue,
|
||||
// writable: true,
|
||||
// enumerable: true,
|
||||
// configurable: true
|
||||
// });
|
||||
|
||||
// For best browser support, use the following:
|
||||
A[k] = mappedValue;
|
||||
}
|
||||
// d. Increase k by 1.
|
||||
k++;
|
||||
}
|
||||
|
||||
// 9. return A
|
||||
return A;
|
||||
};
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
/*! addEventListener Polyfill ie9- http://stackoverflow.com/a/27790212*/
|
||||
window.addEventListener=window.addEventListener||function(a,b){window.attachEvent("on"+a,b)},/*! Datenow Polyfill ie9- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now */
|
||||
Date.now||(Date.now=function(){return(new Date).getTime()}),/*! Object.create monkey patch ie8 http://stackoverflow.com/a/18020326 */
|
||||
Object.create||(Object.create=function(a,b){function c(){}if("undefined"!=typeof b)throw"The multiple-argument version of Object.create is not provided by this browser and cannot be shimmed.";return c.prototype=a,new c}),/*! https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter */
|
||||
Array.prototype.filter||(Array.prototype.filter=function(a){"use strict";if(void 0===this||null===this)throw new TypeError;var b=Object(this),c=b.length>>>0;if("function"!=typeof a)throw new TypeError;for(var d=[],e=arguments.length>=2?arguments[1]:void 0,f=0;f<c;f++)if(f in b){var g=b[f];a.call(e,g,f,b)&&d.push(g)}return d}),/*! map was added to the ECMA-262 standard in the 5th edition */
|
||||
Array.prototype.map||(Array.prototype.map=function(a,b){var c,d,e;if(null===this)throw new TypeError(" this is null or not defined");var f=Object(this),g=f.length>>>0;if("function"!=typeof a)throw new TypeError(a+" is not a function");for(arguments.length>1&&(c=b),d=new Array(g),e=0;e<g;){var h,i;e in f&&(h=f[e],i=a.call(c,h,e,f),d[e]=i),e++}return d}),/*! Array.from was added to the ECMA-262 standard in the 6th edition (ES2015) */
|
||||
Array.from||(Array.from=function(){var a=Object.prototype.toString,b=function(b){return"function"==typeof b||"[object Function]"===a.call(b)},c=function(a){var b=Number(a);return isNaN(b)?0:0!==b&&isFinite(b)?(b>0?1:-1)*Math.floor(Math.abs(b)):b},d=Math.pow(2,53)-1,e=function(a){var b=c(a);return Math.min(Math.max(b,0),d)};return function(a){var c=this,d=Object(a);if(null==a)throw new TypeError("Array.from requires an array-like object - not null or undefined");var f,g=arguments.length>1?arguments[1]:void 0;if("undefined"!=typeof g){if(!b(g))throw new TypeError("Array.from: when provided, the second argument must be a function");arguments.length>2&&(f=arguments[2])}for(var h,i=e(d.length),j=b(c)?Object(new c(i)):new Array(i),k=0;k<i;)h=d[k],g?j[k]="undefined"==typeof f?g(h,k):g.call(f,h,k):j[k]=h,k+=1;return j.length=i,j}}());
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
// modified version of
|
||||
// outline.js (https://github.com/lindsayevans/outline.js)
|
||||
// based on http://www.paciellogroup.com/blog/2012/04/how-to-remove-css-outlines-in-an-accessible-manner/
|
||||
var tcOutline;
|
||||
(function(d){
|
||||
tcOutline = function() {
|
||||
var style_element = d.createElement('STYLE'),
|
||||
dom_events = 'addEventListener' in d,
|
||||
add_event_listener = function(type, callback){
|
||||
// Basic cross-browser event handling
|
||||
if(dom_events){
|
||||
d.addEventListener(type, callback);
|
||||
}else{
|
||||
d.attachEvent('on' + type, callback);
|
||||
}
|
||||
},
|
||||
set_css = function(css_text){
|
||||
// Handle setting of <style> element contents in IE8
|
||||
if ( !!style_element.styleSheet )
|
||||
style_element.styleSheet.cssText = css_text;
|
||||
else
|
||||
style_element.innerHTML = css_text;
|
||||
}
|
||||
;
|
||||
|
||||
d.getElementsByTagName('HEAD')[0].appendChild(style_element);
|
||||
|
||||
// Using mousedown instead of mouseover, so that previously focused elements don't lose focus ring on mouse move
|
||||
add_event_listener('mousedown', function(){
|
||||
set_css('input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus,select:focus,span:focus,a:focus,button{outline:none!important;-webkit-box-shadow:none!important;box-shadow:none!important;}input[type=file]::-moz-focus-inner,input[type=radio]::-moz-focus-inner,input[type=checkbox]::-moz-focus-inner,select::-moz-focus-inner,a::-moz-focus-inner{border:0;}');
|
||||
});
|
||||
|
||||
add_event_listener('keydown', function(){
|
||||
set_css('');
|
||||
});
|
||||
}
|
||||
})(document);
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
|
||||
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
|
||||
|
||||
// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
|
||||
|
||||
// MIT license
|
||||
(function() {
|
||||
var lastTime = 0;
|
||||
var vendors = ['ms', 'moz', 'webkit', 'o'];
|
||||
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
|
||||
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
|
||||
window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
|
||||
|| window[vendors[x]+'CancelRequestAnimationFrame'];
|
||||
}
|
||||
|
||||
if (!window.requestAnimationFrame)
|
||||
window.requestAnimationFrame = function(callback, element) {
|
||||
var currTime = new Date().getTime();
|
||||
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
|
||||
lastTime = currTime + timeToCall;
|
||||
return window.setTimeout(function() { callback(currTime + timeToCall); },
|
||||
timeToCall);
|
||||
};
|
||||
|
||||
if (!window.cancelAnimationFrame)
|
||||
window.cancelAnimationFrame = function(id) {
|
||||
clearTimeout(id);
|
||||
};
|
||||
}());
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
(function() {
|
||||
var root = (typeof exports === 'undefined' ? window : exports);
|
||||
var config = {
|
||||
// An option to choose a suffix for 2x images
|
||||
retinaImageSuffix : '@2x',
|
||||
|
||||
// Ensure Content-Type is an image before trying to load @2x image
|
||||
// https://github.com/imulus/retinajs/pull/45)
|
||||
check_mime_type: true,
|
||||
|
||||
// Resize high-resolution images to original image's pixel dimensions
|
||||
// https://github.com/imulus/retinajs/issues/8
|
||||
force_original_dimensions: true
|
||||
};
|
||||
|
||||
function Retina() {}
|
||||
|
||||
root.Retina = Retina;
|
||||
|
||||
Retina.configure = function(options) {
|
||||
if (options === null) {
|
||||
options = {};
|
||||
}
|
||||
|
||||
for (var prop in options) {
|
||||
if (options.hasOwnProperty(prop)) {
|
||||
config[prop] = options[prop];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Retina.init = function(context) {
|
||||
if (context === null) {
|
||||
context = root;
|
||||
}
|
||||
context.addEventListener('load', function (){
|
||||
var images = document.getElementsByTagName('img'), imagesLength = images.length, retinaImages = [], i, image;
|
||||
for (i = 0; i < imagesLength; i += 1) {
|
||||
image = images[i];
|
||||
|
||||
if (!!!image.getAttributeNode('data-no-retina')) {
|
||||
if (image.src) {
|
||||
retinaImages.push(new RetinaImage(image));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Retina.isRetina = function(){
|
||||
var mediaQuery = '(-webkit-min-device-pixel-ratio: 1.5), (min--moz-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3/2), (min-resolution: 1.5dppx)';
|
||||
|
||||
if (root.devicePixelRatio > 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (root.matchMedia && root.matchMedia(mediaQuery).matches) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
var regexMatch = /\.[\w\?=]+$/;
|
||||
function suffixReplace (match) {
|
||||
return config.retinaImageSuffix + match;
|
||||
}
|
||||
|
||||
function RetinaImagePath(path, at_2x_path) {
|
||||
this.path = path || '';
|
||||
if (typeof at_2x_path !== 'undefined' && at_2x_path !== null) {
|
||||
this.at_2x_path = at_2x_path;
|
||||
this.perform_check = false;
|
||||
} else {
|
||||
if (undefined !== document.createElement) {
|
||||
var locationObject = document.createElement('a');
|
||||
locationObject.href = this.path;
|
||||
locationObject.pathname = locationObject.pathname.replace(regexMatch, suffixReplace);
|
||||
this.at_2x_path = locationObject.href;
|
||||
} else {
|
||||
var parts = this.path.split('?');
|
||||
parts[0] = parts[0].replace(regexMatch, suffixReplace);
|
||||
this.at_2x_path = parts.join('?');
|
||||
}
|
||||
this.perform_check = true;
|
||||
}
|
||||
}
|
||||
|
||||
root.RetinaImagePath = RetinaImagePath;
|
||||
|
||||
RetinaImagePath.confirmed_paths = [];
|
||||
|
||||
RetinaImagePath.prototype.is_external = function() {
|
||||
return !!(this.path.match(/^https?\:/i) && !this.path.match('//' + document.domain) );
|
||||
};
|
||||
|
||||
RetinaImagePath.prototype.check_2x_variant = function(callback) {
|
||||
var http, that = this;
|
||||
if (!this.perform_check && typeof this.at_2x_path !== 'undefined' && this.at_2x_path !== null) {
|
||||
return callback(true);
|
||||
} else if (this.at_2x_path in RetinaImagePath.confirmed_paths) {
|
||||
return callback(true);
|
||||
} else if (this.is_external()) {
|
||||
return callback(false);
|
||||
} else {
|
||||
http = new XMLHttpRequest();
|
||||
http.open('HEAD', this.at_2x_path);
|
||||
http.onreadystatechange = function() {
|
||||
if (http.readyState !== 4) {
|
||||
return callback(false);
|
||||
}
|
||||
|
||||
if (http.status >= 200 && http.status <= 399) {
|
||||
if (config.check_mime_type) {
|
||||
var type = http.getResponseHeader('Content-Type');
|
||||
if (type === null || !type.match(/^image/i)) {
|
||||
return callback(false);
|
||||
}
|
||||
}
|
||||
|
||||
RetinaImagePath.confirmed_paths.push(that.at_2x_path);
|
||||
return callback(true);
|
||||
} else {
|
||||
return callback(false);
|
||||
}
|
||||
};
|
||||
http.send();
|
||||
}
|
||||
};
|
||||
|
||||
function RetinaImage(el) {
|
||||
this.el = el;
|
||||
this.path = new RetinaImagePath(this.el.getAttribute('src'), this.el.getAttribute('data-at2x'));
|
||||
var that = this;
|
||||
this.path.check_2x_variant(function(hasVariant) {
|
||||
if (hasVariant) {
|
||||
that.swap();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
root.RetinaImage = RetinaImage;
|
||||
|
||||
RetinaImage.prototype.swap = function(path) {
|
||||
if (typeof path === 'undefined') {
|
||||
path = this.path.at_2x_path;
|
||||
}
|
||||
|
||||
var that = this;
|
||||
function load() {
|
||||
if (! that.el.complete) {
|
||||
setTimeout(load, 5);
|
||||
} else {
|
||||
if (config.force_original_dimensions) {
|
||||
if (that.el.offsetWidth == 0 && that.el.offsetHeight == 0) {
|
||||
that.el.setAttribute('width', that.el.naturalWidth);
|
||||
that.el.setAttribute('height', that.el.naturalHeight);
|
||||
} else {
|
||||
that.el.setAttribute('width', that.el.offsetWidth);
|
||||
that.el.setAttribute('height', that.el.offsetHeight);
|
||||
}
|
||||
}
|
||||
|
||||
that.el.setAttribute('src', path);
|
||||
}
|
||||
}
|
||||
load();
|
||||
};
|
||||
|
||||
|
||||
if (Retina.isRetina()) {
|
||||
Retina.init(root);
|
||||
}
|
||||
})();
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
!function(){function a(){}function b(a){return f.retinaImageSuffix+a}function c(a,c){if(this.path=a||"","undefined"!=typeof c&&null!==c)this.at_2x_path=c,this.perform_check=!1;else{if(void 0!==document.createElement){var d=document.createElement("a");d.href=this.path,d.pathname=d.pathname.replace(g,b),this.at_2x_path=d.href}else{var e=this.path.split("?");e[0]=e[0].replace(g,b),this.at_2x_path=e.join("?")}this.perform_check=!0}}function d(a){this.el=a,this.path=new c(this.el.getAttribute("src"),this.el.getAttribute("data-at2x"));var b=this;this.path.check_2x_variant(function(a){a&&b.swap()})}var e="undefined"==typeof exports?window:exports,f={retinaImageSuffix:"@2x",check_mime_type:!0,force_original_dimensions:!0};e.Retina=a,a.configure=function(a){null===a&&(a={});for(var b in a)a.hasOwnProperty(b)&&(f[b]=a[b])},a.init=function(a){null===a&&(a=e),a.addEventListener("load",function(){var a,b,c=document.getElementsByTagName("img"),e=c.length,f=[];for(a=0;e>a;a+=1)b=c[a],b.getAttributeNode("data-no-retina")||b.src&&f.push(new d(b))})},a.isRetina=function(){var a="(-webkit-min-device-pixel-ratio: 1.5), (min--moz-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3/2), (min-resolution: 1.5dppx)";return e.devicePixelRatio>1?!0:!(!e.matchMedia||!e.matchMedia(a).matches)};var g=/\.[\w\?=]+$/;e.RetinaImagePath=c,c.confirmed_paths=[],c.prototype.is_external=function(){return!(!this.path.match(/^https?\:/i)||this.path.match("//"+document.domain))},c.prototype.check_2x_variant=function(a){var b,d=this;return this.perform_check||"undefined"==typeof this.at_2x_path||null===this.at_2x_path?this.at_2x_path in c.confirmed_paths?a(!0):this.is_external()?a(!1):(b=new XMLHttpRequest,b.open("HEAD",this.at_2x_path),b.onreadystatechange=function(){if(4!==b.readyState)return a(!1);if(b.status>=200&&b.status<=399){if(f.check_mime_type){var e=b.getResponseHeader("Content-Type");if(null===e||!e.match(/^image/i))return a(!1)}return c.confirmed_paths.push(d.at_2x_path),a(!0)}return a(!1)},b.send(),void 0):a(!0)},e.RetinaImage=d,d.prototype.swap=function(a){function b(){c.el.complete?(f.force_original_dimensions&&(0==c.el.offsetWidth&&0==c.el.offsetHeight?(c.el.setAttribute("width",c.el.naturalWidth),c.el.setAttribute("height",c.el.naturalHeight)):(c.el.setAttribute("width",c.el.offsetWidth),c.el.setAttribute("height",c.el.offsetHeight))),c.el.setAttribute("src",a)):setTimeout(b,5)}"undefined"==typeof a&&(a=this.path.at_2x_path);var c=this;b()},a.isRetina()&&a.init(e)}();
|
||||
+708
@@ -0,0 +1,708 @@
|
||||
// Customizr version of Galambosi's SmoothScroll
|
||||
|
||||
// SmoothScroll for websites v1.3.8 (Balazs Galambosi)
|
||||
// Licensed under the terms of the MIT license.
|
||||
//
|
||||
// You may use it in your theme if you credit me.
|
||||
// It is also free to use on any individual website.
|
||||
//
|
||||
// Exception:
|
||||
// The only restriction would be not to publish any
|
||||
// extension for browsers or native application
|
||||
// without getting a written permission first.
|
||||
//
|
||||
|
||||
(function () {
|
||||
|
||||
// Scroll Variables (tweakable)
|
||||
var defaultOptions = {
|
||||
|
||||
// Scrolling Core
|
||||
frameRate : 150, // [Hz]
|
||||
animationTime : 400, // [px]
|
||||
stepSize : 120, // [px]
|
||||
|
||||
// Pulse (less tweakable)
|
||||
// ratio of "tail" to "acceleration"
|
||||
pulseAlgorithm : true,
|
||||
pulseScale : 4,
|
||||
pulseNormalize : 1,
|
||||
|
||||
// Acceleration
|
||||
accelerationDelta : 20, // 20
|
||||
accelerationMax : 1, // 1
|
||||
|
||||
// Keyboard Settings
|
||||
keyboardSupport : true, // option
|
||||
arrowScroll : 50, // [px]
|
||||
|
||||
// Other
|
||||
touchpadSupport : true,
|
||||
fixedBackground : true,
|
||||
excluded : ''
|
||||
};
|
||||
|
||||
var options = defaultOptions;
|
||||
|
||||
|
||||
// Other Variables
|
||||
var isExcluded = false;
|
||||
var isFrame = false;
|
||||
var direction = { x: 0, y: 0 };
|
||||
var initDone = false;
|
||||
var root = document.documentElement;
|
||||
var activeElement;
|
||||
var observer;
|
||||
var deltaBuffer = [];
|
||||
var isMac = /^Mac/.test(navigator.platform);
|
||||
|
||||
var key = { left: 37, up: 38, right: 39, down: 40, spacebar: 32,
|
||||
pageup: 33, pagedown: 34, end: 35, home: 36 };
|
||||
|
||||
|
||||
/***********************************************
|
||||
* SETTINGS
|
||||
***********************************************/
|
||||
|
||||
var options = defaultOptions;
|
||||
|
||||
|
||||
/***********************************************
|
||||
* INITIALIZE
|
||||
***********************************************/
|
||||
|
||||
/**
|
||||
* Tests if smooth scrolling is allowed. Shuts down everything if not.
|
||||
*/
|
||||
function initTest() {
|
||||
if (options.keyboardSupport) {
|
||||
addEvent('keydown', keydown);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up scrolls array, determines if frames are involved.
|
||||
*/
|
||||
function init() {
|
||||
|
||||
if (initDone || !document.body) return;
|
||||
|
||||
initDone = true;
|
||||
|
||||
var body = document.body;
|
||||
var html = document.documentElement;
|
||||
var windowHeight = window.innerHeight;
|
||||
var scrollHeight = body.scrollHeight;
|
||||
|
||||
// check compat mode for root element
|
||||
root = (document.compatMode.indexOf('CSS') >= 0) ? html : body;
|
||||
activeElement = body;
|
||||
|
||||
initTest();
|
||||
|
||||
// Checks if this script is running in a frame
|
||||
if (top != self) {
|
||||
isFrame = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This fixes a bug where the areas left and right to
|
||||
* the content does not trigger the onmousewheel event
|
||||
* on some pages. e.g.: html, body { height: 100% }
|
||||
*/
|
||||
else if (scrollHeight > windowHeight &&
|
||||
(body.offsetHeight <= windowHeight ||
|
||||
html.offsetHeight <= windowHeight)) {
|
||||
|
||||
var fullPageElem = document.createElement('div');
|
||||
fullPageElem.style.cssText = 'position:absolute; z-index:-10000; ' +
|
||||
'top:0; left:0; right:0; height:' +
|
||||
root.scrollHeight + 'px';
|
||||
document.body.appendChild(fullPageElem);
|
||||
|
||||
// DOM changed (throttled) to fix height
|
||||
var pendingRefresh;
|
||||
var refresh = function () {
|
||||
if (pendingRefresh) return; // could also be: clearTimeout(pendingRefresh);
|
||||
pendingRefresh = setTimeout(function () {
|
||||
if (isExcluded) return; // could be running after cleanup
|
||||
fullPageElem.style.height = '0';
|
||||
fullPageElem.style.height = root.scrollHeight + 'px';
|
||||
pendingRefresh = null;
|
||||
}, 500); // act rarely to stay fast
|
||||
};
|
||||
|
||||
setTimeout(refresh, 10);
|
||||
|
||||
// TODO: attributeFilter?
|
||||
var config = {
|
||||
attributes: true,
|
||||
childList: true,
|
||||
characterData: false
|
||||
// subtree: true
|
||||
};
|
||||
|
||||
observer = new MutationObserver(refresh);
|
||||
observer.observe(body, config);
|
||||
|
||||
if (root.offsetHeight <= windowHeight) {
|
||||
var clearfix = document.createElement('div');
|
||||
clearfix.style.clear = 'both';
|
||||
body.appendChild(clearfix);
|
||||
}
|
||||
}
|
||||
|
||||
// disable fixed background
|
||||
if (!options.fixedBackground && !isExcluded) {
|
||||
body.style.backgroundAttachment = 'scroll';
|
||||
html.style.backgroundAttachment = 'scroll';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes event listeners and other traces left on the page.
|
||||
*/
|
||||
function cleanup() {
|
||||
observer && observer.disconnect();
|
||||
removeEvent(wheelEvent, wheel);
|
||||
removeEvent('mousedown', mousedown);
|
||||
removeEvent('keydown', keydown);
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
* SCROLLING
|
||||
************************************************/
|
||||
var que = [];
|
||||
var pending = false;
|
||||
var lastScroll = Date.now();
|
||||
|
||||
/**
|
||||
* Pushes scroll actions to the scrolling queue.
|
||||
*/
|
||||
function scrollArray(elem, left, top) {
|
||||
|
||||
directionCheck(left, top);
|
||||
|
||||
if (options.accelerationMax != 1) {
|
||||
var now = Date.now();
|
||||
var elapsed = now - lastScroll;
|
||||
if (elapsed < options.accelerationDelta) {
|
||||
var factor = (1 + (50 / elapsed)) / 2;
|
||||
if (factor > 1) {
|
||||
factor = Math.min(factor, options.accelerationMax);
|
||||
left *= factor;
|
||||
top *= factor;
|
||||
}
|
||||
}
|
||||
lastScroll = Date.now();
|
||||
}
|
||||
|
||||
// push a scroll command
|
||||
que.push({
|
||||
x: left,
|
||||
y: top,
|
||||
lastX: (left < 0) ? 0.99 : -0.99,
|
||||
lastY: (top < 0) ? 0.99 : -0.99,
|
||||
start: Date.now()
|
||||
});
|
||||
|
||||
// don't act if there's a pending queue
|
||||
if (pending) {
|
||||
return;
|
||||
}
|
||||
|
||||
var scrollWindow = (elem === document.body);
|
||||
|
||||
var step = function (time) {
|
||||
|
||||
var now = Date.now();
|
||||
var scrollX = 0;
|
||||
var scrollY = 0;
|
||||
|
||||
for (var i = 0; i < que.length; i++) {
|
||||
|
||||
var item = que[i];
|
||||
var elapsed = now - item.start;
|
||||
var finished = (elapsed >= options.animationTime);
|
||||
|
||||
// scroll position: [0, 1]
|
||||
var position = (finished) ? 1 : elapsed / options.animationTime;
|
||||
|
||||
// easing [optional]
|
||||
if (options.pulseAlgorithm) {
|
||||
position = pulse(position);
|
||||
}
|
||||
|
||||
// only need the difference
|
||||
var x = (item.x * position - item.lastX) >> 0;
|
||||
var y = (item.y * position - item.lastY) >> 0;
|
||||
|
||||
// add this to the total scrolling
|
||||
scrollX += x;
|
||||
scrollY += y;
|
||||
|
||||
// update last values
|
||||
item.lastX += x;
|
||||
item.lastY += y;
|
||||
|
||||
// delete and step back if it's over
|
||||
if (finished) {
|
||||
que.splice(i, 1); i--;
|
||||
}
|
||||
}
|
||||
|
||||
// scroll left and top
|
||||
if (scrollWindow) {
|
||||
window.scrollBy(scrollX, scrollY);
|
||||
}
|
||||
else {
|
||||
if (scrollX) elem.scrollLeft += scrollX;
|
||||
if (scrollY) elem.scrollTop += scrollY;
|
||||
}
|
||||
|
||||
// clean up if there's nothing left to do
|
||||
if (!left && !top) {
|
||||
que = [];
|
||||
}
|
||||
|
||||
if (que.length) {
|
||||
requestFrame(step, elem, (1000 / options.frameRate + 1));
|
||||
} else {
|
||||
pending = false;
|
||||
}
|
||||
};
|
||||
|
||||
// start a new queue of actions
|
||||
requestFrame(step, elem, 0);
|
||||
pending = true;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************
|
||||
* EVENTS
|
||||
***********************************************/
|
||||
|
||||
/**
|
||||
* Mouse wheel handler.
|
||||
* @param {Object} event
|
||||
*/
|
||||
function wheel(event) {
|
||||
|
||||
if (!initDone) {
|
||||
init();
|
||||
}
|
||||
|
||||
var target = event.target;
|
||||
var overflowing = overflowingAncestor(target);
|
||||
|
||||
// use default if there's no overflowing
|
||||
// element or default action is prevented
|
||||
// or it's a zooming event with CTRL
|
||||
if (!overflowing || event.defaultPrevented || event.ctrlKey) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// leave embedded content alone (flash & pdf)
|
||||
if (isNodeName(activeElement, 'embed') ||
|
||||
(isNodeName(target, 'embed') && /\.pdf/i.test(target.src)) ||
|
||||
isNodeName(activeElement, 'object')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var deltaX = -event.wheelDeltaX || event.deltaX || 0;
|
||||
var deltaY = -event.wheelDeltaY || event.deltaY || 0;
|
||||
|
||||
if (isMac) {
|
||||
if (event.wheelDeltaX && isDivisible(event.wheelDeltaX, 120)) {
|
||||
deltaX = -120 * (event.wheelDeltaX / Math.abs(event.wheelDeltaX));
|
||||
}
|
||||
if (event.wheelDeltaY && isDivisible(event.wheelDeltaY, 120)) {
|
||||
deltaY = -120 * (event.wheelDeltaY / Math.abs(event.wheelDeltaY));
|
||||
}
|
||||
}
|
||||
|
||||
// use wheelDelta if deltaX/Y is not available
|
||||
if (!deltaX && !deltaY) {
|
||||
deltaY = -event.wheelDelta || 0;
|
||||
}
|
||||
|
||||
// line based scrolling (Firefox mostly)
|
||||
if (event.deltaMode === 1) {
|
||||
deltaX *= 40;
|
||||
deltaY *= 40;
|
||||
}
|
||||
|
||||
// check if it's a touchpad scroll that should be ignored
|
||||
if (!options.touchpadSupport && isTouchpad(deltaY)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// scale by step size
|
||||
// delta is 120 most of the time
|
||||
// synaptics seems to send 1 sometimes
|
||||
if (Math.abs(deltaX) > 1.2) {
|
||||
deltaX *= options.stepSize / 120;
|
||||
}
|
||||
if (Math.abs(deltaY) > 1.2) {
|
||||
deltaY *= options.stepSize / 120;
|
||||
}
|
||||
|
||||
scrollArray(overflowing, deltaX, deltaY);
|
||||
event.preventDefault();
|
||||
scheduleClearCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Keydown event handler.
|
||||
* @param {Object} event
|
||||
*/
|
||||
function keydown(event) {
|
||||
|
||||
var target = event.target;
|
||||
var modifier = event.ctrlKey || event.altKey || event.metaKey ||
|
||||
(event.shiftKey && event.keyCode !== key.spacebar);
|
||||
|
||||
// our own tracked active element could've been removed from the DOM
|
||||
if (!document.contains(activeElement)) {
|
||||
activeElement = document.activeElement;
|
||||
}
|
||||
|
||||
// do nothing if user is editing text
|
||||
// or using a modifier key (except shift)
|
||||
// or in a dropdown
|
||||
// or inside interactive elements
|
||||
var inputNodeNames = /^(textarea|select|embed|object)$/i;
|
||||
var buttonTypes = /^(button|submit|radio|checkbox|file|color|image)$/i;
|
||||
if ( inputNodeNames.test(target.nodeName) ||
|
||||
isNodeName(target, 'input') && !buttonTypes.test(target.type) ||
|
||||
isNodeName(activeElement, 'video') ||
|
||||
isInsideYoutubeVideo(event) ||
|
||||
target.isContentEditable ||
|
||||
event.defaultPrevented ||
|
||||
modifier ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// spacebar should trigger button press
|
||||
if ((isNodeName(target, 'button') ||
|
||||
isNodeName(target, 'input') && buttonTypes.test(target.type)) &&
|
||||
event.keyCode === key.spacebar) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var shift, x = 0, y = 0;
|
||||
var elem = overflowingAncestor(activeElement);
|
||||
var clientHeight = elem.clientHeight;
|
||||
|
||||
if (elem == document.body) {
|
||||
clientHeight = window.innerHeight;
|
||||
}
|
||||
|
||||
switch (event.keyCode) {
|
||||
case key.up:
|
||||
y = -options.arrowScroll;
|
||||
break;
|
||||
case key.down:
|
||||
y = options.arrowScroll;
|
||||
break;
|
||||
case key.spacebar: // (+ shift)
|
||||
shift = event.shiftKey ? 1 : -1;
|
||||
y = -shift * clientHeight * 0.9;
|
||||
break;
|
||||
case key.pageup:
|
||||
y = -clientHeight * 0.9;
|
||||
break;
|
||||
case key.pagedown:
|
||||
y = clientHeight * 0.9;
|
||||
break;
|
||||
case key.home:
|
||||
y = -elem.scrollTop;
|
||||
break;
|
||||
case key.end:
|
||||
var damt = elem.scrollHeight - elem.scrollTop - clientHeight;
|
||||
y = (damt > 0) ? damt+10 : 0;
|
||||
break;
|
||||
case key.left:
|
||||
x = -options.arrowScroll;
|
||||
break;
|
||||
case key.right:
|
||||
x = options.arrowScroll;
|
||||
break;
|
||||
default:
|
||||
return true; // a key we don't care about
|
||||
}
|
||||
|
||||
scrollArray(elem, x, y);
|
||||
event.preventDefault();
|
||||
scheduleClearCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Mousedown event only for updating activeElement
|
||||
*/
|
||||
function mousedown(event) {
|
||||
activeElement = event.target;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************
|
||||
* OVERFLOW
|
||||
***********************************************/
|
||||
|
||||
var uniqueID = (function () {
|
||||
var i = 0;
|
||||
return function (el) {
|
||||
return el.uniqueID || (el.uniqueID = i++);
|
||||
};
|
||||
})();
|
||||
|
||||
var cache = {}; // cleared out after a scrolling session
|
||||
var clearCacheTimer;
|
||||
|
||||
//setInterval(function () { cache = {}; }, 10 * 1000);
|
||||
|
||||
function scheduleClearCache() {
|
||||
clearTimeout(clearCacheTimer);
|
||||
clearCacheTimer = setInterval(function () { cache = {}; }, 1*1000);
|
||||
}
|
||||
|
||||
function setCache(elems, overflowing) {
|
||||
for (var i = elems.length; i--;)
|
||||
cache[uniqueID(elems[i])] = overflowing;
|
||||
return overflowing;
|
||||
}
|
||||
|
||||
// (body) (root)
|
||||
// | hidden | visible | scroll | auto |
|
||||
// hidden | no | no | YES | YES |
|
||||
// visible | no | YES | YES | YES |
|
||||
// scroll | no | YES | YES | YES |
|
||||
// auto | no | YES | YES | YES |
|
||||
|
||||
function overflowingAncestor(el) {
|
||||
var elems = [];
|
||||
var body = document.body;
|
||||
var rootScrollHeight = root.scrollHeight;
|
||||
do {
|
||||
var cached = cache[uniqueID(el)];
|
||||
if (cached) {
|
||||
return setCache(elems, cached);
|
||||
}
|
||||
elems.push(el);
|
||||
if (rootScrollHeight === el.scrollHeight) {
|
||||
var topOverflowsNotHidden = overflowNotHidden(root) && overflowNotHidden(body);
|
||||
var isOverflowCSS = topOverflowsNotHidden || overflowAutoOrScroll(root);
|
||||
if (isFrame && isContentOverflowing(root) ||
|
||||
!isFrame && isOverflowCSS) {
|
||||
return setCache(elems, getScrollRoot());
|
||||
}
|
||||
} else if (isContentOverflowing(el) && overflowAutoOrScroll(el)) {
|
||||
return setCache(elems, el);
|
||||
}
|
||||
} while (el = el.parentElement);
|
||||
}
|
||||
|
||||
function isContentOverflowing(el) {
|
||||
return (el.clientHeight + 10 < el.scrollHeight);
|
||||
}
|
||||
|
||||
// typically for <body> and <html>
|
||||
function overflowNotHidden(el) {
|
||||
var overflow = getComputedStyle(el, '').getPropertyValue('overflow-y');
|
||||
return (overflow !== 'hidden');
|
||||
}
|
||||
|
||||
// for all other elements
|
||||
function overflowAutoOrScroll(el) {
|
||||
var overflow = getComputedStyle(el, '').getPropertyValue('overflow-y');
|
||||
return (overflow === 'scroll' || overflow === 'auto');
|
||||
}
|
||||
|
||||
|
||||
/***********************************************
|
||||
* HELPERS
|
||||
***********************************************/
|
||||
|
||||
function addEvent(type, fn) {
|
||||
window.addEventListener(type, fn, false);
|
||||
}
|
||||
|
||||
function removeEvent(type, fn) {
|
||||
window.removeEventListener(type, fn, false);
|
||||
}
|
||||
|
||||
function isNodeName(el, tag) {
|
||||
return (el.nodeName||'').toLowerCase() === tag.toLowerCase();
|
||||
}
|
||||
|
||||
function directionCheck(x, y) {
|
||||
x = (x > 0) ? 1 : -1;
|
||||
y = (y > 0) ? 1 : -1;
|
||||
if (direction.x !== x || direction.y !== y) {
|
||||
direction.x = x;
|
||||
direction.y = y;
|
||||
que = [];
|
||||
lastScroll = 0;
|
||||
}
|
||||
}
|
||||
|
||||
var deltaBufferTimer;
|
||||
|
||||
if (window.localStorage && localStorage.SS_deltaBuffer) {
|
||||
deltaBuffer = localStorage.SS_deltaBuffer.split(',');
|
||||
}
|
||||
|
||||
function isTouchpad(deltaY) {
|
||||
if (!deltaY) return;
|
||||
if (!deltaBuffer.length) {
|
||||
deltaBuffer = [deltaY, deltaY, deltaY];
|
||||
}
|
||||
deltaY = Math.abs(deltaY)
|
||||
deltaBuffer.push(deltaY);
|
||||
deltaBuffer.shift();
|
||||
clearTimeout(deltaBufferTimer);
|
||||
deltaBufferTimer = setTimeout(function () {
|
||||
if (window.localStorage) {
|
||||
localStorage.SS_deltaBuffer = deltaBuffer.join(',');
|
||||
}
|
||||
}, 1000);
|
||||
return !allDeltasDivisableBy(120) && !allDeltasDivisableBy(100);
|
||||
}
|
||||
|
||||
function isDivisible(n, divisor) {
|
||||
return (Math.floor(n / divisor) == n / divisor);
|
||||
}
|
||||
|
||||
function allDeltasDivisableBy(divisor) {
|
||||
return (isDivisible(deltaBuffer[0], divisor) &&
|
||||
isDivisible(deltaBuffer[1], divisor) &&
|
||||
isDivisible(deltaBuffer[2], divisor));
|
||||
}
|
||||
|
||||
function isInsideYoutubeVideo(event) {
|
||||
var elem = event.target;
|
||||
var isControl = false;
|
||||
if (document.URL.indexOf ('www.youtube.com/watch') != -1) {
|
||||
do {
|
||||
isControl = (elem.classList &&
|
||||
elem.classList.contains('html5-video-controls'));
|
||||
if (isControl) break;
|
||||
} while (elem = elem.parentNode);
|
||||
}
|
||||
return isControl;
|
||||
}
|
||||
|
||||
var requestFrame = (function () {
|
||||
return (window.requestAnimationFrame ||
|
||||
window.webkitRequestAnimationFrame ||
|
||||
window.mozRequestAnimationFrame ||
|
||||
function (callback, element, delay) {
|
||||
window.setTimeout(callback, delay || (1000/60));
|
||||
});
|
||||
})();
|
||||
|
||||
var MutationObserver = (window.MutationObserver ||
|
||||
window.WebKitMutationObserver ||
|
||||
window.MozMutationObserver);
|
||||
|
||||
var getScrollRoot = (function() {
|
||||
var SCROLL_ROOT;
|
||||
return function() {
|
||||
if (!SCROLL_ROOT) {
|
||||
var dummy = document.createElement('div');
|
||||
dummy.style.cssText = 'height:10000px;width:1px;';
|
||||
document.body.appendChild(dummy);
|
||||
var bodyScrollTop = document.body.scrollTop;
|
||||
var docElScrollTop = document.documentElement.scrollTop;
|
||||
window.scrollBy(0, 1);
|
||||
if (document.body.scrollTop != bodyScrollTop)
|
||||
(SCROLL_ROOT = document.body);
|
||||
else
|
||||
(SCROLL_ROOT = document.documentElement);
|
||||
window.scrollBy(0, -1);
|
||||
document.body.removeChild(dummy);
|
||||
}
|
||||
return SCROLL_ROOT;
|
||||
};
|
||||
})();
|
||||
|
||||
|
||||
/***********************************************
|
||||
* PULSE (by Michael Herf)
|
||||
***********************************************/
|
||||
|
||||
/**
|
||||
* Viscous fluid with a pulse for part and decay for the rest.
|
||||
* - Applies a fixed force over an interval (a damped acceleration), and
|
||||
* - Lets the exponential bleed away the velocity over a longer interval
|
||||
* - Michael Herf, http://stereopsis.com/stopping/
|
||||
*/
|
||||
function pulse_(x) {
|
||||
var val, start, expx;
|
||||
// test
|
||||
x = x * options.pulseScale;
|
||||
if (x < 1) { // acceleartion
|
||||
val = x - (1 - Math.exp(-x));
|
||||
} else { // tail
|
||||
// the previous animation ended here:
|
||||
start = Math.exp(-1);
|
||||
// simple viscous drag
|
||||
x -= 1;
|
||||
expx = 1 - Math.exp(-x);
|
||||
val = start + (expx * (1 - start));
|
||||
}
|
||||
return val * options.pulseNormalize;
|
||||
}
|
||||
|
||||
function pulse(x) {
|
||||
if (x >= 1) return 1;
|
||||
if (x <= 0) return 0;
|
||||
|
||||
if (options.pulseNormalize == 1) {
|
||||
options.pulseNormalize /= pulse_(1);
|
||||
}
|
||||
return pulse_(x);
|
||||
}
|
||||
|
||||
var wheelEvent;
|
||||
if ('onwheel' in document.createElement('div'))
|
||||
wheelEvent = 'wheel';
|
||||
else if ('onmousewheel' in document.createElement('div'))
|
||||
wheelEvent = 'mousewheel';
|
||||
|
||||
|
||||
// Customizr mod
|
||||
//Customizr mod wrap following: instructions in a function statement
|
||||
//returns whether or not the smootScroll has been initialized
|
||||
function _maybeInit( fire ){
|
||||
if (wheelEvent) {
|
||||
addEvent(wheelEvent, wheel);
|
||||
addEvent('mousedown', mousedown);
|
||||
if ( ! fire ) addEvent('load', init);
|
||||
else init();
|
||||
}
|
||||
return wheelEvent ? true : false;
|
||||
}
|
||||
// smoothScroll "constructor"
|
||||
smoothScroll = function ( _options ) {
|
||||
smoothScroll._setCustomOptions( _options );
|
||||
_maybeInit() && czrapp.$_body.addClass('tc-smoothscroll');
|
||||
}
|
||||
// expose useful methods ( for the preview )
|
||||
smoothScroll._cleanUp = function(){
|
||||
cleanup();
|
||||
czrapp.$_body.removeClass('tc-smoothscroll');
|
||||
}
|
||||
smoothScroll._maybeFire = function(){
|
||||
//will be called from the preview so when document already loaded
|
||||
// pass to the function _fire = true, fire it immediately
|
||||
_maybeInit(true) && czrapp.$_body.addClass('tc-smoothscroll');
|
||||
}
|
||||
smoothScroll._setCustomOptions = function( _options ){
|
||||
options = _options ? _.extend( options, _options) : options;
|
||||
}
|
||||
// end Customizr mod
|
||||
})();
|
||||
|
||||
var smoothScroll;
|
||||
+1
File diff suppressed because one or more lines are too long
+5
File diff suppressed because one or more lines are too long
Vendored
+7
File diff suppressed because one or more lines are too long
+662
@@ -0,0 +1,662 @@
|
||||
/*!
|
||||
Waypoints - 4.0.1
|
||||
Copyright © 2011-2016 Caleb Troughton
|
||||
Licensed under the MIT license.
|
||||
https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
|
||||
*/
|
||||
(function() {
|
||||
'use strict'
|
||||
|
||||
var keyCounter = 0
|
||||
var allWaypoints = {}
|
||||
|
||||
/* http://imakewebthings.com/waypoints/api/waypoint */
|
||||
function Waypoint(options) {
|
||||
if (!options) {
|
||||
throw new Error('No options passed to Waypoint constructor')
|
||||
}
|
||||
if (!options.element) {
|
||||
throw new Error('No element option passed to Waypoint constructor')
|
||||
}
|
||||
if (!options.handler) {
|
||||
throw new Error('No handler option passed to Waypoint constructor')
|
||||
}
|
||||
|
||||
this.key = 'waypoint-' + keyCounter
|
||||
this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options)
|
||||
this.element = this.options.element
|
||||
this.adapter = new Waypoint.Adapter(this.element)
|
||||
this.callback = options.handler
|
||||
this.axis = this.options.horizontal ? 'horizontal' : 'vertical'
|
||||
this.enabled = this.options.enabled
|
||||
this.triggerPoint = null
|
||||
this.group = Waypoint.Group.findOrCreate({
|
||||
name: this.options.group,
|
||||
axis: this.axis
|
||||
})
|
||||
this.context = Waypoint.Context.findOrCreateByElement(this.options.context)
|
||||
|
||||
if (Waypoint.offsetAliases[this.options.offset]) {
|
||||
this.options.offset = Waypoint.offsetAliases[this.options.offset]
|
||||
}
|
||||
this.group.add(this)
|
||||
this.context.add(this)
|
||||
allWaypoints[this.key] = this
|
||||
keyCounter += 1
|
||||
}
|
||||
|
||||
/* Private */
|
||||
Waypoint.prototype.queueTrigger = function(direction) {
|
||||
this.group.queueTrigger(this, direction)
|
||||
}
|
||||
|
||||
/* Private */
|
||||
Waypoint.prototype.trigger = function(args) {
|
||||
if (!this.enabled) {
|
||||
return
|
||||
}
|
||||
if (this.callback) {
|
||||
this.callback.apply(this, args)
|
||||
}
|
||||
}
|
||||
|
||||
/* Public */
|
||||
/* http://imakewebthings.com/waypoints/api/destroy */
|
||||
Waypoint.prototype.destroy = function() {
|
||||
this.context.remove(this)
|
||||
this.group.remove(this)
|
||||
delete allWaypoints[this.key]
|
||||
}
|
||||
|
||||
/* Public */
|
||||
/* http://imakewebthings.com/waypoints/api/disable */
|
||||
Waypoint.prototype.disable = function() {
|
||||
this.enabled = false
|
||||
return this
|
||||
}
|
||||
|
||||
/* Public */
|
||||
/* http://imakewebthings.com/waypoints/api/enable */
|
||||
Waypoint.prototype.enable = function() {
|
||||
this.context.refresh()
|
||||
this.enabled = true
|
||||
return this
|
||||
}
|
||||
|
||||
/* Public */
|
||||
/* http://imakewebthings.com/waypoints/api/next */
|
||||
Waypoint.prototype.next = function() {
|
||||
return this.group.next(this)
|
||||
}
|
||||
|
||||
/* Public */
|
||||
/* http://imakewebthings.com/waypoints/api/previous */
|
||||
Waypoint.prototype.previous = function() {
|
||||
return this.group.previous(this)
|
||||
}
|
||||
|
||||
/* Private */
|
||||
Waypoint.invokeAll = function(method) {
|
||||
var allWaypointsArray = []
|
||||
for (var waypointKey in allWaypoints) {
|
||||
allWaypointsArray.push(allWaypoints[waypointKey])
|
||||
}
|
||||
for (var i = 0, end = allWaypointsArray.length; i < end; i++) {
|
||||
allWaypointsArray[i][method]()
|
||||
}
|
||||
}
|
||||
|
||||
/* Public */
|
||||
/* http://imakewebthings.com/waypoints/api/destroy-all */
|
||||
Waypoint.destroyAll = function() {
|
||||
Waypoint.invokeAll('destroy')
|
||||
}
|
||||
|
||||
/* Public */
|
||||
/* http://imakewebthings.com/waypoints/api/disable-all */
|
||||
Waypoint.disableAll = function() {
|
||||
Waypoint.invokeAll('disable')
|
||||
}
|
||||
|
||||
/* Public */
|
||||
/* http://imakewebthings.com/waypoints/api/enable-all */
|
||||
Waypoint.enableAll = function() {
|
||||
Waypoint.Context.refreshAll()
|
||||
for (var waypointKey in allWaypoints) {
|
||||
allWaypoints[waypointKey].enabled = true
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
/* Public */
|
||||
/* http://imakewebthings.com/waypoints/api/refresh-all */
|
||||
Waypoint.refreshAll = function() {
|
||||
Waypoint.Context.refreshAll()
|
||||
}
|
||||
|
||||
/* Public */
|
||||
/* http://imakewebthings.com/waypoints/api/viewport-height */
|
||||
Waypoint.viewportHeight = function() {
|
||||
return window.innerHeight || document.documentElement.clientHeight
|
||||
}
|
||||
|
||||
/* Public */
|
||||
/* http://imakewebthings.com/waypoints/api/viewport-width */
|
||||
Waypoint.viewportWidth = function() {
|
||||
return document.documentElement.clientWidth
|
||||
}
|
||||
|
||||
Waypoint.adapters = []
|
||||
|
||||
Waypoint.defaults = {
|
||||
context: window,
|
||||
continuous: true,
|
||||
enabled: true,
|
||||
group: 'default',
|
||||
horizontal: false,
|
||||
offset: 0
|
||||
}
|
||||
|
||||
Waypoint.offsetAliases = {
|
||||
'bottom-in-view': function() {
|
||||
return this.context.innerHeight() - this.adapter.outerHeight()
|
||||
},
|
||||
'right-in-view': function() {
|
||||
return this.context.innerWidth() - this.adapter.outerWidth()
|
||||
}
|
||||
}
|
||||
|
||||
window.Waypoint = Waypoint
|
||||
}())
|
||||
;(function() {
|
||||
'use strict'
|
||||
|
||||
function requestAnimationFrameShim(callback) {
|
||||
window.setTimeout(callback, 1000 / 60)
|
||||
}
|
||||
|
||||
var keyCounter = 0
|
||||
var contexts = {}
|
||||
var Waypoint = window.Waypoint
|
||||
var oldWindowLoad = window.onload
|
||||
|
||||
/* http://imakewebthings.com/waypoints/api/context */
|
||||
function Context(element) {
|
||||
this.element = element
|
||||
this.Adapter = Waypoint.Adapter
|
||||
this.adapter = new this.Adapter(element)
|
||||
this.key = 'waypoint-context-' + keyCounter
|
||||
this.didScroll = false
|
||||
this.didResize = false
|
||||
this.oldScroll = {
|
||||
x: this.adapter.scrollLeft(),
|
||||
y: this.adapter.scrollTop()
|
||||
}
|
||||
this.waypoints = {
|
||||
vertical: {},
|
||||
horizontal: {}
|
||||
}
|
||||
|
||||
element.waypointContextKey = this.key
|
||||
contexts[element.waypointContextKey] = this
|
||||
keyCounter += 1
|
||||
if (!Waypoint.windowContext) {
|
||||
Waypoint.windowContext = true
|
||||
Waypoint.windowContext = new Context(window)
|
||||
}
|
||||
|
||||
this.createThrottledScrollHandler()
|
||||
this.createThrottledResizeHandler()
|
||||
}
|
||||
|
||||
/* Private */
|
||||
Context.prototype.add = function(waypoint) {
|
||||
var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical'
|
||||
this.waypoints[axis][waypoint.key] = waypoint
|
||||
this.refresh()
|
||||
}
|
||||
|
||||
/* Private */
|
||||
Context.prototype.checkEmpty = function() {
|
||||
var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal)
|
||||
var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical)
|
||||
var isWindow = this.element == this.element.window
|
||||
if (horizontalEmpty && verticalEmpty && !isWindow) {
|
||||
this.adapter.off('.waypoints')
|
||||
delete contexts[this.key]
|
||||
}
|
||||
}
|
||||
|
||||
/* Private */
|
||||
Context.prototype.createThrottledResizeHandler = function() {
|
||||
var self = this
|
||||
|
||||
function resizeHandler() {
|
||||
self.handleResize()
|
||||
self.didResize = false
|
||||
}
|
||||
|
||||
this.adapter.on('resize.waypoints', function() {
|
||||
if (!self.didResize) {
|
||||
self.didResize = true
|
||||
Waypoint.requestAnimationFrame(resizeHandler)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/* Private */
|
||||
Context.prototype.createThrottledScrollHandler = function() {
|
||||
var self = this
|
||||
function scrollHandler() {
|
||||
self.handleScroll()
|
||||
self.didScroll = false
|
||||
}
|
||||
|
||||
this.adapter.on('scroll.waypoints', function() {
|
||||
if (!self.didScroll || Waypoint.isTouch) {
|
||||
self.didScroll = true
|
||||
Waypoint.requestAnimationFrame(scrollHandler)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/* Private */
|
||||
Context.prototype.handleResize = function() {
|
||||
Waypoint.Context.refreshAll()
|
||||
}
|
||||
|
||||
/* Private */
|
||||
Context.prototype.handleScroll = function() {
|
||||
var triggeredGroups = {}
|
||||
var axes = {
|
||||
horizontal: {
|
||||
newScroll: this.adapter.scrollLeft(),
|
||||
oldScroll: this.oldScroll.x,
|
||||
forward: 'right',
|
||||
backward: 'left'
|
||||
},
|
||||
vertical: {
|
||||
newScroll: this.adapter.scrollTop(),
|
||||
oldScroll: this.oldScroll.y,
|
||||
forward: 'down',
|
||||
backward: 'up'
|
||||
}
|
||||
}
|
||||
|
||||
for (var axisKey in axes) {
|
||||
var axis = axes[axisKey]
|
||||
var isForward = axis.newScroll > axis.oldScroll
|
||||
var direction = isForward ? axis.forward : axis.backward
|
||||
|
||||
for (var waypointKey in this.waypoints[axisKey]) {
|
||||
var waypoint = this.waypoints[axisKey][waypointKey]
|
||||
if (waypoint.triggerPoint === null) {
|
||||
continue
|
||||
}
|
||||
var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint
|
||||
var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint
|
||||
var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint
|
||||
var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint
|
||||
if (crossedForward || crossedBackward) {
|
||||
waypoint.queueTrigger(direction)
|
||||
triggeredGroups[waypoint.group.id] = waypoint.group
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var groupKey in triggeredGroups) {
|
||||
triggeredGroups[groupKey].flushTriggers()
|
||||
}
|
||||
|
||||
this.oldScroll = {
|
||||
x: axes.horizontal.newScroll,
|
||||
y: axes.vertical.newScroll
|
||||
}
|
||||
}
|
||||
|
||||
/* Private */
|
||||
Context.prototype.innerHeight = function() {
|
||||
/*eslint-disable eqeqeq */
|
||||
if (this.element == this.element.window) {
|
||||
return Waypoint.viewportHeight()
|
||||
}
|
||||
/*eslint-enable eqeqeq */
|
||||
return this.adapter.innerHeight()
|
||||
}
|
||||
|
||||
/* Private */
|
||||
Context.prototype.remove = function(waypoint) {
|
||||
delete this.waypoints[waypoint.axis][waypoint.key]
|
||||
this.checkEmpty()
|
||||
}
|
||||
|
||||
/* Private */
|
||||
Context.prototype.innerWidth = function() {
|
||||
/*eslint-disable eqeqeq */
|
||||
if (this.element == this.element.window) {
|
||||
return Waypoint.viewportWidth()
|
||||
}
|
||||
/*eslint-enable eqeqeq */
|
||||
return this.adapter.innerWidth()
|
||||
}
|
||||
|
||||
/* Public */
|
||||
/* http://imakewebthings.com/waypoints/api/context-destroy */
|
||||
Context.prototype.destroy = function() {
|
||||
var allWaypoints = []
|
||||
for (var axis in this.waypoints) {
|
||||
for (var waypointKey in this.waypoints[axis]) {
|
||||
allWaypoints.push(this.waypoints[axis][waypointKey])
|
||||
}
|
||||
}
|
||||
for (var i = 0, end = allWaypoints.length; i < end; i++) {
|
||||
allWaypoints[i].destroy()
|
||||
}
|
||||
}
|
||||
|
||||
/* Public */
|
||||
/* http://imakewebthings.com/waypoints/api/context-refresh */
|
||||
Context.prototype.refresh = function() {
|
||||
/*eslint-disable eqeqeq */
|
||||
var isWindow = this.element == this.element.window
|
||||
/*eslint-enable eqeqeq */
|
||||
var contextOffset = isWindow ? undefined : this.adapter.offset()
|
||||
var triggeredGroups = {}
|
||||
var axes
|
||||
|
||||
this.handleScroll()
|
||||
axes = {
|
||||
horizontal: {
|
||||
contextOffset: isWindow ? 0 : contextOffset.left,
|
||||
contextScroll: isWindow ? 0 : this.oldScroll.x,
|
||||
contextDimension: this.innerWidth(),
|
||||
oldScroll: this.oldScroll.x,
|
||||
forward: 'right',
|
||||
backward: 'left',
|
||||
offsetProp: 'left'
|
||||
},
|
||||
vertical: {
|
||||
contextOffset: isWindow ? 0 : contextOffset.top,
|
||||
contextScroll: isWindow ? 0 : this.oldScroll.y,
|
||||
contextDimension: this.innerHeight(),
|
||||
oldScroll: this.oldScroll.y,
|
||||
forward: 'down',
|
||||
backward: 'up',
|
||||
offsetProp: 'top'
|
||||
}
|
||||
}
|
||||
|
||||
for (var axisKey in axes) {
|
||||
var axis = axes[axisKey]
|
||||
for (var waypointKey in this.waypoints[axisKey]) {
|
||||
var waypoint = this.waypoints[axisKey][waypointKey]
|
||||
var adjustment = waypoint.options.offset
|
||||
var oldTriggerPoint = waypoint.triggerPoint
|
||||
var elementOffset = 0
|
||||
var freshWaypoint = oldTriggerPoint == null
|
||||
var contextModifier, wasBeforeScroll, nowAfterScroll
|
||||
var triggeredBackward, triggeredForward
|
||||
|
||||
if (waypoint.element !== waypoint.element.window) {
|
||||
elementOffset = waypoint.adapter.offset()[axis.offsetProp]
|
||||
}
|
||||
|
||||
if (typeof adjustment === 'function') {
|
||||
adjustment = adjustment.apply(waypoint)
|
||||
}
|
||||
else if (typeof adjustment === 'string') {
|
||||
adjustment = parseFloat(adjustment)
|
||||
if (waypoint.options.offset.indexOf('%') > - 1) {
|
||||
adjustment = Math.ceil(axis.contextDimension * adjustment / 100)
|
||||
}
|
||||
}
|
||||
|
||||
contextModifier = axis.contextScroll - axis.contextOffset
|
||||
waypoint.triggerPoint = Math.floor(elementOffset + contextModifier - adjustment)
|
||||
wasBeforeScroll = oldTriggerPoint < axis.oldScroll
|
||||
nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll
|
||||
triggeredBackward = wasBeforeScroll && nowAfterScroll
|
||||
triggeredForward = !wasBeforeScroll && !nowAfterScroll
|
||||
|
||||
if (!freshWaypoint && triggeredBackward) {
|
||||
waypoint.queueTrigger(axis.backward)
|
||||
triggeredGroups[waypoint.group.id] = waypoint.group
|
||||
}
|
||||
else if (!freshWaypoint && triggeredForward) {
|
||||
waypoint.queueTrigger(axis.forward)
|
||||
triggeredGroups[waypoint.group.id] = waypoint.group
|
||||
}
|
||||
else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) {
|
||||
waypoint.queueTrigger(axis.forward)
|
||||
triggeredGroups[waypoint.group.id] = waypoint.group
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Waypoint.requestAnimationFrame(function() {
|
||||
for (var groupKey in triggeredGroups) {
|
||||
triggeredGroups[groupKey].flushTriggers()
|
||||
}
|
||||
})
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/* Private */
|
||||
Context.findOrCreateByElement = function(element) {
|
||||
return Context.findByElement(element) || new Context(element)
|
||||
}
|
||||
|
||||
/* Private */
|
||||
Context.refreshAll = function() {
|
||||
for (var contextId in contexts) {
|
||||
contexts[contextId].refresh()
|
||||
}
|
||||
}
|
||||
|
||||
/* Public */
|
||||
/* http://imakewebthings.com/waypoints/api/context-find-by-element */
|
||||
Context.findByElement = function(element) {
|
||||
return contexts[element.waypointContextKey]
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
if (oldWindowLoad) {
|
||||
oldWindowLoad()
|
||||
}
|
||||
Context.refreshAll()
|
||||
}
|
||||
|
||||
|
||||
Waypoint.requestAnimationFrame = function(callback) {
|
||||
var requestFn = window.requestAnimationFrame ||
|
||||
window.mozRequestAnimationFrame ||
|
||||
window.webkitRequestAnimationFrame ||
|
||||
requestAnimationFrameShim
|
||||
requestFn.call(window, callback)
|
||||
}
|
||||
Waypoint.Context = Context
|
||||
}())
|
||||
;(function() {
|
||||
'use strict'
|
||||
|
||||
function byTriggerPoint(a, b) {
|
||||
return a.triggerPoint - b.triggerPoint
|
||||
}
|
||||
|
||||
function byReverseTriggerPoint(a, b) {
|
||||
return b.triggerPoint - a.triggerPoint
|
||||
}
|
||||
|
||||
var groups = {
|
||||
vertical: {},
|
||||
horizontal: {}
|
||||
}
|
||||
var Waypoint = window.Waypoint
|
||||
|
||||
/* http://imakewebthings.com/waypoints/api/group */
|
||||
function Group(options) {
|
||||
this.name = options.name
|
||||
this.axis = options.axis
|
||||
this.id = this.name + '-' + this.axis
|
||||
this.waypoints = []
|
||||
this.clearTriggerQueues()
|
||||
groups[this.axis][this.name] = this
|
||||
}
|
||||
|
||||
/* Private */
|
||||
Group.prototype.add = function(waypoint) {
|
||||
this.waypoints.push(waypoint)
|
||||
}
|
||||
|
||||
/* Private */
|
||||
Group.prototype.clearTriggerQueues = function() {
|
||||
this.triggerQueues = {
|
||||
up: [],
|
||||
down: [],
|
||||
left: [],
|
||||
right: []
|
||||
}
|
||||
}
|
||||
|
||||
/* Private */
|
||||
Group.prototype.flushTriggers = function() {
|
||||
for (var direction in this.triggerQueues) {
|
||||
var waypoints = this.triggerQueues[direction]
|
||||
var reverse = direction === 'up' || direction === 'left'
|
||||
waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint)
|
||||
for (var i = 0, end = waypoints.length; i < end; i += 1) {
|
||||
var waypoint = waypoints[i]
|
||||
if (waypoint.options.continuous || i === waypoints.length - 1) {
|
||||
waypoint.trigger([direction])
|
||||
}
|
||||
}
|
||||
}
|
||||
this.clearTriggerQueues()
|
||||
}
|
||||
|
||||
/* Private */
|
||||
Group.prototype.next = function(waypoint) {
|
||||
this.waypoints.sort(byTriggerPoint)
|
||||
var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
|
||||
var isLast = index === this.waypoints.length - 1
|
||||
return isLast ? null : this.waypoints[index + 1]
|
||||
}
|
||||
|
||||
/* Private */
|
||||
Group.prototype.previous = function(waypoint) {
|
||||
this.waypoints.sort(byTriggerPoint)
|
||||
var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
|
||||
return index ? this.waypoints[index - 1] : null
|
||||
}
|
||||
|
||||
/* Private */
|
||||
Group.prototype.queueTrigger = function(waypoint, direction) {
|
||||
this.triggerQueues[direction].push(waypoint)
|
||||
}
|
||||
|
||||
/* Private */
|
||||
Group.prototype.remove = function(waypoint) {
|
||||
var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
|
||||
if (index > -1) {
|
||||
this.waypoints.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
/* Public */
|
||||
/* http://imakewebthings.com/waypoints/api/first */
|
||||
Group.prototype.first = function() {
|
||||
return this.waypoints[0]
|
||||
}
|
||||
|
||||
/* Public */
|
||||
/* http://imakewebthings.com/waypoints/api/last */
|
||||
Group.prototype.last = function() {
|
||||
return this.waypoints[this.waypoints.length - 1]
|
||||
}
|
||||
|
||||
/* Private */
|
||||
Group.findOrCreate = function(options) {
|
||||
return groups[options.axis][options.name] || new Group(options)
|
||||
}
|
||||
|
||||
Waypoint.Group = Group
|
||||
}())
|
||||
;(function() {
|
||||
'use strict'
|
||||
|
||||
var $ = window.jQuery
|
||||
var Waypoint = window.Waypoint
|
||||
|
||||
function JQueryAdapter(element) {
|
||||
this.$element = $(element)
|
||||
}
|
||||
|
||||
$.each([
|
||||
'innerHeight',
|
||||
'innerWidth',
|
||||
'off',
|
||||
'offset',
|
||||
'on',
|
||||
'outerHeight',
|
||||
'outerWidth',
|
||||
'scrollLeft',
|
||||
'scrollTop'
|
||||
], function(i, method) {
|
||||
JQueryAdapter.prototype[method] = function() {
|
||||
var args = Array.prototype.slice.call(arguments)
|
||||
return this.$element[method].apply(this.$element, args)
|
||||
}
|
||||
})
|
||||
|
||||
$.each([
|
||||
'extend',
|
||||
'inArray',
|
||||
'isEmptyObject'
|
||||
], function(i, method) {
|
||||
JQueryAdapter[method] = $[method]
|
||||
})
|
||||
|
||||
Waypoint.adapters.push({
|
||||
name: 'jquery',
|
||||
Adapter: JQueryAdapter
|
||||
})
|
||||
Waypoint.Adapter = JQueryAdapter
|
||||
}())
|
||||
;(function() {
|
||||
'use strict'
|
||||
|
||||
var Waypoint = window.Waypoint
|
||||
|
||||
function createExtension(framework) {
|
||||
return function() {
|
||||
var waypoints = []
|
||||
var overrides = arguments[0]
|
||||
|
||||
if (framework.isFunction(arguments[0])) {
|
||||
overrides = framework.extend({}, arguments[1])
|
||||
overrides.handler = arguments[0]
|
||||
}
|
||||
|
||||
this.each(function() {
|
||||
var options = framework.extend({}, overrides, {
|
||||
element: this
|
||||
})
|
||||
if (typeof options.context === 'string') {
|
||||
options.context = framework(this).closest(options.context)[0]
|
||||
}
|
||||
waypoints.push(new Waypoint(options))
|
||||
})
|
||||
|
||||
return waypoints
|
||||
}
|
||||
}
|
||||
|
||||
if (window.jQuery) {
|
||||
window.jQuery.fn.waypoint = createExtension(window.jQuery)
|
||||
}
|
||||
if (window.Zepto) {
|
||||
window.Zepto.fn.waypoint = createExtension(window.Zepto)
|
||||
}
|
||||
}())
|
||||
;
|
||||
wp-content/plugins/nimble-builder/assets/front/js/__FRONT_JS_FMK_TO_BE_UPDATED/libs/waypoints.min.js
Vendored
+7
File diff suppressed because one or more lines are too long
+234
@@ -0,0 +1,234 @@
|
||||
// global sekFrontLocalized, nb_
|
||||
if ( window.nb_ === void 0 && window.console && window.console.log ) {
|
||||
console.log('Nimble error => window.nb_ global not instantiated');
|
||||
}
|
||||
|
||||
|
||||
// add an helper to get the query variable
|
||||
// used for grid module
|
||||
window.nb_.getQueryVariable = function(variable) {
|
||||
var query = window.location.search.substring(1);
|
||||
var vars = query.split("&");
|
||||
for (var i=0;i<vars.length;i++) {
|
||||
var pair = vars[i].split("=");
|
||||
if(pair[0] == variable){return pair[1];}
|
||||
}
|
||||
return(false);
|
||||
};
|
||||
|
||||
// adds jQuery dependant methods to window.nb_
|
||||
(function(w, d){
|
||||
var callbackFunc = function() {
|
||||
jQuery( function($){
|
||||
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError, isMap, isWeakMap, isSet, isWeakSet
|
||||
// see https://underscorejs.org/docs/underscore.html#section-149
|
||||
jQuery.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error', 'Symbol', 'Map', 'WeakMap', 'Set', 'WeakSet'], function(index, name) {
|
||||
window.nb_['is' + name] = function(obj) {
|
||||
// https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Object/toString
|
||||
var _toString = Object.prototype.toString;
|
||||
return _toString.call(obj) === '[object ' + name + ']';
|
||||
};
|
||||
});
|
||||
|
||||
//https://underscorejs.org/docs/underscore.html#section-17
|
||||
//helper for nb_.delay
|
||||
var _restArguments = function(func, startIndex) {
|
||||
startIndex = startIndex == null ? func.length - 1 : +startIndex;
|
||||
return function() {
|
||||
var length = Math.max(arguments.length - startIndex, 0),
|
||||
rest = Array(length),
|
||||
index = 0;
|
||||
for (; index < length; index++) {
|
||||
rest[index] = arguments[index + startIndex];
|
||||
}
|
||||
switch (startIndex) {
|
||||
case 0: return func.call(this, rest);
|
||||
case 1: return func.call(this, arguments[0], rest);
|
||||
case 2: return func.call(this, arguments[0], arguments[1], rest);
|
||||
}
|
||||
var args = Array(startIndex + 1);
|
||||
for (index = 0; index < startIndex; index++) {
|
||||
args[index] = arguments[index];
|
||||
}
|
||||
args[startIndex] = rest;
|
||||
return func.apply(this, args);
|
||||
};
|
||||
};
|
||||
// helper for nb_.throttle()
|
||||
var _now = function() {
|
||||
return Date.now || new Date().getTime();
|
||||
};
|
||||
|
||||
$.extend( nb_, {
|
||||
cachedElements : {
|
||||
$window : $(window),
|
||||
$body : $('body')
|
||||
},
|
||||
isMobile : function() {
|
||||
return ( nb_.isFunction( window.matchMedia ) && matchMedia( 'only screen and (max-width: 768px)' ).matches ) || ( this.isCustomizing() && 'desktop' != this.previewedDevice );
|
||||
},
|
||||
isCustomizing : function() {
|
||||
return this.cachedElements.$body.hasClass('is-customizing') || ( 'undefined' !== typeof wp && 'undefined' !== typeof wp.customize );
|
||||
},
|
||||
previewedDevice : 'desktop',
|
||||
//Simple Utility telling if a given Dom element is currently in the window <=> visible.
|
||||
//Useful to mimic a very basic WayPoint
|
||||
elOrFirstVisibleParentIsInWindow : function( element, threshold ) {
|
||||
var $_el = !( element instanceof $ ) ? $(element) : element;
|
||||
if ( !( $_el instanceof $ ) ) {
|
||||
nb_.errorLog('invalid element in nb_.elOrFirstVisibleParentIsInWindow', $_el );
|
||||
return;
|
||||
}
|
||||
if ( threshold && !nb_.isNumber( threshold ) ) {
|
||||
nb_.errorLog('invalid threshold in nb_.elOrFirstVisibleParentIsInWindow');
|
||||
return;
|
||||
}
|
||||
|
||||
var sniffFirstVisiblePrevElement = function( $el ) {
|
||||
if ( $el.length > 0 && $el.is(':visible') )
|
||||
return $el;
|
||||
var $prev = $el.prev();
|
||||
// if there's a previous sibling and this sibling is visible, use it
|
||||
if ( $prev.length > 0 && $prev.is(':visible') ) {
|
||||
return $prev;
|
||||
}
|
||||
// if there's a previous sibling but it's not visible, let's try the next previous sibling
|
||||
if ( $prev.length > 0 && !$prev.is(':visible') ) {
|
||||
return sniffFirstVisiblePrevElement( $prev );
|
||||
}
|
||||
// if no previous sibling visible, let's go up the parent level
|
||||
var $parent = $el.parent();
|
||||
if ( $parent.length > 0 ) {
|
||||
return sniffFirstVisiblePrevElement( $parent );
|
||||
}
|
||||
// we don't have siblings or parent
|
||||
return null;
|
||||
};
|
||||
|
||||
// Is the candidate visible ? <= not display:none
|
||||
// If not visible, we can't determine the offset().top because of https://github.com/presscustomizr/nimble-builder/issues/363
|
||||
// So let's sniff up in the DOM to find the first visible sibling or container
|
||||
var $el_candidate = sniffFirstVisiblePrevElement( $_el );
|
||||
if ( !$el_candidate || $el_candidate.length < 1 )
|
||||
return false;
|
||||
|
||||
var wt = this.cachedElements.$window.scrollTop(),
|
||||
wb = wt + this.cachedElements.$window.height(),
|
||||
it = $el_candidate.offset().top,
|
||||
ib = it + $el_candidate.height(),
|
||||
th = threshold || 0;
|
||||
|
||||
return ib >= wt - th && it <= wb + th;
|
||||
},//elOrFirstVisibleParentIsInWindow
|
||||
|
||||
// HELPERS COPIED FROM UNDERSCORE
|
||||
has : function(obj, path) {
|
||||
if (!_.isArray(path)) {
|
||||
return obj != null && hasOwnProperty.call(obj, path);
|
||||
}
|
||||
var length = path.length;
|
||||
for (var i = 0; i < length; i++) {
|
||||
var key = path[i];
|
||||
if (obj == null || !Object.prototype.hasOwnProperty.call(obj, key)) {
|
||||
return false;
|
||||
}
|
||||
obj = obj[key];
|
||||
}
|
||||
return !!length;
|
||||
},
|
||||
// https://davidwalsh.name/javascript-debounce-function
|
||||
debounce : function(func, wait, immediate) {
|
||||
var timeout;
|
||||
return function() {
|
||||
var context = this, args = arguments;
|
||||
var later = function() {
|
||||
timeout = null;
|
||||
if (!immediate) func.apply(context, args);
|
||||
};
|
||||
var callNow = immediate && !timeout;
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(later, wait);
|
||||
if (callNow) func.apply(context, args);
|
||||
};
|
||||
},
|
||||
// https://underscorejs.org/docs/underscore.html#section-85
|
||||
throttle : function(func, wait, options) {
|
||||
var timeout, context, args, result;
|
||||
var previous = 0;
|
||||
if (!options) options = {};
|
||||
|
||||
var later = function() {
|
||||
previous = options.leading === false ? 0 : _now();
|
||||
timeout = null;
|
||||
result = func.apply(context, args);
|
||||
if (!timeout) context = args = null;
|
||||
};
|
||||
|
||||
var throttled = function() {
|
||||
var now = _now();
|
||||
if (!previous && options.leading === false) previous = now;
|
||||
var remaining = wait - (now - previous);
|
||||
context = this;
|
||||
args = arguments;
|
||||
if (remaining <= 0 || remaining > wait) {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
}
|
||||
previous = now;
|
||||
result = func.apply(context, args);
|
||||
if (!timeout) context = args = null;
|
||||
} else if (!timeout && options.trailing !== false) {
|
||||
timeout = setTimeout(later, remaining);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
throttled.cancel = function() {
|
||||
clearTimeout(timeout);
|
||||
previous = 0;
|
||||
timeout = context = args = null;
|
||||
};
|
||||
|
||||
return throttled;
|
||||
},
|
||||
delay : _restArguments(function(func, wait, args) {
|
||||
return setTimeout(function() {
|
||||
return func.apply(null, args);
|
||||
}, wait);
|
||||
})
|
||||
// Browser detection
|
||||
// @see https://stackoverflow.com/questions/9847580/how-to-detect-safari-chrome-ie-firefox-and-opera-browser#9851769
|
||||
// browserIs : function( browser ) {
|
||||
// var bool = false,
|
||||
// isIE = false || !!document.documentMode;
|
||||
// switch( browser) {
|
||||
// case 'safari' :
|
||||
// bool = /constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window.safari || (typeof safari !== 'undefined' && safari.pushNotification));
|
||||
// break;
|
||||
// case 'firefox' :
|
||||
// bool = typeof InstallTrigger !== 'undefined';
|
||||
// break;
|
||||
// case 'IE' :
|
||||
// // https://stackoverflow.com/questions/19999388/check-if-user-is-using-ie
|
||||
// bool = isIE && /MSIE|Trident/.test(window.navigator.userAgent);
|
||||
// break;
|
||||
// case 'edge' :
|
||||
// bool = !isIE && !!window.StyleMedia;
|
||||
// break;
|
||||
// case 'chrome' :
|
||||
// bool = !!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime);
|
||||
// break;
|
||||
// }
|
||||
// return bool;
|
||||
// },
|
||||
});//$.extend( nb_
|
||||
|
||||
// now that nb_ has been populated, let's say it to the app
|
||||
nb_.emit('nb-app-ready');
|
||||
});// jQuery( function($){
|
||||
};
|
||||
// 'nb-jquery-loaded' is fired @'wp_footer' see inline script in ::_schedule_front_assets_printing()
|
||||
nb_.listenTo('nb-jquery-loaded', callbackFunc );
|
||||
|
||||
}(window, document));
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/*global jQuery */
|
||||
/*!
|
||||
* FitText.js 1.2
|
||||
*
|
||||
* Copyright 2011, Dave Rupert http://daverupert.com
|
||||
* Released under the WTFPL license
|
||||
* http://sam.zoy.org/wtfpl/
|
||||
*
|
||||
* Date: Thu May 05 14:23:00 2011 -0600
|
||||
*/
|
||||
// global sekFrontLocalized, nimbleListenTo
|
||||
(function(w, d){
|
||||
var callbackFunc = function() {
|
||||
(function( $ ){
|
||||
$.fn.fitText = function( kompressor, options ) {
|
||||
|
||||
// Setup options
|
||||
var compressor = kompressor || 1,
|
||||
settings = $.extend({
|
||||
'minFontSize' : Number.NEGATIVE_INFINITY,
|
||||
'maxFontSize' : Number.POSITIVE_INFINITY
|
||||
}, options);
|
||||
|
||||
return this.each(function(){
|
||||
|
||||
// Store the object
|
||||
var $this = $(this);
|
||||
|
||||
// Resizer() resizes items based on the object width divided by the compressor * 10
|
||||
var resizer = function () {
|
||||
$this.css('font-size', Math.max(Math.min($this.width() / (compressor*10), parseFloat(settings.maxFontSize)), parseFloat(settings.minFontSize)) + 'px');
|
||||
};
|
||||
|
||||
// Call once to set.
|
||||
resizer();
|
||||
|
||||
// Call on resize. Opera debounces their resize by default.
|
||||
nb_.cachedElements.$window.on('resize.fittext orientationchange.fittext', resizer);
|
||||
|
||||
});
|
||||
};
|
||||
})( jQuery );
|
||||
|
||||
var doFitText = function() {
|
||||
$(".sek-module-placeholder").each( function() {
|
||||
$(this).fitText( 0.4, { minFontSize: '50px', maxFontSize: '300px' } ).data('sek-fittext-done', true );
|
||||
});
|
||||
// Delegate instantiation
|
||||
$('.sektion-wrapper').on(
|
||||
'sek-columns-refreshed sek-modules-refreshed sek-section-added sek-level-refreshed',
|
||||
'div[data-sek-level="section"]',
|
||||
function( evt ) {
|
||||
$(this).find(".sek-module-placeholder").fitText( 0.4, { minFontSize: '50px', maxFontSize: '300px' } ).data('sek-fittext-done', true );
|
||||
}
|
||||
);
|
||||
};
|
||||
//doFitText();
|
||||
// if ( 'function' == typeof(_) && window.wp && ! nb_.isUndefined( wp.customize ) ) {
|
||||
// wp.customize.selectiveRefresh.bind('partial-content-rendered' , function() {
|
||||
// doFitText();
|
||||
// });
|
||||
// }
|
||||
};// onJQueryReady
|
||||
|
||||
// on 'nb-app-ready', jQuery is loaded
|
||||
nb_.listenTo('nb-app-ready', callbackFunc );
|
||||
}(window, document));
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
// global sekFrontLocalized, nimbleListenTo
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* SCROLL TO ANCHOR
|
||||
/* ------------------------------------------------------------------------- */
|
||||
(function(w, d){
|
||||
var callbackFunc = function() {
|
||||
jQuery( function($){
|
||||
// does the same as new URL(url)
|
||||
// but support IE.
|
||||
// @see https://stackoverflow.com/questions/736513/how-do-i-parse-a-url-into-hostname-and-path-in-javascript
|
||||
// @see https://gist.github.com/acdcjunior/9820040
|
||||
// @see https://developer.mozilla.org/en-US/docs/Web/API/URL#Properties
|
||||
var parseURL = function(url) {
|
||||
var parser = document.createElement("a");
|
||||
parser.href = url;
|
||||
// IE 8 and 9 dont load the attributes "protocol" and "host" in case the source URL
|
||||
// is just a pathname, that is, "/example" and not "http://domain.com/example".
|
||||
parser.href = parser.href;
|
||||
|
||||
// copies all the properties to this object
|
||||
var properties = ['host', 'hostname', 'hash', 'href', 'port', 'protocol', 'search'];
|
||||
for (var i = 0, n = properties.length; i < n; i++) {
|
||||
this[properties[i]] = parser[properties[i]];
|
||||
}
|
||||
|
||||
// pathname is special because IE takes the "/" of the starting of pathname
|
||||
this.pathname = (parser.pathname.charAt(0) !== "/" ? "/" : "") + parser.pathname;
|
||||
};
|
||||
|
||||
var $root = $('html, body');
|
||||
window.nb_allImagesLazyLoadedForScrollToAnchor = false;
|
||||
// this = $nimbleTargetCandidate
|
||||
var _doAnimateToTarget = function() {
|
||||
var $target = $(this);
|
||||
// Check is scrollIntoView is fully supported, in particular the options for smooth behavior
|
||||
// https://stackoverflow.com/questions/46919627/is-it-possible-to-test-for-scrollintoview-browser-compatibility
|
||||
// if not, fallback on jQuery animate()
|
||||
if( 'scrollBehavior' in document.documentElement.style ) {
|
||||
$target[0].scrollIntoView( { behavior: "smooth" } );
|
||||
} else {
|
||||
$root.animate({ scrollTop : $target.offset().top - 150 }, 400 );
|
||||
}
|
||||
};
|
||||
var runTime = 0;
|
||||
// this = $nimbleTargetCandidate
|
||||
var _checkThatAllImgAreLoaded = function() {
|
||||
var $el = $(this);
|
||||
// If all images (except the ones in error ) are loaded animate
|
||||
// if not, loop until images are loaded
|
||||
// do not loop more than 2000 ms
|
||||
if ( $('img[data-sek-src]').not('.sek-lazy-load-error').length < 1 ) {
|
||||
window.nb_allImagesLazyLoadedForScrollToAnchor = true;
|
||||
_doAnimateToTarget.call($el);
|
||||
} else if ( runTime < 20 ) {
|
||||
runTime++;
|
||||
// Loop on myself, maximum 20 times until all images are lazyloaded
|
||||
nb_.delay( function() {
|
||||
_checkThatAllImgAreLoaded.call($el);
|
||||
}, 100 );
|
||||
// Start animating after 200ms so that user doesn't wait too long
|
||||
// even if another animation may take over after all remaining images have been loaded
|
||||
nb_.delay( function() {
|
||||
_doAnimateToTarget.call($el);
|
||||
}, 200 );
|
||||
} else {
|
||||
_doAnimateToTarget.call($el);
|
||||
}
|
||||
};
|
||||
var maybeScrollToAnchor = function( evt ){
|
||||
// problem to solve : users want to define anchor links that work inside a page, but also from other pages.
|
||||
// @see https://github.com/presscustomizr/nimble-builder/issues/413
|
||||
var clickedItemUrl = $(this).attr('href');
|
||||
if ( '' === clickedItemUrl || null === clickedItemUrl || 'string' !== typeof( clickedItemUrl ) || -1 === clickedItemUrl.indexOf('#') )
|
||||
return;
|
||||
|
||||
// an anchor link looks like this : http://mysite.com/contact/#anchor
|
||||
var itemURLObject = new parseURL( clickedItemUrl ),
|
||||
_currentPageUrl = new parseURL( window.document.location.href );
|
||||
|
||||
if( itemURLObject.pathname !== _currentPageUrl.pathname )
|
||||
return;
|
||||
if( 'string' !== typeof(itemURLObject.hash) || '' === itemURLObject.hash )
|
||||
return;
|
||||
|
||||
var $nimbleTargetCandidate = $('[data-sek-level="location"]' ).find( '[id="' + itemURLObject.hash.replace('#','') + '"]');
|
||||
if ( 1 !== $nimbleTargetCandidate.length )
|
||||
return;
|
||||
|
||||
evt.preventDefault();
|
||||
|
||||
// Sept 2020 => LAYOUT SHIFT PROBLEMS
|
||||
// => if lazy load is enabled and there are still images to load, make sure all images are loaded before scrolling to an anchor
|
||||
// => lazyload all images + add a tiny delay before scrolling
|
||||
// otherwise, the scroll might no land to the right place, due to image dimensions not OK ( occurs on chrome and edge at least )
|
||||
// see https://github.com/presscustomizr/nimble-builder/issues/744
|
||||
// additional issue : https://github.com/presscustomizr/nimble-builder/issues/748
|
||||
var _scrollDelay = 0;
|
||||
if ( sekFrontLocalized.lazyload_enabled && false === window.nb_allImagesLazyLoadedForScrollToAnchor && $('img[data-sek-src]').not('.sek-lazy-load-error').length > 0 ) {
|
||||
$('body').one( 'smartload', 'img', function() { _checkThatAllImgAreLoaded.call( $nimbleTargetCandidate );} );
|
||||
$('img[data-sek-src]').trigger('sek_load_img');
|
||||
} else {
|
||||
_doAnimateToTarget.call( $nimbleTargetCandidate );
|
||||
}
|
||||
};
|
||||
|
||||
// animate menu item to Nimble anchors
|
||||
nb_.cachedElements.$body.find('.menu-item' ).on( 'click', 'a', maybeScrollToAnchor );
|
||||
|
||||
// animate an anchor link inside Nimble sections
|
||||
// fixes https://github.com/presscustomizr/nimble-builder/issues/443
|
||||
$('[data-sek-level="location"]' ).on( 'click', 'a', maybeScrollToAnchor );
|
||||
});
|
||||
};/////////////// callbackFunc
|
||||
|
||||
nb_.listenTo('nb-app-ready', callbackFunc );
|
||||
}(window, document));
|
||||
+294
@@ -0,0 +1,294 @@
|
||||
/* ===================================================
|
||||
* jquerynimbleLazyLoad.js v1.0.0
|
||||
* ===================================================
|
||||
*
|
||||
* Replace all img src placeholder in the $element by the real src on scroll window event
|
||||
* Handles background image for sections
|
||||
* Hacked to lazyload iframes
|
||||
*
|
||||
* Note : the data-src (data-srcset) attr has to be pre-processed before the actual page load
|
||||
* Example of regex to pre-process img server side with php :
|
||||
* preg_replace_callback('#<img([^>]+?)src=[\'"]?([^\'"\s>]+)[\'"]?([^>]*)>#', 'regex_callback' , $_html)
|
||||
*
|
||||
* Note May 2020 : lazyload can be skipped by adding data-skip-lazyload="true" to the img src when generating the HTML markup
|
||||
*
|
||||
* (c) 2020 Nicolas Guillaume, Nice, France
|
||||
*
|
||||
* Example of gif 1px x 1px placeholder :
|
||||
* 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
|
||||
*
|
||||
* inspired by the work of Luís Almeida
|
||||
* http://luis-almeida.github.com/unveil
|
||||
*
|
||||
* Requires requestAnimationFrame polyfill:
|
||||
* http://paulirish.com/2011/requestanimationframe-for-smart-animating/
|
||||
*
|
||||
* Feb 2019 : added support for iframe lazyloading for https://github.com/presscustomizr/nimble-builder/issues/361
|
||||
* =================================================== */
|
||||
// global sekFrontLocalized, nimbleListenTo
|
||||
(function(w, d){
|
||||
var callbackFunc = function() {
|
||||
(function ( $, window ) {
|
||||
//defaults
|
||||
var pluginName = 'nimbleLazyLoad',
|
||||
defaults = {
|
||||
load_all_images_on_first_scroll : false,
|
||||
//attribute : [ 'data-sek-src' ],
|
||||
threshold : 100,
|
||||
fadeIn_options : { duration : 400 },
|
||||
delaySmartLoadEvent : 0,
|
||||
candidateSelectors : '[data-sek-src], [data-sek-iframe-src]',
|
||||
force:false//<= can be useful when nb_.isCustomizing()
|
||||
},
|
||||
//- to avoid multi processing in general
|
||||
_skipLoadClass = 'sek-lazy-loaded';
|
||||
|
||||
|
||||
function Plugin( element, options ) {
|
||||
this.element = element;
|
||||
this.options = $.extend( {}, defaults, options);
|
||||
var allowLazyLoad = sekFrontLocalized.lazyload_enabled;
|
||||
if ( this.options.force ) {
|
||||
allowLazyLoad = true;
|
||||
}
|
||||
|
||||
if ( !allowLazyLoad )
|
||||
return;
|
||||
// Do we already have an instance for this element ?
|
||||
if ( $(this.element).data('nimbleLazyLoadDone') ) {
|
||||
$(this.element).trigger('nb-trigger-lazyload' );
|
||||
return;
|
||||
}
|
||||
|
||||
this._defaults = defaults;
|
||||
this._name = pluginName;
|
||||
var self = this;
|
||||
// 'nb-trigger-lazyload' can be fired from the slider module
|
||||
$(this.element).on('nb-trigger-lazyload', function() {
|
||||
self._maybe_trigger_load( 'nb-trigger-lazyload' );
|
||||
});
|
||||
this.init();
|
||||
}
|
||||
|
||||
Plugin.prototype._getCandidateEls = function() {
|
||||
return $( this.options.candidateSelectors, this.element );
|
||||
};
|
||||
|
||||
//can access this.element and this.option
|
||||
Plugin.prototype.init = function () {
|
||||
var self = this;
|
||||
// img to be lazy loaded looks like data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
// [src*="data:image"] =>
|
||||
// [data-sek-src*="http"] => background images, images in image modules, wp editor module, post grids, slider module, etc..
|
||||
// [data-sek-iframe-src] => ?
|
||||
|
||||
// Bind with delegation
|
||||
// April 2020 : implemented for https://github.com/presscustomizr/nimble-builder/issues/669
|
||||
$('body').on( 'sek_load_img sek_load_iframe', self.options.candidateSelectors , function( evt ) {
|
||||
// has this image been lazy loaded ?
|
||||
if ( true === $(this).data( 'sek-lazy-loaded' ) )
|
||||
return;
|
||||
if ( 'sek_load_img' === evt.type ) {
|
||||
self._load_img(this);
|
||||
} else if ( 'sek_load_iframe' === evt.type ) {
|
||||
self._load_iframe(this);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
//the scroll event gets throttled with the requestAnimationFrame
|
||||
nb_.cachedElements.$window.on('scroll', function( _evt ) {
|
||||
self._better_scroll_event_handler( _evt );
|
||||
});
|
||||
//debounced resize event
|
||||
nb_.cachedElements.$window.on('resize', nb_.debounce( function( _evt ) {
|
||||
self._maybe_trigger_load( _evt );
|
||||
}, 100 ) );
|
||||
|
||||
// on DOM ready
|
||||
this._maybe_trigger_load('dom-ready');
|
||||
// Wait and trigger the dom-ready again, so we don't miss any image initially below the viewport
|
||||
// ( can happen if the height of a page element like a slider is modified at dom ready )
|
||||
setTimeout( function() {
|
||||
self._maybe_trigger_load('dom-ready');
|
||||
}, 1000 );
|
||||
|
||||
// flag so we can check whether his element has been lazyloaded
|
||||
$(this.element).data('nimbleLazyLoadDone', true );
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* @param : array of $img
|
||||
* @param : current event
|
||||
* @return : void
|
||||
* scroll event performance enhancer => avoid browser stack if too much scrolls
|
||||
*/
|
||||
Plugin.prototype._better_scroll_event_handler = function( _evt ) {
|
||||
var self = this;
|
||||
if ( ! this.doingAnimation ) {
|
||||
this.doingAnimation = true;
|
||||
window.requestAnimationFrame(function() {
|
||||
self._maybe_trigger_load(_evt );
|
||||
self.doingAnimation = false;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* @param : array of $img
|
||||
* @param : current event
|
||||
* @return : void
|
||||
*/
|
||||
Plugin.prototype._maybe_trigger_load = function(_evt ) {
|
||||
var self = this,
|
||||
$_imgs = self._getCandidateEls(),
|
||||
// get the visible images list
|
||||
// don't apply a threshold on page load so that Google audit is happy
|
||||
// for https://github.com/presscustomizr/nimble-builder/issues/619
|
||||
threshold = ( _evt && 'scroll' === _evt.type ) ? this.options.threshold : 0;
|
||||
|
||||
_visible_list = $_imgs.filter( function( ind, _el ) {
|
||||
//force all images to visible if first scroll option enabled
|
||||
if ( _evt && 'scroll' == _evt.type && self.options.load_all_images_on_first_scroll )
|
||||
return true;
|
||||
return nb_.elOrFirstVisibleParentIsInWindow( _el, threshold );
|
||||
});
|
||||
|
||||
//trigger load_img event for visible images
|
||||
_visible_list.map( function( ind, _el ) {
|
||||
// trigger a lazy load if image not processed yet
|
||||
if ( true !== $(_el).data( 'sek-lazy-loaded' ) ) {
|
||||
if ( 'IFRAME' === $(_el).prop("tagName") ) {
|
||||
$(_el).trigger( 'sek_load_iframe' );
|
||||
} else {
|
||||
$(_el).trigger( 'sek_load_img' );
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* @param single $img object
|
||||
* @return void
|
||||
* replace src place holder by data-src attr val which should include the real src
|
||||
*/
|
||||
Plugin.prototype._load_img = function( _el_ ) {
|
||||
var $_el = $(_el_);
|
||||
|
||||
// Stop here if
|
||||
// - the image has no data-sek-src attribute
|
||||
// - the image has already been lazyloaded
|
||||
// - the image is being lazyloaded
|
||||
if ( !$_el.attr( 'data-sek-src' ) || $_el.hasClass( _skipLoadClass ) || $_el.hasClass( 'lazy-loading' ) )
|
||||
return;
|
||||
|
||||
var _src = $_el.attr( 'data-sek-src' ),
|
||||
_src_set = $_el.attr( 'data-sek-srcset' ),
|
||||
_sizes = $_el.attr( 'data-sek-sizes' ),
|
||||
self = this,
|
||||
$jQueryImgToLoad = $("<img />", { src : _src } );
|
||||
|
||||
$_el.addClass('lazy-loading');
|
||||
$_el.off('sek_load_img');
|
||||
|
||||
$jQueryImgToLoad
|
||||
// .hide()
|
||||
.on( 'load', function () {
|
||||
//https://api.jquery.com/removeAttr/
|
||||
//An attribute to remove; as of version 1.7, it can be a space-separated list of attributes.
|
||||
//minimum supported wp version (3.4+) embeds jQuery 1.7.2
|
||||
$_el.removeAttr( [ 'data-sek-src', 'data-sek-srcset', 'data-sek-sizes' ].join(' ') );
|
||||
// Case of a lazyloaded background
|
||||
if( $_el.data("sek-lazy-bg") ){
|
||||
$_el.css('backgroundImage', 'url('+_src+')');
|
||||
} else {
|
||||
// Case of a regular image
|
||||
$_el.attr("src", _src );
|
||||
if ( _src_set ) {
|
||||
$_el.attr("srcset", _src_set );
|
||||
}
|
||||
if ( _sizes ) {
|
||||
$_el.attr("sizes", _sizes );
|
||||
}
|
||||
}
|
||||
//prevent executing this twice on an already smartloaded img
|
||||
if ( ! $_el.hasClass(_skipLoadClass) ) {
|
||||
$_el.addClass(_skipLoadClass);
|
||||
}
|
||||
//Following would be executed twice if needed, as some browsers at the
|
||||
//first execution of the load callback might still have not actually loaded the img
|
||||
|
||||
$_el.trigger('smartload');
|
||||
//flag to avoid double triggering
|
||||
$_el.data('sek-lazy-loaded', true );
|
||||
self._clean_css_loader( $_el );
|
||||
|
||||
})//<= create a load() fn
|
||||
.on('error', function( evt, error ) {
|
||||
$_el.addClass('sek-lazy-load-error');
|
||||
});// on error
|
||||
//http://stackoverflow.com/questions/1948672/how-to-tell-if-an-image-is-loaded-or-cached-in-jquery
|
||||
if ( $jQueryImgToLoad[0].complete ) {
|
||||
$jQueryImgToLoad.trigger( 'load' );
|
||||
}
|
||||
$_el.removeClass('lazy-loading');
|
||||
};
|
||||
|
||||
// Remove CSS loaded markup close to the element if any
|
||||
Plugin.prototype._clean_css_loader = function( $_el ) {
|
||||
// maybe remove the CSS loader
|
||||
$.each( [ $_el.find('.sek-css-loader'), $_el.parent().find('.sek-css-loader') ], function( k, $_el ) {
|
||||
if ( $_el.length > 0 )
|
||||
$_el.remove();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* @param single iframe el object
|
||||
* @return void
|
||||
*/
|
||||
Plugin.prototype._load_iframe = function( _el_ ) {
|
||||
var $_el = $(_el_),
|
||||
self = this;
|
||||
|
||||
//$_el.addClass('lazy-loading');
|
||||
$_el.off('sek_load_iframe');
|
||||
|
||||
$_el.attr( 'src', function() {
|
||||
var src = $(this).attr('data-sek-iframe-src');
|
||||
$(this).removeAttr('data-sek-iframe-src');
|
||||
$_el.data('sek-lazy-loaded', true );
|
||||
$_el.trigger('smartload');
|
||||
if ( ! $_el.hasClass(_skipLoadClass) ) {
|
||||
$_el.addClass(_skipLoadClass);
|
||||
}
|
||||
return src;
|
||||
});
|
||||
//$_el.removeClass('lazy-loading');
|
||||
};
|
||||
|
||||
|
||||
// prevents against multiple instantiations
|
||||
$.fn[pluginName] = function ( options ) {
|
||||
return this.each(function () {
|
||||
if (!$.data(this, 'plugin_' + pluginName)) {
|
||||
$.data(this, 'plugin_' + pluginName,
|
||||
new Plugin( this, options ));
|
||||
}
|
||||
});
|
||||
};
|
||||
})( jQuery, window );
|
||||
|
||||
};////////////// callbackFunc
|
||||
// on 'nb-app-ready', jQuery is loaded
|
||||
nb_.listenTo('nb-app-ready', function(){
|
||||
callbackFunc();
|
||||
// Sept 2020 => always emit lazyload parsed event when customizing
|
||||
if ( sekFrontLocalized.lazyload_enabled || nb_.isCustomizing() ) { nb_.emit('nb-lazyload-parsed'); }
|
||||
});
|
||||
}(window, document));
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
// global sekFrontLocalized, nimbleListenTo
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* SCROLL LISTENER FOR DYNAMIC ASSET LOADING
|
||||
/* ------------------------------------------------------------------------- */
|
||||
(function(w, d){
|
||||
// Fire now or schedule when becoming visible.
|
||||
nb_.loadAssetWhenElementVisible = function( id, handlerParams ) {
|
||||
jQuery(function($){
|
||||
if ( nb_.scrollHandlers[id].loaded )
|
||||
return;
|
||||
nb_.scrollHandlers[id].loaded = false;
|
||||
var $elements = handlerParams.elements,
|
||||
loaderFunc = handlerParams.func;
|
||||
|
||||
$.each( $elements, function( k, el ) {
|
||||
if ( !nb_.scrollHandlers[id].loaded && nb_.elOrFirstVisibleParentIsInWindow($(el) ) ) {
|
||||
loaderFunc();
|
||||
nb_.scrollHandlers[id].loaded = true;
|
||||
}
|
||||
});
|
||||
|
||||
if ( handlerParams.scrollHandler && nb_.scrollHandlers[id].loaded ) {
|
||||
nb_.cachedElements.$window.off('scroll', handlerParams.scrollHandler );
|
||||
}
|
||||
});
|
||||
};//_loadAssetWhenElementVisible
|
||||
|
||||
nb_.loopOnScrollHandlers = function() {
|
||||
var _scrollHandler;
|
||||
jQuery(function($){
|
||||
$.each( nb_.scrollHandlers, function( id, handlerParams ) {
|
||||
// has it been loaded already ?
|
||||
if ( handlerParams.loaded )
|
||||
return true;//<=> continue see https://api.jquery.com/jquery.each/
|
||||
|
||||
// do nothing if dynamic asset loading is not enabled for js and css AND the assets in not in "force" mode
|
||||
var load_authorized = sekFrontLocalized.load_front_assets_on_dynamically;
|
||||
if ( true === handlerParams.force_loading ) {
|
||||
load_authorized = true;
|
||||
}
|
||||
if ( !load_authorized )
|
||||
return;
|
||||
|
||||
if ( 1 > handlerParams.elements.length )
|
||||
return true;
|
||||
|
||||
// try on load
|
||||
try{ nb_.loadAssetWhenElementVisible( id, handlerParams ); } catch(er){
|
||||
nb_.errorLog('Nimble error => nb_.loopOnScrollHandlers', er, handlerParams );
|
||||
}
|
||||
|
||||
// schedule on scroll
|
||||
// the scroll event is unbound once the scrollhandler is executed
|
||||
if( nb_.isFunction( handlerParams.func ) && nb_.isUndefined( handlerParams.scrollHandler ) ) {
|
||||
handlerParams.scrollHandler = nb_.throttle( function() {
|
||||
try{ nb_.loadAssetWhenElementVisible( id, handlerParams ); } catch(er){
|
||||
nb_.errorLog('Nimble error => nb_.loopOnScrollHandlers', er, handlerParams );
|
||||
}
|
||||
}, 100 );
|
||||
|
||||
nb_.cachedElements.$window.on( 'scroll', handlerParams.scrollHandler );
|
||||
} else if ( !nb_.isFunction( handlerParams.func ) ) {
|
||||
nb_.errorLog('Nimble error => nb_.loopOnScrollHandlers => wrong callback func param', handlerParams );
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
nb_.listenTo('nb-app-ready', function() {
|
||||
jQuery(function($){
|
||||
// nb_.scrollHandlers = [
|
||||
// { id : 'swiper', elements : $(), func : function(){} }
|
||||
// ...
|
||||
// ]
|
||||
|
||||
// each time a new scroll handler is added, it emits the event 'nimble-new-scroll-handler-added'
|
||||
// so when caught, let's try to detect any dependant element is visible in the page
|
||||
// and if so, load.
|
||||
// Typically useful on page load if for example the slider is on top of the page and we need to load swiper-bundle.js right away before scrolling
|
||||
nb_.listenTo('nimble-new-scroll-handler-added', nb_.loopOnScrollHandlers );
|
||||
|
||||
});//jQuery
|
||||
});
|
||||
}(window, document));
|
||||
+233
@@ -0,0 +1,233 @@
|
||||
// global sekFrontLocalized, nimbleListenTo, nb_
|
||||
(function(w, d){
|
||||
nb_.listenTo( 'nb-app-ready', function() {
|
||||
jQuery(function($){
|
||||
// params = {
|
||||
// elements : $swiperCandidate,
|
||||
// func : function() {}
|
||||
// }
|
||||
nb_.maybeLoadAssetsWhenSelectorInScreen = function( params ) {
|
||||
params = $.extend( { id : '', elements : '', func : '' }, params );
|
||||
|
||||
if ( 1 > params.id.length ) {
|
||||
nb_.errorLog('Nimble error => maybeLoadAssetsWhenSelectorInScreen => missing id', params );
|
||||
return;
|
||||
}
|
||||
if ( 1 > $(params.elements).length )
|
||||
return;
|
||||
if ( !nb_.isFunction( params.func ) )
|
||||
return;
|
||||
|
||||
// populate the collection of scroll handlers looped on ::loopOnScrollHandlers()
|
||||
// + emit
|
||||
nb_.scrollHandlers = nb_.scrollHandlers || {};
|
||||
var handlerParams = { elements : params.elements, func : params.func, force_loading : params.force_loading };
|
||||
nb_.scrollHandlers[params.id] = handlerParams;
|
||||
nb_.emit('nimble-new-scroll-handler-added', { fire_once : false } );
|
||||
};
|
||||
nb_.emit('nimble-ready-to-load-assets-on-scroll');
|
||||
});//jQuery(function($){})
|
||||
});//'nb-app-ready'
|
||||
}(window, document));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* LOAD SWIPEBOX
|
||||
/* ------------------------------------------------------------------------- */
|
||||
(function(w, d){
|
||||
var callbackFunc = function() {
|
||||
jQuery(function($){
|
||||
if ( !sekFrontLocalized.load_front_assets_on_dynamically )
|
||||
return;
|
||||
|
||||
var $linkCandidates = $('[data-sek-module-type="czr_image_module"]').find('.sek-link-to-img-lightbox');
|
||||
$linkCandidates = $linkCandidates.add($('[data-sek-level="module"]').find('.sek-gal-link-to-img-lightbox'));
|
||||
// Abort if no link candidate, or if the link href looks like :javascript:void(0) <= this can occur with the default image for example.
|
||||
if ( $linkCandidates.length < 1 )
|
||||
return;
|
||||
var doLoad = function() {
|
||||
//Load the style
|
||||
if ( $('head').find( '#nb-swipebox' ).length < 1 ) {
|
||||
$('head').append( $('<link/>' , {
|
||||
rel : 'stylesheet',
|
||||
id : 'nb-swipebox',
|
||||
type : 'text/css',
|
||||
href : sekFrontLocalized.frontAssetsPath + 'css/libs/swipebox.min.css?' + sekFrontLocalized.assetVersion
|
||||
}) );
|
||||
}
|
||||
|
||||
if ( !nb_.isFunction( $.fn.swipebox ) && sekFrontLocalized.load_front_assets_on_dynamically ) {
|
||||
nb_.ajaxLoadScript({
|
||||
path : 'js/libs/jquery-swipebox.min.js',
|
||||
loadcheck : function() { return nb_.isFunction( $.fn.swipebox ); }
|
||||
});
|
||||
}
|
||||
};// doLoad
|
||||
|
||||
// Load js plugin if needed
|
||||
// when the plugin is loaded => it emits 'nb-swipebox-parsed' listened to by nb_.listenTo()
|
||||
nb_.maybeLoadAssetsWhenSelectorInScreen( {
|
||||
id : 'swipebox',
|
||||
elements : $linkCandidates,
|
||||
func : doLoad
|
||||
});
|
||||
});//jQuery(function($){})
|
||||
};/////////////// callbackFunc
|
||||
|
||||
//When loaded with defer, we can not be sure that jQuery will be loaded before
|
||||
nb_.listenTo( 'nb-app-ready', function() {
|
||||
nb_.listenTo( 'nb-needs-swipebox', callbackFunc );
|
||||
});
|
||||
}(window, document));
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* MAYBE LOAD SWIPER ON SCROLL
|
||||
/* ------------------------------------------------------------------------- */
|
||||
(function(w, d){
|
||||
var callbackFunc = function() {
|
||||
jQuery(function($){
|
||||
if ( !sekFrontLocalized.load_front_assets_on_dynamically )
|
||||
return;
|
||||
// Load js plugin if needed
|
||||
// // when the plugin is loaded => it emits 'nimble-swiper-ready' listened to by nb_.listenTo()
|
||||
var doLoad = function() {
|
||||
//Load the style
|
||||
if ( $('head').find( '#czr-swiper' ).length < 1 ) {
|
||||
$('head').append( $('<link/>' , {
|
||||
rel : 'stylesheet',
|
||||
id : 'czr-swiper',
|
||||
type : 'text/css',
|
||||
href : sekFrontLocalized.frontAssetsPath + 'css/libs/swiper-bundle.min.css?'+sekFrontLocalized.assetVersion
|
||||
}) );
|
||||
}
|
||||
nb_.ajaxLoadScript({
|
||||
path : 'js/libs/swiper-bundle.min.js?'+sekFrontLocalized.assetVersion,
|
||||
loadcheck : function() { return nb_.isFunction( window.Swiper ); },
|
||||
// complete : function() {
|
||||
// nb_.ajaxLoadScript({
|
||||
// path : 'js/prod-front-simple-slider-module.min.js',
|
||||
// });
|
||||
// }
|
||||
});
|
||||
};// doLoad
|
||||
|
||||
// is it already loaded ?
|
||||
if ( nb_.isFunction( window.Swiper ) )
|
||||
return;
|
||||
|
||||
// do we have candidate selectors printed on page ?
|
||||
var $swiperCandidates = $('[data-sek-module-type="czr_img_slider_module"]');
|
||||
if ( $swiperCandidates.length < 1 )
|
||||
return;
|
||||
|
||||
nb_.maybeLoadAssetsWhenSelectorInScreen( {
|
||||
id : 'swiper',
|
||||
elements : $swiperCandidates,
|
||||
func : doLoad
|
||||
});
|
||||
});//jQuery(function($){})
|
||||
};/////////////// callbackFunc
|
||||
|
||||
// When loaded with defer, we can not be sure that jQuery will be loaded before
|
||||
// on 'nb-app-ready', jQuery is loaded
|
||||
nb_.listenTo( 'nb-app-ready', function() {
|
||||
nb_.listenTo('nb-needs-swiper', callbackFunc );
|
||||
});
|
||||
}(window, document));
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* LOAD VIDEO BACKGROUND JS
|
||||
/* ------------------------------------------------------------------------- */
|
||||
(function(w, d){
|
||||
var callbackFunc = function() {
|
||||
jQuery(function($){
|
||||
if ( !sekFrontLocalized.load_front_assets_on_dynamically )
|
||||
return;
|
||||
var $candidates = $('[data-sek-video-bg-src]');
|
||||
// Abort if no link candidate, or if the link href looks like :javascript:void(0) <= this can occur with the default image for example.
|
||||
if ( $candidates.length < 1 )
|
||||
return;
|
||||
|
||||
// Load js plugin if needed
|
||||
// when the plugin is loaded => it emits 'nb-..-parsed' listened to by nb_.listenTo()
|
||||
nb_.maybeLoadAssetsWhenSelectorInScreen( {
|
||||
id : 'nb-video-bg',
|
||||
elements : $candidates,
|
||||
func : function() {
|
||||
//Load js
|
||||
nb_.ajaxLoadScript({
|
||||
path : 'js/libs/nimble-video-bg.min.js?'+sekFrontLocalized.assetVersion
|
||||
});
|
||||
}// doLoad
|
||||
});
|
||||
});// jQuery
|
||||
};/////////////// callbackFunc
|
||||
nb_.listenTo('nb-app-ready', function() {
|
||||
nb_.listenTo('nb-needs-videobg-js', callbackFunc );
|
||||
});
|
||||
}(window, document));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* MAYBE LOAD FONTAWESOME ON SCROLL
|
||||
/* ------------------------------------------------------------------------- */
|
||||
(function(w, d){
|
||||
var callbackFunc = function() {
|
||||
jQuery(function($){
|
||||
// we don't need to inject font awesome if already enqueued by a theme
|
||||
if ( sekFrontLocalized.fontAwesomeAlreadyEnqueued )
|
||||
return;
|
||||
if ( !sekFrontLocalized.load_front_assets_on_dynamically )
|
||||
return;
|
||||
var $candidates = $('i[class*=fa-]');
|
||||
|
||||
if ( $candidates.length < 1 )
|
||||
return;
|
||||
|
||||
// Load js plugin if needed
|
||||
// when the plugin is loaded => it emits "nb-needs-fa" listened to by nb_.listenTo()
|
||||
var doLoad = function() {
|
||||
//Load the style
|
||||
if ( $('head').find( '#nb-font-awesome' ).length < 1 ) {
|
||||
var link = document.createElement('link');
|
||||
link.setAttribute('href', sekFrontLocalized.frontAssetsPath + 'fonts/css/fontawesome-all.min.css?'+sekFrontLocalized.assetVersion );
|
||||
link.setAttribute('id', 'nb-font-awesome');
|
||||
link.setAttribute('data-sek-injected-dynamically', 'yes');
|
||||
link.setAttribute('rel', nb_.hasPreloadSupport() ? 'preload' : 'stylesheet' );
|
||||
link.setAttribute('as', 'style');
|
||||
link.onload = function() {
|
||||
this.onload=null;
|
||||
if ( nb_.hasPreloadSupport() ) {
|
||||
this.rel='stylesheet';
|
||||
}
|
||||
};
|
||||
document.getElementsByTagName('head')[0].appendChild(link);
|
||||
}
|
||||
};// doLoad
|
||||
// Load js plugin if needed
|
||||
// when the plugin is loaded => it emits 'nb-...-parsed' listened to by nb_.listenTo()
|
||||
nb_.maybeLoadAssetsWhenSelectorInScreen({
|
||||
id : 'font-awesome',
|
||||
elements : $candidates,
|
||||
func : doLoad
|
||||
});
|
||||
});//jQuery(function($){})
|
||||
};/////////////// callbackFunc
|
||||
|
||||
// When loaded with defer, we can not be sure that jQuery will be loaded before
|
||||
// on 'nb-app-ready', jQuery is loaded
|
||||
nb_.listenTo( 'nb-app-ready', function() {
|
||||
nb_.listenTo( 'nb-needs-fa', callbackFunc );
|
||||
});
|
||||
}(window, document));
|
||||
+211
@@ -0,0 +1,211 @@
|
||||
// global sekFrontLocalized, nimbleListenTo
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* LIGHT BOX SWIPEBOX ( April 2022 for #886)
|
||||
/* ------------------------------------------------------------------------- */
|
||||
(function(w, d){
|
||||
nb_.listenTo('nb-swipebox-parsed', function() {
|
||||
jQuery(function($){
|
||||
if ( nb_.isCustomizing() )
|
||||
return;
|
||||
|
||||
var $linkCandidates = [
|
||||
$('[data-sek-level="module"]').find('.sek-link-to-img-lightbox'),// image module
|
||||
$('[data-sek-level="module"]').find('.sek-gal-link-to-img-lightbox')// gallery module
|
||||
];
|
||||
|
||||
//https://github.com/brutaldesign/swipebox
|
||||
var _params = {
|
||||
loopAtEnd: true
|
||||
};
|
||||
//var $linkCand;
|
||||
$.each( $linkCandidates, function(_k, $linkCand) {
|
||||
// Abort if no link candidate
|
||||
if ( $linkCand.length < 1 ) {
|
||||
return;
|
||||
}
|
||||
// Abort if candidate already setup
|
||||
if ( $linkCand.data('nimble-swiperbox-done') )
|
||||
return;
|
||||
try { $linkCand.swipebox( _params ); } catch( er ) {
|
||||
nb_.errorLog( 'error in callback of nb-swipebox-parsed => ', er );
|
||||
}
|
||||
$linkCand.data('nimble-swiperbox-done', true );
|
||||
});
|
||||
|
||||
// July 2021, prevent gallery images to be clicked when no link is specified
|
||||
$('.sek-gallery-lightbox').on('click', '.sek-no-img-link', function(evt) {
|
||||
evt.preventDefault();
|
||||
});
|
||||
|
||||
});//jQuery(function($){})
|
||||
});
|
||||
}(window, document));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* SMARTLOAD
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// nimble-lazyload-parsed is fired in lazyload plugin, only when sekFrontLocalized.lazyload_enabled OR when nb_.isCustomizing()
|
||||
(function(w, d){
|
||||
nb_.listenTo('nb-lazyload-parsed', function() {
|
||||
jQuery(function($){
|
||||
var _do = function(evt) {
|
||||
$(this).each( function() {
|
||||
var _maybeDoLazyLoad = function() {
|
||||
// if the element already has an instance of nimbleLazyLoad, simply trigger an event
|
||||
if ( !$(this).data('nimbleLazyLoadDone') ) {
|
||||
$(this).nimbleLazyLoad({force : nb_.isCustomizing()});
|
||||
} else {
|
||||
$(this).trigger('nb-trigger-lazyload');
|
||||
}
|
||||
};
|
||||
try { _maybeDoLazyLoad.call($(this)); } catch( er ) {
|
||||
nb_.errorLog( 'error with nimbleLazyLoad => ', er );
|
||||
}
|
||||
});
|
||||
};
|
||||
// on page load
|
||||
_do.call( $('.sektion-wrapper') );
|
||||
// when customizing
|
||||
nb_.cachedElements.$body.on( 'sek-section-added sek-level-refreshed sek-location-refreshed sek-columns-refreshed sek-modules-refreshed', '[data-sek-level="location"]', function(evt) {
|
||||
_do.call( $(this), evt );
|
||||
_.delay( function() {
|
||||
nb_.cachedElements.$window.trigger('resize');
|
||||
}, 200 );
|
||||
});
|
||||
|
||||
|
||||
// TO EXPLORE : implement a mutation observer like in Hueman theme for images dynamically inserted in the DOM via ajax ?
|
||||
// Is it really needed now that lazyload uses event delegation to trigger image loading ?
|
||||
// ( see https://github.com/presscustomizr/nimble-builder/issues/669 )
|
||||
// Observer Mutations of the DOM for a given element selector
|
||||
// <=> of previous $(document).bind( 'DOMNodeInserted', fn );
|
||||
// implemented to fix https://github.com/presscustomizr/hueman/issues/880
|
||||
// see https://stackoverflow.com/questions/10415400/jquery-detecting-div-of-certain-class-has-been-added-to-dom#10415599
|
||||
// observeAddedNodesOnDom : function(containerSelector, elementSelector, callback) {
|
||||
// var onMutationsObserved = function(mutations) {
|
||||
// mutations.forEach(function(mutation) {
|
||||
// if (mutation.addedNodes.length) {
|
||||
// var elements = $(mutation.addedNodes).find(elementSelector);
|
||||
// for (var i = 0, len = elements.length; i < len; i++) {
|
||||
// callback(elements[i]);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// },
|
||||
// target = $(containerSelector)[0],
|
||||
// config = { childList: true, subtree: true },
|
||||
// MutationObserver = window.MutationObserver || window.WebKitMutationObserver,
|
||||
// observer = new MutationObserver(onMutationsObserved);
|
||||
|
||||
// observer.observe(target, config);
|
||||
// }
|
||||
// Observer Mutations off the DOM to detect images
|
||||
// <=> of previous $(document).bind( 'DOMNodeInserted', fn );
|
||||
// implemented to fix https://github.com/presscustomizr/hueman/issues/880
|
||||
// this.observeAddedNodesOnDom('body', 'img', _.debounce( function(element) {
|
||||
// _doLazyLoad();
|
||||
// }, 50 ));
|
||||
|
||||
});
|
||||
});
|
||||
}(window, document));
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* BG PARALLAX
|
||||
/* ------------------------------------------------------------------------- */
|
||||
(function(w, d){
|
||||
nb_.listenTo('nb-parallax-parsed', function() {
|
||||
jQuery(function($){
|
||||
$('[data-sek-bg-parallax="true"]').each( function() {
|
||||
$(this).parallaxBg( { parallaxForce : $(this).data('sek-parallax-force') } );
|
||||
});
|
||||
var _setParallaxWhenCustomizing = function() {
|
||||
$(this).parallaxBg( { parallaxForce : $(this).data('sek-parallax-force') } );
|
||||
// hack => always trigger a 'resize' event with a small delay to make sure bg positions are ok
|
||||
setTimeout( function() {
|
||||
nb_.cachedElements.$body.trigger('resize');
|
||||
}, 500 );
|
||||
};
|
||||
// When previewing, react to level refresh
|
||||
// This can occur to any level. We listen to the bubbling event on 'body' tag
|
||||
// and salmon up to maybe instantiate any missing candidate
|
||||
// Example : when a preset_section is injected
|
||||
nb_.cachedElements.$body.on('sek-level-refreshed sek-section-added', function( evt ){
|
||||
if ( "true" === $(this).data('sek-bg-parallax') ) {
|
||||
_setParallaxWhenCustomizing.call(this);
|
||||
} else {
|
||||
$(this).find('[data-sek-bg-parallax="true"]').each( function() {
|
||||
_setParallaxWhenCustomizing.call(this);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}(window, document));
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* GRID MODULE
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// June 2020 : added for https://github.com/presscustomizr/nimble-builder/issues/716
|
||||
nb_.listenTo('nb-docready', function() {
|
||||
if ( window.nb_ && window.nb_.getQueryVariable ) {
|
||||
var anchorId = window.nb_.getQueryVariable('nb_grid_module_go_to'),
|
||||
el = document.getElementById(anchorId);
|
||||
// Then clean the url
|
||||
var _cleanUrl = function() {
|
||||
var currPathName = window.location.pathname; //get current address
|
||||
//1- get the part before '?go_to'
|
||||
var beforeQueryString = currPathName.split("?go_to")[0];
|
||||
window.history.replaceState({}, document.title, beforeQueryString );
|
||||
};
|
||||
if( anchorId && el ) {
|
||||
setTimeout( function() { el.scrollIntoView();}, 200 );
|
||||
try{ _cleanUrl(); } catch(er) {
|
||||
if( window.console && window.console.log ) {
|
||||
console.log( 'NB => error when cleaning url "go_to" param');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// September 2021 => Solves the problem of CSS loaders not cleaned
|
||||
// see https://github.com/presscustomizr/nimble-builder/issues/874
|
||||
nb_.listenTo('nb-app-ready', function() {
|
||||
jQuery(function($){
|
||||
var $cssLoaders = $('.sek-css-loader');
|
||||
if ( $cssLoaders.length < 1 )
|
||||
return;
|
||||
|
||||
var $el,
|
||||
removeCssLoaderAfterADelay = nb_.throttle( function() {
|
||||
$cssLoaders = $('.sek-css-loader');
|
||||
$.each($cssLoaders, function(){
|
||||
$el = $(this);
|
||||
if ( nb_.elOrFirstVisibleParentIsInWindow($el) ) {
|
||||
nb_.delay( function() {
|
||||
if ( $el.length > 0 ) {
|
||||
$el.remove();
|
||||
}
|
||||
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
|
||||
if ( $cssLoaders.length < 1 ) {
|
||||
// When no more loaders to remove, remove scroll listener
|
||||
nb_.cachedElements.$window.off('scroll', removeCssLoaderAfterADelay );
|
||||
}
|
||||
}, 200 );
|
||||
nb_.cachedElements.$window.on('scroll', removeCssLoaderAfterADelay );
|
||||
});
|
||||
});
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// printed in function sek_customizr_js_stuff()
|
||||
// global sekFrontLocalized, nimbleListenTo
|
||||
(function(w, d){
|
||||
nb_.listenTo( 'nb-app-ready', function() {
|
||||
//PREVIEWED DEVICE ?
|
||||
//Listen to the customizer previewed device
|
||||
var _setPreviewedDevice = function() {
|
||||
wp.customize.preview.bind( 'previewed-device', function( device ) {
|
||||
nb_.previewedDevice = device;// desktop, tablet, mobile
|
||||
});
|
||||
};
|
||||
if ( wp.customize.preview ) {
|
||||
_setPreviewedDevice();
|
||||
} else {
|
||||
wp.customize.bind( 'preview-ready', function() {
|
||||
_setPreviewedDevice();
|
||||
});
|
||||
}
|
||||
});// onJQueryReady
|
||||
}(window, document));
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,497 @@
|
||||
/*!
|
||||
* imagesLoaded PACKAGED v4.1.4
|
||||
* JavaScript is all like "You images are done yet or what?"
|
||||
* MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* EvEmitter v1.1.0
|
||||
* Lil' event emitter
|
||||
* MIT License
|
||||
*/
|
||||
|
||||
/* jshint unused: true, undef: true, strict: true */
|
||||
|
||||
( function( global, factory ) {
|
||||
// universal module definition
|
||||
/* jshint strict: false */ /* globals define, module, window */
|
||||
if ( typeof define == 'function' && define.amd ) {
|
||||
// AMD - RequireJS
|
||||
define( 'ev-emitter/ev-emitter',factory );
|
||||
} else if ( typeof module == 'object' && module.exports ) {
|
||||
// CommonJS - Browserify, Webpack
|
||||
module.exports = factory();
|
||||
} else {
|
||||
// Browser globals
|
||||
global.EvEmitter = factory();
|
||||
}
|
||||
|
||||
}( typeof window != 'undefined' ? window : this, function() {
|
||||
|
||||
|
||||
|
||||
function EvEmitter() {}
|
||||
|
||||
var proto = EvEmitter.prototype;
|
||||
|
||||
proto.on = function( eventName, listener ) {
|
||||
if ( !eventName || !listener ) {
|
||||
return;
|
||||
}
|
||||
// set events hash
|
||||
var events = this._events = this._events || {};
|
||||
// set listeners array
|
||||
var listeners = events[ eventName ] = events[ eventName ] || [];
|
||||
// only add once
|
||||
if ( listeners.indexOf( listener ) == -1 ) {
|
||||
listeners.push( listener );
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
proto.once = function( eventName, listener ) {
|
||||
if ( !eventName || !listener ) {
|
||||
return;
|
||||
}
|
||||
// add event
|
||||
this.on( eventName, listener );
|
||||
// set once flag
|
||||
// set onceEvents hash
|
||||
var onceEvents = this._onceEvents = this._onceEvents || {};
|
||||
// set onceListeners object
|
||||
var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
|
||||
// set flag
|
||||
onceListeners[ listener ] = true;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
proto.off = function( eventName, listener ) {
|
||||
var listeners = this._events && this._events[ eventName ];
|
||||
if ( !listeners || !listeners.length ) {
|
||||
return;
|
||||
}
|
||||
var index = listeners.indexOf( listener );
|
||||
if ( index != -1 ) {
|
||||
listeners.splice( index, 1 );
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
proto.emitEvent = function( eventName, args ) {
|
||||
var listeners = this._events && this._events[ eventName ];
|
||||
if ( !listeners || !listeners.length ) {
|
||||
return;
|
||||
}
|
||||
// copy over to avoid interference if .off() in listener
|
||||
listeners = listeners.slice(0);
|
||||
args = args || [];
|
||||
// once stuff
|
||||
var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
|
||||
|
||||
for ( var i=0; i < listeners.length; i++ ) {
|
||||
var listener = listeners[i]
|
||||
var isOnce = onceListeners && onceListeners[ listener ];
|
||||
if ( isOnce ) {
|
||||
// remove listener
|
||||
// remove before trigger to prevent recursion
|
||||
this.off( eventName, listener );
|
||||
// unset once flag
|
||||
delete onceListeners[ listener ];
|
||||
}
|
||||
// trigger listener
|
||||
listener.apply( this, args );
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
proto.allOff = function() {
|
||||
delete this._events;
|
||||
delete this._onceEvents;
|
||||
};
|
||||
|
||||
return EvEmitter;
|
||||
|
||||
}));
|
||||
|
||||
/*!
|
||||
* imagesLoaded v4.1.4
|
||||
* JavaScript is all like "You images are done yet or what?"
|
||||
* MIT License
|
||||
*/
|
||||
|
||||
( function( window, factory ) { 'use strict';
|
||||
// universal module definition
|
||||
|
||||
/*global define: false, module: false, require: false */
|
||||
|
||||
if ( typeof define == 'function' && define.amd ) {
|
||||
// AMD
|
||||
define( [
|
||||
'ev-emitter/ev-emitter'
|
||||
], function( EvEmitter ) {
|
||||
return factory( window, EvEmitter );
|
||||
});
|
||||
} else if ( typeof module == 'object' && module.exports ) {
|
||||
// CommonJS
|
||||
module.exports = factory(
|
||||
window,
|
||||
require('ev-emitter')
|
||||
);
|
||||
} else {
|
||||
// browser global
|
||||
window.nimbleImagesLoaded = factory(
|
||||
window,
|
||||
window.EvEmitter
|
||||
);
|
||||
}
|
||||
|
||||
})( typeof window !== 'undefined' ? window : this,
|
||||
|
||||
// -------------------------- factory -------------------------- //
|
||||
|
||||
function factory( window, EvEmitter ) {
|
||||
|
||||
|
||||
|
||||
var $ = window.jQuery;
|
||||
var console = window.console;
|
||||
|
||||
// -------------------------- helpers -------------------------- //
|
||||
|
||||
// extend objects
|
||||
function extend( a, b ) {
|
||||
for ( var prop in b ) {
|
||||
a[ prop ] = b[ prop ];
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
var arraySlice = Array.prototype.slice;
|
||||
|
||||
// turn element or nodeList into an array
|
||||
function makeArray( obj ) {
|
||||
if ( Array.isArray( obj ) ) {
|
||||
// use object if already an array
|
||||
return obj;
|
||||
}
|
||||
|
||||
var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
|
||||
if ( isArrayLike ) {
|
||||
// convert nodeList to array
|
||||
return arraySlice.call( obj );
|
||||
}
|
||||
|
||||
// array of single index
|
||||
return [ obj ];
|
||||
}
|
||||
|
||||
// -------------------------- imagesLoaded -------------------------- //
|
||||
|
||||
/**
|
||||
* @param {Array, Element, NodeList, String} elem
|
||||
* @param {Object or Function} options - if function, use as callback
|
||||
* @param {Function} onAlways - callback function
|
||||
*/
|
||||
function ImagesLoaded( elem, options, onAlways ) {
|
||||
// coerce ImagesLoaded() without new, to be new ImagesLoaded()
|
||||
if ( !( this instanceof ImagesLoaded ) ) {
|
||||
return new ImagesLoaded( elem, options, onAlways );
|
||||
}
|
||||
// use elem as selector string
|
||||
var queryElem = elem;
|
||||
if ( typeof elem == 'string' ) {
|
||||
queryElem = document.querySelectorAll( elem );
|
||||
}
|
||||
// bail if bad element
|
||||
if ( !queryElem ) {
|
||||
console.error( 'Bad element for imagesLoaded ' + ( queryElem || elem ) );
|
||||
return;
|
||||
}
|
||||
|
||||
this.elements = makeArray( queryElem );
|
||||
this.options = extend( {}, this.options );
|
||||
// shift arguments if no options set
|
||||
if ( typeof options == 'function' ) {
|
||||
onAlways = options;
|
||||
} else {
|
||||
extend( this.options, options );
|
||||
}
|
||||
|
||||
if ( onAlways ) {
|
||||
this.on( 'always', onAlways );
|
||||
}
|
||||
|
||||
this.getImages();
|
||||
|
||||
if ( $ ) {
|
||||
// add jQuery Deferred object
|
||||
this.jqDeferred = new $.Deferred();
|
||||
}
|
||||
|
||||
// HACK check async to allow time to bind listeners
|
||||
setTimeout( this.check.bind( this ) );
|
||||
}
|
||||
|
||||
ImagesLoaded.prototype = Object.create( EvEmitter.prototype );
|
||||
|
||||
ImagesLoaded.prototype.options = {};
|
||||
|
||||
ImagesLoaded.prototype.getImages = function() {
|
||||
this.images = [];
|
||||
|
||||
// filter & find items if we have an item selector
|
||||
this.elements.forEach( this.addElementImages, this );
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Node} element
|
||||
*/
|
||||
ImagesLoaded.prototype.addElementImages = function( elem ) {
|
||||
// filter siblings
|
||||
if ( elem.nodeName == 'IMG' ) {
|
||||
this.addImage( elem );
|
||||
}
|
||||
// get background image on element
|
||||
if ( this.options.background === true ) {
|
||||
this.addElementBackgroundImages( elem );
|
||||
}
|
||||
|
||||
// find children
|
||||
// no non-element nodes, #143
|
||||
var nodeType = elem.nodeType;
|
||||
if ( !nodeType || !elementNodeTypes[ nodeType ] ) {
|
||||
return;
|
||||
}
|
||||
var childImgs = elem.querySelectorAll('img');
|
||||
// concat childElems to filterFound array
|
||||
for ( var i=0; i < childImgs.length; i++ ) {
|
||||
var img = childImgs[i];
|
||||
this.addImage( img );
|
||||
}
|
||||
|
||||
// get child background images
|
||||
if ( typeof this.options.background == 'string' ) {
|
||||
var children = elem.querySelectorAll( this.options.background );
|
||||
for ( i=0; i < children.length; i++ ) {
|
||||
var child = children[i];
|
||||
this.addElementBackgroundImages( child );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var elementNodeTypes = {
|
||||
1: true,
|
||||
9: true,
|
||||
11: true
|
||||
};
|
||||
|
||||
ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {
|
||||
var style = getComputedStyle( elem );
|
||||
if ( !style ) {
|
||||
// Firefox returns null if in a hidden iframe https://bugzil.la/548397
|
||||
return;
|
||||
}
|
||||
// get url inside url("...")
|
||||
var reURL = /url\((['"])?(.*?)\1\)/gi;
|
||||
var matches = reURL.exec( style.backgroundImage );
|
||||
while ( matches !== null ) {
|
||||
var url = matches && matches[2];
|
||||
if ( url ) {
|
||||
this.addBackground( url, elem );
|
||||
}
|
||||
matches = reURL.exec( style.backgroundImage );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Image} img
|
||||
*/
|
||||
ImagesLoaded.prototype.addImage = function( img ) {
|
||||
var loadingImage = new LoadingImage( img );
|
||||
this.images.push( loadingImage );
|
||||
};
|
||||
|
||||
ImagesLoaded.prototype.addBackground = function( url, elem ) {
|
||||
var background = new Background( url, elem );
|
||||
this.images.push( background );
|
||||
};
|
||||
|
||||
ImagesLoaded.prototype.check = function() {
|
||||
var _this = this;
|
||||
this.progressedCount = 0;
|
||||
this.hasAnyBroken = false;
|
||||
// complete if no images
|
||||
if ( !this.images.length ) {
|
||||
this.complete();
|
||||
return;
|
||||
}
|
||||
|
||||
function onProgress( image, elem, message ) {
|
||||
// HACK - Chrome triggers event before object properties have changed. #83
|
||||
setTimeout( function() {
|
||||
_this.progress( image, elem, message );
|
||||
});
|
||||
}
|
||||
|
||||
this.images.forEach( function( loadingImage ) {
|
||||
loadingImage.once( 'progress', onProgress );
|
||||
loadingImage.check();
|
||||
});
|
||||
};
|
||||
|
||||
ImagesLoaded.prototype.progress = function( image, elem, message ) {
|
||||
this.progressedCount++;
|
||||
this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
|
||||
// progress event
|
||||
this.emitEvent( 'progress', [ this, image, elem ] );
|
||||
if ( this.jqDeferred && this.jqDeferred.notify ) {
|
||||
this.jqDeferred.notify( this, image );
|
||||
}
|
||||
// check if completed
|
||||
if ( this.progressedCount == this.images.length ) {
|
||||
this.complete();
|
||||
}
|
||||
|
||||
if ( this.options.debug && console ) {
|
||||
console.log( 'progress: ' + message, image, elem );
|
||||
}
|
||||
};
|
||||
|
||||
ImagesLoaded.prototype.complete = function() {
|
||||
var eventName = this.hasAnyBroken ? 'fail' : 'done';
|
||||
this.isComplete = true;
|
||||
this.emitEvent( eventName, [ this ] );
|
||||
this.emitEvent( 'always', [ this ] );
|
||||
if ( this.jqDeferred ) {
|
||||
var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve';
|
||||
this.jqDeferred[ jqMethod ]( this );
|
||||
}
|
||||
};
|
||||
|
||||
// -------------------------- -------------------------- //
|
||||
|
||||
function LoadingImage( img ) {
|
||||
this.img = img;
|
||||
}
|
||||
|
||||
LoadingImage.prototype = Object.create( EvEmitter.prototype );
|
||||
|
||||
LoadingImage.prototype.check = function() {
|
||||
// If complete is true and browser supports natural sizes,
|
||||
// try to check for image status manually.
|
||||
var isComplete = this.getIsImageComplete();
|
||||
if ( isComplete ) {
|
||||
// report based on naturalWidth
|
||||
this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
|
||||
return;
|
||||
}
|
||||
|
||||
// If none of the checks above matched, simulate loading on detached element.
|
||||
this.proxyImage = new Image();
|
||||
this.proxyImage.addEventListener( 'load', this );
|
||||
this.proxyImage.addEventListener( 'error', this );
|
||||
// bind to image as well for Firefox. #191
|
||||
this.img.addEventListener( 'load', this );
|
||||
this.img.addEventListener( 'error', this );
|
||||
this.proxyImage.src = this.img.src;
|
||||
};
|
||||
|
||||
LoadingImage.prototype.getIsImageComplete = function() {
|
||||
// check for non-zero, non-undefined naturalWidth
|
||||
// fixes Safari+InfiniteScroll+Masonry bug infinite-scroll#671
|
||||
return this.img.complete && this.img.naturalWidth;
|
||||
};
|
||||
|
||||
LoadingImage.prototype.confirm = function( isLoaded, message ) {
|
||||
this.isLoaded = isLoaded;
|
||||
this.emitEvent( 'progress', [ this, this.img, message ] );
|
||||
};
|
||||
|
||||
// ----- events ----- //
|
||||
|
||||
// trigger specified handler for event type
|
||||
LoadingImage.prototype.handleEvent = function( event ) {
|
||||
var method = 'on' + event.type;
|
||||
if ( this[ method ] ) {
|
||||
this[ method ]( event );
|
||||
}
|
||||
};
|
||||
|
||||
LoadingImage.prototype.onload = function() {
|
||||
this.confirm( true, 'onload' );
|
||||
this.unbindEvents();
|
||||
};
|
||||
|
||||
LoadingImage.prototype.onerror = function() {
|
||||
this.confirm( false, 'onerror' );
|
||||
this.unbindEvents();
|
||||
};
|
||||
|
||||
LoadingImage.prototype.unbindEvents = function() {
|
||||
this.proxyImage.removeEventListener( 'load', this );
|
||||
this.proxyImage.removeEventListener( 'error', this );
|
||||
this.img.removeEventListener( 'load', this );
|
||||
this.img.removeEventListener( 'error', this );
|
||||
};
|
||||
|
||||
// -------------------------- Background -------------------------- //
|
||||
|
||||
function Background( url, element ) {
|
||||
this.url = url;
|
||||
this.element = element;
|
||||
this.img = new Image();
|
||||
}
|
||||
|
||||
// inherit LoadingImage prototype
|
||||
Background.prototype = Object.create( LoadingImage.prototype );
|
||||
|
||||
Background.prototype.check = function() {
|
||||
this.img.addEventListener( 'load', this );
|
||||
this.img.addEventListener( 'error', this );
|
||||
this.img.src = this.url;
|
||||
// check if image is already complete
|
||||
var isComplete = this.getIsImageComplete();
|
||||
if ( isComplete ) {
|
||||
this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
|
||||
this.unbindEvents();
|
||||
}
|
||||
};
|
||||
|
||||
Background.prototype.unbindEvents = function() {
|
||||
this.img.removeEventListener( 'load', this );
|
||||
this.img.removeEventListener( 'error', this );
|
||||
};
|
||||
|
||||
Background.prototype.confirm = function( isLoaded, message ) {
|
||||
this.isLoaded = isLoaded;
|
||||
this.emitEvent( 'progress', [ this, this.element, message ] );
|
||||
};
|
||||
|
||||
// -------------------------- jQuery -------------------------- //
|
||||
|
||||
ImagesLoaded.makeJQueryPlugin = function( jQuery ) {
|
||||
jQuery = jQuery || window.jQuery;
|
||||
if ( !jQuery ) {
|
||||
return;
|
||||
}
|
||||
// set local variable
|
||||
$ = jQuery;
|
||||
// $().imagesLoaded()
|
||||
$.fn.nimbleImagesLoaded = function( options, callback ) {
|
||||
var instance = new ImagesLoaded( this, options, callback );
|
||||
return instance.jqDeferred.promise( $(this) );
|
||||
};
|
||||
};
|
||||
// try making plugin
|
||||
ImagesLoaded.makeJQueryPlugin();
|
||||
|
||||
// -------------------------- -------------------------- //
|
||||
|
||||
return ImagesLoaded;
|
||||
|
||||
});
|
||||
nb_.emit('nb-image-loaded-lib-parsed');
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,965 @@
|
||||
/*! Swipebox v1.5.2 | Constantin Saguin csag.co | MIT License | github.com/brutaldesign/swipebox */
|
||||
|
||||
;( function ( window, document, $, undefined ) {
|
||||
|
||||
$.swipebox = function( elem, options ) {
|
||||
|
||||
$( elem ).addClass( 'swipebox' ); // fugly but yea, swipebox class all the things
|
||||
|
||||
// Default options
|
||||
var ui,
|
||||
defaults = {
|
||||
useCSS : true,
|
||||
useSVG : true,
|
||||
initialIndexOnArray : 0,
|
||||
removeBarsOnMobile : true,
|
||||
hideCloseButtonOnMobile : false,
|
||||
hideBarsDelay : 3000,
|
||||
videoMaxWidth : 1140,
|
||||
vimeoColor : 'cccccc',
|
||||
beforeOpen: null,
|
||||
afterOpen: null,
|
||||
afterClose: null,
|
||||
afterMedia: null,
|
||||
nextSlide: null,
|
||||
prevSlide: null,
|
||||
loopAtEnd: false,
|
||||
autoplayVideos: false,
|
||||
queryStringData: {},
|
||||
toggleClassOnLoad: ''
|
||||
},
|
||||
|
||||
plugin = this,
|
||||
elements = [], // slides array [ { href:'...', title:'...' }, ...],
|
||||
$elem,
|
||||
selector = '.swipebox',
|
||||
isMobile = navigator.userAgent.match( /(iPad)|(iPhone)|(iPod)|(Android)|(PlayBook)|(BB10)|(BlackBerry)|(Opera Mini)|(IEMobile)|(webOS)|(MeeGo)/i ),
|
||||
isTouch = isMobile !== null || document.createTouch !== undefined || ( 'ontouchstart' in window ) || ( 'onmsgesturechange' in window ) || navigator.msMaxTouchPoints,
|
||||
supportSVG = !! document.createElementNS && !! document.createElementNS( 'http://www.w3.org/2000/svg', 'svg').createSVGRect,
|
||||
winWidth = window.innerWidth ? window.innerWidth : $( window ).width(),
|
||||
winHeight = window.innerHeight ? window.innerHeight : $( window ).height(),
|
||||
currentX = 0,
|
||||
/* jshint multistr: true */
|
||||
html = '<div id="swipebox-overlay">\
|
||||
<div id="swipebox-container">\
|
||||
<div id="swipebox-slider"></div>\
|
||||
<div id="swipebox-top-bar">\
|
||||
<div id="swipebox-title"></div>\
|
||||
</div>\
|
||||
<div id="swipebox-bottom-bar">\
|
||||
<div id="swipebox-arrows">\
|
||||
<a id="swipebox-prev"></a>\
|
||||
<a id="swipebox-next"></a>\
|
||||
</div>\
|
||||
</div>\
|
||||
<a id="swipebox-close"></a>\
|
||||
</div>\
|
||||
</div>';
|
||||
|
||||
plugin.settings = {};
|
||||
|
||||
$.swipebox.close = function () {
|
||||
ui.closeSlide();
|
||||
};
|
||||
|
||||
$.swipebox.extend = function () {
|
||||
return ui;
|
||||
};
|
||||
|
||||
plugin.init = function() {
|
||||
|
||||
plugin.settings = $.extend( {}, defaults, options );
|
||||
|
||||
if ( Array.isArray( elem ) ) {
|
||||
|
||||
elements = elem;
|
||||
ui.target = $( window );
|
||||
ui.init( plugin.settings.initialIndexOnArray );
|
||||
|
||||
} else {
|
||||
|
||||
$( document ).on( 'click', selector, function( event ) {
|
||||
|
||||
// console.log( isTouch );
|
||||
|
||||
if ( event.target.parentNode.className === 'slide current' ) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! Array.isArray( elem ) ) {
|
||||
ui.destroy();
|
||||
$elem = $( selector );
|
||||
ui.actions();
|
||||
}
|
||||
|
||||
elements = [];
|
||||
var index, relType, relVal;
|
||||
|
||||
// Allow for HTML5 compliant attribute before legacy use of rel
|
||||
if ( ! relVal ) {
|
||||
relType = 'data-rel';
|
||||
relVal = $( this ).attr( relType );
|
||||
}
|
||||
|
||||
if ( ! relVal ) {
|
||||
relType = 'rel';
|
||||
relVal = $( this ).attr( relType );
|
||||
}
|
||||
|
||||
if ( relVal && relVal !== '' && relVal !== 'nofollow' ) {
|
||||
$elem = $( selector ).filter( '[' + relType + '="' + relVal + '"]' );
|
||||
} else {
|
||||
$elem = $( selector );
|
||||
}
|
||||
|
||||
$elem.each( function() {
|
||||
|
||||
var title = null,
|
||||
href = null;
|
||||
|
||||
if ( $( this ).attr( 'title' ) ) {
|
||||
title = $( this ).attr( 'title' );
|
||||
}
|
||||
|
||||
if ( $( this ).attr( 'href' ) ) {
|
||||
href = $( this ).attr( 'href' );
|
||||
}
|
||||
|
||||
elements.push( {
|
||||
href: href,
|
||||
title: title
|
||||
} );
|
||||
} );
|
||||
|
||||
index = $elem.index( $( this ) );
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
ui.target = $( event.target );
|
||||
ui.init( index );
|
||||
} );
|
||||
}
|
||||
};
|
||||
|
||||
ui = {
|
||||
|
||||
/**
|
||||
* Initiate Swipebox
|
||||
*/
|
||||
init : function( index ) {
|
||||
if ( plugin.settings.beforeOpen ) {
|
||||
plugin.settings.beforeOpen();
|
||||
}
|
||||
this.target.trigger( 'swipebox-start' );
|
||||
$.swipebox.isOpen = true;
|
||||
this.build();
|
||||
this.openSlide( index );
|
||||
this.openMedia( index );
|
||||
this.preloadMedia( index+1 );
|
||||
this.preloadMedia( index-1 );
|
||||
if ( plugin.settings.afterOpen ) {
|
||||
plugin.settings.afterOpen(index);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Built HTML containers and fire main functions
|
||||
*/
|
||||
build : function () {
|
||||
var $this = this, bg;
|
||||
|
||||
$( 'body' ).append( html );
|
||||
|
||||
if ( supportSVG && plugin.settings.useSVG === true ) {
|
||||
bg = $( '#swipebox-close' ).css( 'background-image' );
|
||||
bg = bg.replace( 'png', 'svg' );
|
||||
$( '#swipebox-prev, #swipebox-next, #swipebox-close' ).css( {
|
||||
'background-image' : bg
|
||||
} );
|
||||
}
|
||||
|
||||
if ( isMobile && plugin.settings.removeBarsOnMobile ) {
|
||||
$( '#swipebox-bottom-bar, #swipebox-top-bar' ).remove();
|
||||
}
|
||||
|
||||
$.each( elements, function() {
|
||||
$( '#swipebox-slider' ).append( '<div class="slide"></div>' );
|
||||
} );
|
||||
|
||||
$this.setDim();
|
||||
$this.actions();
|
||||
|
||||
if ( isTouch ) {
|
||||
$this.gesture();
|
||||
}
|
||||
|
||||
// Devices can have both touch and keyboard input so always allow key events
|
||||
$this.keyboard();
|
||||
|
||||
$this.animBars();
|
||||
$this.resize();
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Set dimensions depending on windows width and height
|
||||
*/
|
||||
setDim : function () {
|
||||
|
||||
var width, height, sliderCss = {};
|
||||
|
||||
// Reset dimensions on mobile orientation change
|
||||
if ( 'onorientationchange' in window ) {
|
||||
|
||||
window.addEventListener( 'orientationchange', function() {
|
||||
if ( window.orientation === 0 ) {
|
||||
width = winWidth;
|
||||
height = winHeight;
|
||||
} else if ( window.orientation === 90 || window.orientation === -90 ) {
|
||||
width = winHeight;
|
||||
height = winWidth;
|
||||
}
|
||||
}, false );
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
width = window.innerWidth ? window.innerWidth : $( window ).width();
|
||||
height = window.innerHeight ? window.innerHeight : $( window ).height();
|
||||
}
|
||||
|
||||
sliderCss = {
|
||||
width : width,
|
||||
height : height
|
||||
};
|
||||
|
||||
$( '#swipebox-overlay' ).css( sliderCss );
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Reset dimensions on window resize envent
|
||||
*/
|
||||
resize : function () {
|
||||
var $this = this;
|
||||
|
||||
$( window ).resize( function() {
|
||||
$this.setDim();
|
||||
} ).resize();
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if device supports CSS transitions
|
||||
*/
|
||||
supportTransition : function () {
|
||||
|
||||
var prefixes = 'transition WebkitTransition MozTransition OTransition msTransition KhtmlTransition'.split( ' ' ),
|
||||
i;
|
||||
|
||||
for ( i = 0; i < prefixes.length; i++ ) {
|
||||
if ( document.createElement( 'div' ).style[ prefixes[i] ] !== undefined ) {
|
||||
return prefixes[i];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if CSS transitions are allowed (options + devicesupport)
|
||||
*/
|
||||
doCssTrans : function () {
|
||||
if ( plugin.settings.useCSS && this.supportTransition() ) {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Touch navigation
|
||||
*/
|
||||
gesture : function () {
|
||||
|
||||
var $this = this,
|
||||
index,
|
||||
hDistance,
|
||||
vDistance,
|
||||
hDistanceLast,
|
||||
vDistanceLast,
|
||||
hDistancePercent,
|
||||
vSwipe = false,
|
||||
hSwipe = false,
|
||||
hSwipMinDistance = 10,
|
||||
vSwipMinDistance = 50,
|
||||
startCoords = {},
|
||||
endCoords = {},
|
||||
bars = $( '#swipebox-top-bar, #swipebox-bottom-bar' ),
|
||||
slider = $( '#swipebox-slider' );
|
||||
|
||||
bars.addClass( 'visible-bars' );
|
||||
$this.setTimeout();
|
||||
|
||||
$( 'body' ).bind( 'touchstart', function( event ) {
|
||||
|
||||
$( this ).addClass( 'touching' );
|
||||
index = $( '#swipebox-slider .slide' ).index( $( '#swipebox-slider .slide.current' ) );
|
||||
endCoords = event.originalEvent.targetTouches[0];
|
||||
startCoords.pageX = event.originalEvent.targetTouches[0].pageX;
|
||||
startCoords.pageY = event.originalEvent.targetTouches[0].pageY;
|
||||
|
||||
$( '#swipebox-slider' ).css( {
|
||||
'-webkit-transform' : 'translate3d(' + currentX +'%, 0, 0)',
|
||||
'transform' : 'translate3d(' + currentX + '%, 0, 0)'
|
||||
} );
|
||||
|
||||
$( '.touching' ).bind( 'touchmove',function( event ) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
endCoords = event.originalEvent.targetTouches[0];
|
||||
|
||||
if ( ! hSwipe ) {
|
||||
vDistanceLast = vDistance;
|
||||
vDistance = endCoords.pageY - startCoords.pageY;
|
||||
if ( Math.abs( vDistance ) >= vSwipMinDistance || vSwipe ) {
|
||||
var opacity = 0.75 - Math.abs(vDistance) / slider.height();
|
||||
|
||||
slider.css( { 'top': vDistance + 'px' } );
|
||||
slider.css( { 'opacity': opacity } );
|
||||
|
||||
vSwipe = true;
|
||||
}
|
||||
}
|
||||
|
||||
hDistanceLast = hDistance;
|
||||
hDistance = endCoords.pageX - startCoords.pageX;
|
||||
hDistancePercent = hDistance * 100 / winWidth;
|
||||
|
||||
if ( ! hSwipe && ! vSwipe && Math.abs( hDistance ) >= hSwipMinDistance ) {
|
||||
$( '#swipebox-slider' ).css( {
|
||||
'-webkit-transition' : '',
|
||||
'transition' : ''
|
||||
} );
|
||||
hSwipe = true;
|
||||
}
|
||||
|
||||
if ( hSwipe ) {
|
||||
|
||||
// swipe left
|
||||
if ( 0 < hDistance ) {
|
||||
|
||||
// first slide
|
||||
if ( 0 === index ) {
|
||||
// console.log( 'first' );
|
||||
$( '#swipebox-overlay' ).addClass( 'leftSpringTouch' );
|
||||
} else {
|
||||
// Follow gesture
|
||||
$( '#swipebox-overlay' ).removeClass( 'leftSpringTouch' ).removeClass( 'rightSpringTouch' );
|
||||
$( '#swipebox-slider' ).css( {
|
||||
'-webkit-transform' : 'translate3d(' + ( currentX + hDistancePercent ) +'%, 0, 0)',
|
||||
'transform' : 'translate3d(' + ( currentX + hDistancePercent ) + '%, 0, 0)'
|
||||
} );
|
||||
}
|
||||
|
||||
// swipe right
|
||||
} else if ( 0 > hDistance ) {
|
||||
|
||||
// last Slide
|
||||
if ( elements.length === index +1 ) {
|
||||
// console.log( 'last' );
|
||||
$( '#swipebox-overlay' ).addClass( 'rightSpringTouch' );
|
||||
} else {
|
||||
$( '#swipebox-overlay' ).removeClass( 'leftSpringTouch' ).removeClass( 'rightSpringTouch' );
|
||||
$( '#swipebox-slider' ).css( {
|
||||
'-webkit-transform' : 'translate3d(' + ( currentX + hDistancePercent ) +'%, 0, 0)',
|
||||
'transform' : 'translate3d(' + ( currentX + hDistancePercent ) + '%, 0, 0)'
|
||||
} );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
return false;
|
||||
|
||||
} ).bind( 'touchend',function( event ) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
$( '#swipebox-slider' ).css( {
|
||||
'-webkit-transition' : '-webkit-transform 0.4s ease',
|
||||
'transition' : 'transform 0.4s ease'
|
||||
} );
|
||||
|
||||
vDistance = endCoords.pageY - startCoords.pageY;
|
||||
hDistance = endCoords.pageX - startCoords.pageX;
|
||||
hDistancePercent = hDistance*100/winWidth;
|
||||
|
||||
// Swipe to bottom to close
|
||||
if ( vSwipe ) {
|
||||
vSwipe = false;
|
||||
if ( Math.abs( vDistance ) >= 2 * vSwipMinDistance && Math.abs( vDistance ) > Math.abs( vDistanceLast ) ) {
|
||||
var vOffset = vDistance > 0 ? slider.height() : - slider.height();
|
||||
slider.animate( { top: vOffset + 'px', 'opacity': 0 },
|
||||
300,
|
||||
function () {
|
||||
$this.closeSlide();
|
||||
} );
|
||||
} else {
|
||||
slider.animate( { top: 0, 'opacity': 1 }, 300 );
|
||||
}
|
||||
|
||||
} else if ( hSwipe ) {
|
||||
|
||||
hSwipe = false;
|
||||
|
||||
// swipeLeft
|
||||
if( hDistance >= hSwipMinDistance && hDistance >= hDistanceLast) {
|
||||
|
||||
$this.getPrev();
|
||||
|
||||
// swipeRight
|
||||
} else if ( hDistance <= -hSwipMinDistance && hDistance <= hDistanceLast) {
|
||||
|
||||
$this.getNext();
|
||||
}
|
||||
|
||||
} else { // Top and bottom bars have been removed on touchable devices
|
||||
// tap
|
||||
if ( ! bars.hasClass( 'visible-bars' ) ) {
|
||||
$this.showBars();
|
||||
$this.setTimeout();
|
||||
} else {
|
||||
$this.clearTimeout();
|
||||
$this.hideBars();
|
||||
}
|
||||
}
|
||||
|
||||
$( '#swipebox-slider' ).css( {
|
||||
'-webkit-transform' : 'translate3d(' + currentX + '%, 0, 0)',
|
||||
'transform' : 'translate3d(' + currentX + '%, 0, 0)'
|
||||
} );
|
||||
|
||||
$( '#swipebox-overlay' ).removeClass( 'leftSpringTouch' ).removeClass( 'rightSpringTouch' );
|
||||
$( '.touching' ).off( 'touchmove' ).removeClass( 'touching' );
|
||||
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* Set timer to hide the action bars
|
||||
*/
|
||||
setTimeout: function () {
|
||||
if ( plugin.settings.hideBarsDelay > 0 ) {
|
||||
var $this = this;
|
||||
$this.clearTimeout();
|
||||
$this.timeout = window.setTimeout( function() {
|
||||
$this.hideBars();
|
||||
},
|
||||
|
||||
plugin.settings.hideBarsDelay
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear timer
|
||||
*/
|
||||
clearTimeout: function () {
|
||||
window.clearTimeout( this.timeout );
|
||||
this.timeout = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Show navigation and title bars
|
||||
*/
|
||||
showBars : function () {
|
||||
var bars = $( '#swipebox-top-bar, #swipebox-bottom-bar' );
|
||||
if ( this.doCssTrans() ) {
|
||||
bars.addClass( 'visible-bars' );
|
||||
} else {
|
||||
$( '#swipebox-top-bar' ).animate( { top : 0 }, 500 );
|
||||
$( '#swipebox-bottom-bar' ).animate( { bottom : 0 }, 500 );
|
||||
setTimeout( function() {
|
||||
bars.addClass( 'visible-bars' );
|
||||
}, 1000 );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Hide navigation and title bars
|
||||
*/
|
||||
hideBars : function () {
|
||||
var bars = $( '#swipebox-top-bar, #swipebox-bottom-bar' );
|
||||
if ( this.doCssTrans() ) {
|
||||
bars.removeClass( 'visible-bars' );
|
||||
} else {
|
||||
$( '#swipebox-top-bar' ).animate( { top : '-50px' }, 500 );
|
||||
$( '#swipebox-bottom-bar' ).animate( { bottom : '-50px' }, 500 );
|
||||
setTimeout( function() {
|
||||
bars.removeClass( 'visible-bars' );
|
||||
}, 1000 );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Animate navigation and top bars
|
||||
*/
|
||||
animBars : function () {
|
||||
var $this = this,
|
||||
bars = $( '#swipebox-top-bar, #swipebox-bottom-bar' );
|
||||
|
||||
bars.addClass( 'visible-bars' );
|
||||
$this.setTimeout();
|
||||
|
||||
$( '#swipebox-slider' ).click( function() {
|
||||
if ( ! bars.hasClass( 'visible-bars' ) ) {
|
||||
$this.showBars();
|
||||
$this.setTimeout();
|
||||
}
|
||||
} );
|
||||
|
||||
$( '#swipebox-bottom-bar' ).hover( function() {
|
||||
$this.showBars();
|
||||
bars.addClass( 'visible-bars' );
|
||||
$this.clearTimeout();
|
||||
|
||||
}, function() {
|
||||
if ( plugin.settings.hideBarsDelay > 0 ) {
|
||||
bars.removeClass( 'visible-bars' );
|
||||
$this.setTimeout();
|
||||
}
|
||||
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* Keyboard navigation
|
||||
*/
|
||||
keyboard : function () {
|
||||
var $this = this;
|
||||
$( window ).bind( 'keyup', function( event ) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
if ( event.keyCode === 37 ) {
|
||||
|
||||
$this.getPrev();
|
||||
|
||||
} else if ( event.keyCode === 39 ) {
|
||||
|
||||
$this.getNext();
|
||||
|
||||
} else if ( event.keyCode === 27 ) {
|
||||
|
||||
$this.closeSlide();
|
||||
}
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* Navigation events : go to next slide, go to prevous slide and close
|
||||
*/
|
||||
actions : function () {
|
||||
var $this = this,
|
||||
action = 'touchend click'; // Just detect for both event types to allow for multi-input
|
||||
|
||||
if ( elements.length < 2 ) {
|
||||
|
||||
$( '#swipebox-bottom-bar' ).hide();
|
||||
|
||||
if ( undefined === elements[ 1 ] ) {
|
||||
$( '#swipebox-top-bar' ).hide();
|
||||
}
|
||||
|
||||
} else {
|
||||
$( '#swipebox-prev' ).bind( action, function( event ) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
$this.getPrev();
|
||||
$this.setTimeout();
|
||||
} );
|
||||
|
||||
$( '#swipebox-next' ).bind( action, function( event ) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
$this.getNext();
|
||||
$this.setTimeout();
|
||||
} );
|
||||
}
|
||||
|
||||
$( '#swipebox-close' ).bind( action, function( event ) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
$this.closeSlide();
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* Set current slide
|
||||
*/
|
||||
setSlide : function ( index, isFirst ) {
|
||||
|
||||
isFirst = isFirst || false;
|
||||
|
||||
var slider = $( '#swipebox-slider' );
|
||||
|
||||
currentX = -index*100;
|
||||
|
||||
if ( this.doCssTrans() ) {
|
||||
slider.css( {
|
||||
'-webkit-transform' : 'translate3d(' + (-index*100)+'%, 0, 0)',
|
||||
'transform' : 'translate3d(' + (-index*100)+'%, 0, 0)'
|
||||
} );
|
||||
} else {
|
||||
slider.animate( { left : ( -index*100 )+'%' } );
|
||||
}
|
||||
|
||||
$( '#swipebox-slider .slide' ).removeClass( 'current' );
|
||||
$( '#swipebox-slider .slide' ).eq( index ).addClass( 'current' );
|
||||
this.setTitle( index );
|
||||
|
||||
if ( isFirst ) {
|
||||
slider.fadeIn();
|
||||
}
|
||||
|
||||
$( '#swipebox-prev, #swipebox-next' ).removeClass( 'disabled' );
|
||||
|
||||
if ( index === 0 ) {
|
||||
$( '#swipebox-prev' ).addClass( 'disabled' );
|
||||
} else if ( index === elements.length - 1 && plugin.settings.loopAtEnd !== true ) {
|
||||
$( '#swipebox-next' ).addClass( 'disabled' );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Open slide
|
||||
*/
|
||||
openSlide : function ( index ) {
|
||||
$( 'html' ).addClass( 'swipebox-html' );
|
||||
if ( isTouch ) {
|
||||
$( 'html' ).addClass( 'swipebox-touch' );
|
||||
|
||||
if ( plugin.settings.hideCloseButtonOnMobile ) {
|
||||
$( 'html' ).addClass( 'swipebox-no-close-button' );
|
||||
}
|
||||
} else {
|
||||
$( 'html' ).addClass( 'swipebox-no-touch' );
|
||||
}
|
||||
$( window ).trigger( 'resize' ); // fix scroll bar visibility on desktop
|
||||
this.setSlide( index, true );
|
||||
},
|
||||
|
||||
/**
|
||||
* Set a time out if the media is a video
|
||||
*/
|
||||
preloadMedia : function ( index ) {
|
||||
var $this = this,
|
||||
src = null;
|
||||
|
||||
if ( elements[ index ] !== undefined ) {
|
||||
src = elements[ index ].href;
|
||||
}
|
||||
|
||||
if ( ! $this.isVideo( src ) ) {
|
||||
setTimeout( function() {
|
||||
$this.openMedia( index );
|
||||
}, 1000);
|
||||
} else {
|
||||
$this.openMedia( index );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Open
|
||||
*/
|
||||
openMedia : function ( index ) {
|
||||
var $this = this,
|
||||
src,
|
||||
slide;
|
||||
|
||||
if ( elements[ index ] !== undefined ) {
|
||||
src = elements[ index ].href;
|
||||
}
|
||||
|
||||
if ( index < 0 || index >= elements.length ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
slide = $( '#swipebox-slider .slide' ).eq( index );
|
||||
|
||||
if ( ! $this.isVideo( src ) ) {
|
||||
slide.addClass( 'slide-loading' );
|
||||
$this.loadMedia( src, function() {
|
||||
slide.removeClass( 'slide-loading' );
|
||||
slide.html( this );
|
||||
|
||||
if ( plugin.settings.afterMedia ) {
|
||||
plugin.settings.afterMedia( index );
|
||||
}
|
||||
} );
|
||||
} else {
|
||||
slide.html( $this.getVideo( src ) );
|
||||
|
||||
if ( plugin.settings.afterMedia ) {
|
||||
plugin.settings.afterMedia( index );
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Set link title attribute as caption
|
||||
*/
|
||||
setTitle : function ( index ) {
|
||||
var title = null;
|
||||
|
||||
$( '#swipebox-title' ).empty();
|
||||
|
||||
if ( elements[ index ] !== undefined ) {
|
||||
title = elements[ index ].title;
|
||||
}
|
||||
|
||||
if ( title ) {
|
||||
$( '#swipebox-top-bar' ).show();
|
||||
$( '#swipebox-title' ).append( title );
|
||||
} else {
|
||||
$( '#swipebox-top-bar' ).hide();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the URL is a video
|
||||
*/
|
||||
isVideo : function ( src ) {
|
||||
|
||||
if ( src ) {
|
||||
if ( src.match( /(youtube\.com|youtube-nocookie\.com)\/watch\?v=([a-zA-Z0-9\-_]+)/) || src.match( /vimeo\.com\/([0-9]*)/ ) || src.match( /youtu\.be\/([a-zA-Z0-9\-_]+)/ ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( src.toLowerCase().indexOf( 'swipeboxvideo=1' ) >= 0 ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Parse URI querystring and:
|
||||
* - overrides value provided via dictionary
|
||||
* - rebuild it again returning a string
|
||||
*/
|
||||
parseUri : function (uri, customData) {
|
||||
var a = document.createElement('a'),
|
||||
qs = {};
|
||||
|
||||
// Decode the URI
|
||||
a.href = decodeURIComponent( uri );
|
||||
|
||||
// QueryString to Object
|
||||
if ( a.search ) {
|
||||
qs = JSON.parse( '{"' + a.search.toLowerCase().replace('?','').replace(/&/g,'","').replace(/=/g,'":"') + '"}' );
|
||||
}
|
||||
|
||||
// Extend with custom data
|
||||
if ( $.isPlainObject( customData ) ) {
|
||||
qs = $.extend( qs, customData, plugin.settings.queryStringData ); // The dev has always the final word
|
||||
}
|
||||
|
||||
// Return querystring as a string
|
||||
return $
|
||||
.map( qs, function (val, key) {
|
||||
if ( val && val > '' ) {
|
||||
return encodeURIComponent( key ) + '=' + encodeURIComponent( val );
|
||||
}
|
||||
})
|
||||
.join('&');
|
||||
},
|
||||
|
||||
/**
|
||||
* Get video iframe code from URL
|
||||
*/
|
||||
getVideo : function( url ) {
|
||||
var iframe = '',
|
||||
youtubeUrl = url.match( /((?:www\.)?youtube\.com|(?:www\.)?youtube-nocookie\.com)\/watch\?v=([a-zA-Z0-9\-_]+)/ ),
|
||||
youtubeShortUrl = url.match(/(?:www\.)?youtu\.be\/([a-zA-Z0-9\-_]+)/),
|
||||
vimeoUrl = url.match( /(?:www\.)?vimeo\.com\/([0-9]*)/ ),
|
||||
qs = '';
|
||||
|
||||
if ( youtubeUrl || youtubeShortUrl) {
|
||||
if ( youtubeShortUrl ) {
|
||||
youtubeUrl = youtubeShortUrl;
|
||||
}
|
||||
|
||||
console.log( youtubeUrl );
|
||||
|
||||
qs = ui.parseUri( url, {
|
||||
'autoplay' : ( plugin.settings.autoplayVideos ? '1' : '0' ),
|
||||
'v' : ''
|
||||
});
|
||||
iframe = '<iframe width="560" height="315" src="https://' + youtubeUrl[1] + '/embed/' + youtubeUrl[2] + '?' + qs + '" frameborder="0" allowfullscreen></iframe>';
|
||||
|
||||
} else if ( vimeoUrl ) {
|
||||
qs = ui.parseUri( url, {
|
||||
'autoplay' : ( plugin.settings.autoplayVideos ? '1' : '0' ),
|
||||
'byline' : '0',
|
||||
'portrait' : '0',
|
||||
'color': plugin.settings.vimeoColor
|
||||
});
|
||||
iframe = '<iframe width="560" height="315" src="//player.vimeo.com/video/' + vimeoUrl[1] + '?' + qs + '" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>';
|
||||
|
||||
} else {
|
||||
iframe = '<iframe width="560" height="315" src="' + url + '" frameborder="0" allowfullscreen></iframe>';
|
||||
}
|
||||
|
||||
return '<div class="swipebox-video-container" style="max-width:' + plugin.settings.videoMaxWidth + 'px"><div class="swipebox-video">' + iframe + '</div></div>';
|
||||
},
|
||||
|
||||
/**
|
||||
* Load image
|
||||
*/
|
||||
loadMedia : function ( src, callback ) {
|
||||
// Inline content
|
||||
if ( src.trim().indexOf('#') === 0 ) {
|
||||
callback.call(
|
||||
$('<div>', {
|
||||
'class' : 'swipebox-inline-container'
|
||||
})
|
||||
.append(
|
||||
$(src)
|
||||
.clone()
|
||||
.toggleClass( plugin.settings.toggleClassOnLoad )
|
||||
)
|
||||
);
|
||||
}
|
||||
// Everything else
|
||||
else {
|
||||
if ( ! this.isVideo( src ) ) {
|
||||
var img = $( '<img>' ).on( 'load', function() {
|
||||
callback.call( img );
|
||||
} );
|
||||
|
||||
img.attr( 'src', src );
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get next slide
|
||||
*/
|
||||
getNext : function () {
|
||||
var $this = this,
|
||||
src,
|
||||
index = $( '#swipebox-slider .slide' ).index( $( '#swipebox-slider .slide.current' ) );
|
||||
if ( index + 1 < elements.length ) {
|
||||
|
||||
src = $( '#swipebox-slider .slide' ).eq( index ).contents().find( 'iframe' ).attr( 'src' );
|
||||
$( '#swipebox-slider .slide' ).eq( index ).contents().find( 'iframe' ).attr( 'src', src );
|
||||
index++;
|
||||
$this.setSlide( index );
|
||||
$this.preloadMedia( index+1 );
|
||||
if ( plugin.settings.nextSlide ) {
|
||||
plugin.settings.nextSlide(index);
|
||||
}
|
||||
} else {
|
||||
|
||||
if ( plugin.settings.loopAtEnd === true ) {
|
||||
src = $( '#swipebox-slider .slide' ).eq( index ).contents().find( 'iframe' ).attr( 'src' );
|
||||
$( '#swipebox-slider .slide' ).eq( index ).contents().find( 'iframe' ).attr( 'src', src );
|
||||
index = 0;
|
||||
$this.preloadMedia( index );
|
||||
$this.setSlide( index );
|
||||
$this.preloadMedia( index + 1 );
|
||||
if ( plugin.settings.nextSlide ) {
|
||||
plugin.settings.nextSlide(index);
|
||||
}
|
||||
} else {
|
||||
$( '#swipebox-overlay' ).addClass( 'rightSpring' );
|
||||
setTimeout( function() {
|
||||
$( '#swipebox-overlay' ).removeClass( 'rightSpring' );
|
||||
}, 500 );
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get previous slide
|
||||
*/
|
||||
getPrev : function () {
|
||||
var index = $( '#swipebox-slider .slide' ).index( $( '#swipebox-slider .slide.current' ) ),
|
||||
src;
|
||||
if ( index > 0 ) {
|
||||
src = $( '#swipebox-slider .slide' ).eq( index ).contents().find( 'iframe').attr( 'src' );
|
||||
$( '#swipebox-slider .slide' ).eq( index ).contents().find( 'iframe' ).attr( 'src', src );
|
||||
index--;
|
||||
this.setSlide( index );
|
||||
this.preloadMedia( index-1 );
|
||||
if ( plugin.settings.prevSlide ) {
|
||||
plugin.settings.prevSlide(index);
|
||||
}
|
||||
} else {
|
||||
$( '#swipebox-overlay' ).addClass( 'leftSpring' );
|
||||
setTimeout( function() {
|
||||
$( '#swipebox-overlay' ).removeClass( 'leftSpring' );
|
||||
}, 500 );
|
||||
}
|
||||
},
|
||||
/* jshint unused:false */
|
||||
nextSlide : function ( index ) {
|
||||
// Callback for next slide
|
||||
},
|
||||
|
||||
prevSlide : function ( index ) {
|
||||
// Callback for prev slide
|
||||
},
|
||||
|
||||
/**
|
||||
* Close
|
||||
*/
|
||||
closeSlide : function () {
|
||||
$( 'html' ).removeClass( 'swipebox-html' );
|
||||
$( 'html' ).removeClass( 'swipebox-touch' );
|
||||
$( window ).trigger( 'resize' );
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroy the whole thing
|
||||
*/
|
||||
destroy : function () {
|
||||
$( window ).unbind( 'keyup' );
|
||||
$( 'body' ).unbind( 'touchstart' );
|
||||
$( 'body' ).unbind( 'touchmove' );
|
||||
$( 'body' ).unbind( 'touchend' );
|
||||
$( '#swipebox-slider' ).unbind();
|
||||
$( '#swipebox-overlay' ).remove();
|
||||
|
||||
if ( ! Array.isArray( elem ) ) {
|
||||
elem.removeData( '_swipebox' );
|
||||
}
|
||||
|
||||
if ( this.target ) {
|
||||
this.target.trigger( 'swipebox-destroy' );
|
||||
}
|
||||
|
||||
$.swipebox.isOpen = false;
|
||||
|
||||
if ( plugin.settings.afterClose ) {
|
||||
plugin.settings.afterClose();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
plugin.init();
|
||||
};
|
||||
|
||||
$.fn.swipebox = function( options ) {
|
||||
|
||||
if ( ! $.data( this, '_swipebox' ) ) {
|
||||
var swipebox = new $.swipebox( this, options );
|
||||
this.data( '_swipebox', swipebox );
|
||||
}
|
||||
return this.data( '_swipebox' );
|
||||
|
||||
};
|
||||
|
||||
}( window, document, jQuery ) );
|
||||
// on 'nb-app-ready', jQuery is loaded
|
||||
nb_.listenTo('nb-app-ready', function(){nb_.emit('nb-swipebox-parsed');});
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,552 @@
|
||||
// global sekFrontLocalized, nimbleListenTo
|
||||
// jQuery plugin
|
||||
// Fired in ...front_fire.js
|
||||
(function(w, d){
|
||||
var callbackFunc = function() {
|
||||
(function ( $, window ) {
|
||||
//defaults
|
||||
var pluginName = 'nimbleLoadVideoBg',
|
||||
defaults = {
|
||||
bgVideoContainerClass: 'sek-bg-video-wrapper',
|
||||
bgYoutubeVideoContainerClass : 'sek-bg-youtube-video-wrapper',
|
||||
bgLocalVideoContainerClass: 'sek-background-video-local',
|
||||
bgLoadingClass: 'sek-bg-loading',
|
||||
loop:true,
|
||||
delayBeforeStart:null,
|
||||
activeOnMobile:false,
|
||||
startAt:null,
|
||||
endAt:null,
|
||||
lazyLoad:false
|
||||
//enableCentering : true,
|
||||
// onresize : true,
|
||||
// onInit : true,//<= shall we smartload on init or wait for a custom event, typically smartload ?
|
||||
// oncustom : [],//list of event here
|
||||
// $containerToListen : null,//<= we might want to listen to custom event trigger to a parent container.Should be a jQuery obj
|
||||
// imgSel : 'img',
|
||||
// defaultCSSVal : { width : 'auto' , height : 'auto' },
|
||||
// leftAdjust : 0,
|
||||
// zeroLeftAdjust : 0,
|
||||
// topAdjust : 0,
|
||||
// zeroTopAdjust : -2,//<= top ajustement for sek-h-centrd
|
||||
// useImgAttr:false,//uses the img height and width attributes if not visible (typically used for the customizr slider hidden images)
|
||||
// setOpacityWhenCentered : false,//this can be used to hide the image during the time it is centered
|
||||
// addCenteredClassWithDelay : 0,//<= a small delay can be required when we rely on the sek-v-centrd or sek-h-centrd css classes to set the opacity for example
|
||||
// opacity : 1
|
||||
};
|
||||
|
||||
function Plugin( element, options ) {
|
||||
var self = this;
|
||||
this.$element = $(element);
|
||||
this.$window = nb_.cachedElements.$window;
|
||||
this._defaults = defaults;
|
||||
this._name = pluginName;
|
||||
this.options = nb_.isObject( options ) ? options : {};
|
||||
|
||||
this.videoPlayer = false;//<= will hold the video player object
|
||||
|
||||
if ( this.options.lazyLoad ) {
|
||||
//the scroll event gets throttled with the requestAnimationFrame
|
||||
nb_.cachedElements.$window.on('scroll', nb_.throttle( function( _evt ) {
|
||||
if ( nb_.elOrFirstVisibleParentIsInWindow( self.$element ) && !self.$element.data('sek-player-instantiated') ) {
|
||||
// Are we already instantiated ?
|
||||
if ( false === self.videoPlayer ) {
|
||||
self.initSetup();
|
||||
}
|
||||
}
|
||||
}, 50 ) );
|
||||
|
||||
//debounced resize event
|
||||
nb_.cachedElements.$window.on('resize', nb_.debounce( function( _evt ) {
|
||||
if ( nb_.elOrFirstVisibleParentIsInWindow( self.$element ) && !self.$element.data('sek-player-instantiated') ) {
|
||||
// Are we already instantiated ?
|
||||
if ( false === self.videoPlayer ) {
|
||||
self.initSetup();
|
||||
}
|
||||
}
|
||||
}, 100 ) );
|
||||
|
||||
if ( nb_.elOrFirstVisibleParentIsInWindow( self.$element ) && !self.$element.data('sek-player-instantiated') ) {
|
||||
// Are we already instantiated ?
|
||||
if ( false === self.videoPlayer ) {
|
||||
self.initSetup();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Are we already instantiated ?
|
||||
if ( false === self.videoPlayer ) {
|
||||
self.initSetup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Plugin.prototype.initSetup = function() {
|
||||
var self = this;
|
||||
|
||||
// set options from data attributes
|
||||
if ( ! nb_.isUndefined( self.$element.data('sek-video-bg-loop') ) ) {
|
||||
this.options.loop = self.$element.data('sek-video-bg-loop');
|
||||
}
|
||||
this.options.delayBeforeStart = self.$element.data('sek-video-delay-before');
|
||||
this.options.delayBeforeStart = Math.abs( self.options.delayBeforeStart ? parseInt( self.options.delayBeforeStart, 10 ) : 0 );
|
||||
|
||||
if ( ! nb_.isUndefined( self.$element.data('sek-video-bg-on-mobile') ) ) {
|
||||
this.options.activeOnMobile = self.$element.data('sek-video-bg-on-mobile');
|
||||
}
|
||||
this.options.startAt = self.$element.data('sek-video-start-at');
|
||||
this.options.startAt = Math.abs( self.options.startAt ? parseInt( self.options.startAt, 10 ) : 0 );
|
||||
|
||||
this.options.endAt = self.$element.data('sek-video-end-at');
|
||||
this.options.endAt = Math.abs( self.options.endAt ? parseInt( self.options.endAt, 10 ) : 0 );
|
||||
|
||||
// make sure the video fragment is consistent
|
||||
// endAt > startAt, ...
|
||||
this.isFragmentedVideo = false;
|
||||
var startAt = this.options.startAt,
|
||||
endAt = this.options.endAt;
|
||||
|
||||
if ( startAt || endAt ) {
|
||||
if ( startAt && endAt < 1 ) {
|
||||
this.isFragmentedVideo = true;
|
||||
} else if ( startAt && endAt && endAt > startAt ) {
|
||||
this.isFragmentedVideo = true;
|
||||
} else if ( startAt < 1 && endAt ) {
|
||||
this.isFragmentedVideo = true;
|
||||
}
|
||||
}
|
||||
|
||||
this.options = $.extend( {}, defaults, this.options );
|
||||
|
||||
var _doInit = function() {
|
||||
// init now
|
||||
self.init();
|
||||
self.$element.on( 'refresh-video-dimensions', nb_.debounce( function() {
|
||||
nb_.delay( function() {
|
||||
self.updatePlayerDimensions();
|
||||
}, 300 );
|
||||
}, 200 ) );
|
||||
|
||||
// Flag
|
||||
self.$element.data('sek-player-instantiated', true );
|
||||
};
|
||||
|
||||
// maybe delay init if set by user
|
||||
nb_.delay( _doInit, self.options.delayBeforeStart * 1000 );
|
||||
};
|
||||
|
||||
/*
|
||||
* @param : array of $img
|
||||
* @param : current event
|
||||
* @return : void
|
||||
* scroll event performance enhancer => avoid browser stack if too much scrolls
|
||||
*/
|
||||
Plugin.prototype._better_scroll_event_handler = function( $_Elements , _evt ) {
|
||||
var self = this;
|
||||
if ( ! this.doingAnimation ) {
|
||||
this.doingAnimation = true;
|
||||
window.requestAnimationFrame(function() {
|
||||
self._maybe_trigger_load( $_Elements , _evt );
|
||||
self.doingAnimation = false;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//can access this.element and this.option
|
||||
//@return void
|
||||
Plugin.prototype.init = function () {
|
||||
var self = this;
|
||||
|
||||
// Always fire when customzing
|
||||
if ( !nb_.isCustomizing() && !this.options.activeOnMobile && nb_.isMobile() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// set video url prop
|
||||
this.videoUrl = self.$element.data('sek-video-bg-src');
|
||||
|
||||
// set videoOrigin
|
||||
if ( -1 !== this.videoUrl.indexOf('vimeo.com') ) {
|
||||
this.videoOrigin = 'vimeo';
|
||||
this.videoApiHelpers = this.getVideoApiHelpers( 'vimeo' );
|
||||
} else if ( this.videoUrl.match(/^(?:https?:\/\/)?(?:www\.)?(?:m\.)?(?:youtu\.be\/|youtube\.com)/ ) ) {
|
||||
this.videoOrigin = 'youtube';
|
||||
this.videoApiHelpers = this.getVideoApiHelpers( 'youtube' );
|
||||
}
|
||||
|
||||
|
||||
// inject video container if not done yet
|
||||
if ( nb_.isUndefined(self.$backgroundVideoContainer) || self.$backgroundVideoContainer.length < 1 ) {
|
||||
self.$element.children().first().before( $('<div>', { class : self.options.bgVideoContainerClass} ) );
|
||||
self.$backgroundVideoContainer = $( '.' + self.options.bgVideoContainerClass, self.$element );
|
||||
}
|
||||
|
||||
if ( this.videoApiHelpers ) {
|
||||
self.$backgroundVideoContainer.append( $('<div>', { class : self.options.bgYoutubeVideoContainerClass } ) );
|
||||
this.videoId = this.videoApiHelpers.getVideoIDFromURL( this.videoUrl );
|
||||
if ( this.videoId ) {
|
||||
this.videoApiHelpers.onApiReady( function ( apiInstance ) {
|
||||
self.apiInstance = apiInstance;
|
||||
if ('youtube' === self.videoOrigin) {
|
||||
self.setupYtubeVideo();
|
||||
}
|
||||
if ('vimeo' === self.videoOrigin) {
|
||||
self.setupVimeoVideo();
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.videoOrigin = 'local';
|
||||
self.setupLocalVideo();
|
||||
}
|
||||
|
||||
// update video dimension for all players on resize
|
||||
this.$window.on( 'resize', nb_.debounce( function() { self.updatePlayerDimensions(); }, 200 ) );
|
||||
};
|
||||
|
||||
|
||||
|
||||
Plugin.prototype.setupLocalVideo = function() {
|
||||
var self = this;
|
||||
var _attributes = ['autoplay', 'muted', 'playsinline'];
|
||||
if ( self.options.loop ) {
|
||||
_attributes.push('loop');
|
||||
}
|
||||
_attributes = _attributes.join(' ');
|
||||
|
||||
if ( self.$backgroundVideoContainer.find('video').length < 1 ) {
|
||||
self.$backgroundVideoContainer.append( '<video ' + _attributes + ' class="' + self.options.bgLocalVideoContainerClass +'"></video>');
|
||||
}
|
||||
self.$backgroundVideoLocal = $( '.' + self.options.bgLocalVideoContainerClass, self.$element );
|
||||
self.videoPlayer = self.$backgroundVideoLocal;
|
||||
|
||||
var startAt = self.options.startAt,
|
||||
endAt = self.options.endAt;
|
||||
|
||||
// Fragment video if conditions are met
|
||||
if ( this.isFragmentedVideo ) {
|
||||
if ( startAt && endAt < 1 ) {
|
||||
this.videoUrl += '#t=' + startAt;
|
||||
} else if ( startAt && endAt && endAt > startAt ) {
|
||||
this.videoUrl += '#t=' + startAt + ',' + endAt;
|
||||
} else if ( startAt < 1 && endAt ) {
|
||||
this.videoUrl += '#t=0,' + endAt;
|
||||
}
|
||||
}
|
||||
|
||||
self.$backgroundVideoContainer
|
||||
.find( '.' + self.options.bgLocalVideoContainerClass )
|
||||
.attr('src', this.videoUrl )
|
||||
.one( 'canplay', function() {
|
||||
self.updatePlayerDimensions();
|
||||
self.$backgroundVideoContainer.css('opacity', 1);
|
||||
});
|
||||
|
||||
// if video is fragmented and should be looped, we need to hack because when fragmented, looping won't be done automatically
|
||||
var isVideoUrlSetupForFragment = -1 !== this.videoUrl.indexOf('#t=');
|
||||
if ( self.options.loop && isVideoUrlSetupForFragment ) {
|
||||
// solution found here : https://stackoverflow.com/questions/23304021/loop-video-with-media-fragments
|
||||
self.videoPlayer.on( 'timeupdate', nb_.throttle( function () {
|
||||
if( this.currentTime > endAt ) {
|
||||
this.currentTime = startAt;
|
||||
this.play();
|
||||
}
|
||||
}, 100 ) );
|
||||
} else {
|
||||
// If not looped, remove video after play
|
||||
self.videoPlayer.on( 'ended', function () {
|
||||
self.videoPlayer.hide();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Plugin.prototype.setupYtubeVideo = function() {
|
||||
var self = this;
|
||||
|
||||
// params : { initial : true, videoPlayer : self.videoPlayer }
|
||||
var _setupYtubeLoopWhenFragmented = function( params ) {
|
||||
var _self_ = this;
|
||||
|
||||
// container still exists?
|
||||
if ( !params.videoPlayer.getIframe().contentWindow )
|
||||
return;
|
||||
|
||||
var startAt = self.options.startAt,
|
||||
endAt = self.options.endAt;
|
||||
|
||||
if ( !self.options.loop && !params.initial ) {
|
||||
params.videoPlayer.stopVideo();
|
||||
return;
|
||||
}
|
||||
|
||||
params.videoPlayer.seekTo( startAt );
|
||||
|
||||
if ( endAt ) {
|
||||
var fragmentLength = endAt - startAt + 1;
|
||||
setTimeout(function () {
|
||||
_setupYtubeLoopWhenFragmented( { initial : false , videoPlayer : params.videoPlayer } );
|
||||
}, fragmentLength * 1000 );
|
||||
}
|
||||
};
|
||||
|
||||
// Chrome browser may not fire the `PLAYING` state on starttime
|
||||
// if ( window.chrome ) {
|
||||
// startStateCode = self.apiInstance.PlayerState.UNSTARTED;
|
||||
// }
|
||||
// Updated in January 2020
|
||||
// fixes https://github.com/presscustomizr/nimble-builder/issues/574
|
||||
var startStateCode = self.apiInstance.PlayerState.UNSTARTED;
|
||||
|
||||
self.$backgroundVideoContainer.addClass( self.options.bgLoadingClass );
|
||||
this.videoPlayer = new self.apiInstance.Player( self.$backgroundVideoContainer.find( '.' + self.options.bgYoutubeVideoContainerClass )[0], {
|
||||
videoId: self.videoId,
|
||||
events: {
|
||||
onReady: function onReady() {
|
||||
self.videoPlayer.mute();
|
||||
self.updatePlayerDimensions();
|
||||
if ( self.isFragmentedVideo ) {
|
||||
_setupYtubeLoopWhenFragmented( { initial : true, videoPlayer : self.videoPlayer } );
|
||||
}
|
||||
self.videoPlayer.playVideo();
|
||||
},
|
||||
onStateChange: function onStateChange(event) {
|
||||
switch (event.data) {
|
||||
case startStateCode:
|
||||
self.$backgroundVideoContainer.removeClass( self.options.bgLoadingClass );
|
||||
self.$backgroundVideoContainer.css('opacity', 1);
|
||||
break;
|
||||
|
||||
case self.apiInstance.PlayerState.ENDED:
|
||||
self.videoPlayer.seekTo( self.options.startAt );
|
||||
|
||||
if ( !self.options.loop ) {
|
||||
self.videoPlayer.destroy();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
playerVars: {
|
||||
controls: 0,
|
||||
rel: 0
|
||||
}
|
||||
});
|
||||
};//setupYtubeVideo
|
||||
|
||||
|
||||
Plugin.prototype.setupVimeoVideo = function() {
|
||||
var self = this;
|
||||
|
||||
var _setupVimeoFragment = function() {
|
||||
var _self_ = this;
|
||||
var startAt = self.options.startAt,
|
||||
endAt = self.options.endAt;
|
||||
// If a start time is defined, set the start time
|
||||
if ( startAt ) {
|
||||
self.videoPlayer.on( 'play', function ( data ) {
|
||||
if ( 0 === data.seconds ) {
|
||||
self.videoPlayer.setCurrentTime( startAt );
|
||||
}
|
||||
});
|
||||
} // If an end time is defined, handle ending the video
|
||||
|
||||
|
||||
self.videoPlayer.on( 'timeupdate', function (data) {
|
||||
if ( endAt && endAt < data.seconds ) {
|
||||
if ( ! self.options.loop ) {
|
||||
// Stop at user-defined end time if not loop
|
||||
self.videoPlayer.pause();
|
||||
} else {
|
||||
// Go to start time if loop
|
||||
self.videoPlayer.setCurrentTime( startAt );
|
||||
}
|
||||
} // If start time is defined but an end time is not, go to user-defined start time at video end.
|
||||
// Vimeo JS API has an 'ended' event, but it never fires when infinite loop is defined, so we
|
||||
// get the video duration (returns a promise) then use duration-0.5s as end time
|
||||
|
||||
|
||||
self.videoPlayer.getDuration().then( function ( duration ) {
|
||||
if ( startAt && !endAt && data.seconds > duration - 0.5 ) {
|
||||
self.videoPlayer.setCurrentTime( startAt );
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
self.$backgroundVideoContainer.addClass( self.options.bgLoadingClass );
|
||||
// doc : https://github.com/vimeo/player.js
|
||||
this.videoPlayer = new self.apiInstance.Player( self.$backgroundVideoContainer, {
|
||||
id: self.videoId,
|
||||
width: self.$backgroundVideoContainer.outerWidth().width,
|
||||
autoplay: true,
|
||||
loop: self.options.loop,
|
||||
transparent: false,
|
||||
playsinline: false,
|
||||
background: true,
|
||||
muted: true,
|
||||
controls:false//<= hide all elements in the player (play bar, sharing buttons, etc)
|
||||
} ); // Handle user-defined start/end times
|
||||
|
||||
if ( this.isFragmentedVideo ) {
|
||||
_setupVimeoFragment();
|
||||
}
|
||||
|
||||
this.videoPlayer.ready().then(function () {
|
||||
$( self.videoPlayer.element ).addClass('sek-background-vimeo-element');
|
||||
self.updatePlayerDimensions();
|
||||
nb_.delay( function() {
|
||||
self.$backgroundVideoContainer.removeClass( self.options.bgLoadingClass );
|
||||
self.$backgroundVideoContainer.css('opacity', 1);
|
||||
}, 200 );
|
||||
});
|
||||
};//setupVimeoVideo
|
||||
|
||||
|
||||
|
||||
Plugin.prototype.updatePlayerDimensions = function() {
|
||||
var self = this;
|
||||
if ( 'local' !== this.videoOrigin && !this.videoPlayer )
|
||||
return;
|
||||
|
||||
var $playerElement;
|
||||
if ('youtube' === this.videoOrigin) {
|
||||
$playerElement = $( this.videoPlayer.getIframe() );
|
||||
} else if ('vimeo' === this.videoOrigin ) {
|
||||
$playerElement = $( this.videoPlayer.element );
|
||||
} else if ('local' === this.videoOrigin ) {
|
||||
$playerElement = self.videoPlayer;
|
||||
}
|
||||
|
||||
if ( !$playerElement )
|
||||
return;
|
||||
|
||||
var aspectRatioSetting = '16:9';
|
||||
|
||||
if ('vimeo' === this.videoOrigin) {
|
||||
aspectRatioSetting = $playerElement[0].width + ':' + $playerElement[0].height;
|
||||
}
|
||||
|
||||
var containerWidth = this.$backgroundVideoContainer.outerWidth(),
|
||||
containerHeight = this.$backgroundVideoContainer.outerHeight(),
|
||||
aspectRatioArray = aspectRatioSetting.split(':'),
|
||||
aspectRatio = aspectRatioArray[0] / aspectRatioArray[1],
|
||||
ratioWidth = containerWidth / aspectRatio,
|
||||
ratioHeight = containerHeight * aspectRatio,
|
||||
isWidthFixed = containerWidth / containerHeight > aspectRatio;
|
||||
|
||||
$playerElement
|
||||
.width( isWidthFixed ? containerWidth : ratioHeight )
|
||||
.height( isWidthFixed ? ratioWidth : containerHeight );
|
||||
};
|
||||
|
||||
|
||||
|
||||
Plugin.prototype.getVideoApiHelpers = function( videoOrigin ) {
|
||||
var self = this;
|
||||
return {
|
||||
insertAPI : function() {
|
||||
$('script:first').before( $('<script>', {
|
||||
src : 'youtube' === videoOrigin ? 'https://www.youtube.com/iframe_api' : 'https://player.vimeo.com/api/player.js',
|
||||
id : 'sek-' + videoOrigin + '-api'
|
||||
}));
|
||||
},
|
||||
//see /wp-includes/js/mediaelement/renderers/vimeo.js
|
||||
getVideoIDFromURL : function(url) {
|
||||
if (url === undefined || url === null) {
|
||||
return null;
|
||||
}
|
||||
if ( 'youtube' === videoOrigin ) {
|
||||
var videoIDParts = url.match( /^(?:https?:\/\/)?(?:www\.)?(?:m\.)?(?:youtu\.be\/|youtube\.com\/(?:(?:watch)?\?(?:.*&)?vi?=|(?:embed|v|vi|user)\/))([^?&"'>]+)/ );
|
||||
return videoIDParts && videoIDParts[1];
|
||||
} else {
|
||||
var parts = url.split('?');
|
||||
url = parts[0];
|
||||
return parseInt(url.substring(url.lastIndexOf('/') + 1), 10);
|
||||
}
|
||||
},
|
||||
onApiReady: function(callback) {
|
||||
var self = this;
|
||||
if ( $('#' + 'sek-' + videoOrigin + '-api').length < 1 ) {
|
||||
this.insertAPI();
|
||||
}
|
||||
var _isPlayerRemoteApiLoaded = 'youtube' === videoOrigin ? ( window.YT && YT.loaded ) : window.Vimeo;
|
||||
if ( _isPlayerRemoteApiLoaded ) {
|
||||
callback( 'youtube' === videoOrigin ? YT : Vimeo );
|
||||
} else {
|
||||
// If not ready check again by timeout..
|
||||
setTimeout(function () {
|
||||
self.onApiReady(callback);
|
||||
}, 350);
|
||||
}
|
||||
}
|
||||
};//defaults
|
||||
};//getVideoApiHelpers
|
||||
|
||||
|
||||
// prevents against multiple instantiations
|
||||
$.fn[pluginName] = function ( options ) {
|
||||
return this.each(function () {
|
||||
if (!$.data(this, 'plugin_' + pluginName)) {
|
||||
$.data(this, 'plugin_' + pluginName,
|
||||
new Plugin( this, options ));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
})( jQuery, window );
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* VIDEO BACKGROUND FOR SECTIONS AND COLUMNS
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// - insert bg video container
|
||||
// - inject player api script
|
||||
// - print video iframe
|
||||
// - on api ready, do stuff
|
||||
jQuery( function($){
|
||||
var _maybeInstantiatePlayers = function() {
|
||||
$('[data-sek-video-bg-src]').each(function() {
|
||||
if ( 'section' === $(this).data('sek-level') || 'column' === $(this).data('sek-level') ) {
|
||||
if ( ! $(this).data('sek-player-instantiated') ) {
|
||||
$(this).nimbleLoadVideoBg( { lazyLoad: sekFrontLocalized.video_bg_lazyload_enabled } );
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// on page load
|
||||
_maybeInstantiatePlayers();
|
||||
|
||||
// WHEN CUSTOMIZING
|
||||
// on various nimble events when customizing
|
||||
nb_.cachedElements.$body.on('sek-section-added sek-columns-refreshed', function( evt, params ){
|
||||
_maybeInstantiatePlayers();
|
||||
});
|
||||
|
||||
// On module refreshed inside a section, simply trigger a dimensions update
|
||||
nb_.cachedElements.$body.on('sek-modules-refreshed', function( evt, params ){
|
||||
$('[data-sek-video-bg-src]').each(function() {
|
||||
$(this).trigger('refresh-video-dimensions');
|
||||
});
|
||||
});
|
||||
|
||||
// when customizing the level
|
||||
nb_.cachedElements.$body.on('sek-level-refreshed', function( evt, params ){
|
||||
// when removing a level => no params.id
|
||||
if ( !params || !nb_.isObject( params ) || !params.id )
|
||||
return;
|
||||
|
||||
var $levelRefreshed = $( '[data-sek-id="'+ params.id +'"][data-sek-video-bg-src]' );
|
||||
if ( $levelRefreshed.length > 0 && !$levelRefreshed.data('sek-player-instantiated') ) {
|
||||
$levelRefreshed.nimbleLoadVideoBg( { lazyLoad: sekFrontLocalized.video_bg_lazyload_enabled } );
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
};/////////////// callbackFunc
|
||||
|
||||
// on 'nb-app-ready', jQuery is loaded
|
||||
nb_.listenTo('nb-app-ready', function(){
|
||||
callbackFunc();
|
||||
nb_.emit('nb-videobg-parsed');
|
||||
});
|
||||
}(window, document));
|
||||
|
||||
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
@@ -0,0 +1,397 @@
|
||||
// global sekFrontLocalized, nimbleListenTo
|
||||
window.nb_ = {};
|
||||
// Jquery agnostic
|
||||
(function(w, d){
|
||||
window.nb_ = {
|
||||
isArray : function(obj) {
|
||||
return Array.isArray(obj) || toString.call(obj) === '[object Array]';
|
||||
},
|
||||
inArray : function(obj, value) {
|
||||
if ( !nb_.isArray(obj) || nb_.isUndefined(value) )
|
||||
return false;
|
||||
return obj.indexOf(value) > -1;
|
||||
},
|
||||
isUndefined : function(obj) {
|
||||
return obj === void 0;
|
||||
},
|
||||
isObject : function(obj) {
|
||||
var type = typeof obj;
|
||||
return type === 'function' || type === 'object' && !!obj;
|
||||
},
|
||||
// safe console log for
|
||||
errorLog : function() {
|
||||
//fix for IE, because console is only defined when in F12 debugging mode in IE
|
||||
if ( nb_.isUndefined( console ) || 'function' != typeof window.console.log )
|
||||
return;
|
||||
console.log.apply(console,arguments);
|
||||
},
|
||||
hasPreloadSupport : function( browser ) {
|
||||
var link = document.createElement('link');
|
||||
var relList = link.relList;
|
||||
if (!relList || !relList.supports)
|
||||
return false;
|
||||
return relList.supports('preload');
|
||||
},
|
||||
listenTo : function( evt, func ) {
|
||||
// store it, so if the event has been emitted before the listener is fired, we know it's been emitted
|
||||
nb_.eventsListenedTo.push(evt);
|
||||
|
||||
var canWeFireCallbackForEvent = {
|
||||
'nb-jquery-loaded' : function() { return typeof undefined !== typeof jQuery; },
|
||||
'nb-app-ready' : function() { return ( typeof undefined !== typeof window.nb_ ) && nb_.wasListenedTo('nb-jquery-loaded'); },
|
||||
'nb-swipebox-parsed' : function() { return ( typeof undefined !== typeof jQuery ) && ( typeof undefined !== typeof jQuery.fn.swipebox ); },
|
||||
'nb-main-swiper-parsed' : function() { return typeof undefined !== typeof window.Swiper; }
|
||||
};
|
||||
// e is the event object passed
|
||||
// it is possible to add params but we need to use new CustomEvent with a polyfill for IE
|
||||
// see : https://stackoverflow.com/questions/18613456/trigger-event-with-parameters
|
||||
var _executeAndLog = function(e) {
|
||||
if ( !nb_.isUndefined(canWeFireCallbackForEvent[evt]) && false === canWeFireCallbackForEvent[evt]() ) {
|
||||
nb_.errorLog('Nimble error => an event callback could not be fired because conditions not met => ', evt, nb_.eventsListenedTo, func );
|
||||
return;
|
||||
}
|
||||
func();
|
||||
// // store it, so if the event has been emitted before the listener is fired, we know it's been emitted
|
||||
// nb_.eventsListenedTo.push(evt);
|
||||
};
|
||||
// if the event requires a condition to be executed let's check it
|
||||
// if the event has alreay been listened to, let's fire the func, otherwise wait for its emission
|
||||
if ( 'function' === typeof func ) {
|
||||
if ( nb_.wasEmitted(evt) ) {
|
||||
_executeAndLog();
|
||||
} else {
|
||||
document.addEventListener(evt,_executeAndLog);
|
||||
}
|
||||
} else {
|
||||
nb_.errorLog('Nimble error => listenTo func param is not a function for event => ', evt );
|
||||
}
|
||||
},
|
||||
eventsEmitted : [],
|
||||
eventsListenedTo : [],
|
||||
// @param params { fire_once : false }
|
||||
// fire_once is used in nb_.maybeLoadAssetsWhenSelectorInScreen()
|
||||
emit : function(evt, params ) {
|
||||
var _fire_once = nb_.isUndefined( params ) || params.fire_once;
|
||||
if ( _fire_once && nb_.wasEmitted(evt) )
|
||||
return;
|
||||
|
||||
// it is possible to add params when dispatching the event, but we need to use new CustomEvent with a polyfill for IE
|
||||
// see : https://stackoverflow.com/questions/18613456/trigger-event-with-parameters
|
||||
var _evt = document.createEvent('Event');
|
||||
_evt.initEvent(evt, true, true); //can bubble, and is cancellable
|
||||
document.dispatchEvent(_evt);
|
||||
nb_.eventsEmitted.push(evt);
|
||||
},
|
||||
wasListenedTo : function( evt ) {
|
||||
return ('string' === typeof evt) && nb_.inArray( nb_.eventsListenedTo, evt );
|
||||
},
|
||||
wasEmitted : function( evt ) {
|
||||
return ('string' === typeof evt) && nb_.inArray( nb_.eventsEmitted, evt );
|
||||
},
|
||||
// https://stackoverflow.com/questions/5353934/check-if-element-is-visible-on-screen
|
||||
isInScreen : function(el) {
|
||||
if ( !nb_.isObject( el ) )
|
||||
return false;
|
||||
var rect = el.getBoundingClientRect(),
|
||||
viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
|
||||
return !(rect.bottom < 0 || rect.top - viewHeight >= 0);
|
||||
},
|
||||
isCustomizing : function() {
|
||||
return true == '<?php echo skp_is_customizing(); ?>';
|
||||
},
|
||||
isLazyLoadEnabled : function() {
|
||||
return !nb_.isCustomizing() && true == '<?php echo sek_is_img_smartload_enabled(); ?>';
|
||||
},
|
||||
// params = {
|
||||
// id : 'nb-animate-css',
|
||||
// as : 'style',
|
||||
// href : "",
|
||||
// onEvent : 'nb-docready',
|
||||
// scriptEl : document.currentScript,
|
||||
// eventOnLoad : 'animate-css-loaded'
|
||||
// }
|
||||
// About preloading : rel="preload" tells the browser to start loading an important assets in priority
|
||||
// example :
|
||||
// - load late-discovered resources early
|
||||
// - early loading of fonts
|
||||
// NB asset strategy :
|
||||
// - use rel="preload" for webfonts like Font Awesome ( stylesheet + fonts )
|
||||
// - use defer attribute for all javascript files( see https://flaviocopes.com/javascript-async-defer/ ) "The best thing to do to speed up your page loading when using scripts is to put them in the head, and add a defer attribute to your script tag:"
|
||||
// see https://www.smashingmagazine.com/2016/02/preload-what-is-it-good-for/
|
||||
preloadOrDeferAsset : function(params) {
|
||||
params = params || {};
|
||||
// bail if preloaded already ?
|
||||
nb_.preloadedAssets = nb_.preloadedAssets || [];
|
||||
if ( nb_.inArray( nb_.preloadedAssets, params.id ) )
|
||||
return;
|
||||
|
||||
var headTag = document.getElementsByTagName('head')[0],
|
||||
link,
|
||||
_injectFinalAsset = function() {
|
||||
var link = this;
|
||||
// this is the link element
|
||||
if ( 'style' === params.as ) {
|
||||
link.setAttribute('rel', 'stylesheet');
|
||||
link.setAttribute('type', 'text/css');
|
||||
link.setAttribute('media', 'all');
|
||||
} else {
|
||||
var _script = document.createElement("script");
|
||||
_script.setAttribute('src', params.href );
|
||||
_script.setAttribute('id', params.id );
|
||||
if ( 'script' === params.as ) {
|
||||
_script.setAttribute('defer', 'defer');
|
||||
}
|
||||
headTag.appendChild(_script);
|
||||
// clean the loader link
|
||||
_maybeRemoveScriptEl.call(link);
|
||||
}
|
||||
if ( params.eventOnLoad ) {
|
||||
nb_.emit( params.eventOnLoad );
|
||||
}
|
||||
},
|
||||
_maybeRemoveScriptEl = function() {
|
||||
var _el = this;
|
||||
if ( _el && _el.parentNode && _el.parentNode.contains(_el) ) {
|
||||
try{_el.parentNode.removeChild(_el);} catch(er) {
|
||||
nb_.errorLog('NB error when removing a script el', el);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// terminate here in the case of a font preload when preload not supported
|
||||
if ( 'font' === params.as && !nb_.hasPreloadSupport() )
|
||||
return;
|
||||
|
||||
link = document.createElement('link');
|
||||
|
||||
// script without preload support
|
||||
if ( 'script' === params.as ) {
|
||||
if ( params.onEvent ) {
|
||||
nb_.listenTo( params.onEvent, function() { _injectFinalAsset.call(link); });
|
||||
} else {
|
||||
_injectFinalAsset.call(link);
|
||||
}
|
||||
} else {
|
||||
// script, font and stylesheet
|
||||
link.setAttribute('href', params.href);
|
||||
if ( 'style' === params.as ) {
|
||||
link.setAttribute('rel', nb_.hasPreloadSupport() ? 'preload' : 'stylesheet' );
|
||||
} else if ( 'font' === params.as && nb_.hasPreloadSupport() ) {
|
||||
link.setAttribute('rel', 'preload' );
|
||||
}
|
||||
link.setAttribute('id', params.id );
|
||||
link.setAttribute('as', params.as);
|
||||
|
||||
// attributes specific to fonts
|
||||
if ( 'font' === params.as ) {
|
||||
link.setAttribute('type', params.type);
|
||||
link.setAttribute('crossorigin', 'anonymous');
|
||||
}
|
||||
|
||||
// watch load events
|
||||
link.onload = function() {
|
||||
this.onload=null;
|
||||
// if this is a font, let's only check if an event is scheduled on load
|
||||
if ( 'font' === params.as ) {
|
||||
if ( params.eventOnLoad ) {
|
||||
nb_.emit( params.eventOnLoad );
|
||||
}
|
||||
// nothing left to do if this is a font. It can now be used by the stylesheet
|
||||
return;
|
||||
}
|
||||
|
||||
if ( params.onEvent ) {
|
||||
nb_.listenTo( params.onEvent, function() { _injectFinalAsset.call(link); });
|
||||
} else {
|
||||
_injectFinalAsset.call(link);
|
||||
}
|
||||
};
|
||||
link.onerror = function(er) {
|
||||
nb_.errorLog('Nimble preloadOrDeferAsset error', er, params );
|
||||
};
|
||||
}
|
||||
// append link now
|
||||
headTag.appendChild(link);
|
||||
|
||||
// store the asset as done
|
||||
nb_.preloadedAssets.push( params.id );
|
||||
|
||||
// clean the script element from which preload has been requested
|
||||
_maybeRemoveScriptEl.call(params.scriptEl);
|
||||
},
|
||||
mayBeRevealBG : function() {
|
||||
var imgSrc = this.getAttribute('data-sek-src');
|
||||
if ( imgSrc ) {
|
||||
this.setAttribute( 'style', 'background-image:url("' + this.getAttribute('data-sek-src') +'")' );
|
||||
this.className += ' sek-lazy-loaded';//<= so we don't parse it twice when lazyload is active
|
||||
// clean css loader
|
||||
var css_loaders = this.querySelectorAll('.sek-css-loader');
|
||||
css_loaders.forEach( function(_cssl) {
|
||||
if ( nb_.isObject(_cssl) ) {
|
||||
_cssl.parentNode.removeChild(_cssl);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};//window.nb_
|
||||
|
||||
// forEach not supported by IE
|
||||
// This polyfill adds compatibility to all Browsers supporting ES5:
|
||||
if (window.NodeList && !NodeList.prototype.forEach) {
|
||||
NodeList.prototype.forEach = function (callback, thisArg) {
|
||||
thisArg = thisArg || window;
|
||||
for (var i = 0; i < this.length; i++) {
|
||||
callback.call(thisArg, this[i], i, this);
|
||||
}
|
||||
};
|
||||
}
|
||||
// maybe reveal bg images on dom ready
|
||||
// if lazyload is not loaded yet, and container is visible
|
||||
// Sept 2020 : if lazyload disabled, make sure all background get revealed
|
||||
// because background are always printed as data-sek-src attribute for a level, lazyload or not, and therefore need to be inlined styled with javascript
|
||||
nb_.listenTo('nb-docready', function() {
|
||||
var matches = document.querySelectorAll('div.sek-has-bg');
|
||||
if ( !nb_.isObject( matches ) || matches.length < 1 )
|
||||
return;
|
||||
var imgSrc;
|
||||
matches.forEach( function(el) {
|
||||
if ( !nb_.isObject(el) )
|
||||
return;
|
||||
if ( window.sekFrontLocalized && window.sekFrontLocalized.lazyload_enabled ) {
|
||||
if ( nb_.isInScreen(el) ) {
|
||||
nb_.mayBeRevealBG.call(el);
|
||||
}
|
||||
} else {
|
||||
nb_.mayBeRevealBG.call(el);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Add an internal document ready listener the jquery way
|
||||
// Catch cases where $(document).ready() is called
|
||||
// after the browser event has already occurred.
|
||||
// Support: IE <=9 - 10 only
|
||||
// Older IE sometimes signals "interactive" too soon
|
||||
if ( document.readyState === "complete" || ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
|
||||
nb_.emit('nb-docready');
|
||||
} else {
|
||||
var _docReady = function() {
|
||||
if ( !nb_.wasEmitted('nb-docready') ) {
|
||||
nb_.emit('nb-docready');
|
||||
}
|
||||
};
|
||||
// Use the handy event callback
|
||||
document.addEventListener( "DOMContentLoaded", _docReady );
|
||||
// A fallback to window.onload, that will always work
|
||||
window.addEventListener( "load", _docReady );
|
||||
}
|
||||
|
||||
}(window, document ));
|
||||
|
||||
|
||||
// introduced for https://github.com/presscustomizr/nimble-builder/issues/626
|
||||
// jQuery can potentially be loaded async, so let's react to its load or the presence of window.jQuery
|
||||
// This relies on the fact that we use add_filter( 'script_loader_tag', array( $this, 'sek_filter_script_loader_tag' ), 10, 2 ); to add id 'nb-jquery'
|
||||
( function() {
|
||||
var _maybeEmit = function() {
|
||||
var evt = 'nb-jquery-loaded';
|
||||
if ( !nb_.wasEmitted(evt) ) {
|
||||
nb_.emit(evt);
|
||||
}
|
||||
};
|
||||
// recursively try to load jquery every 200ms during 6s ( max 30 times )
|
||||
var _emitWhenJqueryIsReady = function( attempts ) {
|
||||
attempts = attempts || 0;
|
||||
if ( typeof undefined !== typeof window.jQuery ) {
|
||||
_maybeEmit();
|
||||
} else if ( attempts < 30 ) {
|
||||
setTimeout( function() {
|
||||
attempts++;
|
||||
_emitWhenJqueryIsReady( attempts );
|
||||
}, 200 );
|
||||
} else {
|
||||
if ( window.console && window.console.log ) {
|
||||
console.log('Nimble Builder problem : jQuery.js was not detected on your website');
|
||||
}
|
||||
}
|
||||
};
|
||||
// if jQuery has already be printed, let's listen to the load event
|
||||
var jquery_script_el = document.getElementById('nb-jquery');
|
||||
if ( jquery_script_el ) {
|
||||
jquery_script_el.addEventListener('load', function() {
|
||||
_maybeEmit();
|
||||
});
|
||||
}
|
||||
_emitWhenJqueryIsReady();
|
||||
})();
|
||||
|
||||
|
||||
|
||||
//printed in sek_maybe_load_scripts_in_ajax()
|
||||
(function(w, d){
|
||||
nb_.listenTo( 'nb-jquery-loaded', function() {
|
||||
if ( !sekFrontLocalized.load_front_assets_on_dynamically )
|
||||
return;
|
||||
// params = {
|
||||
// path : 'js/libs/swiper-bundle.min.js'
|
||||
// complete : function() {
|
||||
// $.ajax( {
|
||||
// url : sekFrontLocalized.frontAssetsPath + 'js/prod-front-simple-slider-module.min.js?'+sekFrontLocalized.assetVersion,
|
||||
// cache : true,// use the browser cached version when available
|
||||
// dataType: "script"
|
||||
// }).done(function() {
|
||||
// }).fail( function() {
|
||||
// nb_.errorLog('script instantiation failed');
|
||||
// });
|
||||
// }
|
||||
// loadcheck : 'function' === typeof( window.Swiper )
|
||||
// }
|
||||
nb_.scriptsLoadingStatus = {};
|
||||
nb_.ajaxLoadScript = function( params ) {
|
||||
jQuery(function($){
|
||||
params = $.extend( { path : '', complete : '', loadcheck : false }, params );
|
||||
// Bail if the load request has already been made, but not yet finished.
|
||||
if ( nb_.scriptsLoadingStatus[params.path] && 'pending' === nb_.scriptsLoadingStatus[params.path].state() ) {
|
||||
return;
|
||||
}
|
||||
// set the script loading status now to avoid several calls
|
||||
nb_.scriptsLoadingStatus[params.path] = nb_.scriptsLoadingStatus[params.path] || $.Deferred();
|
||||
jQuery.ajax( {
|
||||
url : sekFrontLocalized.frontAssetsPath + params.path + '?'+ sekFrontLocalized.assetVersion,
|
||||
cache : true,// use the browser cached version when available
|
||||
dataType: "script"
|
||||
}).done(function() {
|
||||
if ( ('function' === typeof params.loadcheck) && !params.loadcheck() ) {
|
||||
nb_.errorLog('ajaxLoadScript success but loadcheck failed for => ' + params.path );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( 'function' === typeof params.complete ) {
|
||||
params.complete();
|
||||
}
|
||||
}).fail( function() {
|
||||
nb_.errorLog('ajaxLoadScript failed for => ' + params.path );
|
||||
});
|
||||
});
|
||||
};//ajaxLoadScript
|
||||
});/////////////// callbackFunc
|
||||
|
||||
nb_.listenTo('nb-jquery-loaded', function() {
|
||||
jQuery(function($){
|
||||
if ( !sekFrontLocalized.load_front_assets_on_dynamically )
|
||||
return;
|
||||
// Main script
|
||||
nb_.ajaxLoadScript({ path : sekFrontLocalized.isDevMode ? 'js/ccat-nimble-front.js' : 'js/ccat-nimble-front.min.js'});
|
||||
|
||||
// Partial scripts
|
||||
$.each( sekFrontLocalized.partialFrontScripts, function( _name, _event ){
|
||||
nb_.listenTo( _event, function() {
|
||||
nb_.ajaxLoadScript({ path : sekFrontLocalized.isDevMode ? 'js/partials/' + _name + '.js' : 'js/partials/' + _name + '.min.js'});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
}(window, document));
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,69 @@
|
||||
// global sekFrontLocalized, nimbleListenTo
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* ACCORDION MODULE
|
||||
/* ------------------------------------------------------------------------- */
|
||||
(function(w, d){
|
||||
var callbackFunc = function() {
|
||||
jQuery( function($){
|
||||
$( 'body' ).on( 'click sek-expand-accord-item', '.sek-accord-item > .sek-accord-title', function( evt ) {
|
||||
//evt.preventDefault();
|
||||
//evt.stopPropagation();
|
||||
var $item = $(this).closest( '.sek-accord-item'),
|
||||
$accordion = $(this).closest( '.sek-accord-wrapper');
|
||||
|
||||
// Note : cast the boolean to a string by adding +''
|
||||
if ( "true" == $accordion.data('sek-one-expanded')+'' ) {
|
||||
$accordion.find('.sek-accord-item').not( $item ).each( function() {
|
||||
var $current_item = $(this);
|
||||
$current_item.find('.sek-accord-content').stop( true, true ).slideUp( {
|
||||
duration : 200,
|
||||
start : function() {
|
||||
// If already expanded, make sure inline style display:block is set
|
||||
// otherwise, the CSS style display:none will apply first, making the transition brutal.
|
||||
if ( "true" == $current_item.attr('data-sek-expanded')+'' ) {
|
||||
$current_item.find('.sek-accord-content').css('display', 'block');
|
||||
}
|
||||
$current_item.attr('data-sek-expanded', "false" );
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
if ( 'sek-expand-accord-item' === evt.type && "true" == $item.attr('data-sek-expanded')+'' ) {
|
||||
return;
|
||||
} else {
|
||||
$item.find('.sek-accord-content').stop( true, true ).slideToggle({
|
||||
duration : 200,
|
||||
start : function() {
|
||||
// If already expanded, make sure inline style display:block is set
|
||||
// otherwise, the CSS style display:none will apply first, making the transition brutal.
|
||||
if ( "true" == $item.attr('data-sek-expanded')+'' ) {
|
||||
$item.find('.sek-accord-content').css('display', 'block');
|
||||
}
|
||||
$item.attr('data-sek-expanded', "false" == $item.attr('data-sek-expanded')+'' ? "true" : "false" );
|
||||
$item.trigger( "true" == $item.attr('data-sek-expanded') ? 'sek-accordion-expanded' : 'sek-accordion-collapsed' );
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});// on 'click'
|
||||
|
||||
// When customizing, expand the currently edited item
|
||||
// @see CZRItemConstructor in api.czrModuleMap.czr_img_slider_collection_child
|
||||
if ( window.wp && ! nb_.isUndefined( wp.customize ) ) {
|
||||
wp.customize.preview.bind('sek-item-focus', function( params ) {
|
||||
|
||||
var $itemEl = $('[data-sek-item-id="' + params.item_id +'"]', '.sek-accord-wrapper').first();
|
||||
if ( 1 > $itemEl.length )
|
||||
return;
|
||||
|
||||
$itemEl.find('.sek-accord-title').trigger('sek-expand-accord-item');
|
||||
});
|
||||
}
|
||||
});//jQuery()
|
||||
|
||||
};/////////////// callbackFunc
|
||||
// on 'nb-app-ready', jQuery is loaded
|
||||
nb_.listenTo('nb-app-ready', callbackFunc );
|
||||
}(window, document));
|
||||
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
window,document,nb_.listenTo("nb-app-ready",function(){jQuery(function(d){d("body").on("click sek-expand-accord-item",".sek-accord-item > .sek-accord-title",function(e){var t=d(this).closest(".sek-accord-item"),a=d(this).closest(".sek-accord-wrapper");"true"==a.data("sek-one-expanded")+""&&a.find(".sek-accord-item").not(t).each(function(){var e=d(this);e.find(".sek-accord-content").stop(!0,!0).slideUp({duration:200,start:function(){"true"==e.attr("data-sek-expanded")+""&&e.find(".sek-accord-content").css("display","block"),e.attr("data-sek-expanded","false")}})}),"sek-expand-accord-item"===e.type&&"true"==t.attr("data-sek-expanded")+""||t.find(".sek-accord-content").stop(!0,!0).slideToggle({duration:200,start:function(){"true"==t.attr("data-sek-expanded")+""&&t.find(".sek-accord-content").css("display","block"),t.attr("data-sek-expanded","false"==t.attr("data-sek-expanded")+""?"true":"false"),t.trigger("true"==t.attr("data-sek-expanded")?"sek-accordion-expanded":"sek-accordion-collapsed")}})}),window.wp&&!nb_.isUndefined(wp.customize)&&wp.customize.preview.bind("sek-item-focus",function(e){var t=d('[data-sek-item-id="'+e.item_id+'"]',".sek-accord-wrapper").first();t.length<1||t.find(".sek-accord-title").trigger("sek-expand-accord-item")})})});
|
||||
@@ -0,0 +1,160 @@
|
||||
// global sekFrontLocalized, nimbleListenTo
|
||||
/* ===================================================
|
||||
* jquery.fn.parallaxBg v1.0.0
|
||||
* Created in October 2018.
|
||||
* Inspired from https://github.com/presscustomizr/front-jquery-plugins/blob/master/jqueryParallax.js
|
||||
* ===================================================
|
||||
*/
|
||||
(function(w, d){
|
||||
var callbackFunc = function() {
|
||||
(function ( $, window ) {
|
||||
//defaults
|
||||
var pluginName = 'parallaxBg',
|
||||
defaults = {
|
||||
parallaxForce : 40,
|
||||
oncustom : [],//list of event here
|
||||
matchMedia : 'only screen and (max-width: 800px)'
|
||||
};
|
||||
|
||||
function Plugin( element, options ) {
|
||||
this.element = $(element);
|
||||
//this.element_wrapper = this.element.closest( '.parallax-wrapper' );
|
||||
this.options = $.extend( {}, defaults, options, this.parseElementDataOptions() ) ;
|
||||
this._defaults = defaults;
|
||||
this._name = pluginName;
|
||||
this.init();
|
||||
}
|
||||
|
||||
Plugin.prototype.parseElementDataOptions = function () {
|
||||
return this.element.data();
|
||||
};
|
||||
|
||||
//can access this.element and this.option
|
||||
//@return void
|
||||
Plugin.prototype.init = function () {
|
||||
var self = this;
|
||||
//cache some element
|
||||
this.$_window = nb_.cachedElements.$window;
|
||||
this.doingAnimation = false;
|
||||
this.isVisible = false;
|
||||
this.isBefore = false;//the element is before the scroll point
|
||||
this.isAfter = true;// the element is after the scroll point
|
||||
|
||||
// normalize the parallax ratio
|
||||
// must be a number 0 > ratio > 100
|
||||
if ( 'number' !== typeof( self.options.parallaxForce ) || self.options.parallaxForce < 0 ) {
|
||||
if ( sekFrontLocalized.isDevMode ) {
|
||||
console.log('parallaxBg => the provided parallaxForce is invalid => ' + self.options.parallaxForce );
|
||||
}
|
||||
self.options.parallaxForce = this._defaults.parallaxForce;
|
||||
}
|
||||
if ( self.options.parallaxForce > 100 ) {
|
||||
self.options.parallaxForce = 100;
|
||||
}
|
||||
|
||||
//the scroll event gets throttled with the requestAnimationFrame
|
||||
this.$_window.on( 'scroll', function(_evt) { self.maybeParallaxMe(_evt); } );
|
||||
//debounced resize event
|
||||
this.$_window.on( 'resize', nb_.debounce( function(_evt) {
|
||||
self.maybeParallaxMe(_evt);
|
||||
}, 100 ) );
|
||||
|
||||
//on load
|
||||
this.checkIfIsVisibleAndCacheProperties();
|
||||
this.setTopPositionAndBackgroundSize();
|
||||
};
|
||||
|
||||
//@see https://www.paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/
|
||||
Plugin.prototype.setTopPositionAndBackgroundSize = function() {
|
||||
var self = this;
|
||||
|
||||
// options.matchMedia is set to 'only screen and (max-width: 768px)' by default
|
||||
// if a match is found, then reset the top position
|
||||
if ( nb_.isFunction( window.matchMedia ) && matchMedia( self.options.matchMedia ).matches ) {
|
||||
this.element.css({'background-position-y' : '', 'background-attachment' : '' });
|
||||
return;
|
||||
}
|
||||
|
||||
var $element = this.element,
|
||||
elemHeight = $element.outerHeight(),
|
||||
winHeight = this.$_window.height(),
|
||||
offsetTop = $element.offset().top,
|
||||
scrollTop = this.$_window.scrollTop(),
|
||||
percentOfPage = 100;
|
||||
|
||||
// the percentOfPage can vary from -1 to 1
|
||||
if ( this.isVisible ) {
|
||||
//percentOfPage = currentDistanceToMiddleScreen / maxDistanceToMiddleScreen;
|
||||
percentOfPage = ( offsetTop - scrollTop ) / winHeight;
|
||||
} else if ( this.isBefore ) {
|
||||
percentOfPage = 1;
|
||||
} else if ( this.isAfter ) {
|
||||
percentOfPage = - 1;
|
||||
}
|
||||
|
||||
var maxBGYMove = this.options.parallaxForce > 0 ? winHeight * ( 100 - this.options.parallaxForce ) / 100 : winHeight,
|
||||
bgPositionY = Math.round( percentOfPage * maxBGYMove );
|
||||
|
||||
this.element.css({
|
||||
'background-position-y' : [
|
||||
'calc(50% ',
|
||||
bgPositionY > 0 ? '+ ' : '- ',
|
||||
Math.abs( bgPositionY ) + 'px)'
|
||||
].join('')
|
||||
});
|
||||
};
|
||||
|
||||
// When does the image enter the viewport ?
|
||||
Plugin.prototype.checkIfIsVisibleAndCacheProperties = function( _evt ) {
|
||||
var $element = this.element;
|
||||
// bail if the level is display:none;
|
||||
// because $.offset() won't work
|
||||
// see because of https://github.com/presscustomizr/nimble-builder/issues/363
|
||||
if ( ! $element.is(':visible') )
|
||||
return false;
|
||||
|
||||
var scrollTop = this.$_window.scrollTop(),
|
||||
wb = scrollTop + this.$_window.height(),
|
||||
offsetTop = $element.offset().top,
|
||||
ib = offsetTop + $element.outerHeight();
|
||||
|
||||
// Cache now
|
||||
this.isVisible = ib >= scrollTop && offsetTop <= wb;
|
||||
this.isBefore = offsetTop > wb ;//the element is before the scroll point
|
||||
this.isAfter = ib < scrollTop;// the element is after the scroll point
|
||||
return this.isVisible;
|
||||
};
|
||||
|
||||
// a throttle is implemented with window.requestAnimationFrame
|
||||
Plugin.prototype.maybeParallaxMe = function(evt) {
|
||||
var self = this;
|
||||
if ( ! this.checkIfIsVisibleAndCacheProperties() )
|
||||
return;
|
||||
|
||||
if ( ! this.doingAnimation ) {
|
||||
this.doingAnimation = true;
|
||||
window.requestAnimationFrame(function() {
|
||||
self.setTopPositionAndBackgroundSize();
|
||||
self.doingAnimation = false;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// prevents against multiple instantiations
|
||||
$.fn[pluginName] = function ( options ) {
|
||||
return this.each(function () {
|
||||
if (!$.data(this, 'plugin_' + pluginName)) {
|
||||
$.data(this, 'plugin_' + pluginName,
|
||||
new Plugin( this, options ));
|
||||
}
|
||||
});
|
||||
};
|
||||
})( jQuery, window );
|
||||
};/////////////// callbackFunc
|
||||
|
||||
// on 'nb-app-ready', jQuery is loaded
|
||||
nb_.listenTo('nb-app-ready', function(){
|
||||
callbackFunc();
|
||||
nb_.emit('nb-parallax-parsed');
|
||||
});
|
||||
}(window, document));
|
||||
+1
@@ -0,0 +1 @@
|
||||
window,document,nb_.listenTo("nb-app-ready",function(){!function(e,r){var o="parallaxBg",n={parallaxForce:40,oncustom:[],matchMedia:"only screen and (max-width: 800px)"};function t(i,t){this.element=e(i),this.options=e.extend({},n,t,this.parseElementDataOptions()),this._defaults=n,this._name=o,this.init()}t.prototype.parseElementDataOptions=function(){return this.element.data()},t.prototype.init=function(){var t=this;this.$_window=nb_.cachedElements.$window,this.doingAnimation=!1,this.isVisible=!1,this.isBefore=!1,this.isAfter=!0,("number"!=typeof t.options.parallaxForce||t.options.parallaxForce<0)&&(sekFrontLocalized.isDevMode&&console.log("parallaxBg => the provided parallaxForce is invalid => "+t.options.parallaxForce),t.options.parallaxForce=this._defaults.parallaxForce),100<t.options.parallaxForce&&(t.options.parallaxForce=100),this.$_window.on("scroll",function(i){t.maybeParallaxMe(i)}),this.$_window.on("resize",nb_.debounce(function(i){t.maybeParallaxMe(i)},100)),this.checkIfIsVisibleAndCacheProperties(),this.setTopPositionAndBackgroundSize()},t.prototype.setTopPositionAndBackgroundSize=function(){if(nb_.isFunction(r.matchMedia)&&matchMedia(this.options.matchMedia).matches)this.element.css({"background-position-y":"","background-attachment":""});else{var i=this.element,t=(i.outerHeight(),this.$_window.height()),e=i.offset().top,o=this.$_window.scrollTop(),n=100;this.isVisible?n=(e-o)/t:this.isBefore?n=1:this.isAfter&&(n=-1);var s=0<this.options.parallaxForce?t*(100-this.options.parallaxForce)/100:t,a=Math.round(n*s);this.element.css({"background-position-y":["calc(50% ",0<a?"+ ":"- ",Math.abs(a)+"px)"].join("")})}},t.prototype.checkIfIsVisibleAndCacheProperties=function(i){var t=this.element;if(!t.is(":visible"))return!1;var e=this.$_window.scrollTop(),o=e+this.$_window.height(),n=t.offset().top,s=n+t.outerHeight();return this.isVisible=e<=s&&n<=o,this.isBefore=o<n,this.isAfter=s<e,this.isVisible},t.prototype.maybeParallaxMe=function(i){var t=this;this.checkIfIsVisibleAndCacheProperties()&&(this.doingAnimation||(this.doingAnimation=!0,r.requestAnimationFrame(function(){t.setTopPositionAndBackgroundSize(),t.doingAnimation=!1})))},e.fn[o]=function(i){return this.each(function(){e.data(this,"plugin_"+o)||e.data(this,"plugin_"+o,new t(this,i))})}}(jQuery,window),nb_.emit("nb-parallax-parsed")});
|
||||
@@ -0,0 +1,712 @@
|
||||
// global sekFrontLocalized, nimbleListenTo
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* MENU
|
||||
/* ------------------------------------------------------------------------- */
|
||||
(function(w, d){
|
||||
var callbackFunc = function() {
|
||||
jQuery( function($){
|
||||
// Set the attribute data-sek-is-mobile-vertical-menu on page load and dynamically set on resize
|
||||
var _setVerticalMobileBooleanAttribute = function() {
|
||||
// Set vertical mobile boolean attribute
|
||||
var breakpoint = 768, deviceWidth;
|
||||
$('nav.sek-nav-wrap').each( function() {
|
||||
breakpoint = $(this).data('sek-mobile-menu-breakpoint') || breakpoint;
|
||||
// cast to integer
|
||||
breakpoint = parseInt( breakpoint, 10 );
|
||||
deviceWidth = window.innerWidth > 0 ? window.innerWidth : screen.width;
|
||||
// console.log('window.innerWidth ??', window.innerWidth, window.innerWidth > 0 );
|
||||
// console.log('SOO ? breakpoint | device width', breakpoint + ' | ' + deviceWidth );
|
||||
|
||||
// add a data attribute so we can target the mobile menu with dynamic css rules
|
||||
// @needed when coding : https://github.com/presscustomizr/nimble-builder/issues/491
|
||||
$(this).attr('data-sek-is-mobile-vertical-menu', deviceWidth < breakpoint ? 'yes' : 'no');
|
||||
});
|
||||
};
|
||||
|
||||
_setVerticalMobileBooleanAttribute();
|
||||
nb_.cachedElements.$window.on('resize', nb_.debounce( _setVerticalMobileBooleanAttribute, 100) );
|
||||
|
||||
// HELPER TO DETERMINE IF A NODE BELONGS TO A MOBILE MENU
|
||||
// this is the element
|
||||
var nodeBelongsToAMobileMenu = function() {
|
||||
if ( this.length && this.length > 0 ) {
|
||||
// Note that [data-sek-is-mobile-vertical-menu] value is set on page load and dynamically on window resize
|
||||
return "yes" === this.closest('[data-sek-is-mobile-vertical-menu]').attr('data-sek-is-mobile-vertical-menu');
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//DESKTOP DROPDOWN
|
||||
var desktopDropdownOnHover = function() {
|
||||
//dropdown
|
||||
var DATA_KEY = 'sek.sekDropdown',
|
||||
EVENT_KEY = '.' + DATA_KEY,
|
||||
Event = {
|
||||
PLACE_ME : 'placeme'+ EVENT_KEY,
|
||||
PLACE_ALL : 'placeall' + EVENT_KEY,
|
||||
SHOWN : 'shown' + EVENT_KEY,
|
||||
SHOW : 'show' + EVENT_KEY,
|
||||
HIDDEN : 'hidden' + EVENT_KEY,
|
||||
HIDE : 'hide' + EVENT_KEY,
|
||||
CLICK : 'click' + EVENT_KEY,
|
||||
TAP : 'tap' + EVENT_KEY,
|
||||
},
|
||||
ClassName = {
|
||||
DROPDOWN : 'sek-dropdown-menu',
|
||||
DROPDOWN_SUBMENU : 'sek-dropdown-submenu',
|
||||
SHOW : 'show',
|
||||
PARENTS : 'menu-item-has-children',
|
||||
ALLOW_POINTER_ON_SCROLL : 'allow-pointer-events-on-scroll'
|
||||
},
|
||||
Selector = {
|
||||
DATA_SHOWN_TOGGLE_LINK : '.' +ClassName.SHOW+ '> a',
|
||||
HOVER_MENU : '.sek-nav-wrap',
|
||||
HOVER_PARENT : '.sek-nav-wrap .menu-item-has-children',
|
||||
PARENTS : '.sek-nav-wrap .menu-item-has-children',
|
||||
SNAKE_PARENTS : '.sek-nav-wrap .menu-item-has-children',
|
||||
CHILD_DROPDOWN : 'ul.sek-dropdown-menu'
|
||||
};
|
||||
|
||||
// unify all the dropdowns classes whether the menu is a proper menu or the all pages fall-back
|
||||
$( '.sek-nav .children, .sek-nav .sub-menu' ).addClass( ClassName.DROPDOWN );
|
||||
$( '.sek-nav-wrap .page_item_has_children' ).addClass( ClassName.PARENTS );
|
||||
$( '.sek-nav' + ' .' + ClassName.DROPDOWN + ' .' + ClassName.PARENTS ).addClass( ClassName.DROPDOWN_SUBMENU );
|
||||
|
||||
|
||||
//Handle dropdown on hover via js
|
||||
var dropdownMenuOnHover = function() {
|
||||
var _dropdown_selector = Selector.HOVER_PARENT;
|
||||
|
||||
bindEvents();
|
||||
|
||||
function _addOpenClass( evt ) {
|
||||
var $_el = $(this),
|
||||
$_child_dropdown = $_el.find( Selector.CHILD_DROPDOWN ).first();
|
||||
|
||||
// Jan 2021 : start of a fix for https://github.com/presscustomizr/nimble-builder/issues/772
|
||||
if ( nb_.cachedElements.$body.hasClass('is-touch-device') ) {
|
||||
// When navigating the regular menu ( horizontal ) on a mobile touch device, typically a tablet in landscape orientation
|
||||
// we want to prevent opening the link of a parent menu if the children are not displayed yet
|
||||
if ( "true" != $_child_dropdown.attr('aria-expanded') && !nodeBelongsToAMobileMenu.call($_child_dropdown) ) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
}
|
||||
//a little delay to balance the one added in removing the open class
|
||||
var _debounced_addOpenClass = nb_.debounce( function() {
|
||||
//do nothing if menu is mobile
|
||||
if( 'static' == $_el.find( '.'+ClassName.DROPDOWN ).css( 'position' ) ) {
|
||||
return false;
|
||||
}
|
||||
var $_child_dropdown = $_el.find( Selector.CHILD_DROPDOWN ).first();
|
||||
|
||||
if ( !$_el.hasClass(ClassName.SHOW) ) {
|
||||
nb_.cachedElements.$body.addClass( ClassName.ALLOW_POINTER_ON_SCROLL );
|
||||
|
||||
$_el.trigger( Event.SHOW )
|
||||
.addClass(ClassName.SHOW)
|
||||
.trigger( Event.SHOWN);
|
||||
|
||||
if ( $_child_dropdown.length > 0 ) {
|
||||
$_child_dropdown[0].setAttribute('aria-expanded', 'true');
|
||||
}
|
||||
}
|
||||
}, 30);
|
||||
|
||||
_debounced_addOpenClass();
|
||||
}
|
||||
|
||||
function _removeOpenClass() {
|
||||
|
||||
var $_el = $(this),
|
||||
$_child_dropdown = $_el.find( Selector.CHILD_DROPDOWN ).first();
|
||||
|
||||
//a little delay before closing to avoid closing a parent before accessing the child
|
||||
var _debounced_removeOpenClass = nb_.debounce( function() {
|
||||
if ( $_el.find("ul li:hover").length < 1 && ! $_el.closest('ul').find('li:hover').is( $_el ) ) {
|
||||
// april 2020 => some actions should be only done when not on a "touch" device
|
||||
// otherwise we have a bug on submenu expansion
|
||||
// see : https://github.com/presscustomizr/customizr/issues/1824
|
||||
//if ( !nb_.cachedElements.$body.hasClass('is-touch-device') ) {
|
||||
// $_el.trigger( Event.HIDE )
|
||||
// .removeClass( ClassName.SHOW)
|
||||
// .trigger( Event.HIDDEN );
|
||||
//}
|
||||
$_el.trigger( Event.HIDE )
|
||||
.removeClass( ClassName.SHOW)
|
||||
.trigger( Event.HIDDEN );
|
||||
|
||||
//make sure pointer events on scroll are still allowed if there's at least one submenu opened
|
||||
if ( $_el.closest( Selector.HOVER_MENU ).find( '.' + ClassName.SHOW ).length < 1 ) {
|
||||
nb_.cachedElements.$body.removeClass( ClassName.ALLOW_POINTER_ON_SCROLL );
|
||||
}
|
||||
|
||||
if ( $_child_dropdown.length > 0 ) {
|
||||
$_child_dropdown[0].setAttribute('aria-expanded', 'false');
|
||||
}
|
||||
}
|
||||
}, 30 );
|
||||
|
||||
_debounced_removeOpenClass();
|
||||
}
|
||||
|
||||
function bindEvents() {
|
||||
// april 2020 : is-touch-device class is added on body on the first touch
|
||||
// This way, we can prevent the problem reported on https://github.com/presscustomizr/customizr/issues/1824
|
||||
// ( two touches needed to reveal submenus on touch devices )
|
||||
nb_.cachedElements.$body.on('touchstart', function() {
|
||||
if ( !$(this).hasClass('is-touch-device') ) {
|
||||
$(this).addClass('is-touch-device');
|
||||
}
|
||||
});
|
||||
//BIND
|
||||
nb_.cachedElements.$body
|
||||
.on( 'mouseenter', _dropdown_selector, function(evt) {
|
||||
if ( !nodeBelongsToAMobileMenu.call($(this)) ) {
|
||||
_addOpenClass.call($(this), evt );
|
||||
}
|
||||
})
|
||||
.on( 'mouseleave', _dropdown_selector , function(evt) {
|
||||
if ( !nodeBelongsToAMobileMenu.call($(this)) ) {
|
||||
_removeOpenClass.call($(this), evt );
|
||||
}
|
||||
})
|
||||
.on( 'click', _dropdown_selector, function(evt) {
|
||||
if ( !nodeBelongsToAMobileMenu.call($(this)) ) {
|
||||
_addOpenClass.call($(this), evt );
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// DESKTOP SNAKE
|
||||
dropdownPlacement = function() {
|
||||
var isRTL = 'rtl' === $('html').attr('dir'),
|
||||
doingAnimation = false;
|
||||
|
||||
nb_.cachedElements.$window
|
||||
//on resize trigger Event.PLACE on active dropdowns
|
||||
.on( 'resize', function() {
|
||||
if ( ! doingAnimation ) {
|
||||
doingAnimation = true;
|
||||
window.requestAnimationFrame(function() {
|
||||
//trigger a placement on the open dropdowns
|
||||
$( Selector.SNAKE_PARENTS+'.'+ClassName.SHOW)
|
||||
.trigger(Event.PLACE_ME);
|
||||
doingAnimation = false;
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$( document )
|
||||
.on( Event.PLACE_ALL, function() {
|
||||
//trigger a placement on all
|
||||
$( Selector.SNAKE_PARENTS )
|
||||
.trigger(Event.PLACE_ME);
|
||||
})
|
||||
//snake bound on menu-item shown and place
|
||||
.on( Event.SHOWN+' '+Event.PLACE_ME, Selector.SNAKE_PARENTS, function(evt) {
|
||||
evt.stopPropagation();
|
||||
_do_snake( $(this), evt );
|
||||
});
|
||||
|
||||
|
||||
//snake
|
||||
//$_el is the menu item with children whose submenu will be 'snaked'
|
||||
function _do_snake( $_el, evt ) {
|
||||
if ( !( evt && evt.namespace && DATA_KEY === evt.namespace ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $_this = $_el,
|
||||
$_dropdown = $_this.children( '.'+ClassName.DROPDOWN );
|
||||
|
||||
if ( !$_dropdown.length ) {
|
||||
return;
|
||||
}
|
||||
|
||||
//stage
|
||||
/*
|
||||
* we display the dropdown so that jQuery is able to retrieve exact size and positioning
|
||||
* we also hide whatever overflows the menu item with children whose submenu will be 'snaked'
|
||||
* this to avoid some glitches that would made it lose the focus:
|
||||
* During RTL testing when a menu item with children reached the left edge of the window
|
||||
* it happened that while the submenu was showing (because of the show class added, so not depending on the snake)
|
||||
* this submenu (ul) stole the focus and then released it in a very short time making the mouseleave callback
|
||||
* defined in dropdownMenuOnHover react, hence closing the whole submenu tree.
|
||||
* This might be a false positive, as we don't really test RTL with RTL browsers (only the html direction changes),
|
||||
* but since the 'cure' has no side effects, let's be pedantic!
|
||||
*/
|
||||
$_el.css( 'overflow', 'hidden' );
|
||||
$_dropdown.css( {
|
||||
'zIndex' : '-100',
|
||||
'display' : 'block'
|
||||
});
|
||||
|
||||
_maybe_move( $_dropdown, $_el );
|
||||
|
||||
//unstage
|
||||
$_dropdown.css({
|
||||
'zIndex' : '',
|
||||
'display' : ''
|
||||
});
|
||||
$_el.css( 'overflow', '' );
|
||||
}//_so_snake
|
||||
|
||||
|
||||
function _maybe_move( $_dropdown, $_el ) {
|
||||
var Direction = isRTL ? {
|
||||
//when in RTL we open the submenu by default on the left side
|
||||
_DEFAULT : 'left',
|
||||
_OPPOSITE : 'right'
|
||||
} : {
|
||||
//when in LTR we open the submenu by default on the right side
|
||||
_DEFAULT : 'right',
|
||||
_OPPOSITE : 'left'
|
||||
},
|
||||
ClassName = {
|
||||
OPEN_PREFIX : 'open-',
|
||||
DD_SUBMENU : 'sek-dropdown-submenu',
|
||||
CARET_TITLE_FLIP : 'sek-menu-link__row-reverse',
|
||||
//CARET : 'caret__dropdown-toggler',
|
||||
DROPDOWN : 'sek-dropdown-menu'
|
||||
},
|
||||
_caret_title_maybe_flip = function( $_el, _direction, _old_direction ) {
|
||||
$.each( $_el, function() {
|
||||
var $_el = $(this),
|
||||
$_a = $_el.find( 'a' ).first();
|
||||
|
||||
if ( 1 == $_a.length ) {
|
||||
$_a.toggleClass( ClassName.CARET_TITLE_FLIP, _direction == Direction._OPPOSITE );
|
||||
}
|
||||
});
|
||||
},
|
||||
_setOpenDirection = function( _direction ) {
|
||||
//retrieve the old direction => used to remove the old direction class
|
||||
var _old_direction = _direction == Direction._OPPOSITE ? Direction._DEFAULT : Direction._OPPOSITE;
|
||||
|
||||
//tell the dropdown to open on the direction _direction (hence remove the old direction class)
|
||||
$_dropdown.removeClass( ClassName.OPEN_PREFIX + _old_direction ).addClass( ClassName.OPEN_PREFIX + _direction );
|
||||
if ( $_el.hasClass( ClassName.DD_SUBMENU ) ) {
|
||||
_caret_title_maybe_flip( $_el, _direction, _old_direction );
|
||||
//make the first level submenus caret inherit this
|
||||
_caret_title_maybe_flip( $_dropdown.children( '.' + ClassName.DD_SUBMENU ), _direction, _old_direction );
|
||||
}
|
||||
};
|
||||
|
||||
//snake inheritance
|
||||
if ( $_dropdown.parent().closest( '.'+ClassName.DROPDOWN ).hasClass( ClassName.OPEN_PREFIX + Direction._OPPOSITE ) ) {
|
||||
//open on the opposite direction
|
||||
_setOpenDirection( Direction._OPPOSITE );
|
||||
} else {
|
||||
//open on the default direction
|
||||
_setOpenDirection( Direction._DEFAULT );
|
||||
}
|
||||
|
||||
//let's compute on which side open the dropdown
|
||||
if ( $_dropdown.offset().left + $_dropdown.width() > nb_.cachedElements.$window.width() ) {
|
||||
//open on the left
|
||||
_setOpenDirection( 'left' );
|
||||
} else if ( $_dropdown.offset().left < 0 ) {
|
||||
//open on the right
|
||||
_setOpenDirection( 'right' );
|
||||
}
|
||||
}//_maybe_move
|
||||
};//dropdownPlacement
|
||||
|
||||
//FireAll
|
||||
dropdownMenuOnHover();
|
||||
dropdownPlacement();
|
||||
};//desktopDropdownOnHover
|
||||
|
||||
|
||||
// FIRE DESKTOP MENU METHODS
|
||||
desktopDropdownOnHover();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// MOBILE MENU HAMBURGER BUTTON
|
||||
// handle the mobile hamburger hover effect
|
||||
$( document )
|
||||
.on( 'mouseenter', '.sek-nav-toggler', function(){ $(this).addClass( 'hovering' ); } )
|
||||
.on( 'mouseleave', '.sek-nav-toggler', function(){ $(this).removeClass( 'hovering' ); } )
|
||||
.on( 'show.sek.sekCollapse hide.sek.sekCollapse', '.sek-nav-collapse', function() {
|
||||
$('[data-target="#'+$(this).attr('id')+'"]').removeClass( 'hovering' );
|
||||
nb_.cachedElements.$window.trigger('scroll');
|
||||
});
|
||||
|
||||
|
||||
// MOBILE MENU VISIBILITY
|
||||
toggleMobileMenuVisibility = function() {
|
||||
var EVENT_KEY = ".nbMobMenuBtn",
|
||||
TRANSITION_DURATION = 400,
|
||||
Event = {
|
||||
SHOW: "show" + EVENT_KEY,
|
||||
SHOWN: "shown" + EVENT_KEY,
|
||||
HIDE: "hide" + EVENT_KEY,
|
||||
HIDDEN: "hidden" + EVENT_KEY,
|
||||
CLICK_EVENT: "click" + EVENT_KEY
|
||||
},
|
||||
ClassName = {
|
||||
COLLAPSING: 'sek-collapsing',
|
||||
COLLAPSED: 'sek-collapsed'
|
||||
},
|
||||
Selector = {
|
||||
MM_TOGGLER: '.sek-nav-toggler'
|
||||
};
|
||||
|
||||
// attach click event
|
||||
nb_.cachedElements.$body.on( Event.CLICK_EVENT, Selector.MM_TOGGLER, function (event, params) {
|
||||
// preventDefault only for <a> elements (which change the URL) not inside the collapsible element
|
||||
if (event.currentTarget.tagName === 'A') {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
var $toggler = $(this),
|
||||
//get the data toggle
|
||||
_mob_menu_selector = $toggler.data('target');
|
||||
|
||||
$(_mob_menu_selector).each( function () {
|
||||
var $mobMenuWrapper = $(this),
|
||||
mobMenuIsExpanded = "expanded" === $mobMenuWrapper.attr('data-sek-mm-state'),
|
||||
$maybeHeaderParentEl = $mobMenuWrapper.closest('#nimble-header');
|
||||
|
||||
// console.log('"$mobMenuWrapper ?', $mobMenuWrapper );
|
||||
// console.log('mobMenuIsExpanded ?', mobMenuIsExpanded );
|
||||
|
||||
$mobMenuWrapper.stop()[ mobMenuIsExpanded ? 'slideUp' : 'slideDown' ]({
|
||||
duration: (params && params.close_fast) ? 0 : TRANSITION_DURATION,
|
||||
start : function() {
|
||||
$mobMenuWrapper.addClass(ClassName.COLLAPSING).trigger( mobMenuIsExpanded ? Event.HIDE : Event.SHOW );
|
||||
if ( mobMenuIsExpanded ) {
|
||||
$toggler.addClass( ClassName.COLLAPSED ).attr( 'aria-expanded', 'false' );
|
||||
if ( $maybeHeaderParentEl.length > 0 ) {
|
||||
$maybeHeaderParentEl.removeClass('sek-header-mobile-menu-expanded');
|
||||
}
|
||||
} else {
|
||||
$toggler.removeClass( ClassName.COLLAPSED ).attr( 'aria-expanded', 'true' );
|
||||
$mobMenuWrapper.attr('data-sek-mm-state', 'expanded');
|
||||
if ( $maybeHeaderParentEl.length > 0 ) {
|
||||
$maybeHeaderParentEl.addClass('sek-header-mobile-menu-expanded');
|
||||
}
|
||||
}
|
||||
},
|
||||
complete: function() {
|
||||
// console.log('SOO DATA ?', mobMenuIsExpanded, $mobMenuWrapper.attr('data-sek-mm-state') );
|
||||
if ( mobMenuIsExpanded ) {
|
||||
$mobMenuWrapper.removeClass(ClassName.COLLAPSING).trigger(Event.HIDDEN);
|
||||
$mobMenuWrapper.attr('data-sek-mm-state', 'collapsed');
|
||||
} else {
|
||||
$mobMenuWrapper.removeClass(ClassName.COLLAPSING).trigger(Event.SHOWN);
|
||||
}
|
||||
//remove all the inline style added by the slideUp/Down methods
|
||||
$mobMenuWrapper.css({
|
||||
'display' : '',
|
||||
'paddingTop' : '',
|
||||
'marginTop' : '',
|
||||
'paddingBottom' : '',
|
||||
'marginBottom' : '',
|
||||
'height' : ''
|
||||
});
|
||||
}
|
||||
});//end slideUp/slideDown
|
||||
});//end each
|
||||
});//end attach click event
|
||||
|
||||
// close mobile menu on resize event
|
||||
nb_.cachedElements.$window.on('resize', nb_.debounce( function() {
|
||||
$(Selector.MM_TOGGLER).each(function() {
|
||||
var associated_mob_menu_selector = $(this).data('target');
|
||||
if ( 'true' == $(this).attr( 'aria-expanded' ) ) {
|
||||
if ( $(associated_mob_menu_selector).length && !nodeBelongsToAMobileMenu.call( $(associated_mob_menu_selector) ) ) {
|
||||
$(this).trigger(Event.CLICK_EVENT, {close_fast:true});
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 100) );
|
||||
};//toggleMobileMenuVisibility()
|
||||
|
||||
toggleMobileMenuVisibility();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//////////// COLLAPSIBLE MENU ( janv 2021 )
|
||||
//hueman theme inspired
|
||||
var maybeApplyCollapsibleMenu = function() {
|
||||
var $mobMenuWrapper = this;
|
||||
if ( 'true' == $mobMenuWrapper.data('nb-mm-menu-is-instantiated') )
|
||||
return;
|
||||
|
||||
// Flag so we don't instantiate twice ( typically when previewing)
|
||||
$mobMenuWrapper.data('nb-mm-menu-is-instantiated', 'true');
|
||||
|
||||
//specific class added to this mobile menu which tells its submenus have to be expanded on click (purpose: style)
|
||||
$mobMenuWrapper.addClass( 'nb-collapsible-mobile-menu' );
|
||||
|
||||
var EVENT_KEY = '.nb.submenu',
|
||||
Event = {
|
||||
SHOW : 'show' + EVENT_KEY,
|
||||
HIDE : 'hide' + EVENT_KEY,
|
||||
CLICK : 'mousedown' + EVENT_KEY,
|
||||
FOCUSIN : 'focusin' + EVENT_KEY,
|
||||
FOCUSOUT : 'focusout' + EVENT_KEY
|
||||
},
|
||||
Classname = {
|
||||
DD_TOGGLE_ON_CLICK : 'nb-collapsible-mobile-menu',
|
||||
SHOWN : 'expanded',
|
||||
DD_TOGGLE : 'nb-dd-mm-toggle',
|
||||
DD_TOGGLE_WRAPPER : 'nb-dd-mm-toggle-wrapper',
|
||||
SCREEN_READER : 'screen-reader-text',
|
||||
|
||||
},
|
||||
Selector = {
|
||||
DD_TOGGLE_PARENT : '.menu-item-has-children, .page_item_has_children',
|
||||
CURRENT_ITEM_ANCESTOR : '.current-menu-ancestor',
|
||||
SUBMENU : '.sub-menu'
|
||||
},
|
||||
// Add dropdown toggle that displays child menu items.
|
||||
dropdownToggle = $( '<button />', { 'class': Classname.DD_TOGGLE, 'aria-expanded': false })
|
||||
.append(' <i class="nb-arrow-for-mobile-menu"></i>' )
|
||||
.append( $( '<span />', { 'class': Classname.SCREEN_READER, text: 'Expand' } ) ),
|
||||
dropdownToggleWrapper = $( '<span />', { 'class': Classname.DD_TOGGLE_WRAPPER })
|
||||
.append( dropdownToggle );
|
||||
|
||||
//add dropdown toggler button to each submenu parent item (li)
|
||||
$mobMenuWrapper.find( Selector.DD_TOGGLE_PARENT ).children('a').after( dropdownToggleWrapper );
|
||||
|
||||
// Set the active submenu dropdown toggle button initial state.
|
||||
// $mobMenuWrapper.find( Selector.CURRENT_ITEM_ANCESTOR +'>.'+ Classname.DD_TOGGLE_WRAPPER +' .'+ Classname.DD_TOGGLE )
|
||||
// .addClass( Classname.SHOWN )
|
||||
// .attr( 'aria-expanded', 'true' )
|
||||
// .find( '.'+Classname.SCREEN_READER )
|
||||
// .text( 'Collapse' );
|
||||
|
||||
// Set the active submenu initial state.
|
||||
// $mobMenuWrapper.find( Selector.CURRENT_ITEM_ANCESTOR +'>'+ Selector.SUBMENU ).addClass( Classname.SHOWN );
|
||||
// $mobMenuWrapper.find( Selector.CURRENT_ITEM_ANCESTOR ).addClass( Classname.SHOWN );
|
||||
|
||||
$( $mobMenuWrapper )
|
||||
//when clicking on a menu item whose href is just a "#", let's emulate a click on the caret dropdown
|
||||
.on( Event.CLICK, 'a[href="#"]', function(evt) {
|
||||
if ( !nodeBelongsToAMobileMenu.call( $mobMenuWrapper ) )
|
||||
return;
|
||||
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
$(this).next('.'+Classname.DD_TOGGLE_WRAPPER).find('.'+Classname.DD_TOGGLE).trigger( Event.CLICK );
|
||||
})
|
||||
//when clicking on the toggle button
|
||||
//1) trigger the appropriate "internal" event: hide or show
|
||||
//2) maybe collapse all other open submenus within this menu
|
||||
.on( Event.CLICK, '.'+Classname.DD_TOGGLE, function( e ) {
|
||||
e.preventDefault();
|
||||
|
||||
var $_this = $( this );
|
||||
$_this.trigger( $_this.closest( Selector.DD_TOGGLE_PARENT ).hasClass( Classname.SHOWN ) ? Event.HIDE: Event.SHOW );
|
||||
|
||||
//close other submenus
|
||||
_clearMenus( $_this );
|
||||
})
|
||||
//when the hide/show event is triggered
|
||||
//1) toggle the toggle parent menu item (li) expanded class
|
||||
//2) expand/collapse the submenu(ul)
|
||||
//2.1) on expansion/collapse completed change aria attribute and screenreader text
|
||||
//2.2) toggle the subemnu (ul.sub-menu) expanded class
|
||||
//2.3) clear any inline CSS applied by the slideDown/slideUp jQuery functions : the visibility is completely handled via CSS (expanded class)
|
||||
// we use the aforementioned method only for the animations
|
||||
.on( Event.SHOW+' '+Event.HIDE, '.'+Classname.DD_TOGGLE, function( e ) {
|
||||
var $_this = $( this );
|
||||
|
||||
$_this.closest( Selector.DD_TOGGLE_PARENT ).toggleClass( Classname.SHOWN );
|
||||
|
||||
$_this.closest('.'+Classname.DD_TOGGLE_WRAPPER).next( Selector.SUBMENU )
|
||||
.stop()[Event.SHOW == e.type + '.' + e.namespace ? 'slideDown' : 'slideUp']( {
|
||||
duration: 300,
|
||||
complete: function() {
|
||||
var _to_expand = 'false' === $_this.attr( 'aria-expanded' );
|
||||
$submenu = $(this);
|
||||
|
||||
$_this.attr( 'aria-expanded', _to_expand )
|
||||
.find( '.'+Classname.SCREEN_READER )
|
||||
.text( _to_expand ? 'collapse' : 'expand' );
|
||||
|
||||
$submenu.toggleClass( Classname.SHOWN );
|
||||
//resets remaining inline CSS rules
|
||||
$submenu.css({
|
||||
'display' : '',
|
||||
'paddingTop' : '',
|
||||
'marginTop' : '',
|
||||
'paddingBottom' : '',
|
||||
'marginBottom' : '',
|
||||
'height' : ''
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
// Keyboard navigation ( August 2019 )
|
||||
// https://github.com/presscustomizr/hueman/issues/819
|
||||
//when focusin on a menu item whose href is just a "#", let's emulate a click on the caret dropdown
|
||||
.on( Event.FOCUSIN, 'a[href="#"]', function(evt) {
|
||||
if ( !nodeBelongsToAMobileMenu.call( $mobMenuWrapper ) )
|
||||
return;
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
$(this).next('.'+Classname.DD_TOGGLE_WRAPPER).find('.'+Classname.DD_TOGGLE).trigger( Event.FOCUSIN );
|
||||
})
|
||||
.on( Event.FOCUSOUT, 'a[href="#"]', function(evt) {
|
||||
if ( !nodeBelongsToAMobileMenu.call( $mobMenuWrapper ) )
|
||||
return;
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
nb_.delay( function() {
|
||||
$(this).next('.'+Classname.DD_TOGGLE_WRAPPER).find('.'+Classname.DD_TOGGLE).trigger( Event.FOCUSOUT );
|
||||
}, 250 );
|
||||
})
|
||||
//when focusin on the toggle button
|
||||
//1) trigger the appropriate "internal" event: hide or show
|
||||
//2) maybe collapse all other open submenus within this menu
|
||||
.on( Event.FOCUSIN, '.'+Classname.DD_TOGGLE, function( e ) {
|
||||
e.preventDefault();
|
||||
|
||||
var $_this = $( this );
|
||||
$_this.trigger( Event.SHOW );
|
||||
//close other submenus
|
||||
//_clearMenus( mobMenu, $_this );
|
||||
})
|
||||
.on( Event.FOCUSIN, function( evt ) {
|
||||
evt.preventDefault();
|
||||
if ( $(evt.target).length > 0 ) {
|
||||
$(evt.target).addClass( 'nb-mm-focused');
|
||||
}
|
||||
})
|
||||
.on( Event.FOCUSOUT,function( evt ) {
|
||||
evt.preventDefault();
|
||||
|
||||
var $_this = $( this );
|
||||
nb_.delay( function() {
|
||||
if ( $(evt.target).length > 0 ) {
|
||||
$(evt.target).removeClass( 'nb-mm-focused');
|
||||
}
|
||||
// if ( $mobMenuWrapper.find('.nb-mm-focused').length < 1 ) {
|
||||
// console.log('TOP DO => TRIGGER MOBILE MENU COLLAPSE NOW');
|
||||
// //mobMenu( 'collapsed');
|
||||
// }
|
||||
}, 200 );
|
||||
|
||||
});
|
||||
|
||||
//bs dropdown inspired
|
||||
var _clearMenus = function( $_toggle ) {
|
||||
var _parentsToNotClear = $.makeArray( $_toggle.parents( Selector.DD_TOGGLE_PARENT ) ),
|
||||
_toggles = $.makeArray( $( '.'+Classname.DD_TOGGLE, $mobMenuWrapper ) );
|
||||
|
||||
for (var i = 0; i < _toggles.length; i++) {
|
||||
var _parent = $(_toggles[i]).closest( Selector.DD_TOGGLE_PARENT )[0];
|
||||
|
||||
if (!$(_parent).hasClass( Classname.SHOWN ) || $.inArray(_parent, _parentsToNotClear ) > -1 ){
|
||||
continue;
|
||||
}
|
||||
|
||||
$(_toggles[i]).trigger( Event.HIDE );
|
||||
}
|
||||
};
|
||||
};//maybeApplyCollapsibleMenu()
|
||||
|
||||
|
||||
|
||||
// Instanciate collabsible menu
|
||||
$('.sek-nav-wrap').each( function() {
|
||||
try { maybeApplyCollapsibleMenu.call($(this) ); } catch( er ) {
|
||||
console.log('NB error => collapsible menu', er );
|
||||
}
|
||||
});
|
||||
// When previewing, react to level refresh
|
||||
// This can occur to any level. We listen to the bubbling event on 'body' tag
|
||||
nb_.cachedElements.$body.on('sek-level-refreshed sek-modules-refreshed sek-columns-refreshed sek-section-added', function( evt ){
|
||||
$('.sek-nav-wrap').each( function() {
|
||||
try { maybeApplyCollapsibleMenu.call($(this) ); } catch( er ) {
|
||||
console.log('NB error => collapsible menu', er );
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// How to have a logo plus an hamburger in mobiles on the same line?
|
||||
// => clone the menu module, and append it to the closest sektion-inner wrapper
|
||||
// => this way it will occupy 100% of the width
|
||||
// => and also the clone inherits the style of the module
|
||||
// https://github.com/presscustomizr/nimble-builder/issues/368
|
||||
var mayBeCloneMobileMenu = function() {
|
||||
$( '[data-sek-module-type="czr_menu_module"]' ).find('[data-sek-expand-below="yes"]').each( function() {
|
||||
// make sure we don't do the setup twice when customizing
|
||||
if ( true === $(this).data('sek-setup-menu-mobile-expanded-below-done') )
|
||||
return;
|
||||
|
||||
var $_mobile_menu_module = $(this).closest('[data-sek-module-type="czr_menu_module"]').clone(true),
|
||||
//create a new id for the mobile menu nav collapse that will used by the button toggler too
|
||||
_new_id = $( '.sek-nav-collapse', this ).attr('id') + '-mobile';
|
||||
|
||||
$_mobile_menu_module
|
||||
/// place the mobile menu at the end of this sektion inner
|
||||
.appendTo( $(this).closest( '.sek-sektion-inner' ) )
|
||||
//wrap in a convenient div for styling and targeting
|
||||
.wrap( '<div class="sek-col-base sek-mobile-menu-expanded-below" id="'+_new_id+'-wrapper"></div>');
|
||||
|
||||
// assign the new id to the mobile nav collapse
|
||||
$( '.sek-nav-collapse', '#'+_new_id+'-wrapper' ).attr( 'id', _new_id );
|
||||
// remove the duplicate button
|
||||
$( '.sek-nav-toggler', '#'+_new_id+'-wrapper' ).detach();
|
||||
// update the toggler button so that will now refer to the "cloned" mobile menu
|
||||
$( '.sek-nav-toggler', this ).data( 'target', '#' + _new_id )
|
||||
.attr( 'aria-controls', _new_id );
|
||||
// flag setup done
|
||||
$(this).data('sek-setup-menu-mobile-expanded-below-done', true );
|
||||
});//$.each()
|
||||
};
|
||||
mayBeCloneMobileMenu();
|
||||
|
||||
// When previewing, react to level refresh
|
||||
// This can occur to any level. We listen to the bubbling event on 'body' tag
|
||||
nb_.cachedElements.$body.on('sek-level-refreshed sek-modules-refreshed sek-columns-refreshed sek-section-added', function( evt ){
|
||||
// clean the previously duplicated menu if any
|
||||
$('.sek-mobile-menu-expanded-below').remove();
|
||||
mayBeCloneMobileMenu();
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
});//jQuery( function($){})
|
||||
|
||||
};/////////////// callbackFunc
|
||||
// on 'nb-app-ready', jQuery is loaded
|
||||
nb_.listenTo('nb-app-ready', callbackFunc );
|
||||
}(window, document));
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,573 @@
|
||||
// global sekFrontLocalized, nimbleListenTo
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* SWIPER CAROUSEL implemented for the simple slider module czr_img_slider_module
|
||||
* doc : https://swiperjs.com/api/
|
||||
* dependency : $.fn.nimbleCenterImages()
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
(function(w, d){
|
||||
var callbackFunc = function() {
|
||||
jQuery( function($){
|
||||
var mySwipers = [];
|
||||
var triggerSimpleLoad = function( $_imgs ) {
|
||||
if ( 0 === $_imgs.length )
|
||||
return;
|
||||
|
||||
$_imgs.map( function( _ind, _img ) {
|
||||
$(_img).load( function () {
|
||||
$(_img).trigger('simple_load');
|
||||
});//end load
|
||||
if ( $(_img)[0] && $(_img)[0].complete )
|
||||
$(_img).load();
|
||||
} );//end map
|
||||
};//end of fn
|
||||
|
||||
|
||||
// Each swiper is instantiated with a unique id
|
||||
// so that if we have several instance on the same page, they are totally independant.
|
||||
// If we don't use a unique Id for swiper + navigation buttons, a click on a button, make all slider move synchronously.
|
||||
var doSingleSwiperInstantiation = function() {
|
||||
var $swiperWrapper = $(this), swiperClass = 'sek-swiper' + $swiperWrapper.data('sek-swiper-id');
|
||||
var swiperParams = {
|
||||
// slidesPerView: 3,
|
||||
// spaceBetween: 30,
|
||||
loop : true === $swiperWrapper.data('sek-loop') && true === $swiperWrapper.data('sek-is-multislide'),//Set to true to enable continuous loop mode
|
||||
grabCursor : true === $swiperWrapper.data('sek-is-multislide'),
|
||||
on : {
|
||||
init : function() {
|
||||
// remove the .sek-swiper-loading class from the wrapper => remove the display:none rule
|
||||
$swiperWrapper.removeClass('sek-swiper-loading');
|
||||
|
||||
// remove the css loader
|
||||
$swiperWrapper.parent().find('.sek-css-loader').remove();
|
||||
|
||||
// lazy load the first slider image with Nimble if not done already
|
||||
// the other images will be lazy loaded by swiper if the option is activated
|
||||
// if ( sekFrontLocalized.lazyload_enabled && $.fn.nimbleLazyLoad ) {
|
||||
|
||||
// }
|
||||
$swiperWrapper.trigger('nb-trigger-lazyload');
|
||||
|
||||
// center images with Nimble wizard when needed
|
||||
if ( 'nimble-wizard' === $swiperWrapper.data('sek-image-layout') ) {
|
||||
$swiperWrapper.find('.sek-carousel-img').each( function() {
|
||||
var $_imgsToSimpleLoad = $(this).nimbleCenterImages({
|
||||
enableCentering : 1,
|
||||
zeroTopAdjust: 0,
|
||||
setOpacityWhenCentered : false,//will set the opacity to 1
|
||||
oncustom : [ 'simple_load', 'smartload', 'sek-nimble-refreshed', 'recenter']
|
||||
})
|
||||
//images with src which starts with "data" are our smartload placeholders
|
||||
//we don't want to trigger the simple_load on them
|
||||
//the centering, will be done on the smartload event (see onCustom above)
|
||||
.find( 'img:not([src^="data"])' );
|
||||
|
||||
//trigger the simple load
|
||||
nb_.delay( function() {
|
||||
triggerSimpleLoad( $_imgsToSimpleLoad );
|
||||
}, 50 );
|
||||
});//each()
|
||||
}
|
||||
},// init
|
||||
// make sure slides are always lazyloaded
|
||||
slideChange : function(params) {
|
||||
// when lazy load is active, we want to lazy load the first image of the slider if offscreen
|
||||
// img to be lazy loaded looks like data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
$swiperWrapper.trigger('nb-trigger-lazyload');
|
||||
|
||||
if ( $swiperWrapper.find('[src*="data:image/gif;"]').length > 0 ) {
|
||||
// Make sure we load clean lazy loaded slides on change
|
||||
// for https://github.com/presscustomizr/nimble-builder/issues/677
|
||||
$swiperWrapper.find('[src*="data:image/gif;"]').each( function() {
|
||||
var $img = $(this);
|
||||
if ( $img.attr('data-sek-img-sizes') ) {
|
||||
$img.attr('sizes', $img.attr('data-sek-img-sizes') );
|
||||
$img.removeAttr('data-sek-img-sizes');
|
||||
}
|
||||
if ( $img.attr('data-src') ) {
|
||||
$img.attr('src', $img.attr('data-src') );
|
||||
$img.removeAttr('data-src');
|
||||
}
|
||||
if ( $img.attr('data-sek-src') ) {
|
||||
$img.attr('src', $img.attr('data-sek-src') );
|
||||
$img.removeAttr('data-sek-src');
|
||||
}
|
||||
if ( $img.attr('data-srcset') ) {
|
||||
$img.attr('srcset', $img.attr('data-srcset') );
|
||||
$img.removeAttr('data-srcset');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}//on
|
||||
};
|
||||
|
||||
// AUTOPLAY
|
||||
if ( true === $swiperWrapper.data('sek-autoplay') ) {
|
||||
$.extend( swiperParams, {
|
||||
autoplay : {
|
||||
delay : $swiperWrapper.data('sek-autoplay-delay'),
|
||||
disableOnInteraction : $swiperWrapper.data('sek-pause-on-hover')
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$.extend( swiperParams, {
|
||||
autoplay : {
|
||||
delay : 999999999//<= the autoplay:false doesn't seem to work...
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// NAVIGATION ARROWS && PAGINATION DOTS
|
||||
if ( true === $swiperWrapper.data('sek-is-multislide') ) {
|
||||
var navType = $swiperWrapper.data('sek-navtype');
|
||||
if ( 'arrows_dots' === navType || 'arrows' === navType ) {
|
||||
$.extend( swiperParams, {
|
||||
navigation: {
|
||||
nextEl: '.sek-swiper-next' + $swiperWrapper.data('sek-swiper-id'),
|
||||
prevEl: '.sek-swiper-prev' + $swiperWrapper.data('sek-swiper-id')
|
||||
}
|
||||
});
|
||||
}
|
||||
if ( 'arrows_dots' === navType || 'dots' === navType ) {
|
||||
$.extend( swiperParams, {
|
||||
pagination: {
|
||||
el: '.swiper-pagination' + $swiperWrapper.data('sek-swiper-id'),
|
||||
clickable: true,
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// LAZYLOAD @see https://swiperjs.com/api/#lazy
|
||||
if ( true === $swiperWrapper.data('sek-lazyload') ) {
|
||||
$.extend( swiperParams, {
|
||||
// Disable preloading of all images
|
||||
preloadImages: false,
|
||||
lazy : {
|
||||
// By default, Swiper will load lazy images after transition to this slide, so you may enable this parameter if you need it to start loading of new image in the beginning of transition
|
||||
loadOnTransitionStart : true
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Prepare Pro slider effects
|
||||
var _effect = '',
|
||||
_duration = 300;//default Swiper value
|
||||
|
||||
if ( $swiperWrapper && $swiperWrapper.length > 0 ) {
|
||||
_effect = $swiperWrapper.data('sek-slider-effect');
|
||||
_duration = parseInt( $swiperWrapper.data('sek-effect-duration'), 10 );
|
||||
}
|
||||
if ( _duration > 0 ) {
|
||||
$.extend( swiperParams, {
|
||||
speed : _duration
|
||||
});
|
||||
}
|
||||
if ( nb_.isString( _effect) && 0 !== _effect.length ) {
|
||||
$.extend( swiperParams, {
|
||||
effect: _effect
|
||||
});
|
||||
// See doc here : https://swiperjs.com/swiper-api#fade-effect
|
||||
switch (_effect) {
|
||||
case 'fade':
|
||||
swiperParams[_effect + 'Effect'] = {
|
||||
crossFade: true
|
||||
};
|
||||
break;
|
||||
case 'coverflow':
|
||||
swiperParams[_effect + 'Effect'] = {
|
||||
rotate: 30,
|
||||
slideShadows: false
|
||||
};
|
||||
break;
|
||||
case 'flip':
|
||||
case 'cube':
|
||||
swiperParams[_effect + 'Effect'] = {
|
||||
slideShadows: false
|
||||
};
|
||||
break;
|
||||
case 'cards':
|
||||
swiperParams[_effect + 'Effect'] = {};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mySwipers.push( new Swiper(
|
||||
'.' + swiperClass,//$(this)[0],
|
||||
swiperParams
|
||||
));
|
||||
|
||||
// On Swiper Lazy Loading
|
||||
// https://swiperjs.com/api/#lazy
|
||||
$.each( mySwipers, function( ind, _swiperInstance ){
|
||||
_swiperInstance.on( 'lazyImageReady', function( slideEl, imageEl ) {
|
||||
$(imageEl).trigger('recenter');
|
||||
});
|
||||
_swiperInstance.on( 'lazyImageLoad', function( slideEl, imageEl ) {
|
||||
// clean the extra attribute added when preprocessing for lazy loading
|
||||
var $img = $(imageEl);
|
||||
if ( $img.attr('data-sek-img-sizes') ) {
|
||||
$img.attr('sizes', $img.attr('data-sek-img-sizes') );
|
||||
$img.removeAttr('data-sek-img-sizes');
|
||||
}
|
||||
// add 'recenter' events to fix https://github.com/presscustomizr/nimble-builder/issues/855
|
||||
nb_.delay( function() {$img.trigger('recenter');}, 200 );
|
||||
nb_.delay( function() {$img.trigger('recenter');}, 800 );
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
var doAllSwiperInstanciation = function() {
|
||||
$('.sektion-wrapper').find('[data-sek-swiper-id]').each( function() {
|
||||
doSingleSwiperInstantiation.call($(this));
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
// On custom events
|
||||
nb_.cachedElements.$body.on( 'sek-columns-refreshed sek-modules-refreshed sek-section-added sek-level-refreshed', '[data-sek-level="location"]',
|
||||
function(evt) {
|
||||
if ( 0 !== mySwipers.length ) {
|
||||
$.each( mySwipers, function( ind, _swiperInstance ){
|
||||
_swiperInstance.destroy();
|
||||
});
|
||||
}
|
||||
mySwipers = [];
|
||||
doAllSwiperInstanciation();
|
||||
|
||||
$(this).find('.swiper img').each( function() {
|
||||
$(this).trigger('sek-nimble-refreshed');
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// When the stylesheet is refreshed, update the centering with a custom event
|
||||
// this is needed when setting the custom height of the slider wrapper
|
||||
nb_.cachedElements.$body.on( 'sek-stylesheet-refreshed', '[data-sek-module-type="czr_img_slider_module"]',
|
||||
function() {
|
||||
$(this).find('.swiper img').each( function() {
|
||||
$(this).trigger('sek-nimble-refreshed');
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// on load
|
||||
$('.sektion-wrapper').find('.swiper').each( function() {
|
||||
doAllSwiperInstanciation();
|
||||
});
|
||||
|
||||
|
||||
// Action on click
|
||||
// $( 'body').on( 'click', '[data-sek-module-type="czr_img_slider_module"]', function(evt ) {
|
||||
// // $(this).find('[data-sek-swiper-id]').each( function() {
|
||||
// // $(this).trigger('sek-nimble-refreshed');
|
||||
// // });
|
||||
// }
|
||||
// );
|
||||
|
||||
|
||||
// Behaviour on mouse hover
|
||||
// @seehttps://stackoverflow.com/questions/53028089/swiper-autoplay-stop-the-swiper-when-you-move-the-mouse-cursor-and-start-playba
|
||||
$('.swiper-slide').on('mouseover mouseout', function( evt ) {
|
||||
var swiperInstance = $(this).closest('.swiper')[0].swiper;
|
||||
if ( ! nb_.isUndefined( swiperInstance ) && true === swiperInstance.params.autoplay.disableOnInteraction ) {
|
||||
switch( evt.type ) {
|
||||
case 'mouseover' :
|
||||
swiperInstance.autoplay.stop();
|
||||
break;
|
||||
case 'mouseout' :
|
||||
swiperInstance.autoplay.start();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// When customizing, focus on the currently expanded / edited item
|
||||
// @see CZRItemConstructor in api.czrModuleMap.czr_img_slider_collection_child
|
||||
if ( window.wp && ! nb_.isUndefined( wp.customize ) ) {
|
||||
wp.customize.preview.bind('sek-item-focus', function( params ) {
|
||||
|
||||
var $itemEl = $('[data-sek-item-id="' + params.item_id +'"]', '.swiper').first();
|
||||
if ( 1 > $itemEl.length )
|
||||
return;
|
||||
var $swiperContainer = $itemEl.closest('.swiper');
|
||||
if ( 1 > $swiperContainer.length )
|
||||
return;
|
||||
|
||||
var activeSwiperInstance = $itemEl.closest('.swiper')[0].swiper;
|
||||
|
||||
if ( nb_.isUndefined( activeSwiperInstance ) )
|
||||
return;
|
||||
// we can't rely on internal indexing system of swipe, because it uses duplicate item when infinite looping is enabled
|
||||
// jQuery is our friend
|
||||
var slideIndex = $( '.swiper-slide', $swiperContainer ).index( $itemEl );
|
||||
//http://idangero.us/swiper/api/#methods
|
||||
//mySwiper.slideTo(index, speed, runCallbacks);
|
||||
activeSwiperInstance.slideTo( slideIndex, 100 );
|
||||
});
|
||||
|
||||
// Trigger a window resize when control send a 'sek-preview-device-changed'
|
||||
// wp.customize.preview.bind('sek-preview-device-changed', nb_.debounce( function( params ) {
|
||||
// nb_.cachedElements.$window.trigger('resize');
|
||||
// }, 1000 ));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ===================================================
|
||||
* jquerynimbleCenterImages.js v1.0.0
|
||||
* ( inspired by Customizr theme jQuery plugin )
|
||||
* ===================================================
|
||||
* (c) 2019 Nicolas Guillaume, Nice, France
|
||||
* CenterImages plugin may be freely distributed under the terms of the GNU GPL v2.0 or later license.
|
||||
*
|
||||
* License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* Center images in a specified container
|
||||
*
|
||||
* =================================================== */
|
||||
(function ( $, window ) {
|
||||
//defaults
|
||||
var pluginName = 'nimbleCenterImages',
|
||||
defaults = {
|
||||
enableCentering : true,
|
||||
onresize : true,
|
||||
onInit : true,//<= shall we smartload on init or wait for a custom event, typically smartload ?
|
||||
oncustom : [],//list of event here
|
||||
$containerToListen : null,//<= we might want to listen to custom event trigger to a parent container.Should be a jQuery obj
|
||||
imgSel : 'img',
|
||||
defaultCSSVal : { width : 'auto' , height : 'auto' },
|
||||
leftAdjust : 0,
|
||||
zeroLeftAdjust : 0,
|
||||
topAdjust : 0,
|
||||
zeroTopAdjust : -2,//<= top ajustement for sek-h-centrd
|
||||
useImgAttr:false,//uses the img height and width attributes if not visible (typically used for the customizr slider hidden images)
|
||||
setOpacityWhenCentered : false,//this can be used to hide the image during the time it is centered
|
||||
addCenteredClassWithDelay : 0,//<= a small delay can be required when we rely on the sek-v-centrd or sek-h-centrd css classes to set the opacity for example
|
||||
opacity : 1
|
||||
};
|
||||
|
||||
function Plugin( element, options ) {
|
||||
var self = this;
|
||||
this.container = element;
|
||||
this.options = $.extend( {}, defaults, options) ;
|
||||
this._defaults = defaults;
|
||||
this._name = pluginName;
|
||||
this._customEvt = nb_.isArray(self.options.oncustom) ? self.options.oncustom : self.options.oncustom.split(' ');
|
||||
this.init();
|
||||
}
|
||||
|
||||
//can access this.element and this.option
|
||||
//@return void
|
||||
Plugin.prototype.init = function () {
|
||||
var self = this,
|
||||
_do = function( _event_ ) {
|
||||
_event_ = _event_ || 'init';
|
||||
|
||||
//parses imgs ( if any ) in current container
|
||||
var $_imgs = $( self.options.imgSel , self.container );
|
||||
|
||||
//if no images or centering is not active, only handle the golden ratio on resize event
|
||||
if ( 1 <= $_imgs.length && self.options.enableCentering ) {
|
||||
self._parse_imgs( $_imgs, _event_ );
|
||||
}
|
||||
};
|
||||
|
||||
//fire
|
||||
if ( self.options.onInit ) {
|
||||
_do();
|
||||
}
|
||||
|
||||
//bind the container element with custom events if any
|
||||
//( the images will also be bound )
|
||||
if ( nb_.isArray( self._customEvt ) ) {
|
||||
self._customEvt.map( function( evt ) {
|
||||
var $_containerToListen = ( self.options.$containerToListen instanceof $ && 1 < self.options.$containerToListen.length ) ? self.options.$containerToListen : $( self.container );
|
||||
$_containerToListen.bind( evt, {} , function() {
|
||||
_do( evt );
|
||||
});
|
||||
} );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//@return void
|
||||
Plugin.prototype._parse_imgs = function( $_imgs, _event_ ) {
|
||||
var self = this;
|
||||
$_imgs.each(function ( ind, img ) {
|
||||
var $_img = $(img);
|
||||
self._pre_img_cent( $_img, _event_ );
|
||||
|
||||
// IMG CENTERING FN ON RESIZE ?
|
||||
// Parse Img can be fired several times, so bind once
|
||||
if ( self.options.onresize && ! $_img.data('resize-react-bound' ) ) {
|
||||
$_img.data('resize-react-bound', true );
|
||||
nb_.cachedElements.$window.on('resize', nb_.debounce( function() {
|
||||
self._pre_img_cent( $_img, 'resize');
|
||||
}, 100 ) );
|
||||
}
|
||||
|
||||
});//$_imgs.each()
|
||||
|
||||
// Mainly designed to check if a container is not getting parsed too many times
|
||||
if ( $(self.container).attr('data-img-centered-in-container') ) {
|
||||
var _n = parseInt( $(self.container).attr('data-img-centered-in-container'), 10 ) + 1;
|
||||
$(self.container).attr('data-img-centered-in-container', _n );
|
||||
} else {
|
||||
$(self.container).attr('data-img-centered-in-container', 1 );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//@return void
|
||||
Plugin.prototype._pre_img_cent = function( $_img ) {
|
||||
|
||||
var _state = this._get_current_state( $_img ),
|
||||
self = this,
|
||||
_case = _state.current,
|
||||
_p = _state.prop[_case],
|
||||
_not_p = _state.prop[ 'h' == _case ? 'v' : 'h'],
|
||||
_not_p_dir_val = 'h' == _case ? ( this.options.zeroTopAdjust || 0 ) : ( this.options.zeroLeftAdjust || 0 );
|
||||
|
||||
var _centerImg = function( $_img ) {
|
||||
$_img
|
||||
.css( _p.dim.name , _p.dim.val )
|
||||
.css( _not_p.dim.name , self.options.defaultCSSVal[ _not_p.dim.name ] || 'auto' )
|
||||
.css( _p.dir.name, _p.dir.val ).css( _not_p.dir.name, _not_p_dir_val );
|
||||
|
||||
if ( 0 !== self.options.addCenteredClassWithDelay && nb_.isNumber( self.options.addCenteredClassWithDelay ) ) {
|
||||
nb_.delay( function() {
|
||||
$_img.addClass( _p._class ).removeClass( _not_p._class );
|
||||
}, self.options.addCenteredClassWithDelay );
|
||||
} else {
|
||||
$_img.addClass( _p._class ).removeClass( _not_p._class );
|
||||
}
|
||||
|
||||
// Mainly designed to check if a single image is not getting parsed too many times
|
||||
if ( $_img.attr('data-img-centered') ) {
|
||||
var _n = parseInt( $_img.attr('data-img-centered'), 10 ) + 1;
|
||||
$_img.attr('data-img-centered', _n );
|
||||
} else {
|
||||
$_img.attr('data-img-centered', 1 );
|
||||
}
|
||||
return $_img;
|
||||
};
|
||||
if ( this.options.setOpacityWhenCentered ) {
|
||||
$.when( _centerImg( $_img ) ).done( function( $_img ) {
|
||||
$_img.css( 'opacity', self.options.opacity );
|
||||
});
|
||||
} else {
|
||||
nb_.delay(function() { _centerImg( $_img ); }, 0 );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/********
|
||||
* HELPERS
|
||||
*********/
|
||||
//@return object with initial conditions : { current : 'h' or 'v', prop : {} }
|
||||
Plugin.prototype._get_current_state = function( $_img ) {
|
||||
var c_x = $_img.closest(this.container).outerWidth(),
|
||||
c_y = $(this.container).outerHeight(),
|
||||
i_x = this._get_img_dim( $_img , 'x'),
|
||||
i_y = this._get_img_dim( $_img , 'y'),
|
||||
up_i_x = i_y * c_y !== 0 ? Math.round( i_x / i_y * c_y ) : c_x,
|
||||
up_i_y = i_x * c_x !== 0 ? Math.round( i_y / i_x * c_x ) : c_y,
|
||||
current = 'h';
|
||||
//avoid dividing by zero if c_x or i_x === 0
|
||||
if ( 0 !== c_x * i_x ) {
|
||||
current = ( c_y / c_x ) >= ( i_y / i_x ) ? 'h' : 'v';
|
||||
}
|
||||
|
||||
var prop = {
|
||||
h : {
|
||||
dim : { name : 'height', val : c_y },
|
||||
dir : { name : 'left', val : ( c_x - up_i_x ) / 2 + ( this.options.leftAdjust || 0 ) },
|
||||
_class : 'sek-h-centrd'
|
||||
},
|
||||
v : {
|
||||
dim : { name : 'width', val : c_x },
|
||||
dir : { name : 'top', val : ( c_y - up_i_y ) / 2 + ( this.options.topAdjust || 0 ) },
|
||||
_class : 'sek-v-centrd'
|
||||
}
|
||||
};
|
||||
|
||||
return { current : current , prop : prop };
|
||||
};
|
||||
|
||||
//@return img height or width
|
||||
//uses the img height and width if not visible and set in options
|
||||
Plugin.prototype._get_img_dim = function( $_img, _dim ) {
|
||||
if ( ! this.options.useImgAttr )
|
||||
return 'x' == _dim ? $_img.outerWidth() : $_img.outerHeight();
|
||||
|
||||
if ( $_img.is(":visible") ) {
|
||||
return 'x' == _dim ? $_img.outerWidth() : $_img.outerHeight();
|
||||
} else {
|
||||
if ( 'x' == _dim ){
|
||||
var _width = $_img.originalWidth();
|
||||
return typeof _width === undefined ? 0 : _width;
|
||||
}
|
||||
if ( 'y' == _dim ){
|
||||
var _height = $_img.originalHeight();
|
||||
return typeof _height === undefined ? 0 : _height;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* @params string : ids or classes
|
||||
* @return boolean
|
||||
*/
|
||||
Plugin.prototype._is_selector_allowed = function() {
|
||||
//has requested sel ?
|
||||
if ( ! $(this.container).attr( 'class' ) )
|
||||
return true;
|
||||
|
||||
var _elSels = $(this.container).attr( 'class' ).split(' '),
|
||||
_selsToSkip = [],
|
||||
_filtered = _elSels.filter( function(classe) { return -1 != $.inArray( classe , _selsToSkip ) ;});
|
||||
|
||||
//check if the filtered selectors array with the non authorized selectors is empty or not
|
||||
//if empty => all selectors are allowed
|
||||
//if not, at least one is not allowed
|
||||
return 0 === _filtered.length;
|
||||
};
|
||||
|
||||
|
||||
// prevents against multiple instantiations
|
||||
$.fn[pluginName] = function ( options ) {
|
||||
return this.each(function () {
|
||||
if (!$.data(this, 'plugin_' + pluginName)) {
|
||||
$.data(this, 'plugin_' + pluginName,
|
||||
new Plugin( this, options ));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
})( jQuery, window );
|
||||
};/////////////// callbackFunc
|
||||
|
||||
// When loaded with defer, we can not be sure that jQuery will be loaded before
|
||||
// so let's make sure that we have both the plugin and jQuery loaded
|
||||
nb_.listenTo( 'nb-app-ready', function() {
|
||||
// on 'nb-app-ready', jQuery is loaded
|
||||
nb_.listenTo( 'nb-main-swiper-parsed', callbackFunc );
|
||||
});
|
||||
}(window, document));
|
||||
+1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user