PageSourceSearch

https://riddimbank.com/js/email-check.js

js riddimbank.com collected 2026-10-07 22:24:20 UTC 4,106 bytes, 71 lines download raw bytes

1/* /js/email-check.js — "Did you mean [email protected]?" under every email box
2   (3 Oct 2026: Joe typed ".om" for ".com" and his receipt bounced).
3   Watches every <input type="email"> on the page. When someone leaves the box
4   with a likely typo of a common provider (gmial.com, yahoo.con) or ending
5   (.om, .con), it shows the fix with a "Yes, fix it" button. It never changes
6   the address by itself. The server makes the same check, and also refuses an
7   address whose domain cannot receive mail (functions/email-domain.js: keep
8   PROVIDERS and TLD_FIX the same in both files). */
9(function () {
10  'use strict';
11  var PROVIDERS = ['gmail.com', 'yahoo.com', 'hotmail.com', 'outlook.com', 'icloud.com', 'aol.com', 'live.com', 'msn.com', 'me.com', 'mac.com', 'protonmail.com', 'proton.me', 'comcast.net', 'att.net', 'verizon.net', 'ymail.com', 'googlemail.com', 'riddimbank.com'];
12  var TLD_FIX = { om: 'com', con: 'com', cmo: 'com', ocm: 'com', vom: 'com', xom: 'com', comm: 'com', coom: 'com', cpm: 'com', cm: 'com', nte: 'net', ner: 'net', nett: 'net', ogr: 'org', orh: 'org' };
13  function lev(a, b) {
14    var m = a.length, n = b.length, d = [], i, j;
15    for (i = 0; i <= m; i++) d[i] = [i];
16    for (j = 1; j <= n; j++) d[0][j] = j;
17    for (i = 1; i <= m; i++) for (j = 1; j <= n; j++) {
18      d[i][j] = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1));
19      if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + 1);
20    }
21    return d[m][n];
22  }
23  function suggest(email) {
24    var e = String(email || '').trim().toLowerCase(), at = e.lastIndexOf('@');
25    if (at < 1) return null;
26    var user = e.slice(0, at), dom = e.slice(at + 1);
27    if (!dom || PROVIDERS.indexOf(dom) !== -1) return null;
28    var best = null, bestD = 3;
29    PROVIDERS.forEach(function (p) { var d = lev(dom, p); if (d < bestD) { best = p; bestD = d; } });
30    if (best && bestD <= 2) return user + '@' + best;
31    var dot = dom.lastIndexOf('.');
32    if (dot > 0 && TLD_FIX[dom.slice(dot + 1)]) return user + '@' + dom.slice(0, dot + 1) + TLD_FIX[dom.slice(dot + 1)];
33    return null;
34  }
35  window.rbEmailSuggest = suggest;   // for the tests
36  /* Not an email at all (4 Oct 2026: Joe typed anything and got no warning). */
37  var FORMAT = /^[^@\s]+@[^@\s]+\.[^@\s]{2,}$/;
38  function incomplete(email) { var e = String(email || '').trim(); return e !== '' && !FORMAT.test(e); }
39  window.rbEmailIncomplete = incomplete;
40
41  function attach(input) {
42    if (input.dataset.rbEmailCheck) return;
43    input.dataset.rbEmailCheck = '1';
44    var hint = document.createElement('div');
45    hint.className = 'rb-email-hint';
46    hint.style.cssText = 'display:none;margin-top:6px;font-size:14px;color:#FFA726;';
47    input.insertAdjacentElement('afterend', hint);
48    function check() {
49      if (incomplete(input.value)) {
50        hint.textContent = 'That doesn\u2019t look like a complete email address (like [email protected]).';
51        hint.style.display = 'block';
52        return;
53      }
54      var fix = suggest(input.value);
55      if (!fix) { hint.style.display = 'none'; return; }
56      hint.textContent = 'Did you mean ' + fix + '? ';
57      var b = document.createElement('button');
58      b.type = 'button';
59      b.textContent = 'Yes, fix it';
60      b.style.cssText = 'background:none;border:0;padding:0;color:#1DB954;font-weight:bold;cursor:pointer;text-decoration:underline;font-size:14px;';
61      b.onclick = function () { input.value = fix; hint.style.display = 'none'; input.dispatchEvent(new Event('input', { bubbles: true })); };
62      hint.appendChild(b);
63      hint.style.display = 'block';
64    }
65    input.addEventListener('blur', check);
66    input.addEventListener('change', check);
67    input.addEventListener('input', function () { if (hint.style.display !== 'none') check(); });
68  }
69  function scan() { Array.prototype.forEach.call(document.querySelectorAll('input[type="email"]'), attach); }
70  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', scan); else scan();
71})();

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.