From c332881ed5d0ad35ce2b633abcbc8516cf59aa9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joni=20Ha=CC=88ma=CC=88la=CC=88inen?= Date: Wed, 23 Aug 2023 14:23:30 +0300 Subject: [PATCH] replace innerHTML with TT friendly ways This will enable usage in [Trusted Types](https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types_API) context. As Element.innerHTML is considered to be dangerous injection sink, its usage is denied when `Content-Security-Policy` enforces `require-trusted-types-for 'script'` directive. E.g. it throws something like this from `clearElement` function: ``` TypeError: Failed to set the 'innerHTML' property on 'Element': This document requires 'TrustedHTML' assignment. at D.clearElement (xyz.js:733:62) at D.start (xyz.js:710:176) ``` [textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent#differences_from_innerhtml) in MDN. [replaceChildren](https://developer.mozilla.org/en-US/docs/Web/API/Element/replaceChildren) has [~91% coverage](https://caniuse.com/mdn-api_element_replacechildren) --- src/html5-qrcode-scanner.ts | 22 ++++++++++---------- src/html5-qrcode.ts | 2 +- tests/ui/scanner/camera-selection-ui.test.ts | 10 ++++----- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/html5-qrcode-scanner.ts b/src/html5-qrcode-scanner.ts index 028262f..019bd73 100644 --- a/src/html5-qrcode-scanner.ts +++ b/src/html5-qrcode-scanner.ts @@ -272,7 +272,7 @@ export class Html5QrcodeScanner { if (!container) { throw `HTML Element with id=${this.elementId} not found`; } - container.innerHTML = ""; + container.textContent = ""; this.createBasicLayout(container!); this.html5Qrcode = new Html5Qrcode( this.getScanRegionId(), @@ -336,7 +336,7 @@ export class Html5QrcodeScanner { const emptyHtmlContainer = () => { const mainContainer = document.getElementById(this.elementId); if (mainContainer) { - mainContainer.innerHTML = ""; + mainContainer.textContent = ""; this.resetBasicLayout(mainContainer); } } @@ -1047,15 +1047,15 @@ export class Html5QrcodeScanner { this.getScanRegionId())!; if (this.cameraScanImage) { - qrCodeScanRegion.innerHTML = "
"; - qrCodeScanRegion.appendChild(this.cameraScanImage); + const br = document.createElement("br"); + qrCodeScanRegion.replaceChildren(br, this.cameraScanImage); return; } this.cameraScanImage = new Image; this.cameraScanImage.onload = (_) => { - qrCodeScanRegion.innerHTML = "
"; - qrCodeScanRegion.appendChild($this.cameraScanImage!); + const br = document.createElement("br"); + qrCodeScanRegion.replaceChildren(br, $this.cameraScanImage!); } this.cameraScanImage.width = 64; this.cameraScanImage.style.opacity = "0.8"; @@ -1069,15 +1069,15 @@ export class Html5QrcodeScanner { this.getScanRegionId())!; if (this.fileScanImage) { - qrCodeScanRegion.innerHTML = "
"; - qrCodeScanRegion.appendChild(this.fileScanImage); + const br = document.createElement("br"); + qrCodeScanRegion.replaceChildren(br, this.fileScanImage); return; } this.fileScanImage = new Image; this.fileScanImage.onload = (_) => { - qrCodeScanRegion.innerHTML = "
"; - qrCodeScanRegion.appendChild($this.fileScanImage!); + const br = document.createElement("br"); + qrCodeScanRegion.replaceChildren(br, $this.fileScanImage!); } this.fileScanImage.width = 64; this.fileScanImage.style.opacity = "0.8"; @@ -1088,7 +1088,7 @@ export class Html5QrcodeScanner { private clearScanRegion() { const qrCodeScanRegion = document.getElementById( this.getScanRegionId())!; - qrCodeScanRegion.innerHTML = ""; + qrCodeScanRegion.textContent = ""; } //#region state getters diff --git a/src/html5-qrcode.ts b/src/html5-qrcode.ts index b3fcbda..be71f41 100644 --- a/src/html5-qrcode.ts +++ b/src/html5-qrcode.ts @@ -1380,7 +1380,7 @@ export class Html5Qrcode { } const element = document.getElementById(this.elementId); if (element) { - element.innerHTML = ""; + element.textContent = ""; } } diff --git a/tests/ui/scanner/camera-selection-ui.test.ts b/tests/ui/scanner/camera-selection-ui.test.ts index 2289618..fa8f70c 100644 --- a/tests/ui/scanner/camera-selection-ui.test.ts +++ b/tests/ui/scanner/camera-selection-ui.test.ts @@ -22,7 +22,7 @@ describe("CameraSelectionUi#create()", () => { after(() => { document.body.removeChild(parentElement!); - parentElement!.innerHTML = ""; + parentElement!.textContent = ""; parentElement = undefined; }); @@ -40,7 +40,7 @@ describe("CameraSelectionUi#create()", () => { }); it("Single cameras, creates the camera selection", () => { - parentElement!.innerHTML = ""; + parentElement!.textContent = ""; let numCameras = 1; let cameras = createCameraList(numCameras); let cameraSelectUi = CameraSelectionUi.create(parentElement!, cameras); @@ -58,7 +58,7 @@ describe("CameraSelectionUi#create()", () => { let cameras = createCameraList(numCameras); expect(() => { let _ = CameraSelectionUi.create(parentElement!, cameras); - }).to.throw(); + }).to.throw(); }); }); @@ -72,7 +72,7 @@ describe("CameraSelectionUi#enable() & disable()", () => { after(() => { document.body.removeChild(parentElement!); - parentElement!.innerHTML = ""; + parentElement!.textContent = ""; parentElement = undefined; }); @@ -113,7 +113,7 @@ describe("CameraSelectionUi setting and getting values", () => { after(() => { document.body.removeChild(parentElement!); - parentElement!.innerHTML = ""; + parentElement!.textContent = ""; parentElement = undefined; });