Fix the creation of DOM elements from a HTML string
authorAlexander Ebert <ebert@woltlab.com>
Mon, 14 Nov 2022 14:26:03 +0000 (15:26 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Mon, 14 Nov 2022 14:26:03 +0000 (15:26 +0100)
The naive approach of using `innerHTML` does not work for script tags. These are only recognized when they are manually inserted into the DOM for security reasons.

ts/WoltLabSuite/Core/Component/Dialog/Setup.ts
wcfsetup/install/files/js/WoltLabSuite/Core/Component/Dialog/Setup.js

index 024f76d41d8c61a0942f8d8f1dacaeedb70ad0df..44a620d1ed1d9e971a5e362f6cd7e7d2dbfbf996 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 import DialogControls from "./Controls";
+import * as DomUtil from "../../Dom/Util";
 
 export class DialogSetup {
   fromElement(element: HTMLElement | DocumentFragment): DialogControls {
@@ -33,15 +34,11 @@ export class DialogSetup {
   }
 
   fromHtml(html: string): DialogControls {
-    const element = document.createElement("div");
-    element.innerHTML = html;
-    if (element.childElementCount === 0 && element.textContent!.trim() === "") {
+    const fragment = DomUtil.createFragmentFromHtml(html);
+    if (fragment.childElementCount === 0 && fragment.textContent!.trim() === "") {
       throw new TypeError("The provided HTML string was empty.");
     }
 
-    const fragment = document.createDocumentFragment();
-    fragment.append(...element.childNodes);
-
     return this.fromElement(fragment);
   }
 
index 532cea23b71ea00f432e4247b66505e5c766188b..2c58cfe622cddb73caf1c0d091d6244e3ad8059b 100644 (file)
@@ -8,11 +8,12 @@
  * @module WoltLabSuite/Core/Component/Dialog/Setup
  * @since 6.0
  */
-define(["require", "exports", "tslib", "./Controls"], function (require, exports, tslib_1, Controls_1) {
+define(["require", "exports", "tslib", "./Controls", "../../Dom/Util"], function (require, exports, tslib_1, Controls_1, DomUtil) {
     "use strict";
     Object.defineProperty(exports, "__esModule", { value: true });
     exports.DialogSetup = void 0;
     Controls_1 = tslib_1.__importDefault(Controls_1);
+    DomUtil = tslib_1.__importStar(DomUtil);
     class DialogSetup {
         fromElement(element) {
             if (element instanceof HTMLTemplateElement) {
@@ -30,13 +31,10 @@ define(["require", "exports", "tslib", "./Controls"], function (require, exports
             return this.fromElement(element);
         }
         fromHtml(html) {
-            const element = document.createElement("div");
-            element.innerHTML = html;
-            if (element.childElementCount === 0 && element.textContent.trim() === "") {
+            const fragment = DomUtil.createFragmentFromHtml(html);
+            if (fragment.childElementCount === 0 && fragment.textContent.trim() === "") {
                 throw new TypeError("The provided HTML string was empty.");
             }
-            const fragment = document.createDocumentFragment();
-            fragment.append(...element.childNodes);
             return this.fromElement(fragment);
         }
         withoutContent() {