diff --git a/script.js b/script.js index c91a53b..4c6c3ec 100644 --- a/script.js +++ b/script.js @@ -3,13 +3,13 @@ document.addEventListener('DOMContentLoaded', () => { const qrContainer = document.getElementById('qr-container'); const downloadBtn = document.getElementById('btn-download'); const stickyWrapper = document.querySelector('.sticky-wrapper'); - + // Gauge Elements const capMeter = document.getElementById('capacity-meter'); const capBar = document.getElementById('capacity-bar'); const capText = document.getElementById('capacity-text'); const capLabel = document.getElementById('capacity-label'); - + // Inputs const modeSelector = document.getElementById('mode-selector'); const optEcc = document.getElementById('opt-ecc'); @@ -18,7 +18,7 @@ document.addEventListener('DOMContentLoaded', () => { const optBg = document.getElementById('opt-bg'); const hexFg = document.getElementById('hex-fg'); const hexBg = document.getElementById('hex-bg'); - + const fmtRadios = document.getElementsByName('opt-fmt'); let debounceTimer; @@ -41,7 +41,7 @@ document.addEventListener('DOMContentLoaded', () => { const pass = document.getElementById('inp-wifi-pass').value; const type = document.getElementById('inp-wifi-type').value; // Note: Even if empty, we return the structure so the logic can decide - if (!ssid) return ''; + if (!ssid) return ''; const cleanSSID = ssid.replace(/([\\;,:])/g, '\\$1'); const cleanPass = pass.replace(/([\\;,:])/g, '\\$1'); return `WIFI:S:${cleanSSID};T:${type};P:${cleanPass};;`; @@ -67,7 +67,7 @@ document.addEventListener('DOMContentLoaded', () => { if (modules[r][c]) { const x = c * modSize; const y = r * modSize; - pathData += `M${x},${y}h${modSize}v${modSize}h-${modSize}z`; + pathData += `M${x},${y}h${modSize}v${modSize}h-${modSize}z`; } } } @@ -80,12 +80,12 @@ document.addEventListener('DOMContentLoaded', () => { `; } - function renderError() { + function renderError(title, subtitle) { qrContainer.innerHTML = `
- ERROR: CAPACITY EXCEEDED
+ ERROR: ${title}
- REDUCE TEXT OR
LOWER ECC LEVEL + ${subtitle}
`; @@ -105,18 +105,18 @@ document.addEventListener('DOMContentLoaded', () => { const blob = new Blob([textData]); const bytes = blob.size; - + // Limits based on Version 40 (Byte Mode) const maxCapacityMap = { 'L': 2950, 'M': 2328, 'Q': 1660, 'H': 1270 }; const maxBytes = maxCapacityMap[optEcc.value] || 1270; - + const raw_usage = Math.round((bytes / maxBytes) * 100); const usage = Math.min(100, raw_usage); if (usage > 50) { capMeter.style.display = 'block'; capBar.style.width = `${usage}%`; - + capText.textContent = `${usage}% (${bytes} / ${maxBytes} B)`; if (raw_usage <= 100) { @@ -124,7 +124,7 @@ document.addEventListener('DOMContentLoaded', () => { } else { capLabel.textContent = 'OVER CAPACITY'; } - + if (usage > 90) { capBar.style.backgroundColor = 'red'; capText.style.color = 'red'; @@ -137,7 +137,7 @@ document.addEventListener('DOMContentLoaded', () => { } } - // B. The Main Renderer (Stateless: Flush and Rebuild) +// B. The Main Renderer (Stateless: Flush and Rebuild) function renderQR() { // 1. Gather State const textData = getDataString(); @@ -145,8 +145,7 @@ document.addEventListener('DOMContentLoaded', () => { const ecc = QRCode.CorrectLevel[optEcc.value]; const colorDark = optFg.value; const colorLight = optBg.value; - - // Update Hex Labels + hexFg.textContent = colorDark; hexBg.textContent = colorLight; @@ -158,22 +157,20 @@ document.addEventListener('DOMContentLoaded', () => { if (!textData || textData.trim() === '') { downloadBtn.disabled = true; downloadBtn.textContent = `DOWNLOAD ${format.toUpperCase()}`; - return; // Stop here. Container is clean. + return; } downloadBtn.textContent = `DOWNLOAD ${format.toUpperCase()}`; - // 4. Validate Size (Prevent Crashes) + // 4. Validate Size let size = parseInt(optSize.value) || 256; if (size < 64) size = 64; if (size > 4000) size = 4000; // 5. Generate try { - // We create a local instance. It populates qrContainer with a Canvas/Img. - // We do not save this instance globally. It is single-use. const instance = new QRCode(qrContainer, { - text: textData, // Passing text here triggers makeCode immediately + text: textData, width: size, height: size, colorDark : colorDark, @@ -181,25 +178,17 @@ document.addEventListener('DOMContentLoaded', () => { correctLevel : ecc }); - // 6. Post-Process (Swap to SVG if needed) + // 6. Post-Process if (format === 'svg') { - // The library just painted a canvas. We hide it and inject SVG. - // We use the internal data of our local 'instance' const modules = instance._oQRCode.modules; - - // Hide library output const nodes = qrContainer.childNodes; for(let i=0; i. We are done. - // Just ensure it's visible (library defaults to display:none sometimes for the img) const img = qrContainer.querySelector('img'); if(img) img.style.display = 'block'; } @@ -207,10 +196,31 @@ document.addEventListener('DOMContentLoaded', () => { downloadBtn.disabled = false; } catch (e) { - console.log(e) - // 7. Handle Overflow/Errors - // Since we flushed the DOM at the start, we can just render the error now. - renderError(); + // 7. Smart Error Handling + + // Calculate usage to guess the error type + const blob = new Blob([textData]); + const bytes = blob.size; + const maxCapacityMap = { 'L': 2953, 'M': 2331, 'Q': 1663, 'H': 1273 }; + const maxBytes = maxCapacityMap[optEcc.value] || 1273; + + // If we are over (or extremely close to) the limit, it's definitely a capacity issue. + // (We use >= because sometimes overhead pushes it over even if bytes == maxBytes) + if (bytes >= maxBytes) { + renderError( + "CAPACITY EXCEEDED", + "REDUCE TEXT OR LOWER ECC LEVEL" + ); + } + else { + // If usage is low but it crashed, it's a real bug (e.g. invalid char code). + // Show the specific error for debugging. + console.error(e); // Keep looking at console for devs + renderError( + "UNKNOWN ERROR", + `CODE: ${e.name || 'Except'} // ${e.message || 'Check Console'}` + ); + } } } @@ -218,7 +228,7 @@ document.addEventListener('DOMContentLoaded', () => { function handleUpdate(immediate = false) { const text = getDataString(); - + // Always update gauge immediately updateCapacityUI(text); @@ -257,7 +267,7 @@ document.addEventListener('DOMContentLoaded', () => { // Download Handler downloadBtn.addEventListener('click', () => { const format = getFormat(); - + if (format === 'png') { const img = qrContainer.querySelector('img'); if (img && img.src) {