/* BestDadJokes.lol client-side behavior */ (function () { 'use strict'; document.body.classList.add('js-ux'); var JOKES = (window.BDJ && window.BDJ.jokes) || []; function byId(id) { return JOKES[id]; } function $(sel, root) { return (root || document).querySelector(sel); } function $$(sel, root) { return Array.prototype.slice.call((root || document).querySelectorAll(sel)); } /* ---- punchline reveal ---- */ document.addEventListener('click', function (e) { var punch = e.target.closest && e.target.closest('[data-punch]'); if (punch && !punch.classList.contains('revealed')) { punch.classList.add('revealed'); } }); /* ---- random ---- */ var lastId = -1; function randomJoke() { if (!JOKES.length) return null; var j, guard = 0; do { j = JOKES[Math.floor(Math.random() * JOKES.length)]; guard++; } while (j.id === lastId && guard < 20 && JOKES.length > 1); lastId = j.id; return j; } function fillRandom(setupEl, punchEl) { var j = randomJoke(); if (!j) return null; setupEl.textContent = j.s; punchEl.textContent = j.p; punchEl.classList.add('revealed'); punchEl.setAttribute('data-no-blur', ''); return j; } /* ---- clipboard ---- */ function copyText(text, btn) { function ok() { if (btn) { var o = btn.textContent; btn.textContent = '✅ Copied'; setTimeout(function () { btn.textContent = o; }, 1400); } } if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(text).then(ok, function () { legacy(); }); } else { legacy(); } function legacy() { var ta = document.createElement('textarea'); ta.value = text; document.body.appendChild(ta); ta.select(); try { document.execCommand('copy'); ok(); } catch (err) {} document.body.removeChild(ta); } } /* ---- share card (1080x1350) ---- */ function wrapText(ctx, text, x, y, maxW, lh) { var words = text.split(' '), line = '', lines = []; words.forEach(function (w) { var test = line + w + ' '; if (ctx.measureText(test).width > maxW && line) { lines.push(line.trim()); line = w + ' '; } else { line = test; } }); lines.push(line.trim()); lines.forEach(function (l, i) { ctx.fillText(l, x, y + i * lh); }); return y + lines.length * lh; } function makeCard(setup, punch, cb) { var c = document.createElement('canvas'); c.width = 1080; c.height = 1350; var ctx = c.getContext('2d'); ctx.fillStyle = '#fff8ec'; ctx.fillRect(0, 0, 1080, 1350); // border frame ctx.strokeStyle = '#2b2118'; ctx.lineWidth = 8; ctx.strokeRect(36, 36, 1008, 1278); // emoji ctx.font = '110px serif'; ctx.textAlign = 'center'; ctx.fillText('😂', 540, 240); // setup ctx.fillStyle = '#2b2118'; ctx.textAlign = 'center'; ctx.font = '700 54px ui-rounded, -apple-system, "Segoe UI", Arial, sans-serif'; var y = wrapText(ctx, setup, 540, 380, 880, 72); // punchline ctx.fillStyle = '#e4572e'; ctx.font = '800 66px ui-rounded, -apple-system, "Segoe UI", Arial, sans-serif'; y = wrapText(ctx, punch, 540, y + 150, 880, 86); // footer ctx.fillStyle = '#5c4f43'; ctx.font = '700 34px -apple-system, "Segoe UI", Arial, sans-serif'; ctx.fillText('BestDadJokes.lol', 540, 1240); cb(c); } function shareCard(setup, punch) { var name = 'dad-joke.png'; makeCard(setup, punch, function (canvas) { if (navigator.canShare && navigator.share) { canvas.toBlob(function (blob) { if (!blob) return; var file = new File([blob], name, { type: 'image/png' }); if (navigator.canShare({ files: [file] })) { navigator.share({ files: [file], title: 'A dad joke for you' }).catch(function () {}); } }, 'image/png'); } else { var a = document.createElement('a'); a.download = name; a.href = canvas.toDataURL('image/png'); document.body.appendChild(a); a.click(); document.body.removeChild(a); } }); } function wireCard(opts) { var setupEl = $(opts.setup), punchEl = $(opts.punch); if (!setupEl || !punchEl) return; var current = opts.initial || null; if (opts.nextBtn) { $(opts.nextBtn).addEventListener('click', function () { current = fillRandom(setupEl, punchEl); }); } if (opts.copyBtn) { $(opts.copyBtn).addEventListener('click', function (e) { if (current) copyText(current.s + ' ' + current.p, e.target); }); } if (opts.shareBtn) { $(opts.shareBtn).addEventListener('click', function () { if (current) shareCard(current.s, current.p); }); } return { get: function () { return current; }, set: function (j) { current = j; setupEl.textContent = j.s; punchEl.textContent = j.p; punchEl.classList.add('revealed'); punchEl.setAttribute('data-no-blur', ''); } }; } /* ---- page-specific wiring ---- */ // hero var hero = wireCard({ setup: '[data-hero-setup]', punch: '[data-hero-punch]', nextBtn: '[data-hero-next]', copyBtn: '[data-copy-hero]', shareBtn: '[data-share-hero]' }); if (hero) hero.set(randomJoke()); // generator wireCard({ setup: '[data-gen-setup]', punch: '[data-gen-punch]', nextBtn: '[data-gen-next]', copyBtn: '[data-gen-copy]', shareBtn: '[data-gen-share]' }); // joke of the day (+ ?d= override for archive permalinks) var jodSetup = $('[data-jod-setup]'); if (jodSetup) { var m = /[?&]d=(\d{4}-\d{2}-\d{2})/.exec(location.search); var base = new Date(Date.UTC(2026, 8, 15)); // launch epoch for the rotation var jod = null; if (m) { var parts = m[1].split('-'), d = new Date(Date.UTC(+parts[0], +parts[1] - 1, +parts[2])); if (!isNaN(d.getTime())) { var idx = Math.floor((d - new Date(d.getUTCFullYear(), 0, 1)) / 86400000) + d.getUTCMonth() * 31 + d.getUTCDate(); jod = JOKES[(d.getTime() / 86400000 | 0) % JOKES.length] || JOKES[0]; $('[data-jod-date]').textContent = d.toUTCString().slice(0, 16); var ctl = { setup: '[data-jod-setup]', punch: '[data-jod-punch]' }; jodSetup.textContent = jod.s; $('[data-jod-punch]').textContent = jod.p; $('[data-jod-punch]').classList.add('revealed'); $('[data-jod-punch]').setAttribute('data-no-blur', ''); } } var jodCopy = $('[data-jod-copy]'); if (jodCopy) { var punchEl = $('[data-jod-punch]'); jodCopy.addEventListener('click', function (e) { copyText(jodSetup.textContent + ' ' + punchEl.textContent, e.target); }); } var jodShare = $('[data-jod-share]'); if (jodShare) { jodShare.addEventListener('click', function () { shareCard(jodSetup.textContent, $('[data-jod-punch]').textContent); }); } // archive: last 30 days var arch = $('[data-jod-archive]'); if (arch && JOKES.length) { var today = new Date(); var html = ''; for (var i = 1; i <= 30; i++) { var dd = new Date(today.getTime() - i * 86400000); var iso = dd.toISOString().slice(0, 10); var jj = JOKES[Math.floor(dd.getTime() / 86400000) % JOKES.length]; html += '

' + iso + '

' + '

' + jj.s.replace(/' + '

' + jj.p.replace(/
'; } arch.innerHTML = html; } } /* ---- per-card copy/share buttons ---- */ document.addEventListener('click', function (e) { var t = e.target; if (t.hasAttribute && t.hasAttribute('data-copy')) { var j = byId(+t.getAttribute('data-copy')); if (j) copyText(j.s + ' ' + j.p, t); } if (t.hasAttribute && t.hasAttribute('data-share')) { var jj = byId(+t.getAttribute('data-share')); if (jj) shareCard(jj.s, jj.p); } }); /* ---- search ---- */ var box = $('#search-box'); if (box) { var results = $('[data-search-results]'); var countEl = $('[data-search-count]'); var emptyEl = $('[data-search-empty]'); function renderResults(q) { q = q.trim().toLowerCase(); var hits = []; if (q.length > 1) { hits = JOKES.filter(function (j) { return (j.s + ' ' + j.p).toLowerCase().indexOf(q) !== -1; }).slice(0, 60); } countEl.textContent = q.length > 1 ? hits.length + ' joke' + (hits.length === 1 ? '' : 's') + ' matching "' + q + '"' : ''; emptyEl.style.display = (q.length > 1 && !hits.length) ? 'block' : 'none'; results.innerHTML = hits.map(function (j) { return '

' + j.s.replace(/' + '

' + j.p.replace(/' + '
' + 'Category →
'; }).join(''); } box.addEventListener('input', function () { renderResults(box.value); }); var q = /[?&]q=([^&]*)/.exec(location.search); if (q) { box.value = decodeURIComponent(q[1].replace(/\+/g, ' ')); } renderResults(box.value); box.focus(); } /* ---- close mobile nav on selection ---- */ $$('.site-nav a').forEach(function (a) { a.addEventListener('click', function () { var t = $('#navtoggle'); if (t) t.checked = false; }); }); })();