From 5b4c0b926b48cc2ae02fc737e411bf82fc89176f Mon Sep 17 00:00:00 2001
From: Andreas Fernandez <a.fernandez@scripting-base.de>
Date: Fri, 19 Aug 2022 11:02:28 +0200
Subject: [PATCH] [BUGFIX] Convert Node to DocumentFragment for modal
 consumption in EXT:dashboard

The patches #98164 and #98165 conflicted with each other as one made
the modal API stricter while the other populated the modal with a
soon-to-be invalid configuration. This currently breaks all subsequent
builds.

The modals received objects of type `Node` which are not consumable by
jQuery's `append()` method. To solve this issue, `Node` is now converted
to a `DocumentFragment`, which can be consumed by all involved parties.

Resolves: #98177
Related: #98164
Related: #98165
Releases: main
Change-Id: I4524b383e559d3b1342c0bf95e435caec6d36cc6
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/75517
Tested-by: core-ci <typo3@b13.com>
Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
---
 Build/Sources/TypeScript/dashboard/dashboard-modal.ts       | 6 +++++-
 Build/Sources/TypeScript/dashboard/widget-selector.ts       | 6 +++++-
 .../Resources/Public/JavaScript/dashboard-modal.js          | 2 +-
 .../Resources/Public/JavaScript/widget-selector.js          | 2 +-
 4 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/Build/Sources/TypeScript/dashboard/dashboard-modal.ts b/Build/Sources/TypeScript/dashboard/dashboard-modal.ts
