diff --git a/js/utils/qrcode.js b/js/utils/qrcode.js index 5e1d7abd..b8e32b57 100644 --- a/js/utils/qrcode.js +++ b/js/utils/qrcode.js @@ -336,7 +336,9 @@ if (hasDocument) { var nCount = oQRCode.getModuleCount(); var nWidth = Math.floor(_htOption.width / nCount); var nHeight = Math.floor(_htOption.height / nCount); - var aHTML = ['']; + + var table = document.createElement("table"); + table.className = "qr-code__table"; updateQrCodeContainerStyles(_el, { colorDark: _htOption.colorDark, @@ -347,23 +349,27 @@ if (hasDocument) { }); for (var row = 0; row < nCount; row++) { - aHTML.push(''); + var tr = document.createElement("tr"); for (var col = 0; col < nCount; col++) { - var cellClass = oQRCode.isDark(row, col) + var td = document.createElement("td"); + td.className = oQRCode.isDark(row, col) ? "qr-code__cell qr-code__cell--dark" : "qr-code__cell"; - aHTML.push(''); + tr.appendChild(td); } - aHTML.push(''); + table.appendChild(tr); } - aHTML.push('
'); - _el.innerHTML = aHTML.join(''); + // Clear previous content + while (_el.firstChild) { + _el.removeChild(_el.firstChild); + } + _el.appendChild(table); // Fix the margin values as real size. - var elTable = _el.childNodes[0]; + var elTable = table; var nLeftMarginTable = (_htOption.width - (nCount * nWidth)) / 2; var nTopMarginTable = (_htOption.height - (nCount * nHeight)) / 2; @@ -378,7 +384,9 @@ if (hasDocument) { * Clear the QRCode */ Drawing.prototype.clear = function () { - this._el.innerHTML = ''; + while (this._el.firstChild) { + this._el.removeChild(this._el.firstChild); + } }; return Drawing; diff --git a/tests/qrcode_table_fallback.test.mjs b/tests/qrcode_table_fallback.test.mjs new file mode 100644 index 00000000..d2147d26 --- /dev/null +++ b/tests/qrcode_table_fallback.test.mjs @@ -0,0 +1,43 @@ +import { test, describe } from 'node:test'; +import assert from 'node:assert'; +import { JSDOM } from 'jsdom'; + +describe('QRCode Table Fallback', () => { + test('should generate table when Canvas is not supported', async () => { + const dom = new JSDOM(`
`); + + // Set up global environment for the library + global.document = dom.window.document; + global.window = dom.window; + global.HTMLStyleElement = dom.window.HTMLStyleElement; + global.HTMLElement = dom.window.HTMLElement; + global.WeakMap = dom.window.WeakMap || global.WeakMap; + global.Map = dom.window.Map || global.Map; + + // Ensure CanvasRenderingContext2D is NOT defined to trigger table fallback + delete global.CanvasRenderingContext2D; + delete global.window.CanvasRenderingContext2D; + + // Ensure we are not in SVG mode (JSDOM default is HTML) + + // Import the module dynamically + const { createQrCode } = await import('../js/utils/qrcode.js'); + + const el = global.document.getElementById('qrcode'); + + // Create QR code + createQrCode(el, { text: "test", width: 100, height: 100 }); + + // Verify table is used + const table = el.querySelector('table'); + assert.ok(table, "Table element should be created"); + assert.ok(table.classList.contains('qr-code__table'), "Table should have correct class"); + + // Check for table structure + const rows = table.querySelectorAll('tr'); + assert.ok(rows.length > 0, "Should have rows"); + + const cells = table.querySelectorAll('td'); + assert.ok(cells.length > 0, "Should have cells"); + }); +});