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");
+ });
+});