PageSourceSearch

https://www.bottegadelsuono.it/wp-content/plugins/wp-popups-lite/src/assets/js/wppopups.js?ver=2.1.4.9

js bottegadelsuono.it collected 2026-09-25 10:48:53 UTC 47,915 bytes, 1,448 lines download raw bytes

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.