1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429 |
- (function($){
- if(typeof FLBuilderLayout != 'undefined') {
- return;
- }
- /**
- * Helper class with generic logic for a builder layout.
- *
- * @class FLBuilderLayout
- * @since 1.0
- */
- FLBuilderLayout = {
- /**
- * Initializes a builder layout.
- *
- * @since 1.0
- * @method init
- */
- init: function()
- {
- // Destroy existing layout events.
- FLBuilderLayout._destroy();
- // Init CSS classes.
- FLBuilderLayout._initClasses();
- // Init backgrounds.
- FLBuilderLayout._initBackgrounds();
- // Init row shape layer height.
- FLBuilderLayout._initRowShapeLayerHeight();
- // Only init if the builder isn't active.
- if ( 0 === $('.fl-builder-edit').length ) {
- // Init module animations.
- FLBuilderLayout._initModuleAnimations();
- // Init anchor links.
- FLBuilderLayout._initAnchorLinks();
- // Init the browser hash.
- FLBuilderLayout._initHash();
- // Init forms.
- FLBuilderLayout._initForms();
- FLBuilderLayout._reorderMenu();
- }
- },
- /**
- * Public method for refreshing Wookmark or MosaicFlow galleries
- * within an element.
- *
- * @since 1.7.4
- * @method refreshGalleries
- */
- refreshGalleries: function( element )
- {
- var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ),
- mfContent = $element.find( '.fl-mosaicflow-content' ),
- wmContent = $element.find( '.fl-gallery' ),
- mfObject = null;
- if ( mfContent ) {
- mfObject = mfContent.data( 'mosaicflow' );
- if ( mfObject ) {
- mfObject.columns = $( [] );
- mfObject.columnsHeights = [];
- mfContent.data( 'mosaicflow', mfObject );
- mfContent.mosaicflow( 'refill' );
- }
- }
- if ( wmContent ) {
- wmContent.trigger( 'refreshWookmark' );
- }
- },
- /**
- * Public method for refreshing Masonry within an element
- *
- * @since 1.8.1
- * @method refreshGridLayout
- */
- refreshGridLayout: function( element )
- {
- var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ),
- msnryContent = $element.find('.masonry');
- if ( msnryContent.length ) {
- msnryContent.masonry('layout');
- }
- },
- /**
- * Public method for reloading BxSlider within an element
- *
- * @since 1.8.1
- * @method reloadSlider
- */
- reloadSlider: function( content )
- {
- var $content = 'undefined' == typeof content ? $('body') : $(content);
- // reload sliders.
- if ($content.find('.bx-viewport > div').length > 0) {
- $.each($content.find('.bx-viewport > div'), function (key, slider) {
- setTimeout(function () {
- $(slider).data('bxSlider').reloadSlider();
- }, 100);
- });
- }
- },
- /**
- * Public method for resizing WP audio player
- *
- * @since 1.8.2
- * @method resizeAudio
- */
- resizeAudio: function( element )
- {
- var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ),
- audioPlayers = $element.find('.wp-audio-shortcode.mejs-audio'),
- player = null,
- mejsPlayer = null,
- rail = null,
- railWidth = 400;
- if ( audioPlayers.length && typeof mejs !== 'undefined' ) {
- audioPlayers.each(function(){
- player = $(this);
- mejsPlayer = mejs.players[player.attr('id')];
- rail = player.find('.mejs-controls .mejs-time-rail');
- var innerMejs = player.find('.mejs-inner'),
- total = player.find('.mejs-controls .mejs-time-total');
- if ( typeof mejsPlayer !== 'undefined' ) {
- railWidth = Math.ceil(player.width() * 0.8);
- if ( innerMejs.length ) {
- rail.css('width', railWidth +'px!important');
- //total.width(rail.width() - 10);
- mejsPlayer.options.autosizeProgress = true;
- // webkit has trouble doing this without a delay
- setTimeout(function () {
- mejsPlayer.setControlsSize();
- }, 50);
- player.find('.mejs-inner').css({
- visibility: 'visible',
- height: 'inherit'
- });
- }
- }
- });
- }
- },
- /**
- * Public method for preloading WP audio player when it's inside the hidden element
- *
- * @since 1.8.2
- * @method preloadAudio
- */
- preloadAudio: function(element)
- {
- var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ),
- contentWrap = $element.closest('.fl-accordion-item'),
- audioPlayers = $element.find('.wp-audio-shortcode.mejs-audio');
- if ( ! contentWrap.hasClass('fl-accordion-item-active') && audioPlayers.find('.mejs-inner').length ) {
- audioPlayers.find('.mejs-inner').css({
- visibility : 'hidden',
- height: 0
- });
- }
- },
- /**
- * Public method for resizing slideshow momdule within the tab
- *
- * @since 1.10.5
- * @method resizeSlideshow
- */
- resizeSlideshow: function(){
- if(typeof YUI !== 'undefined') {
- YUI().use('node-event-simulate', function(Y) {
- Y.one(window).simulate("resize");
- });
- }
- },
- /**
- * Public method for reloading an embedded Google Map within the tabs or hidden element.
- *
- * @since 2.2
- * @method reloadGoogleMap
- */
- reloadGoogleMap: function(element){
- var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ),
- googleMap = $element.find( 'iframe[src*="google.com/maps"]' );
- if ( googleMap.length ) {
- googleMap.attr( 'src', function(i, val) {
- return val;
- });
- }
- },
- /**
- * Unbinds builder layout events.
- *
- * @since 1.0
- * @access private
- * @method _destroy
- */
- _destroy: function()
- {
- var win = $(window);
- win.off('scroll.fl-bg-parallax');
- win.off('resize.fl-bg-video');
- },
- /**
- * Checks to see if the current device has touch enabled.
- *
- * @since 1.0
- * @access private
- * @method _isTouch
- * @return {Boolean}
- */
- _isTouch: function()
- {
- if(('ontouchstart' in window) || (window.DocumentTouch && document instanceof DocumentTouch)) {
- return true;
- }
- return false;
- },
- /**
- * Checks to see if the current device is mobile.
- *
- * @since 1.7
- * @access private
- * @method _isMobile
- * @return {Boolean}
- */
- _isMobile: function()
- {
- return /Mobile|Android|Silk\/|Kindle|BlackBerry|Opera Mini|Opera Mobi|webOS/i.test( navigator.userAgent );
- },
- /**
- * Initializes builder body classes.
- *
- * @since 1.0
- * @access private
- * @method _initClasses
- */
- _initClasses: function()
- {
- var body = $( 'body' ),
- ua = navigator.userAgent;
- // Add the builder body class.
- if ( ! body.hasClass( 'archive' ) && $( '.fl-builder-content-primary' ).length > 0 ) {
- body.addClass('fl-builder');
- }
- // Add the builder touch body class.
- if(FLBuilderLayout._isTouch()) {
- body.addClass('fl-builder-touch');
- }
- // Add the builder mobile body class.
- if(FLBuilderLayout._isMobile()) {
- body.addClass('fl-builder-mobile');
- }
- if ( $(window).width() < FLBuilderLayoutConfig.breakpoints.small ) {
- body.addClass( 'fl-builder-breakpoint-small' );
- }
- if ( $(window).width() > FLBuilderLayoutConfig.breakpoints.small && $(window).width() < FLBuilderLayoutConfig.breakpoints.medium ) {
- body.addClass( 'fl-builder-breakpoint-medium' );
- }
- if ( $(window).width() > FLBuilderLayoutConfig.breakpoints.medium && $(window).width() < FLBuilderLayoutConfig.breakpoints.large ) {
- body.addClass( 'fl-builder-breakpoint-large' );
- }
- if ( $(window).width() > FLBuilderLayoutConfig.breakpoints.large ) {
- body.addClass( 'fl-builder-breakpoint-default' );
- }
- // IE11 body class.
- if ( ua.indexOf( 'Trident/7.0' ) > -1 && ua.indexOf( 'rv:11.0' ) > -1 ) {
- body.addClass( 'fl-builder-ie-11' );
- }
- },
- /**
- * Initializes builder node backgrounds that require
- * additional JavaScript logic such as parallax.
- *
- * @since 1.1.4
- * @access private
- * @method _initBackgrounds
- */
- _initBackgrounds: function()
- {
- var win = $(window);
- // Init parallax backgrounds.
- if($('.fl-row-bg-parallax').length > 0 && !FLBuilderLayout._isMobile()) {
- FLBuilderLayout._scrollParallaxBackgrounds();
- FLBuilderLayout._initParallaxBackgrounds();
- win.on('resize.fl-bg-parallax', FLBuilderLayout._initParallaxBackgrounds);
- win.on('scroll.fl-bg-parallax', FLBuilderLayout._scrollParallaxBackgrounds);
- }
- // Init video backgrounds.
- if($('.fl-bg-video').length > 0) {
- FLBuilderLayout._initBgVideos();
- FLBuilderLayout._resizeBgVideos();
- // Ensure FLBuilderLayout._resizeBgVideos() is only called once on window resize.
- var resizeBGTimer = null;
- win.on('resize.fl-bg-video', function(e){
- clearTimeout( resizeBGTimer );
- resizeBGTimer = setTimeout(function() {
- FLBuilderLayout._resizeBgVideos(e);
- }, 100 );
- });
- }
- },
- /**
- * Initializes all parallax backgrounds in a layout.
- *
- * @since 1.1.4
- * @access private
- * @method _initParallaxBackgrounds
- */
- _initParallaxBackgrounds: function()
- {
- $('.fl-row-bg-parallax').each(FLBuilderLayout._initParallaxBackground);
- },
- /**
- * Initializes a single parallax background.
- *
- * @since 1.1.4
- * @access private
- * @method _initParallaxBackgrounds
- */
- _initParallaxBackground: function()
- {
- var row = $(this),
- content = row.find('> .fl-row-content-wrap'),
- winWidth = $(window).width(),
- screenSize = '',
- imageSrc = {
- default: '',
- medium: '',
- responsive: '',
- };
- imageSrc.default = row.data('parallax-image') || '';
- imageSrc.medium = row.data('parallax-image-medium') || imageSrc.default;
- imageSrc.responsive = row.data('parallax-image-responsive') || imageSrc.medium;
- if (winWidth > FLBuilderLayoutConfig.breakpoints.medium) {
- screenSize = 'default';
- } else if (winWidth > FLBuilderLayoutConfig.breakpoints.small && winWidth <= FLBuilderLayoutConfig.breakpoints.medium ) {
- screenSize = 'medium';
- } else if (winWidth <= FLBuilderLayoutConfig.breakpoints.small) {
- screenSize = 'responsive';
- }
- content.css('background-image', 'url(' + imageSrc[screenSize] + ')');
- row.data('current-image-loaded', screenSize );
- },
- /**
- * Fires when the window is scrolled to adjust
- * parallax backgrounds.
- *
- * @since 1.1.4
- * @access private
- * @method _scrollParallaxBackgrounds
- */
- _scrollParallaxBackgrounds: function()
- {
- $('.fl-row-bg-parallax').each(FLBuilderLayout._scrollParallaxBackground);
- },
- /**
- * Fires when the window is scrolled to adjust
- * a single parallax background.
- *
- * @since 1.1.4
- * @access private
- * @method _scrollParallaxBackground
- */
- _scrollParallaxBackground: function()
- {
- var win = $(window),
- row = $(this),
- content = row.find('> .fl-row-content-wrap'),
- speed = row.data('parallax-speed'),
- offset = content.offset(),
- yPos = -((win.scrollTop() - offset.top) / speed),
- initialOffset = ( row.data('parallax-offset') != null ) ? row.data('parallax-offset') : 0,
- totalOffset = yPos - initialOffset;
- content.css('background-position', 'center ' + totalOffset + 'px');
- },
- /**
- * Initializes all video backgrounds.
- *
- * @since 1.6.3.3
- * @access private
- * @method _initBgVideos
- */
- _initBgVideos: function()
- {
- $('.fl-bg-video').each(FLBuilderLayout._initBgVideo);
- },
- /**
- * Initializes a video background.
- *
- * @since 1.6.3.3
- * @access private
- * @method _initBgVideo
- */
- _initBgVideo: function()
- {
- var wrap = $( this ),
- width = wrap.data( 'width' ),
- height = wrap.data( 'height' ),
- mp4 = wrap.data( 'mp4' ),
- youtube = wrap.data( 'youtube'),
- vimeo = wrap.data( 'vimeo'),
- mp4Type = wrap.data( 'mp4-type' ),
- webm = wrap.data( 'webm' ),
- webmType = wrap.data( 'webm-type' ),
- fallback = wrap.data( 'fallback' ),
- loaded = wrap.data( 'loaded' ),
- videoMobile = wrap.data( 'video-mobile' ),
- fallbackTag = '',
- videoTag = null,
- mp4Tag = null,
- webmTag = null;
- // Return if the video has been loaded for this row.
- if ( loaded ) {
- return;
- }
- videoTag = $( '<video autoplay loop muted playsinline></video>' );
- /**
- * Add poster image (fallback image)
- */
- if( 'undefined' != typeof fallback && '' != fallback ) {
- videoTag.attr( 'poster', 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' )
- videoTag.css({
- backgroundImage: 'url("' + fallback + '")',
- backgroundColor: 'transparent',
- backgroundRepeat: 'no-repeat',
- backgroundSize: 'cover',
- backgroundPosition: 'center center',
- })
- }
- // MP4 Source Tag
- if ( 'undefined' != typeof mp4 && '' != mp4 ) {
- mp4Tag = $( '<source />' );
- mp4Tag.attr( 'src', mp4 );
- mp4Tag.attr( 'type', mp4Type );
- videoTag.append( mp4Tag );
- }
- // WebM Source Tag
- if ( 'undefined' != typeof webm && '' != webm ) {
- webmTag = $( '<source />' );
- webmTag.attr( 'src', webm );
- webmTag.attr( 'type', webmType );
- videoTag.append( webmTag );
- }
- // This is either desktop, or mobile is enabled.
- if ( ! FLBuilderLayout._isMobile() || ( FLBuilderLayout._isMobile() && "yes" == videoMobile ) ) {
- if ( 'undefined' != typeof youtube ) {
- FLBuilderLayout._initYoutubeBgVideo.apply( this );
- }
- else if ( 'undefined' != typeof vimeo ) {
- FLBuilderLayout._initVimeoBgVideo.apply( this );
- }
- else {
- wrap.append( videoTag );
- }
- }
- else {
- // if we are here, it means we are on mobile and NO is set so remove video src and use fallback
- videoTag.attr('src', '')
- wrap.append( videoTag );
- }
- // Mark this video as loaded.
- wrap.data('loaded', true);
- },
- /**
- * Initializes Youtube video background
- *
- * @since 1.9
- * @access private
- * @method _initYoutubeBgVideo
- */
- _initYoutubeBgVideo: function()
- {
- var playerWrap = $(this),
- videoId = playerWrap.data('video-id'),
- videoPlayer = playerWrap.find('.fl-bg-video-player'),
- enableAudio = playerWrap.data('enable-audio'),
- audioButton = playerWrap.find('.fl-bg-video-audio'),
- startTime = 'undefined' !== typeof playerWrap.data('start') ? playerWrap.data('start') : 0,
- startTime = 'undefined' !== typeof playerWrap.data('t') && startTime === 0 ? playerWrap.data('t') : startTime,
- endTime = 'undefined' !== typeof playerWrap.data('end') ? playerWrap.data('end') : 0,
- loop = 'undefined' !== typeof playerWrap.data('loop') ? playerWrap.data('loop') : 1,
- stateCount = 0,
- player,fallback_showing;
- if ( videoId ) {
- fallback = playerWrap.data('fallback') || false
- if( fallback ) {
- playerWrap.find('iframe').remove()
- fallbackTag = $( '<div></div>' );
- fallbackTag.addClass( 'fl-bg-video-fallback' );
- fallbackTag.css( 'background-image', 'url(' + playerWrap.data('fallback') + ')' );
- fallbackTag.css( 'background-size', 'cover' );
- fallbackTag.css( 'transition', 'background-image 1s')
- playerWrap.append( fallbackTag );
- fallback_showing = true;
- }
- FLBuilderLayout._onYoutubeApiReady( function( YT ) {
- setTimeout( function() {
- player = new YT.Player( videoPlayer[0], {
- videoId: videoId,
- events: {
- onReady: function(event) {
- if ( "no" === enableAudio || FLBuilderLayout._isMobile() ) {
- event.target.mute();
- }
- else if ( "yes" === enableAudio && event.target.isMuted ) {
- event.target.unMute();
- }
- // Store an instance to a parent
- playerWrap.data('YTPlayer', player);
- FLBuilderLayout._resizeYoutubeBgVideo.apply(playerWrap);
- // Queue the video.
- event.target.playVideo();
- if ( audioButton.length > 0 && ! FLBuilderLayout._isMobile() ) {
- audioButton.on( 'click', {button: audioButton, player: player}, FLBuilderLayout._toggleBgVideoAudio );
- }
- },
- onStateChange: function( event ) {
- if ( event.data === 1 ) {
- if ( fallback_showing ) {
- $( '.fl-bg-video-fallback' ).css( 'background-image', 'url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)' )
- }
- }
- // Manual check if video is not playable in some browsers.
- // StateChange order: [-1, 3, -1]
- if ( stateCount < 4 ) {
- stateCount++;
- }
- // Comply with the audio policy in some browsers like Chrome and Safari.
- if ( stateCount > 1 && (-1 === event.data || 2 === event.data) && "yes" === enableAudio ) {
- player.mute();
- player.playVideo();
- audioButton.show();
- }
- if ( event.data === YT.PlayerState.ENDED && 1 === loop ) {
- if ( startTime > 0 ) {
- player.seekTo( startTime );
- }
- else {
- player.playVideo();
- }
- }
- },
- onError: function(event) {
- console.info('YT Error: ' + event.data)
- FLBuilderLayout._onErrorYoutubeVimeo(playerWrap)
- }
- },
- playerVars: {
- playsinline: FLBuilderLayout._isMobile() ? 1 : 0,
- controls: 0,
- showinfo: 0,
- rel : 0,
- start: startTime,
- end: endTime,
- }
- } );
- }, 1 );
- } );
- }
- },
- /**
- * On youtube or vimeo error show the fallback image if available.
- * @since 2.0.7
- */
- _onErrorYoutubeVimeo: function(playerWrap) {
- fallback = playerWrap.data('fallback') || false
- if( ! fallback ) {
- return false;
- }
- playerWrap.find('iframe').remove()
- fallbackTag = $( '<div></div>' );
- fallbackTag.addClass( 'fl-bg-video-fallback' );
- fallbackTag.css( 'background-image', 'url(' + playerWrap.data('fallback') + ')' );
- playerWrap.append( fallbackTag );
- },
- /**
- * Check if Youtube API has been downloaded
- *
- * @since 1.9
- * @access private
- * @method _onYoutubeApiReady
- * @param {Function} callback Method to call when YT API has been loaded
- */
- _onYoutubeApiReady: function( callback ) {
- if ( window.YT && YT.loaded ) {
- callback( YT );
- } else {
- // If not ready check again by timeout..
- setTimeout( function() {
- FLBuilderLayout._onYoutubeApiReady( callback );
- }, 350 );
- }
- },
- /**
- * Initializes Vimeo video background
- *
- * @since 1.9
- * @access private
- * @method _initVimeoBgVideo
- */
- _initVimeoBgVideo: function()
- {
- var playerWrap = $(this),
- videoId = playerWrap.data('video-id'),
- videoPlayer = playerWrap.find('.fl-bg-video-player'),
- enableAudio = playerWrap.data('enable-audio'),
- audioButton = playerWrap.find('.fl-bg-video-audio'),
- player,
- width = playerWrap.outerWidth(),
- ua = navigator.userAgent;
- if ( typeof Vimeo !== 'undefined' && videoId ) {
- player = new Vimeo.Player(videoPlayer[0], {
- id : videoId,
- loop : true,
- title : false,
- portrait : false,
- background : true,
- autopause : false,
- muted : true
- });
- playerWrap.data('VMPlayer', player);
- if ( "no" === enableAudio ) {
- player.setVolume(0);
- }
- else if ("yes" === enableAudio ) {
- // Chrome, Safari, Firefox have audio policy restrictions for autoplay videos.
- if ( ua.indexOf("Safari") > -1 || ua.indexOf("Chrome") > -1 || ua.indexOf("Firefox") > -1 ) {
- player.setVolume(0);
- audioButton.show();
- }
- else {
- player.setVolume(1);
- }
- }
- player.play().catch(function(error) {
- FLBuilderLayout._onErrorYoutubeVimeo(playerWrap)
- });
- if ( audioButton.length > 0 ) {
- audioButton.on( 'click', {button: audioButton, player: player}, FLBuilderLayout._toggleBgVideoAudio );
- }
- }
- },
- /**
- * Mute / unmute audio on row's video background.
- * It works for both Youtube and Vimeo.
- *
- * @since 2.1.3
- * @access private
- * @method _toggleBgVideoAudio
- * @param {Object} e Method arguments
- */
- _toggleBgVideoAudio: function( e ) {
- var player = e.data.player,
- control = e.data.button.find('.fl-audio-control');
- if ( control.hasClass( 'fa-volume-off' ) ) {
- // Unmute
- control
- .removeClass( 'fa-volume-off' )
- .addClass( 'fa-volume-up' );
- e.data.button.find( '.fa-times' ).hide();
- if ( 'function' === typeof player.unMute ) {
- player.unMute();
- }
- else {
- player.setVolume( 1 );
- }
- }
- else {
- // Mute
- control
- .removeClass( 'fa-volume-up' )
- .addClass( 'fa-volume-off' );
- e.data.button.find( '.fa-times' ).show();
- if ( 'function' === typeof player.unMute ) {
- player.mute();
- }
- else {
- player.setVolume( 0 );
- }
- }
- },
- /**
- * Fires when there is an error loading a video
- * background source and shows the fallback.
- *
- * @since 1.6.3.3
- * @access private
- * @method _videoBgSourceError
- * @param {Object} e An event object
- * @deprecated 2.0.3
- */
- _videoBgSourceError: function( e )
- {
- var source = $( e.target ),
- wrap = source.closest( '.fl-bg-video' ),
- vid = wrap.find( 'video' ),
- fallback = wrap.data( 'fallback' ),
- fallbackTag = '';
- source.remove();
- if ( vid.find( 'source' ).length ) {
- // Don't show the fallback if we still have other sources to check.
- return;
- } else if ( '' !== fallback ) {
- fallbackTag = $( '<div></div>' );
- fallbackTag.addClass( 'fl-bg-video-fallback' );
- fallbackTag.css( 'background-image', 'url(' + fallback + ')' );
- wrap.append( fallbackTag );
- vid.remove();
- }
- },
- /**
- * Fires when the window is resized to resize
- * all video backgrounds.
- *
- * @since 1.1.4
- * @access private
- * @method _resizeBgVideos
- */
- _resizeBgVideos: function()
- {
- $('.fl-bg-video').each( function() {
- FLBuilderLayout._resizeBgVideo.apply( this );
- if ( $( this ).parent().find( 'img' ).length > 0 ) {
- $( this ).parent().imagesLoaded( $.proxy( FLBuilderLayout._resizeBgVideo, this ) );
- }
- } );
- },
- /**
- * Fires when the window is resized to resize
- * a single video background.
- *
- * @since 1.1.4
- * @access private
- * @method _resizeBgVideo
- */
- _resizeBgVideo: function()
- {
- if ( 0 === $( this ).find( 'video' ).length && 0 === $( this ).find( 'iframe' ).length ) {
- return;
- }
- var wrap = $(this),
- wrapHeight = wrap.outerHeight(),
- wrapWidth = wrap.outerWidth(),
- vid = wrap.find('video'),
- vidHeight = wrap.data('height'),
- vidWidth = wrap.data('width'),
- newWidth = wrapWidth,
- newHeight = Math.round(vidHeight * wrapWidth/vidWidth),
- newLeft = 0,
- newTop = 0,
- iframe = wrap.find('iframe'),
- isRowFullHeight = $(this).closest('.fl-row-bg-video').hasClass('fl-row-full-height'),
- vidCSS = {
- top: '50%',
- left: '50%',
- transform: 'translate(-50%,-50%)',
- };
- if ( vid.length ) {
- if(vidHeight === '' || typeof vidHeight === 'undefined' || vidWidth === '' || typeof vidWidth === 'undefined') {
- vid.css({
- 'left' : '0px',
- 'top' : '0px',
- 'width' : newWidth + 'px'
- });
- // Try to set the actual video dimension on 'loadedmetadata' when using URL as video source
- vid.on('loadedmetadata', FLBuilderLayout._resizeOnLoadedMeta);
- return;
- }
- if ( ! isRowFullHeight ) {
- if ( newHeight < wrapHeight ) {
- newHeight = wrapHeight;
- newLeft = -((newWidth - wrapWidth) / 2);
- newWidth = vidHeight ? Math.round(vidWidth * wrapHeight/vidHeight) : newWidth;
- }
- else {
- newTop = -((newHeight - wrapHeight)/2);
- }
- vidCSS = {
- left : newLeft + 'px',
- top : newTop + 'px',
- height : newHeight + 'px',
- width : newWidth + 'px',
- }
- }
- vid.css( vidCSS );
- }
- else if ( iframe.length ) {
- // Resize Youtube video player within iframe tag
- if ( typeof wrap.data('youtube') !== 'undefined' ) {
- FLBuilderLayout._resizeYoutubeBgVideo.apply(this);
- }
- }
- },
- /**
- * Fires when video meta has been loaded.
- * This will be Triggered when width/height attributes were not specified during video background resizing.
- *
- * @since 1.8.5
- * @access private
- * @method _resizeOnLoadedMeta
- */
- _resizeOnLoadedMeta: function(){
- var video = $(this),
- wrapHeight = video.parent().outerHeight(),
- wrapWidth = video.parent().outerWidth(),
- vidWidth = video[0].videoWidth,
- vidHeight = video[0].videoHeight,
- newHeight = Math.round(vidHeight * wrapWidth/vidWidth),
- newWidth = wrapWidth,
- newLeft = 0,
- newTop = 0;
- if(newHeight < wrapHeight) {
- newHeight = wrapHeight;
- newWidth = Math.round(vidWidth * wrapHeight/vidHeight);
- newLeft = -((newWidth - wrapWidth)/2);
- }
- else {
- newTop = -((newHeight - wrapHeight)/2);
- }
- video.parent().data('width', vidWidth);
- video.parent().data('height', vidHeight);
- video.css({
- 'left' : newLeft + 'px',
- 'top' : newTop + 'px',
- 'width' : newWidth + 'px',
- 'height' : newHeight + 'px'
- });
- },
- /**
- * Fires when the window is resized to resize
- * a single Youtube video background.
- *
- * @since 1.9
- * @access private
- * @method _resizeYoutubeBgVideo
- */
- _resizeYoutubeBgVideo: function()
- {
- var wrap = $(this),
- wrapWidth = wrap.outerWidth(),
- wrapHeight = wrap.outerHeight(),
- player = wrap.data('YTPlayer'),
- video = player ? player.getIframe() : null,
- aspectRatioSetting = '16:9', // Medium
- aspectRatioArray = aspectRatioSetting.split( ':' ),
- aspectRatio = aspectRatioArray[0] / aspectRatioArray[1],
- ratioWidth = wrapWidth / aspectRatio,
- ratioHeight = wrapHeight * aspectRatio,
- isWidthFixed = wrapWidth / wrapHeight > aspectRatio,
- width = isWidthFixed ? wrapWidth : ratioHeight,
- height = isWidthFixed ? ratioWidth : wrapHeight;
- if ( video ) {
- $(video).width( width ).height( height );
- }
- },
- /**
- * Initializes module animations.
- *
- * @since 1.1.9
- * @access private
- * @method _initModuleAnimations
- */
- _initModuleAnimations: function()
- {
- if(typeof jQuery.fn.waypoint !== 'undefined') {
- $('.fl-animation').each( function() {
- var node = $( this ),
- nodeTop = node.offset().top,
- winHeight = $( window ).height(),
- bodyHeight = $( 'body' ).height(),
- waypoint = FLBuilderLayoutConfig.waypoint,
- offset = '80%';
- if ( typeof waypoint.offset !== undefined ) {
- offset = FLBuilderLayoutConfig.waypoint.offset + '%';
- }
- if ( bodyHeight - nodeTop < winHeight * 0.2 ) {
- offset = '100%';
- }
- node.waypoint({
- offset: offset,
- handler: FLBuilderLayout._doModuleAnimation
- });
- } );
- }
- },
- /**
- * Runs a module animation.
- *
- * @since 1.1.9
- * @access private
- * @method _doModuleAnimation
- */
- _doModuleAnimation: function()
- {
- var module = 'undefined' == typeof this.element ? $(this) : $(this.element),
- delay = parseFloat(module.data('animation-delay')),
- duration = parseFloat(module.data('animation-duration'));
- if ( ! isNaN( duration ) ) {
- module.css( 'animation-duration', duration + 's' );
- }
- if(!isNaN(delay) && delay > 0) {
- setTimeout(function(){
- module.addClass('fl-animated');
- }, delay * 1000);
- } else {
- setTimeout(function(){
- module.addClass('fl-animated');
- }, 1);
- }
- },
- /**
- * Opens a tab or accordion item if the browser hash is set
- * to the ID of one on the page.
- *
- * @since 1.6.0
- * @access private
- * @method _initHash
- */
- _initHash: function()
- {
- var hash = window.location.hash.replace( '#', '' ).split( '/' ).shift(),
- element = null,
- tabs = null,
- responsiveLabel = null,
- tabIndex = null,
- label = null;
- if ( '' !== hash ) {
- try {
- element = $( '#' + hash );
- if ( element.length > 0 ) {
- if ( element.hasClass( 'fl-accordion-item' ) ) {
- setTimeout( function() {
- element.find( '.fl-accordion-button' ).trigger( 'click' );
- }, 100 );
- }
- if ( element.hasClass( 'fl-tabs-panel' ) ) {
- setTimeout( function() {
- tabs = element.closest( '.fl-tabs' );
- responsiveLabel = element.find( '.fl-tabs-panel-label' );
- tabIndex = responsiveLabel.data( 'index' );
- label = tabs.find( '.fl-tabs-labels .fl-tabs-label[data-index=' + tabIndex + ']' );
- label[0].click();
- FLBuilderLayout._scrollToElement(element);
- }, 100 );
- }
- }
- }
- catch( e ) {}
- }
- },
- /**
- * Initializes all anchor links on the page for smooth scrolling.
- *
- * @since 1.4.9
- * @access private
- * @method _initAnchorLinks
- */
- _initAnchorLinks: function()
- {
- $( 'a' ).each( FLBuilderLayout._initAnchorLink );
- },
- /**
- * Initializes a single anchor link for smooth scrolling.
- *
- * @since 1.4.9
- * @access private
- * @method _initAnchorLink
- */
- _initAnchorLink: function()
- {
- var link = $( this ),
- href = link.attr( 'href' ),
- loc = window.location,
- id = null,
- element = null,
- flNode = false;
- if ( 'undefined' != typeof href && href.indexOf( '#' ) > -1 && link.closest('svg').length < 1 ) {
- if ( loc.pathname.replace( /^\//, '' ) == this.pathname.replace( /^\//, '' ) && loc.hostname == this.hostname ) {
- try {
- id = href.split( '#' ).pop();
- // If there is no ID then we have nowhere to look
- // Fixes a quirk in jQuery and FireFox
- if( ! id ) {
- return;
- }
- element = $( '#' + id );
- if ( element.length > 0 ) {
- flNode = element.hasClass( 'fl-row' ) || element.hasClass( 'fl-col' ) || element.hasClass( 'fl-module' );
- if ( !element.hasClass( 'fl-no-scroll' ) && ( link.hasClass( 'fl-scroll-link' ) || flNode ) ) {
- $( link ).on( 'click', FLBuilderLayout._scrollToElementOnLinkClick );
- }
- if ( element.hasClass( 'fl-accordion-item' ) ) {
- $( link ).on( 'click', FLBuilderLayout._scrollToAccordionOnLinkClick );
- }
- if ( element.hasClass( 'fl-tabs-panel' ) ) {
- $( link ).on( 'click', FLBuilderLayout._scrollToTabOnLinkClick );
- }
- }
- }
- catch( e ) {}
- }
- }
- },
- /**
- * Scrolls to an element when an anchor link is clicked.
- *
- * @since 1.4.9
- * @access private
- * @method _scrollToElementOnLinkClick
- * @param {Object} e An event object.
- * @param {Function} callback A function to call when the scroll is complete.
- */
- _scrollToElementOnLinkClick: function( e, callback )
- {
- var element = $( '#' + $( this ).attr( 'href' ).split( '#' ).pop() );
- FLBuilderLayout._scrollToElement( element, callback );
- e.preventDefault();
- },
- /**
- * Scrolls to an element.
- *
- * @since 1.6.4.5
- * @access private
- * @method _scrollToElement
- * @param {Object} element The element to scroll to.
- * @param {Function} callback A function to call when the scroll is complete.
- */
- _scrollToElement: function( element, callback )
- {
- var config = FLBuilderLayoutConfig.anchorLinkAnimations,
- dest = 0,
- win = $( window ),
- doc = $( document );
- if ( element.length > 0 ) {
- if ( 'fixed' === element.css('position') || 'fixed' === element.parent().css('position') ) {
- dest = element.position().top;
- }
- else if ( element.offset().top > doc.height() - win.height() ) {
- dest = doc.height() - win.height();
- }
- else {
- dest = element.offset().top - config.offset;
- }
- $( 'html, body' ).animate( { scrollTop: dest }, config.duration, config.easing, function() {
- if ( 'undefined' != typeof callback ) {
- callback();
- }
- if ( undefined != element.attr( 'id' ) ) {
- if ( history.pushState ) {
- history.pushState( null, null, '#' + element.attr( 'id' ) );
- }
- else {
- window.location.hash = element.attr( 'id' );
- }
- }
- } );
- }
- },
- /**
- * Scrolls to an accordion item when a link is clicked.
- *
- * @since 1.5.9
- * @access private
- * @method _scrollToAccordionOnLinkClick
- * @param {Object} e An event object.
- */
- _scrollToAccordionOnLinkClick: function( e )
- {
- var element = $( '#' + $( this ).attr( 'href' ).split( '#' ).pop() );
- if ( element.length > 0 ) {
- var callback = function() {
- if ( element ) {
- element.find( '.fl-accordion-button' ).trigger( 'click' );
- element = false;
- }
- };
- FLBuilderLayout._scrollToElementOnLinkClick.call( this, e, callback );
- }
- },
- /**
- * Scrolls to a tab panel when a link is clicked.
- *
- * @since 1.5.9
- * @access private
- * @method _scrollToTabOnLinkClick
- * @param {Object} e An event object.
- */
- _scrollToTabOnLinkClick: function( e )
- {
- var element = $( '#' + $( this ).attr( 'href' ).split( '#' ).pop() ),
- tabs = null,
- label = null,
- responsiveLabel = null;
- if ( element.length > 0 ) {
- tabs = element.closest( '.fl-tabs' );
- responsiveLabel = element.find( '.fl-tabs-panel-label' );
- tabIndex = responsiveLabel.data( 'index' );
- label = tabs.find( '.fl-tabs-labels .fl-tabs-label[data-index=' + tabIndex + ']' );
- if ( responsiveLabel.is( ':visible' ) ) {
- var callback = function() {
- if ( element ) {
- responsiveLabel.trigger( $.Event( 'click', { which: 1 } ) );
- }
- };
- FLBuilderLayout._scrollToElementOnLinkClick.call( this, e, callback );
- }
- else {
- label[0].click();
- FLBuilderLayout._scrollToElement( element );
- }
- e.preventDefault();
- }
- },
- /**
- * Initializes all builder forms on a page.
- *
- * @since 1.5.4
- * @access private
- * @method _initForms
- */
- _initForms: function()
- {
- if ( ! FLBuilderLayout._hasPlaceholderSupport ) {
- $( '.fl-form-field input' ).each( FLBuilderLayout._initFormFieldPlaceholderFallback );
- }
- $( '.fl-form-field input' ).on( 'focus', FLBuilderLayout._clearFormFieldError );
- },
- /**
- * Checks to see if the current device has HTML5
- * placeholder support.
- *
- * @since 1.5.4
- * @access private
- * @method _hasPlaceholderSupport
- * @return {Boolean}
- */
- _hasPlaceholderSupport: function()
- {
- var input = document.createElement( 'input' );
- return 'undefined' != input.placeholder;
- },
- /**
- * Initializes the fallback for when placeholders aren't supported.
- *
- * @since 1.5.4
- * @access private
- * @method _initFormFieldPlaceholderFallback
- */
- _initFormFieldPlaceholderFallback: function()
- {
- var field = $( this ),
- val = field.val(),
- placeholder = field.attr( 'placeholder' );
- if ( 'undefined' != placeholder && '' === val ) {
- field.val( placeholder );
- field.on( 'focus', FLBuilderLayout._hideFormFieldPlaceholderFallback );
- field.on( 'blur', FLBuilderLayout._showFormFieldPlaceholderFallback );
- }
- },
- /**
- * Hides a fallback placeholder on focus.
- *
- * @since 1.5.4
- * @access private
- * @method _hideFormFieldPlaceholderFallback
- */
- _hideFormFieldPlaceholderFallback: function()
- {
- var field = $( this ),
- val = field.val(),
- placeholder = field.attr( 'placeholder' );
- if ( val == placeholder ) {
- field.val( '' );
- }
- },
- /**
- * Shows a fallback placeholder on blur.
- *
- * @since 1.5.4
- * @access private
- * @method _showFormFieldPlaceholderFallback
- */
- _showFormFieldPlaceholderFallback: function()
- {
- var field = $( this ),
- val = field.val(),
- placeholder = field.attr( 'placeholder' );
- if ( '' === val ) {
- field.val( placeholder );
- }
- },
- /**
- * Clears a form field error message.
- *
- * @since 1.5.4
- * @access private
- * @method _clearFormFieldError
- */
- _clearFormFieldError: function()
- {
- var field = $( this );
- field.removeClass( 'fl-form-error' );
- field.siblings( '.fl-form-error-message' ).hide();
- },
- /**
- * Init Row Shape Layer's height.
- *
- * @since 2.5.3
- * @access private
- * @method _initRowShapeLayerHeight
- */
- _initRowShapeLayerHeight: function () {
- FLBuilderLayout._adjustRowShapeLayerHeight();
- $( window ).on( 'resize', FLBuilderLayout._adjustRowShapeLayerHeight );
- },
- /**
- * Adjust Row Shape Layer's height to fix to remove the fine line that appears on certain screen sizes.
- *
- * @since 2.5.3
- * @access private
- * @method _adjustRowShapeLayerHeight
- */
- _adjustRowShapeLayerHeight: function() {
- var rowShapeLayers = $('.fl-builder-shape-layer');
- $( rowShapeLayers ).each(function (index) {
- var rowShapeLayer = $(this),
- shape = $(rowShapeLayer).find('svg'),
- height = shape.height(),
- excludeShapes = '.fl-builder-shape-circle, .fl-builder-shape-dot-cluster, .fl-builder-shape-topography, .fl-builder-shape-rect';
- if ( ! rowShapeLayer.is( excludeShapes ) ) {
- $(shape).css('height', Math.ceil( height ) );
- }
- });
- },
- _string_to_slug: function( str ) {
- str = str.replace(/^\s+|\s+$/g, ''); // trim
- if ( 'undefined' == typeof window._fl_string_to_slug_regex ) {
- regex = new RegExp('[^a-zA-Z0-9\'":() !.,-_|]', 'g');
- } else {
- regex = new RegExp('[^' + window._fl_string_to_slug_regex + '\'":\(\) !.,-_|\\\p{Letter}]', 'ug');
- }
- str = str.replace(regex, '') // remove invalid chars
- .replace(/\s+/g, ' '); // collapse whitespace and replace by a space
- return str;
- },
- _reorderMenu: function() {
- if ( $('#wp-admin-bar-fl-builder-frontend-edit-link-default li').length > 1 ) {
- $( '#wp-admin-bar-fl-builder-frontend-duplicate-link' )
- .appendTo('#wp-admin-bar-fl-builder-frontend-edit-link-default')
- .css( 'padding-top', '5px' )
- .css( 'border-top', '2px solid #1D2125' )
- .css( 'margin-top', '5px' )
- }
- }
- };
- /* Initializes the builder layout. */
- $(function(){
- FLBuilderLayout.init();
- });
- })(jQuery);
|