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://www.captivate.fm/wp-admin/admin-ajax.php';var flBuilderUrl = 'https://www.captivate.fm/wp-content/plugins/bb-plugin/';var FLBuilderLayoutConfig = { 623 anchorLinkAnimations : { 624 duration : 1000, 625 easing : 'swing', 626 offset : 100 627 }, 628 paths : { 629 pluginUrl : 'https://www.captivate.fm/wp-content/plugins/bb-plugin/', 630 wpAjaxUrl : 'https://www.captivate.fm/wp-admin/admin-ajax.php' 631 }, 632 breakpoints : { 633 small : 768, 634 medium : 992 }, 635 waypoint: { 636 offset: 80 637 } 638}; 639(function($){ 640 641 if(typeof FLBuilderLayout != 'undefined') { 642 return; 643 } 644 645 /** 646 * Helper class with generic logic for a builder layout. 647 * 648 * @class FLBuilderLayout 649 * @since 1.0 650 */ 651 FLBuilderLayout = { 652 653 /** 654 * Initializes a builder layout. 655 * 656 * @since 1.0 657 * @method init 658 */ 659 init: function() 660 { 661 // Destroy existing layout events. 662 FLBuilderLayout._destroy(); 663 664 // Init CSS classes. 665 FLBuilderLayout._initClasses(); 666 667 // Init backgrounds.
668 FLBuilderLayout._initBackgrounds(); 669 670 // Init row shape layer height. 671 FLBuilderLayout._initRowShapeLayerHeight(); 672 673 // Only init if the builder isn't active. 674 if ( 0 === $('.fl-builder-edit').length ) { 675 676 // Init module animations. 677 FLBuilderLayout._initModuleAnimations(); 678 679 // Init anchor links. 680 FLBuilderLayout._initAnchorLinks(); 681 682 // Init the browser hash. 683 FLBuilderLayout._initHash(); 684 685 // Init forms. 686 FLBuilderLayout._initForms(); 687 } 688 }, 689 690 /** 691 * Public method for refreshing Wookmark or MosaicFlow galleries 692 * within an element. 693 * 694 * @since 1.7.4 695 * @method refreshGalleries 696 */ 697 refreshGalleries: function( element ) 698 { 699 var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ), 700 mfContent = $element.find( '.fl-mosaicflow-content' ), 701 wmContent = $element.find( '.fl-gallery' ), 702 mfObject = null; 703 704 if ( mfContent ) { 705 706 mfObject = mfContent.data( 'mosaicflow' ); 707 708 if ( mfObject ) { 709 mfObject.columns = $( [] ); 710 mfObject.columnsHeights = []; 711 mfContent.data( 'mosaicflow', mfObject ); 712 mfContent.mosaicflow( 'refill' ); 713 } 714 } 715 if ( wmContent ) { 716 wmContent.trigger( 'refreshWookmark' ); 717 } 718 }, 719 720 /** 721 * Public method for refreshing Masonry within an element 722 * 723 * @since 1.8.1 724 * @method refreshGridLayout 725 */ 726 refreshGridLayout: function( element ) 727 { 728 var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ), 729 msnryContent = $element.find('.masonry'); 730 731 if ( msnryContent.length ) { 732 msnryContent.masonry('layout'); 733 } 734 }, 735 736 /** 737 * Public method for reloading BxSlider within an element 738 * 739 * @since 1.8.1 740 * @method reloadSlider 741 */ 742 reloadSlider: function( element ) 743 { 744 var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ), 745 bxContent = $element.find('.bx-viewport > div').eq(0), 746 bxObject = null; 747 748 if ( bxContent.length ) { 749 bxObject = bxContent.data( 'bxSlider'); 750 if ( bxObject ) { 751 bxObject.reloadSlider(); 752 } 753 } 754 }, 755 756 /** 757 * Public method for resizing WP audio player 758 * 759 * @since 1.8.2 760 * @method resizeAudio 761 */ 762 resizeAudio: function( element ) 763 { 764 var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ), 765 audioPlayers = $element.find('.wp-audio-shortcode.mejs-audio'), 766 player = null, 767 mejsPlayer = null, 768 rail = null, 769 railWidth = 400; 770 771 if ( audioPlayers.length && typeof mejs !== 'undefined' ) { 772 audioPlayers.each(function(){ 773 player = $(this); 774 mejsPlayer = mejs.players[player.attr('id')]; 775 rail = player.find('.mejs-controls .mejs-time-rail'); 776 var innerMejs = player.find('.mejs-inner'), 777 total = player.find('.mejs-controls .mejs-time-total'); 778 779 if ( typeof mejsPlayer !== 'undefined' ) { 780 railWidth = Math.ceil(player.width() * 0.8); 781 782 if ( innerMejs.length ) { 783 784 rail.css('width', railWidth +'px!important'); 785 //total.width(rail.width() - 10); 786 787 mejsPlayer.options.autosizeProgress = true; 788 789 // webkit has trouble doing this without a delay 790 setTimeout(function () { 791 mejsPlayer.setControlsSize(); 792 }, 50); 793 794 player.find('.mejs-inner').css({ 795 visibility: 'visible', 796 height: 'inherit' 797 }); 798 } 799 } 800 }); 801 } 802 }, 803 804 /** 805 * Public method for preloading WP audio player when it's inside the hidden element 806 * 807 * @since 1.8.2 808 * @method preloadAudio 809 */ 810 preloadAudio: function(element) 811 { 812 var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ), 813 contentWrap = $element.closest('.fl-accordion-item'), 814 audioPlayers = $element.find('.wp-audio-shortcode.mejs-audio'); 815 816 if ( ! contentWrap.hasClass('fl-accordion-item-active') && audioPlayers.find('.mejs-inner').length ) { 817 audioPlayers.find('.mejs-inner').css({ 818 visibility : 'hidden', 819 height: 0 820 }); 821 } 822 }, 823 824 /** 825 * Public method for resizing slideshow momdule within the tab 826 * 827 * @since 1.10.5 828 * @method resizeSlideshow 829 */ 830 resizeSlideshow: function(){ 831 if(typeof YUI !== 'undefined') { 832 YUI().use('node-event-simulate', function(Y) { 833 Y.one(window).simulate("resize"); 834 }); 835 } 836 }, 837 838 /** 839 * Public method for reloading an embedded Google Map within the tabs or hidden element. 840 * 841 * @since 2.2 842 * @method reloadGoogleMap 843 */ 844 reloadGoogleMap: function(element){ 845 var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ),
846 googleMap = $element.find( 'iframe[src*="google.com/maps"]' ); 847 848 if ( googleMap.length ) { 849 googleMap.attr( 'src', function(i, val) { 850 return val; 851 }); 852 } 853 }, 854 855 /** 856 * Unbinds builder layout events. 857 * 858 * @since 1.0 859 * @access private 860 * @method _destroy 861 */ 862 _destroy: function() 863 { 864 var win = $(window); 865 866 win.off('scroll.fl-bg-parallax'); 867 win.off('resize.fl-bg-video'); 868 }, 869 870 /** 871 * Checks to see if the current device has touch enabled. 872 * 873 * @since 1.0 874 * @access private 875 * @method _isTouch 876 * @return {Boolean} 877 */ 878 _isTouch: function() 879 { 880 if(('ontouchstart' in window) || (window.DocumentTouch && document instanceof DocumentTouch)) { 881 return true; 882 } 883 884 return false; 885 }, 886 887 /** 888 * Checks to see if the current device is mobile. 889 * 890 * @since 1.7 891 * @access private 892 * @method _isMobile 893 * @return {Boolean} 894 */ 895 _isMobile: function() 896 { 897 return /Mobile|Android|Silk\/|Kindle|BlackBerry|Opera Mini|Opera Mobi|webOS/i.test( navigator.userAgent ); 898 }, 899 900 /** 901 * Initializes builder body classes. 902 * 903 * @since 1.0 904 * @access private 905 * @method _initClasses 906 */ 907 _initClasses: function() 908 { 909 var body = $( 'body' ), 910 ua = navigator.userAgent; 911 912 // Add the builder body class. 913 if ( ! body.hasClass( 'archive' ) && $( '.fl-builder-content-primary' ).length > 0 ) { 914 body.addClass('fl-builder'); 915 } 916 917 // Add the builder touch body class. 918 if(FLBuilderLayout._isTouch()) { 919 body.addClass('fl-builder-touch'); 920 } 921 922 // Add the builder mobile body class. 923 if(FLBuilderLayout._isMobile()) { 924 body.addClass('fl-builder-mobile'); 925 } 926 927 if ( $(window).width() < FLBuilderLayoutConfig.breakpoints.small ) { 928 body.addClass( 'fl-builder-breakpoint-small' ); 929 } 930 931 if ( $(window).width() > FLBuilderLayoutConfig.breakpoints.small && $(window).width() < FLBuilderLayoutConfig.breakpoints.medium ) { 932 body.addClass( 'fl-builder-breakpoint-medium' ); 933 } 934 935 if ( $(window).width() > FLBuilderLayoutConfig.breakpoints.medium ) { 936 body.addClass( 'fl-builder-breakpoint-large' ); 937 } 938 939 // IE11 body class. 940 if ( ua.indexOf( 'Trident/7.0' ) > -1 && ua.indexOf( 'rv:11.0' ) > -1 ) { 941 body.addClass( 'fl-builder-ie-11' ); 942 } 943 }, 944 945 /** 946 * Initializes builder node backgrounds that require 947 * additional JavaScript logic such as parallax. 948 * 949 * @since 1.1.4 950 * @access private
951 * @method _initBackgrounds 952 */ 953 _initBackgrounds: function() 954 { 955 var win = $(window); 956 957 // Init parallax backgrounds. 958 if($('.fl-row-bg-parallax').length > 0 && !FLBuilderLayout._isMobile()) { 959 FLBuilderLayout._scrollParallaxBackgrounds(); 960 FLBuilderLayout._initParallaxBackgrounds(); 961 win.on('resize.fl-bg-parallax', FLBuilderLayout._initParallaxBackgrounds); 962 win.on('scroll.fl-bg-parallax', FLBuilderLayout._scrollParallaxBackgrounds); 963 } 964 965 // Init video backgrounds. 966 if($('.fl-bg-video').length > 0) { 967 FLBuilderLayout._initBgVideos(); 968 FLBuilderLayout._resizeBgVideos(); 969 win.on('resize.fl-bg-video', FLBuilderLayout._resizeBgVideos); 970 } 971 }, 972 973 /** 974 * Initializes all parallax backgrounds in a layout. 975 * 976 * @since 1.1.4 977 * @access private 978 * @method _initParallaxBackgrounds 979 */ 980 _initParallaxBackgrounds: function() 981 { 982 $('.fl-row-bg-parallax').each(FLBuilderLayout._initParallaxBackground); 983 }, 984 985 /** 986 * Initializes a single parallax background. 987 * 988 * @since 1.1.4 989 * @access private 990 * @method _initParallaxBackgrounds 991 */ 992 _initParallaxBackground: function() 993 { 994 var row = $(this), 995 content = row.find('> .fl-row-content-wrap'), 996 winWidth = $(window).width(), 997 screenSize = '', 998 imageSrc = { 999 default: '', 1000 medium: '', 1001 responsive: '', 1002 }; 1003 1004 imageSrc.default = row.data('parallax-image') || ''; 1005 imageSrc.medium = row.data('parallax-image-medium') || imageSrc.default; 1006 imageSrc.responsive = row.data('parallax-image-responsive') || imageSrc.medium; 1007 1008 if (winWidth > FLBuilderLayoutConfig.breakpoints.medium) { 1009 screenSize = 'default'; 1010 } else if (winWidth > FLBuilderLayoutConfig.breakpoints.small && winWidth <= FLBuilderLayoutConfig.breakpoints.medium ) { 1011 screenSize = 'medium'; 1012 } else if (winWidth <= FLBuilderLayoutConfig.breakpoints.small) { 1013 screenSize = 'responsive'; 1014 } 1015 1016 content.css('background-image', 'url(' + imageSrc[screenSize] + ')'); 1017 row.data('current-image-loaded', screenSize ); 1018 1019 }, 1020 1021 /** 1022 * Fires when the window is scrolled to adjust 1023 * parallax backgrounds. 1024 * 1025 * @since 1.1.4 1026 * @access private 1027 * @method _scrollParallaxBackgrounds 1028 */ 1029 _scrollParallaxBackgrounds: function() 1030 { 1031 $('.fl-row-bg-parallax').each(FLBuilderLayout._scrollParallaxBackground); 1032 }, 1033 1034 /** 1035 * Fires when the window is scrolled to adjust 1036 * a single parallax background. 1037 * 1038 * @since 1.1.4 1039 * @access private 1040 * @method _scrollParallaxBackground 1041 */ 1042 _scrollParallaxBackground: function() 1043 { 1044 var win = $(window), 1045 row = $(this), 1046 content = row.find('> .fl-row-content-wrap'), 1047 speed = row.data('parallax-speed'), 1048 offset = content.offset(), 1049 yPos = -((win.scrollTop() - offset.top) / speed), 1050 initialOffset = ( row.data('parallax-offset') != null ) ? row.data('parallax-offset') : 0, 1051 totalOffset = yPos - initialOffset; 1052 1053 content.css('background-position', 'center ' + totalOffset + 'px'); 1054 }, 1055 1056 /** 1057 * Initializes all video backgrounds. 1058 * 1059 * @since 1.6.3.3 1060 * @access private 1061 * @method _initBgVideos 1062 */ 1063 _initBgVideos: function() 1064 { 1065 $('.fl-bg-video').each(FLBuilderLayout._initBgVideo); 1066 }, 1067 1068 /** 1069 * Initializes a video background. 1070 * 1071 * @since 1.6.3.3 1072 * @access private 1073 * @method _initBgVideo 1074 */ 1075 _initBgVideo: function() 1076 { 1077 var wrap = $( this ), 1078 width = wrap.data( 'width' ), 1079 height = wrap.data( 'height' ), 1080 mp4 = wrap.data( 'mp4' ), 1081 youtube = wrap.data( 'youtube'), 1082 vimeo = wrap.data( 'vimeo'), 1083 mp4Type = wrap.data( 'mp4-type' ), 1084 webm = wrap.data( 'webm' ), 1085 webmType = wrap.data( 'webm-type' ), 1086 fallback = wrap.data( 'fallback' ), 1087 loaded = wrap.data( 'loaded' ), 1088 videoMobile = wrap.data( 'video-mobile' ), 1089 fallbackTag = '', 1090 videoTag = null, 1091 mp4Tag = null, 1092 webmTag = null; 1093 1094 // Return if the video has been loaded for this row. 1095 if ( loaded ) { 1096 return; 1097 } 1098
1099 videoTag = $( '<video autoplay loop muted playsinline></video>' ); 1100 1101 /** 1102 * Add poster image (fallback image) 1103 */ 1104 if( 'undefined' != typeof fallback && '' != fallback ) { 1105 videoTag.attr( 'poster', 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' ) 1106 videoTag.css( 'background', 'transparent url("' + fallback + '") no-repeat center center' ) 1107 videoTag.css( 'background-size', 'cover' ) 1108 videoTag.css( 'height', '100%' ) 1109 } 1110 1111 // MP4 Source Tag 1112 if ( 'undefined' != typeof mp4 && '' != mp4 ) { 1113 1114 mp4Tag = $( '<source />' ); 1115 mp4Tag.attr( 'src', mp4 ); 1116 mp4Tag.attr( 'type', mp4Type ); 1117 1118 videoTag.append( mp4Tag ); 1119 } 1120 // WebM Source Tag 1121 if ( 'undefined' != typeof webm && '' != webm ) { 1122 1123 webmTag = $( '<source />' ); 1124 webmTag.attr( 'src', webm ); 1125 webmTag.attr( 'type', webmType ); 1126 1127 videoTag.append( webmTag ); 1128 } 1129 1130 // This is either desktop, or mobile is enabled. 1131 if ( ! FLBuilderLayout._isMobile() || ( FLBuilderLayout._isMobile() && "yes" == videoMobile ) ) { 1132 if ( 'undefined' != typeof youtube ) { 1133 FLBuilderLayout._initYoutubeBgVideo.apply( this ); 1134 } 1135 else if ( 'undefined' != typeof vimeo ) { 1136 FLBuilderLayout._initVimeoBgVideo.apply( this ); 1137 } 1138 else { 1139 wrap.append( videoTag ); 1140 } 1141 } 1142 else { 1143 // if we are here, it means we are on mobile and NO is set so remove video src and use fallback 1144 videoTag.attr('src', '') 1145 wrap.append( videoTag ); 1146 } 1147 1148 // Mark this video as loaded. 1149 wrap.data('loaded', true); 1150 }, 1151 1152 /** 1153 * Initializes Youtube video background 1154 * 1155 * @since 1.9 1156 * @access private 1157 * @method _initYoutubeBgVideo 1158 */ 1159 _initYoutubeBgVideo: function() 1160 { 1161 var playerWrap = $(this), 1162 videoId = playerWrap.data('video-id'), 1163 videoPlayer = playerWrap.find('.fl-bg-video-player'), 1164 enableAudio = playerWrap.data('enable-audio'), 1165 audioButton = playerWrap.find('.fl-bg-video-audio'), 1166 startTime = 'undefined' !== typeof playerWrap.data('start') ? playerWrap.data('start') : 0, 1167 startTime = 'undefined' !== typeof playerWrap.data('t') && startTime === 0 ? playerWrap.data('t') : startTime, 1168 endTime = 'undefined' !== typeof playerWrap.data('end') ? playerWrap.data('end') : 0, 1169 loop = 'undefined' !== typeof playerWrap.data('loop') ? playerWrap.data('loop') : 1, 1170 stateCount = 0, 1171 player,fallback_showing; 1172 1173 if ( videoId ) { 1174 fallback = playerWrap.data('fallback') || false 1175 if( fallback ) { 1176 playerWrap.find('iframe').remove() 1177 fallbackTag = $( '<div></div>' ); 1178 fallbackTag.addClass( 'fl-bg-video-fallback' ); 1179 fallbackTag.css( 'background-image', 'url(' + playerWrap.data('fallback') + ')' ); 1180 fallbackTag.css( 'background-size', 'cover' ); 1181 fallbackTag.css( 'transition', 'background-image 1s') 1182 playerWrap.append( fallbackTag ); 1183 fallback_showing = true; 1184 } 1185 FLBuilderLayout._onYoutubeApiReady( function( YT ) { 1186 setTimeout( function() { 1187 1188 player = new YT.Player( videoPlayer[0], { 1189 videoId: videoId, 1190 events: { 1191 onReady: function(event) { 1192 if ( "no" === enableAudio || FLBuilderLayout._isMobile() ) { 1193 event.target.mute(); 1194 } 1195 else if ( "yes" === enableAudio && event.target.isMuted ) { 1196 event.target.unMute(); 1197 } 1198 1199 // Store an instance to a parent 1200 playerWrap.data('YTPlayer', player); 1201 FLBuilderLayout._resizeYoutubeBgVideo.apply(playerWrap); 1202 1203 // Queue the video. 1204 event.target.playVideo(); 1205 1206 if ( audioButton.length > 0 && ! FLBuilderLayout._isMobile() ) { 1207 audioButton.on( 'click', {button: audioButton, player: player}, FLBuilderLayout._toggleBgVideoAudio ); 1208 } 1209 }, 1210 onStateChange: function( event ) { 1211 1212 if ( event.data === 1 ) { 1213 if ( fallback_showing ) { 1214 $( '.fl-bg-video-fallback' ).css( 'background-image', 'url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)' ) 1215 } 1216 } 1217 // Manual check if video is not playable in some browsers. 1218 // StateChange order: [-1, 3, -1] 1219 if ( stateCount < 4 ) { 1220 stateCount++; 1221 } 1222 1223 // Comply with the audio policy in some browsers like Chrome and Safari. 1224 if ( stateCount > 1 && (-1 === event.data || 2 === event.data) && "yes" === enableAudio ) { 1225 player.mute(); 1226 player.playVideo(); 1227 audioButton.show(); 1228 } 1229 1230 if ( event.data === YT.PlayerState.ENDED && 1 === loop ) { 1231 if ( startTime > 0 ) { 1232 player.seekTo( startTime ); 1233 } 1234 else { 1235 player.playVideo(); 1236 } 1237 } 1238 }, 1239 onError: function(event) { 1240 console.info('YT Error: ' + event.data) 1241 FLBuilderLayout._onErrorYoutubeVimeo(playerWrap) 1242 } 1243 }, 1244 playerVars: { 1245 playsinline: FLBuilderLayout._isMobile() ? 1 : 0, 1246 controls: 0, 1247 showinfo: 0, 1248 rel : 0, 1249 start: startTime, 1250 end: endTime, 1251 } 1252 } ); 1253 }, 1 ); 1254 } ); 1255 } 1256 }, 1257 1258 /** 1259 * On youtube or vimeo error show the fallback image if available. 1260 * @since 2.0.7 1261 */ 1262 _onErrorYoutubeVimeo: function(playerWrap) { 1263 1264 fallback = playerWrap.data('fallback') || false 1265 if( ! fallback ) { 1266 return false;
1267 } 1268 playerWrap.find('iframe').remove() 1269 fallbackTag = $( '<div></div>' ); 1270 fallbackTag.addClass( 'fl-bg-video-fallback' ); 1271 fallbackTag.css( 'background-image', 'url(' + playerWrap.data('fallback') + ')' ); 1272 playerWrap.append( fallbackTag ); 1273 }, 1274 1275 /** 1276 * Check if Youtube API has been downloaded 1277 * 1278 * @since 1.9 1279 * @access private 1280 * @method _onYoutubeApiReady 1281 * @param {Function} callback Method to call when YT API has been loaded 1282 */ 1283 _onYoutubeApiReady: function( callback ) { 1284 if ( window.YT && YT.loaded ) { 1285 callback( YT ); 1286 } else { 1287 // If not ready check again by timeout.. 1288 setTimeout( function() { 1289 FLBuilderLayout._onYoutubeApiReady( callback ); 1290 }, 350 ); 1291 } 1292 }, 1293 1294 /** 1295 * Initializes Vimeo video background 1296 * 1297 * @since 1.9 1298 * @access private 1299 * @method _initVimeoBgVideo 1300 */ 1301 _initVimeoBgVideo: function() 1302 { 1303 var playerWrap = $(this), 1304 videoId = playerWrap.data('video-id'), 1305 videoPlayer = playerWrap.find('.fl-bg-video-player'), 1306 enableAudio = playerWrap.data('enable-audio'), 1307 audioButton = playerWrap.find('.fl-bg-video-audio'), 1308 player, 1309 width = playerWrap.outerWidth(), 1310 ua = navigator.userAgent; 1311 1312 if ( typeof Vimeo !== 'undefined' && videoId ) { 1313 player = new Vimeo.Player(videoPlayer[0], { 1314 id : videoId, 1315 loop : true, 1316 title : false, 1317 portrait : false, 1318 background : true, 1319 autopause : false, 1320 muted : true 1321 }); 1322 1323 playerWrap.data('VMPlayer', player); 1324 if ( "no" === enableAudio ) { 1325 player.setVolume(0); 1326 } 1327 else if ("yes" === enableAudio ) { 1328 // Chrome, Safari, Firefox have audio policy restrictions for autoplay videos. 1329 if ( ua.indexOf("Safari") > -1 || ua.indexOf("Chrome") > -1 || ua.indexOf("Firefox") > -1 ) { 1330 player.setVolume(0); 1331 audioButton.show(); 1332 } 1333 else { 1334 player.setVolume(1); 1335 } 1336 } 1337 1338 player.play().catch(function(error) { 1339 FLBuilderLayout._onErrorYoutubeVimeo(playerWrap) 1340 }); 1341 1342 if ( audioButton.length > 0 ) { 1343 audioButton.on( 'click', {button: audioButton, player: player}, FLBuilderLayout._toggleBgVideoAudio ); 1344 } 1345 } 1346 }, 1347 1348 /** 1349 * Mute / unmute audio on row's video background. 1350 * It works for both Youtube and Vimeo. 1351 * 1352 * @since 2.1.3 1353 * @access private 1354 * @method _toggleBgVideoAudio 1355 * @param {Object} e Method arguments 1356 */ 1357 _toggleBgVideoAudio: function( e ) { 1358 var player = e.data.player, 1359 control = e.data.button.find('.fl-audio-control'); 1360 1361 if ( control.hasClass( 'fa-volume-off' ) ) { 1362 // Unmute 1363 control 1364 .removeClass( 'fa-volume-off' ) 1365 .addClass( 'fa-volume-up' ); 1366 e.data.button.find( '.fa-times' ).hide(); 1367 1368 if ( 'function' === typeof player.unMute ) { 1369 player.unMute(); 1370 } 1371 else { 1372 player.setVolume( 1 ); 1373 } 1374 } 1375 else { 1376 // Mute 1377 control 1378 .removeClass( 'fa-volume-up' ) 1379 .addClass( 'fa-volume-off' ); 1380 e.data.button.find( '.fa-times' ).show(); 1381 1382 if ( 'function' === typeof player.unMute ) { 1383 player.mute(); 1384 } 1385 else { 1386 player.setVolume( 0 ); 1387 } 1388 } 1389 }, 1390 1391 /** 1392 * Fires when there is an error loading a video 1393 * background source and shows the fallback. 1394 * 1395 * @since 1.6.3.3 1396 * @access private 1397 * @method _videoBgSourceError 1398 * @param {Object} e An event object 1399 * @deprecated 2.0.3 1400 */ 1401 _videoBgSourceError: function( e ) 1402 { 1403 var source = $( e.target ), 1404 wrap = source.closest( '.fl-bg-video' ), 1405 vid = wrap.find( 'video' ), 1406 fallback = wrap.data( 'fallback' ), 1407 fallbackTag = ''; 1408 source.remove(); 1409 1410 if ( vid.find( 'source' ).length ) { 1411 // Don't show the fallback if we still have other sources to check. 1412 return; 1413 } else if ( '' !== fallback ) { 1414 fallbackTag = $( '<div></div>' ); 1415 fallbackTag.addClass( 'fl-bg-video-fallback' ); 1416 fallbackTag.css( 'background-image', 'url(' + fallback + ')' ); 1417 wrap.append( fallbackTag ); 1418 vid.remove(); 1419 } 1420 }, 1421 1422 /** 1423 * Fires when the window is resized to resize 1424 * all video backgrounds. 1425 * 1426 * @since 1.1.4 1427 * @access private 1428 * @method _resizeBgVideos 1429 */ 1430 _resizeBgVideos: function() 1431 { 1432 $('.fl-bg-video').each( function() { 1433 1434 FLBuilderLayout._resizeBgVideo.apply( this ); 1435 1436 if ( $( this ).parent().find( 'img' ).length > 0 ) { 1437 $( this ).parent().imagesLoaded( $.proxy( FLBuilderLayout._resizeBgVideo, this ) ); 1438 } 1439 } ); 1440 }, 1441 1442 /** 1443 * Fires when the window is resized to resize 1444 * a single video background. 1445 * 1446 * @since 1.1.4 1447 * @access private 1448 * @method _resizeBgVideo 1449 */ 1450 _resizeBgVideo: function() 1451 { 1452 if ( 0 === $( this ).find( 'video' ).length && 0 === $( this ).find( 'iframe' ).length ) { 1453 return; 1454 } 1455 1456 var wrap = $(this), 1457 wrapHeight = wrap.outerHeight(), 1458 wrapWidth = wrap.outerWidth(), 1459 vid = wrap.find('video'), 1460 vidHeight = wrap.data('height'), 1461 vidWidth = wrap.data('width'), 1462 newWidth = wrapWidth, 1463 newHeight = Math.round(vidHeight * wrapWidth/vidWidth), 1464 newLeft = 0, 1465 newTop = 0, 1466 iframe = wrap.find('iframe'); 1467 1468 if ( vid.length ) { 1469 if(vidHeight === '' || typeof vidHeight === 'undefined' || vidWidth === '' || typeof vidWidth === 'undefined') { 1470 vid.css({ 1471 'left' : '0px', 1472 'top' : '0px', 1473 'width' : newWidth + 'px' 1474 }); 1475 1476 // Try to set the actual video dimension on 'loadedmetadata' when using URL as video source 1477 vid.on('loadedmetadata', FLBuilderLayout._resizeOnLoadedMeta); 1478 1479 } 1480 else { 1481 if(newHeight < wrapHeight) { 1482 newHeight = wrapHeight; 1483 newLeft = -((newWidth - wrapWidth) / 2); 1484 1485 if ( 0 != vidHeight ) { 1486 newWidth = Math.round(vidWidth * wrapHeight/vidHeight); 1487 } 1488 } 1489 else { 1490 newTop = -((newHeight - wrapHeight)/2); 1491 } 1492 1493 vid.css({ 1494 'left' : newLeft + 'px', 1495 'top' : newTop + 'px', 1496 'height' : newHeight + 'px', 1497 'width' : newWidth + 'px' 1498 }); 1499 1500 vid.on('loadedmetadata', FLBuilderLayout._resizeOnLoadedMeta); 1501 1502 } 1503 } 1504 else if ( iframe.length ) { 1505 1506 // Resize Youtube video player within iframe tag 1507 if ( typeof wrap.data('youtube') !== 'undefined' ) { 1508 FLBuilderLayout._resizeYoutubeBgVideo.apply(this); 1509 } 1510 } 1511 }, 1512 1513 /** 1514 * Fires when video meta has been loaded. 1515 * This will be Triggered when width/height attributes were not specified during video background resizing. 1516 * 1517 * @since 1.8.5 1518 * @access private 1519 * @method _resizeOnLoadedMeta 1520 */ 1521 _resizeOnLoadedMeta: function(){ 1522 var video = $(this), 1523 wrapHeight = video.parent().outerHeight(), 1524 wrapWidth = video.parent().outerWidth(), 1525 vidWidth = video[0].videoWidth, 1526 vidHeight = video[0].videoHeight, 1527 newHeight = Math.round(vidHeight * wrapWidth/vidWidth), 1528 newWidth = wrapWidth, 1529 newLeft = 0, 1530 newTop = 0; 1531 1532 if(newHeight < wrapHeight) { 1533 newHeight = wrapHeight; 1534 newWidth = Math.round(vidWidth * wrapHeight/vidHeight); 1535 newLeft = -((newWidth - wrapWidth)/2); 1536 } 1537 else { 1538 newTop = -((newHeight - wrapHeight)/2); 1539 } 1540 1541 video.parent().data('width', vidWidth); 1542 video.parent().data('height', vidHeight); 1543 1544 video.css({ 1545 'left' : newLeft + 'px', 1546 'top' : newTop + 'px', 1547 'width' : newWidth + 'px', 1548 'height' : newHeight + 'px' 1549 }); 1550 }, 1551 1552 /** 1553 * Fires when the window is resized to resize 1554 * a single Youtube video background. 1555 * 1556 * @since 1.9 1557 * @access private 1558 * @method _resizeYoutubeBgVideo 1559 */ 1560 _resizeYoutubeBgVideo: function() 1561 { 1562 var wrap = $(this), 1563 wrapWidth = wrap.outerWidth(), 1564 wrapHeight = wrap.outerHeight(), 1565 player = wrap.data('YTPlayer'), 1566 video = player ? player.getIframe() : null, 1567 aspectRatioSetting = '16:9', // Medium 1568 aspectRatioArray = aspectRatioSetting.split( ':' ),
1569 aspectRatio = aspectRatioArray[0] / aspectRatioArray[1], 1570 ratioWidth = wrapWidth / aspectRatio, 1571 ratioHeight = wrapHeight * aspectRatio, 1572 isWidthFixed = wrapWidth / wrapHeight > aspectRatio, 1573 width = isWidthFixed ? wrapWidth : ratioHeight, 1574 height = isWidthFixed ? ratioWidth : wrapHeight; 1575 1576 if ( video ) { 1577 $(video).width( width ).height( height ); 1578 } 1579 }, 1580 1581 /** 1582 * Initializes module animations. 1583 * 1584 * @since 1.1.9 1585 * @access private 1586 * @method _initModuleAnimations 1587 */ 1588 _initModuleAnimations: function() 1589 { 1590 if(typeof jQuery.fn.waypoint !== 'undefined') { 1591 $('.fl-animation').each( function() { 1592 var node = $( this ), 1593 nodeTop = node.offset().top, 1594 winHeight = $( window ).height(), 1595 bodyHeight = $( 'body' ).height(), 1596 waypoint = FLBuilderLayoutConfig.waypoint, 1597 offset = '80%'; 1598 1599 if ( typeof waypoint.offset !== undefined ) { 1600 offset = FLBuilderLayoutConfig.waypoint.offset + '%'; 1601 } 1602 1603 if ( bodyHeight - nodeTop < winHeight * 0.2 ) { 1604 offset = '100%'; 1605 } 1606 1607 node.waypoint({ 1608 offset: offset, 1609 handler: FLBuilderLayout._doModuleAnimation 1610 }); 1611 } ); 1612 } 1613 }, 1614 1615 /** 1616 * Runs a module animation. 1617 * 1618 * @since 1.1.9 1619 * @access private 1620 * @method _doModuleAnimation 1621 */ 1622 _doModuleAnimation: function() 1623 { 1624 var module = 'undefined' == typeof this.element ? $(this) : $(this.element), 1625 delay = parseFloat(module.data('animation-delay')), 1626 duration = parseFloat(module.data('animation-duration')); 1627 1628 if ( ! isNaN( duration ) ) { 1629 module.css( 'animation-duration', duration + 's' ); 1630 } 1631 1632 if(!isNaN(delay) && delay > 0) { 1633 setTimeout(function(){ 1634 module.addClass('fl-animated'); 1635 }, delay * 1000); 1636 } else { 1637 setTimeout(function(){ 1638 module.addClass('fl-animated'); 1639 }, 1); 1640 } 1641 }, 1642 1643 /** 1644 * Opens a tab or accordion item if the browser hash is set 1645 * to the ID of one on the page. 1646 * 1647 * @since 1.6.0 1648 * @access private 1649 * @method _initHash 1650 */ 1651 _initHash: function() 1652 { 1653 var hash = window.location.hash.replace( '#', '' ).split( '/' ).shift(), 1654 element = null, 1655 tabs = null, 1656 responsiveLabel = null, 1657 tabIndex = null, 1658 label = null; 1659 1660 if ( '' !== hash ) { 1661 1662 try { 1663 1664 element = $( '#' + hash ); 1665 1666 if ( element.length > 0 ) { 1667 1668 if ( element.hasClass( 'fl-accordion-item' ) ) { 1669 setTimeout( function() { 1670 element.find( '.fl-accordion-button' ).trigger( 'click' ); 1671 }, 100 ); 1672 } 1673 if ( element.hasClass( 'fl-tabs-panel' ) ) { 1674 1675 setTimeout( function() { 1676 1677 tabs = element.closest( '.fl-tabs' ); 1678 responsiveLabel = element.find( '.fl-tabs-panel-label' ); 1679 tabIndex = responsiveLabel.data( 'index' ); 1680 label = tabs.find( '.fl-tabs-labels .fl-tabs-label[data-index=' + tabIndex + ']' ); 1681 1682 if ( responsiveLabel.is( ':visible' ) ) { 1683 responsiveLabel.trigger( 'click' ); 1684 } 1685 else { 1686 label[0].click(); 1687 FLBuilderLayout._scrollToElement( element ); 1688 } 1689 1690 }, 100 ); 1691 } 1692 } 1693 } 1694 catch( e ) {} 1695 } 1696 }, 1697 1698 /** 1699 * Initializes all anchor links on the page for smooth scrolling. 1700 * 1701 * @since 1.4.9 1702 * @access private 1703 * @method _initAnchorLinks 1704 */ 1705 _initAnchorLinks: function() 1706 { 1707 $( 'a' ).each( FLBuilderLayout._initAnchorLink ); 1708 }, 1709 1710 /** 1711 * Initializes a single anchor link for smooth scrolling. 1712 * 1713 * @since 1.4.9 1714 * @access private 1715 * @method _initAnchorLink 1716 */ 1717 _initAnchorLink: function() 1718 { 1719 var link = $( this ), 1720 href = link.attr( 'href' ), 1721 loc = window.location, 1722 id = null, 1723 element = null, 1724 flNode = false; 1725 1726 if ( 'undefined' != typeof href && href.indexOf( '#' ) > -1 && link.closest('svg').length < 1 ) { 1727 1728 if ( loc.pathname.replace( /^\//, '' ) == this.pathname.replace( /^\//, '' ) && loc.hostname == this.hostname ) { 1729 1730 try { 1731 1732 id = href.split( '#' ).pop(); 1733 // If there is no ID then we have nowhere to look 1734 // Fixes a quirk in jQuery and FireFox 1735 if( ! id ) { 1736 return; 1737 } 1738 element = $( '#' + id ); 1739 1740 if ( element.length > 0 ) { 1741 flNode = element.hasClass( 'fl-row' ) || element.hasClass( 'fl-col' ) || element.hasClass( 'fl-module' ); 1742 if ( !element.hasClass( 'fl-no-scroll' ) && ( link.hasClass( 'fl-scroll-link' ) || flNode ) ) { 1743 $( link ).on( 'click', FLBuilderLayout._scrollToElementOnLinkClick ); 1744 } 1745 if ( element.hasClass( 'fl-accordion-item' ) ) { 1746 $( link ).on( 'click', FLBuilderLayout._scrollToAccordionOnLinkClick ); 1747 } 1748 if ( element.hasClass( 'fl-tabs-panel' ) ) { 1749 $( link ).on( 'click', FLBuilderLayout._scrollToTabOnLinkClick ); 1750 } 1751 } 1752 } 1753 catch( e ) {} 1754 } 1755 } 1756 }, 1757 1758 /** 1759 * Scrolls to an element when an anchor link is clicked. 1760 * 1761 * @since 1.4.9 1762 * @access private 1763 * @method _scrollToElementOnLinkClick 1764 * @param {Object} e An event object. 1765 * @param {Function} callback A function to call when the scroll is complete. 1766 */ 1767 _scrollToElementOnLinkClick: function( e, callback ) 1768 { 1769 var element = $( '#' + $( this ).attr( 'href' ).split( '#' ).pop() ); 1770 1771 FLBuilderLayout._scrollToElement( element, callback ); 1772 1773 e.preventDefault(); 1774 }, 1775 1776 /** 1777 * Scrolls to an element. 1778 * 1779 * @since 1.6.4.5 1780 * @access private 1781 * @method _scrollToElement 1782 * @param {Object} element The element to scroll to. 1783 * @param {Function} callback A function to call when the scroll is complete. 1784 */ 1785 _scrollToElement: function( element, callback ) 1786 { 1787 var config = FLBuilderLayoutConfig.anchorLinkAnimations, 1788 dest = 0, 1789 win = $( window ), 1790 doc = $( document ); 1791 1792 if ( element.length > 0 ) { 1793 1794 if ( 'fixed' === element.css('position') || 'fixed' === element.parent().css('position') ) { 1795 dest = element.position().top; 1796 } 1797 else if ( element.offset().top > doc.height() - win.height() ) { 1798 dest = doc.height() - win.height(); 1799 } 1800 else { 1801 dest = element.offset().top - config.offset; 1802 } 1803 1804 $( 'html, body' ).animate( { scrollTop: dest }, config.duration, config.easing, function() { 1805 1806 if ( 'undefined' != typeof callback ) { 1807 callback(); 1808 } 1809 1810 if ( undefined != element.attr( 'id' ) ) { 1811 1812 if ( history.pushState ) { 1813 history.pushState( null, null, '#' + element.attr( 'id' ) ); 1814 } 1815 else { 1816 window.location.hash = element.attr( 'id' ); 1817 } 1818 } 1819 } ); 1820 } 1821 }, 1822 1823 /** 1824 * Scrolls to an accordion item when a link is clicked. 1825 * 1826 * @since 1.5.9 1827 * @access private 1828 * @method _scrollToAccordionOnLinkClick 1829 * @param {Object} e An event object. 1830 */ 1831 _scrollToAccordionOnLinkClick: function( e ) 1832 { 1833 var element = $( '#' + $( this ).attr( 'href' ).split( '#' ).pop() ); 1834 1835 if ( element.length > 0 ) { 1836 1837 var callback = function() { 1838 if ( element ) { 1839 element.find( '.fl-accordion-button' ).trigger( 'click' ); 1840 element = false;
1841 } 1842 }; 1843 1844 FLBuilderLayout._scrollToElementOnLinkClick.call( this, e, callback ); 1845 } 1846 }, 1847 1848 /** 1849 * Scrolls to a tab panel when a link is clicked. 1850 * 1851 * @since 1.5.9 1852 * @access private 1853 * @method _scrollToTabOnLinkClick 1854 * @param {Object} e An event object. 1855 */ 1856 _scrollToTabOnLinkClick: function( e ) 1857 { 1858 var element = $( '#' + $( this ).attr( 'href' ).split( '#' ).pop() ), 1859 tabs = null, 1860 label = null, 1861 responsiveLabel = null; 1862 1863 if ( element.length > 0 ) { 1864 1865 tabs = element.closest( '.fl-tabs' ); 1866 responsiveLabel = element.find( '.fl-tabs-panel-label' ); 1867 tabIndex = responsiveLabel.data( 'index' ); 1868 label = tabs.find( '.fl-tabs-labels .fl-tabs-label[data-index=' + tabIndex + ']' ); 1869 1870 if ( responsiveLabel.is( ':visible' ) ) { 1871 1872 var callback = function() { 1873 if ( element ) { 1874 responsiveLabel.trigger( 'click' ); 1875 element = false; 1876 } 1877 }; 1878 1879 FLBuilderLayout._scrollToElementOnLinkClick.call( this, e, callback ); 1880 } 1881 else { 1882 label[0].click(); 1883 FLBuilderLayout._scrollToElement( element ); 1884 } 1885 1886 e.preventDefault(); 1887 } 1888 }, 1889 1890 /** 1891 * Initializes all builder forms on a page. 1892 * 1893 * @since 1.5.4 1894 * @access private 1895 * @method _initForms 1896 */ 1897 _initForms: function() 1898 { 1899 if ( ! FLBuilderLayout._hasPlaceholderSupport ) { 1900 $( '.fl-form-field input' ).each( FLBuilderLayout._initFormFieldPlaceholderFallback ); 1901 } 1902 1903 $( '.fl-form-field input' ).on( 'focus', FLBuilderLayout._clearFormFieldError ); 1904 }, 1905 1906 /** 1907 * Checks to see if the current device has HTML5 1908 * placeholder support. 1909 * 1910 * @since 1.5.4 1911 * @access private 1912 * @method _hasPlaceholderSupport 1913 * @return {Boolean} 1914 */ 1915 _hasPlaceholderSupport: function() 1916 { 1917 var input = document.createElement( 'input' ); 1918 1919 return 'undefined' != input.placeholder; 1920 }, 1921 1922 /** 1923 * Initializes the fallback for when placeholders aren't supported. 1924 * 1925 * @since 1.5.4 1926 * @access private 1927 * @method _initFormFieldPlaceholderFallback 1928 */ 1929 _initFormFieldPlaceholderFallback: function() 1930 { 1931 var field = $( this ), 1932 val = field.val(), 1933 placeholder = field.attr( 'placeholder' ); 1934 1935 if ( 'undefined' != placeholder && '' === val ) { 1936 field.val( placeholder ); 1937 field.on( 'focus', FLBuilderLayout._hideFormFieldPlaceholderFallback ); 1938 field.on( 'blur', FLBuilderLayout._showFormFieldPlaceholderFallback ); 1939 } 1940 }, 1941 1942 /** 1943 * Hides a fallback placeholder on focus. 1944 * 1945 * @since 1.5.4 1946 * @access private 1947 * @method _hideFormFieldPlaceholderFallback 1948 */ 1949 _hideFormFieldPlaceholderFallback: function() 1950 { 1951 var field = $( this ), 1952 val = field.val(), 1953 placeholder = field.attr( 'placeholder' ); 1954 1955 if ( val == placeholder ) { 1956 field.val( '' ); 1957 } 1958 }, 1959 1960 /** 1961 * Shows a fallback placeholder on blur. 1962 * 1963 * @since 1.5.4 1964 * @access private 1965 * @method _showFormFieldPlaceholderFallback 1966 */ 1967 _showFormFieldPlaceholderFallback: function() 1968 { 1969 var field = $( this ), 1970 val = field.val(), 1971 placeholder = field.attr( 'placeholder' ); 1972 1973 if ( '' === val ) { 1974 field.val( placeholder ); 1975 } 1976 }, 1977 1978 /** 1979 * Clears a form field error message. 1980 * 1981 * @since 1.5.4 1982 * @access private 1983 * @method _clearFormFieldError 1984 */ 1985 _clearFormFieldError: function() 1986 { 1987 var field = $( this ); 1988 1989 field.removeClass( 'fl-form-error' ); 1990 field.siblings( '.fl-form-error-message' ).hide(); 1991 }, 1992 1993 /** 1994 * Init Row Shape Layer's height. 1995 * 1996 * @since 2.5.3 1997 * @access private 1998 * @method _initRowShapeLayerHeight 1999 */ 2000 _initRowShapeLayerHeight: function () { 2001 FLBuilderLayout._adjustRowShapeLayerHeight(); 2002 $( window ).on( 'resize', FLBuilderLayout._adjustRowShapeLayerHeight ); 2003 }, 2004 2005 /** 2006 * Adjust Row Shape Layer's height to fix to remove the fine line that appears on certain screen sizes. 2007 * 2008 * @since 2.5.3 2009 * @access private 2010 * @method _adjustRowShapeLayerHeight 2011 */ 2012 _adjustRowShapeLayerHeight: function() { 2013 var rowShapeLayers = $('.fl-builder-shape-layer'); 2014 2015 $( rowShapeLayers ).each(function (index) { 2016 var rowShapeLayer = $(this), 2017 shape = $(rowShapeLayer).find('svg'), 2018 height = shape.height(),
2019 excludeShapes = '.fl-builder-shape-circle, .fl-builder-shape-dot-cluster, .fl-builder-shape-topography, .fl-builder-shape-rect'; 2020 2021 if ( ! rowShapeLayer.is( excludeShapes ) ) { 2022 $(shape).css('height', Math.ceil( height ) ); 2023 } 2024 }); 2025 } 2026 }; 2027 2028 /* Initializes the builder layout. */ 2029 $(function(){ 2030 FLBuilderLayout.init(); 2031 }); 2032 2033})(jQuery); 2034 2035/* Start Global JS */ 2036 2037/* End Global JS */ 2038 2039jQuery(function($) { 2040 2041 $(function() { 2042 $( '.fl-node-37mguot5cp0b .fl-photo-img' ) 2043 .on( 'mouseenter', function( e ) { 2044 $( this ).data( 'title', $( this ).attr( 'title' ) ).removeAttr( 'title' ); 2045 } ) 2046 .on( 'mouseleave', function( e ){ 2047 $( this ).attr( 'title', $( this ).data( 'title' ) ).data( 'title', null ); 2048 } ); 2049 }); 2050 }); 2051 2052(function($) { 2053 2054 FLBuilderPostGrid = function(settings) 2055 { 2056 this.settings = settings; 2057 this.nodeClass = '.fl-node-' + settings.id; 2058 this.matchHeight = settings.matchHeight; 2059 2060 if ( 'columns' == this.settings.layout ) { 2061 this.wrapperClass = this.nodeClass + ' .fl-post-grid'; 2062 this.postClass = this.nodeClass + ' .fl-post-column'; 2063 } 2064 else { 2065 this.wrapperClass = this.nodeClass + ' .fl-post-' + this.settings.layout; 2066 this.postClass = this.wrapperClass + '-post'; 2067 } 2068 2069 if(this._hasPosts()) { 2070 this._initLayout(); 2071 this._initInfiniteScroll(); 2072 } 2073 }; 2074 2075 FLBuilderPostGrid.prototype = { 2076 2077 settings : {}, 2078 nodeClass : '', 2079 wrapperClass : '', 2080 postClass : '', 2081 gallery : null, 2082 currPage : 1, 2083 totalPages : 1, 2084 2085 _hasPosts: function() 2086 { 2087 return $(this.postClass).length > 0; 2088 }, 2089 2090 _initLayout: function() 2091 { 2092 switch(this.settings.layout) { 2093 2094 case 'columns': 2095 this._columnsLayout(); 2096 break; 2097 2098 case 'grid': 2099 this._gridLayout(); 2100 break; 2101 2102 case 'gallery': 2103 this._galleryLayout(); 2104 break; 2105 } 2106 2107 $(this.postClass).css('visibility', 'visible'); 2108 2109 FLBuilderLayout._scrollToElement( $( this.nodeClass + ' .fl-paged-scroll-to' ) ); 2110 }, 2111 2112 _columnsLayout: function() 2113 { 2114 $(this.wrapperClass).imagesLoaded( $.proxy( function() { 2115 this._gridLayoutMatchHeight(); 2116 }, this ) ); 2117 2118 $( window ).on( 'resize', $.proxy( function(){ 2119 $(this.wrapperClass).imagesLoaded( $.proxy( function() { 2120 this._gridLayoutMatchHeight(); 2121 }, this ) ); 2122 }, this ) ); 2123 }, 2124 2125 _gridLayout: function() 2126 { 2127 var wrap = $(this.wrapperClass); 2128 2129 wrap.masonry({ 2130 columnWidth : this.nodeClass + ' .fl-post-grid-sizer', 2131 gutter : parseInt(this.settings.postSpacing), 2132 isFitWidth : true, 2133 itemSelector : this.postClass, 2134 transitionDuration : 0, 2135 isRTL : this.settings.isRTL 2136 }); 2137 2138 wrap.imagesLoaded( $.proxy( function() { 2139 this._gridLayoutMatchHeight(); 2140 wrap.masonry(); 2141 }, this ) ); 2142 2143 $(window).scroll($.debounce( 25, function(){ 2144 wrap.masonry() 2145 })); 2146 2147 }, 2148 2149 _gridLayoutMatchHeight: function() 2150 { 2151 var highestBox = 0; 2152 2153 if ( ! this._isMatchHeight() ) { 2154 $(this.nodeClass + ' .fl-post-grid-post').css('height', ''); 2155 return; 2156 } 2157 2158 $(this.nodeClass + ' .fl-post-grid-post').css('height', '').each(function(){ 2159 2160 if($(this).height() > highestBox) { 2161 highestBox = $(this).height(); 2162 } 2163 }); 2164 2165 $(this.nodeClass + ' .fl-post-grid-post').height(highestBox); 2166 }, 2167 2168 _isMatchHeight: function(){ 2169 var width = $( window ).width(), 2170 breakpoints = FLBuilderLayoutConfig.breakpoints, 2171 matchMedium = '' != this.matchHeight.medium ? this.matchHeight.medium : this.matchHeight.default; 2172 matchSmall = '' != this.matchHeight.responsive ? this.matchHeight.responsive : this.matchHeight.default; 2173 2174 return (width > breakpoints.medium && 1 == this.matchHeight.default) 2175 || (width > breakpoints.small && width <= breakpoints.medium && 1 == matchMedium) 2176 || (width <= breakpoints.small && 1 == matchSmall); 2177 }, 2178 2179 _galleryLayout: function() 2180 { 2181 this.gallery = new FLBuilderGalleryGrid({ 2182 'wrapSelector' : this.wrapperClass, 2183 'itemSelector' : '.fl-post-gallery-post', 2184 'isRTL' : this.settings.isRTL 2185 }); 2186 }, 2187 2188 _initInfiniteScroll: function() 2189 { 2190 var isScroll = 'scroll' == this.settings.pagination || 'load_more' == this.settings.pagination,
2191 pages = $( this.nodeClass + ' .fl-builder-pagination' ).find( 'li .page-numbers:not(.next)' ); 2192 2193 if( pages.length > 1) { 2194 total = pages.last().text().replace( /\D/g, '' ) 2195 this.totalPages = parseInt( total ); 2196 } 2197 2198 if( isScroll && this.totalPages > 1 && 'undefined' === typeof FLBuilder ) { 2199 this._infiniteScroll(); 2200 2201 if( 'load_more' == this.settings.pagination ) { 2202 this._infiniteScrollLoadMore(); 2203 } 2204 } 2205 }, 2206 2207 _infiniteScroll: function(settings) 2208 { 2209 var path = $(this.nodeClass + ' .fl-builder-pagination a.next').attr('href'), 2210 pagePattern = /(.*?(\/|\&|\?)paged-[0-9]{1,}(\/|=))([0-9]{1,})+(.*)/, 2211 wpPattern = /^(.*?\/?page\/?)(?:\d+)(.*?$)/, 2212 pageMatched = null, 2213 scrollData = { 2214 navSelector : this.nodeClass + ' .fl-builder-pagination', 2215 nextSelector : this.nodeClass + ' .fl-builder-pagination a.next', 2216 itemSelector : this.postClass, 2217 prefill : true, 2218 bufferPx : 200, 2219 loading : { 2220 msgText : 'Loading', 2221 finishedMsg : '', 2222 img : FLBuilderLayoutConfig.paths.pluginUrl + 'img/ajax-loader-grey.gif', 2223 speed : 1 2224 } 2225 }; 2226 2227 // Define path since Infinitescroll incremented our custom pagination '/paged-2/2/' to '/paged-3/2/'. 2228 if ( pagePattern.test( path ) ) { 2229 scrollData.path = function( currPage ){ 2230 pageMatched = path.match( pagePattern ); 2231 path = pageMatched[1] + currPage + pageMatched[5]; 2232 return path; 2233 } 2234 } 2235 else if ( wpPattern.test( path ) ) { 2236 scrollData.path = path.match( wpPattern ).slice( 1 ); 2237 } 2238 2239 $(this.wrapperClass).infinitescroll( scrollData, $.proxy(this._infiniteScrollComplete, this) ); 2240 2241 setTimeout(function(){ 2242 $(window).trigger('resize'); 2243 }, 100); 2244 }, 2245 2246 _infiniteScrollComplete: function(elements) 2247 { 2248 var wrap = $(this.wrapperClass); 2249 2250 elements = $(elements); 2251 2252 if(this.settings.layout == 'columns') { 2253 wrap.imagesLoaded( $.proxy( function() { 2254 this._gridLayoutMatchHeight(); 2255 elements.css('visibility', 'visible'); 2256 }, this ) ); 2257 } 2258 else if(this.settings.layout == 'grid') { 2259 wrap.imagesLoaded( $.proxy( function() { 2260 this._gridLayoutMatchHeight(); 2261 wrap.masonry('appended', elements); 2262 wrap.masonry(); 2263 elements.css('visibility', 'visible'); 2264 }, this ) ); 2265 } 2266 else if(this.settings.layout == 'gallery') { 2267 this.gallery.resize(); 2268 elements.css('visibility', 'visible'); 2269 } 2270 2271 if( 'load_more' == this.settings.pagination ) { 2272 $( this.wrapperClass + ' .fl-post-grid-sizer.masonry-brick' ).appendTo( this.wrapperClass ); 2273 $( '#infscr-loading' ).appendTo( this.wrapperClass ); 2274 } 2275 2276 elements.find( 'img[srcset]' ).each( function( index, img ) { 2277 img.outerHTML = img.outerHTML; 2278 }); 2279 2280 this.currPage++; 2281 2282 this._removeLoadMoreButton(); 2283 }, 2284 2285 _infiniteScrollLoadMore: function() 2286 { 2287 var wrap = $( this.wrapperClass ); 2288 2289 $( window ).unbind( '.infscr' ); 2290 2291 $(this.nodeClass + ' .fl-builder-pagination-load-more .fl-button').on( 'click', function(){ 2292 wrap.infinitescroll( 'retrieve' ); 2293 return false; 2294 }); 2295 }, 2296 2297 _removeLoadMoreButton: function() 2298 { 2299 if ( 'load_more' == this.settings.pagination && this.totalPages == this.currPage ) { 2300 $( this.nodeClass + ' .fl-builder-pagination-load-more' ).remove(); 2301 } 2302 } 2303 }; 2304 2305})(jQuery); 2306(function($) { 2307 2308 $(function() { 2309 2310 new FLBuilderPostGrid({ 2311 id: '9ydjvc8op5kw', 2312 layout: 'feed', 2313 pagination: 'none', 2314 postSpacing: '60', 2315 postWidth: '300', 2316 matchHeight: { 2317 default : '0', 2318 medium : '', 2319 responsive : '' 2320 }, 2321 isRTL: false }); 2322 2323 }); 2324 2325})(jQuery); 2326(function($) { 2327 2328 $(function() { 2329 2330 new FLBuilderPostGrid({ 2331 id: 'ldzcsxe40pvw', 2332 layout: 'columns', 2333 pagination: 'none', 2334 postSpacing: '60', 2335 postWidth: '300', 2336 matchHeight: { 2337 default : '0', 2338 medium : '', 2339 responsive : '' 2340 }, 2341 isRTL: false }); 2342 2343 }); 2344 2345})(jQuery); 2346(function($) { 2347 2348 $(function() { 2349 2350 new FLBuilderPostGrid({ 2351 id: 'l719grof5ent', 2352 layout: 'feed', 2353 pagination: 'none', 2354 postSpacing: '60', 2355 postWidth: '300', 2356 matchHeight: { 2357 default : '0', 2358 medium : '', 2359 responsive : '' 2360 }, 2361 isRTL: false }); 2362 2363 }); 2364 2365})(jQuery); 2366 2367( function( $ ) { 2368 2369 window.onLoadFLReCaptcha = function() { 2370 var reCaptchaFields = $( '.fl-grecaptcha' ), 2371 widgetID; 2372 2373 if ( reCaptchaFields.length > 0 ) { 2374 reCaptchaFields.each(function(i){ 2375 var self = $( this ), 2376 attrWidget = self.attr('data-widgetid'), 2377 newID = $(this).attr('id') + '-' + i; 2378 2379 // Avoid re-rendering as it's throwing API error 2380 if ( (typeof attrWidget !== typeof undefined && attrWidget !== false) ) { 2381 return; 2382 } 2383 else { 2384 2385 // Increment ID to avoid conflict with the same form. 2386 self.attr( 'id', newID ); 2387 2388 widgetID = grecaptcha.render( newID, { 2389 sitekey : self.data( 'sitekey' ), 2390 theme : self.data( 'theme' ), 2391 size : self.data( 'validate' ), 2392 callback: function( response ){ 2393 if ( response != '' ) { 2394 self.attr( 'data-fl-grecaptcha-response', response ); 2395 2396 // Re-submitting the form after a successful invisible validation. 2397 if ( 'invisible' == self.data( 'validate' ) ) { 2398 self.closest( '.fl-subscribe-form' ).find( 'a.fl-button' ).trigger( 'click' ); 2399 } 2400 } 2401 } 2402 }); 2403 2404 self.attr( 'data-widgetid', widgetID ); 2405 2406 } 2407 }); 2408 } 2409 }; 2410 2411 FLBuilderSubscribeForm = function( settings ) 2412 { 2413 this.settings = settings; 2414 this.nodeClass = '.fl-node-' + settings.id; 2415 this.form = $( this.nodeClass + ' .fl-subscribe-form' ); 2416 this.button = this.form.find( 'a.fl-button' ); 2417 this._init(); 2418 }; 2419 2420 FLBuilderSubscribeForm.prototype = { 2421 2422 settings : {}, 2423 nodeClass : '', 2424 form : null, 2425 button : null, 2426 2427 _init: function() 2428 { 2429 this.button.on( 'click', $.proxy( this._submitForm, this ) ); 2430 this.button.on( 'keydown, keyup', $.proxy( this._keyupdown, this ) );
2431 this.form.find( 'input[type="email"]' ).on( 'keypress', $.proxy( this._onEnterKey, this) ); 2432 }, 2433 2434 _keyupdown: function(e) { 2435 if( e.keyCode === 13 || e.keyCode === 32 ) { 2436 e.preventDefault(); 2437 this._submitForm(e); 2438 } 2439 }, 2440 2441 _submitForm: function( e ) 2442 { 2443 var submitButton = $( e.currentTarget ), 2444 currentForm = submitButton.closest( '.fl-subscribe-form' ), 2445 postId = currentForm.closest( '.fl-builder-content' ).data( 'post-id' ), 2446 templateId = currentForm.data( 'template-id' ), 2447 templateNodeId = currentForm.data( 'template-node-id' ), 2448 nodeId = currentForm.closest( '.fl-module' ).data( 'node' ), 2449 buttonText = submitButton.find( '.fl-button-text' ).text(), 2450 waitText = submitButton.closest( '.fl-form-button' ).data( 'wait-text' ), 2451 name = currentForm.find( 'input[name=fl-subscribe-form-name]' ), 2452 email = currentForm.find( 'input[name=fl-subscribe-form-email]' ), 2453 successUrl = this.settings.successUrl, 2454 termsCheckbox = currentForm.find( 'input[name=fl-terms-checkbox]'), 2455 recaptcha = currentForm.find( '.fl-grecaptcha' ), 2456 reCaptchaValue = recaptcha.data( 'fl-grecaptcha-response' ), 2457 re = /\S+@\S+\.\S+/, 2458 valid = true, 2459 ajaxData = null; 2460 2461 e.preventDefault(); 2462 2463 if ( submitButton.hasClass( 'fl-form-button-disabled' ) ) { 2464 return; // Already submitting 2465 } 2466 2467 if ( name.length > 0 && name.val() == '' ) { 2468 name.addClass( 'fl-form-error' ); 2469 name.siblings( '.fl-form-error-message' ).show(); 2470 valid = false; 2471 } 2472 if ( '' == email.val() || ! re.test( email.val() ) ) { 2473 email.addClass( 'fl-form-error' ); 2474 email.siblings( '.fl-form-error-message' ).show(); 2475 valid = false; 2476 } 2477 2478 if ( termsCheckbox.length ) { 2479 if ( ! termsCheckbox.is(':checked') ) { 2480 valid = false; 2481 termsCheckbox.addClass( 'fl-form-error' ); 2482 termsCheckbox.parent().siblings( '.fl-form-error-message' ).show(); 2483 } 2484 else { 2485 termsCheckbox.removeClass( 'fl-form-error' ); 2486 termsCheckbox.parent().siblings( '.fl-form-error-message' ).hide(); 2487 } 2488 } 2489 2490 if ( recaptcha.length > 0 && valid ) { 2491 if ( 'undefined' === typeof reCaptchaValue || reCaptchaValue === false ) { 2492 if ( 'normal' == recaptcha.data( 'validate' ) ) { 2493 recaptcha.addClass( 'fl-form-error' ); 2494 recaptcha.siblings( '.fl-form-error-message' ).show(); 2495 } else if ( 'invisible' == recaptcha.data( 'validate' ) ) { 2496 2497 // Invoke the reCAPTCHA check. 2498 if ( 'undefined' !== typeof recaptcha.data( 'action' ) ) { 2499 // V3 2500 grecaptcha.execute( recaptcha.data( 'widgetid' ), {action: recaptcha.data( 'action' )} ); 2501 } 2502 else { 2503 // V2 2504 grecaptcha.execute( recaptcha.data( 'widgetid' ) ); 2505 } 2506 } 2507 2508 valid = false; 2509 } else { 2510 recaptcha.removeClass( 'fl-form-error' ); 2511 recaptcha.siblings( '.fl-form-error-message' ).hide(); 2512 } 2513 } 2514 2515 if ( valid ) { 2516 2517 currentForm.find( '> .fl-form-error-message' ).hide(); 2518 submitButton.find( '.fl-button-text' ).text( waitText ); 2519 submitButton.data( 'original-text', buttonText ); 2520 submitButton.addClass( 'fl-form-button-disabled' ); 2521 2522 ajaxData = { 2523 action : 'fl_builder_subscribe_form_submit', 2524 name : name.val(), 2525 email : email.val(), 2526 success_url : successUrl, 2527 terms_checked : termsCheckbox.is(':checked') ? '1' : '0', 2528 post_id : postId, 2529 template_id : templateId, 2530 template_node_id : templateNodeId, 2531 node_id : nodeId 2532 }; 2533 2534 if ( reCaptchaValue ) { 2535 ajaxData.recaptcha = reCaptchaValue; 2536 } 2537 2538 $.post( FLBuilderLayoutConfig.paths.wpAjaxUrl, ajaxData, $.proxy( function( response ){ 2539 this._submitFormComplete( response, submitButton ); 2540 }, this )); 2541 } 2542 }, 2543 2544 _submitFormComplete: function( response, button ) 2545 { 2546 var data = JSON.parse( response ), 2547 buttonText = button.data( 'original-text' ), 2548 form = button.closest( '.fl-subscribe-form' ); 2549 2550 if ( data.error ) { 2551 2552 if ( data.error ) { 2553 form.find( '> .fl-form-error-message' ).text( data.error ); 2554 } 2555 2556 form.find( '> .fl-form-error-message' ).show(); 2557 button.removeClass( 'fl-form-button-disabled' ); 2558 button.find( '.fl-button-text' ).text( buttonText ); 2559 if ( typeof data.errorInfo !== 'undefined' ) { 2560 console.log('Subscribe Form:',data.errorInfo); 2561 } 2562 } 2563 else if ( 'message' == data.action ) { 2564 form.find( '> *' ).hide(); 2565 $( this.nodeClass + ' .fl-form-success-message' ).show(); 2566 } 2567 else if ( 'redirect' == data.action ) { 2568 window.location.href = data.url; 2569 } 2570 }, 2571 2572 _onEnterKey: function( e ) 2573 { 2574 if (e.which == 13) { 2575 var currentForm = $( e.currentTarget ).closest( '.fl-subscribe-form' ); 2576 currentForm.find( 'a.fl-button' ).trigger( 'click' ); 2577 } 2578 } 2579 } 2580 2581})( jQuery ); 2582(function($) { 2583 $(function() { 2584 2585 new FLBuilderSubscribeForm({ 2586 id: 'a9sgv13wurem', 2587 successAction: 'message', 2588 successUrl: '', 2589 }); 2590 }); 2591 2592})(jQuery); 2593(function($) { 2594 2595 $(function() { 2596 2597 new FLBuilderPostGrid({ 2598 id: 'o7dbpjrz8yg0', 2599 layout: 'columns', 2600 pagination: 'none', 2601 postSpacing: '60', 2602 postWidth: '300', 2603 matchHeight: { 2604 default : '0', 2605 medium : '', 2606 responsive : '' 2607 }, 2608 isRTL: false }); 2609 2610 }); 2611 2612})(jQuery); 2613(function($) { 2614 2615 $(function() { 2616 2617 new FLBuilderPostGrid({ 2618 id: '6vdkou7s5ah4', 2619 layout: 'columns', 2620 pagination: 'none', 2621 postSpacing: '60', 2622 postWidth: '300', 2623 matchHeight: { 2624 default : '0', 2625 medium : '', 2626 responsive : '' 2627 }, 2628 isRTL: false }); 2629 2630 }); 2631 2632})(jQuery); 2633(function($) { 2634 2635 $(function() { 2636 2637 new FLBuilderPostGrid({ 2638 id: 'ixjcr38nwghe', 2639 layout: 'columns', 2640 pagination: 'none', 2641 postSpacing: '60', 2642 postWidth: '300', 2643 matchHeight: { 2644 default : '0', 2645 medium : '', 2646 responsive : '' 2647 }, 2648 isRTL: false }); 2649 2650 }); 2651 2652})(jQuery); 2653(function($) { 2654 2655 $(function() { 2656 2657 new FLBuilderPostGrid({ 2658 id: '3qh0jy5ucfx1', 2659 layout: 'columns', 2660 pagination: 'none', 2661 postSpacing: '60', 2662 postWidth: '300', 2663 matchHeight: { 2664 default : '0', 2665 medium : '', 2666 responsive : '' 2667 }, 2668 isRTL: false }); 2669 2670 }); 2671 2672})(jQuery); 2673(function($) { 2674 2675 $(function() { 2676 2677 new FLBuilderPostGrid({ 2678 id: 'sjbvt8kr6idz', 2679 layout: 'columns', 2680 pagination: 'none', 2681 postSpacing: '60', 2682 postWidth: '300', 2683 matchHeight: { 2684 default : '0', 2685 medium : '', 2686 responsive : '' 2687 }, 2688 isRTL: false }); 2689 2690 }); 2691 2692})(jQuery); 2693(function($) { 2694 2695 $(function() { 2696 2697 new FLBuilderPostGrid({ 2698 id: 'yof4vekdz597', 2699 layout: 'columns', 2700 pagination: 'none', 2701 postSpacing: '60', 2702 postWidth: '300', 2703 matchHeight: { 2704 default : '1', 2705 medium : '', 2706 responsive : '' 2707 }, 2708 isRTL: false }); 2709 2710 }); 2711 2712})(jQuery); 2713jQuery(function($) { 2714 2715 $(function() { 2716 $( '.fl-node-897mdlib6xgo .fl-photo-img' ) 2717 .on( 'mouseenter', function( e ) { 2718 $( this ).data( 'title', $( this ).attr( 'title' ) ).removeAttr( 'title' ); 2719 } ) 2720 .on( 'mouseleave', function( e ){ 2721 $( this ).attr( 'title', $( this ).data( 'title' ) ).data( 'title', null ); 2722 } ); 2723 }); 2724 }); 2725(function($) { 2726 2727 $(function() { 2728 2729 new FLBuilderPostGrid({ 2730 id: 'xkucbez5jyvn', 2731 layout: 'columns', 2732 pagination: 'none', 2733 postSpacing: '40', 2734 postWidth: '300', 2735 matchHeight: { 2736 default : '0', 2737 medium : '', 2738 responsive : '' 2739 }, 2740 isRTL: false }); 2741 2742 }); 2743 2744})(jQuery); 2745jQuery(function($) { 2746 2747 $(function() { 2748 $( '.fl-node-63cpmkyw4zt0 .fl-photo-img' ) 2749 .on( 'mouseenter', function( e ) { 2750 $( this ).data( 'title', $( this ).attr( 'title' ) ).removeAttr( 'title' ); 2751 } ) 2752 .on( 'mouseleave', function( e ){ 2753 $( this ).attr( 'title', $( this ).data( 'title' ) ).data( 'title', null ); 2754 } ); 2755 }); 2756 }); 2757jQuery(function($) { 2758 2759 $(function() { 2760 $( '.fl-node-d5u0wgrkb4ms .fl-photo-img' ) 2761 .on( 'mouseenter', function( e ) { 2762 $( this ).data( 'title', $( this ).attr( 'title' ) ).removeAttr( 'title' ); 2763 } ) 2764 .on( 'mouseleave', function( e ){ 2765 $( this ).attr( 'title', $( this ).data( 'title' ) ).data( 'title', null ); 2766 } ); 2767 }); 2768 }); 2769jQuery(function($) { 2770 2771 $(function() { 2772 $( '.fl-node-sa1e6hzv9nqy .fl-photo-img' ) 2773 .on( 'mouseenter', function( e ) { 2774 $( this ).data( 'title', $( this ).attr( 'title' ) ).removeAttr( 'title' ); 2775 } ) 2776 .on( 'mouseleave', function( e ){ 2777 $( this ).attr( 'title', $( this ).data( 'title' ) ).data( 'title', null ); 2778 } ); 2779 }); 2780 }); 2781jQuery(function($) { 2782 2783 $(function() { 2784 $( '.fl-node-8ykob3smpa7t .fl-photo-img' ) 2785 .on( 'mouseenter', function( e ) { 2786 $( this ).data( 'title', $( this ).attr( 'title' ) ).removeAttr( 'title' ); 2787 } ) 2788 .on( 'mouseleave', function( e ){ 2789 $( this ).attr( 'title', $( this ).data( 'title' ) ).data( 'title', null ); 2790 } ); 2791 }); 2792 }); 2793jQuery(function($) { 2794 2795 $(function() { 2796 $( '.fl-node-86wbul72xt1s .fl-photo-img' ) 2797 .on( 'mouseenter', function( e ) { 2798 $( this ).data( 'title', $( this ).attr( 'title' ) ).removeAttr( 'title' ); 2799 } ) 2800 .on( 'mouseleave', function( e ){ 2801 $( this ).attr( 'title', $( this ).data( 'title' ) ).data( 'title', null ); 2802 } ); 2803 }); 2804 }); 2805jQuery(function($) { 2806 2807 $(function() { 2808 $( '.fl-node-x2gi706khtc1 .fl-photo-img' ) 2809 .on( 'mouseenter', function( e ) { 2810 $( this ).data( 'title', $( this ).attr( 'title' ) ).removeAttr( 'title' ); 2811 } ) 2812 .on( 'mouseleave', function( e ){ 2813 $( this ).attr( 'title', $( this ).data( 'title' ) ).data( 'title', null ); 2814 } ); 2815 }); 2816 }); 2817 2818/* Start Global Node Custom JS */ 2819 2820/* End Global Node Custom JS */ 2821 2822 2823/* Start Layout Custom JS */ 2824 2825/* End Layout Custom JS */ 2826
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.