1var wpAjaxUrl = 'https://rizepropertymanagement.com/wp-admin/admin-ajax.php';var flBuilderUrl = 'https://rizepropertymanagement.com/wp-content/plugins/bb-plugin/';var FLBuilderLayoutConfig = { 2 anchorLinkAnimations : { 3 duration : 1000, 4 easing : 'swing', 5 offset : 100 6 }, 7 paths : { 8 pluginUrl : 'https://rizepropertymanagement.com/wp-content/plugins/bb-plugin/', 9 wpAjaxUrl : 'https://rizepropertymanagement.com/wp-admin/admin-ajax.php' 10 }, 11 breakpoints : { 12 small : 768, 13 medium : 992, 14 large : 1200 }, 15 waypoint: { 16 offset: 80 17 }, 18 emptyColWidth: '0%' 19}; 20(function($){ 21 22 if(typeof FLBuilderLayout != 'undefined') { 23 return; 24 } 25 26 /** 27 * Helper class with generic logic for a builder layout. 28 * 29 * @class FLBuilderLayout 30 * @since 1.0 31 */ 32 FLBuilderLayout = { 33 34 /** 35 * Initializes a builder layout. 36 * 37 * @since 1.0 38 * @method init 39 */ 40 init: function() 41 { 42 // Destroy existing layout events. 43 FLBuilderLayout._destroy(); 44 45 // Init CSS classes. 46 FLBuilderLayout._initClasses(); 47 48 // Init backgrounds.
49 FLBuilderLayout._initBackgrounds(); 50 51 // Init row shape layer height. 52 FLBuilderLayout._initRowShapeLayerHeight(); 53 54 // Only init if the builder isn't active. 55 if ( 0 === $('.fl-builder-edit').length ) { 56 57 // Init module animations. 58 FLBuilderLayout._initModuleAnimations(); 59 60 // Init anchor links. 61 FLBuilderLayout._initAnchorLinks(); 62 63 // Init the browser hash. 64 FLBuilderLayout._initHash(); 65 66 // Init forms. 67 FLBuilderLayout._initForms(); 68 69 FLBuilderLayout._reorderMenu(); 70 } 71 else { 72 FLBuilderLayout._initNestedColsWidth(); 73 } 74 }, 75 76 /** 77 * Public method for refreshing Wookmark or MosaicFlow galleries 78 * within an element. 79 * 80 * @since 1.7.4 81 * @method refreshGalleries 82 */ 83 refreshGalleries: function( element ) 84 { 85 var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ), 86 mfContent = $element.find( '.fl-mosaicflow-content' ), 87 wmContent = $element.find( '.fl-gallery' ), 88 mfObject = null; 89 90 if ( mfContent ) { 91 92 mfObject = mfContent.data( 'mosaicflow' ); 93 94 if ( mfObject ) { 95 mfObject.columns = $( [] ); 96 mfObject.columnsHeights = []; 97 mfContent.data( 'mosaicflow', mfObject ); 98 mfContent.mosaicflow( 'refill' ); 99 } 100 } 101 if ( wmContent ) { 102 wmContent.trigger( 'refreshWookmark' ); 103 } 104 }, 105 106 /** 107 * Public method for refreshing Masonry within an element 108 * 109 * @since 1.8.1 110 * @method refreshGridLayout 111 */ 112 refreshGridLayout: function( element ) 113 { 114 var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ), 115 msnryContent = $element.find('.masonry'); 116 117 if ( msnryContent.length ) { 118 msnryContent.masonry('layout'); 119 } 120 }, 121 122 /** 123 * Public method for reloading BxSlider within an element 124 * 125 * @since 1.8.1 126 * @method reloadSlider 127 */ 128 reloadSlider: function( content ) 129 { 130 var $content = 'undefined' == typeof content ? $('body') : $(content); 131 132 // reload sliders. 133 if ($content.find('.bx-viewport > div').length > 0) { 134 $.each($content.find('.bx-viewport > div'), function (key, slider) { 135 setTimeout(function () { 136 $(slider).data('bxSlider').reloadSlider(); 137 }, 100); 138 }); 139 } 140 }, 141 142 /** 143 * Public method for resizing WP audio player 144 * 145 * @since 1.8.2 146 * @method resizeAudio 147 */ 148 resizeAudio: function( element ) 149 { 150 var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ), 151 audioPlayers = $element.find('.wp-audio-shortcode.mejs-audio'), 152 player = null, 153 mejsPlayer = null, 154 rail = null, 155 railWidth = 400; 156 157 if ( audioPlayers.length && typeof mejs !== 'undefined' ) { 158 audioPlayers.each(function(){ 159 player = $(this); 160 mejsPlayer = mejs.players[player.attr('id')]; 161 rail = player.find('.mejs-controls .mejs-time-rail'); 162 var innerMejs = player.find('.mejs-inner'), 163 total = player.find('.mejs-controls .mejs-time-total'); 164 165 if ( typeof mejsPlayer !== 'undefined' ) { 166 railWidth = Math.ceil(player.width() * 0.8); 167 168 if ( innerMejs.length ) { 169 170 rail.css('width', railWidth +'px!important'); 171 //total.width(rail.width() - 10); 172 173 mejsPlayer.options.autosizeProgress = true; 174 175 // webkit has trouble doing this without a delay 176 setTimeout(function () { 177 mejsPlayer.setControlsSize(); 178 }, 50); 179 180 player.find('.mejs-inner').css({ 181 visibility: 'visible', 182 height: 'inherit' 183 }); 184 } 185 } 186 }); 187 } 188 }, 189 190 /** 191 * Public method for preloading WP audio player when it's inside the hidden element 192 * 193 * @since 1.8.2 194 * @method preloadAudio 195 */ 196 preloadAudio: function(element) 197 { 198 var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ), 199 contentWrap = $element.closest('.fl-accordion-item'), 200 audioPlayers = $element.find('.wp-audio-shortcode.mejs-audio'); 201 202 if ( ! contentWrap.hasClass('fl-accordion-item-active') && audioPlayers.find('.mejs-inner').length ) { 203 audioPlayers.find('.mejs-inner').css({ 204 visibility : 'hidden', 205 height: 0 206 }); 207 } 208 }, 209 210 /** 211 * Public method for resizing slideshow momdule within the tab 212 * 213 * @since 1.10.5 214 * @method resizeSlideshow 215 */ 216 resizeSlideshow: function(){ 217 if(typeof YUI !== 'undefined') { 218 YUI().use('node-event-simulate', function(Y) { 219 Y.one(window).simulate("resize"); 220 }); 221 } 222 }, 223 224 /** 225 * Public method for reloading an embedded Google Map within the tabs or hidden element. 226 * 227 * @since 2.2 228 * @method reloadGoogleMap 229 */ 230 reloadGoogleMap: function(element){ 231 var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ),
232 googleMap = $element.find( 'iframe[src*="google.com/maps"]' ); 233 234 if ( googleMap.length ) { 235 googleMap.attr( 'src', function(i, val) { 236 return val; 237 }); 238 } 239 }, 240 241 /** 242 * Unbinds builder layout events. 243 * 244 * @since 1.0 245 * @access private 246 * @method _destroy 247 */ 248 _destroy: function() 249 { 250 var win = $(window); 251 252 win.off('scroll.fl-bg-parallax'); 253 win.off('resize.fl-bg-video'); 254 }, 255 256 /** 257 * Checks to see if the current device has touch enabled. 258 * 259 * @since 1.0 260 * @access private 261 * @method _isTouch 262 * @return {Boolean} 263 */ 264 _isTouch: function() 265 { 266 if(('ontouchstart' in window) || (window.DocumentTouch && document instanceof DocumentTouch)) { 267 return true; 268 } 269 270 return false; 271 }, 272 273 /** 274 * Checks to see if the current device is mobile. 275 * 276 * @since 1.7 277 * @access private 278 * @method _isMobile 279 * @return {Boolean} 280 */ 281 _isMobile: function() 282 { 283 return /Mobile|Android|Silk\/|Kindle|BlackBerry|Opera Mini|Opera Mobi|webOS/i.test( navigator.userAgent ); 284 }, 285 286 /** 287 * Initializes builder body classes. 288 * 289 * @since 1.0 290 * @access private 291 * @method _initClasses 292 */ 293 _initClasses: function() 294 { 295 var body = $( 'body' ), 296 ua = navigator.userAgent; 297 298 // Add the builder body class. 299 if ( ! body.hasClass( 'archive' ) && $( '.fl-builder-content-primary' ).length > 0 ) { 300 body.addClass('fl-builder'); 301 } 302 303 // Add the builder touch body class. 304 if(FLBuilderLayout._isTouch()) { 305 body.addClass('fl-builder-touch'); 306 } 307 308 // Add the builder mobile body class. 309 if(FLBuilderLayout._isMobile()) { 310 body.addClass('fl-builder-mobile'); 311 } 312 313 if ( $(window).width() < FLBuilderLayoutConfig.breakpoints.small ) { 314 body.addClass( 'fl-builder-breakpoint-small' ); 315 } 316 317 if ( $(window).width() > FLBuilderLayoutConfig.breakpoints.small && $(window).width() < FLBuilderLayoutConfig.breakpoints.medium ) { 318 body.addClass( 'fl-builder-breakpoint-medium' ); 319 } 320 321 if ( $(window).width() > FLBuilderLayoutConfig.breakpoints.medium && $(window).width() < FLBuilderLayoutConfig.breakpoints.large ) { 322 body.addClass( 'fl-builder-breakpoint-large' ); 323 } 324 325 if ( $(window).width() > FLBuilderLayoutConfig.breakpoints.large ) { 326 body.addClass( 'fl-builder-breakpoint-default' ); 327 } 328 329 // IE11 body class. 330 if ( ua.indexOf( 'Trident/7.0' ) > -1 && ua.indexOf( 'rv:11.0' ) > -1 ) { 331 body.addClass( 'fl-builder-ie-11' ); 332 } 333 }, 334 335 /** 336 * Initializes builder node backgrounds that require 337 * additional JavaScript logic such as parallax. 338 * 339 * @since 1.1.4 340 * @access private
341 * @method _initBackgrounds 342 */ 343 _initBackgrounds: function() 344 { 345 var win = $(window); 346 347 // Init parallax backgrounds. 348 if($('.fl-row-bg-parallax').length > 0 && !FLBuilderLayout._isMobile()) { 349 FLBuilderLayout._scrollParallaxBackgrounds(); 350 FLBuilderLayout._initParallaxBackgrounds(); 351 win.on('resize.fl-bg-parallax', FLBuilderLayout._initParallaxBackgrounds); 352 win.on('scroll.fl-bg-parallax', FLBuilderLayout._scrollParallaxBackgrounds); 353 } 354 355 // Init video backgrounds. 356 if($('.fl-bg-video').length > 0) { 357 FLBuilderLayout._initBgVideos(); 358 FLBuilderLayout._resizeBgVideos(); 359 360 // Ensure FLBuilderLayout._resizeBgVideos() is only called once on window resize. 361 var resizeBGTimer = null; 362 win.on('resize.fl-bg-video', function(e){ 363 clearTimeout( resizeBGTimer ); 364 resizeBGTimer = setTimeout(function() { 365 FLBuilderLayout._resizeBgVideos(e); 366 }, 100 ); 367 }); 368 } 369 }, 370 371 /** 372 * Initializes all parallax backgrounds in a layout. 373 * 374 * @since 1.1.4 375 * @access private 376 * @method _initParallaxBackgrounds 377 */ 378 _initParallaxBackgrounds: function() 379 { 380 $('.fl-row-bg-parallax').each(FLBuilderLayout._initParallaxBackground); 381 }, 382 383 /** 384 * Initializes a single parallax background. 385 * 386 * @since 1.1.4 387 * @access private 388 * @method _initParallaxBackgrounds 389 */ 390 _initParallaxBackground: function() 391 { 392 var row = $(this), 393 content = row.find('> .fl-row-content-wrap'), 394 winWidth = $(window).width(), 395 screenSize = '', 396 imageSrc = { 397 default: '', 398 medium: '', 399 responsive: '', 400 }; 401 402 imageSrc.default = row.data('parallax-image') || ''; 403 imageSrc.medium = row.data('parallax-image-medium') || imageSrc.default; 404 imageSrc.responsive = row.data('parallax-image-responsive') || imageSrc.medium; 405 406 if (winWidth > FLBuilderLayoutConfig.breakpoints.medium) { 407 screenSize = 'default'; 408 } else if (winWidth > FLBuilderLayoutConfig.breakpoints.small && winWidth <= FLBuilderLayoutConfig.breakpoints.medium ) { 409 screenSize = 'medium'; 410 } else if (winWidth <= FLBuilderLayoutConfig.breakpoints.small) { 411 screenSize = 'responsive'; 412 } 413 414 content.css('background-image', 'url(' + imageSrc[screenSize] + ')'); 415 row.data('current-image-loaded', screenSize ); 416 417 }, 418 419 /** 420 * Fires when the window is scrolled to adjust 421 * parallax backgrounds. 422 * 423 * @since 1.1.4 424 * @access private 425 * @method _scrollParallaxBackgrounds 426 */ 427 _scrollParallaxBackgrounds: function() 428 { 429 $('.fl-row-bg-parallax').each(FLBuilderLayout._scrollParallaxBackground); 430 }, 431 432 /** 433 * Fires when the window is scrolled to adjust 434 * a single parallax background. 435 * 436 * @since 1.1.4 437 * @access private 438 * @method _scrollParallaxBackground 439 */ 440 _scrollParallaxBackground: function() 441 { 442 var win = $(window), 443 row = $(this), 444 content = row.find('> .fl-row-content-wrap'), 445 speed = row.data('parallax-speed'), 446 offset = content.offset(), 447 yPos = -((win.scrollTop() - offset.top) / speed), 448 initialOffset = ( row.data('parallax-offset') != null ) ? row.data('parallax-offset') : 0, 449 totalOffset = yPos - initialOffset; 450 451 content.css('background-position', 'center ' + totalOffset + 'px'); 452 }, 453 454 /** 455 * Initializes all video backgrounds. 456 * 457 * @since 1.6.3.3 458 * @access private 459 * @method _initBgVideos 460 */ 461 _initBgVideos: function() 462 { 463 $('.fl-bg-video').each(FLBuilderLayout._initBgVideo); 464 }, 465 466 /** 467 * Initializes a video background. 468 * 469 * @since 1.6.3.3 470 * @access private 471 * @method _initBgVideo 472 */ 473 _initBgVideo: function() 474 { 475 var wrap = $( this ), 476 width = wrap.data( 'width' ), 477 height = wrap.data( 'height' ), 478 mp4 = wrap.data( 'mp4' ), 479 youtube = wrap.data( 'youtube'), 480 vimeo = wrap.data( 'vimeo'), 481 mp4Type = wrap.data( 'mp4-type' ), 482 webm = wrap.data( 'webm' ), 483 webmType = wrap.data( 'webm-type' ), 484 fallback = wrap.data( 'fallback' ), 485 loaded = wrap.data( 'loaded' ), 486 videoMobile = wrap.data( 'video-mobile' ), 487 fallbackTag = '', 488 videoTag = null, 489 mp4Tag = null, 490 webmTag = null; 491 492 // Return if the video has been loaded for this row. 493 if ( loaded ) { 494 return; 495 } 496
497 videoTag = $( '<video autoplay loop muted playsinline></video>' ); 498 499 /** 500 * Add poster image (fallback image) 501 */ 502 if( 'undefined' != typeof fallback && '' != fallback ) { 503 videoTag.attr( 'poster', 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' ) 504 videoTag.css({ 505 backgroundImage: 'url("' + fallback + '")', 506 backgroundColor: 'transparent', 507 backgroundRepeat: 'no-repeat', 508 backgroundSize: 'cover', 509 backgroundPosition: 'center center', 510 }) 511 } 512 513 // MP4 Source Tag 514 if ( 'undefined' != typeof mp4 && '' != mp4 ) { 515 516 mp4Tag = $( '<source />' ); 517 mp4Tag.attr( 'src', mp4 ); 518 mp4Tag.attr( 'type', mp4Type ); 519 520 videoTag.append( mp4Tag ); 521 } 522 // WebM Source Tag 523 if ( 'undefined' != typeof webm && '' != webm ) { 524 525 webmTag = $( '<source />' ); 526 webmTag.attr( 'src', webm ); 527 webmTag.attr( 'type', webmType ); 528 529 videoTag.append( webmTag ); 530 } 531 532 // This is either desktop, or mobile is enabled. 533 if ( ! FLBuilderLayout._isMobile() || ( FLBuilderLayout._isMobile() && "yes" == videoMobile ) ) { 534 if ( 'undefined' != typeof youtube ) { 535 FLBuilderLayout._initYoutubeBgVideo.apply( this ); 536 } 537 else if ( 'undefined' != typeof vimeo ) { 538 FLBuilderLayout._initVimeoBgVideo.apply( this ); 539 } 540 else { 541 wrap.append( videoTag ); 542 } 543 } 544 else { 545 // if we are here, it means we are on mobile and NO is set so remove video src and use fallback 546 videoTag.attr('src', '') 547 wrap.append( videoTag ); 548 } 549 550 // Mark this video as loaded. 551 wrap.data('loaded', true); 552 }, 553 554 /** 555 * Initializes Youtube video background 556 * 557 * @since 1.9 558 * @access private 559 * @method _initYoutubeBgVideo 560 */ 561 _initYoutubeBgVideo: function() 562 { 563 var playerWrap = $(this), 564 videoId = playerWrap.data('video-id'), 565 videoPlayer = playerWrap.find('.fl-bg-video-player'), 566 enableAudio = playerWrap.data('enable-audio'), 567 audioButton = playerWrap.find('.fl-bg-video-audio'), 568 startTime = 'undefined' !== typeof playerWrap.data('start') ? playerWrap.data('start') : 0, 569 startTime = 'undefined' !== typeof playerWrap.data('t') && startTime === 0 ? playerWrap.data('t') : startTime, 570 endTime = 'undefined' !== typeof playerWrap.data('end') ? playerWrap.data('end') : 0, 571 loop = 'undefined' !== typeof playerWrap.data('loop') ? playerWrap.data('loop') : 1, 572 stateCount = 0, 573 player,fallback_showing; 574 575 if ( videoId ) { 576 fallback = playerWrap.data('fallback') || false 577 if( fallback ) { 578 playerWrap.find('iframe').remove() 579 fallbackTag = $( '<div></div>' ); 580 fallbackTag.addClass( 'fl-bg-video-fallback' ); 581 fallbackTag.css( 'background-image', 'url(' + playerWrap.data('fallback') + ')' ); 582 fallbackTag.css( 'background-size', 'cover' ); 583 fallbackTag.css( 'transition', 'background-image 1s') 584 playerWrap.append( fallbackTag ); 585 fallback_showing = true; 586 } 587 FLBuilderLayout._onYoutubeApiReady( function( YT ) { 588 setTimeout( function() { 589 590 player = new YT.Player( videoPlayer[0], { 591 videoId: videoId, 592 events: { 593 onReady: function(event) { 594 if ( "no" === enableAudio || FLBuilderLayout._isMobile() ) { 595 event.target.mute(); 596 } 597 else if ( "yes" === enableAudio && event.target.isMuted ) { 598 event.target.unMute(); 599 } 600 601 // Store an instance to a parent 602 playerWrap.data('YTPlayer', player); 603 FLBuilderLayout._resizeYoutubeBgVideo.apply(playerWrap); 604 605 // Queue the video. 606 event.target.playVideo(); 607 608 if ( audioButton.length > 0 && ! FLBuilderLayout._isMobile() ) { 609 audioButton.on( 'click', {button: audioButton, player: player}, FLBuilderLayout._toggleBgVideoAudio ); 610 } 611 }, 612 onStateChange: function( event ) { 613 614 if ( event.data === 1 ) { 615 if ( fallback_showing ) { 616 $( '.fl-bg-video-fallback' ).css( 'background-image', 'url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)' ) 617 } 618 } 619 // Manual check if video is not playable in some browsers. 620 // StateChange order: [-1, 3, -1] 621 if ( stateCount < 4 ) { 622 stateCount++; 623 } 624 625 // Comply with the audio policy in some browsers like Chrome and Safari. 626 if ( stateCount > 1 && (-1 === event.data || 2 === event.data) && "yes" === enableAudio ) { 627 player.mute(); 628 player.playVideo(); 629 audioButton.show(); 630 } 631 632 if ( event.data === YT.PlayerState.ENDED && 1 === loop ) { 633 if ( startTime > 0 ) { 634 player.seekTo( startTime ); 635 } 636 else { 637 player.playVideo(); 638 } 639 } 640 }, 641 onError: function(event) { 642 console.info('YT Error: ' + event.data) 643 FLBuilderLayout._onErrorYoutubeVimeo(playerWrap) 644 } 645 }, 646 playerVars: { 647 playsinline: FLBuilderLayout._isMobile() ? 1 : 0, 648 controls: 0, 649 showinfo: 0, 650 rel : 0, 651 start: startTime, 652 end: endTime, 653 } 654 } ); 655 }, 1 ); 656 } ); 657 } 658 }, 659 660 /** 661 * On youtube or vimeo error show the fallback image if available. 662 * @since 2.0.7 663 */ 664 _onErrorYoutubeVimeo: function(playerWrap) { 665 666 fallback = playerWrap.data('fallback') || false 667 if( ! fallback ) { 668 return false;
669 } 670 playerWrap.find('iframe').remove() 671 fallbackTag = $( '<div></div>' ); 672 fallbackTag.addClass( 'fl-bg-video-fallback' ); 673 fallbackTag.css( 'background-image', 'url(' + playerWrap.data('fallback') + ')' ); 674 playerWrap.append( fallbackTag ); 675 }, 676 677 /** 678 * Check if Youtube API has been downloaded 679 * 680 * @since 1.9 681 * @access private 682 * @method _onYoutubeApiReady 683 * @param {Function} callback Method to call when YT API has been loaded 684 */ 685 _onYoutubeApiReady: function( callback ) { 686 if ( window.YT && YT.loaded ) { 687 callback( YT ); 688 } else { 689 // If not ready check again by timeout.. 690 setTimeout( function() { 691 FLBuilderLayout._onYoutubeApiReady( callback ); 692 }, 350 ); 693 } 694 }, 695 696 /** 697 * Initializes Vimeo video background 698 * 699 * @since 1.9 700 * @access private 701 * @method _initVimeoBgVideo 702 */ 703 _initVimeoBgVideo: function() 704 { 705 var playerWrap = $(this), 706 videoId = playerWrap.data('video-id'), 707 videoPlayer = playerWrap.find('.fl-bg-video-player'), 708 enableAudio = playerWrap.data('enable-audio'), 709 audioButton = playerWrap.find('.fl-bg-video-audio'), 710 player, 711 width = playerWrap.outerWidth(), 712 ua = navigator.userAgent; 713 714 if ( typeof Vimeo !== 'undefined' && videoId ) { 715 player = new Vimeo.Player(videoPlayer[0], { 716 id : videoId, 717 loop : true, 718 title : false, 719 portrait : false, 720 background : true, 721 autopause : false, 722 muted : true 723 }); 724 725 playerWrap.data('VMPlayer', player); 726 if ( "no" === enableAudio ) { 727 player.setVolume(0); 728 } 729 else if ("yes" === enableAudio ) { 730 // Chrome, Safari, Firefox have audio policy restrictions for autoplay videos. 731 if ( ua.indexOf("Safari") > -1 || ua.indexOf("Chrome") > -1 || ua.indexOf("Firefox") > -1 ) { 732 player.setVolume(0); 733 audioButton.show(); 734 } 735 else { 736 player.setVolume(1); 737 } 738 } 739 740 player.play().catch(function(error) { 741 FLBuilderLayout._onErrorYoutubeVimeo(playerWrap) 742 }); 743 744 if ( audioButton.length > 0 ) { 745 audioButton.on( 'click', {button: audioButton, player: player}, FLBuilderLayout._toggleBgVideoAudio ); 746 } 747 } 748 }, 749 750 /** 751 * Mute / unmute audio on row's video background. 752 * It works for both Youtube and Vimeo. 753 * 754 * @since 2.1.3 755 * @access private 756 * @method _toggleBgVideoAudio 757 * @param {Object} e Method arguments 758 */ 759 _toggleBgVideoAudio: function( e ) { 760 var player = e.data.player, 761 control = e.data.button.find('.fl-audio-control'); 762 763 if ( control.hasClass( 'fa-volume-off' ) ) { 764 // Unmute 765 control 766 .removeClass( 'fa-volume-off' ) 767 .addClass( 'fa-volume-up' ); 768 e.data.button.find( '.fa-times' ).hide(); 769 770 if ( 'function' === typeof player.unMute ) { 771 player.unMute(); 772 } 773 else { 774 player.setVolume( 1 ); 775 } 776 } 777 else { 778 // Mute 779 control 780 .removeClass( 'fa-volume-up' ) 781 .addClass( 'fa-volume-off' ); 782 e.data.button.find( '.fa-times' ).show(); 783 784 if ( 'function' === typeof player.unMute ) { 785 player.mute(); 786 } 787 else { 788 player.setVolume( 0 ); 789 } 790 } 791 }, 792 793 /** 794 * Fires when there is an error loading a video 795 * background source and shows the fallback. 796 * 797 * @since 1.6.3.3 798 * @access private 799 * @method _videoBgSourceError 800 * @param {Object} e An event object 801 * @deprecated 2.0.3 802 */ 803 _videoBgSourceError: function( e ) 804 { 805 var source = $( e.target ), 806 wrap = source.closest( '.fl-bg-video' ), 807 vid = wrap.find( 'video' ), 808 fallback = wrap.data( 'fallback' ), 809 fallbackTag = ''; 810 source.remove(); 811 812 if ( vid.find( 'source' ).length ) { 813 // Don't show the fallback if we still have other sources to check. 814 return; 815 } else if ( '' !== fallback ) { 816 fallbackTag = $( '<div></div>' ); 817 fallbackTag.addClass( 'fl-bg-video-fallback' ); 818 fallbackTag.css( 'background-image', 'url(' + fallback + ')' ); 819 wrap.append( fallbackTag ); 820 vid.remove(); 821 } 822 }, 823 824 /** 825 * Fires when the window is resized to resize 826 * all video backgrounds. 827 * 828 * @since 1.1.4 829 * @access private 830 * @method _resizeBgVideos 831 */ 832 _resizeBgVideos: function() 833 { 834 $('.fl-bg-video').each( function() { 835 836 FLBuilderLayout._resizeBgVideo.apply( this ); 837 838 if ( $( this ).parent().find( 'img' ).length > 0 ) { 839 $( this ).parent().imagesLoaded( $.proxy( FLBuilderLayout._resizeBgVideo, this ) ); 840 } 841 } ); 842 }, 843 844 /** 845 * Fires when the window is resized to resize 846 * a single video background. 847 * 848 * @since 1.1.4 849 * @access private 850 * @method _resizeBgVideo 851 */ 852 _resizeBgVideo: function() 853 { 854 if ( 0 === $( this ).find( 'video' ).length && 0 === $( this ).find( 'iframe' ).length ) { 855 return; 856 } 857 858 var wrap = $(this), 859 wrapHeight = wrap.outerHeight(), 860 wrapWidth = wrap.outerWidth(), 861 vid = wrap.find('video'), 862 vidHeight = wrap.data('height'), 863 vidWidth = wrap.data('width'), 864 newWidth = wrapWidth, 865 newHeight = Math.round(vidHeight * wrapWidth/vidWidth), 866 newLeft = 0, 867 newTop = 0, 868 iframe = wrap.find('iframe'), 869 isRowFullHeight = $(this).closest('.fl-row-bg-video').hasClass('fl-row-full-height'), 870 vidCSS = { 871 top: '50%', 872 left: '50%', 873 transform: 'translate(-50%,-50%)', 874 }; 875 876 if ( vid.length ) { 877 if(vidHeight === '' || typeof vidHeight === 'undefined' || vidWidth === '' || typeof vidWidth === 'undefined') { 878 vid.css({ 879 'left' : '0px', 880 'top' : '0px', 881 'width' : newWidth + 'px' 882 }); 883 884 // Try to set the actual video dimension on 'loadedmetadata' when using URL as video source 885 vid.on('loadedmetadata', FLBuilderLayout._resizeOnLoadedMeta); 886 887 return; 888 } 889 890 if ( ! isRowFullHeight ) { 891 if ( newHeight < wrapHeight ) { 892 newHeight = wrapHeight; 893 newLeft = -((newWidth - wrapWidth) / 2); 894 newWidth = vidHeight ? Math.round(vidWidth * wrapHeight/vidHeight) : newWidth; 895 } 896 else { 897 newTop = -((newHeight - wrapHeight)/2); 898 } 899 vidCSS = { 900 left : newLeft + 'px', 901 top : newTop + 'px', 902 height : newHeight + 'px', 903 width : newWidth + 'px', 904 } 905 } 906 907 vid.css( vidCSS ); 908 909 } 910 else if ( iframe.length ) { 911 912 // Resize Youtube video player within iframe tag 913 if ( typeof wrap.data('youtube') !== 'undefined' ) { 914 FLBuilderLayout._resizeYoutubeBgVideo.apply(this); 915 } 916 } 917 }, 918 919 /** 920 * Fires when video meta has been loaded. 921 * This will be Triggered when width/height attributes were not specified during video background resizing. 922 * 923 * @since 1.8.5 924 * @access private 925 * @method _resizeOnLoadedMeta 926 */ 927 _resizeOnLoadedMeta: function(){ 928 var video = $(this), 929 wrapHeight = video.parent().outerHeight(), 930 wrapWidth = video.parent().outerWidth(), 931 vidWidth = video[0].videoWidth, 932 vidHeight = video[0].videoHeight, 933 newHeight = Math.round(vidHeight * wrapWidth/vidWidth), 934 newWidth = wrapWidth, 935 newLeft = 0, 936 newTop = 0; 937 938 if(newHeight < wrapHeight) { 939 newHeight = wrapHeight; 940 newWidth = Math.round(vidWidth * wrapHeight/vidHeight); 941 newLeft = -((newWidth - wrapWidth)/2); 942 } 943 else { 944 newTop = -((newHeight - wrapHeight)/2); 945 } 946 947 video.parent().data('width', vidWidth); 948 video.parent().data('height', vidHeight); 949 950 video.css({ 951 'left' : newLeft + 'px', 952 'top' : newTop + 'px', 953 'width' : newWidth + 'px', 954 'height' : newHeight + 'px' 955 }); 956 }, 957 958 /** 959 * Fires when the window is resized to resize 960 * a single Youtube video background. 961 * 962 * @since 1.9 963 * @access private 964 * @method _resizeYoutubeBgVideo 965 */ 966 _resizeYoutubeBgVideo: function() 967 { 968 var wrap = $(this), 969 wrapWidth = wrap.outerWidth(), 970 wrapHeight = wrap.outerHeight(), 971 player = wrap.data('YTPlayer'), 972 video = player ? player.getIframe() : null, 973 aspectRatioSetting = '16:9', // Medium 974 aspectRatioArray = aspectRatioSetting.split( ':' ),
975 aspectRatio = aspectRatioArray[0] / aspectRatioArray[1], 976 ratioWidth = wrapWidth / aspectRatio, 977 ratioHeight = wrapHeight * aspectRatio, 978 isWidthFixed = wrapWidth / wrapHeight > aspectRatio, 979 width = isWidthFixed ? wrapWidth : ratioHeight, 980 height = isWidthFixed ? ratioWidth : wrapHeight; 981 982 if ( video ) { 983 $(video).width( width ).height( height ); 984 } 985 }, 986 987 /** 988 * Initializes module animations. 989 * 990 * @since 1.1.9 991 * @access private 992 * @method _initModuleAnimations 993 */ 994 _initModuleAnimations: function() 995 { 996 if(typeof jQuery.fn.waypoint !== 'undefined') { 997 $('.fl-animation').each( function() { 998 var node = $( this ), 999 nodeTop = node.offset().top, 1000 winHeight = $( window ).height(), 1001 bodyHeight = $( 'body' ).height(), 1002 waypoint = FLBuilderLayoutConfig.waypoint, 1003 offset = '80%'; 1004 1005 if ( typeof waypoint.offset !== undefined ) { 1006 offset = FLBuilderLayoutConfig.waypoint.offset + '%'; 1007 } 1008 1009 if ( bodyHeight - nodeTop < winHeight * 0.2 ) { 1010 offset = '100%'; 1011 } 1012 1013 node.waypoint({ 1014 offset: offset, 1015 handler: FLBuilderLayout._doModuleAnimation 1016 }); 1017 } ); 1018 } 1019 }, 1020 1021 /** 1022 * Runs a module animation. 1023 * 1024 * @since 1.1.9 1025 * @access private 1026 * @method _doModuleAnimation 1027 */ 1028 _doModuleAnimation: function() 1029 { 1030 var module = 'undefined' == typeof this.element ? $(this) : $(this.element), 1031 delay = parseFloat(module.data('animation-delay')), 1032 duration = parseFloat(module.data('animation-duration')); 1033 1034 if ( ! isNaN( duration ) ) { 1035 module.css( 'animation-duration', duration + 's' ); 1036 } 1037 1038 if(!isNaN(delay) && delay > 0) { 1039 setTimeout(function(){ 1040 module.addClass('fl-animated'); 1041 }, delay * 1000); 1042 } else { 1043 setTimeout(function(){ 1044 module.addClass('fl-animated'); 1045 }, 1); 1046 } 1047 }, 1048 1049 /** 1050 * Opens a tab or accordion item if the browser hash is set 1051 * to the ID of one on the page. 1052 * 1053 * @since 1.6.0 1054 * @access private 1055 * @method _initHash 1056 */ 1057 _initHash: function() 1058 { 1059 var hash = window.location.hash.replace( '#', '' ).split( '/' ).shift(), 1060 element = null, 1061 tabs = null, 1062 responsiveLabel = null, 1063 tabIndex = null, 1064 label = null; 1065 1066 if ( '' !== hash ) { 1067 1068 try { 1069 1070 element = $( '#' + hash ); 1071 1072 if ( element.length > 0 ) { 1073 1074 if ( element.hasClass( 'fl-accordion-item' ) ) { 1075 setTimeout( function() { 1076 element.find( '.fl-accordion-button' ).trigger( 'click' ); 1077 }, 100 ); 1078 } 1079 if ( element.hasClass( 'fl-tabs-panel' ) ) { 1080 setTimeout( function() { 1081 tabs = element.closest( '.fl-tabs' ); 1082 responsiveLabel = element.find( '.fl-tabs-panel-label' ); 1083 tabIndex = responsiveLabel.data( 'index' ); 1084 label = tabs.find( '.fl-tabs-labels .fl-tabs-label[data-index=' + tabIndex + ']' ); 1085 1086 label[0].click(); 1087 FLBuilderLayout._scrollToElement(element); 1088 }, 100 ); 1089 } 1090 } 1091 } 1092 catch( e ) {} 1093 } 1094 }, 1095 1096 /** 1097 * Initializes all anchor links on the page for smooth scrolling. 1098 * 1099 * @since 1.4.9 1100 * @access private 1101 * @method _initAnchorLinks 1102 */ 1103 _initAnchorLinks: function() 1104 { 1105 $( 'a' ).each( FLBuilderLayout._initAnchorLink ); 1106 }, 1107 1108 /** 1109 * Initializes a single anchor link for smooth scrolling. 1110 * 1111 * @since 1.4.9 1112 * @access private 1113 * @method _initAnchorLink 1114 */ 1115 _initAnchorLink: function() 1116 { 1117 var link = $( this ), 1118 href = link.attr( 'href' ), 1119 loc = window.location, 1120 id = null, 1121 element = null, 1122 flNode = false; 1123 1124 if ( 'undefined' != typeof href && href.indexOf( '#' ) > -1 && link.closest('svg').length < 1 ) { 1125 1126 if ( loc.pathname.replace( /^\//, '' ) == this.pathname.replace( /^\//, '' ) && loc.hostname == this.hostname ) { 1127 1128 try { 1129 1130 id = href.split( '#' ).pop(); 1131 // If there is no ID then we have nowhere to look 1132 // Fixes a quirk in jQuery and FireFox 1133 if( ! id ) { 1134 return; 1135 } 1136 element = $( '#' + id ); 1137 1138 if ( element.length > 0 ) { 1139 flNode = element.hasClass( 'fl-row' ) || element.hasClass( 'fl-col' ) || element.hasClass( 'fl-module' ); 1140 if ( !element.hasClass( 'fl-no-scroll' ) && ( link.hasClass( 'fl-scroll-link' ) || flNode ) ) { 1141 $( link ).on( 'click', FLBuilderLayout._scrollToElementOnLinkClick ); 1142 } 1143 if ( element.hasClass( 'fl-accordion-item' ) ) { 1144 $( link ).on( 'click', FLBuilderLayout._scrollToAccordionOnLinkClick ); 1145 } 1146 if ( element.hasClass( 'fl-tabs-panel' ) ) { 1147 $( link ).on( 'click', FLBuilderLayout._scrollToTabOnLinkClick ); 1148 } 1149 } 1150 } 1151 catch( e ) {} 1152 } 1153 } 1154 }, 1155 1156 /** 1157 * Scrolls to an element when an anchor link is clicked. 1158 * 1159 * @since 1.4.9 1160 * @access private 1161 * @method _scrollToElementOnLinkClick 1162 * @param {Object} e An event object. 1163 * @param {Function} callback A function to call when the scroll is complete. 1164 */ 1165 _scrollToElementOnLinkClick: function( e, callback ) 1166 { 1167 var element = $( '#' + $( this ).attr( 'href' ).split( '#' ).pop() ); 1168 1169 FLBuilderLayout._scrollToElement( element, callback ); 1170 1171 e.preventDefault(); 1172 }, 1173 1174 /** 1175 * Scrolls to an element. 1176 * 1177 * @since 1.6.4.5 1178 * @access private 1179 * @method _scrollToElement 1180 * @param {Object} element The element to scroll to. 1181 * @param {Function} callback A function to call when the scroll is complete. 1182 */ 1183 _scrollToElement: function( element, callback ) 1184 { 1185 var config = FLBuilderLayoutConfig.anchorLinkAnimations, 1186 dest = 0, 1187 win = $( window ), 1188 doc = $( document ); 1189 1190 if ( element.length > 0 ) { 1191 1192 if ( 'fixed' === element.css('position') || 'fixed' === element.parent().css('position') ) { 1193 dest = element.position().top; 1194 } 1195 else if ( element.offset().top > doc.height() - win.height() ) { 1196 dest = doc.height() - win.height(); 1197 } 1198 else { 1199 dest = element.offset().top - config.offset; 1200 } 1201 1202 $( 'html, body' ).animate( { scrollTop: dest }, config.duration, config.easing, function() { 1203 1204 if ( 'undefined' != typeof callback ) { 1205 callback(); 1206 } 1207 1208 if ( undefined != element.attr( 'id' ) ) { 1209 1210 if ( history.pushState ) { 1211 history.pushState( null, null, '#' + element.attr( 'id' ) ); 1212 } 1213 else { 1214 window.location.hash = element.attr( 'id' ); 1215 } 1216 } 1217 } ); 1218 } 1219 }, 1220 1221 /** 1222 * Scrolls to an accordion item when a link is clicked. 1223 * 1224 * @since 1.5.9 1225 * @access private 1226 * @method _scrollToAccordionOnLinkClick 1227 * @param {Object} e An event object. 1228 */ 1229 _scrollToAccordionOnLinkClick: function( e ) 1230 { 1231 var element = $( '#' + $( this ).attr( 'href' ).split( '#' ).pop() ); 1232 1233 if ( element.length > 0 ) { 1234 1235 var callback = function() { 1236 if ( element ) { 1237 element.find( '.fl-accordion-button' ).trigger( 'click' ); 1238 element = false;
1239 } 1240 }; 1241 1242 FLBuilderLayout._scrollToElementOnLinkClick.call( this, e, callback ); 1243 } 1244 }, 1245 1246 /** 1247 * Scrolls to a tab panel when a link is clicked. 1248 * 1249 * @since 1.5.9 1250 * @access private 1251 * @method _scrollToTabOnLinkClick 1252 * @param {Object} e An event object. 1253 */ 1254 _scrollToTabOnLinkClick: function( e ) 1255 { 1256 var element = $( '#' + $( this ).attr( 'href' ).split( '#' ).pop() ), 1257 tabs = null, 1258 label = null, 1259 responsiveLabel = null; 1260 1261 if ( element.length > 0 ) { 1262 1263 tabs = element.closest( '.fl-tabs' ); 1264 responsiveLabel = element.find( '.fl-tabs-panel-label' ); 1265 tabIndex = responsiveLabel.data( 'index' ); 1266 label = tabs.find( '.fl-tabs-labels .fl-tabs-label[data-index=' + tabIndex + ']' ); 1267 1268 if ( responsiveLabel.is( ':visible' ) ) { 1269 1270 var callback = function() { 1271 if ( element ) { 1272 responsiveLabel.trigger( $.Event( 'click', { which: 1 } ) ); 1273 } 1274 }; 1275 1276 FLBuilderLayout._scrollToElementOnLinkClick.call( this, e, callback ); 1277 } 1278 else { 1279 label[0].click(); 1280 FLBuilderLayout._scrollToElement( element ); 1281 } 1282 1283 e.preventDefault(); 1284 } 1285 }, 1286 1287 /** 1288 * Initializes all builder forms on a page. 1289 * 1290 * @since 1.5.4 1291 * @access private 1292 * @method _initForms 1293 */ 1294 _initForms: function() 1295 { 1296 if ( ! FLBuilderLayout._hasPlaceholderSupport ) { 1297 $( '.fl-form-field input' ).each( FLBuilderLayout._initFormFieldPlaceholderFallback ); 1298 } 1299 1300 $( '.fl-form-field input' ).on( 'focus', FLBuilderLayout._clearFormFieldError ); 1301 }, 1302 1303 /** 1304 * Checks to see if the current device has HTML5 1305 * placeholder support. 1306 * 1307 * @since 1.5.4 1308 * @access private 1309 * @method _hasPlaceholderSupport 1310 * @return {Boolean} 1311 */ 1312 _hasPlaceholderSupport: function() 1313 { 1314 var input = document.createElement( 'input' ); 1315 1316 return 'undefined' != input.placeholder; 1317 }, 1318 1319 /** 1320 * Initializes the fallback for when placeholders aren't supported. 1321 * 1322 * @since 1.5.4 1323 * @access private 1324 * @method _initFormFieldPlaceholderFallback 1325 */ 1326 _initFormFieldPlaceholderFallback: function() 1327 { 1328 var field = $( this ), 1329 val = field.val(), 1330 placeholder = field.attr( 'placeholder' ); 1331 1332 if ( 'undefined' != placeholder && '' === val ) { 1333 field.val( placeholder ); 1334 field.on( 'focus', FLBuilderLayout._hideFormFieldPlaceholderFallback ); 1335 field.on( 'blur', FLBuilderLayout._showFormFieldPlaceholderFallback ); 1336 } 1337 }, 1338 1339 /** 1340 * Hides a fallback placeholder on focus. 1341 * 1342 * @since 1.5.4 1343 * @access private 1344 * @method _hideFormFieldPlaceholderFallback 1345 */ 1346 _hideFormFieldPlaceholderFallback: function() 1347 { 1348 var field = $( this ), 1349 val = field.val(), 1350 placeholder = field.attr( 'placeholder' ); 1351 1352 if ( val == placeholder ) { 1353 field.val( '' ); 1354 } 1355 }, 1356 1357 /** 1358 * Shows a fallback placeholder on blur. 1359 * 1360 * @since 1.5.4 1361 * @access private 1362 * @method _showFormFieldPlaceholderFallback 1363 */ 1364 _showFormFieldPlaceholderFallback: function() 1365 { 1366 var field = $( this ), 1367 val = field.val(), 1368 placeholder = field.attr( 'placeholder' ); 1369 1370 if ( '' === val ) { 1371 field.val( placeholder ); 1372 } 1373 }, 1374 1375 /** 1376 * Clears a form field error message. 1377 * 1378 * @since 1.5.4 1379 * @access private 1380 * @method _clearFormFieldError 1381 */ 1382 _clearFormFieldError: function() 1383 { 1384 var field = $( this ); 1385 1386 field.removeClass( 'fl-form-error' ); 1387 field.siblings( '.fl-form-error-message' ).hide(); 1388 }, 1389 1390 /** 1391 * Init Row Shape Layer's height. 1392 * 1393 * @since 2.5.3 1394 * @access private 1395 * @method _initRowShapeLayerHeight 1396 */ 1397 _initRowShapeLayerHeight: function () { 1398 FLBuilderLayout._adjustRowShapeLayerHeight(); 1399 $( window ).on( 'resize', FLBuilderLayout._adjustRowShapeLayerHeight ); 1400 }, 1401 1402 /** 1403 * Set parent column width of nested columns when it's zero or blank. 1404 * 1405 * @since 2.7.4 1406 * @access private 1407 * @method _initNestedColsWidth 1408 */ 1409 _initNestedColsWidth: function() 1410 { 1411 var nestedCols = $( '.fl-col-has-cols' ); 1412 1413 if ( nestedCols.length <= 0 ) { 1414 return; 1415 } 1416 1417 $( nestedCols ).each( function(index, col ){ 1418 if ( $( col ).width() <= 0 ) { 1419 $( col ).css( 'width', FLBuilderLayoutConfig.emptyColWidth ); 1420 } 1421 }); 1422 }, 1423 1424 /** 1425 * Adjust Row Shape Layer's height to fix to remove the fine line that appears on certain screen sizes. 1426 * 1427 * @since 2.5.3 1428 * @access private 1429 * @method _adjustRowShapeLayerHeight 1430 */
1431 _adjustRowShapeLayerHeight: function() { 1432 var rowShapeLayers = $('.fl-builder-shape-layer'); 1433 1434 $( rowShapeLayers ).each(function (index) { 1435 var rowShapeLayer = $(this), 1436 shape = $(rowShapeLayer).find('svg'), 1437 height = shape.height(), 1438 excludeShapes = '.fl-builder-shape-circle, .fl-builder-shape-dot-cluster, .fl-builder-shape-topography, .fl-builder-shape-rect'; 1439 1440 if ( ! rowShapeLayer.is( excludeShapes ) ) { 1441 $(shape).css('height', Math.ceil( height ) ); 1442 } 1443 }); 1444 }, 1445 _string_to_slug: function( str ) { 1446 str = str.replace(/^\s+|\s+$/g, ''); // trim 1447 if ( 'undefined' == typeof window._fl_string_to_slug_regex ) { 1448 regex = new RegExp('[^a-zA-Z0-9\'":() !.,-_|]', 'g'); 1449 } else { 1450 regex = new RegExp('[^' + window._fl_string_to_slug_regex + '\'":\(\) !.,-_|\\\p{Letter}]', 'ug'); 1451 } 1452 str = str.replace(regex, '') // remove invalid chars 1453 .replace(/\s+/g, ' '); // collapse whitespace and replace by a space 1454 return str; 1455 }, 1456 _reorderMenu: function() { 1457 if ( $('#wp-admin-bar-fl-builder-frontend-edit-link-default li').length > 1 ) { 1458 $( '#wp-admin-bar-fl-builder-frontend-duplicate-link' ) 1459 .appendTo('#wp-admin-bar-fl-builder-frontend-edit-link-default') 1460 .css( 'padding-top', '5px' ) 1461 .css( 'border-top', '2px solid #1D2125' ) 1462 .css( 'margin-top', '5px' ) 1463 } 1464 } 1465 }; 1466 1467 /* Initializes the builder layout. */ 1468 $(function(){ 1469 FLBuilderLayout.init(); 1470 }); 1471 1472})(jQuery); 1473 1474/* Start Global JS */ 1475 1476/* End Global JS */ 1477 1478;;; 1479/* Start Global Node Custom JS */ 1480 1481/* End Global Node Custom JS */ 1482 1483 1484/* Start Layout Custom JS */ 1485 1486/* End Layout Custom JS */ 1487
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.