89 lines
3.0 KiB
HTML
89 lines
3.0 KiB
HTML
<!DOCTYPE html>
|
|
<!--
|
|
Embed endpoint for OnlyQR.
|
|
|
|
Static hosts (GitHub/Gitea/Codeberg Pages) serve this file for every unknown path,
|
|
so https://onlyqr.0n8.de/<text> renders a QR code for <text> and nothing else.
|
|
Meant to be embedded via <iframe>. (Note: the HTTP status is 404, which iframes ignore.)
|
|
|
|
Usage:
|
|
/<text> QR code for <text> (percent-decoded)
|
|
/<text>?color=ff0000 custom colour (hex without '#', or any CSS colour name)
|
|
|
|
Recommended: build the path with encodeURIComponent(text) so that '?', '#', '%' and
|
|
'/' inside the text survive unchanged. Unknown query parameters are kept as part of
|
|
the text, so /https://example.com/page?id=5&color=ff0000 encodes
|
|
"https://example.com/page?id=5" in red.
|
|
-->
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
<meta name="robots" content="noindex" />
|
|
<title>QR Code</title>
|
|
<style>
|
|
html, body { margin: 0; padding: 0; width: 100%; height: 100%; background: transparent; overflow: hidden; }
|
|
#qrcode { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; }
|
|
#qrcode svg { width: 100%; height: 100%; display: block; }
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<div id="qrcode"></div>
|
|
|
|
<!-- Absolute paths: this page is served under arbitrary (possibly nested) paths. -->
|
|
<script src="/qrcode.js"></script>
|
|
<script src="/qr-svg.js"></script>
|
|
<script>
|
|
(function() {
|
|
'use strict';
|
|
|
|
var DEFAULT_COLOR = '#004c93';
|
|
|
|
function safeDecode(s) {
|
|
try { return decodeURIComponent(s); } catch (e) { return s; }
|
|
}
|
|
|
|
function parseColor(value) {
|
|
if (!value) return DEFAULT_COLOR;
|
|
value = safeDecode(value).trim();
|
|
if (/^[0-9a-f]{3}([0-9a-f]{3})?([0-9a-f]{2})?$/i.test(value)) value = '#' + value;
|
|
return (window.CSS && CSS.supports('color', value)) ? value : DEFAULT_COLOR;
|
|
}
|
|
|
|
// Split the query string: "color" is ours, everything else belongs to the text.
|
|
var color = null;
|
|
var rest = [];
|
|
location.search.replace(/^\?/, '').split('&').forEach(function(part) {
|
|
if (!part) return;
|
|
if (/^color=/i.test(part)) color = part.slice(6);
|
|
else rest.push(part);
|
|
});
|
|
|
|
var raw = location.pathname.replace(/^\//, '') +
|
|
(rest.length ? '?' + rest.join('&') : '') +
|
|
location.hash;
|
|
var text = safeDecode(raw);
|
|
|
|
if (!text) return;
|
|
document.title = text;
|
|
|
|
var el = document.getElementById('qrcode');
|
|
new QRCode(el, { text: text, colorDark: parseColor(color) });
|
|
|
|
var svg = el.querySelector('svg');
|
|
if (svg) {
|
|
svg = optimizeQRSVG(svg);
|
|
// Let the SVG scale to the iframe instead of using fixed pixel dimensions.
|
|
svg.removeAttribute('width');
|
|
svg.removeAttribute('height');
|
|
svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');
|
|
svg.setAttribute('shape-rendering', 'crispEdges');
|
|
}
|
|
})();
|
|
</script>
|
|
</body>
|
|
|
|
</html>
|