index 895a06ff3017..7e3ceb9b4ed4 100644
--- a/Build/Sources/TypeScript/dashboard/dashboard-modal.ts
+++ b/Build/Sources/TypeScript/dashboard/dashboard-modal.ts
@@ -26,12 +26,16 @@ class DashboardModal {
   public initialize(): void {
     new RegularEvent('click', function (this: HTMLElement, e: Event): void {
       e.preventDefault();
+
+      const modalContent = new DocumentFragment();
+      modalContent.append((document.getElementById(`dashboardModal-${this.dataset.modalIdentifier}`) as HTMLTemplateElement).content.cloneNode(true));
+
       const configuration = {
         type: Modal.types.default,
         title: this.dataset.modalTitle,
         size: Modal.sizes.medium,
         severity: SeverityEnum.notice,
-        content: (document.getElementById(`dashboardModal-${this.dataset.modalIdentifier}`) as HTMLTemplateElement).content.cloneNode(true),
+        content: modalContent,
         additionalCssClasses: ['dashboard-modal'],
         callback: (currentModal: any): void => {
           currentModal.on('submit', '.dashboardModal-form', (e: JQueryEventObject): void => {
diff --git a/Build/Sources/TypeScript/dashboard/widget-selector.ts b/Build/Sources/TypeScript/dashboard/widget-selector.ts
index 8828d83f615c..d2d2efae4eda 100644
--- a/Build/Sources/TypeScript/dashboard/widget-selector.ts
+++ b/Build/Sources/TypeScript/dashboard/widget-selector.ts
@@ -26,12 +26,16 @@ class WidgetSelector {
   public initialize(): void {
     new RegularEvent('click', function (this: HTMLElement, e: Event): void {
       e.preventDefault();
+
+      const modalContent = new DocumentFragment();
+      modalContent.append((document.getElementById('widgetSelector') as HTMLTemplateElement).content.cloneNode(true));
+
       const configuration = {
         type: Modal.types.default,
         title: this.dataset.modalTitle,
         size: Modal.sizes.medium,
         severity: SeverityEnum.notice,
-        content: (document.getElementById('widgetSelector') as HTMLTemplateElement).content.cloneNode(true),
+        content: modalContent,
         additionalCssClasses: ['dashboard-modal'],
         callback: (currentModal: JQuery): void => {
           currentModal.on('click', 'a.dashboard-modal-item-block', (e: JQueryEventObject): void => {
diff --git a/typo3/sysext/dashboard/Resources/Public/JavaScript/dashboard-modal.js b/typo3/sysext/dashboard/Resources/Public/JavaScript/dashboard-modal.js
index 3ae63b285230..31081f59614c 100644
--- a/typo3/sysext/dashboard/Resources/Public/JavaScript/dashboard-modal.js
+++ b/typo3/sysext/dashboard/Resources/Public/JavaScript/dashboard-modal.js
@@ -10,4 +10,4 @@
  *
  * The TYPO3 project - inspiring people to share!
  */
-import Modal from"@typo3/backend/modal.js";import{SeverityEnum}from"@typo3/backend/enum/severity.js";import RegularEvent from"@typo3/core/event/regular-event.js";class DashboardModal{constructor(){this.selector=".js-dashboard-modal",this.initialize()}initialize(){new RegularEvent("click",(function(t){t.preventDefault();const e={type:Modal.types.default,title:this.dataset.modalTitle,size:Modal.sizes.medium,severity:SeverityEnum.notice,content:document.getElementById("dashboardModal-"+this.dataset.modalIdentifier).content.cloneNode(!0),additionalCssClasses:["dashboard-modal"],callback:t=>{t.on("submit",".dashboardModal-form",e=>{t.trigger("modal-dismiss")}),t.on("button.clicked",e=>{if("save"===e.target.getAttribute("name")){t.find("form").trigger("submit")}else t.trigger("modal-dismiss")})},buttons:[{text:this.dataset.buttonCloseText,btnClass:"btn-default",name:"cancel"},{text:this.dataset.buttonOkText,active:!0,btnClass:"btn-info",name:"save"}]};Modal.advanced(e)})).delegateTo(document,this.selector)}}export default new DashboardModal;
\ No newline at end of file
+import Modal from"@typo3/backend/modal.js";import{SeverityEnum}from"@typo3/backend/enum/severity.js";import RegularEvent from"@typo3/core/event/regular-event.js";class DashboardModal{constructor(){this.selector=".js-dashboard-modal",this.initialize()}initialize(){new RegularEvent("click",(function(t){t.preventDefault();const e=new DocumentFragment;e.append(document.getElementById("dashboardModal-"+this.dataset.modalIdentifier).content.cloneNode(!0));const a={type:Modal.types.default,title:this.dataset.modalTitle,size:Modal.sizes.medium,severity:SeverityEnum.notice,content:e,additionalCssClasses:["dashboard-modal"],callback:t=>{t.on("submit",".dashboardModal-form",e=>{t.trigger("modal-dismiss")}),t.on("button.clicked",e=>{if("save"===e.target.getAttribute("name")){t.find("form").trigger("submit")}else t.trigger("modal-dismiss")})},buttons:[{text:this.dataset.buttonCloseText,btnClass:"btn-default",name:"cancel"},{text:this.dataset.buttonOkText,active:!0,btnClass:"btn-info",name:"save"}]};Modal.advanced(a)})).delegateTo(document,this.selector)}}export default new DashboardModal;
\ No newline at end of file
diff --git a/typo3/sysext/dashboard/Resources/Public/JavaScript/widget-selector.js b/typo3/sysext/dashboard/Resources/Public/JavaScript/widget-selector.js
index 826b15d7ef67..2f71b884b86d 100644
--- a/typo3/sysext/dashboard/Resources/Public/JavaScript/widget-selector.js
+++ b/typo3/sysext/dashboard/Resources/Public/JavaScript/widget-selector.js
@@ -10,4 +10,4 @@
  *
  * The TYPO3 project - inspiring people to share!
  */
-import Modal from"@typo3/backend/modal.js";import{SeverityEnum}from"@typo3/backend/enum/severity.js";import RegularEvent from"@typo3/core/event/regular-event.js";class WidgetSelector{constructor(){this.selector=".js-dashboard-addWidget",this.initialize()}initialize(){new RegularEvent("click",(function(e){e.preventDefault();const t={type:Modal.types.default,title:this.dataset.modalTitle,size:Modal.sizes.medium,severity:SeverityEnum.notice,content:document.getElementById("widgetSelector").content.cloneNode(!0),additionalCssClasses:["dashboard-modal"],callback:e=>{e.on("click","a.dashboard-modal-item-block",t=>{e.trigger("modal-dismiss")})}};Modal.advanced(t)})).delegateTo(document,this.selector),document.querySelectorAll(this.selector).forEach(e=>{e.classList.remove("hide")})}}export default new WidgetSelector;
\ No newline at end of file
+import Modal from"@typo3/backend/modal.js";import{SeverityEnum}from"@typo3/backend/enum/severity.js";import RegularEvent from"@typo3/core/event/regular-event.js";class WidgetSelector{constructor(){this.selector=".js-dashboard-addWidget",this.initialize()}initialize(){new RegularEvent("click",(function(e){e.preventDefault();const t=new DocumentFragment;t.append(document.getElementById("widgetSelector").content.cloneNode(!0));const o={type:Modal.types.default,title:this.dataset.modalTitle,size:Modal.sizes.medium,severity:SeverityEnum.notice,content:t,additionalCssClasses:["dashboard-modal"],callback:e=>{e.on("click","a.dashboard-modal-item-block",t=>{e.trigger("modal-dismiss")})}};Modal.advanced(o)})).delegateTo(document,this.selector),document.querySelectorAll(this.selector).forEach(e=>{e.classList.remove("hide")})}}export default new WidgetSelector;
\ No newline at end of file
-- 
GitLab