diff --git a/main.js b/main.js index 166dddd..f6d84e2 100644 --- a/main.js +++ b/main.js @@ -42,7 +42,41 @@ const queryWarningElement = document.querySelector("#query-warning"); const qrCodeImage = document.querySelector("#qrcode"); const qrCodeCorrectionLevelContainer = document.querySelector("#qr-correct-level-container"); const qrCodeCorrectionLevelElement = document.querySelector("#qr-correct-level"); -qrCodeCorrectionLevelElement.addEventListener("change", updateOutput); + +let qrCorrectionManuallySet = false; + +qrCodeCorrectionLevelElement.addEventListener("change", () => { + qrCorrectionManuallySet = true; + updateOutput(); +}); + +function getOptimalErrorCorrectionLevel (text) { + const levels = ["M", "Q", "H"]; + + const baseVersion = QRCode.create(text, { + errorCorrectionLevel: levels[0] + }).version; + + let optimalLevel = levels[0]; + + for (const level of levels.slice(1)) { + try { + const candidate = QRCode.create(text, { + errorCorrectionLevel: level + }); + + if (candidate.version > baseVersion) { + break; + } + + optimalLevel = level; + } catch { + break; + } + } + + return optimalLevel; +} function updateOutput () { const input = inputLinkElement.value.trim(); @@ -86,10 +120,21 @@ function updateOutput () { outputLinkElement.href = `http://ha.mr#${output}`; outputLinkElement.style.color = ""; if (settings.qr) { - const errorCorrection = ["L", "M", "Q", "H"][qrCodeCorrectionLevelElement.value]; + const correctionLevels = ["L", "M", "Q", "H"]; + qrCodeImage.style.display = "inline"; qrCodeCorrectionLevelContainer.style.display = "inline"; - let qrCodeLink = `HTTP://HA.MR/${compress(input, outputAlphabetQR)}`; + + const qrCodeLink = `HTTP://HA.MR/${compress(input, outputAlphabetQR)}`; + + if (!qrCorrectionManuallySet) { + const optimalLevel = getOptimalErrorCorrectionLevel(qrCodeLink); + qrCodeCorrectionLevelElement.value = correctionLevels.indexOf(optimalLevel); + } + + const errorCorrection = + correctionLevels[qrCodeCorrectionLevelElement.value]; + QRCode.toDataURL(qrCodeLink, { errorCorrectionLevel: errorCorrection, scale: 8 @@ -121,7 +166,11 @@ function updateOutput () { queryWarningElement.style.display = "none"; } } -inputLinkElement.addEventListener("input", updateOutput); + +inputLinkElement.addEventListener("input", () => { + qrCorrectionManuallySet = false; + updateOutput(); +}); (() => { let payload = null;