1// contact â fires when a user clicks or copies an email address or phone number. 2(function () { 3 var MK = window.MKTracking; 4 if (!MK) return; 5 6 var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; 7 8 function fire(name, type) { 9 if (!name) return; 10 MK.push({ 11 event: 'contact', 12 event_id: MK.newEventId('contact'), // unique per event; Pixel-only, no CAPI dedup counterpart 13 content: { 14 name: name, // email or phone number clicked/copied 15 type: type // "click" or "copy" 16 } 17 }); 18 } 19 20 // Extracts the email/phone value from a mailto:/tel: link, or null. 21 function linkContactValue(link) { 22 if (!link) return null; 23 var href = link.getAttribute('href') || ''; 24 var match = href.match(/^\s*(mailto|tel):(.+)$/i); 25 if (!match) return null; 26 // Drop any mailto query string (?subject=...) and decode escapes. 27 var value = match[2].split('?')[0]; 28 try { value = decodeURIComponent(value); } catch (e) {} 29 return value.trim() || null; 30 } 31 32 // Loose phone check: only phone characters, 7â15 digits total. 33 function isPhone(text) { 34 if (!/^\+?[\d\s().-]+$/.test(text)) return false; 35 var digits = text.replace(/\D/g, '').length; 36 return digits >= 7 && digits <= 15; 37 } 38 39 function elementFromNode(node) { 40 if (!node) return null; 41 return node.nodeType === 1 ? node : node.parentElement; 42 } 43 44 // Clicks on email/phone links. 45 document.addEventListener('click', function (e) { 46 var link = e.target && e.target.closest ? e.target.closest('a') : null; 47 var value = linkContactValue(link); 48 if (value) fire(value, 'click'); 49 }); 50 51 // Copying an email/phone from the page. 52 document.addEventListener('copy', function () { 53 var selection = window.getSelection ? window.getSelection() : null; 54 var text = selection ? String(selection).trim() : ''; 55 if (!text) return; 56 57 // Email is unambiguous. 58 if (EMAIL_RE.test(text)) { 59 fire(text, 'copy'); 60 return; 61 } 62 63 // Prefer the exact value from a mailto:/tel: link the selection sits in. 64 var el = selection.anchorNode ? elementFromNode(selection.anchorNode) : null; 65 var link = el && el.closest ? el.closest('a[href^="tel:"], a[href^="mailto:"]') : null; 66 var linkValue = linkContactValue(link); 67 if (linkValue) { 68 fire(linkValue, 'copy'); 69 return; 70 } 71 72 // Fallback: the selection itself looks like a phone number. 73 if (isPhone(text)) { 74 fire(text, 'copy'); 75 } 76 }); 77})();
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.