1/** 2 * Frontend functionality for subscribers and tags. 3 * 4 * @since 1.9.6 5 * 6 * @package ConvertKit 7 * @author ConvertKit 8 */ 9 10/** 11 * Gets the subscriber ID for the given email address, storing 12 * it in the `ck_subscriber_id` cookie if it exists. 13 * 14 * Typically called when the user completes a ConvertKit Form 15 * that has either "Auto-confirm new subscribers" or 16 * "Send subscriber to thank you page" enabled (both scenarios 17 * include a ck_subscriber_id). 18 * 19 * @since 1.9.6 20 * 21 * @param string emailAddress Email Address 22 */ 23function convertStoreSubscriberEmailAsIDInCookie( emailAddress ) { 24 25 if ( convertkit.debug ) { 26 console.log( 'convertStoreSubscriberEmailAsIDInCookie' ); 27 console.log( emailAddress ); 28 } 29 30 fetch( 31 convertkit.ajaxurl, 32 { 33 method: 'POST', 34 headers: { 35 'Content-Type': 'application/x-www-form-urlencoded', 36 }, 37 body: new URLSearchParams( 38 { 39 action: 'convertkit_store_subscriber_email_as_id_in_cookie', 40 convertkit_nonce: convertkit.nonce, 41 email: emailAddress 42 } 43 ) 44 } 45 ) 46 .then( 47 function ( response ) { 48 if ( convertkit.debug ) { 49 console.log( response ); 50 } 51 52 return response.json(); 53 } 54 ) 55 .then( 56 function ( result ) { 57 if ( convertkit.debug ) { 58 console.log( result ); 59 } 60 61 // Emit custom event with subscriber ID. 62 convertKitEmitCustomEvent( 63 'convertkit_user_subscribed', 64 { 65 id: result.data.id, 66 email: emailAddress 67 } 68 ); 69 } 70 ) 71 .catch( 72 function ( error ) { 73 if ( convertkit.debug ) { 74 console.error( error ); 75 } 76 } 77 ); 78 79} 80 81/** 82 * Remove the url subscriber_id url param 83 * 84 * The 'ck_subscriber_id' should only be set on URLs included on 85 * links from a ConvertKit email with no other URL parameters. 86 * This function removes the parameters so a customer won't share 87 * a URL with their subscriber ID in it. 88 * 89 * @param url 90 */ 91function convertKitRemoveSubscriberIDFromURL( url ) { 92 93 // Remove ck_subscriber_id, retaining other params. 94 const url_object = new URL( url ); 95 url_object.searchParams.delete( 'ck_subscriber_id' ); 96 97 // Get title and string of parameters. 98 const title = document.getElementsByTagName( 'title' )[0].innerHTML; 99 let params = url_object.searchParams.toString(); 100 101 // Only add '?' if there are parameters. 102 if ( params.length > 0 ) { 103 params = '?' + params; 104 } 105 106 // Update history. 107 window.history.pushState( null, title, url_object.pathname + params + url_object.hash ); 108 109} 110 111/** 112 * Utility function to pause for the given number of milliseconds 113 * 114 * @since 1.9.6 115 * 116 * @param int milliseconds 117 */ 118function convertKitSleep( milliseconds ) { 119 120 var start = new Date().getTime(); 121 for (var i = 0; i < 1e7; i++) { 122 if ((new Date().getTime() - start) > milliseconds) { 123 break; 124 } 125 } 126 127} 128 129/** 130 * Emit a custom event with optional detail data. 131 * 132 * This function creates and dispatches a custom event with the specified 133 * event name and detail data. 134 * 135 * @since 2.5.0 136 * 137 * @param {string} eventName The name of the custom event to emit. 138 * @param {Object} [detail={}] Optional detail data to include with the event. 139 */ 140function convertKitEmitCustomEvent( eventName, detail ) { 141 142 const event = new CustomEvent( eventName, { detail } ); 143 document.dispatchEvent( event ); 144 145} 146 147/** 148 * Register events 149 */ 150document.addEventListener( 151 'DOMContentLoaded', 152 function () { 153 154 // Removes `ck_subscriber_id` from the URI. 155 convertKitRemoveSubscriberIDFromURL( window.location.href ); 156 157 // Store subscriber ID as a cookie from the email address used when a ConvertKit Form is submitted. 158 document.addEventListener( 159 'click', 160 function (e) { 161 // Check if the form submit button was clicked, or the span element was clicked and its parent is the form submit button. 162 if ( ! e.target.matches( '.formkit-submit' ) && ( ! e.target.parentElement || ! e.target.parentElement.matches( '.formkit-submit' ) ) ) { 163 if ( convertkit.debug ) { 164 console.log( 'not a ck form' ); 165 } 166 167 return; 168 } 169 170 // Get email address. 171 let emailAddress = document.querySelector( 'input[name="email_address"]' ).value; 172 173 // If the email address is empty, don't attempt to get the subscriber ID by email. 174 if ( ! emailAddress.length ) { 175 if ( convertkit.debug ) { 176 console.log( 'email empty' ); 177 } 178 179 return; 180 } 181
182 // If the email address is invalid, don't attempt to get the subscriber ID by email. 183 var validator = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 184 if ( ! validator.test( emailAddress.toLowerCase() ) ) { 185 if ( convertkit.debug ) { 186 console.log( 'email not an email address' ); 187 } 188 189 return; 190 } 191 192 // Wait a moment before sending the AJAX request. 193 convertKitSleep( 2000 ); 194 convertStoreSubscriberEmailAsIDInCookie( emailAddress ); 195 } 196 ); 197 198 } 199);
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.