PageSourceSearch

https://www.robinsonpetshop.it/app/mu-plugins/jmp-checkout-woo-files/checkout.js?ver=6.8.5

js robinsonpetshop.it collected 2026-09-26 19:19:25 UTC 44,177 bytes, 1,311 lines download raw bytes

1// Timer per il debouncing dell'aggiornamento checkout
2let checkoutUpdateTimer = null;
3let isCheckoutUpdating = false;
4
5// Funzione di debouncing per l'aggiornamento del checkout
6function debounceCheckoutUpdate(delay = 800) {
7  if (checkoutUpdateTimer) {
8    clearTimeout(checkoutUpdateTimer);
9  }
10  
11  // Evita chiamate multiple sovrapposte
12  if (isCheckoutUpdating) {
13    return;
14  }
15  
16  checkoutUpdateTimer = setTimeout(function () {
17    isCheckoutUpdating = true;
18    jQuery(document.body).trigger("update_checkout", {
19      update_shipping_method: true,
20    });
21    
22    // Reset del flag dopo un breve delay e trigger auto-click degli updatePudo
23    setTimeout(function() {
24      isCheckoutUpdating = false;
25    }, 1000);
26  }, delay);
27}
28
29function ensureShippingContainer() {
30  let shippingContainer = document.querySelector("app-shipping-container ul");
31  if (shippingContainer) {
32    return shippingContainer;
33  }
34
35  const appShipping = document.querySelector("app-shipping-container");
36  if (!appShipping) {
37    return null;
38  }
39
40  shippingContainer = document.createElement("ul");
41  shippingContainer.id = "shipping_method";
42  shippingContainer.className =
43    "woocommerce-shipping-methods Shipping__Methods";
44  appShipping.appendChild(shippingContainer);
45  return shippingContainer;
46}
47
48document.addEventListener("DOMContentLoaded", function () {
49  // Aspetta che WooCommerce sia completamente caricato
50  setTimeout(function () {
51    syncBillingForm();
52    // Forza un aggiornamento iniziale per calcolare le spedizioni al primo load
53    if (!document.body.dataset.checkoutInitialUpdate) {
54      document.body.dataset.checkoutInitialUpdate = "1";
55      if (window.wc_checkout_form && document.querySelector("form.checkout")) {
56        debounceCheckoutUpdate(0);
57      }
58    }
59  }, 1000);
60
61  // Ri-inizializza dopo gli aggiornamenti del checkout
62  jQuery(document.body).on("updated_checkout", function (event, data) {
63    //console.log("Checkout updated, re-initializing sync");
64    //console.log("Updated checkout data:", data);
65
66    setTimeout(function () {
67      syncBillingForm();
68      handleShippingContainerUpdate();
69
70      // Debug: verifica se ci sono frammenti aggiornati
71      if (data && data.fragments) {
72        //TODO: fix shipping methods update
73       /*  console.log(
74          "Available fragments:",
75          Object.keys(data.fragments),
76          data.fragments
77        ); */
78        let shippingContainer = ensureShippingContainer();
79        //console.log("Shipping container:", shippingContainer);
80        if (shippingContainer) {
81          //empty and repopulate the shipping container
82          shippingContainer.innerHTML = "";
83          Object.keys(data.fragments).forEach(function (key) {
84            if (key.includes("available-shipping-methods")) {
85              let fragment = data.fragments[key];
86              shippingContainer.insertAdjacentHTML("beforeend", fragment);
87            } else if (key.includes("sumo-points")) {
88              // Prima rimuovi TUTTI gli elementi sumo-points esistenti con diversi selettori
89              let selectors = [
90                ".sumo_reward_points_checkout_apply_discount",
91                ".EcommerceRecap__Content.sumo_reward_points_checkout_apply_discount", 
92                ".EcommerceRecap__Content .sumo_reward_points_checkout_apply_discount",
93                "[class*='sumo_reward_points_checkout']",
94                "[class*='sumo-points']"
95              ];
96              
97              selectors.forEach(function(selector) {
98                let existingElements = document.querySelectorAll(selector);
99                existingElements.forEach(function (el) {
100                  console.log("Removing sumo element:", el);
101                  el.remove();
102                });
103              });
104              
105              // Inserisci il nuovo elemento dopo l'info element
106              let infoElement = document.querySelector(
107                ".EcommerceRecap__Content .woocommerce-info.sumo_available_points.rs_checkout_messages"
108              );
109              if (infoElement) {
110                infoElement.insertAdjacentHTML(
111                  "afterend",
112                  data.fragments[key]
113                );
114                console.log("Inserted new Sumo Points element after info element");
115              } else {
116                // Fallback: inserisci nell'EcommerceRecap__Content se l'info element non esiste
117                let recapContent = document.querySelector(".EcommerceRecap__Content");
118                if (recapContent) {
119                  recapContent.insertAdjacentHTML(
120                    "beforeend",
121                    data.fragments[key]
122                  );
123                  console.log("Inserted new Sumo Points element in recap content");
124                } else {
125                  console.warn(
126                    "Info element and EcommerceRecap__Content not found for Sumo Points"
127                  );
128                }
129              }
130            }
131          });
132        } else {
133          console.warn("Shipping container not found");
134        }
135      }
136    }, 250);
137  });
138
139  // Listener specifico per l'aggiornamento dei metodi di spedizione
140  jQuery(document.body).on("updated_shipping_method", function () {
141    handleShippingContainerUpdate();
142  }); 
143});
144
145function checkFermoPointSection() {
146  // Deve controllare se il valore della select del paese è IT
147  let countrySelect = document.querySelector("#shipping_country");
148  if (!countrySelect) {
149    console.error("Country select not found");
150    return;
151  }
152
153  let countryValue = countrySelect.value;
154  const pudoAlert = document.querySelectorAll(".wc_brt_div_alert");
155
156  if (countryValue !== "IT") {
157    pudoAlert.forEach((alert) => {
158      alert.style.display = "none";
159    });
160  }
161}
162 
163function syncBillingForm() {
164  let body = document.querySelector("body");
165  if (!body.classList.contains("woocommerce-checkout")) {
166    return;
167  }
168  let shippingFormWrapper = document.querySelector(
169    ".woocommerce-shipping-fields"
170  );
171  let billingFormWrapper = document.querySelector(
172    ".woocommerce-billing-fields"
173  );
174
175  //early return if no billing form found
176  if (!billingFormWrapper) {
177    console.error("No billing form found");
178    return;
179  }
180  if (!shippingFormWrapper) {
181    console.error("No shipping form found");
182    return;
183  }
184
185  // Rimuovi event listeners precedenti per evitare duplicati
186  shippingFormWrapper.removeAttribute("data-sync-initialized");
187
188  // Controlla se già inizializzato
189  if (shippingFormWrapper.getAttribute("data-sync-initialized") === "true") {
190    return;
191  }
192
193  //select all input, select, textarea fields in billing form
194  let shippingFields = shippingFormWrapper.querySelectorAll(
195    "input, select, textarea"
196  );
197  //loop through all fields in shipping form
198  shippingFields.forEach((shippingField) => {
199    // Funzione per sincronizzare il campo
200    function syncField() {
201      if (!isSyncActive()) {
202        return;
203      }
204
205      checkFermoPointSection();
206
207      if (shippingField.id === "shipping_phone" || shippingField.id === "shipping_email") {
208        autoClickUpdatePudo();
209      }
210      
211      //since the field name is like shipping_first_name, we need to extract the field name, and look for billing field with the same name
212      let fieldName = shippingField.getAttribute("name");
213      /* console.log(
214        "Syncing field:",
215        fieldName,
216        "with billing form",
217        `[name="${fieldName.replace("shipping_", "billing_")}"]`
218      ); */
219      let billingField = billingFormWrapper.querySelector(
220        `[name="${fieldName.replace("shipping_", "billing_")}"]`
221      );
222      /* console.log(
223        "Syncing field:",
224        fieldName,
225        "with billing field:",
226        billingField
227      ); */
228      
229      // SINCRONIZZAZIONE: Avviene SEMPRE per TUTTI i campi se esiste il campo billing corrispondente
230      if (billingField) {
231        // Evita di aggiornare se il valore è già uguale
232        if (billingField.value === shippingField.value) {
233          // Il valore è già sincronizzato, ma controlla comunque se serve aggiornare il checkout
234        } else {
235          // Sincronizza il valore dal campo shipping a quello billing
236          billingField.value = shippingField.value;
237
238          // Se il campo billing è anche un Select2, aggiorna anche quello
239          if (jQuery(billingField).hasClass("select2-hidden-accessible")) {
240            jQuery(billingField).val(shippingField.value).trigger("change");
241          }
242        }
243      }
244
245      // AGGIORNAMENTO CHECKOUT: Triggera solo per campi che influenzano la spedizione
246      const shippingRelevantFields = [
247        "shipping_country",
248        "shipping_state",
249        "shipping_postcode",
250        "shipping_city",
251      ];
252      if (shippingRelevantFields.includes(fieldName)) {
253        /* console.log(
254          "Triggering debounced checkout update for shipping field:",
255          fieldName
256        ); */
257
258        // Usa il debouncing per evitare troppe chiamate AJAX
259        debounceCheckoutUpdate();
260      }
261    }
262
263    // Event listeners per campi normali
264    // Usa solo eventi significativi per ridurre il numero di chiamate
265    const fieldType = shippingField.type || shippingField.tagName.toLowerCase();
266    let events = ["change"];
267    
268    // Per i campi di testo, aggiungi anche blur per catturare quando l'utente finisce di editare
269    if (fieldType === "text" || fieldType === "email" || fieldType === "tel" || shippingField.tagName.toLowerCase() === "textarea") {
270      events.push("blur");
271    }
272    
273    events.forEach((event) => {
274      shippingField.addEventListener(event, syncField);
275    });
276
277    // Event listener specifico per Select2 - usa jQuery direttamente
278    if (jQuery(shippingField).hasClass("select2-hidden-accessible")) {
279      /* console.log("Found Select2 field:", shippingField.getAttribute("name")); */
280
281      // Rimuovi event listeners precedenti
282      jQuery(shippingField).off(
283        "select2:select.syncBilling select2:unselect.syncBilling change.syncBilling"
284      );
285
286      // Aggiungi nuovi event listeners con namespace
287      jQuery(shippingField).on("select2:select.syncBilling", function (e) {
288        /* console.log("Select2 select event triggered for:", this.name); */
289        syncField();
290      });
291
292      jQuery(shippingField).on("select2:unselect.syncBilling", function (e) {
293        /* console.log("Select2 unselect event triggered for:", this.name); */
294        syncField();
295      });
296
297      // Fallback con change normale
298      jQuery(shippingField).on("change.syncBilling", function (e) {
299        /* console.log("Change event triggered for:", this.name); */
300        syncField();
301      });
302    }
303  });
304
305  // Marca come inizializzato
306  shippingFormWrapper.setAttribute("data-sync-initialized", "true");
307}
308
309// Gestione specifica per il componente app-shipping-container
310function handleShippingContainerUpdate() {
311  //console.log("Handling shipping container update");
312
313  // Assicurati che i nuovi elementi shipping siano gestiti correttamente
314  const shippingContainer = document.querySelector("app-shipping-container");
315  if (shippingContainer) {
316    //console.log("Shipping container found and updated");
317
318    // Forza un refresh della sezione shipping se necessario
319    // Cerca elementi con classi WooCommerce standard che potrebbero essere stati aggiornati
320    const shippingMethods = shippingContainer.querySelectorAll(
321      ".woocommerce-shipping-methods"
322    );
323    //console.log("Found shipping methods containers:", shippingMethods.length);
324
325    // Se non ci sono metodi di spedizione visibili, prova a forzare un altro aggiornamento
326    if (shippingMethods.length === 0) {
327      //console.log("No shipping methods found, forcing another update");
328      setTimeout(function () {
329        jQuery(document.body).trigger("wc_update_cart");
330      }, 200);
331    }
332  } else {
333    //console.log("Shipping container not found");
334
335    // Se il container non esiste, potrebbe essere stato rimosso durante l'aggiornamento
336    // Prova a forzare un refresh completo
337    setTimeout(function () {
338      jQuery(document.body).trigger("wc_update_cart");
339    }, 200);
340  }
341}
342
343function isSyncActive() {
344  let radio = document.querySelector("#shipping-invoice_yes, #shipping-invoice_si");
345  if (radio && radio.checked) {
346    return true;
347  }
348  return false;
349}
350
351// Funzione per cliccare automaticamente tutti gli elementi .updatePudo
352function autoClickUpdatePudo() {
353  const updatePudoElements = document.querySelectorAll('.updatePudo');
354  
355  if (updatePudoElements.length > 0) {
356    //console.log(`Trovati ${updatePudoElements.length} elementi .updatePudo, esecuzione click automatico...`);
357    
358    updatePudoElements.forEach((element, index) => {
359      // Aggiungi un piccolo delay tra i click per evitare problemi di concorrenza
360      setTimeout(() => {
361        if (element && typeof element.click === 'function') {
362          element.click();
363          //console.log(`Clicked .updatePudo elemento ${index + 1}/${updatePudoElements.length}`);
364        }
365      }, index * 50); // 50ms di delay tra ogni click
366    });
367  } else {
368    // Log solo se siamo in modalità debug (rimuovi in produzione se vuoi)
369    // console.log('Nessun elemento .updatePudo trovato per l\'auto-click');
370  }
371}
372
373/* global wc_checkout_params */
374jQuery(function ($) {
375  // wc_checkout_params is required to continue, ensure the object exists
376  if (typeof wc_checkout_params === "undefined") {
377    return false;
378  }
379
380  $.blockUI.defaults.overlayCSS.cursor = "default";
381
382  var wc_checkout_form = {
383    updateTimer: false,
384    dirtyInput: false,
385    selectedPaymentMethod: false,
386    xhr: false,
387    $order_review: $("#order_review"),
388    $checkout_form: $("form.checkout"),
389    init: function () {
390      $(document.body).on("update_checkout", this.update_checkout);
391      $(document.body).on("init_checkout", this.init_checkout);
392
393      // Payment methods
394      this.$checkout_form.on(
395        "click",
396        'input[name="payment_method"]',
397        this.payment_method_selected
398      );
399
400      if ($(document.body).hasClass("woocommerce-order-pay")) {
401        this.$order_review.on(
402          "click",
403          'input[name="payment_method"]',
404          this.payment_method_selected
405        );
406        this.$order_review.on("submit", this.submitOrder);
407        this.$order_review.attr("novalidate", "novalidate");
408      }
409
410      // Prevent HTML5 validation which can conflict.
411      this.$checkout_form.attr("novalidate", "novalidate");
412
413      // Form submission
414      this.$checkout_form.on("submit", this.submit);
415
416      // Inline validation
417      this.$checkout_form.on(
418        "input validate change focusout",
419        ".input-text, select, input:checkbox",
420        this.validate_field
421      );
422
423      // Manual trigger
424      this.$checkout_form.on("update", this.trigger_update_checkout);
425
426      // Inputs/selects which update totals
427      this.$checkout_form.on(
428        "change",
429        'select.shipping_method, input[name^="shipping_method"], #ship-to-different-address input, .update_totals_on_change select, .update_totals_on_change input[type="radio"], .update_totals_on_change input[type="checkbox"]',
430        this.trigger_update_checkout
431      );
432      this.$checkout_form.on(
433        "change",
434        ".address-field select",
435        this.input_changed
436      );
437      this.$checkout_form.on(
438        "change",
439        ".address-field input.input-text, .update_totals_on_change input.input-text",
440        this.maybe_input_changed
441      );
442      this.$checkout_form.on(
443        "keydown",
444        ".address-field input.input-text, .update_totals_on_change input.input-text",
445        this.queue_update_checkout
446      );
447
448      // Address fields
449      this.$checkout_form.on(
450        "change",
451        "#ship-to-different-address input",
452        this.ship_to_different_address
453      );
454
455      // Trigger events
456      this.$checkout_form
457        .find("#ship-to-different-address input")
458        .trigger("change");
459      this.init_payment_methods();
460
461      // Update on page load
462      if (wc_checkout_params.is_checkout === "1") {
463        $(document.body).trigger("init_checkout");
464      }
465
466      // Make sure the create account checkbox is visible and functional
467      if (wc_checkout_params.option_guest_checkout === "yes") {
468        $("input#createaccount")
469          .on("change", this.toggle_create_account)
470          .trigger("change");
471        // Make sure the checkbox is visible
472        $("input#createaccount").closest(".form-row").show();
473      }
474    },
475    init_payment_methods: function () {
476      var $payment_methods = $(".woocommerce-checkout").find(
477        'input[name="payment_method"]'
478      );
479
480      // If there is one method, we can hide the radio input
481      if (1 === $payment_methods.length) {
482        $payment_methods.eq(0).hide();
483      }
484
485      // If there was a previously selected method, check that one.
486      if (wc_checkout_form.selectedPaymentMethod) {
487        $("#" + wc_checkout_form.selectedPaymentMethod).prop("checked", true);
488      }
489
490      // If there are none selected, select the first.
491      if (0 === $payment_methods.filter(":checked").length) {
492        $payment_methods.eq(0).prop("checked", true);
493      }
494
495      // Get name of new selected method.
496      var checkedPaymentMethod = $payment_methods
497        .filter(":checked")
498        .eq(0)
499        .prop("id");
500
501      if ($payment_methods.length > 1) {
502        // Hide open descriptions.
503        $('div.payment_box:not(".' + checkedPaymentMethod + '")')
504          .filter(":visible")
505          .slideUp(0);
506      }
507
508      // Trigger click event for selected method
509      $payment_methods.filter(":checked").eq(0).trigger("click");
510    },
511    get_payment_method: function () {
512      return wc_checkout_form.$checkout_form
513        .find('input[name="payment_method"]:checked')
514        .val();
515    },
516    payment_method_selected: function (e) {
517      e.stopPropagation();
518
519      if ($(".payment_methods input.input-radio").length > 1) {
520        var target_payment_box = $("div.payment_box." + $(this).attr("ID")),
521          is_checked = $(this).is(":checked");
522
523        if (is_checked && !target_payment_box.is(":visible")) {
524          $("div.payment_box").filter(":visible").slideUp(230);
525
526          if (is_checked) {
527            target_payment_box.slideDown(230);
528          }
529        }
530      } else {
531        $("div.payment_box").show();
532      }
533
534      if ($(this).data("order_button_text")) {
535        $("#place_order").text($(this).data("order_button_text"));
536      } else {
537        $("#place_order").text($("#place_order").data("value"));
538      }
539
540      var selectedPaymentMethod = $(
541        '.woocommerce-checkout input[name="payment_method"]:checked'
542      ).attr("id");
543
544      if (selectedPaymentMethod !== wc_checkout_form.selectedPaymentMethod) {
545        $(document.body).trigger("payment_method_selected");
546      }
547
548      wc_checkout_form.selectedPaymentMethod = selectedPaymentMethod;
549    },
550    toggle_create_account: function () {
551      $("div.create-account").hide();
552
553      if ($(this).is(":checked")) {
554        // Ensure password is not pre-populated.
555        $("#account_password").val("").trigger("change");
556        $("div.create-account").slideDown();
557      }
558    },
559    init_checkout: function () {
560      $(document.body).trigger("update_checkout");
561    },
562    maybe_input_changed: function (e) {
563      if (wc_checkout_form.dirtyInput) {
564        wc_checkout_form.input_changed(e);
565      }
566    },
567    input_changed: function (e) {
568      wc_checkout_form.dirtyInput = e.target;
569      wc_checkout_form.maybe_update_checkout();
570    },
571    queue_update_checkout: function (e) {
572      var code = e.keyCode || e.which || 0;
573
574      if (code === 9) {
575        return true;
576      }
577
578      wc_checkout_form.dirtyInput = this;
579      wc_checkout_form.reset_update_checkout_timer();
580      wc_checkout_form.updateTimer = setTimeout(
581        wc_checkout_form.maybe_update_checkout,
582        "1000"
583      );
584    },
585    trigger_update_checkout: function (event) {
586      wc_checkout_form.reset_update_checkout_timer();
587      wc_checkout_form.dirtyInput = false;
588      $(document.body).trigger("update_checkout", {
589        current_target: event ? event.currentTarget : null,
590      });
591    },
592    maybe_update_checkout: function () {
593      var update_totals = true;
594
595      if ($(wc_checkout_form.dirtyInput).length) {
596        var $required_inputs = $(wc_checkout_form.dirtyInput)
597          .closest("div")
598          .find(".address-field.validate-required");
599
600        if ($required_inputs.length) {
601          $required_inputs.each(function () {
602            if ($(this).find("input.input-text").val() === "") {
603              update_totals = false;
604            }
605          });
606        }
607      }
608      if (update_totals) {
609        wc_checkout_form.trigger_update_checkout();
610      }
611    },
612    ship_to_different_address: function () {
613      $("div.shipping_address").hide();
614      if ($(this).is(":checked")) {
615        $("div.shipping_address").slideDown();
616      }
617    },
618    reset_update_checkout_timer: function () {
619      clearTimeout(wc_checkout_form.updateTimer);
620    },
621    is_valid_json: function (raw_json) {
622      try {
623        var json = JSON.parse(raw_json);
624
625        return json && "object" === typeof json;
626      } catch (e) {
627        return false;
628      }
629    },
630    validate_field: function (e) {
631      var $this = $(this),
632        $parent = $this.closest(".form-row"),
633        validated = true,
634        validate_required = $parent.is(".validate-required"),
635        validate_email = $parent.is(".validate-email"),
636        validate_cf = $parent.is(".validate-cf"),
637        validate_phone = $parent.is(".validate-phone"),
638        pattern = "",
639        event_type = e.type;
640
641      if ("input" === event_type) {
642        $parent.removeClass(
643          "woocommerce-invalid woocommerce-invalid-required-field woocommerce-invalid-email woocommerce-invalid-cf woocommerce-invalid-phone woocommerce-validated"
644        );
645      }
646
647      if ("validate" === event_type || "change" === event_type) {
648        if (validate_required) {
649          if ("checkbox" === $this.attr("type") && !$this.is(":checked")) {
650            $parent
651              .removeClass("woocommerce-validated")
652              .addClass(
653                "woocommerce-invalid woocommerce-invalid-required-field"
654              );
655            validated = false;
656          } else if ($this.val() === "") {
657            $parent
658              .removeClass("woocommerce-validated")
659              .addClass(
660                "woocommerce-invalid woocommerce-invalid-required-field"
661              );
662            validated = false;
663          }
664        }
665
666        if (validate_email) {
667          if ($this.val()) {
668            /* https://stackoverflow.com/questions/2855865/jquery-validate-e-mail-address-regex */
669            pattern = new RegExp(
670              /^([a-z\d!#$%&'*+\-\/=?^_`{|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+(\.[a-z\d!#$%&'*+\-\/=?^_`{|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)*|"((([ \t]*\r\n)?[ \t]+)?([\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|\\[\x01-\x09\x0b\x0c\x0d-\u7f\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))*(([ \t]*\r\n)?[ \t]+)?")@(([a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|[a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF][a-z\d\-._~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]*[a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])\.)+([a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|[a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF][a-z\d\-._~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]*[a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])\.?$/i
671            ); // eslint-disable-line max-len
672
673            if (!pattern.test($this.val())) {
674              $parent
675                .removeClass("woocommerce-validated")
676                .addClass("woocommerce-invalid woocommerce-invalid-email");
677              validated = false;
678            }
679          }
680        }
681
682        if (validate_cf) {
683            // Check if the field is empty
684            if ($this.val() != "") {
685              pattern = new RegExp(/^[A-Za-z]{6}[0-9]{2}[A-Za-z]{1}[0-9]{2}[A-Za-z]{1}[0-9]{3}[A-Za-z]{1}$/);  
686              if (!pattern.test($this.val())) {
687                $parent
688                  .removeClass("woocommerce-validated")
689                  .addClass("woocommerce-invalid woocommerce-invalid-cf");
690                validated = false;
691              }
692          }
693        }
694
695        if (validate_phone) {
696          pattern = new RegExp(/[\s\#0-9_\-\+\/\(\)\.]/g);
697
698          if (0 < $this.val().replace(pattern, "").length) {
699            $parent
700              .removeClass("woocommerce-validated")
701              .addClass("woocommerce-invalid woocommerce-invalid-phone");
702            validated = false;
703          }
704        }
705
706        if (validated) {
707          $parent
708            .removeClass(
709              "woocommerce-invalid woocommerce-invalid-required-field woocommerce-invalid-email woocommerce-invalid-phone woocommerce-invalid-cf"
710            )
711            .addClass("woocommerce-validated");
712        }
713      }
714    },
715    update_checkout: function (event, args) {
716      // Small timeout to prevent multiple requests when several fields update at the same time
717      wc_checkout_form.reset_update_checkout_timer();
718      wc_checkout_form.updateTimer = setTimeout(
719        wc_checkout_form.update_checkout_action,
720        "5",
721        args
722      );
723    },
724    update_checkout_action: function (args) {
725      if (wc_checkout_form.xhr) {
726        wc_checkout_form.xhr.abort();
727      }
728
729      if ($("form.checkout").length === 0) {
730        return;
731      }
732
733      args =
734        typeof args !== "undefined"
735          ? args
736          : {
737              update_shipping_method: true,
738            };
739
740      var country = $("#billing_country").val(),
741        state = $("#billing_state").val(),
742        postcode = $(":input#billing_postcode").val(),
743        city = $("#billing_city").val(),
744        address = $(":input#billing_address_1").val(),
745        address_2 = $(":input#billing_address_2").val(),
746        s_country = country,
747        s_state = state,
748        s_postcode = postcode,
749        s_city = city,
750        s_address = address,
751        s_address_2 = address_2,
752        $required_inputs = $(wc_checkout_form.$checkout_form).find(
753          ".address-field.validate-required:visible"
754        ),
755        has_full_address = true;
756
757      if ($required_inputs.length) {
758        $required_inputs.each(function () {
759          if ($(this).find(":input").val() === "") {
760            has_full_address = false;
761          }
762        });
763      }
764
765      if ($("#ship-to-different-address").find("input").is(":checked")) {
766        s_country = $("#shipping_country").val();
767        s_state = $("#shipping_state").val();
768        s_postcode = $(":input#shipping_postcode").val();
769        s_city = $("#shipping_city").val();
770        s_address = $(":input#shipping_address_1").val();
771        s_address_2 = $(":input#shipping_address_2").val();
772      }
773
774      var data = {
775        security: wc_checkout_params.update_order_review_nonce,
776        payment_method: wc_checkout_form.get_payment_method(),
777        country: country,
778        state: state,
779        postcode: postcode,
780        city: city,
781        address: address,
782        address_2: address_2,
783        s_country: s_country,
784        s_state: s_state,
785        s_postcode: s_postcode,
786        s_city: s_city,
787        s_address: s_address,
788        s_address_2: s_address_2,
789        has_full_address: has_full_address,
790        post_data: $("form.checkout").serialize(),
791      };
792
793      if (false !== args.update_shipping_method) {
794        var shipping_methods = {};
795
796        // eslint-disable-next-line max-len
797        $(
798          'select.shipping_method, input[name^="shipping_method"][type="radio"]:checked, input[name^="shipping_method"][type="hidden"]'
799        ).each(function () {
800          shipping_methods[$(this).data("index")] = $(this).val();
801        });
802
803        data.shipping_method = shipping_methods;
804      }
805
806      $(
807        ".woocommerce-checkout-payment, .woocommerce-checkout-review-order-table"
808      ).block({
809        message: null,
810        overlayCSS: {
811          background: "#fff",
812          opacity: 0.6,
813        },
814      });
815
816      wc_checkout_form.xhr = $.ajax({
817        type: "POST",
818        url: wc_checkout_params.wc_ajax_url
819          .toString()
820          .replace("%%endpoint%%", "update_order_review"),
821        data: data,
822        success: function (data) {
823          // Reload the page if requested
824          if (data && true === data.reload) {
825            window.location.reload();
826            return;
827          }
828
829          // Remove any notices added previously
830          $(".woocommerce-NoticeGroup-updateOrderReview").remove();
831
832          var termsCheckBoxChecked = $("#terms").prop("checked");
833
834          // Save payment details to a temporary object
835          var paymentDetails = {};
836          $(".payment_box :input").each(function () {
837            var ID = $(this).attr("id");
838
839            if (ID) {
840              if (
841                $.inArray($(this).attr("type"), ["checkbox", "radio"]) !== -1
842              ) {
843                paymentDetails[ID] = $(this).prop("checked");
844              } else {
845                paymentDetails[ID] = $(this).val();
846              }
847            }
848          });
849
850          // Always update the fragments
851          if (data && data.fragments) {
852            $.each(data.fragments, function (key, value) {
853              if (
854                !wc_checkout_form.fragments ||
855                wc_checkout_form.fragments[key] !== value
856              ) {
857                $(key).replaceWith(value);
858              }
859              $(key).unblock();
860            });
861            wc_checkout_form.fragments = data.fragments;
862          }
863
864          // Recheck the terms and conditions box, if needed
865          if (termsCheckBoxChecked) {
866            $("#terms").prop("checked", true);
867          }
868
869          // Fill in the payment details if possible without overwriting data
870          if (!$.isEmptyObject(paymentDetails)) {
871            $(".payment_box :input").each(function () {
872              var ID = $(this).attr("id");
873              if (ID) {
874                if (
875                  $.inArray($(this).attr("type"), ["checkbox", "radio"]) !== -1
876                ) {
877                  $(this).prop("checked", paymentDetails[ID]).trigger("change");
878                } else if ($.inArray($(this).attr("type"), ["select"]) !== -1) {
879                  $(this).val(paymentDetails[ID]).trigger("change");
880                } else if (
881                  null !== $(this).val() &&
882                  0 === $(this).val().length
883                ) {
884                  $(this).val(paymentDetails[ID]).trigger("change");
885                }
886              }
887            });
888          }
889
890          // Check for error
891          if (data && "failure" === data.result) {
892            var $form = $("form.checkout");
893
894            // Remove notices from all sources
895            $(".woocommerce-error, .woocommerce-message").remove();
896
897            // Add new errors returned by this event
898            if (data.messages) {
899              $form.prepend(
900                '<div class="woocommerce-NoticeGroup woocommerce-NoticeGroup-updateOrderReview">' +
901                  data.messages +
902                  "</div>"
903              ); // eslint-disable-line max-len
904            } else {
905              $form.prepend(data);
906            }
907
908            // Lose focus for all fields
909            $form
910              .find(".input-text, select, input:checkbox")
911              .trigger("validate")
912              .trigger("blur");
913
914            wc_checkout_form.scroll_to_notices();
915          }
916
917          // Re-init methods
918          wc_checkout_form.init_payment_methods();
919
920          // Fire updated_checkout event.
921          $(document.body).trigger("updated_checkout", [data]);
922        },
923      });
924    },
925    submit: function () {
926      wc_checkout_form.reset_update_checkout_timer();
927      var $form = $(this);
928
929      if ($form.is(".processing")) {
930        return false;
931      }
932
933      // Trigger a handler to let gateways manipulate the checkout if needed
934      // eslint-disable-next-line max-len
935      if (
936        $form.triggerHandler("checkout_place_order") !== false &&
937        $form.triggerHandler(
938          "checkout_place_order_" + wc_checkout_form.get_payment_method()
939        ) !== false
940      ) {
941        $form.addClass("processing");
942
943        wc_checkout_form.blockOnSubmit($form);
944
945        // Attach event to block reloading the page when the form has been submitted
946        wc_checkout_form.attachUnloadEventsOnSubmit();
947
948        // ajaxSetup is global, but we use it to ensure JSON is valid once returned.
949        $.ajaxSetup({
950          dataFilter: function (raw_response, dataType) {
951            // We only want to work with JSON
952            if ("json" !== dataType) {
953              return raw_response;
954            }
955
956            if (wc_checkout_form.is_valid_json(raw_response)) {
957              return raw_response;
958            } else {
959              // Attempt to fix the malformed JSON
960              var maybe_valid_json = raw_response.match(/{"result.*}/);
961
962              if (null === maybe_valid_json) {
963                //console.log("Unable to fix malformed JSON");
964              } else if (wc_checkout_form.is_valid_json(maybe_valid_json[0])) {
965                //console.log("Fixed malformed JSON. Original:");
966                //console.log(raw_response);
967                raw_response = maybe_valid_json[0];
968              } else {
969                //console.log("Unable to fix malformed JSON");
970              }
971            }
972
973            return raw_response;
974          },
975        });
976
977        $.ajax({
978          type: "POST",
979          url: wc_checkout_params.checkout_url,
980          data: $form.serialize(),
981          dataType: "json",
982          success: function (result) {
983            wc_checkout_form.detachUnloadEventsOnSubmit();
984
985            try {
986              if (
987                "success" === result.result &&
988                $form.triggerHandler("checkout_place_order_success", result) !==
989                  false
990              ) {
991                if (
992                  -1 === result.redirect.indexOf("https://") ||
993                  -1 === result.redirect.indexOf("http://")
994                ) {
995                  window.location = result.redirect;
996                } else {
997                  window.location = decodeURI(result.redirect);
998                }
999              } else if ("failure" === result.result) {
1000                throw "Result failure";
1001              } else {
1002                throw "Invalid response";
1003              }
1004            } catch (err) {
1005              // Reload page
1006              if (true === result.reload) {
1007                window.location.reload();
1008                return;
1009              }
1010
1011              // Trigger update in case we need a fresh nonce
1012              if (true === result.refresh) {
1013                $(document.body).trigger("update_checkout");
1014              }
1015
1016              // Add new errors
1017              if (result.messages) {
1018                wc_checkout_form.submit_error(result.messages);
1019              } else {
1020                wc_checkout_form.submit_error(
1021                  '<div class="woocommerce-error">' +
1022                    wc_checkout_params.i18n_checkout_error +
1023                    "</div>"
1024                ); // eslint-disable-line max-len
1025              }
1026            }
1027          },
1028          error: function (jqXHR, textStatus, errorThrown) {
1029            wc_checkout_form.detachUnloadEventsOnSubmit();
1030            wc_checkout_form.submit_error(
1031              '<div class="woocommerce-error">' + errorThrown + "</div>"
1032            );
1033          },
1034        });
1035      }
1036
1037      return false;
1038    },
1039    scroll_to_notices: function () {
1040      const headerMain = document.querySelector('.Header--Main');
1041      var scrollElement = $(
1042        ".woocommerce-NoticeGroup-updateOrderReview, .woocommerce-NoticeGroup-checkout"
1043      );
1044
1045      if (!scrollElement.length) {
1046        scrollElement = $("form.checkout");
1047      }
1048
1049      // Calcola l'altezza dell'headerMain se presente
1050      let headerOffset = 0;
1051      if (headerMain) {
1052        headerOffset = headerMain.offsetHeight || 0;
1053      }
1054
1055      // Scroll con offset per evitare che l'header copra l'elemento
1056      $("html, body").animate(
1057        {
1058          scrollTop: scrollElement.offset().top - headerOffset - 20,
1059        },
1060        500
1061      );
1062    },
1063    attach_listener_for_add_new_card_option: function () {
1064      // This ensures the checkout is re-rendered when a new payment method is added.
1065      if (wc_checkout_form.is_form_ready) {
1066        $(document.body).on("payment_method_selected", function () {
1067          $(document.body).trigger("update_checkout");
1068        });
1069        wc_checkout_form.is_form_ready = false;
1070      }
1071    },
1072    attach_listener_for_checkout_credentials_input: function () {
1073      // Listen for changes to the checkout credentials (e.g. username and password)
1074      // and make sure the user is warned if they're already logged in.
1075      if (wc_checkout_form.is_logged_in) {
1076        const $username_field = $("#username");
1077        const $password_field = $("#password");
1078        const on_input_change = function () {
1079          if ($username_field.length && $username_field.val()) {
1080            $(".woocommerce-checkout").on("checkout_place_order", function () {
1081              return confirm(
1082                wc_checkout_params.i18n_checkout_logged_in_message
1083              );
1084            });
1085          }
1086        };
1087        $username_field.on("change", on_input_change);
1088        $password_field.on("change", on_input_change);
1089      }
1090    },
1091    submit_error: function (error_message) {
1092      $(
1093        ".woocommerce-NoticeGroup-checkout, .woocommerce-error, .woocommerce-message"
1094      ).remove();
1095      wc_checkout_form.$checkout_form.prepend(
1096        '<div class="woocommerce-NoticeGroup woocommerce-NoticeGroup-checkout">' +
1097          error_message +
1098          "</div>"
1099      ); // eslint-disable-line max-len
1100      wc_checkout_form.$checkout_form.removeClass("processing").unblock();
1101      wc_checkout_form.$checkout_form
1102        .find(".input-text, select, input:checkbox")
1103        .trigger("validate")
1104        .trigger("blur");
1105      wc_checkout_form.scroll_to_notices();
1106      $(document.body).trigger("checkout_error", [error_message]);
1107    },
1108    blockOnSubmit: function ($form) {
1109      var form_data = $form.data();
1110
1111      if (1 !== form_data["blockUI.isBlocked"]) {
1112        $form.block({
1113          message: null,
1114          overlayCSS: {
1115            background: "#fff",
1116            opacity: 0.6,
1117          },
1118        });
1119      }
1120    },
1121    attachUnloadEventsOnSubmit: function () {
1122      $(window).on("beforeunload", this.handleUnloadEvent);
1123    },
1124    detachUnloadEventsOnSubmit: function () {
1125      $(window).off("beforeunload", this.handleUnloadEvent);
1126    },
1127    handleUnloadEvent: function (e) {
1128      // Modern browsers have their own standard generic messages that they will display.
1129      // Confirm, alert, prompt or custom message are not allowed during the unload event
1130      // Browsers will display their own standard messages
1131
1132      // Check if the browser is Internet Explorer
1133      if (
1134        navigator.userAgent.indexOf("MSIE") !== -1 ||
1135        !!document.documentMode
1136      ) {
1137        // IE handles unload events differently than modern browsers
1138        e.preventDefault();
1139        return undefined;
1140      }
1141
1142      return true;
1143    },
1144  };
1145
1146  var wc_checkout_coupons = {
1147    init: function () {
1148      $(document.body).on("click", "a.showcoupon", this.show_coupon_form);
1149      $(document.body).on(
1150        "click",
1151        ".woocommerce-remove-coupon",
1152        this.remove_coupon
1153      );
1154      $("form.checkout_coupon").hide().on("submit", this.submit);
1155    },
1156    show_coupon_form: function () {
1157      $(".checkout_coupon").slideToggle(400, function () {
1158        $(".checkout_coupon").find(":input:eq(0)").trigger("focus");
1159      });
1160      return false;
1161    },
1162    submit: function () {
1163      var $form = $(this);
1164
1165      if ($form.is(".processing")) {
1166        return false;
1167      }
1168
1169      $form.addClass("processing").block({
1170        message: null,
1171        overlayCSS: {
1172          background: "#fff",
1173          opacity: 0.6,
1174        },
1175      });
1176
1177      var data = {
1178        security: wc_checkout_params.apply_coupon_nonce,
1179        coupon_code: $form.find('input[name="coupon_code"]').val(),
1180      };
1181
1182      $.ajax({
1183        type: "POST",
1184        url: wc_checkout_params.wc_ajax_url
1185          .toString()
1186          .replace("%%endpoint%%", "apply_coupon"),
1187        data: data,
1188        success: function (code) {
1189          $(".woocommerce-error, .woocommerce-message").remove();
1190          $form.removeClass("processing").unblock();
1191
1192          if (code) {
1193            $form.before(code);
1194            $form.slideUp();
1195
1196            $(document.body).trigger("applied_coupon_in_checkout", [
1197              data.coupon_code,
1198            ]);
1199            $(document.body).trigger("update_checkout", {
1200              update_shipping_method: false,
1201            });
1202          }
1203        },
1204        dataType: "html",
1205      });
1206
1207      return false;
1208    },
1209    remove_coupon: function (e) {
1210      e.preventDefault();
1211
1212      var container = $(this).parents(".woocommerce-checkout-review-order"),
1213        coupon = $(this).data("coupon");
1214
1215      container.addClass("processing").block({
1216        message: null,
1217        overlayCSS: {
1218          background: "#fff",
1219          opacity: 0.6,
1220        },
1221      });
1222
1223      var data = {
1224        security: wc_checkout_params.remove_coupon_nonce,
1225        coupon: coupon,
1226      };
1227
1228      $.ajax({
1229        type: "POST",
1230        url: wc_checkout_params.wc_ajax_url
1231          .toString()
1232          .replace("%%endpoint%%", "remove_coupon"),
1233        data: data,
1234        success: function (code) {
1235          $(".woocommerce-error, .woocommerce-message").remove();
1236          container.removeClass("processing").unblock();
1237
1238          if (code) {
1239            $("form.woocommerce-checkout").before(code);
1240
1241            $(document.body).trigger("removed_coupon_in_checkout", [
1242              data.coupon,
1243            ]);
1244            $(document.body).trigger("update_checkout", {
1245              update_shipping_method: false,
1246            });
1247
1248            // Remove coupon code from coupon field
1249            $("form.checkout_coupon").find('input[name="coupon_code"]').val("");
1250          }
1251        },
1252        error: function (jqXHR) {
1253          if (wc_checkout_params.debug_mode) {
1254            /* jshint devel: true */
1255            //console.log(jqXHR.responseText);
1256          }
1257        },
1258        dataType: "html",
1259      });
1260    },
1261  };
1262
1263  var wc_checkout_login_form = {
1264    init: function () {
1265      $(document.body).on("click", "a.showlogin", this.show_login_form);
1266    },
1267    show_login_form: function () {
1268      $("form.login, form.woocommerce-form--login").slideToggle();
1269      return false;
1270    },
1271  };
1272
1273  var wc_terms_toggle = {
1274    init: function () {
1275      $(document.body).on(
1276        "click",
1277        "a.woocommerce-terms-and-conditions-link",
1278        this.toggle_terms
1279      );
1280    },
1281
1282    toggle_terms: function () {
1283      if ($(".woocommerce-terms-and-conditions").length) {
1284        $(".woocommerce-terms-and-conditions").slideToggle(function () {
1285          var link_toggle = $(".woocommerce-terms-and-conditions-link");
1286
1287          if ($(".woocommerce-terms-and-conditions").is(":visible")) {
1288            link_toggle.addClass("woocommerce-terms-and-conditions-link--open");
1289            link_toggle.removeClass(
1290              "woocommerce-terms-and-conditions-link--closed"
1291            );
1292          } else {
1293            link_toggle.removeClass(
1294              "woocommerce-terms-and-conditions-link--open"
1295            );
1296            link_toggle.addClass(
1297              "woocommerce-terms-and-conditions-link--closed"
1298            );
1299          }
1300        });
1301
1302        return false;
1303      }
1304    },
1305  };
1306
1307  wc_checkout_form.init();
1308  wc_checkout_coupons.init();
1309  wc_checkout_login_form.init();
1310  wc_terms_toggle.init();
1311});

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.