1/*! 2 * Funnel Tools Capture Library v1.1.0 3 * http://brandonhilkert.com/funnel-tools/capture 4 * 5 * Copyright 2015 Big Blue Media, LLC 6 * http://brandonhilkert.com 7 * 8 * Date: 2015-02-20T13:58Z 9 */ 10 11window.FunnelTools || (window.FunnelTools = {}); 12FunnelTools.Capture = { 13 showTime: 32000, 14 15 init: function(opts) { 16 if (opts && opts.showTime) { 17 this.showTime = opts.showTime; 18 } 19 try { 20 this.expiredStorage = new ExpiredStorage(); 21 } catch (exc) { 22 console.error(exc); 23 } 24 25 // The collapsed/open states are pure CSS (see funnel-tools-capture.css), 26 // so nothing is measured or positioned here. 27 this.triggerShow(this.showTime); 28 }, 29 widget: function() { 30 return $("#funnel-tools-capture"); 31 }, 32 open: function() { 33 return $("#funnel-tools-capture .open"); 34 }, 35 36 close: function() { 37 return $("#funnel-tools-capture .close"); 38 }, 39 show: function() { 40 this.widget().addClass('open'); 41 if (this.expiredStorage) { 42 this.expiredStorage.setItem('toasterShown', true, 3600 * 24 * 5); // 5 days 43 } 44 }, 45 triggerShow: function(time) { 46 var that = this; 47 48 setTimeout(function() { 49 if (!that.wasShown()) { 50 that.show(); 51 } 52 }, time); 53 }, 54 wasShown: function() { 55 return this.expiredStorage && this.expiredStorage.getItem('toasterShown'); 56 }, 57 hide: function() { 58 this.widget().removeClass('open'); 59 }, 60 toggle: function() { 61 if (!this.isVisible()) { 62 this.show(); 63 } else { 64 this.hide(); 65 } 66 }, 67 isVisible: function() { 68 return this.widget().hasClass('open'); 69 }, 70} 71 72$(document).on("click", "#funnel-tools-capture .title, #funnel-tools-capture .open, #funnel-tools-capture .close", function() { 73 FunnelTools.Capture.toggle(); 74}); 75 76// Hide widget when clicking outside 77$(document).click(function(event) { 78 if (!FunnelTools.Capture.isVisible()) { 79 return; 80 } 81 if ($(event.target).parents("#funnel-tools-capture").length === 0) { 82 FunnelTools.Capture.hide(); 83 } 84}); 85 86function gaSend(obj) { 87 if (typeof ga !== "undefined") { 88 try { 89 ga('send', obj); 90 } catch (e) { 91 console.error(e); 92 } 93 } else { 94 console.error('Google Analytics not loaded on page.'); 95 } 96} 97 98$(document).ready(function() { 99 FunnelTools.Capture.init(); 100 101 function submitHandler($form) { 102 var $submit = $form.find('*[type=submit]'); 103 var $title = $("#funnel-tools-capture .title"); 104 var $description = $("#funnel-tools-capture .description"); 105 var $email = $("#funnel-tools-capture input[type=email]"); 106 $submit 107 .prop('disabled', true) 108 .data('submitText', $submit.text()) 109 .text('Submitting...'); 110 gaSend({ 111 hitType: 'event', 112 eventCategory: 'Python Morsels', 113 eventAction: 'button click', 114 eventLabel: 'Toaster Widget' 115 }); 116 $.ajax({ 117 url: $form.attr('action'), 118 method: 'POST', 119 data: $form.serialize() 120 }).always(function() { 121 $submit 122 .prop('disabled', false) 123 .text($submit.data('submitText')); 124 }).done(function(data, textStatus, xhr) { 125 if (xhr.status == 201) { 126 var thanksMessage = $('#morsels-signup-thanks').html(); 127 $title.html('You just signed up!... almost'); 128 $description.html(thanksMessage); 129 if ($email.val().indexOf("gmail.com") != -1) { 130 $description.find('.email-message').html('<p><a href="https://mail.google.com" target="_blank">Go to Gmail to continue</a> :)</p>') 131 } 132 gaSend({ 133 hitType: 'event', 134 eventCategory: 'Python Morsels', 135 eventAction: 'signup', 136 eventLabel: 'Toaster Widget' 137 }); 138 } else if (data.code == 1) { 139 $description.html("You've already signed up with that email. You can <a href=\"https://www.pythonmorsels.com/accounts/login/\">login here</a>.") 140 gaSend({ 141 hitType: 'event', 142 eventCategory: 'Python Morsels', 143 eventAction: 'email already signed up', 144 eventLabel: 'Toaster Widget' 145 }); 146 } else if (data.code == 3) { 147 $email.next('span.error').remove(); 148 $email.after('<span class="error">Email invalid</span>'); 149 $email.addClass('error'); 150 gaSend({ 151 hitType: 'event', 152 eventCategory: 'Python Morsels', 153 eventAction: 'email invalid', 154 eventLabel: 'Toaster Widget' 155 }); 156 } else { 157 alert("An unexpected error occurred while submitting this form. Sorry! Please feel free to contact Trey to troubleshoot."); 158 console.error(data, textStatus, xhr); 159 gaSend({ 160 hitType: 'event', 161 eventCategory: 'Python Morsels', 162 eventAction: 'server error', 163 eventLabel: 'Toaster Widget' 164 }); 165 } 166 }).fail(function(xhr, textStatus, error) { 167 if (xhr.status == 401) { 168 $description.html("You've already signed up with that email. You can <a href=\"https://www.pythonmorsels.com/accounts/login/\">login here</a>.") 169 } else if (xhr.status == 400) { 170 $email.next('span.error').remove(); 171 $email.after('<span class="error">Email invalid</span>'); 172 $email.addClass('error'); 173 } else { 174 alert("An unexpected error occurred while submitting this form. Sorry! Please feel free to contact Trey to troubleshoot."); 175 } 176 }); 177 } 178 179 $("#funnel-tools-capture form[action*=pythonmorsels]").submit(function(event) { 180 var $form = $(event.target); 181 grecaptcha.ready(function() { 182 grecaptcha.execute('6LfP0cEUAAAAAAlbI-d5M7xLioNYWX0LDj78gN2b', { 183 action: 'signup' 184 }).then(function(token) { 185 $form.find('*[name=captcha_token]').val(token); 186 submitHandler($form); 187 }); 188 }); 189 event.preventDefault(); 190 }); 191 192 $("#funnel-tools-capture input[type=email]").focus(function(event) { 193 var $email = $(event.target); 194 $email.removeClass('error') 195 $email.next('span.error').remove(); 196 }); 197});
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.