From b2654761be234449b2335127dfa5798c88e70a55 Mon Sep 17 00:00:00 2001
From: Andreas Kienast <a.fernandez@scripting-base.de>
Date: Tue, 4 Jun 2024 11:37:55 +0200
Subject: [PATCH] [BUGFIX] IRRE: Rewrite stylesheet loading sequence

The stylesheet loading process in IRRE was kept for several years and
moved from version to version. A recent change in #103375 migrated a
usage of `delete` to `.splice()`, breaking stylesheet loading as the
original iterated object was modified.

Since the code was quite dated and had other potental bugs, the whole
loading sequence has been transformed to functional programming style
to reduce complicated, potentially error-prone, array operations.

Resolves: #103971
Related: #103375
Releases: main, 12.4
Change-Id: I18caafc68ceebce53723b7208270043faafc7458
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/84487
Tested-by: rogier Helmer <rogier.helmer@maxserv.com>
Tested-by: core-ci <typo3@b13.com>
Reviewed-by: rogier Helmer <rogier.helmer@maxserv.com>
Tested-by: Benjamin Franzke <ben@bnf.dev>
Reviewed-by: Benjamin Franzke <ben@bnf.dev>
---
 .../inline-relation/ajax-dispatcher.ts        | 21 ++++++++-----------
 .../inline-relation/ajax-dispatcher.js        |  2 +-
 2 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/Build/Sources/TypeScript/backend/form-engine/inline-relation/ajax-dispatcher.ts b/Build/Sources/TypeScript/backend/form-engine/inline-relation/ajax-dispatcher.ts
index e510428c68e8..0def5b5207bf 100644
--- a/Build/Sources/TypeScript/backend/form-engine/inline-relation/ajax-dispatcher.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/inline-relation/ajax-dispatcher.ts
@@ -98,19 +98,16 @@ export class AjaxDispatcher {
       }
     }
 
-    // If there are elements they should be added to the <HEAD> tag (e.g. for RTEhtmlarea):
     if (json.stylesheetFiles) {
-      for (const [index, stylesheetFile] of json.stylesheetFiles.entries()) {
-        if (!stylesheetFile) {
-          break;
-        }
-        const element = document.createElement('link');
-        element.rel = 'stylesheet';
-        element.type = 'text/css';
-        element.href = stylesheetFile;
-        document.querySelector('head').appendChild(element);
-        json.stylesheetFiles.splice(index, 1);
-      }
+      document.querySelector('head').append(
+        ...json.stylesheetFiles.filter(file => file).map(file => {
+          const element = document.createElement('link');
+          element.rel = 'stylesheet';
+          element.type = 'text/css';
+          element.href = file;
+          return element;
+        })
+      );
     }
 
     if (typeof json.inlineData === 'object') {
diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/form-engine/inline-relation/ajax-dispatcher.js b/typo3/sysext/backend/Resources/Public/JavaScript/form-engine/inline-relation/ajax-dispatcher.js
index c9d74db24841..83f316bcfa2c 100644
--- a/typo3/sysext/backend/Resources/Public/JavaScript/form-engine/inline-relation/ajax-dispatcher.js
+++ b/typo3/sysext/backend/Resources/Public/JavaScript/form-engine/inline-relation/ajax-dispatcher.js
@@ -10,4 +10,4 @@
  *
  * The TYPO3 project - inspiring people to share!
  */
-import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import{JavaScriptItemProcessor}from"@typo3/core/java-script-item-processor.js";import Notification from"@typo3/backend/notification.js";import Utility from"@typo3/backend/utility.js";export class AjaxDispatcher{constructor(e){this.objectGroup=null,this.objectGroup=e}newRequest(e){return new AjaxRequest(e)}getEndpoint(e){if(void 0!==TYPO3.settings.ajaxUrls[e])return TYPO3.settings.ajaxUrls[e];throw'Undefined endpoint for route "'+e+'"'}send(e,t){const s=e.post(this.createRequestBody(t)).then((async e=>this.processResponse(await e.resolve())));return s.catch((e=>{Notification.error("Error "+e.message)})),s}createRequestBody(e){const t={};for(let s=0;s<e.length;s++)t["ajax["+s+"]"]=e[s];return t["ajax[context]"]=JSON.stringify(this.getContext()),t}getContext(){let e;return void 0!==TYPO3.settings.FormEngineInline.config[this.objectGroup]&&void 0!==TYPO3.settings.FormEngineInline.config[this.objectGroup].context&&(e=TYPO3.settings.FormEngineInline.config[this.objectGroup].context),e}processResponse(e){if(e.hasErrors)for(const t of e.messages)Notification.error(t.title,t.message);if(e.stylesheetFiles)for(const[t,s]of e.stylesheetFiles.entries()){if(!s)break;const o=document.createElement("link");o.rel="stylesheet",o.type="text/css",o.href=s,document.querySelector("head").appendChild(o),e.stylesheetFiles.splice(t,1)}if("object"==typeof e.inlineData&&(TYPO3.settings.FormEngineInline=Utility.mergeDeep(TYPO3.settings.FormEngineInline,e.inlineData)),e.scriptItems instanceof Array&&e.scriptItems.length>0){(new JavaScriptItemProcessor).processItems(e.scriptItems)}return e}}
\ No newline at end of file
+import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import{JavaScriptItemProcessor}from"@typo3/core/java-script-item-processor.js";import Notification from"@typo3/backend/notification.js";import Utility from"@typo3/backend/utility.js";export class AjaxDispatcher{constructor(e){this.objectGroup=null,this.objectGroup=e}newRequest(e){return new AjaxRequest(e)}getEndpoint(e){if(void 0!==TYPO3.settings.ajaxUrls[e])return TYPO3.settings.ajaxUrls[e];throw'Undefined endpoint for route "'+e+'"'}send(e,t){const s=e.post(this.createRequestBody(t)).then((async e=>this.processResponse(await e.resolve())));return s.catch((e=>{Notification.error("Error "+e.message)})),s}createRequestBody(e){const t={};for(let s=0;s<e.length;s++)t["ajax["+s+"]"]=e[s];return t["ajax[context]"]=JSON.stringify(this.getContext()),t}getContext(){let e;return void 0!==TYPO3.settings.FormEngineInline.config[this.objectGroup]&&void 0!==TYPO3.settings.FormEngineInline.config[this.objectGroup].context&&(e=TYPO3.settings.FormEngineInline.config[this.objectGroup].context),e}processResponse(e){if(e.hasErrors)for(const t of e.messages)Notification.error(t.title,t.message);if(e.stylesheetFiles&&document.querySelector("head").append(...e.stylesheetFiles.filter((e=>e)).map((e=>{const t=document.createElement("link");return t.rel="stylesheet",t.type="text/css",t.href=e,t}))),"object"==typeof e.inlineData&&(TYPO3.settings.FormEngineInline=Utility.mergeDeep(TYPO3.settings.FormEngineInline,e.inlineData)),e.scriptItems instanceof Array&&e.scriptItems.length>0){(new JavaScriptItemProcessor).processItems(e.scriptItems)}return e}}
\ No newline at end of file
-- 
GitLab