Improve exception handling
This commit is contained in:
82
script.js
82
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 = `
|
||||
<div class="qr-error-msg">
|
||||
ERROR: CAPACITY EXCEEDED<br>
|
||||
ERROR: ${title}<br>
|
||||
<span style="font-size:0.7em; opacity:0.8; display:block; margin-top:0.5rem;">
|
||||
REDUCE TEXT OR<br>LOWER ECC LEVEL
|
||||
${subtitle}
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
@@ -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<nodes.length; i++) {
|
||||
if(nodes[i].style) nodes[i].style.display = 'none';
|
||||
}
|
||||
|
||||
// Inject SVG
|
||||
const svgString = generateSVGString(modules, size, colorDark, colorLight);
|
||||
qrContainer.insertAdjacentHTML('beforeend', svgString);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// PNG Mode: The library already appended an <img>. 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) {
|
||||
|
||||
Reference in New Issue
Block a user