1/* Email Encoder */ 2/*global jQuery, window*/ 3jQuery(function ($) { 4 5 'use strict'; 6 7 // encoding method 8 function rot13(s) { 9 // source: http://jsfromhell.com/string/rot13 10 return s.replace(/[a-zA-Z]/g, function (c) { 11 return String.fromCharCode((c <= 'Z' ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26); 12 }); 13 } 14 15 /** 16 * EMAIL RELATED LOGIC 17 */ 18 19 // fetch email from data attribute 20 function fetchEmail(el) { 21 var email = el.getAttribute('data-enc-email'); 22 23 if (!email) { 24 return null; 25 } 26 27 // replace [at] sign 28 email = email.replace(/\[at\]/g, '@'); 29 30 // encode 31 email = rot13(email); 32 33 return email; 34 } 35 36 // replace email in title attribute 37 function parseTitle(el) { 38 var title = el.getAttribute('title'); 39 var email = fetchEmail(el); 40 41 if (title && email) { 42 title = title.replace('{{email}}', email); 43 el.setAttribute('title', title); 44 } 45 } 46 47 // set input value attribute 48 function setInputValue(el) { 49 var email = fetchEmail(el); 50 51 if (email) { 52 el.setAttribute('value', email); 53 } 54 } 55 56 // open mailto link (fallback for links that were never hydrated) 57 function mailto(el) { 58 var email = fetchEmail(el); 59 60 if (email) { 61 window.location.href = 'mailto:' + email; 62 } 63 } 64 65 // Build the real "mailto:" href from data-enc-email, lazily â only once the 66 // visitor engages with the link (mousedown / touch / focus), which always 67 // happens before a click, middle-click or "open in new tab". Doing it lazily 68 // rather than on page load keeps the plaintext address out of the rendered 69 // DOM for agents that run JS but never interact (search-engine renderers, 70 // headless harvesters), while still giving real navigations a genuine link. 71 // It also replaces the inert "javascript:;" placeholder before any navigation, 72 // so iOS Safari never tries to open a javascript: URL in a new tab (which 73 // throws "cannot run script"). 74 function hydrateMailto(el) { 75 var email = fetchEmail(el); 76 77 if (email && el.getAttribute('href') !== 'mailto:' + email) { 78 el.setAttribute('href', 'mailto:' + email); 79 } 80 } 81 82 // revert 83 function revert(el, rtl) { 84 var email = fetchEmail(el); 85 86 if (email) { 87 rtl.text(email); 88 rtl.removeClass('eeb-rtl'); 89 } 90 } 91 92 // prepare for copying email 93 document.addEventListener('copy', function(e){ 94 $('a[data-enc-email]').each(function () { 95 var rtl = $(this).find('.eeb-rtl'); 96 97 if (rtl.text()) { 98 revert(this, rtl); 99 } 100 }); 101 console.log('copy'); 102 }); 103 104 // hydrate the mailto href the moment the visitor engages with the link, 105 // before any click / middle-click / "open in new tab" navigation resolves 106 $('body').on('mousedown touchstart focusin', 'a[data-enc-email]', function () { 107 hydrateMailto(this); 108 }); 109 110 // set mailto click 111 $('body').on('click', 'a[data-enc-email]', function () { 112 // Already hydrated to a real mailto (on mousedown/touch/focus): let the 113 // browser handle it natively. Otherwise open it ourselves. 114 if ((this.getAttribute('href') || '').indexOf('mailto:') === 0) { 115 return; 116 } 117 118 mailto(this); 119 }); 120 121 // parse title attribute 122 $('a[data-enc-email]').each(function () { 123 parseTitle(this); 124 }); 125 126 // parse input fields 127 $('input[data-enc-email]').each(function () { 128 setInputValue(this); 129 }); 130 131});
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.