vendor: 14,874 bytes, lines 1-513
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://willzies.com/wp-admin/admin-ajax.php';var flBuilderUrl = 'https://willzies.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://willzies.com/wp-content/plugins/bb-plugin/', 630 wpAjaxUrl : 'https://willzies.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. 921 if ( ! 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' ).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.attr( 'href' ), 1785 loc = window.location, 1786 id = null, 1787 element = null, 1788 flNode = false; 1789 1790 if ( 'undefined' != typeof href && href.indexOf( '#' ) > -1 && link.closest('svg').length < 1 ) { 1791 1792 if ( loc.pathname.replace( /^\//, '' ) == this.pathname.replace( /^\//, '' ) && loc.hostname == this.hostname ) { 1793 1794 try { 1795 1796 id = href.split( '#' ).pop(); 1797 // If there is no ID then we have nowhere to look 1798 // Fixes a quirk in jQuery and FireFox 1799 if( ! id ) { 1800 return; 1801 } 1802 element = $( '#' + id ); 1803 1804 if ( element.length > 0 ) { 1805 flNode = element.hasClass( 'fl-row' ) || element.hasClass( 'fl-col' ) || element.hasClass( 'fl-module' ); 1806 if ( !element.hasClass( 'fl-no-scroll' ) && ( link.hasClass( 'fl-scroll-link' ) || flNode ) ) { 1807 $( link ).on( 'click', FLBuilderLayout._scrollToElementOnLinkClick ); 1808 } 1809 if ( element.hasClass( 'fl-accordion-item' ) ) { 1810 $( link ).on( 'click', FLBuilderLayout._scrollToAccordionOnLinkClick ); 1811 } 1812 if ( element.hasClass( 'fl-tabs-panel' ) ) { 1813 $( link ).on( 'click', FLBuilderLayout._scrollToTabOnLinkClick ); 1814 } 1815 } 1816 } 1817 catch( e ) {} 1818 } 1819 } 1820 }, 1821 1822 /** 1823 * Scrolls to an element when an anchor link is clicked. 1824 * 1825 * @since 1.4.9 1826 * @access private 1827 * @method _scrollToElementOnLinkClick 1828 * @param {Object} e An event object. 1829 * @param {Function} callback A function to call when the scroll is complete. 1830 */ 1831 _scrollToElementOnLinkClick: function( e, callback ) 1832 { 1833 var element = $( '#' + $( this ).attr( 'href' ).split( '#' ).pop() ); 1834 1835 FLBuilderLayout._scrollToElement( element, callback ); 1836 1837 e.preventDefault(); 1838 }, 1839 1840 /** 1841 * Scrolls to an element. 1842 * 1843 * @since 1.6.4.5 1844 * @access private 1845 * @method _scrollToElement 1846 * @param {Object} element The element to scroll to. 1847 * @param {Function} callback A function to call when the scroll is complete. 1848 */ 1849 _scrollToElement: function( element, callback ) 1850 { 1851 var config = FLBuilderLayoutConfig.anchorLinkAnimations, 1852 dest = 0, 1853 win = $( window ), 1854 doc = $( document ); 1855 1856 if ( element.length > 0 ) { 1857 1858 if ( 'fixed' === element.css('position') || 'fixed' === element.parent().css('position') ) { 1859 dest = element.position().top; 1860 } 1861 else if ( element.offset().top > doc.height() - win.height() ) { 1862 dest = doc.height() - win.height(); 1863 } 1864 else { 1865 dest = element.offset().top - config.offset; 1866 } 1867 1868 $( 'html, body' ).stop( true ).animate( { scrollTop: dest }, config.duration, config.easing, function() { 1869 1870 if ( 'undefined' != typeof callback ) { 1871 callback(); 1872 } 1873 1874 if ( undefined != element.attr( 'id' ) && window.location.hash !== '#' + element.attr( 'id' ) ) { 1875 1876 var firefox_version = window.navigator.userAgent.match( /Firefox\/(\d+)\./ ), 1877 firefox_version = firefox_version ? parseInt( firefox_version[1], 10 ) : null; 1878 1879 if ( firefox_version !== null && firefox_version < 135 ) { 1880 window.location.hash = element.attr( 'id' ); 1881 } else { 1882 if ( history.pushState ) { 1883 history.pushState( null, null, '#' + element.attr( 'id' ) ); 1884 } else { 1885 window.location.hash = element.attr( 'id' ); 1886 } 1887 } 1888 } 1889 } ); 1890 } 1891 }, 1892 1893 /** 1894 * Scrolls to an accordion item when a link is clicked. 1895 * 1896 * @since 1.5.9 1897 * @access private 1898 * @method _scrollToAccordionOnLinkClick 1899 * @param {Object} e An event object. 1900 */ 1901 _scrollToAccordionOnLinkClick: function( e ) 1902 { 1903 var element = $( '#' + $( this ).attr( 'href' ).split( '#' ).pop() ); 1904 1905 if ( element.length > 0 ) { 1906 1907 var callback = function() { 1908 if ( element ) { 1909 element.find( '.fl-accordion-button' ).trigger( 'click' ); 1910 element = false;
1911 } 1912 }; 1913 1914 FLBuilderLayout._scrollToElementOnLinkClick.call( this, e, callback ); 1915 } 1916 }, 1917 1918 /** 1919 * Scrolls to a tab panel when a link is clicked. 1920 * 1921 * @since 1.5.9 1922 * @access private 1923 * @method _scrollToTabOnLinkClick 1924 * @param {Object} e An event object. 1925 */ 1926 _scrollToTabOnLinkClick: function( e ) 1927 { 1928 var element = $( '#' + $( this ).attr( 'href' ).split( '#' ).pop() ), 1929 tabs = null, 1930 label = null, 1931 responsiveLabel = null; 1932 1933 if ( element.length > 0 ) { 1934 1935 tabs = element.closest( '.fl-tabs' ); 1936 responsiveLabel = element.find( '.fl-tabs-panel-label' ); 1937 tabIndex = responsiveLabel.data( 'index' ); 1938 label = tabs.find( '.fl-tabs-labels .fl-tabs-label[data-index=' + tabIndex + ']' ); 1939 1940 if ( responsiveLabel.is( ':visible' ) ) { 1941 1942 var callback = function() { 1943 if ( element ) { 1944 responsiveLabel.trigger( $.Event( 'click', { which: 1 } ) ); 1945 } 1946 }; 1947 1948 FLBuilderLayout._scrollToElementOnLinkClick.call( this, e, callback ); 1949 } 1950 else { 1951 label[0].click(); 1952 FLBuilderLayout._scrollToElement( element ); 1953 } 1954 1955 e.preventDefault(); 1956 } 1957 }, 1958 1959 /** 1960 * Initializes all builder forms on a page. 1961 * 1962 * @since 1.5.4 1963 * @access private 1964 * @method _initForms 1965 */ 1966 _initForms: function() 1967 { 1968 if ( ! FLBuilderLayout._hasPlaceholderSupport ) { 1969 $( '.fl-form-field input' ).each( FLBuilderLayout._initFormFieldPlaceholderFallback ); 1970 } 1971 1972 $( '.fl-form-field input' ).on( 'focus', FLBuilderLayout._clearFormFieldError ); 1973 }, 1974 1975 /** 1976 * Checks to see if the current device has HTML5 1977 * placeholder support. 1978 * 1979 * @since 1.5.4 1980 * @access private 1981 * @method _hasPlaceholderSupport 1982 * @return {Boolean} 1983 */ 1984 _hasPlaceholderSupport: function() 1985 { 1986 var input = document.createElement( 'input' ); 1987 1988 return 'undefined' != input.placeholder; 1989 }, 1990 1991 /** 1992 * Initializes the fallback for when placeholders aren't supported. 1993 * 1994 * @since 1.5.4 1995 * @access private 1996 * @method _initFormFieldPlaceholderFallback 1997 */ 1998 _initFormFieldPlaceholderFallback: function() 1999 { 2000 var field = $( this ), 2001 val = field.val(), 2002 placeholder = field.attr( 'placeholder' ); 2003 2004 if ( 'undefined' != placeholder && '' === val ) { 2005 field.val( placeholder ); 2006 field.on( 'focus', FLBuilderLayout._hideFormFieldPlaceholderFallback ); 2007 field.on( 'blur', FLBuilderLayout._showFormFieldPlaceholderFallback ); 2008 } 2009 }, 2010 2011 /** 2012 * Hides a fallback placeholder on focus. 2013 * 2014 * @since 1.5.4 2015 * @access private 2016 * @method _hideFormFieldPlaceholderFallback 2017 */ 2018 _hideFormFieldPlaceholderFallback: function() 2019 { 2020 var field = $( this ), 2021 val = field.val(), 2022 placeholder = field.attr( 'placeholder' ); 2023 2024 if ( val == placeholder ) { 2025 field.val( '' ); 2026 } 2027 }, 2028 2029 /** 2030 * Shows a fallback placeholder on blur. 2031 * 2032 * @since 1.5.4 2033 * @access private 2034 * @method _showFormFieldPlaceholderFallback 2035 */ 2036 _showFormFieldPlaceholderFallback: function() 2037 { 2038 var field = $( this ), 2039 val = field.val(), 2040 placeholder = field.attr( 'placeholder' ); 2041 2042 if ( '' === val ) { 2043 field.val( placeholder ); 2044 } 2045 }, 2046 2047 /** 2048 * Clears a form field error message. 2049 * 2050 * @since 1.5.4 2051 * @access private 2052 * @method _clearFormFieldError 2053 */ 2054 _clearFormFieldError: function() 2055 { 2056 var field = $( this ); 2057 2058 field.removeAttr( 'aria-invalid' ); 2059 field.removeClass( 'fl-form-error' ); 2060 const message = field.attr('aria-describedby'); 2061 message ? $( '#' + message ).hide() : field.siblings( '.fl-form-error-message' ).hide(); 2062 }, 2063 2064 /** 2065 * Init Row Shape Layer's height. 2066 * 2067 * @since 2.5.3 2068 * @access private 2069 * @method _initRowShapeLayerHeight 2070 */ 2071 _initRowShapeLayerHeight: function () { 2072 FLBuilderLayout._adjustRowShapeLayerHeight(); 2073 $( window ).on( 'resize', FLBuilderLayout._adjustRowShapeLayerHeight ); 2074 }, 2075 2076 /** 2077 * Set parent column width of nested columns when it's zero or blank. 2078 * 2079 * @since 2.7.4 2080 * @access private 2081 * @method _initNestedColsWidth 2082 */ 2083 _initNestedColsWidth: function() 2084 { 2085 var nestedCols = $( '.fl-col-has-cols' ); 2086 2087 if ( nestedCols.length <= 0 ) { 2088 return; 2089 } 2090 2091 $( nestedCols ).each( function(index, col ){ 2092 if ( $( col ).width() <= 0 ) { 2093 $( col ).css( 'width', FLBuilderLayoutConfig.emptyColWidth ); 2094 } 2095 }); 2096 }, 2097 2098 /** 2099 * Adjust Row Shape Layer's height to fix to remove the fine line that appears on certain screen sizes. 2100 * 2101 * @since 2.5.3 2102 * @access private 2103 * @method _adjustRowShapeLayerHeight 2104 */
2105 _adjustRowShapeLayerHeight: function() { 2106 var rowShapeLayers = $('.fl-builder-shape-layer'); 2107 2108 $( rowShapeLayers ).each(function (index) { 2109 var rowShapeLayer = $(this), 2110 shape = $(rowShapeLayer).find('svg'), 2111 height = shape.height(), 2112 excludeShapes = '.fl-builder-shape-circle, .fl-builder-shape-dot-cluster, .fl-builder-shape-topography, .fl-builder-shape-rect'; 2113 2114 if ( ! rowShapeLayer.is( excludeShapes ) ) { 2115 $(shape).css('height', Math.ceil( height ) ); 2116 } 2117 }); 2118 }, 2119 _string_to_slug: function( str ) { 2120 str = str.replace(/^\s+|\s+$/g, ''); // trim 2121 if ( 'undefined' == typeof window._fl_string_to_slug_regex ) { 2122 regex = new RegExp('[^a-zA-Z0-9\'":() !.,-_|]', 'g'); 2123 } else { 2124 regex = new RegExp('[^' + window._fl_string_to_slug_regex + '\'":\(\) !.,-_|\\\p{Letter}]', 'ug'); 2125 } 2126 str = str.replace(regex, '') // remove invalid chars 2127 .replace(/\s+/g, ' '); // collapse whitespace and replace by a space 2128 return str; 2129 }, 2130 _reorderMenu: function() { 2131 if ( $('#wp-admin-bar-fl-builder-frontend-edit-link-default li').length > 1 ) { 2132 $( '#wp-admin-bar-fl-builder-frontend-duplicate-link' ) 2133 .appendTo('#wp-admin-bar-fl-builder-frontend-edit-link-default') 2134 .css( 'padding-top', '5px' ) 2135 .css( 'border-top', '2px solid #1D2125' ) 2136 .css( 'margin-top', '5px' ) 2137 } 2138 } 2139 }; 2140 2141 /* Initializes the builder layout. */ 2142 $(function(){ 2143 FLBuilderLayout.init(); 2144 }); 2145 2146})(jQuery); 2147(function($){ 2148 2149 if(typeof FLBuilderLayoutModules !== 'undefined') { 2150 return; 2151 } 2152 2153 /** 2154 * Helper class with generic logic for builder modules. 2155 * If generic module code needs to work in both the block 2156 * editor and builder, it should go here. Otherwise, it 2157 * should go on FLBuilderLayout. 2158 * 2159 * @since 2.9 2160 */ 2161 FLBuilderLayoutModules = { 2162 2163 /** 2164 * Initializes builder module logic. 2165 * 2166 * @since 2.9 2167 * @method init 2168 */ 2169 init: function() 2170 { 2171 // Only init if the builder isn't active. 2172 if ( 0 === $('.fl-builder-edit').length ) { 2173 2174 // Init module animations. 2175 FLBuilderLayoutModules._initModuleAnimations(); 2176 } 2177 }, 2178 2179 /** 2180 * Initializes module animations. 2181 * 2182 * @since 1.1.9 2183 * @access private 2184 * @method _initModuleAnimations 2185 */ 2186 _initModuleAnimations: function() 2187 { 2188 if(typeof jQuery.fn.waypoint !== 'undefined') { 2189 $('.fl-animation').each( function() { 2190 var node = $( this ), 2191 nodeTop = node.offset().top, 2192 winHeight = $( window ).height(), 2193 bodyHeight = $( 'body' ).height(), 2194 waypoint = FLBuilderLayoutConfig.waypoint, 2195 offset = '80%'; 2196 2197 if ( typeof waypoint.offset !== undefined ) { 2198 offset = FLBuilderLayoutConfig.waypoint.offset + '%'; 2199 } 2200 2201 if ( bodyHeight - nodeTop < winHeight * 0.2 ) { 2202 offset = '100%'; 2203 } 2204 2205 node.waypoint({ 2206 offset: offset, 2207 handler: FLBuilderLayoutModules._doModuleAnimation 2208 }); 2209 } ); 2210 } 2211 }, 2212 2213 /** 2214 * Runs a module animation. 2215 * 2216 * @since 1.1.9 2217 * @access private 2218 * @method _doModuleAnimation 2219 */ 2220 _doModuleAnimation: function() 2221 { 2222 var module = 'undefined' == typeof this.element ? $(this) : $(this.element), 2223 delay = parseFloat(module.data('animation-delay')), 2224 duration = parseFloat(module.data('animation-duration')); 2225 2226 if ( ! isNaN( duration ) ) { 2227 module.css( 'animation-duration', duration + 's' ); 2228 } 2229 2230 if(!isNaN(delay) && delay > 0) { 2231 setTimeout(function(){ 2232 module.addClass('fl-animated'); 2233 }, delay * 1000); 2234 } else { 2235 setTimeout(function(){ 2236 module.addClass('fl-animated'); 2237 }, 1); 2238 } 2239 } 2240 }; 2241 2242 /* Initializes builder module logic. */ 2243 $(function(){ 2244 FLBuilderLayoutModules.init(); 2245 }); 2246 2247})(jQuery); 2248 2249/* Start Global JS */ 2250 2251/* End Global JS */ 2252 2253 2254;/** 2255 * This file should contain frontend logic for 2256 * all module instances. 2257 */(function($) { 2258 $('.fl-node-fiyrcmq7g5np .pp-hover-card').each( function() { 2259 $( this ).on( 'focus', function() { 2260 $( this ).addClass( 'focus' ); 2261 } ).on( 'blur', function(e) { 2262 if ( $( e.relatedTarget ).closest( this ).length > 0 ) { 2263 return; 2264 } 2265 $( this ).removeClass( 'focus' ); 2266 } ); 2267 }); 2268 2269 $( document ).on( 'click focus keyup', function(e) { 2270 if ( $(e.target).closest( '.fl-node-fiyrcmq7g5np .pp-hover-card' ).length > 0 ) { 2271 return; 2272 } 2273 $('.fl-node-fiyrcmq7g5np .pp-hover-card').removeClass('focus'); 2274 } ); 2275})(jQuery);(function($) { 2276 $('.fl-node-6fnm9zdvoclq .pp-hover-card').each( function() { 2277 $( this ).on( 'focus', function() { 2278 $( this ).addClass( 'focus' ); 2279 } ).on( 'blur', function(e) { 2280 if ( $( e.relatedTarget ).closest( this ).length > 0 ) { 2281 return; 2282 } 2283 $( this ).removeClass( 'focus' ); 2284 } ); 2285 }); 2286 2287 $( document ).on( 'click focus keyup', function(e) { 2288 if ( $(e.target).closest( '.fl-node-6fnm9zdvoclq .pp-hover-card' ).length > 0 ) { 2289 return; 2290 } 2291 $('.fl-node-6fnm9zdvoclq .pp-hover-card').removeClass('focus'); 2292 } ); 2293})(jQuery);(function($) { 2294 $('.fl-node-gzsc3on4dfr7 .pp-hover-card').each( function() { 2295 $( this ).on( 'focus', function() { 2296 $( this ).addClass( 'focus' ); 2297 } ).on( 'blur', function(e) { 2298 if ( $( e.relatedTarget ).closest( this ).length > 0 ) { 2299 return; 2300 } 2301 $( this ).removeClass( 'focus' ); 2302 } ); 2303 }); 2304 2305 $( document ).on( 'click focus keyup', function(e) { 2306 if ( $(e.target).closest( '.fl-node-gzsc3on4dfr7 .pp-hover-card' ).length > 0 ) { 2307 return; 2308 } 2309 $('.fl-node-gzsc3on4dfr7 .pp-hover-card').removeClass('focus'); 2310 } ); 2311})(jQuery);(function($) { 2312 $('.fl-node-4yrtdupebnc6 .pp-hover-card').each( function() { 2313 $( this ).on( 'focus', function() { 2314 $( this ).addClass( 'focus' ); 2315 } ).on( 'blur', function(e) { 2316 if ( $( e.relatedTarget ).closest( this ).length > 0 ) { 2317 return; 2318 } 2319 $( this ).removeClass( 'focus' ); 2320 } ); 2321 }); 2322 2323 $( document ).on( 'click focus keyup', function(e) { 2324 if ( $(e.target).closest( '.fl-node-4yrtdupebnc6 .pp-hover-card' ).length > 0 ) { 2325 return; 2326 } 2327 $('.fl-node-4yrtdupebnc6 .pp-hover-card').removeClass('focus'); 2328 } ); 2329})(jQuery);(function($) { 2330 $('.fl-node-49k6v53numwe .pp-hover-card').each( function() { 2331 $( this ).on( 'focus', function() { 2332 $( this ).addClass( 'focus' ); 2333 } ).on( 'blur', function(e) { 2334 if ( $( e.relatedTarget ).closest( this ).length > 0 ) { 2335 return; 2336 } 2337 $( this ).removeClass( 'focus' ); 2338 } ); 2339 }); 2340 2341 $( document ).on( 'click focus keyup', function(e) { 2342 if ( $(e.target).closest( '.fl-node-49k6v53numwe .pp-hover-card' ).length > 0 ) { 2343 return; 2344 } 2345 $('.fl-node-49k6v53numwe .pp-hover-card').removeClass('focus'); 2346 } ); 2347})(jQuery); 2348;( function( $ ) { 2349 2350 UABBSubscribeFormModule = function( settings ) 2351 { 2352 this.settings = settings; 2353 this.nodeClass = '.fl-node-' + settings.id;
2354 this.form = $( this.nodeClass + ' .uabb-subscribe-form' ); 2355 this.button = this.form.find( 'a.uabb-button' ); 2356 this.btn_width = settings.btn_width; 2357 this.btn_padding = settings.btn_padding; 2358 this.layout = settings.layout; 2359 this._init(); 2360 }; 2361 2362 UABBSubscribeFormModule.prototype = { 2363 2364 settings : {}, 2365 nodeClass : '', 2366 form : null, 2367 button : null, 2368 2369 _init: function() 2370 { 2371 this.button.on( 'click', $.proxy( this._submitForm, this ) ); 2372 var form = $( '.uabb-form-wrap' ), 2373 inputFName = form.find( 'input[name=uabb-subscribe-form-fname]' ), 2374 inputLName = form.find( 'input[name=uabb-subscribe-form-lname]' ), 2375 inputEmail = form.find( 'input[name=uabb-subscribe-form-email]' ); 2376 2377 inputFName.on('focusout', this._focusOut); 2378 inputLName.on('focusout', this._focusOut); 2379 inputEmail.on('focusout', this._focusOut); 2380 2381 inputFName.on('focus', this._removeErrorClass); 2382 inputLName.on('focus', this._removeErrorClass); 2383 inputEmail.on('focus', this._removeErrorClass); 2384 2385 if( this.btn_width != 'custom' && this.layout == 'inline' ) { 2386 var height = $( this.nodeClass + ' .uabb-form-field input[type=text]' ).outerHeight(true), 2387 line_height = ( height - ( 2 * this.btn_padding ) ); 2388 $( this.nodeClass + ' .uabb-form-button a' ).css( 'height', height ); 2389 $( this.nodeClass + ' .uabb-form-button a' ).css( 'line-height', line_height + 'px' ); 2390 } 2391 2392 const $scope = jQuery(".uabb-subscribe-form"); 2393 const inputs = $scope.find(".uabb-terms-checkbox-sf"); 2394 2395 inputs.each(function () { 2396 const input = jQuery(this); 2397 2398 input.on("focus", function () { 2399 const label = jQuery(`label[for="${this.id}"]`); 2400 if (label.length) { 2401 label.addClass("uabb-sf-checkbox-focus"); 2402 } 2403 }); 2404 2405 input.on("blur", function () { 2406 const label = jQuery(`label[for="${this.id}"]`); 2407 if (label.length) { 2408 label.removeClass("uabb-sf-checkbox-focus"); 2409 } 2410 }); 2411 2412 }); 2413 }, 2414 2415 _focusOut: function( e ) { 2416 if( $( this ).val().length !== 0 ) { 2417 $( this ).parent().addClass( 'open' ); 2418 } else { 2419 $( this ).parent().removeClass( 'open' ); 2420 } 2421 }, 2422 2423 _removeErrorClass: function(){ 2424 $( this ).removeClass('uabb-form-error'); 2425 }, 2426 2427 _submitForm: function( e ) 2428 { 2429 var submitButton = $( e.currentTarget ), 2430 currentForm = submitButton.closest( '.uabb-subscribe-form' ), 2431 postId = currentForm.closest( '.fl-builder-content' ).data( 'post-id' ), 2432 templateId = currentForm.data( 'template-id' ), 2433 templateNodeId = currentForm.data( 'template-node-id' ), 2434 nodeId = currentForm.closest( '.fl-module' ).data( 'node' ), 2435 buttonText = submitButton.find( '.uabb-button-text' ).text(), 2436 waitText = submitButton.closest( '.uabb-form-button' ).data( 'wait-text' ), 2437 fname = currentForm.find( 'input[name=uabb-subscribe-form-fname]' ), 2438 lname = currentForm.find( 'input[name=uabb-subscribe-form-lname]' ), 2439 email = currentForm.find( 'input[name=uabb-subscribe-form-email]' ), 2440 termsCheckbox = currentForm.find( 'input[name=uabb-terms-checkbox]'), 2441 _nonce = currentForm.find( '.uabb-form-wrap' ).data('nonce'), 2442 re = /\S+@\S+\.\S+/, 2443 valid = true; 2444 2445 e.preventDefault(); 2446 2447 if ( submitButton.hasClass( 'uabb-form-button-disabled' ) ) { 2448 return; // Already submitting 2449 } 2450 /*if ( name.length > 0 && name.val() == '' ) { 2451 name.addClass( 'uabb-form-error' ); 2452 name.siblings( '.uabb-form-error-message' ).show(); 2453 valid = false; 2454 }*/ 2455 if ( '' == email.val() || ! re.test( email.val() ) ) { 2456 email.addClass( 'uabb-form-error' ); 2457 email.siblings( '.uabb-form-error-message' ).show(); 2458 valid = false; 2459 } 2460 2461 if ( termsCheckbox.val() ) { 2462 if ( ! termsCheckbox.is(':checked') ) { 2463 valid = false; 2464 termsCheckbox.closest('.uabb-terms-wrap').addClass( 'uabb-form-error' ); 2465 termsCheckbox.parent().siblings( '.uabb-form-error-message' ).show(); 2466 } 2467 else { 2468 termsCheckbox.removeClass( 'uabb-form-error-message' ); 2469 termsCheckbox.parent().siblings( '.uabb-form-error-message' ).hide(); 2470 } 2471 } 2472 2473 if ( valid ) { 2474 2475 currentForm.find( '> .uabb-form-error-message' ).hide(); 2476 submitButton.find( '.uabb-button-text' ).text( waitText ); 2477 submitButton.data( 'original-text', buttonText ); 2478 submitButton.addClass( 'uabb-form-button-disabled' ); 2479 2480 ajaxData = { 2481 action : 'uabb_subscribe_form_submit', 2482 security : _nonce, 2483 lname : lname.val(), 2484 fname : fname.val(), 2485 email : email.val(), 2486 post_id : postId, 2487 template_id : templateId, 2488 template_node_id : templateNodeId, 2489 node_id : nodeId 2490 }; 2491 2492 $.post( FLBuilderLayoutConfig.paths.wpAjaxUrl, ajaxData, $.proxy( function( response ){ 2493 this._submitFormComplete( response, submitButton ); 2494 }, this )); 2495 2496 } 2497 }, 2498 2499 _submitFormComplete: function( response , button ) 2500 { 2501 2502 var data = response, 2503 buttonText = button.data( 'original-text' ),
2504 form = button.closest( '.uabb-subscribe-form' ); 2505 if ( data.error ) { 2506 2507 form.find( '> .uabb-form-error-message' ).text( data.error ); 2508 form.find( '> .uabb-form-error-message' ).show(); 2509 button.removeClass( 'uabb-form-button-disabled' ); 2510 button.find( '.uabb-button-text' ).text( buttonText ); 2511 } else { 2512 2513 button.removeClass( 'uabb-form-button-disabled' ); 2514 button.find( '.uabb-button-text' ).text( buttonText ); 2515 if ( 'message' == data.action ) { 2516 form.find( '> *' ).hide(); 2517 form.append( '<div class="fl-form-success-message">' + data.message + '</div>' ); 2518 } 2519 else if ( 'redirect' == data.action ) { 2520 window.location.href = data.url; 2521 } 2522 } 2523 2524 } 2525 } 2526 2527})( jQuery ); 2528(function($) { 2529 2530 $(function() { 2531 jQuery( document ).ready(function($) { 2532 new UABBSubscribeFormModule({ 2533 id: 'i5fyaos0k8w3', 2534 btn_width: 'auto', 2535 btn_padding: '12', 2536 layout: 'stacked', 2537 }); 2538 }); 2539 2540 }); 2541})(jQuery); 2542 2543/* Start Global Node Custom JS */ 2544 2545/* End Global Node Custom JS */ 2546 2547 2548/* Start Layout Custom JS */ 2549 2550/* End Layout Custom JS */ 2551
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.