1jQuery(document).ready(function ($) { 2 3 /** 4 * Set a browser cookie with a name, value, and expiry in days. 5 * 6 * @param {string} name - Cookie key name 7 * @param {string} value - Cookie value to store 8 * @param {number} days - Number of days until cookie expires 9 */ 10 function setCookie(name, value, days) { 11 var expires = ""; 12 13 if (days) { 14 var date = new Date(); 15 date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000); 16 expires = "; expires=" + date.toUTCString(); 17 } 18 19 document.cookie = name + "=" + encodeURIComponent(value) + expires + "; path=/"; 20 } 21 22 /** 23 * Read a cookie value by name from the browser. 24 * 25 * @param {string} name - Cookie key to look up 26 * @returns {string} - Decoded cookie value or empty string if not found 27 */ 28 function getCookie(name) { 29 var match = document.cookie.match(new RegExp("(^| )" + name + "=([^;]+)")); 30 return match ? decodeURIComponent(match[2]) : ""; 31 } 32 33 /** 34 * Validate the donation form fields scoped to the clicked button's container. 35 * Uses the button element to find its parent wrapper so each popup is isolated. 36 * 37 * @param {jQuery} $container - jQuery object of the form wrapper containing the fields 38 * @returns {boolean} 39 */ 40 function validateDonationForm($container) { 41 var isValid = true; 42 43 // Read values scoped directly inside the clicked button container 44 var name = $.trim($container.find("#donation_name").val()); 45 var email = $.trim($container.find("#donation_email").val()); 46 47 // Clear previous error states before revalidating 48 $container.find("#donation_name").removeClass("donation-input-error"); 49 $container.find("#donation_email").removeClass("donation-input-error"); 50 $container.find("#donation_name_error").text(""); 51 $container.find("#donation_email_error").text(""); 52 53 // Validate name field is not empty 54 if (!name) { 55 $container.find("#donation_name").addClass("donation-input-error"); 56 $container.find("#donation_name_error").text("Please enter your name."); 57 isValid = false; 58 } 59 60 // Validate email field is not empty and has valid format 61 var emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; 62 63 if (!email) { 64 $container.find("#donation_email").addClass("donation-input-error"); 65 $container.find("#donation_email_error").text("Please enter your email address."); 66 isValid = false; 67 } else if (!emailPattern.test(email)) { 68 $container.find("#donation_email").addClass("donation-input-error"); 69 $container.find("#donation_email_error").text("Please enter a valid email address."); 70 isValid = false; 71 } 72 73 return isValid; 74 } 75 76 /** 77 * Store user name, email and all available UTM cookies before redirect. 78 * 79 * @param {string} userName - User full name from the form input 80 * @param {string} userEmail - User email from the form input 81 */ 82 function storeDonationCookies(userName, userEmail) { 83 84 setCookie("user_name", userName, 30); 85 setCookie("user_email", userEmail, 30); 86 87 // Read UTM values from existing cookies and re-store with 30 day expiry 88 var utmCampaign = getCookie("utm_campaign"); 89 var utmMedium = getCookie("utm_medium"); 90 var utmSource = getCookie("utm_source"); 91 92 if (utmCampaign) { 93 setCookie("utm_campaign", utmCampaign, 30); 94 } 95 96 if (utmMedium) { 97 setCookie("utm_medium", utmMedium, 30); 98 } 99 100 if (utmSource) { 101 setCookie("utm_source", utmSource, 30); 102 } 103 } 104 105 /** 106 * Handle Stripe form SUBMIT button click. 107 * Scopes all field reads and validations to the button's own popup container. 108 */ 109 $(document).on("click", "#donation_submit_btn_stripe", function () { 110 111 // Scope to this button's own popup wrapper to avoid conflict with PayPal popup 112 var $container = $(this).closest("#donation-form-wrapper"); 113 114 if (!validateDonationForm($container)) { 115 return; 116 } 117 118 var stripeLink = (donationConfig && donationConfig.stripeLink) ? donationConfig.stripeLink : ""; 119 120 // Show error if Stripe link is not configured in the donate page meta fields 121 if (!stripeLink) { 122 $container.find("#donation-form-message") 123 .removeClass("donation-success") 124 .addClass("donation-error") 125 .text("Stripe payment link is not configured. Please contact the site administrator.") 126 .show(); 127 return; 128 } 129 130 var userName = $.trim($container.find("#donation_name").val()); 131 var userEmail = $.trim($container.find("#donation_email").val()); 132 133 // Disable button to prevent duplicate submissions 134 $(this).prop("disabled", true).text("Please wait..."); 135 136 // Store all cookies before redirect 137 storeDonationCookies(userName, userEmail); 138 139 $container.find("#donation-form-message") 140 .removeClass("donation-error") 141 .addClass("donation-success")
142 .text("Thank you! Redirecting to Stripe...") 143 .show(); 144 145 // Redirect to Stripe payment page after short delay 146 setTimeout(function () { 147 // window.location.href = stripeLink; 148 window.open(stripeLink, '_blank'); 149 150 // Close/hide the form after opening the payment page 151 setTimeout(function () { 152 $(document).find(".pum-close").trigger("click"); 153 $container.find("#donation_name").val(""); 154 $container.find("#donation_email").val(""); 155 $container.find("#donation-form-message").hide(); 156 $("#donation_submit_btn_stripe").prop("disabled", false).text("Donate via Stripe"); 157 }, 1500); 158 159 }, 800); 160 161 }); 162 163 164 /** 165 * Handle PayPal form SUBMIT button click. 166 * Scopes all field reads and validations to the button's own popup container. 167 */ 168 $(document).on("click", "#donation_submit_btn_paypal", function () { 169 170 // Scope to this button's own popup wrapper to avoid conflict with Stripe popup 171 var $container = $(this).closest("#donation-form-wrapper"); 172 173 if (!validateDonationForm($container)) { 174 return; 175 } 176 177 var paypalLink = (donationConfig && donationConfig.paypalLink) ? donationConfig.paypalLink : ""; 178 179 // Show error if PayPal link is not configured in the donate page meta fields 180 if (!paypalLink) { 181 $container.find("#donation-form-message") 182 .removeClass("donation-success") 183 .addClass("donation-error") 184 .text("PayPal payment link is not configured. Please contact the site administrator.") 185 .show(); 186 return; 187 } 188 189 var userName = $.trim($container.find("#donation_name").val()); 190 var userEmail = $.trim($container.find("#donation_email").val()); 191 192 // Disable button to prevent duplicate submissions 193 $(this).prop("disabled", true).text("Please wait..."); 194 195 // Store all cookies before redirect 196 storeDonationCookies(userName, userEmail); 197 198 $container.find("#donation-form-message") 199 .removeClass("donation-error") 200 .addClass("donation-success") 201 .text("Thank you! Redirecting to PayPal...") 202 .show(); 203 204 // Redirect to PayPal payment page after short delay 205 setTimeout(function () { 206 // window.location.href = paypalLink; 207 window.open(paypalLink, '_blank'); 208 209 // Close/hide the form after opening the payment page 210 setTimeout(function () { 211 $(document).find(".pum-close").trigger("click"); 212 $container.find("#donation_name").val(""); 213 $container.find("#donation_email").val(""); 214 $container.find("#donation-form-message").hide(); 215 $("#donation_submit_btn_paypal").prop("disabled", false).text("Donate via PayPal"); 216 }, 1500); 217 218 }, 800); 219 220 }); 221 222 223 /** 224 * Clear individual field error when the user starts typing again. 225 * Uses document delegation to work inside dynamically loaded popup content. 226 */ 227 $(document).on("input", "#donation_name, #donation_email", function () { 228 $(this).removeClass("donation-input-error"); 229 var $container = $(this).closest("#donation-form-wrapper"); 230 var errorId = "#" + $(this).attr("id") + "_error"; 231 $container.find(errorId).text(""); 232 }); 233 234});
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.