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