PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 3.4.3
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v3.4.3
3.4.3 3.4.2 3.4.1 3.4.0 3.3.9 3.3.8 3.3.7 3.3.6 3.3.5 3.3.4 3.3.3 3.3.2 3.3.1 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 2.3.0 2.3.1 All 196 releases
← All changes | resources/frontend/js/convertkit.js +104 -201 2.2.43.4.3 View file →
@@ -2,250 +2,153 @@
2 2 * Frontend functionality for subscribers and tags.
3 3 *
4 4 * @since 1.9.6
5 5 *
6 - * @package ConvertKit
7 6 * @author ConvertKit
8 7 */
9 8
10 9 /**
11 - * Tags the given subscriber ID with the given tag
10 + * Remove the url subscriber_id url param
12 11 *
13 - * @since 1.9.6
12 + * The 'ck_subscriber_id' should only be set on URLs included on
13 + * links from a ConvertKit email with no other URL parameters.
14 + * This function removes the parameters so a customer won't share
15 + * a URL with their subscriber ID in it.
14 16 *
15 - * @param int subscriber_id Subscriber ID
16 - * @param string tag Tag
17 - * @param int post_id WordPress Post ID
17 + * @param {string} url URL.
18 18 */
19 -function convertKitTagSubscriber( subscriber_id, tag, post_id ) {
19 +function convertKitRemoveSubscriberIDFromURL(url) {
20 + // Parse URL.
21 + const url_object = new URL(url);
22 + const ck_subscriber_id = url_object.searchParams.get('ck_subscriber_id');
20 23
21 - if ( convertkit.debug ) {
22 - console.log( 'convertKitTagSubscriber' );
23 - console.log( convertkit );
24 - console.log( subscriber_id );
25 - console.log( tag );
26 - console.log( post_id );
24 + // If ck_subscriber_id is null, it's not included in the URL.
25 + // Don't modify the URL.
26 + if (ck_subscriber_id === null) {
27 + return;
27 28 }
28 29
29 - ( function( $ ) {
30 + // Remove ck_subscriber_id from URL params.
31 + url_object.searchParams.delete('ck_subscriber_id');
30 32
31 - $.ajax(
32 - {
33 - type: 'POST',
34 - data: {
35 - action: 'convertkit_tag_subscriber',
36 - convertkit_nonce: convertkit.nonce,
37 - subscriber_id: subscriber_id,
38 - tag: tag,
39 - post_id: post_id
40 - },
41 - url: convertkit.ajaxurl,
42 - success: function ( response ) {
43 - if ( convertkit.debug ) {
44 - console.log( response );
45 - }
46 - convertKitRemoveSubscriberIDFromURL( window.location.href );
47 - }
48 - }
49 - ).fail(
50 - function (response) {
51 - if ( convertkit.debug ) {
52 - console.log( response );
53 - }
54 - convertKitRemoveSubscriberIDFromURL( window.location.href );
55 - }
56 - );
33 + // Get title and string of parameters.
34 + const title = document.getElementsByTagName('title')[0].innerHTML;
35 + let params = url_object.searchParams.toString();
57 36
58 - } )( jQuery );
37 + // Only add '?' if there are parameters.
38 + if (params.length > 0) {
39 + params = '?' + params;
40 + }
59 41
42 + // Update history.
43 + window.history.replaceState(
44 + null,
45 + title,
46 + url_object.pathname + params + url_object.hash
47 + );
48 +
49 + // Emit custom event with the removed subscriber ID.
50 + convertKitEmitCustomEvent('kit_subscriber_id_removed_from_url', {
51 + id: ck_subscriber_id,
52 + });
60 53 }
61 54
62 55 /**
63 - * Gets the subscriber ID for the given email address, storing
64 - * it in the `ck_subscriber_id` cookie if it exists.
56 + * Emit a custom event with optional detail data.
65 57 *
66 - * Typically called when the user completes a ConvertKit Form
67 - * that has either "Auto-confirm new subscribers" or
68 - * "Send subscriber to thank you page" enabled (both scenarios
69 - * include a ck_subscriber_id).
58 + * This function creates and dispatches a custom event with the specified
59 + * event name and detail data.
70 60 *
71 - * @since 1.9.6
61 + * @since 2.5.0
72 62 *
73 - * @param int id Subscriber ID
63 + * @param {string} eventName The name of the custom event to emit.
64 + * @param {Object} [detail={}] Optional detail data to include with the event.
74 65 */
75 -function convertStoreSubscriberIDInCookie( subscriber_id ) {
76 -
77 - if ( convertkit.debug ) {
78 - console.log( 'convertStoreSubscriberIDInCookie' );
79 - console.log( subscriber_id );
80 - }
81 -
82 - ( function( $ ) {
83 -
84 - $.ajax(
85 - {
86 - type: 'POST',
87 - data: {
88 - action: 'convertkit_store_subscriber_id_in_cookie',
89 - convertkit_nonce: convertkit.nonce,
90 - subscriber_id: subscriber_id
91 - },
92 - url: convertkit.ajaxurl,
93 - success: function ( response ) {
94 - if ( convertkit.debug ) {
95 - console.log( response );
96 - }
97 -
98 - convertKitRemoveSubscriberIDFromURL( window.location.href );
99 - }
100 - }
101 - ).fail(
102 - function (response) {
103 - if ( convertkit.debug ) {
104 - console.log( response );
105 - }
106 -
107 - convertKitRemoveSubscriberIDFromURL( window.location.href );
108 - }
109 - );
110 -
111 - } )( jQuery );
112 -
66 +function convertKitEmitCustomEvent(eventName, detail) {
67 + const event = new CustomEvent(eventName, { detail });
68 + document.dispatchEvent(event);
113 69 }
114 70
71 +/* eslint-disable no-unused-vars */
115 72 /**
116 - * Gets the subscriber ID for the given email address, storing
117 - * it in the `ck_subscriber_id` cookie if it exists.
73 + * Handles form submissions when reCAPTCHA is enabled.
118 74 *
119 - * Typically called when the user completes a ConvertKit Form
120 - * that has either "Auto-confirm new subscribers" or
121 - * "Send subscriber to thank you page" enabled (both scenarios
122 - * include a ck_subscriber_id).
123 - *
124 - * @since 1.9.6
125 - *
126 - * @param string emailAddress Email Address
75 + * @param {string} token reCAPTCHA token.
127 76 */
128 -function convertStoreSubscriberEmailAsIDInCookie( emailAddress ) {
77 +function convertKitRecaptchaFormSubmit(token) {
78 + // Find submit button with the data-callback attribute.
79 + const submitButton = document.querySelector(
80 + '[type="submit"][data-callback="convertKitRecaptchaFormSubmit"]'
81 + );
129 82
130 - if ( convertkit.debug ) {
131 - console.log( 'convertStoreSubscriberEmailAsIDInCookie' );
132 - console.log( emailAddress );
133 - }
83 + // Get the parent form of the submit button.
84 + const form = submitButton.closest('form');
134 85
135 - ( function( $ ) {
86 + // Submit the form, using requestSubmit() so any submit event listeners are honored
87 + // e.g. the Member Content login form, which submits using AJAX.
88 + form.requestSubmit();
89 +}
136 90
137 - $.ajax(
138 - {
139 - type: 'POST',
140 - data: {
141 - action: 'convertkit_store_subscriber_email_as_id_in_cookie',
142 - convertkit_nonce: convertkit.nonce,
143 - email: emailAddress
144 - },
145 - url: convertkit.ajaxurl,
146 - success: function ( response ) {
147 - if ( convertkit.debug ) {
148 - console.log( response );
149 - }
150 - }
151 - }
152 - ).fail(
153 - function (response) {
154 - if ( convertkit.debug ) {
155 - console.log( response );
156 - }
157 - }
158 - );
91 +// Scope the function to the window object as webpack will wrap everything in a closure,
92 +// resulting in the function not being available globally.
93 +window.convertKitRecaptchaFormSubmit = convertKitRecaptchaFormSubmit;
159 94
160 - } )( jQuery );
161 -
162 -}
163 -
164 95 /**
165 - * Remove the url subscriber_id url param
96 + * Handles form submissions when Cloudflare Turnstile is enabled.
166 97 *
167 - * The 'ck_subscriber_id' should only be set on URLs included on
168 - * links from a ConvertKit email with no other URL parameters.
169 - * This function removes the parameters so a customer won't share
170 - * a URL with their subscriber ID in it.
98 + * Turnstile auto-populates a hidden `cf-turnstile-response` input inside the
99 + * enclosing form once the challenge is solved, so we just need to submit the
100 + * containing form when the callback fires.
171 101 *
172 - * @param url
102 + * @param {string} token Turnstile response token.
173 103 */
174 -function convertKitRemoveSubscriberIDFromURL( url ) {
104 +function convertKitTurnstileFormSubmit(token) {
105 + // Find the Turnstile widget div with the data-callback attribute.
106 + const widget = document.querySelector(
107 + '.cf-turnstile[data-callback="convertKitTurnstileFormSubmit"]'
108 + );
175 109
176 - var clean_url = url.substring( 0, url.indexOf( "?ck_subscriber_id" ) );
177 - var title = document.getElementsByTagName( "title" )[0].innerHTML;
178 - if ( clean_url ) {
179 - window.history.pushState( null, title, clean_url );
110 + if (!widget) {
111 + return;
180 112 }
181 113
182 -}
114 + // Get the parent form of the widget.
115 + const form = widget.closest('form');
183 116
184 -/**
185 - * Utility function to pause for the given number of milliseconds
186 - *
187 - * @since 1.9.6
188 - *
189 - * @param int milliseconds
190 - */
191 -function convertKitSleep( milliseconds ) {
192 -
193 - var start = new Date().getTime();
194 - for (var i = 0; i < 1e7; i++) {
195 - if ((new Date().getTime() - start) > milliseconds) {
196 - break;
197 - }
117 + if (!form) {
118 + return;
198 119 }
199 120
121 + // Submit the form, using requestSubmit() so any submit event listeners are honored
122 + // e.g. the Member Content login form, which submits using AJAX.
123 + form.requestSubmit();
200 124 }
201 125
126 +// Scope the function to the window object as webpack will wrap everything in a closure,
127 +// resulting in the function not being available globally.
128 +window.convertKitTurnstileFormSubmit = convertKitTurnstileFormSubmit;
129 +/* eslint-enable no-unused-vars */
130 +
202 131 /**
203 - * Register events
132 + * Register events on frontend.
133 + *
134 + * @since 3.2.0
204 135 */
205 -jQuery( document ).ready(
206 - function( $ ) {
136 +if (typeof convertkit !== 'undefined') {
137 + document.addEventListener('DOMContentLoaded', function () {
138 + // Removes `ck_subscriber_id` from the URI.
139 + convertKitRemoveSubscriberIDFromURL(window.location.href);
207 140
208 - if ( convertkit.subscriber_id > 0 && convertkit.tag && convertkit.post_id ) {
209 - // If the user can be detected as a ConvertKit Subscriber (i.e. their Subscriber ID is in a cookie or the URL),
210 - // and the Page/Post they are viewing has a Tag specified, subscribe them to the tag.
211 - convertKitTagSubscriber( convertkit.subscriber_id, convertkit.tag, convertkit.post_id );
212 - } else if ( convertkit.subscriber_id > 0 ) {
213 - // If the user can be detected as a ConvertKit Subscriber (i.e. their Subscriber ID is in a cookie or the URL),
214 - // update the cookie now.
215 - convertStoreSubscriberIDInCookie( convertkit.subscriber_id );
141 + // Set a cookie if any scripts with data-kit-limit-per-session attribute exist.
142 + if (
143 + document.querySelectorAll('script[data-kit-limit-per-session="1"]')
144 + .length > 0
145 + ) {
146 + document.cookie = 'ck_non_inline_form_displayed=1; path=/';
147 + if (convertkit.debug) {
148 + console.log(
149 + 'Set `ck_non_inline_form_displayed` cookie for non-inline form limit'
150 + );
151 + }
216 152 }
217 -
218 - // Store subscriber ID as a cookie from the email address used when a ConvertKit Form is submitted.
219 - $( document ).on(
220 - 'click',
221 - '.formkit-submit',
222 - function() {
223 - var emailAddress = $( 'input[name="email_address"]' ).val();
224 -
225 - // If the email address is empty, don't attempt to get the subscriber ID by email.
226 - if ( ! emailAddress.length ) {
227 - if ( convertkit.debug ) {
228 - console.log( 'email empty' );
229 - }
230 -
231 - return;
232 - }
233 -
234 - // If the email address is invalid, don't attempt to get the subscriber ID by email.
235 - 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,}))$/;
236 - if ( ! validator.test( emailAddress.toLowerCase() ) ) {
237 - if ( convertkit.debug ) {
238 - console.log( 'email not an email address' );
239 - }
240 -
241 - return;
242 - }
243 -
244 - // Wait a moment before sending the AJAX request.
245 - convertKitSleep( 2000 );
246 - convertStoreSubscriberEmailAsIDInCookie( emailAddress );
247 - }
248 - );
249 -
250 - }
251 -);
153 + });
154 +}