// QR render helper. Scans for any element with data-qr="" and renders // a Kazuhiko Arase qrcode-generator QR into it as inline . Size is // controlled via data-qr-size="N" (px square, default 96). Error-correction // level via data-qr-ec="L|M|Q|H" (default M). // // The qrcode-generator lib (loaded before this script) exposes a global // `qrcode()` factory: typeNumber 0 = auto, ec = 'L'|'M'|'Q'|'H'. (function () { function render(el) { var text = el.getAttribute('data-qr') || ''; if (!text) return; if (el.dataset.qrRendered === '1') return; var size = parseInt(el.getAttribute('data-qr-size') || '96', 10); var ec = el.getAttribute('data-qr-ec') || 'M'; try { var qr = qrcode(0, ec); qr.addData(text); qr.make(); // createImgTag(cellSize, margin) // 4-cell margin keeps the QR scannable per spec; cell size derived from // requested pixel size and module count. var modules = qr.getModuleCount(); var cellSize = Math.max(1, Math.floor(size / (modules + 8))); el.innerHTML = qr.createImgTag(cellSize, 4); el.dataset.qrRendered = '1'; el.title = 'Scan: ' + text; } catch (e) { el.textContent = '[QR error]'; } } function scan() { var nodes = document.querySelectorAll('[data-qr]'); for (var i = 0; i < nodes.length; i++) render(nodes[i]); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', scan); } else { scan(); } })();