1"use strict"; 2 3; 4/* global wppopups_settings,*/ 5 6(function ($) { 7 'use strict'; 8 9 var WPPopups = { 10 popups: {}, 11 byBind: { 12 'class': [], 13 'href': [] 14 }, 15 16 /** 17 * Start the engine. 18 * 19 * @since 2.0.0 20 */ 21 init: function init() { 22 // Document ready 23 $(document).ready(WPPopups.ready); // Page load 24 25 $(window).on('load', WPPopups.load); // Document ready 26 27 $(document).on('wppopupsAjaxReady', WPPopups.ajaxStart); 28 WPPopups.bindUIActions(); 29 }, 30 31 /** 32 * Document ready. 33 * 34 * @since 2.0.0 35 */ 36 ready: function ready() { 37 $(document).trigger('wppopupsBeforeReady'); 38 if ($(".spu-box").length == 0) return false; 39 var data = { 40 action: 'wppopups_rules', 41 pid: wppopups_vars.pid, 42 referrer: document.referrer, 43 url: document.documentURI, 44 query_string: document.location.search, 45 is_category: wppopups_vars.is_category, 46 is_archive: wppopups_vars.is_archive, 47 is_singular: wppopups_vars.is_singular, 48 is_preview: wppopups_vars.is_preview, 49 is_search: wppopups_vars.is_search, 50 is_front_page: wppopups_vars.is_front_page, 51 is_blog_page: wppopups_vars.is_blog_page, 52 woo_is_shop: wppopups_vars.woo_is_shop, 53 woo_is_order_received: wppopups_vars.woo_is_order_received, 54 woo_is_product_category: wppopups_vars.woo_is_product_category, 55 woo_is_product_tag: wppopups_vars.woo_is_product_tag, 56 woo_is_product: wppopups_vars.woo_is_product, 57 woo_is_cart: wppopups_vars.woo_is_cart, 58 woo_is_checkout: wppopups_vars.woo_is_checkout, 59 woo_is_account_page: wppopups_vars.woo_is_account_page, 60 popups: [] 61 }; // save all popups rules into data 62 63 $(".spu-box").each(function () { 64 var $popup = $(this), 65 $id = $popup.data('id'), 66 $need_ajax = $popup.data('need_ajax'), 67 $rules = WPPopups.settings($popup, 'rules'), 68 $global_rules = WPPopups.settings($popup, 'global_rules'); // if old popup it's enabled id will be empty and break things 69 70 if ($id && $need_ajax) { 71 data.popups.push({ 72 id: $id, 73 rules: JSON.stringify($rules), 74 global_rules: JSON.stringify($global_rules), 75 parent: $popup.data('parent') 76 }); 77 } 78 }); 79 var ajax = { 80 url: wppopups_vars.ajax_url, 81 data: window.wp.hooks.applyFilters('wppopups_pre_ready_data', data), 82 cache: false, 83 type: 'POST', 84 dataType: 'json', 85 timeout: 30000, 86 success: function success(r) { 87 if (r.success) { 88 r.success.forEach(function (id) { 89 WPPopups.removePopup(id); 90 }); 91 } 92 93 $(document).trigger('wppopupsAjaxReady'); 94 }, 95 error: function error(r) { 96 console.log(r); 97 } 98 }; 99 100 if (data.popups.length) { 101 $.ajax(ajax); 102 } 103 104 WPPopups.initVideoSources(); 105 WPPopups.resetPopupsContent(); 106 WPPopups.hashTriggerPopups(); // init popups that doesn't need ajax 107 108 $(".spu-box").each(function () { 109 var $popup = $(this), 110 $need_ajax = $popup.data('need_ajax'); 111 112 if ($need_ajax) { 113 $popup.hide(); 114 return; 115 } 116 117 WPPopups.initPopup($popup); 118 }); 119 WPPopups.loadValidation(); 120 WPPopups.initSocialShortcodes(); 121 $(document).trigger('wppopupsReady'); 122 }, 123 124 /** 125 * Page load. 126 * 127 * @since 2.0.0 128 */ 129 load: function load() { 130 // center again once it's loaded 131 $(".spu-box").each(function () { 132 var $popup = $(this); 133 WPPopups.centerPopup($popup); 134 }); 135 }, 136 ajaxStart: function ajaxStart() { 137 $(".spu-box").each(function () { 138 var $popup = $(this), 139 $need_ajax = $popup.data('need_ajax'); 140 141 if (!$need_ajax) { 142 return; 143 } 144 145 WPPopups.initPopup($popup); 146 }); 147 $(document).trigger('wppopupsAjaxStarted'); 148 }, 149 150 /** 151 * Configure each popup 152 */ 153 initPopup: function initPopup($popup) { 154 var $id = $popup.data('id'); // Save popup for later 155 156 WPPopups.popups[$id] = $popup; // all triggers added by users 157 158 WPPopups.bindPopupTriggers($popup); // click triggers 159 160 WPPopups.bindClickTriggers($popup); // Forms inside popups 161 162 WPPopups.formSubmissions($popup); // Forms Email Marketing 163 //WPPopups.formOptinSubmissions($popup); 164 // Events bindings 165 166 $(window).resize(function () { 167 WPPopups.checkPopupSize($popup); 168 WPPopups.centerPopup($popup, true); 169 }); // This hook will be used by third parties 170 171 window.wp.hooks.doAction('wppopups_loop', $popup); 172 window.wp.hooks.addAction('wppopups_show_popup', 'wppopups', WPPopups.centerPopup, 99); // hide it 173 174 $popup.hide(); 175 }, 176 // --------------------------------------------------------------------// 177 // Triggers 178 // --------------------------------------------------------------------// 179 180 /** 181 * Trigger popup after N seconds 182 * @param value 183 * @param $popup 184 */ 185 triggerBySeconds: function triggerBySeconds(value, $popup) { 186 // if not value provided abort 187 if (value === '') { 188 return; 189 } 190 191 if ($popup.timer) { 192 clearTimeout($popup.timer); 193 } 194 195 $popup.timer = window.setTimeout(function () { 196 if (WPPopups.checkConvertion($popup)) { 197 WPPopups.showPopup($popup); 198 } 199 }, parseInt(value, 10) * 1000); 200 }, 201 202 /** 203 * Trigger if scroll % amount of screen 204 * @param value 205 * @param $popup 206 */ 207 triggerByPercentage: function triggerByPercentage(value, $popup) { 208 // if not value provided abort 209 if (value === '') { 210 return; 211 } 212 213 var $settings = WPPopups.settings($popup, 'settings'); // use custom namespace bind for off later 214 215 $(window).on('scroll.per' + $popup.data('id'), function () { 216 if ($popup.timer) { 217 clearTimeout($popup.timer); 218 } 219 220 $popup.timer = window.setTimeout(function () { 221 var triggerHeight = parseInt(value, 10) / 100 * $(document).height(); 222 var scrollY = $(window).scrollTop(), 223 trigger = scrollY + $(window).height() >= triggerHeight; // show box when criteria for this box is matched 224 225 if (trigger && WPPopups.checkConvertion($popup)) { 226 // remove listen event if box shouldn't be hidden again. TODO: add auto hide in trigger settings 227 if (!$settings.auto_hide) { 228 $(window).off('scroll.per' + $popup.data('id')); 229 } 230 231 WPPopups.showPopup($popup); 232 } else if ($settings.auto_hide) { 233 WPPopups.hidePopup($popup, false, 10, false); 234 } 235 }, 100); 236 }); 237 }, 238 239 /** 240 * Bind TRigger after user scrolled X pixels 241 * @param value 242 * @param $popup 243 */ 244 triggerByPixels: function triggerByPixels(value, $popup) { 245 // if not pixels provided abort 246 if (value === '') { 247 return; 248 } 249 250 var $settings = WPPopups.settings($popup, 'settings'); 251 $(window).on('scroll.pix' + $popup.data('id'), function () { 252 if ($popup.timer) { 253 clearTimeout($popup.timer); 254 } 255 256 $popup.timer = window.setTimeout(function () { 257 var scrollY = $(window).scrollTop(), 258 trigger = scrollY >= parseInt(value, 10); //triggerSeconds equals to the number field really 259 // show box when criteria for this box is matched 260 261 if (trigger && WPPopups.checkConvertion($popup)) { 262 // remove listen event if box shouldn't be hidden again 263 if (!$settings.auto_hide) { 264 $(window).off('scroll.pix' + $popup.data('id')); 265 } 266 267 WPPopups.showPopup($popup); 268 } else if ($settings.auto_hide) { 269 WPPopups.hidePopup($popup, false, 10, false); 270 } 271 }, 100); 272 }); 273 }, 274 triggerByClass: function triggerByClass(value, $popup) { 275 // if not class provided abort 276 if (value === '') { 277 return; 278 } // add . to class attribute if missing 279 280 281 value = value.charAt(0) != '.' ? '.' + value : value; 282 WPPopups.setBindActions(value, 'class'); // Only add the trigger if not cookies are set for popup 283 284 if (WPPopups.hasCookies($popup)) { 285 return; 286 } 287 288 $(document.body).on('click', value, function (e) { 289 e.preventDefault(); 290 WPPopups.showPopup($popup); 291 }); 292 }, 293 // --------------------------------------------------------------------// 294 // Binds 295 // --------------------------------------------------------------------// 296 297 /** 298 * Bind document triggers for popups 299 * @param $popup 300 */ 301 bindClickTriggers: function bindClickTriggers($popup) { 302 var id = $popup.data('id'); 303 WPPopups.setBindActions('.spu-open-' + id, 'class'); 304 WPPopups.setBindActions('#spu-' + id, 'href'); // Only add the trigger if not cookies are set for popup 305 306 if (WPPopups.hasCookies($popup)) { 307 return; 308 } // add link listener for this box 309 310 311 $(document.body).on('click', 'a[href="#spu-' + id + '"], .spu-open-' + id, function (e) { 312 e.preventDefault(); 313 WPPopups.showPopup($popup, true); 314 }); 315 $('a[href="#spu-' + id + '"], .spu-open-' + id).css('cursor', 'pointer').addClass('spu-clickable'); 316 }, 317 318 /** 319 * Bind triggers set in popup settings 320 * @param $popup 321 */ 322 bindPopupTriggers: function bindPopupTriggers($popup) { 323 if (window.wp.hooks.applyFilters('wppopups_disable_triggers', false, $popup)) return; 324 var $triggers = WPPopups.settings($popup, 'triggers'); 325 326 if (Object.keys($triggers).length) { 327 for (var i in $triggers) { 328 var func = 'triggerBy' + $triggers[i].trigger.charAt(0).toUpperCase() + $triggers[i].trigger.substr(1), 329 settings = WPPopups.settings($popup, 'settings'); 330 331 if (!WPPopups.hasCookies($popup) || wppopups_vars.is_preview || func == 'triggerByClass' || wppopups_vars.is_admin && settings.test_mode == '1') { 332 // only try if func really exist , may be premium one 333 if (typeof WPPopups[func] == 'function') { 334 WPPopups[func]($triggers[i].value, $popup); 335 } // hook for premium 336 337 338 window.wp.hooks.doAction('wppopups_trigger_popup', func, $triggers[i].value, $popup); 339 } 340 } 341 } 342 }, 343 344 /** 345 * Element bindings. 346 * 347 * @since 2.0.0 348 */ 349 bindUIActions: function bindUIActions() { 350 // Custom links inside popups conversion 351 $(document).on('click', '.spu-box a:not(".spu-close-popup, .spu-box .flp_wrapper a, .spu-box .spu-not-close, .spu-box .spu-not-close a, .spu-box .spu-gdpr a")', function () { 352 // hide the popup and track conversion 353 WPPopups.hidePopup($(this), true); 354 }); // Close and convert button, similar to above 355 356 $(document).on('click', '.spu-box .spu-close-convert,.spu-box .spu-close-convert a', function (e) { 357 e.preventDefault(); // hide the popup and track conversion 358 359 WPPopups.hidePopup($(this), true); 360 }); //close popup 361 362 $(document).on('click', '.spu-box .spu-close-popup', function (e) { 363 e.preventDefault(); // hide box, no conversion 364 365 WPPopups.hidePopup($(this), false); 366 }); //close with esc 367 368 $(document).on('keyup', function (e) { 369 if (e.keyCode == 27) { 370 WPPopups.togglePopups(false, false); 371 } 372 }); // close by clicking outside of popup 373 // get event by device or browser 374 375 var ua = navigator.userAgent, 376 event = ua.match(/iPad/i) || ua.match(/iPhone/i) ? "touchstart" : "click"; 377 $('body').on(event, function (ev) { 378 var $target = $(ev.target); // TODO: 379 // for some reason ninja form not working, added this dirty workaround 380 // $target.is('.spu-box *, .spu-box') return false, same for .has .parents, etc 381 // so no popup closing when form is clicked 382 383 if ($target.is('input.nf-element')) return; // verify if some bindAction is present 384 385 if (WPPopups.checkBindActions($target)) return; 386 if (window.wp.hooks.applyFilters('wppopups_disable_click_out', false, $target)) return; // test that event is user triggered and not programatically, 387 // and that it is not fired within the box 388 389 if (ev.originalEvent !== undefined && !$target.is('.spu-box *, .spu-box')) { 390 WPPopups.togglePopups(false, false); 391 } 392 }); 393 }, 394 395 /** 396 * Return setting from popup 397 * @param popup 398 * @param key 399 * @returns {*} 400 */ 401 settings: function settings(popup, key) { 402 var settings = {}; 403 404 if (popup.data('settings')) { 405 settings = popup.data('settings'); 406 } 407 408 if (key) { 409 if (typeof settings[key] == 'undefined') return {}; 410 return settings[key]; 411 } 412 413 return settings; 414 }, 415 416 /** 417 * Wrapper to execute toggle box on all popups 418 * @param elements 419 * @param show 420 * @param conversion 421 */ 422 togglePopups: function togglePopups(show, conversion) { 423 $('.spu-box').each(function () { 424 if (show) { 425 WPPopups.showPopup($(this)); 426 } else { 427 // premium version may disable advanced closing methods which use tooglePopups 428 if (window.wp.hooks.applyFilters('wppopups_allow_togglePopups', true, $(this))) { 429 WPPopups.hidePopup($(this), conversion); 430 } 431 } 432 }); 433 }, 434 435 /** 436 * Show given popup 437 * @param popup 438 * @param forse true/false 439 * @returns {boolean} 440 */ 441 showPopup: function showPopup(popup) { 442 var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
443 var $popup = WPPopups.getPopup(popup), 444 $id = $popup.data('id'), 445 $bg = $('#spu-bg-' + $id); // don't do anything if box is undergoing an animation or already visible 446 447 if ($popup.is(":animated") || $popup.is(":visible")) { 448 return false; 449 } // don't do anything if popup has any cookie created 450 451 452 if (!force && WPPopups.hasCookies($popup)) { 453 return false; 454 } // Hook before the popup it's shown 455 456 457 window.wp.hooks.doAction('wppopups_before_show_popup', $popup); // show container and the popup 458 459 $popup.parent('.wppopups-whole').show(); // Overlay Blur 460 461 WPPopups.toggleBlur($popup, true); 462 WPPopups.centerPopup($popup); // I want to stop supporting social shortcodes, let's see how many complain 463 464 /* setTimeout(function(){ 465 WPPopups.centerShortcodes($popup); 466 },1500);*/ 467 // Add scroll if needed 468 469 WPPopups.checkPopupSize($popup); // show box 470 471 var animation = WPPopups.settings($popup, 'animation'); 472 473 switch (animation.animation) { 474 case 'fade': 475 $popup.hide().fadeIn('slow'); 476 break; 477 478 case 'slide': 479 $popup.hide().slideDown('slow'); 480 break; 481 482 default: 483 $popup.show(); 484 break; 485 } //background only if not bottom/top bars 486 487 488 if (!$popup.hasClass('spu-position-top-bar') && !$popup.hasClass('spu-position-bottom-bar')) { 489 if (animation.animation === 'disable') { 490 $bg.show(); 491 } else { 492 $bg.fadeIn(); 493 } 494 } // Hook for show popup, used for example for premium animations 495 496 497 window.wp.hooks.doAction('wppopups_show_popup', $popup); // show videos if any 498 499 WPPopups.toggleVideoSources($popup, true); // trigger opening 500 501 $popup.trigger('wppopups.popup_opened', [$id]); 502 }, 503 504 /** 505 * Hide given popup 506 * @param popup 507 * @param conversion 508 * @param time 509 * @returns {boolean} 510 */ 511 hidePopup: function hidePopup(popup, conversion) { 512 var time = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; 513 var cookie = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; 514 var $popup = WPPopups.getPopup(popup), 515 $id = $popup.data('id'), 516 $bg = $('#spu-bg-' + $id); // don't do anything if box is undergoing an animation or already visible 517 518 if ($popup.is(":animated") || $popup.is(":hidden") || window.wp.hooks.applyFilters('wppopups_cancel_hide', false, $popup, conversion)) { 519 return false; 520 } // save cookie 521 522 523 if (conversion === true) { 524 WPPopups.popupConverted($popup, cookie); 525 } 526 527 var settings = WPPopups.settings($popup, 'settings'); 528 529 if (settings.close_on_conversion == '1' && conversion || !conversion) { 530 setTimeout(function () { 531 var animation = WPPopups.settings($popup, 'animation'); // Hide with animation 532 533 switch (animation.animation) { 534 case 'slide': 535 $popup.slideUp('slow'); 536 $bg.fadeOut(); 537 break; 538 539 case 'disable': 540 $popup.hide(); 541 $bg.hide(); 542 break; 543 544 default: 545 $popup.removeClass('spu-animation-animated'); 546 $popup.fadeOut('slow'); 547 $bg.fadeOut(); 548 break; 549 } // Hook for show popup, used for example for premium animations 550 551 552 window.wp.hooks.doAction('wppopups_hide_popup', $popup); // hide videos if any 553 554 WPPopups.toggleVideoSources($popup, false); 555 }, parseInt(time, 10)); 556 } // Overlay Blur 557 558 559 WPPopups.toggleBlur($popup, false); // save cookie 560 561 WPPopups.popupClosed($popup, cookie); 562 }, 563 centerPopup: function centerPopup(popup, animate) { 564 if (!popup.hasClass('spu-position-centered') && !popup.hasClass('spu-position-float-right') && !popup.hasClass('spu-position-float-left')) { 565 return; 566 } 567 568 if (popup.is(':animated')) { 569 return; 570 } 571 572 var ww = $(window).width(), 573 wh = $(window).height(), 574 pw = popup.outerWidth(), 575 ph = popup.outerHeight(); // To center the box 576 577 var boxLeft = ww / 2 - pw / 2, 578 boxTop = wh / 2 - ph / 2; 579 var css = { 580 top: boxTop 581 }; 582 583 if (popup.hasClass('spu-position-centered')) { 584 css.left = boxLeft; 585 } 586 587 if (animate) { 588 popup.animate(css, { 589 queue: !1, 590 duration: 200 591 }); 592 } else { 593 popup.css(css); 594 } 595 }, 596 597 /** 598 * Removes the popup from DOM 599 * @param $popup 600 */ 601 removePopup: function removePopup(popup) { 602 var $popup = WPPopups.getPopup(popup), 603 $id = $popup.data('id'), 604 $bg = $('#spu-bg-' + $id), 605 $css = $('#spu-css-' + $id); 606 $popup.remove(); 607 $bg.remove(); 608 $css.remove(); 609 }, 610 611 /** 612 * Track popup conversion (save cookie) 613 * @param $popup 614 */ 615 popupConverted: function popupConverted($popup) { 616 var cookie = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; 617 618 if (cookie) { 619 // set cookie 620 var settings = WPPopups.settings($popup, 'settings'), 621 duration = parseFloat(settings.conversion_cookie_duration), 622 _cookie = settings.conversion_cookie_name, 623 type = settings.conversion_cookie_type; 624 625 if (duration > 0) { 626 WPPopups.createCookie(_cookie, true, duration, type); 627 } 628 } 629 630 $popup.trigger('wppopups.popup_converted', [$popup.data('id')]); 631 }, 632 633 /** 634 * Track popup closing (save cookie) 635 * @param $popup 636 */ 637 popupClosed: function popupClosed($popup) { 638 var cookie = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; 639 640 if (cookie) { 641 // set cookie 642 var settings = WPPopups.settings($popup, 'settings'), 643 duration = parseFloat(settings.closing_cookie_duration), 644 _cookie2 = settings.closing_cookie_name, 645 type = settings.closing_cookie_type; 646 647 if (duration > 0) { 648 WPPopups.createCookie(_cookie2, true, duration, type); 649 } 650 } 651 652 $popup.trigger('wppopups.popup_closed', [$popup.data('id')]); 653 }, 654 655 /** 656 * Check if the popup has any cookies created. 657 * @param $popup 658 */ 659 hasCookies: function hasCookies($popup) { 660 var $settings = WPPopups.settings($popup, 'settings'), 661 conversion_name = $settings.conversion_cookie_name, 662 closing_name = $settings.closing_cookie_name; 663 var hasCookies = false;
664 665 if (!(wppopups_vars.is_admin && $settings.test_mode == '1') && (WPPopups.getCookie(conversion_name) || WPPopups.getCookie(closing_name))) { 666 hasCookies = true; 667 } 668 669 return hasCookies; 670 }, 671 672 /** 673 * Apply Overlay Blur 674 * @param $popup 675 * @param show true/false 676 * @return 677 */ 678 toggleBlur: function toggleBlur($popup, show) { 679 // Overlay Blur 680 var colors = WPPopups.settings($popup, 'colors'), 681 $id = $popup.data('id'), 682 $box_css = $('#spu-css-' + $id); 683 684 if (colors.show_overlay == 'yes-blur') { 685 if (show) { 686 var blur_px = colors.overlay_blur ? colors.overlay_blur : 2, 687 blur_css = '/* ini:blur */body > *:not(.wppopups-whole) { -webkit-filter: blur(' + blur_px + 'px); -moz-filter: blur(' + blur_px + 'px); -o-filter: blur(' + blur_px + 'px); -ms-filter: blur(' + blur_px + 'px); filter: blur(' + blur_px + 'px); }/* fin:blur */'; 688 $box_css.append(blur_css); 689 } else { 690 var css = $box_css.text(), 691 ini = css.indexOf('/* ini:blur */'), 692 pro = css.substring(ini); 693 $box_css.text(css.replace(pro, '')); 694 } 695 } 696 }, 697 698 /** 699 * Check all iframes and set source to empty on page load 700 */ 701 initVideoSources: function initVideoSources() { 702 var iframe = $('.spu-box iframe'); 703 704 if (iframe && iframe.length) { 705 iframe.each(function () { 706 $(this).attr('spusrc', $(this).attr('src')); 707 $(this).attr('src', 'https://#'); 708 }); 709 } 710 }, 711 712 /** 713 * Toggle a popup iframe source 714 * @param popup 715 * @param show 716 */ 717 toggleVideoSources: function toggleVideoSources(popup, show) { 718 var iframe = popup.find('iframe'); 719 720 if (iframe && iframe.length) { 721 iframe.each(function () { 722 if (show) { 723 if ($(this).attr('spusrc')) { 724 $(this).attr('src', $(this).attr('spusrc')); 725 $(this).css("width", ""); 726 $(this).css("height", ""); 727 } 728 } else { 729 // destroy videos so they stop playing 730 $(this).attr('src', 'https://#'); 731 } 732 }); 733 } 734 }, 735 736 /** 737 * remove paddings and margins from first and last items inside popups 738 * so it looks even with the given padding 739 */ 740 resetPopupsContent: function resetPopupsContent() { 741 $(".spu-content").children().first().not('.spu-fields-container').css({ 742 "margin-top": 0, 743 "padding-top": 0 744 }).end().last().not('.spu-fields-container').css({ 745 'margin-bottom': 0, 746 'padding-bottom': 0 747 }); 748 }, 749 750 /** 751 * Trigger popup opening if anyone use #spu-open-123 in url 752 */ 753 hashTriggerPopups: function hashTriggerPopups() { 754 // shows the box when hash refers to a box 755 if (window.location.hash && window.location.hash.length > 0) { 756 var hash = window.location.hash, 757 form_key = hash.substring(1).indexOf('spu-form'), 758 link_key = hash.substring(1).indexOf('spu-open'), 759 form_popup = form_key !== -1, 760 link_popup = link_key !== -1; 761 if (form_popup) var i = form_key + 10;else if (link_popup) var i = link_key + 10; 762 763 if ((link_popup || form_popup) && $('#spu-' + hash.substring(i)).is('.spu-box')) { 764 var popup = $('#spu-' + hash.substring(i)); // if triggered by a form add a close button if don't exist already one 765 766 if (form_popup && popup.find('.spu-close-popup').length < 2) { 767 popup.find('.spu-content').append('<p style="text-align: center"><button class="btn btn-primary spu-close-popup">Close</button></p>'); 768 } // unbind regular triggers and set conversion 769 770 771 if (form_popup) { 772 $(window).off('scroll.per' + popup.data('id')); 773 $(window).off('scroll.pix' + popup.data('id')); 774 WPPopups.popupConverted(popup); 775 } 776 777 setTimeout(function () { 778 WPPopups.showPopup(popup, true); 779 }, 200); 780 } 781 } 782 }, 783 784 /** 785 * Handle form submissions in two ways. Adding ajax most known forms callbacks 786 * and adding #spu-form to action for regular forms that will open on page load 787 * @param $popup 788 */ 789 formSubmissions: function formSubmissions($popup) { 790 var popup_id = $popup.data('id'); 791 $popup.find('form').each(function () { 792 var box_form = $(this), 793 action = box_form.attr('action') || ''; 794 box_form.attr('action', action + '#spu-form-' + popup_id); // only run if not our form 795 796 if (box_form.hasClass('spu-optin-form')) { 797 return; 798 } // If url is external, we need to track popup before submission 799 800 801 if (WPPopups.isExternal(action)) { 802 box_form.on('submit', function () { 803 WPPopups.hidePopup($popup, true); 804 }); 805 } 806 }); // Ninja forms don't use form elements O_o 807 808 $(document).on('nfFormSubmitResponse', function () { 809 $popup.trigger('wppopups.form_submitted', [popup_id]); 810 WPPopups.hidePopup($popup, true, 2000); 811 }); // Contact form 7 812 813 $popup.on('wpcf7mailsent', function () { 814 $popup.trigger('wppopups.form_submitted', [popup_id]); 815 WPPopups.hidePopup($popup, true, 2000); 816 }); // Gravity forms (ajax mode) 817 818 $(document).on('gform_post_render', function (jqXHR, form_id) { 819 var $form = $('#gform_ajax_frame_' + form_id); 820 821 if (!$form.is('.spu-box *')) { 822 return; 823 } 824 825 var contents = $form.contents().find('*').html(), 826 form_content = $form.contents().find('#gform_wrapper_' + form_id), 827 is_confirmation = $form.contents().find('#gform_confirmation_wrapper_' + form_id).length > 0, 828 is_redirect = contents.indexOf('gformRedirect(){') >= 0; 829 830 if (is_confirmation || is_redirect) { 831 $popup.trigger('wppopups.form_submitted', [popup_id]); 832 WPPopups.hidePopup($popup, true, 2000); 833 } 834 }); // Caldera Forms (ajax mode) 835 836 $(document).on('cf.submission', function () { 837 $popup.trigger('wppopups.form_submitted', [popup_id]); 838 WPPopups.hidePopup($popup, true, 2000); 839 }); // WPForms (ajax mode) 840 841 $(document).on('wpformsAjaxSubmitSuccess', function () { 842 $popup.trigger('wppopups.form_submitted', [popup_id]); 843 WPPopups.hidePopup($popup, true, 2000); 844 }); // Yikes form 845 846 $(document).on('yikes_mailchimp_ajax_submission', function (e, response) { 847 if (response.success) { 848 $popup.trigger('wppopups.form_submitted', [popup_id]); 849 WPPopups.hidePopup($popup, true, 2000); 850 } 851 }); 852 }, 853 854 /** 855 * Check if url is external 856 * @param url 857 * @returns {boolean} 858 */ 859 isExternal: function isExternal(url) { 860 if (url.length === 0) { 861 return false;
862 } 863 864 var domain = function domain(url) { 865 return url.replace('http://', '').replace('https://', '').split('/')[0]; 866 }; 867 868 return domain(location.href) !== domain(url); 869 }, 870 871 /** 872 * Forms to Email Marketing 873 * @param $popup 874 */ 875 formOptinSubmissions: function formOptinSubmissions($popup) { 876 var popup_id = $popup.data('id'), 877 $form = $popup.find('.wppopups-form'), 878 $submit_btn = $form.find('.wppopups-submit-button'); 879 WPPopups.toggleButton($submit_btn, true); 880 var data = $form.serializeArray(); 881 data.push({ 882 name: 'action', 883 value: 'wppopups_optin_submit' 884 }); 885 data.push({ 886 name: 'id', 887 value: popup_id 888 }); 889 var ajax = { 890 url: wppopups_vars.ajax_url, 891 data: data, 892 cache: false, 893 type: 'POST', 894 dataType: 'json', 895 timeout: 30000, 896 success: function success(r) { 897 console.log(r); 898 899 if (r.success) { 900 // redirect if set in settings 901 if (r.data[1] && r.data[1].optin_redirect) { 902 $popup.trigger('wppopups.optin_on_redirect', [popup_id]); 903 var redirect = r.data[1].optin_redirect; 904 905 if (r.data[1].pass_lead_data && r.data[1].pass_lead_data == 1) { 906 var qstring = []; 907 var sep = redirect.match(/[\?]/g) ? '&' : '?'; 908 909 for (var key in data) { 910 if (data[key]['value'] == '') continue; 911 qstring.push(encodeURIComponent(data[key]['name']) + '=' + encodeURIComponent(data[key]['value'])); 912 } 913 914 redirect = redirect + sep + qstring.join('&'); 915 } 916 917 WPPopups.hidePopup($popup, true); 918 window.location.href = redirect; 919 return; 920 } // clear errors 921 922 923 $popup.find('.optin-errors').html('').hide(); // success message 924 925 if (r.data[0] && r.data[0].optin_success) { 926 WPPopups.popupConverted($popup); 927 $popup.find('.spu-content').html(r.data[0].optin_success); 928 WPPopups.centerPopup($popup, true); 929 930 if (r.data[0].optin_success_seconds && parseInt(r.data[0].optin_success_seconds) > 0) { 931 var seconds = parseInt(r.data[0].optin_success_seconds, 10) * 1000; 932 WPPopups.hidePopup($popup, false, seconds); 933 } 934 } else { 935 WPPopups.hidePopup($popup, true); 936 } 937 } else { 938 $popup.find('.optin-errors').html(r.data).fadeIn(); 939 } 940 941 $popup.trigger('wppopups.optin_form_submitted', [popup_id, r]); 942 WPPopups.toggleButton($submit_btn, false); 943 }, 944 error: function error(r) { 945 console.log(r); 946 WPPopups.toggleButton($submit_btn, false); 947 } 948 }; 949 $.ajax(ajax); 950 }, 951 loadValidation: function loadValidation() { 952 // Only load if jQuery validation library exists. 953 if (typeof $.fn.validate !== 'undefined') { 954 // Prepend URL field contents with http:// if user input doesn't contain a schema. 955 $('.wppopups-validate input[type=url]').change(function () { 956 var url = $(this).val(); 957 958 if (!url) { 959 return false; 960 } 961 962 if (url.substr(0, 7) !== 'http://' && url.substr(0, 8) !== 'https://') { 963 $(this).val('http://' + url); 964 } 965 }); 966 $.validator.messages.required = wppopups_vars.val_required; 967 $.validator.messages.url = wppopups_vars.val_url; 968 $.validator.messages.email = wppopups_vars.val_email; 969 $.validator.messages.number = wppopups_vars.val_number; // Validate email addresses. 970 971 $.validator.methods.email = function (value, element) { 972 return this.optional(element) || /^[a-z0-9.!#$%&'*+\/=?^_`{|}~-]+@((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}$/i.test(value); 973 }; // Validate checkbox choice limit. 974 975 976 $.validator.addMethod('check-limit', function (value, element) { 977 var $ul = $(element).closest('ul'), 978 $checked = $ul.find('input[type="checkbox"]:checked'), 979 choiceLimit = parseInt($ul.attr('data-choice-limit') || 0, 10); 980 981 if (0 === choiceLimit) { 982 return true; 983 } 984 985 return $checked.length <= choiceLimit; 986 }, function (params, element) { 987 var choiceLimit = parseInt($(element).closest('ul').attr('data-choice-limit') || 0, 10); 988 return wppopups_vars.val_checklimit.replace('{#}', choiceLimit); 989 }); // Finally load jQuery Validation library for our forms. 990 991 $('.wppopups-validate').each(function () { 992 var form = $(this), 993 popupID = form.data('popupid'), 994 properties; // TODO: cleanup this BC with wppopups_validate. 995 996 if (typeof window['wppopups_' + popupID] !== 'undefined' && window['wppopups_' + popupID].hasOwnProperty('val
996idate')) { 997 properties = window['wppopups_' + popupID].validate; 998 } else if (typeof wppopups_validate !== 'undefined') { 999 properties = wppopups_validate; 1000 } else { 1001 properties = { 1002 errorClass: 'wppopups-error', 1003 validClass: 'wppopups-valid', 1004 errorPlacement: function errorPlacement(error, element) { 1005 if ('radio' === element.attr('type') || 'checkbox' === element.attr('type')) { 1006 if (element.hasClass('wppopups-likert-scale-option')) { 1007 if (element.closest('table').hasClass('single-row')) { 1008 element.closest('table').after(error); 1009 } else { 1010 element.closest('tr').find('th').append(error); 1011 } 1012 } else if (element.hasClass('wppopups-net-promoter-score-option')) { 1013 element.closest('table').after(error); 1014 } else { 1015 element.closest('.wppopups-field-checkbox').find('label.wppopups-error').remove(); 1016 element.parent().parent().parent().append(error); 1017 } 1018 } else if (element.is('select') && element.attr('class').match(/date-month|date-day|date-year/)) { 1019 if (0 === element.parent().find('label.wppopups-error:visible').length) { 1020 element.parent().find('select:last').after(error); 1021 } 1022 } else if (element.hasClass('wppopups-smart-phone-field')) { 1023 element.parent().after(error); 1024 } else if (element.hasClass('wppopups-validation-group-member')) { 1025 element.closest('.wppopups-field').append(error); 1026 } else { 1027 error.insertAfter(element); 1028 } 1029 }, 1030 highlight: function highlight(element, errorClass, validClass) { 1031 var $element = $(element), 1032 $field = $element.closest('.wppopups-field'), 1033 inputName = $element.attr('name'); 1034 1035 if ('radio' === $element.attr('type') || 'checkbox' === $element.attr('type')) { 1036 $field.find('input[name="' + inputName + '"]').addClass(errorClass).removeClass(validClass); 1037 } else { 1038 $element.addClass(errorClass).removeClass(validClass); 1039 } 1040 1041 $field.addClass('wppopups-has-error'); 1042 }, 1043 unhighlight: function unhighlight(element, errorClass, validClass) { 1044 var $element = $(element), 1045 $field = $element.closest('.wppopups-field'), 1046 inputName = $element.attr('name'); 1047 1048 if ('radio' === $element.attr('type') || 'checkbox' === $element.attr('type')) { 1049 $field.find('input[name="' + inputName + '"]').addClass(validClass).removeClass(errorClass); 1050 } else { 1051 $element.addClass(validClass).removeClass(errorClass); 1052 } 1053 1054 $field.removeClass('wppopups-has-error'); 1055 }, 1056 submitHandler: function submitHandler(form) { 1057 var $popup = $('#spu-' + popupID); 1058 WPPopups.formOptinSubmissions($popup); 1059 },
1060 invalidHandler: function invalidHandler(event, validator) {//if ( typeof validator.errorList[0] !== 'undefined' ) { 1061 // app.scrollToError( $( validator.errorList[0].element ) ); 1062 //} 1063 }, 1064 onkeyup: function onkeyup(element, event) { 1065 // This code is copied from JQuery Validate 'onkeyup' method with only one change: 'wppopups-novalidate-onkeyup' class check. 1066 var excludedKeys = [16, 17, 18, 20, 35, 36, 37, 38, 39, 40, 45, 144, 225]; 1067 1068 if ($(element).hasClass('wppopups-novalidate-onkeyup')) { 1069 return; // Disable onkeyup validation for some elements (e.g. remote calls). 1070 } 1071 1072 if (9 === event.which && '' === this.elementValue(element) || $.inArray(event.keyCode, excludedKeys) !== -1) { 1073 return; 1074 } else if (element.name in this.submitted || element.name in this.invalid) { 1075 this.element(element); 1076 } 1077 }, 1078 onfocusout: function onfocusout(element) { 1079 // This code is copied from JQuery Validate 'onfocusout' method with only one change: 'wppopups-novalidate-onkeyup' class check. 1080 var validate = false; 1081 1082 if ($(element).hasClass('wppopups-novalidate-onkeyup') && !element.value) { 1083 validate = true; // Empty value error handling for elements with onkeyup validation disabled. 1084 } 1085 1086 if (!this.checkable(element) && (element.name in this.submitted || !this.optional(element))) { 1087 validate = true; 1088 } 1089 1090 if (validate) { 1091 this.element(element); 1092 } 1093 }, 1094 onclick: function onclick(element) { 1095 var validate = false, 1096 type = (element || {}).type, 1097 $el = $(element); 1098 1099 if (['checkbox', 'radio'].indexOf(type) > -1) { 1100 if ($el.hasClass('wppopups-likert-scale-option')) { 1101 $el = $el.closest('tr'); 1102 } else { 1103 $el = $el.closest('.wppopups-field'); 1104 } 1105 1106 $el.find('label.wppopups-error').remove(); 1107 validate = true; 1108 } 1109 1110 if (validate) { 1111 this.element(element); 1112 } 1113 } 1114 }; 1115 } 1116 1117 form.validate(properties); 1118 }); 1119 } 1120 }, 1121 1122 /** 1123 * Helper func to toggle optin button 1124 * @param $submit_btn 1125 * @param disable 1126 */ 1127 toggleButton: function toggleButton($submit_btn, disable) { 1128 var oldText = $submit_btn.data('submit-text'), 1129 altText = $submit_btn.data('alt-text'); 1130 1131 if (disable) { 1132 // Display processing text. 1133 if (altText) { 1134 $submit_btn.text(altText); 1135 } 1136 1137 $submit_btn.addClass('spu-sending'); 1138 $submit_btn.attr('disabled', 'disabled'); 1139 } else { 1140 if (oldText) { 1141 $submit_btn.text(oldText); 1142 } 1143 1144 $submit_btn.removeClass('spu-sending'); 1145 $submit_btn.removeAttr('disabled'); 1146 } 1147 }, 1148 1149 /** 1150 * Check if popup it's bigger than windows to add scroll bars 1151 * @param $popup 1152 */ 1153 checkPopupSize: function checkPopupSize($popup) { 1154 // add 150 to give some margins on top/bottom 1155 if ($popup.outerHeight() + 150 >= $(window).height()) { 1156 $popup.css('overflow', 'auto').addClass('spu-scrollable'); 1157 $popup.css('max-height', $(window).height()); 1158 } else { 1159 $popup.css('overflow', 'initial').removeClass('spu-scrollable'); 1160 $popup.css('max-height', ''); 1161 } 1162 }, 1163 initSocialShortcodes: function initSocialShortcodes() { 1164 // if facebook being used on any popup 1165 if (wppopups_vars.facebook) { 1166 var SPUfb = false, 1167 FbTimer = setInterval(function () { 1168 if (typeof FB !== 'undefined' && !SPUfb) { 1169 try { 1170 FB.Event.subscribe('edge.create', function (href, html_element) { 1171 var $popup = $(html_element).parents('.spu-box'); 1172 1173 if ($popup.length) { 1174 WPPopups.hidePopup($popup, true); 1175 } 1176 }); 1177 } catch (ex) { 1178 console.log(ex); 1179 } 1180 1181 SPUfb = true; 1182 clearInterval(FbTimer); 1183 } 1184 }, 1000); 1185 } 1186 1187 if (wppopups_vars.twitter) { 1188 if (typeof twttr !== 'undefined') { 1189 try { 1190 twttr.ready(function (twttr) { 1191 twttr.events.bind('tweet', WPPopups.twitterCB); 1192 twttr.events.bind('follow', WPPopups.twitterCB); 1193 }); 1194 } catch (ex) {} 1195 } 1196 } 1197 1198 if (wppopups_vars.google) { 1199 if (typeof twttr !== 'undefined') { 1200 try { 1201 twttr.ready(function (twttr) { 1202 twttr.events.bind('tweet', WPPopups.twitterCB); 1203 twttr.events.bind('follow', WPPopups.twitterCB); 1204 }); 1205 } catch (ex) {} 1206 } 1207 } 1208 }, 1209 googleCB: function googleCB(a) { 1210 if ("on" == a.state) { 1211 var box_id = $('.spu-gogl').data('box-id'); 1212 1213 if (box_id) { 1214 WPPopups.hidePopup(box_id, true); 1215 } 1216 } 1217 }, 1218 closeGoogle: function closeGoogle(a) { 1219 if ("confirm" == a.type) { 1220 var box_id = $('.spu-gogl').data('box-id'); 1221 1222 if (box_id) { 1223 WPPopups.hidePopup(box_id, true); 1224 } 1225 } 1226 }, 1227 1228 /** 1229 * Twitter callback function 1230 * @param intent_event 1231 */ 1232 twitterCB: function twitterCB(intent_event) { 1233 var $popup = $(intent_event.target).parents('.spu-box'); 1234 1235 if ($popup) { 1236 WPPopups.hidePopup($popup, true); 1237 } 1238 }, 1239 1240 /** 1241 * Set cookie container user UUID. 1242 * 1243 */ 1244 setUserIndentifier: function setUserIndentifier() { 1245 if (wppopups_settings.uuid_cookie && !WPPopups.getCookie('_wpfuuid')) { 1246 // Generate UUID - http://stackoverflow.com/a/873856/1489528 1247 var s = new Array(36), 1248 hexDigits = '0123456789abcdef', 1249 uuid; 1250 1251 for (var i = 0; i < 36; i++) { 1252 s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); 1253 } 1254
1255 s[14] = "4"; 1256 s[19] = hexDigits.substr(s[19] & 0x3 | 0x8, 1); 1257 s[8] = s[13] = s[18] = s[23] = '-'; 1258 uuid = s.join(""); 1259 WPPopups.createCookie('_wpfuuid', uuid, 3999); 1260 } 1261 }, 1262 1263 /** 1264 * Set classes or href link in a global array 1265 * @param bind_name 1266 * @param bind_type 1267 */ 1268 setBindActions: function setBindActions() { 1269 var bind_name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; 1270 var bind_type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'class'; 1271 1272 if (bind_name != '') { 1273 switch (bind_type) { 1274 case 'class': 1275 bind_name = bind_name.charAt(0) == '.' ? bind_name.substring(1) : bind_name; 1276 if ($.inArray(bind_name, WPPopups.byBind['class']) === -1) WPPopups.byBind['class'].push(bind_name); 1277 break; 1278 1279 case 'href': 1280 if ($.inArray(bind_name, WPPopups.byBind['href']) === -1) WPPopups.byBind['href'].push(bind_name); 1281 break; 1282 } 1283 1284 window.wp.hooks.doAction('wppopups_set_bindactions', bind_name, bind_type); 1285 } 1286 }, 1287 1288 /** 1289 * Check if exists any BindActions when happen a event 1290 * @param target 1291 */ 1292 checkBindActions: function checkBindActions(target) { 1293 var $classes = WPPopups.byBind['class']; 1294 1295 for (var i = 0; i < $classes.length; i++) { 1296 if ($classes[i]) { 1297 if (target.hasClass($classes[i]) || target.closest('.' + $classes[i]).length) { 1298 return true; 1299 } 1300 } 1301 } 1302 1303 var $href = WPPopups.byBind['href']; 1304 1305 for (var _i = 0; _i < $href.length; _i++) { 1306 if ($href[_i] && target.attr('href') == $href[_i]) { 1307 return true; 1308 } 1309 } 1310 1311 return false; 1312 }, 1313 1314 /** 1315 * Create cookie. 1316 * 1317 * @since 2.0.0 1318 */ 1319 createCookie: function createCookie(name, value) { 1320 var duration = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 999; 1321 var type = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'd'; 1322 var expires = ''; // If we have a duration value, set it in the expiry of the cookie. 1323 1324 if (duration && type) { 1325 // If -1 is our value, set a session based cookie instead of a persistent cookie. 1326 if ('-1' === duration) { 1327 expires = ''; 1328 } else { 1329 var cookie_time; 1330 1331 switch (type) { 1332 case 'm': 1333 cookie_time = 60 * 1000; 1334 break; 1335 1336 case 'h': 1337 cookie_time = 60 * 60 * 1000; 1338 break; 1339 1340 default: 1341 cookie_time = 24 * 60 * 60 * 1000; 1342 } 1343 1344 var date = new Date(); 1345 date.setTime(date.getTime() + parseInt(duration) * cookie_time); 1346 expires = '; expires=' + date.toGMTString(); 1347 } 1348 } else { 1349 expires = '; expires=Thu, 01 Jan 1970 00:00:01 GMT'; 1350 } // Write the cookie. 1351 1352 1353 document.cookie = name + '=' + value + expires + '; path=/'; 1354 }, 1355 1356 /** 1357 * Retrieve cookie. 1358 * 1359 * @since 2.0.0 1360 */ 1361 getCookie: function getCookie(name) { 1362 var nameEQ = name + '=', 1363 ca = document.cookie.split(';'); 1364 1365 for (var i = 0; i < ca.length; i++) { 1366 var c = ca[i]; 1367 1368 while (c.charAt(0) === ' ') { 1369 c = c.substring(1, c.length); 1370 } 1371 1372 if (c.indexOf(nameEQ) == 0) { 1373 return c.substring(nameEQ.length, c.length); 1374 } 1375 } 1376 1377 return null; 1378 }, 1379 1380 /** 1381 * Delete cookie. 1382 */ 1383 removeCookie: function removeCookie(name) { 1384 WPPopups.createCookie(name, '', -1); 1385 }, 1386 1387 /** 1388 * Check if it's a number. So (12) and ('12') will be good 1389 * @param n 1390 * @returns {boolean} 1391 */ 1392 isNumber: function isNumber(n) { 1393 return !isNaN(parseFloat(n)) && !isNaN(n - 0); 1394 }, 1395 1396 /** 1397 * Get a popup from a string, or selector or inner selector such as coming from event 1398 * @param popup 1399 */ 1400 getPopup: function getPopup(popup) { 1401 if (WPPopups.isNumber(popup)) { 1402 return $('#spu-' + parseInt(popup)); 1403 } 1404 1405 if (popup.is('.spu-box')) { 1406 return popup; 1407 } 1408 1409 return popup.closest('.spu-box'); 1410 }, 1411 1412 /**
1413 * Check if the popup has convertion rules and fire if needed 1414 * We need to runt his check on js because some popups fire when other convert in the same page load 1415 * Eg: Show exit popup A if popup B fails 1416 * @param $popup 1417 * @returns {boolean} 1418 */ 1419 checkConvertion: function checkConvertion($popup) { 1420 // if no class trigger as normal 1421 if (!$popup.hasClass('yes-convert') && !$popup.hasClass('no-convert')) return true; 1422 var $settings = WPPopups.settings($('#spu-' + $popup.data('convert-id')), 'settings'); 1423 var popup_converted = false; 1424 1425 if (WPPopups.getCookie($settings.conversion_cookie_name)) { 1426 popup_converted = true; 1427 } 1428 1429 if ($popup.hasClass('yes-convert')) { 1430 return popup_converted; 1431 } else { 1432 return !popup_converted; 1433 } 1434 }, 1435 isMobile: function isMobile() { 1436 var Android = navigator.userAgent.match(/Android/i), 1437 BlackBerry = navigator.userAgent.match(/BlackBerry/i), 1438 iOS = navigator.userAgent.match(/iPhone|iPad|iPod/i), 1439 Opera = navigator.userAgent.match(/Opera Mini/i), 1440 Windows = navigator.userAgent.match(/IEMobile/i) || navigator.userAgent.match(/WPDesktop/i); 1441 return Android || BlackBerry || iOS || Opera || Windows; 1442 } 1443 }; // Initialize. 1444 1445 WPPopups.init(); // Add to global scope. 1446 1447 window.wppopups = WPPopups; 1448})(jQuery);
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.