Files
CHIEFSOFT\ameye b114fdf4fa first commit
2023-12-28 16:20:07 -05:00

398 lines
18 KiB
JavaScript

// 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));