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