1// Form Tracking // 2const DATA_LAYER_CACHE = 'dataLayerCache'; 3const pushToDataLayerAndCache = (event, data) => { 4 const current = JSON.parse(window.localStorage.getItem(DATA_LAYER_CACHE) ?? "[]"); 5 window.localStorage.setItem(DATA_LAYER_CACHE, JSON.stringify([...current, { 6 event, 7 ...data 8 }])); 9} 10 11const loadDataLayer = () => { 12 const cache = window.localStorage.getItem(DATA_LAYER_CACHE); 13 if (!cache) { 14 return; 15 } 16 window.localStorage.removeItem(DATA_LAYER_CACHE); 17 window.dataLayer = window.dataLayer || []; 18 window.dataLayer.push(...JSON.parse(cache)); 19} 20loadDataLayer(); 21 22window.registerFormLoads = (name, type) => { 23 const formElements = document.querySelectorAll('form'); 24 formElements.forEach((formElement) => { 25 let product; 26 27 formElement.addEventListener('submit', (event) => { 28 const product = formElement.querySelector('[name="Sales_qualified_Product__c"]') !== null ? formElement.querySelector('[name="Sales_qualified_Product__c"]').value : "N/A"; 29 pushToDataLayerAndCache("edm_form_submit_success", { 30 'edm_form_type': type, 31 'edm_form_name': name, 32 'edm_form_products': product 33 }); 34 }); 35 36 const observer = new IntersectionObserver((entries) => { 37 entries.forEach((entry) => { 38 39 if (entry.isIntersecting) { 40 window.dataLayer.push({ 41 'event': 'edm_form_view', 42 'edm_form_type': formElement.getAttribute('data-type'), 43 'edm_form_name': formElement.getAttribute('data-name'), 44 'edm_form_products': product 45 }); 46 observer.unobserve(formElement); 47 } 48 }); 49 }); 50 observer.observe(formElement); 51 }); 52} 53 54 55(function() { 56 57 const fileExtension = /\.(pdf|docx?|xlsx?|pptx?|csv|zip)$/i; 58 const generatedPdfs = { 59 '/catalogs/courseOutlinePDF': 'courseOutline.pdf', 60 '/catalogs/courseSyllabusPDF': 'CourseSyllabus.pdf', 61 '/catalogs/viewPDF': 'catalogs.pdf', 62 '/catalogs/viewDescriptionPDF': 'catalogsWithDescription.pdf', 63 '/catalogs/programListingPDF': 'ProgramListing.pdf' 64 }; 65 66 const trackFileDownload = (event) => { 67 if (event.type === 'auxclick' ? event.button !== 1 : event.button !== 0) { 68 return; 69 } 70 71 const anchor = event.target.closest?.('a[href]'); 72 if (!anchor || !anchor.getAttribute('href').trim()) { 73 return; 74 } 75 76 let url; 77 try { 78 url = new URL(anchor.href); 79 } catch { 80 return; 81 } 82 if (!['http:', 'https:', 'blob:', 'data:'].includes(url.protocol)) { 83 return; 84 } 85 86 const generatedFilename = url.origin === window.location.origin 87 ? generatedPdfs[url.pathname.replace(/\/$/, '')] 88 : undefined; 89 if (!anchor.hasAttribute('download') && !fileExtension.test(url.pathname) && !generatedFilename) { 90 return; 91 } 92 93 const filename = generatedFilename || url.pathname.substring(url.pathname.lastIndexOf('/') + 1); 94 window.dataLayer = window.dataLayer || []; 95 window.dataLayer.push({ 96 'event': 'edm_file_download', 97 'edm_attachment_page_title': document.querySelector('h1')?.innerText || document.title, 98 'edm_attachment': ['blob:', 'data:'].includes(url.protocol) ? (anchor.download || 'download') : filename, 99 'edm_attachment_url': anchor.href 100 }); 101 }; 102 103 // Capture also covers React links mounted later and clicks stopped by components. 104 document.addEventListener('click', trackFileDownload, true); 105 document.addEventListener('auxclick', trackFileDownload, true); 106 107 // Ahref Tracking // 108 const anchorElements = document.querySelectorAll('a'); 109 anchorElements.forEach((anchorElement) => { 110 111 const href = anchorElement.getAttribute('href'); 112 113 // Email ahrefs 114 if (href && href.startsWith('mailto:')) { 115 anchorElement.addEventListener('click', function() { 116 window.window.dataLayer.push({ 117 'event': 'edm_email_click', 118 'edm_email_address': href.substring(7), 119 }); 120 }); 121 } 122 }); 123 124 125 // Drift Chat Tracking // 126 if (typeof window.drift !== 'undefined') { 127 window.drift.on('ready', function(api) { 128 window.drift.on("startConversation", function(data) { 129 window.dataLayer.push({ 130 'event': 'edm_chat_converation_started', 131 'edm_drift_conversation': data.conversationId 132 }); 133 }); 134 window.drift.on("message:sent", function(data) { 135 window.dataLayer.push({ 136 'event': 'edm_chat_message_sent', 137 'edm_drift_conversation': data.conversationId 138 }); 139 }); 140 window.drift.on("message", function(data) { 141 window.dataLayer.push({ 142 'event': 'edm_chat_message_received', 143 'edm_drift_conversation': data.conversationId 144 }); 145 }); 146 window.drift.on("emailCapture", function(data) { 147 window.dataLayer.push({ 148 'event': 'edm_chat_email_captured', 149 'edm_drift_conversation': data.conversationId 150 }); 151 }); 152 window.drift.on("phoneCapture", function(data) { 153 window.dataLayer.push({ 154 'event': 'edm_chat_phone_captured', 155 'edm_drift_conversation': data.conversationId 156 }); 157 }); 158 window.drift.on("scheduling:requestMeeting", function(data) { 159 window.dataLayer.push({ 160 'event': 'edm_chat_meeting_requested', 161 'edm_drift_meetingwith': data.teamMember.name, 162 'edm_drift_conversation': data.conversationId 163 }); 164 }); 165 window.drift.on("scheduling:meetingBooked", function(data) { 166 window.dataLayer.push({ 167 'event': 'edm_chat_meeting_booked', 168 'edm_drift_bookedwith': data.teamMember.name, 169 'edm_drift_conversation': data.conversationId 170 }); 171 }); 172 window.drift.on("conversation:playbookFired", function(data) { 173 window.dataLayer.push({ 174 'event': 'edm_chat_playbook_fired', 175 'edm_drift_playbook': data.playbookId, 176 }); 177 }); 178 window.drift.on("conversation:playbookClicked", function(data) { 179 window.dataLayer.push({ 180 'event': 'edm_chat_playbook_clicked', 181 'edm_drift_playbook': data.playbookId, 182 }); 183 }); 184 window.drift.on("conversation:playbookDismissed", function(data) { 185 window.dataLayer.push({ 186 'event': 'edm_chat_playbook_dismissed', 187 'edm_drift_playbook': data.playbookId, 188 }); 189 }); 190 window.drift.on("conversation:buttonClicked", function(data) { 191 window.dataLayer.push({ 192 'event': 'edm_chat_button_clicked', 193 'edm_drift_button': data.buttonBody, 194 'edm_drift_conversation': data.conversationId 195 }); 196 }); 197 window.drift.on('chatOpen', function(data) { 198 window.dataLayer.push({ 199 'event': 'edm_chat_opened', 200 'edm_drift_conversation': data.conversationId 201 }); 202 }); 203 window.drift.on('chatClosed', function(data) { 204 window.dataLayer.push({ 205 'event': 'edm_chat_closed', 206 'edm_drift_conversation': data.conversationId 207 }); 208 }); 209 }); 210 } 211 212 213 // Video Tracking // 214 var divisor = 25; 215 var videos_status = {}; 216 function eventHandler(e) { 217 var elem = document.getElementById(e.target.id); 218 videos_status[e.target.id].current = Math.round(e.target.currentTime); 219 switch (e.type) { 220 case 'timeupdate': 221 var pct = Math.floor(100 * videos_status[e.target.id].current / e.target.duration); 222 for (var j in videos_status[e.target.id]._progress_markers) { 223 if (pct >= j && j > videos_status[e.target.id].greatest_marker) { 224 videos_status[e.target.id].greatest_marker = j; 225 } 226 } 227 if (videos_status[e.target.id].greatest_marker && !videos_status[e.target.id]._progress_markers[videos_status[e.target.id].greatest_marker]) { 228 videos_status[e.target.id]._progress_markers[videos_status[e.target.id].greatest_marker] = true; 229 window.dataLayer.push({ 230 'event': 'edm_video_' + videos_status[e.target.id].greatest_marker, 231 'edm_video_name': elem.getAttribute('data-title'), 232 'edm_video_type': elem.getAttribute('data-type'), 233 'edm_video_products': elem.getAttribute('data-products'), 234 'edm_video_file': decodeURIComponent(e.target.currentSrc.split('/')[e.target.currentSrc.split('/').length - 1]) 235 }); 236 } 237 break; 238 239 case 'play': 240 window.dataLayer.push({ 241 'event': 'edm_video_play', 242 'edm_video_name': elem.getAttribute('data-title'), 243 'edm_video_type': elem.getAttribute('data-type'), 244 'edm_video_products': elem.getAttribute('data-products'), 245 'edm_video_file': decodeURIComponent(e.target.currentSrc.split('/')[e.target.currentSrc.split('/').length - 1]) 246 }); 247 break; 248 249 case 'pause': 250 window.dataLayer.push({ 251 'event': 'edm_video_pause', 252 'edm_video_percent': Math.floor(100 * videos_status[e.target.id].current / e.target.duration), 253 'edm_video_name': elem.getAttribute('data-title'), 254 'edm_video_type': elem.getAttribute('data-type'), 255 'edm_video_products': elem.getAttribute('data-products'), 256 'edm_video_file': decodeURIComponent(e.target.currentSrc.split('/')[e.target.currentSrc.split('/').length - 1]) 257 }); 258 break; 259 260 case 'ended': 261 window.dataLayer.push({ 262 'event': 'edm_video_complete', 263 'edm_video_name': elem.getAttribute('data-title'), 264 'edm_video_type': elem.getAttribute('data-type'), 265 'edm_video_products': elem.getAttribute('data-products'), 266 'edm_video_file': decodeURIComponent(e.target.currentSrc.split('/')[e.target.currentSrc.split('/').length - 1]) 267 }); 268 break; 269 default: 270 break; 271 } 272 } 273 274 var videos = document.getElementsByTagName('video'); 275 for (var i = 0; i < videos.length; i++) { 276 var videoTagId; 277 if (!videos[i].getAttribute('id')) { 278 videoTagId = 'html5_video_' + Math.random().toString(36).slice(2); 279 videos[i].setAttribute('id', videoTagId); 280 } else { 281 videoTagId = videos[i].getAttribute('id'); 282 } 283 videos_status[videoTagId] = {}; 284 videos_status[videoTagId].greatest_marker = 0; 285 videos_status[videoTagId]._progress_markers = {}; 286 for (j = 0; j < 100; j++) { 287 videos_status[videoTagId].progress_point = divisor * Math.floor(j / divisor); 288 videos_status[videoTagId]._progress_markers[videos_status[videoTagId].progress_point] = false;
289 } 290 videos_status[videoTagId].current = 0; 291 videos[i].addEventListener("play", eventHandler, false); 292 videos[i].addEventListener("pause", eventHandler, false); 293 videos[i].addEventListener("complete", eventHandler, false); 294 videos[i].addEventListener("timeupdate", eventHandler, false); 295 videos[i].addEventListener("ended", eventHandler, false); 296 } 297})();
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.