1/*! 2 * Bowser - a browser detector 3 * https://github.com/ded/bowser 4 * MIT License | (c) Dustin Diaz 2015 5 */ 6 7!function (name, definition) { 8 if (typeof module != 'undefined' && module.exports) module.exports = definition() 9 else if (typeof define == 'function' && define.amd) define(name, definition) 10 else this[name] = definition() 11}('bowser', function () { 12 /** 13 * See useragents.js for examples of navigator.userAgent 14 */ 15 16 var t = true 17 18 function detect(ua) { 19 20 function getFirstMatch(regex) { 21 var match = ua.match(regex); 22 return (match && match.length > 1 && match[1]) || ''; 23 } 24 25 function getSecondMatch(regex) { 26 var match = ua.match(regex); 27 return (match && match.length > 1 && match[2]) || ''; 28 } 29 30 var iosdevice = getFirstMatch(/(ipod|iphone|ipad)/i).toLowerCase() 31 , likeAndroid = /like android/i.test(ua) 32 , android = !likeAndroid && /android/i.test(ua) 33 , nexusMobile = /nexus\s*[0-6]\s*/i.test(ua) 34 , nexusTablet = !nexusMobile && /nexus\s*[0-9]+/i.test(ua) 35 , chromeos = /CrOS/.test(ua) 36 , silk = /silk/i.test(ua) 37 , sailfish = /sailfish/i.test(ua) 38 , tizen = /tizen/i.test(ua) 39 , webos = /(web|hpw)os/i.test(ua) 40 , windowsphone = /windows phone/i.test(ua) 41 , windows = !windowsphone && /windows/i.test(ua) 42 , mac = !iosdevice && !silk && /macintosh/i.test(ua) 43 , linux = !android && !sailfish && !tizen && !webos && /linux/i.test(ua) 44 , edgeVersion = getFirstMatch(/edge\/(\d+(\.\d+)?)/i) 45 , versionIdentifier = getFirstMatch(/version\/(\d+(\.\d+)?)/i) 46 , tablet = /tablet/i.test(ua) 47 , mobile = !tablet && /[^-]mobi/i.test(ua) 48 , xbox = /xbox/i.test(ua) 49 , result 50 51 if (/opera|opr|opios/i.test(ua)) { 52 result = { 53 name: 'Opera' 54 , opera: t 55 , version: versionIdentifier || getFirstMatch(/(?:opera|opr|opios)[\s\/](\d+(\.\d+)?)/i) 56 } 57 } 58 else if (/coast/i.test(ua)) { 59 result = { 60 name: 'Opera Coast' 61 , coast: t 62 , version: versionIdentifier || getFirstMatch(/(?:coast)[\s\/](\d+(\.\d+)?)/i) 63 } 64 } 65 else if (/yabrowser/i.test(ua)) { 66 result = { 67 name: 'Yandex Browser' 68 , yandexbrowser: t 69 , version: versionIdentifier || getFirstMatch(/(?:yabrowser)[\s\/](\d+(\.\d+)?)/i) 70 } 71 } 72 else if (/ucbrowser/i.test(ua)) { 73 result = { 74 name: 'UC Browser' 75 , ucbrowser: t 76 , version: getFirstMatch(/(?:ucbrowser)[\s\/](\d+(?:\.\d+)+)/i) 77 } 78 } 79 else if (/mxios/i.test(ua)) { 80 result = { 81 name: 'Maxthon' 82 , maxthon: t 83 , version: getFirstMatch(/(?:mxios)[\s\/](\d+(?:\.\d+)+)/i) 84 } 85 } 86 else if (/epiphany/i.test(ua)) { 87 result = { 88 name: 'Epiphany' 89 , epiphany: t 90 , version: getFirstMatch(/(?:epiphany)[\s\/](\d+(?:\.\d+)+)/i) 91 } 92 } 93 else if (/puffin/i.test(ua)) { 94 result = { 95 name: 'Puffin' 96 , puffin: t 97 , version: getFirstMatch(/(?:puffin)[\s\/](\d+(?:\.\d+)?)/i) 98 } 99 } 100 else if (/sleipnir/i.test(ua)) { 101 result = { 102 name: 'Sleipnir' 103 , sleipnir: t 104 , version: getFirstMatch(/(?:sleipnir)[\s\/](\d+(?:\.\d+)+)/i) 105 } 106 } 107 else if (/k-meleon/i.test(ua)) { 108 result = { 109 name: 'K-Meleon' 110 , kMeleon: t 111 , version: getFirstMatch(/(?:k-meleon)[\s\/](\d+(?:\.\d+)+)/i) 112 } 113 } 114 else if (windowsphone) { 115 result = { 116 name: 'Windows Phone' 117 , windowsphone: t 118 } 119 if (edgeVersion) { 120 result.msedge = t 121 result.version = edgeVersion 122 } 123 else { 124 result.msie = t 125 result.version = getFirstMatch(/iemobile\/(\d+(\.\d+)?)/i) 126 } 127 } 128 else if (/msie|trident/i.test(ua)) { 129 result = { 130 name: 'Internet Explorer' 131 , msie: t 132 , version: getFirstMatch(/(?:msie |rv:)(\d+(\.\d+)?)/i) 133 } 134 } else if (chromeos) { 135 result = { 136 name: 'Chrome' 137 , chromeos: t 138 , chromeBook: t 139 , chrome: t 140 , version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i) 141 } 142 } else if (/chrome.+? edge/i.test(ua)) { 143 result = { 144 name: 'Microsoft Edge' 145 , msedge: t 146 , version: edgeVersion 147 } 148 } 149 else if (/vivaldi/i.test(ua)) { 150 result = { 151 name: 'Vivaldi' 152 , vivaldi: t 153 , version: getFirstMatch(/vivaldi\/(\d+(\.\d+)?)/i) || versionIdentifier 154 } 155 } 156 else if (sailfish) { 157 result = { 158 name: 'Sailfish' 159 , sailfish: t 160 , version: getFirstMatch(/sailfish\s?browser\/(\d+(\.\d+)?)/i) 161 } 162 } 163 else if (/seamonkey\//i.test(ua)) { 164 result = { 165 name: 'SeaMonkey' 166 , seamonkey: t 167 , version: getFirstMatch(/seamonkey\/(\d+(\.\d+)?)/i) 168 } 169 } 170 else if (/firefox|iceweasel|fxios/i.test(ua)) { 171 result = { 172 name: 'Firefox' 173 , firefox: t 174 , version: getFirstMatch(/(?:firefox|iceweasel|fxios)[ \/](\d+(\.\d+)?)/i) 175 } 176 if (/\((mobile|tablet);[^\)]*rv:[\d\.]+\)/i.test(ua)) { 177 result.firefoxos = t 178 } 179 } 180 else if (silk) { 181 result = { 182 name: 'Amazon Silk' 183 , silk: t 184 , version : getFirstMatch(/silk\/(\d+(\.\d+)?)/i) 185 } 186 } 187 else if (/phantom/i.test(ua)) { 188 result = { 189 name: 'PhantomJS' 190 , phantom: t 191 , version: getFirstMatch(/phantomjs\/(\d+(\.\d+)?)/i) 192 } 193 } 194 else if (/slimerjs/i.test(ua)) { 195 result = { 196 name: 'SlimerJS' 197 , slimer: t 198 , version: getFirstMatch(/slimerjs\/(\d+(\.\d+)?)/i) 199 } 200 } 201 else if (/blackberry|\bbb\d+/i.test(ua) || /rim\stablet/i.test(ua)) { 202 result = { 203 name: 'BlackBerry' 204 , blackberry: t 205 , version: versionIdentifier || getFirstMatch(/blackberry[\d]+\/(\d+(\.\d+)?)/i) 206 } 207 } 208 else if (webos) { 209 result = { 210 name: 'WebOS' 211 , webos: t 212 , version: versionIdentifier || getFirstMatch(/w(?:eb)?osbrowser\/(\d+(\.\d+)?)/i) 213 }; 214 if( /touchpad\//i.test(ua) ){ 215 result.touchpad = t; 216 } 217 } 218 else if (/bada/i.test(ua)) { 219 result = { 220 name: 'Bada' 221 , bada: t 222 , version: getFirstMatch(/dolfin\/(\d+(\.\d+)?)/i) 223 }; 224 } 225 else if (tizen) { 226 result = { 227 name: 'Tizen' 228 , tizen: t 229 , version: getFirstMatch(/(?:tizen\s?)?browser\/(\d+(\.\d+)?)/i) || versionIdentifier 230 }; 231 } 232 else if (/qupzilla/i.test(ua)) { 233 result = { 234 name: 'QupZilla' 235 , qupzilla: t 236 , version: getFirstMatch(/(?:qupzilla)[\s\/](\d+(?:\.\d+)+)/i) || versionIdentifier 237 } 238 } 239 else if (/chromium/i.test(ua)) { 240 result = { 241 name: 'Chromium' 242 , chromium: t 243 , version: getFirstMatch(/(?:chromium)[\s\/](\d+(?:\.\d+)?)/i) || versionIdentifier 244 } 245 } 246 else if (/chrome|crios|crmo/i.test(ua)) { 247 result = { 248 name: 'Chrome' 249 , chrome: t 250 , version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i) 251 } 252 } 253 else if (android) { 254 result = { 255 name: 'Android' 256 , version: versionIdentifier 257 } 258 } 259 else if (/safari|applewebkit/i.test(ua)) { 260 result = { 261 name: 'Safari' 262 , safari: t 263 } 264 if (versionIdentifier) { 265 result.version = versionIdentifier 266 } 267 } 268 else if (iosdevice) { 269 result = { 270 name : iosdevice == 'iphone' ? 'iPhone' : iosdevice == 'ipad' ? 'iPad' : 'iPod' 271 } 272 // WTF: version is not part of user agent in web apps 273 if (versionIdentifier) { 274 result.version = versionIdentifier 275 } 276 } 277 else if(/googlebot/i.test(ua)) { 278 result = { 279 name: 'Googlebot' 280 , googlebot: t 281 , version: getFirstMatch(/googlebot\/(\d+(\.\d+))/i) || versionIdentifier 282 } 283 } 284 else { 285 result = { 286 name: getFirstMatch(/^(.*)\/(.*) /), 287 version: getSecondMatch(/^(.*)\/(.*) /) 288 }; 289 } 290 291 // set webkit or gecko flag for browsers based on these engines 292 if (!result.msedge && /(apple)?webkit/i.test(ua)) { 293 if (/(apple)?webkit\/537\.36/i.test(ua)) { 294 result.name = result.name || "Blink" 295 result.blink = t 296 } else { 297 result.name = result.name || "Webkit" 298 result.webkit = t 299 } 300 if (!result.version && versionIdentifier) { 301 result.version = versionIdentifier 302 } 303 } else if (!result.opera && /gecko\//i.test(ua)) { 304 result.name = result.name || "Gecko" 305 result.gecko = t 306 result.version = result.version || getFirstMatch(/gecko\/(\d+(\.\d+)?)/i) 307 } 308 309 // set OS flags for platforms that have multiple browsers 310 if (!result.msedge && (android || result.silk)) { 311 result.android = t 312 } else if (iosdevice) { 313 result[iosdevice] = t 314 result.ios = t 315 } else if (mac) { 316 result.mac = t 317 } else if (xbox) { 318 result.xbox = t 319 } else if (windows) { 320 result.windows = t 321 } else if (linux) { 322 result.linux = t 323 } 324 325 // OS version extraction 326 var osVersion = ''; 327 if (result.windowsphone) { 328 osVersion = getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i); 329 } else if (iosdevice) { 330 osVersion = getFirstMatch(/os (\d+([_\s]\d+)*) like mac os x/i); 331 osVersion = osVersion.replace(/[_\s]/g, '.'); 332 } else if (android) { 333 osVersion = getFirstMatch(/android[ \/-](\d+(\.\d+)*)/i); 334 } else if (result.webos) { 335 osVersion = getFirstMatch(/(?:web|hpw)os\/(\d+(\.\d+)*)/i); 336 } else if (result.blackberry) { 337 osVersion = getFirstMatch(/rim\stablet\sos\s(\d+(\.\d+)*)/i); 338 } else if (result.bada) { 339 osVersion = getFirstMatch(/bada\/(\d+(\.\d+)*)/i); 340 } else if (result.tizen) { 341 osVersion = getFirstMatch(/tizen[\/\s](\d+(\.\d+)*)/i); 342 } 343 if (osVersion) { 344 result.osversion = osVersion; 345 } 346 347 // device type extraction 348 var osMajorVersion = osVersion.split('.')[0]; 349 if ( 350 tablet 351 || nexusTablet 352 || iosdevice == 'ipad' 353 || (android && (osMajorVersion == 3 || (osMajorVersion >= 4 && !mobile))) 354 || result.silk 355 ) { 356 result.tablet = t 357 } else if ( 358 mobile 359 || iosdevice == 'iphone' 360 || iosdevice == 'ipod' 361 || android 362 || nexusMobile 363 || result.blackberry 364 || result.webos 365 || result.bada 366 ) { 367 result.mobile = t 368 } 369 370 // Graded Browser Support
371 // http://developer.yahoo.com/yui/articles/gbs 372 if (result.msedge || 373 (result.msie && result.version >= 10) || 374 (result.yandexbrowser && result.version >= 15) || 375 (result.vivaldi && result.version >= 1.0) || 376 (result.chrome && result.version >= 20) || 377 (result.firefox && result.version >= 20.0) || 378 (result.safari && result.version >= 6) || 379 (result.opera && result.version >= 10.0) || 380 (result.ios && result.osversion && result.osversion.split(".")[0] >= 6) || 381 (result.blackberry && result.version >= 10.1) 382 || (result.chromium && result.version >= 20) 383 ) { 384 result.a = t; 385 } 386 else if ((result.msie && result.version < 10) || 387 (result.chrome && result.version < 20) || 388 (result.firefox && result.version < 20.0) || 389 (result.safari && result.version < 6) || 390 (result.opera && result.version < 10.0) || 391 (result.ios && result.osversion && result.osversion.split(".")[0] < 6) 392 || (result.chromium && result.version < 20) 393 ) { 394 result.c = t 395 } else result.x = t 396 397 return result 398 } 399 400 var bowser = detect(typeof navigator !== 'undefined' ? navigator.userAgent : '') 401 402 bowser.test = function (browserList) { 403 for (var i = 0; i < browserList.length; ++i) { 404 var browserItem = browserList[i]; 405 if (typeof browserItem=== 'string') { 406 if (browserItem in bowser) { 407 return true; 408 } 409 } 410 } 411 return false; 412 } 413 414 /** 415 * Get version precisions count 416 * 417 * @example 418 * getVersionPrecision("1.10.3") // 3 419 * 420 * @param {string} version 421 * @return {number} 422 */ 423 function getVersionPrecision(version) { 424 return version.split(".").length; 425 } 426 427 /** 428 * Array::map polyfill 429 * 430 * @param {Array} arr 431 * @param {Function} iterator 432 * @return {Array} 433 */ 434 function map(arr, iterator) { 435 var result = [], i; 436 if (Array.prototype.map) { 437 return Array.prototype.map.call(arr, iterator); 438 } 439 for (i = 0; i < arr.length; i++) { 440 result.push(iterator(arr[i])); 441 } 442 return result; 443 } 444 445 /** 446 * Calculate browser version weight 447 * 448 * @example 449 * compareVersions(['1.10.2.1', '1.8.2.1.90']) // 1 450 * compareVersions(['1.010.2.1', '1.09.2.1.90']); // 1 451 * compareVersions(['1.10.2.1', '1.10.2.1']); // 0 452 * compareVersions(['1.10.2.1', '1.0800.2']); // -1 453 * 454 * @param {Array<String>} versions versions to compare 455 * @return {Number} comparison result 456 */ 457 function compareVersions(versions) { 458 // 1) get common precision for both versions, for example for "10.0" and "9" it should be 2 459 var precision = Math.max(getVersionPrecision(versions[0]), getVersionPrecision(versions[1])); 460 var chunks = map(versions, function (version) { 461 var delta = precision - getVersionPrecision(version); 462 463 // 2) "9" -> "9.0" (for precision = 2) 464 version = version + new Array(delta + 1).join(".0"); 465 466 // 3) "9.0" -> ["000000000"", "000000009"] 467 return map(version.split("."), function (chunk) { 468 return new Array(20 - chunk.length).join("0") + chunk; 469 }).reverse(); 470 }); 471 472 // iterate in reverse order by reversed chunks array 473 while (--precision >= 0) { 474 // 4) compare: "000000009" > "000000010" = false (but "9" > "10" = true) 475 if (chunks[0][precision] > chunks[1][precision]) { 476 return 1; 477 } 478 else if (chunks[0][precision] === chunks[1][precision]) { 479 if (precision === 0) { 480 // all version chunks are same 481 return 0; 482 } 483 } 484 else { 485 return -1; 486 } 487 } 488 } 489 490 /** 491 * Check if browser is unsupported 492 * 493 * @example 494 * bowser.isUnsupportedBrowser({ 495 * msie: "10", 496 * firefox: "23", 497 * chrome: "29", 498 * safari: "5.1", 499 * opera: "16", 500 * phantom: "534" 501 * }); 502 * 503 * @param {Object} minVersions map of minimal version to browser 504 * @param {Boolean} [strictMode = false] flag to return false if browser wasn't found in map 505 * @param {String} [ua] user agent string 506 * @return {Boolean} 507 */ 508 function isUnsupportedBrowser(minVersions, strictMode, ua) { 509 var _bowser = bowser; 510 511 // make strictMode param optional with ua param usage 512 if (typeof strictMode === 'string') { 513 ua = strictMode;
514 strictMode = void(0); 515 } 516 517 if (strictMode === void(0)) { 518 strictMode = false; 519 } 520 if (ua) { 521 _bowser = detect(ua); 522 } 523 524 var version = "" + _bowser.version; 525 for (var browser in minVersions) { 526 if (minVersions.hasOwnProperty(browser)) { 527 if (_bowser[browser]) { 528 // browser version and min supported version. 529 return compareVersions([version, minVersions[browser]]) < 0; 530 } 531 } 532 } 533 534 return strictMode; // not found 535 } 536 537 /** 538 * Check if browser is supported 539 * 540 * @param {Object} minVersions map of minimal version to browser 541 * @param {Boolean} [strictMode = false] flag to return false if browser wasn't found in map 542 * @param {String} [ua] user agent string 543 * @return {Boolean} 544 */ 545 function check(minVersions, strictMode, ua) { 546 return !isUnsupportedBrowser(minVersions, strictMode, ua); 547 } 548 549 bowser.isUnsupportedBrowser = isUnsupportedBrowser; 550 bowser.compareVersions = compareVersions; 551 bowser.check = check; 552 553 /* 554 * Set our detect method to the main bowser object so we can 555 * reuse it to test other user agents. 556 * This is needed to implement future tests. 557 */ 558 bowser._detect = detect; 559 560 return bowser 561}); 562 563(function($){ 564 UABBTrigger = { 565 566 /** 567 * Trigger a hook. 568 * 569 * @since 1.1.0.3 570 * @method triggerHook 571 * @param {String} hook The hook to trigger. 572 * @param {Array} args An array of args to pass to the hook. 573 */ 574 triggerHook: function( hook, args ) 575 { 576 $( 'body' ).trigger( 'uabb-trigger.' + hook, args ); 577 }, 578 579 /** 580 * Add a hook. 581 * 582 * @since 1.1.0.3 583 * @method addHook 584 * @param {String} hook The hook to add. 585 * @param {Function} callback A function to call when the hook is triggered. 586 */ 587 addHook: function( hook, callback ) 588 { 589 $( 'body' ).on( 'uabb-trigger.' + hook, callback ); 590 }, 591 592 /** 593 * Remove a hook. 594 * 595 * @since 1.1.0.3 596 * @method removeHook 597 * @param {String} hook The hook to remove. 598 * @param {Function} callback The callback function to remove. 599 */ 600 removeHook: function( hook, callback ) 601 { 602 $( 'body' ).off( 'uabb-trigger.' + hook, callback ); 603 }, 604 }; 605})(jQuery); 606 607jQuery(document).ready(function( $ ) { 608 609 if( typeof bowser !== 'undefined' && bowser !== null ) { 610 611 var uabb_browser = bowser.name, 612 uabb_browser_v = bowser.version, 613 uabb_browser_class = uabb_browser.replace(/\s+/g, '-').toLowerCase(), 614 uabb_browser_v_class = uabb_browser_class + parseInt( uabb_browser_v ); 615 616 $('html').addClass(uabb_browser_class).addClass(uabb_browser_v_class); 617 618 } 619 620 $('.uabb-row-separator').parents('html').css('overflow-x', 'hidden'); 621}); 622var wpAjaxUrl = 'https://peprofessional.com/wp-admin/admin-ajax.php';var flBuilderUrl = 'https://peprofessional.com/wp-content/plugins/bb-plugin/';var FLBuilderLayoutConfig = { 623 anchorLinkAnimations : { 624 duration : 1000, 625 easing : 'swing', 626 offset : 100 627 }, 628 paths : { 629 pluginUrl : 'https://peprofessional.com/wp-content/plugins/bb-plugin/', 630 wpAjaxUrl : 'https://peprofessional.com/wp-admin/admin-ajax.php' 631 }, 632 breakpoints : { 633 small : 768, 634 medium : 992, 635 large : 1200 }, 636 waypoint: { 637 offset: 80 638 }, 639 emptyColWidth: '0%' 640}; 641(function($){ 642 643 if(typeof FLBuilderLayout != 'undefined') { 644 return; 645 } 646 647 /** 648 * Helper class with generic logic for a builder layout. 649 * 650 * @class FLBuilderLayout 651 * @since 1.0 652 */ 653 FLBuilderLayout = { 654 655 /** 656 * Initializes a builder layout. 657 * 658 * @since 1.0 659 * @method init 660 */ 661 init: function() 662 { 663 // Destroy existing layout events. 664 FLBuilderLayout._destroy(); 665 666 // Init CSS classes. 667 FLBuilderLayout._initClasses(); 668 669 // Init backgrounds.
670 FLBuilderLayout._initBackgrounds(); 671 672 // Init buttons. 673 FLBuilderLayout._initButtons(); 674 675 // Init row shape layer height. 676 FLBuilderLayout._initRowShapeLayerHeight(); 677 678 // Only init if the builder isn't active. 679 if ( 0 === $('.fl-builder-edit').length ) { 680 681 // Init anchor links. 682 FLBuilderLayout._initAnchorLinks(); 683 684 // Init the browser hash. 685 FLBuilderLayout._initHash(); 686 687 // Init forms. 688 FLBuilderLayout._initForms(); 689 690 FLBuilderLayout._reorderMenu(); 691 } 692 else { 693 FLBuilderLayout._initNestedColsWidth(); 694 } 695 $('body').removeClass( 'fl-no-js' ); 696 }, 697 698 /** 699 * Public method for refreshing Wookmark or MosaicFlow galleries 700 * within an element. 701 * 702 * @since 1.7.4 703 * @method refreshGalleries 704 */ 705 refreshGalleries: function( element ) 706 { 707 var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ), 708 mfContent = $element.find( '.fl-mosaicflow-content' ), 709 wmContent = $element.find( '.fl-gallery' ), 710 mfObject = null; 711 712 if ( mfContent ) { 713 714 mfObject = mfContent.data( 'mosaicflow' ); 715 716 if ( mfObject ) { 717 mfObject.columns = $( [] ); 718 mfObject.columnsHeights = []; 719 mfContent.data( 'mosaicflow', mfObject ); 720 mfContent.mosaicflow( 'refill' ); 721 } 722 } 723 if ( wmContent ) { 724 wmContent.trigger( 'refreshWookmark' ); 725 } 726 }, 727 728 /** 729 * Public method for refreshing Masonry within an element 730 * 731 * @since 1.8.1 732 * @method refreshGridLayout 733 */ 734 refreshGridLayout: function( element ) 735 { 736 var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ), 737 msnryContent = $element.find('.masonry'); 738 739 if ( msnryContent.length ) { 740 msnryContent.masonry('layout'); 741 } 742 }, 743 744 /** 745 * Public method for reloading BxSlider within an element 746 * 747 * @since 1.8.1 748 * @method reloadSlider 749 */ 750 reloadSlider: function( content ) 751 { 752 var $content = 'undefined' == typeof content ? $('body') : $(content); 753 754 // reload sliders. 755 if ($content.find('.bx-viewport > div').length > 0) { 756 $.each($content.find('.bx-viewport > div'), function (key, slider) { 757 setTimeout(function () { 758 $(slider).data('bxSlider').reloadSlider(); 759 }, 100); 760 }); 761 } 762 }, 763 764 /** 765 * Public method for resizing WP audio player 766 * 767 * @since 1.8.2 768 * @method resizeAudio 769 */ 770 resizeAudio: function( element ) 771 { 772 var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ), 773 audioPlayers = $element.find('.wp-audio-shortcode.mejs-audio'), 774 player = null, 775 mejsPlayer = null, 776 rail = null, 777 railWidth = 400; 778 779 if ( audioPlayers.length && typeof mejs !== 'undefined' ) { 780 audioPlayers.each(function(){ 781 player = $(this); 782 mejsPlayer = mejs.players[player.attr('id')]; 783 rail = player.find('.mejs-controls .mejs-time-rail'); 784 var innerMejs = player.find('.mejs-inner'), 785 total = player.find('.mejs-controls .mejs-time-total'); 786 787 if ( typeof mejsPlayer !== 'undefined' ) { 788 railWidth = Math.ceil(player.width() * 0.8); 789 790 if ( innerMejs.length ) { 791 792 rail.css('width', railWidth +'px!important'); 793 //total.width(rail.width() - 10); 794 795 mejsPlayer.options.autosizeProgress = true; 796 797 // webkit has trouble doing this without a delay 798 setTimeout(function () { 799 mejsPlayer.setControlsSize(); 800 }, 50); 801 802 player.find('.mejs-inner').css({ 803 visibility: 'visible', 804 height: 'inherit' 805 }); 806 } 807 } 808 }); 809 } 810 }, 811 812 /** 813 * Public method for preloading WP audio player when it's inside the hidden element 814 * 815 * @since 1.8.2 816 * @method preloadAudio 817 */ 818 preloadAudio: function(element) 819 { 820 var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ), 821 contentWrap = $element.closest('.fl-accordion-item'), 822 audioPlayers = $element.find('.wp-audio-shortcode.mejs-audio'); 823 824 if ( ! contentWrap.hasClass('fl-accordion-item-active') && audioPlayers.find('.mejs-inner').length ) { 825 audioPlayers.find('.mejs-inner').css({ 826 visibility : 'hidden', 827 height: 0 828 }); 829 } 830 }, 831 832 /** 833 * Public method for resizing slideshow momdule within the tab 834 * 835 * @since 1.10.5 836 * @method resizeSlideshow 837 */ 838 resizeSlideshow: function(){ 839 if(typeof YUI !== 'undefined') { 840 YUI().use('node-event-simulate', function(Y) { 841 Y.one(window).simulate("resize"); 842 }); 843 } 844 }, 845 846 /** 847 * Public method for reloading an embedded Google Map within the tabs or hidden element. 848 * 849 * @since 2.2 850 * @method reloadGoogleMap 851 */ 852 reloadGoogleMap: function(element){ 853 var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ),
854 googleMap = $element.find( 'iframe[src*="google.com/maps"]' ); 855 856 if ( googleMap.length ) { 857 googleMap.attr( 'src', function(i, val) { 858 return val; 859 }); 860 } 861 }, 862 863 /** 864 * Unbinds builder layout events. 865 * 866 * @since 1.0 867 * @access private 868 * @method _destroy 869 */ 870 _destroy: function() 871 { 872 var win = $(window); 873 874 win.off('scroll.fl-bg-parallax'); 875 win.off('resize.fl-bg-video'); 876 }, 877 878 /** 879 * Checks to see if the current device has touch enabled. 880 * 881 * @since 1.0 882 * @access private 883 * @method _isTouch 884 * @return {Boolean} 885 */ 886 _isTouch: function() 887 { 888 if(('ontouchstart' in window) || (window.DocumentTouch && document instanceof DocumentTouch)) { 889 return true; 890 } 891 892 return false; 893 }, 894 895 /** 896 * Checks to see if the current device is mobile. 897 * 898 * @since 1.7 899 * @access private 900 * @method _isMobile 901 * @return {Boolean} 902 */ 903 _isMobile: function() 904 { 905 return /Mobile|Android|Silk\/|Kindle|BlackBerry|Opera Mini|Opera Mobi|webOS/i.test( navigator.userAgent ); 906 }, 907 908 /** 909 * Initializes builder body classes. 910 * 911 * @since 1.0 912 * @access private 913 * @method _initClasses 914 */ 915 _initClasses: function() 916 { 917 var body = $( 'body' ), 918 ua = navigator.userAgent; 919 920 // Add the builder body class (skip on block-only frontend to avoid layout break). 921 if ( ! body.hasClass( 'fl-builder-blocks-only' ) && ! body.hasClass( 'archive' ) && $( '.fl-builder-content-primary' ).length > 0 ) { 922 body.addClass('fl-builder'); 923 } 924 925 // Add the builder touch body class. 926 if(FLBuilderLayout._isTouch()) { 927 body.addClass('fl-builder-touch'); 928 } 929 930 // Add the builder mobile body class. 931 if(FLBuilderLayout._isMobile()) { 932 body.addClass('fl-builder-mobile'); 933 } 934 935 if ( $(window).width() < FLBuilderLayoutConfig.breakpoints.small ) { 936 body.addClass( 'fl-builder-breakpoint-small' ); 937 } 938 939 if ( $(window).width() > FLBuilderLayoutConfig.breakpoints.small && $(window).width() < FLBuilderLayoutConfig.breakpoints.medium ) { 940 body.addClass( 'fl-builder-breakpoint-medium' ); 941 } 942 943 if ( $(window).width() > FLBuilderLayoutConfig.breakpoints.medium && $(window).width() < FLBuilderLayoutConfig.breakpoints.large ) { 944 body.addClass( 'fl-builder-breakpoint-large' ); 945 } 946 947 if ( $(window).width() > FLBuilderLayoutConfig.breakpoints.large ) { 948 body.addClass( 'fl-builder-breakpoint-default' ); 949 } 950 951 // IE11 body class. 952 if ( ua.indexOf( 'Trident/7.0' ) > -1 && ua.indexOf( 'rv:11.0' ) > -1 ) { 953 body.addClass( 'fl-builder-ie-11' ); 954 } 955 }, 956 957 /** 958 * Initializes builder node backgrounds that require 959 * additional JavaScript logic such as parallax. 960 * 961 * @since 1.1.4 962 * @access private
963 * @method _initBackgrounds 964 */ 965 _initBackgrounds: function() 966 { 967 var win = $(window); 968 969 // Init parallax backgrounds. 970 if($('.fl-row-bg-parallax').length > 0 && !FLBuilderLayout._isMobile()) { 971 FLBuilderLayout._scrollParallaxBackgrounds(); 972 FLBuilderLayout._initParallaxBackgrounds(); 973 win.on('resize.fl-bg-parallax', FLBuilderLayout._initParallaxBackgrounds); 974 win.on('scroll.fl-bg-parallax', FLBuilderLayout._scrollParallaxBackgrounds); 975 } 976 977 // Init video backgrounds. 978 if($('.fl-bg-video').length > 0) { 979 FLBuilderLayout._initBgVideos(); 980 FLBuilderLayout._resizeBgVideos(); 981 982 // Ensure FLBuilderLayout._resizeBgVideos() is only called once on window resize. 983 var resizeBGTimer = null; 984 win.on('resize.fl-bg-video', function(e){ 985 clearTimeout( resizeBGTimer ); 986 resizeBGTimer = setTimeout(function() { 987 FLBuilderLayout._resizeBgVideos(e); 988 }, 100 ); 989 }); 990 } 991 }, 992 993 /** 994 * Initializes all buttons in a layout. 995 * 996 * @since 2.10 997 * @access private 998 * @method _initButtons 999 */ 1000 _initButtons: function() 1001 { 1002 // Trigger click event on Enter or Space key press for deprecated button markup. 1003 $('a.fl-button[role="button"]').on('keydown', function(event) { 1004 if (event.key === 'Enter' || event.key === ' ') { 1005 // Necessary to prevent the default behavior of the space key from scrolling the page 1006 event.preventDefault(); 1007 $(this).trigger('click'); 1008 } 1009 }); 1010 }, 1011 1012 /** 1013 * Initializes all parallax backgrounds in a layout. 1014 * 1015 * @since 1.1.4 1016 * @access private 1017 * @method _initParallaxBackgrounds 1018 */ 1019 _initParallaxBackgrounds: function() 1020 { 1021 $('.fl-row-bg-parallax').each(FLBuilderLayout._initParallaxBackground); 1022 }, 1023 1024 /** 1025 * Initializes a single parallax background. 1026 * 1027 * @since 1.1.4 1028 * @access private 1029 * @method _initParallaxBackgrounds 1030 */ 1031 _initParallaxBackground: function() 1032 { 1033 var row = $(this), 1034 content = row.find('> .fl-row-content-wrap'), 1035 winWidth = $(window).width(), 1036 screenSize = '', 1037 imageSrc = { 1038 default: '', 1039 medium: '', 1040 responsive: '', 1041 }; 1042 1043 imageSrc.default = row.data('parallax-image') || ''; 1044 imageSrc.medium = row.data('parallax-image-medium') || imageSrc.default; 1045 imageSrc.responsive = row.data('parallax-image-responsive') || imageSrc.medium; 1046 1047 if (winWidth > FLBuilderLayoutConfig.breakpoints.medium) { 1048 screenSize = 'default'; 1049 } else if (winWidth > FLBuilderLayoutConfig.breakpoints.small && winWidth <= FLBuilderLayoutConfig.breakpoints.medium ) { 1050 screenSize = 'medium'; 1051 } else if (winWidth <= FLBuilderLayoutConfig.breakpoints.small) { 1052 screenSize = 'responsive'; 1053 } 1054 1055 content.css('background-image', 'url(' + imageSrc[screenSize] + ')'); 1056 row.data('current-image-loaded', screenSize ); 1057 1058 }, 1059 1060 /** 1061 * Fires when the window is scrolled to adjust 1062 * parallax backgrounds. 1063 * 1064 * @since 1.1.4 1065 * @access private 1066 * @method _scrollParallaxBackgrounds 1067 */ 1068 _scrollParallaxBackgrounds: function() 1069 { 1070 $('.fl-row-bg-parallax').each(FLBuilderLayout._scrollParallaxBackground); 1071 }, 1072 1073 /** 1074 * Fires when the window is scrolled to adjust 1075 * a single parallax background. 1076 * 1077 * @since 1.1.4 1078 * @access private 1079 * @method _scrollParallaxBackground 1080 */ 1081 _scrollParallaxBackground: function() 1082 { 1083 var win = $(window), 1084 row = $(this), 1085 content = row.find('> .fl-row-content-wrap'), 1086 speed = row.data('parallax-speed'), 1087 offset = content.offset(), 1088 yPos = -((win.scrollTop() - offset.top) / speed), 1089 initialOffset = ( row.data('parallax-offset') != null ) ? row.data('parallax-offset') : 0, 1090 totalOffset = yPos - initialOffset; 1091 1092 content.css('background-position', 'center ' + totalOffset + 'px'); 1093 }, 1094 1095 /** 1096 * Initializes all video backgrounds. 1097 * 1098 * @since 1.6.3.3 1099 * @access private 1100 * @method _initBgVideos 1101 */ 1102 _initBgVideos: function() 1103 { 1104 $('.fl-bg-video').each(FLBuilderLayout._initBgVideo); 1105 }, 1106 1107 /** 1108 * Initializes a video background. 1109 * 1110 * @since 1.6.3.3 1111 * @access private 1112 * @method _initBgVideo 1113 */ 1114 _initBgVideo: function() 1115 { 1116 var wrap = $( this ), 1117 width = wrap.data( 'width' ), 1118 height = wrap.data( 'height' ), 1119 mp4 = wrap.data( 'mp4' ), 1120 youtube = wrap.data( 'youtube'), 1121 vimeo = wrap.data( 'vimeo'), 1122 mp4Type = wrap.data( 'mp4-type' ), 1123 webm = wrap.data( 'webm' ), 1124 webmType = wrap.data( 'webm-type' ), 1125 fallback = wrap.data( 'fallback' ), 1126 loaded = wrap.data( 'loaded' ), 1127 videoMobile = wrap.data( 'video-mobile' ), 1128 playPauseButton = wrap.find('.fl-bg-video-play-pause-control'), 1129 fallbackTag = '', 1130 videoTag = null, 1131 mp4Tag = null, 1132 webmTag = null; 1133 1134 // Return if the video has been loaded for this row. 1135 if ( loaded ) { 1136 return; 1137 } 1138
1139 videoTag = $( '<video autoplay loop muted playsinline></video>' ); 1140 1141 /** 1142 * Add poster image (fallback image) 1143 */ 1144 if( 'undefined' != typeof fallback && '' != fallback ) { 1145 videoTag.attr( 'poster', 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' ) 1146 videoTag.css({ 1147 backgroundImage: 'url("' + fallback + '")', 1148 backgroundColor: 'transparent', 1149 backgroundRepeat: 'no-repeat', 1150 backgroundSize: 'cover', 1151 backgroundPosition: 'center center', 1152 }) 1153 } 1154 1155 // MP4 Source Tag 1156 if ( 'undefined' != typeof mp4 && '' != mp4 ) { 1157 1158 mp4Tag = $( '<source />' ); 1159 mp4Tag.attr( 'src', mp4 ); 1160 mp4Tag.attr( 'type', mp4Type ); 1161 1162 videoTag.append( mp4Tag ); 1163 } 1164 // WebM Source Tag 1165 if ( 'undefined' != typeof webm && '' != webm ) { 1166 1167 webmTag = $( '<source />' ); 1168 webmTag.attr( 'src', webm ); 1169 webmTag.attr( 'type', webmType ); 1170 1171 videoTag.append( webmTag ); 1172 } 1173 1174 // This is either desktop, or mobile is enabled. 1175 if ( ! FLBuilderLayout._isMobile() || ( FLBuilderLayout._isMobile() && "yes" == videoMobile ) ) { 1176 if ( 'undefined' != typeof youtube ) { 1177 FLBuilderLayout._initYoutubeBgVideo.apply( this ); 1178 } 1179 else if ( 'undefined' != typeof vimeo ) { 1180 FLBuilderLayout._initVimeoBgVideo.apply( this ); 1181 } 1182 else { 1183 wrap.append( videoTag ); 1184 1185 if ( playPauseButton.length > 0 ) { 1186 var video = videoTag[0]; 1187 1188 playPauseButton.on( 'click', { video: video }, function(e) { 1189 var video = e.data.video; 1190 1191 if ( video.paused ) { 1192 video.play(); 1193 } else { 1194 video.pause(); 1195 } 1196 } ); 1197 1198 $( video ).on( 'play playing', function () { 1199 playPauseButton.removeClass( 'fa-play' ).addClass( 'fa-pause' ); 1200 } ); 1201 1202 $( video ).on( 'pause ended waiting', function () { 1203 playPauseButton.removeClass( 'fa-pause' ).addClass( 'fa-play' ); 1204 } ); 1205 } 1206 } 1207 } 1208 else { 1209 // if we are here, it means we are on mobile and NO is set so remove video src and use fallback 1210 videoTag.attr('src', '') 1211 wrap.append( videoTag ); 1212 } 1213 1214 // Mark this video as loaded. 1215 wrap.data('loaded', true); 1216 }, 1217 1218 /** 1219 * Initializes Youtube video background 1220 * 1221 * @since 1.9 1222 * @access private 1223 * @method _initYoutubeBgVideo 1224 */ 1225 _initYoutubeBgVideo: function() 1226 { 1227 var playerWrap = $(this), 1228 videoId = playerWrap.data('video-id'), 1229 videoPlayer = playerWrap.find('.fl-bg-video-player'), 1230 enableAudio = playerWrap.data('enable-audio'), 1231 audioButton = playerWrap.find('.fl-bg-video-audio'), 1232 playPauseButton = playerWrap.find('.fl-bg-video-play-pause-control'), 1233 startTime = 'undefined' !== typeof playerWrap.data('start') ? playerWrap.data('start') : 0, 1234 startTime = 'undefined' !== typeof playerWrap.data('t') && startTime === 0 ? playerWrap.data('t') : startTime, 1235 endTime = 'undefined' !== typeof playerWrap.data('end') ? playerWrap.data('end') : 0, 1236 loop = 'undefined' !== typeof playerWrap.data('loop') ? playerWrap.data('loop') : 1, 1237 stateCount = 0, 1238 player,fallback_showing; 1239 1240 if ( videoId ) { 1241 fallback = playerWrap.data('fallback') || false 1242 if( fallback ) { 1243 playerWrap.find('iframe').remove() 1244 fallbackTag = $( '<div></div>' ); 1245 fallbackTag.addClass( 'fl-bg-video-fallback' ); 1246 fallbackTag.css( 'background-image', 'url(' + playerWrap.data('fallback') + ')' ); 1247 fallbackTag.css( 'background-size', 'cover' ); 1248 fallbackTag.css( 'transition', 'background-image 1s') 1249 playerWrap.append( fallbackTag ); 1250 fallback_showing = true; 1251 } 1252 FLBuilderLayout._onYoutubeApiReady( function( YT ) { 1253 setTimeout( function() { 1254 1255 player = new YT.Player( videoPlayer[0], { 1256 videoId: videoId, 1257 events: { 1258 onReady: function(event) { 1259 if ( "no" === enableAudio || FLBuilderLayout._isMobile() ) { 1260 event.target.mute(); 1261 } 1262 else if ( "yes" === enableAudio && event.target.isMuted ) { 1263 event.target.unMute(); 1264 } 1265 1266 // Store an instance to a parent 1267 playerWrap.data('YTPlayer', player); 1268 FLBuilderLayout._resizeYoutubeBgVideo.apply(playerWrap); 1269 1270 // Queue the video. 1271 event.target.playVideo(); 1272 1273 if ( audioButton.length > 0 && ! FLBuilderLayout._isMobile() ) {
1274 audioButton.on( 'click', {button: audioButton, player: player}, FLBuilderLayout._toggleBgVideoAudio ); 1275 } 1276 1277 if ( playPauseButton.length > 0 ) { 1278 playPauseButton.on( 'click', {player: player}, function(e) { 1279 var player = e.data.player; 1280 1281 if ( 1 === player.getPlayerState() ) { 1282 player.pauseVideo(); 1283 } else { 1284 player.playVideo(); 1285 } 1286 }); 1287 } 1288 }, 1289 onStateChange: function( event ) { 1290 1291 if ( event.data === 1 ) { 1292 if ( fallback_showing ) { 1293 $( '.fl-bg-video-fallback' ).css( 'background-image', 'url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)' ) 1294 } 1295 } 1296 // Manual check if video is not playable in some browsers. 1297 // StateChange order: [-1, 3, -1] 1298 if ( stateCount < 4 ) { 1299 stateCount++; 1300 } 1301 1302 // Comply with the audio policy in some browsers like Chrome and Safari. 1303 if ( stateCount > 1 && -1 === event.data && "yes" === enableAudio ) { 1304 player.mute(); 1305 player.playVideo(); 1306 audioButton.show(); 1307 } 1308 1309 if ( event.data === YT.PlayerState.ENDED && 1 === loop ) { 1310 if ( startTime > 0 ) { 1311 player.seekTo( startTime ); 1312 } 1313 else { 1314 player.playVideo(); 1315 } 1316 } 1317 1318 if ( event.data === YT.PlayerState.PLAYING ) { 1319 playPauseButton.removeClass( 'fa-play' ).addClass( 'fa-pause' ); 1320 } else if ( event.data === YT.PlayerState.PAUSED ) { 1321 playPauseButton.removeClass( 'fa-pause' ).addClass( 'fa-play' ); 1322 } else if ( event.data === YT.PlayerState.BUFFERING ) { 1323 playPauseButton.removeClass( 'fa-play' ).addClass( 'fa-pause' ); 1324 } else if ( event.data === YT.PlayerState.CUED ) { 1325 playPauseButton.removeClass( 'fa-pause' ).addClass( 'fa-play' ); 1326 } else if ( event.data === YT.PlayerState.ENDED ) { 1327 playPauseButton.removeClass( 'fa-pause' ).addClass( 'fa-play' ); 1328 } 1329 }, 1330 onError: function(event) { 1331 console.info('YT Error: ' + event.data) 1332 FLBuilderLayout._onErrorYoutubeVimeo(playerWrap) 1333 } 1334 }, 1335 playerVars: { 1336 playsinline: FLBuilderLayout._isMobile() ? 1 : 0, 1337 controls: 0, 1338 showinfo: 0, 1339 rel : 0, 1340 start: startTime, 1341 end: endTime, 1342 } 1343 } ); 1344 }, 1 ); 1345 } ); 1346 } 1347 }, 1348 1349 /** 1350 * On youtube or vimeo error show the fallback image if available. 1351 * @since 2.0.7 1352 */ 1353 _onErrorYoutubeVimeo: function(playerWrap) { 1354 1355 fallback = playerWrap.data('fallback') || false 1356 if( ! fallback ) { 1357 return false; 1358 } 1359 playerWrap.find('iframe').remove() 1360 fallbackTag = $( '<div></div>' ); 1361 fallbackTag.addClass( 'fl-bg-video-fallback' ); 1362 fallbackTag.css( 'background-image', 'url(' + playerWrap.data('fallback') + ')' ); 1363 playerWrap.append( fallbackTag ); 1364 }, 1365 1366 /** 1367 * Check if Youtube API has been downloaded 1368 * 1369 * @since 1.9 1370 * @access private 1371 * @method _onYoutubeApiReady 1372 * @param {Function} callback Method to call when YT API has been loaded 1373 */ 1374 _onYoutubeApiReady: function( callback ) { 1375 if ( window.YT && YT.loaded ) { 1376 callback( YT ); 1377 } else { 1378 // If not ready check again by timeout.. 1379 setTimeout( function() { 1380 FLBuilderLayout._onYoutubeApiReady( callback ); 1381 }, 350 ); 1382 } 1383 }, 1384 1385 /** 1386 * Initializes Vimeo video background 1387 * 1388 * @since 1.9 1389 * @access private 1390 * @method _initVimeoBgVideo 1391 */ 1392 _initVimeoBgVideo: function() 1393 { 1394 var playerWrap = $(this), 1395 videoId = playerWrap.data('video-id'), 1396 videoHash = playerWrap.data('video-hash'), 1397 videoPlayer = playerWrap.find('.fl-bg-video-player'), 1398 enableAudio = playerWrap.data('enable-audio'), 1399 audioButton = playerWrap.find('.fl-bg-video-audio'), 1400 playPauseButton = playerWrap.find('.fl-bg-video-play-pause-control'), 1401 playerState = '', 1402 player, 1403 width = playerWrap.outerWidth(), 1404 ua = navigator.userAgent; 1405 1406 if ( typeof Vimeo !== 'undefined' && videoId ) { 1407 1408 const vimOptions = { 1409 loop : true, 1410 title : false, 1411 portrait : false, 1412 background : true, 1413 autopause : false, 1414 muted : true, 1415 }; 1416 1417 if ( videoHash.length ) { 1418 vimOptions.url = `https://player.vimeo.com/video/${ videoId }?h=${ videoHash }`; 1419 } else { 1420 vimOptions.id = videoId; 1421 } 1422 1423 player = new Vimeo.Player(videoPlayer[0], vimOptions ); 1424 playerWrap.data('VMPlayer', player); 1425 if ( "no" === enableAudio ) { 1426 player.setVolume(0); 1427 } 1428 else if ("yes" === enableAudio ) { 1429 // Chrome, Safari, Firefox have audio policy restrictions for autoplay videos. 1430 if ( ua.indexOf("Safari") > -1 || ua.indexOf("Chrome") > -1 || ua.indexOf("Firefox") > -1 ) { 1431 player.setVolume(0); 1432 audioButton.show(); 1433 } 1434 else { 1435 player.setVolume(1); 1436 } 1437 } 1438 1439 player.play().catch(function(error) { 1440 FLBuilderLayout._onErrorYoutubeVimeo(playerWrap) 1441 }); 1442 1443 if ( audioButton.length > 0 ) {
1444 audioButton.on( 'click', {button: audioButton, player: player}, FLBuilderLayout._toggleBgVideoAudio ); 1445 } 1446 1447 player.on( 'play', function() { 1448 playerState = 'play'; 1449 playPauseButton.removeClass( 'fa-play' ).addClass( 'fa-pause' ); 1450 } ); 1451 player.on( 'pause', function() { 1452 playerState = 'pause'; 1453 playPauseButton.removeClass( 'fa-pause' ).addClass( 'fa-play' ); 1454 } ); 1455 player.on( 'ended', function() { 1456 playerState = 'ended'; 1457 playPauseButton.removeClass( 'fa-pause' ).addClass( 'fa-play' ); 1458 } ); 1459 player.on( 'bufferstart', function() { 1460 playerState = 'bufferstart'; 1461 playPauseButton.removeClass( 'fa-play' ).addClass( 'fa-pause' ); 1462 } ); 1463 1464 if ( playPauseButton.length > 0 ) { 1465 playPauseButton.on( 'click', { player: player }, function( e ) { 1466 var player = e.data.player; 1467 1468 if ( playerState === 'play' ) { 1469 player.pause(); 1470 } else { 1471 player.play(); 1472 } 1473 } ); 1474 } 1475 } 1476 }, 1477 1478 /** 1479 * Mute / unmute audio on row's video background. 1480 * It works for both Youtube and Vimeo. 1481 * 1482 * @since 2.1.3 1483 * @access private 1484 * @method _toggleBgVideoAudio 1485 * @param {Object} e Method arguments 1486 */ 1487 _toggleBgVideoAudio: function( e ) { 1488 var player = e.data.player, 1489 control = e.data.button.find('.fl-audio-control'); 1490 1491 if ( control.hasClass( 'fa-volume-off' ) ) { 1492 // Unmute 1493 control 1494 .removeClass( 'fa-volume-off' ) 1495 .addClass( 'fa-volume-up' ); 1496 e.data.button.find( '.fa-times' ).hide(); 1497 1498 if ( 'function' === typeof player.unMute ) { 1499 player.unMute(); 1500 } 1501 else { 1502 player.setVolume( 1 ); 1503 } 1504 } 1505 else { 1506 // Mute 1507 control 1508 .removeClass( 'fa-volume-up' ) 1509 .addClass( 'fa-volume-off' ); 1510 e.data.button.find( '.fa-times' ).show(); 1511 1512 if ( 'function' === typeof player.unMute ) { 1513 player.mute(); 1514 } 1515 else { 1516 player.setVolume( 0 ); 1517 } 1518 } 1519 }, 1520 1521 /** 1522 * Fires when there is an error loading a video 1523 * background source and shows the fallback. 1524 * 1525 * @since 1.6.3.3 1526 * @access private 1527 * @method _videoBgSourceError 1528 * @param {Object} e An event object 1529 * @deprecated 2.0.3 1530 */ 1531 _videoBgSourceError: function( e ) 1532 { 1533 var source = $( e.target ), 1534 wrap = source.closest( '.fl-bg-video' ), 1535 vid = wrap.find( 'video' ), 1536 fallback = wrap.data( 'fallback' ), 1537 fallbackTag = ''; 1538 source.remove(); 1539 1540 if ( vid.find( 'source' ).length ) { 1541 // Don't show the fallback if we still have other sources to check. 1542 return; 1543 } else if ( '' !== fallback ) { 1544 fallbackTag = $( '<div></div>' ); 1545 fallbackTag.addClass( 'fl-bg-video-fallback' ); 1546 fallbackTag.css( 'background-image', 'url(' + fallback + ')' ); 1547 wrap.append( fallbackTag ); 1548 vid.remove(); 1549 } 1550 }, 1551 1552 /** 1553 * Fires when the window is resized to resize 1554 * all video backgrounds. 1555 * 1556 * @since 1.1.4 1557 * @access private 1558 * @method _resizeBgVideos 1559 */ 1560 _resizeBgVideos: function() 1561 { 1562 $('.fl-bg-video').each( function() { 1563 1564 FLBuilderLayout._resizeBgVideo.apply( this ); 1565 1566 if ( $( this ).parent().find( 'img' ).length > 0 ) { 1567 $( this ).parent().imagesLoaded( $.proxy( FLBuilderLayout._resizeBgVideo, this ) ); 1568 } 1569 } ); 1570 }, 1571 1572 /** 1573 * Fires when the window is resized to resize 1574 * a single video background. 1575 * 1576 * @since 1.1.4 1577 * @access private 1578 * @method _resizeBgVideo 1579 */ 1580 _resizeBgVideo: function() 1581 { 1582 if ( 0 === $( this ).find( 'video' ).length && 0 === $( this ).find( 'iframe' ).length ) { 1583 return; 1584 } 1585 1586 var wrap = $(this), 1587 wrapHeight = wrap.outerHeight(), 1588 wrapWidth = wrap.outerWidth(), 1589 vid = wrap.find('video'), 1590 vidHeight = wrap.data('height'), 1591 vidWidth = wrap.data('width'), 1592 newWidth = wrapWidth, 1593 newHeight = Math.round(vidHeight * wrapWidth/vidWidth), 1594 newLeft = 0, 1595 newTop = 0, 1596 iframe = wrap.find('iframe'), 1597 isRowFullHeight = $(this).closest('.fl-row-bg-video').hasClass('fl-row-full-height'), 1598 vidCSS = { 1599 top: '50%', 1600 left: '50%', 1601 transform: 'translate(-50%,-50%)', 1602 }; 1603 1604 if ( vid.length ) { 1605 if(vidHeight === '' || typeof vidHeight === 'undefined' || vidWidth === '' || typeof vidWidth === 'undefined') { 1606 vid.css({ 1607 'left' : '0px', 1608 'top' : '0px', 1609 'width' : newWidth + 'px' 1610 }); 1611 1612 // Try to set the actual video dimension on 'loadedmetadata' when using URL as video source 1613 vid.on('loadedmetadata', FLBuilderLayout._resizeOnLoadedMeta); 1614 1615 return; 1616 } 1617 1618 if ( ! isRowFullHeight ) { 1619 if ( newHeight < wrapHeight ) { 1620 newHeight = wrapHeight; 1621 newLeft = -((newWidth - wrapWidth) / 2); 1622 newWidth = vidHeight ? Math.round(vidWidth * wrapHeight/vidHeight) : newWidth; 1623 } 1624 else { 1625 newTop = -((newHeight - wrapHeight)/2); 1626 } 1627 vidCSS = { 1628 left : newLeft + 'px', 1629 top : newTop + 'px', 1630 height : newHeight + 'px', 1631 width : newWidth + 'px', 1632 } 1633 } 1634 1635 vid.css( vidCSS ); 1636 1637 } 1638 else if ( iframe.length ) { 1639 1640 // Resize Youtube video player within iframe tag 1641 if ( typeof wrap.data('youtube') !== 'undefined' ) { 1642 FLBuilderLayout._resizeYoutubeBgVideo.apply(this); 1643 } 1644 } 1645 }, 1646 1647 /** 1648 * Fires when video meta has been loaded. 1649 * This will be Triggered when width/height attributes were not specified during video background resizing. 1650 * 1651 * @since 1.8.5 1652 * @access private 1653 * @method _resizeOnLoadedMeta 1654 */ 1655 _resizeOnLoadedMeta: function(){ 1656 var video = $(this), 1657 wrapHeight = video.parent().outerHeight(), 1658 wrapWidth = video.parent().outerWidth(), 1659 vidWidth = video[0].videoWidth, 1660 vidHeight = video[0].videoHeight, 1661 newHeight = Math.round(vidHeight * wrapWidth/vidWidth), 1662 newWidth = wrapWidth, 1663 newLeft = 0, 1664 newTop = 0; 1665 1666 if(newHeight < wrapHeight) { 1667 newHeight = wrapHeight; 1668 newWidth = Math.round(vidWidth * wrapHeight/vidHeight); 1669 newLeft = -((newWidth - wrapWidth)/2); 1670 } 1671 else { 1672 newTop = -((newHeight - wrapHeight)/2); 1673 } 1674 1675 video.parent().data('width', vidWidth); 1676 video.parent().data('height', vidHeight); 1677 1678 video.css({ 1679 'left' : newLeft + 'px', 1680 'top' : newTop + 'px', 1681 'width' : newWidth + 'px', 1682 'height' : newHeight + 'px' 1683 }); 1684 }, 1685 1686 /** 1687 * Fires when the window is resized to resize 1688 * a single Youtube video background. 1689 * 1690 * @since 1.9 1691 * @access private 1692 * @method _resizeYoutubeBgVideo 1693 */ 1694 _resizeYoutubeBgVideo: function() 1695 { 1696 var wrap = $(this), 1697 wrapWidth = wrap.outerWidth(), 1698 wrapHeight = wrap.outerHeight(), 1699 player = wrap.data('YTPlayer'), 1700 video = player ? player.getIframe() : null, 1701 aspectRatioSetting = '16:9', // Medium 1702 aspectRatioArray = aspectRatioSetting.split( ':' ),
1703 aspectRatio = aspectRatioArray[0] / aspectRatioArray[1], 1704 ratioWidth = wrapWidth / aspectRatio, 1705 ratioHeight = wrapHeight * aspectRatio, 1706 isWidthFixed = wrapWidth / wrapHeight > aspectRatio, 1707 width = isWidthFixed ? wrapWidth : ratioHeight, 1708 height = isWidthFixed ? ratioWidth : wrapHeight; 1709 1710 if ( video ) { 1711 $(video).width( width ).height( height ); 1712 } 1713 }, 1714 1715 /** 1716 * Opens a tab or accordion item if the browser hash is set 1717 * to the ID of one on the page. 1718 * 1719 * @since 1.6.0 1720 * @access private 1721 * @method _initHash 1722 */ 1723 _initHash: function() 1724 { 1725 var hash = window.location.hash.replace( '#', '' ).split( '/' ).shift(), 1726 element = null, 1727 tabs = null, 1728 responsiveLabel = null, 1729 tabIndex = null, 1730 label = null; 1731 1732 if ( '' !== hash ) { 1733 1734 try { 1735 1736 element = $( '#' + hash ); 1737 1738 if ( element.length > 0 ) { 1739 1740 if ( element.hasClass( 'fl-accordion-item' ) ) { 1741 setTimeout( function() { 1742 element.find( '.fl-accordion-button' ).trigger( 'click' ); 1743 }, 100 ); 1744 } 1745 if ( element.hasClass( 'fl-tabs-panel' ) ) { 1746 setTimeout( function() { 1747 tabs = element.closest( '.fl-tabs' ); 1748 responsiveLabel = element.find( '.fl-tabs-panel-label' ); 1749 tabIndex = responsiveLabel.data( 'index' ); 1750 label = tabs.find( '.fl-tabs-labels .fl-tabs-label[data-index=' + tabIndex + ']' ); 1751 1752 label[0].click(); 1753 FLBuilderLayout._scrollToElement(element); 1754 }, 100 ); 1755 } 1756 } 1757 } 1758 catch( e ) {} 1759 } 1760 }, 1761 1762 /** 1763 * Initializes all anchor links on the page for smooth scrolling. 1764 * 1765 * @since 1.4.9 1766 * @access private 1767 * @method _initAnchorLinks 1768 */ 1769 _initAnchorLinks: function() 1770 { 1771 $( 'a, [role="link"]' ).each( FLBuilderLayout._initAnchorLink ); 1772 }, 1773 1774 /** 1775 * Initializes a single anchor link for smooth scrolling. 1776 * 1777 * @since 1.4.9 1778 * @access private 1779 * @method _initAnchorLink 1780 */ 1781 _initAnchorLink: function() 1782 { 1783 var link = $( this ), 1784 href = link.data( 'url' ) ? link.data( 'url' ) : link.attr( 'href' ), 1785 target = link.data( 'url' ) ? new URL( href, window.location.href ) : this, 1786 loc = window.location, 1787 id = null, 1788 element = null, 1789 flNode = false; 1790 1791 if ( 'undefined' != typeof href && href.indexOf( '#' ) > -1 && link.closest('svg').length < 1 ) { 1792 1793 if ( loc.pathname.replace( /^\//, '' ) == target.pathname.replace( /^\//, '' ) && loc.hostname == target.hostname ) { 1794 1795 try { 1796 1797 id = href.split( '#' ).pop(); 1798 // If there is no ID then we have nowhere to look 1799 // Fixes a quirk in jQuery and FireFox 1800 if( ! id ) { 1801 return; 1802 } 1803 element = $( '#' + id ); 1804 1805 if ( element.length > 0 ) { 1806 flNode = element.hasClass( 'fl-row' ) || element.hasClass( 'fl-col' ) || element.hasClass( 'fl-module' ); 1807 if ( !element.hasClass( 'fl-no-scroll' ) && ( link.hasClass( 'fl-scroll-link' ) || flNode ) ) { 1808 $( link ).on( 'click', FLBuilderLayout._scrollToElementOnLinkClick ); 1809 } 1810 if ( element.hasClass( 'fl-accordion-item' ) ) { 1811 $( link ).on( 'click', FLBuilderLayout._scrollToAccordionOnLinkClick ); 1812 } 1813 if ( element.hasClass( 'fl-tabs-panel' ) ) { 1814 $( link ).on( 'click', FLBuilderLayout._scrollToTabOnLinkClick ); 1815 } 1816 } 1817 } 1818 catch( e ) {} 1819 } 1820 } 1821 }, 1822 1823 /** 1824 * Scrolls to an element when an anchor link is clicked. 1825 * 1826 * @since 1.4.9 1827 * @access private 1828 * @method _scrollToElementOnLinkClick 1829 * @param {Object} e An event object. 1830 * @param {Function} callback A function to call when the scroll is complete. 1831 */ 1832 _scrollToElementOnLinkClick: function( e, callback ) 1833 { 1834 var attribute = $( this ).data( 'url' ) ? $( this ).data( 'url' ) : $( this ).attr( 'href' ); 1835 var element = $( '#' + attribute.split( '#' ).pop() ); 1836 1837 FLBuilderLayout._scrollToElement( element, callback ); 1838 1839 e.preventDefault(); 1840 }, 1841 1842 /** 1843 * Scrolls to an element. 1844 * 1845 * @since 1.6.4.5 1846 * @access private 1847 * @method _scrollToElement 1848 * @param {Object} element The element to scroll to. 1849 * @param {Function} callback A function to call when the scroll is complete. 1850 */ 1851 _scrollToElement: function( element, callback ) 1852 { 1853 var config = FLBuilderLayoutConfig.anchorLinkAnimations, 1854 dest = 0, 1855 win = $( window ), 1856 doc = $( document ); 1857 1858 if ( element.length > 0 ) { 1859 1860 if ( 'fixed' === element.css('position') || 'fixed' === element.parent().css('position') ) { 1861 dest = element.position().top; 1862 } 1863 else if ( element.offset().top > doc.height() - win.height() ) { 1864 dest = doc.height() - win.height(); 1865 } 1866 else { 1867 dest = element.offset().top - config.offset; 1868 } 1869 1870 $( 'html, body' ).stop( true ).animate( { scrollTop: dest }, config.duration, config.easing, function() { 1871 1872 if ( 'undefined' != typeof callback ) { 1873 callback(); 1874 } 1875 1876 if ( undefined != element.attr( 'id' ) && window.location.hash !== '#' + element.attr( 'id' ) ) { 1877 1878 var firefox_version = window.navigator.userAgent.match( /Firefox\/(\d+)\./ ), 1879 firefox_version = firefox_version ? parseInt( firefox_version[1], 10 ) : null; 1880 1881 if ( firefox_version !== null && firefox_version < 135 ) { 1882 window.location.hash = element.attr( 'id' ); 1883 } else { 1884 if ( history.pushState ) { 1885 history.pushState( null, null, '#' + element.attr( 'id' ) ); 1886 } else { 1887 window.location.hash = element.attr( 'id' ); 1888 } 1889 } 1890 } 1891 } ); 1892 } 1893 }, 1894 1895 /** 1896 * Scrolls to an accordion item when a link is clicked. 1897 * 1898 * @since 1.5.9 1899 * @access private 1900 * @method _scrollToAccordionOnLinkClick 1901 * @param {Object} e An event object. 1902 */ 1903 _scrollToAccordionOnLinkClick: function( e ) 1904 { 1905 var element = $( '#' + $( this ).attr( 'href' ).split( '#' ).pop() ); 1906 1907 if ( element.length > 0 ) { 1908 1909 var callback = function() { 1910 if ( element ) { 1911 element.find( '.fl-accordion-button' ).trigger( 'click' ); 1912 element = false;
1913 } 1914 }; 1915 1916 FLBuilderLayout._scrollToElementOnLinkClick.call( this, e, callback ); 1917 } 1918 }, 1919 1920 /** 1921 * Scrolls to a tab panel when a link is clicked. 1922 * 1923 * @since 1.5.9 1924 * @access private 1925 * @method _scrollToTabOnLinkClick 1926 * @param {Object} e An event object. 1927 */ 1928 _scrollToTabOnLinkClick: function( e ) 1929 { 1930 var element = $( '#' + $( this ).attr( 'href' ).split( '#' ).pop() ), 1931 tabs = null, 1932 label = null, 1933 responsiveLabel = null; 1934 1935 if ( element.length > 0 ) { 1936 1937 tabs = element.closest( '.fl-tabs' ); 1938 responsiveLabel = element.find( '.fl-tabs-panel-label' ); 1939 tabIndex = responsiveLabel.data( 'index' ); 1940 label = tabs.find( '.fl-tabs-labels .fl-tabs-label[data-index=' + tabIndex + ']' ); 1941 1942 if ( responsiveLabel.is( ':visible' ) ) { 1943 1944 var callback = function() { 1945 if ( element ) { 1946 responsiveLabel.trigger( $.Event( 'click', { which: 1 } ) ); 1947 } 1948 }; 1949 1950 FLBuilderLayout._scrollToElementOnLinkClick.call( this, e, callback ); 1951 } 1952 else { 1953 label[0].click(); 1954 FLBuilderLayout._scrollToElement( element ); 1955 } 1956 1957 e.preventDefault(); 1958 } 1959 }, 1960 1961 /** 1962 * Initializes all builder forms on a page. 1963 * 1964 * @since 1.5.4 1965 * @access private 1966 * @method _initForms 1967 */ 1968 _initForms: function() 1969 { 1970 if ( ! FLBuilderLayout._hasPlaceholderSupport ) { 1971 $( '.fl-form-field input' ).each( FLBuilderLayout._initFormFieldPlaceholderFallback ); 1972 } 1973 1974 $( '.fl-form-field input' ).on( 'focus', FLBuilderLayout._clearFormFieldError ); 1975 }, 1976 1977 /** 1978 * Checks to see if the current device has HTML5 1979 * placeholder support. 1980 * 1981 * @since 1.5.4 1982 * @access private 1983 * @method _hasPlaceholderSupport 1984 * @return {Boolean} 1985 */ 1986 _hasPlaceholderSupport: function() 1987 { 1988 var input = document.createElement( 'input' ); 1989 1990 return 'undefined' != input.placeholder; 1991 }, 1992 1993 /** 1994 * Initializes the fallback for when placeholders aren't supported. 1995 * 1996 * @since 1.5.4 1997 * @access private 1998 * @method _initFormFieldPlaceholderFallback 1999 */ 2000 _initFormFieldPlaceholderFallback: function() 2001 { 2002 var field = $( this ), 2003 val = field.val(), 2004 placeholder = field.attr( 'placeholder' ); 2005 2006 if ( 'undefined' != placeholder && '' === val ) { 2007 field.val( placeholder ); 2008 field.on( 'focus', FLBuilderLayout._hideFormFieldPlaceholderFallback ); 2009 field.on( 'blur', FLBuilderLayout._showFormFieldPlaceholderFallback ); 2010 } 2011 }, 2012 2013 /** 2014 * Hides a fallback placeholder on focus. 2015 * 2016 * @since 1.5.4 2017 * @access private 2018 * @method _hideFormFieldPlaceholderFallback 2019 */ 2020 _hideFormFieldPlaceholderFallback: function() 2021 { 2022 var field = $( this ), 2023 val = field.val(), 2024 placeholder = field.attr( 'placeholder' ); 2025 2026 if ( val == placeholder ) { 2027 field.val( '' ); 2028 } 2029 }, 2030 2031 /** 2032 * Shows a fallback placeholder on blur. 2033 * 2034 * @since 1.5.4 2035 * @access private 2036 * @method _showFormFieldPlaceholderFallback 2037 */ 2038 _showFormFieldPlaceholderFallback: function() 2039 { 2040 var field = $( this ), 2041 val = field.val(), 2042 placeholder = field.attr( 'placeholder' ); 2043 2044 if ( '' === val ) { 2045 field.val( placeholder ); 2046 } 2047 }, 2048 2049 /** 2050 * Clears a form field error message. 2051 * 2052 * @since 1.5.4 2053 * @access private 2054 * @method _clearFormFieldError 2055 */ 2056 _clearFormFieldError: function() 2057 { 2058 var field = $( this ); 2059 2060 field.removeAttr( 'aria-invalid' ); 2061 field.removeClass( 'fl-form-error' ); 2062 const message = field.attr('aria-describedby'); 2063 message ? $( '#' + message ).hide() : field.siblings( '.fl-form-error-message' ).hide(); 2064 }, 2065 2066 /** 2067 * Init Row Shape Layer's height. 2068 * 2069 * @since 2.5.3 2070 * @access private 2071 * @method _initRowShapeLayerHeight 2072 */ 2073 _initRowShapeLayerHeight: function () { 2074 FLBuilderLayout._adjustRowShapeLayerHeight(); 2075 $( window ).on( 'resize', FLBuilderLayout._adjustRowShapeLayerHeight ); 2076 }, 2077 2078 /** 2079 * Set parent column width of nested columns when it's zero or blank. 2080 * 2081 * @since 2.7.4 2082 * @access private 2083 * @method _initNestedColsWidth 2084 */ 2085 _initNestedColsWidth: function() 2086 { 2087 var nestedCols = $( '.fl-col-has-cols' ); 2088 2089 if ( nestedCols.length <= 0 ) { 2090 return; 2091 } 2092 2093 $( nestedCols ).each( function(index, col ){ 2094 if ( $( col ).width() <= 0 ) { 2095 $( col ).css( 'width', FLBuilderLayoutConfig.emptyColWidth ); 2096 } 2097 }); 2098 }, 2099 2100 /** 2101 * Adjust Row Shape Layer's height to fix to remove the fine line that appears on certain screen sizes. 2102 * 2103 * @since 2.5.3 2104 * @access private 2105 * @method _adjustRowShapeLayerHeight 2106 */
2107 _adjustRowShapeLayerHeight: function() { 2108 var rowShapeLayers = $('.fl-builder-shape-layer'); 2109 2110 $( rowShapeLayers ).each(function (index) { 2111 var rowShapeLayer = $(this), 2112 shape = $(rowShapeLayer).find('svg'), 2113 height = shape.height(), 2114 excludeShapes = '.fl-builder-shape-circle, .fl-builder-shape-dot-cluster, .fl-builder-shape-topography, .fl-builder-shape-rect'; 2115 2116 if ( ! rowShapeLayer.is( excludeShapes ) ) { 2117 $(shape).css('height', Math.ceil( height ) ); 2118 } 2119 }); 2120 }, 2121 _string_to_slug: function( str ) { 2122 str = str.replace(/^\s+|\s+$/g, ''); // trim 2123 if ( 'undefined' == typeof window._fl_string_to_slug_regex ) { 2124 regex = new RegExp('[^a-zA-Z0-9\'":() !.,-_|]', 'g'); 2125 } else { 2126 regex = new RegExp('[^' + window._fl_string_to_slug_regex + '\'":\(\) !.,-_|\\\p{Letter}]', 'ug'); 2127 } 2128 str = str.replace(regex, '') // remove invalid chars 2129 .replace(/\s+/g, ' '); // collapse whitespace and replace by a space 2130 return str; 2131 }, 2132 _reorderMenu: function() { 2133 if ( $('#wp-admin-bar-fl-builder-frontend-edit-link-default li').length > 1 ) { 2134 $( '#wp-admin-bar-fl-builder-frontend-duplicate-link' ) 2135 .appendTo('#wp-admin-bar-fl-builder-frontend-edit-link-default') 2136 .css( 'padding-top', '5px' ) 2137 .css( 'border-top', '2px solid #1D2125' ) 2138 .css( 'margin-top', '5px' ) 2139 } 2140 } 2141 }; 2142 2143 /* Initializes the builder layout. */ 2144 $(function(){ 2145 FLBuilderLayout.init(); 2146 }); 2147 2148})(jQuery); 2149(function($){ 2150 2151 if(typeof FLBuilderLayoutModules !== 'undefined') { 2152 return; 2153 } 2154 2155 /** 2156 * Helper class with generic logic for builder modules. 2157 * If generic module code needs to work in both the block 2158 * editor and builder, it should go here. Otherwise, it 2159 * should go on FLBuilderLayout. 2160 * 2161 * @since 2.9 2162 */ 2163 FLBuilderLayoutModules = { 2164 2165 /** 2166 * Initializes builder module logic. 2167 * 2168 * @since 2.9 2169 * @method init 2170 */ 2171 init: function() 2172 { 2173 // Only init if the builder isn't active. 2174 if ( 0 === $('.fl-builder-edit').length ) { 2175 2176 // Init module animations. 2177 FLBuilderLayoutModules._initModuleAnimations(); 2178 } 2179 }, 2180 2181 /** 2182 * Initializes module animations. 2183 * 2184 * @since 1.1.9 2185 * @access private 2186 * @method _initModuleAnimations 2187 */ 2188 _initModuleAnimations: function() 2189 { 2190 if(typeof jQuery.fn.waypoint !== 'undefined') { 2191 $('.fl-animation').each( function() { 2192 var node = $( this ), 2193 nodeTop = node.offset().top, 2194 winHeight = $( window ).height(), 2195 bodyHeight = $( 'body' ).height(), 2196 waypoint = FLBuilderLayoutConfig.waypoint, 2197 offset = '80%'; 2198 2199 if ( typeof waypoint.offset !== undefined ) { 2200 offset = FLBuilderLayoutConfig.waypoint.offset + '%'; 2201 } 2202 2203 if ( bodyHeight - nodeTop < winHeight * 0.2 ) { 2204 offset = '100%'; 2205 } 2206 2207 node.waypoint({ 2208 offset: offset, 2209 handler: FLBuilderLayoutModules._doModuleAnimation 2210 }); 2211 } ); 2212 } 2213 }, 2214 2215 /** 2216 * Runs a module animation. 2217 * 2218 * @since 1.1.9 2219 * @access private 2220 * @method _doModuleAnimation 2221 */ 2222 _doModuleAnimation: function() 2223 { 2224 var module = 'undefined' == typeof this.element ? $(this) : $(this.element), 2225 delay = parseFloat(module.data('animation-delay')), 2226 duration = parseFloat(module.data('animation-duration')); 2227 2228 if ( ! isNaN( duration ) ) { 2229 module.css( 'animation-duration', duration + 's' ); 2230 } 2231 2232 if(!isNaN(delay) && delay > 0) { 2233 setTimeout(function(){ 2234 module.addClass('fl-animated'); 2235 }, delay * 1000); 2236 } else { 2237 setTimeout(function(){ 2238 module.addClass('fl-animated'); 2239 }, 1); 2240 } 2241 } 2242 }; 2243 2244 /* Initializes builder module logic. */ 2245 $(function(){ 2246 FLBuilderLayoutModules.init(); 2247 }); 2248 2249})(jQuery); 2250 2251/* Start Global JS */ 2252 2253/* End Global JS */ 2254 2255(function($){ 2256 })(jQuery); 2257 2258/* Start Global Node Custom JS */ 2259 2260/* End Global Node Custom JS */ 2261 2262 2263/* Start Layout Custom JS */ 2264 2265/* End Layout Custom JS */ 2266
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.