diff --git a/public/page-qr.js b/public/page-qr.js new file mode 100644 index 0000000..0fc435c --- /dev/null +++ b/public/page-qr.js @@ -0,0 +1,31 @@ +// Draws the QR on a member's hosted page (/p/ and /p//). +// +// This lives in its own file rather than inline in the rendered HTML for one +// reason: the site's CSP is `script-src 'self'` with no 'unsafe-inline', so an +// inline bootstrap is silently blocked and the QR box renders as an empty white +// square. Nothing errors visibly — the page just quietly loses its QR, which is +// exactly the sort of failure nobody notices until a printed flyer or an ad +// lands somewhere and cannot be scanned. +// +// The link comes from a data attribute so no page data is ever interpolated +// into executable script. +(function () { + 'use strict'; + function draw() { + var el = document.getElementById('ppQr'); + if (!el) return; + var link = el.getAttribute('data-link'); + if (!link || typeof qrcode !== 'function') return; + try { + var q = qrcode(0, 'M'); + q.addData(link); + q.make(); + el.innerHTML = q.createSvgTag({ cellSize: 4, margin: 2, scalable: true }); + } catch (e) { /* leave the box empty rather than break the page */ } + } + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', draw); + } else { + draw(); + } +})(); diff --git a/suite-pages.js b/suite-pages.js index aed0fb2..c5dd6d5 100644 --- a/suite-pages.js +++ b/suite-pages.js @@ -157,11 +157,11 @@ function render(rec) { (bullets ? '
    ' + bullets + '
' : '') + '

' + esc(c.closing || 'Take a look and see what you think.') + '

' + 'See how it works →' + - '
or scan · ' + esc(link.replace(/^https:\/\//, '')) + '
' + + '
or scan · ' + esc(link.replace(/^https:\/\//, '')) + '
' + '
Independent team resource shared by an individual member. Participation takes real effort and involves cryptocurrency risk, including risk of total loss. No income is guaranteed. ' + 'Disclaimers · How the contract works
' + '' + - '' + + '' + '' + ''; }