Project

General

Profile

Actions

Bug #103971

closed

Ajax-dispatcher.ts fails to load all stylesheets when they are loaded through an inline-relation in backend

Added by rogier Helmer 6 months ago. Updated 4 months ago.

Status:
Closed
Priority:
Should have
Assignee:
-
Category:
Backend JavaScript
Start date:
2024-06-04
Due date:
% Done:

100%

Estimated time:
TYPO3 Version:
12
PHP Version:
8.1
Tags:
ajax-disapatcher inline-relation form-engine stylesheets
Complexity:
no-brainer
Is Regression:
Yes
Sprint Focus:

Description

We have a configuration in the backend. Where we have an accordion that can have multiple accordion items. Each accordion item can have multiple buttons. When you add a button to an accordion item, you can also select an icon for in that button. The icon can be selected using an custom styled input select.

When you open the accordion item, it will try to load all js and css required by the module. These are loaded dynamically through an ajax request. `ajax-dispather.ts` is used here to inject the relevant stylesheets. In my example it uses the following stylesheets.

  [
      "/_assets/937be57c7660e085d41e9dabf38b8aa1/Css/editor.css?1710839460",
      "/_assets/f5f6d48c4a9e67b540bea426607200c5/CSS/iconField.css" 
  ],

The issue is that only the first stylesheet is injected into the dom. So we're missing out on iconField.css.
I've debugged the issue, and found a bug in ajax-dispatcher.ts. And specifically in the function `processResponse`.

Here it's going wrong:

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

the line: json.stylesheetFiles.splice(index, 1); splices out an item from the array. But it modifies the array which is being looped through. This causes sideeffects. Which causes it to only inject the first item from the looped array.

The following code should fix it:

    if (json.stylesheetFiles && json.stylesheetFiles.length) {
      const copyStylesheetFiles = [...json.stylesheetFiles];

      for (const stylesheetFile of copyStylesheetFiles.values()) {
        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(json.stylesheetFiles.indexOf(stylesheetFile), 1);
      }
    }

I've created some unit tests, to replicate the issue.
https://playcode.io/1894374


Related issues 1 (0 open1 closed)

Related to TYPO3 Core - Task #103375: Implement `@typescript-eslint/no-array-delete` ruleClosed2024-03-12

Actions
Actions #1

Updated by rogier Helmer 6 months ago

Let me know if you want me to do a PR.

Actions #2

Updated by Andreas Kienast 6 months ago

  • Status changed from New to In Progress
  • Is Regression changed from No to Yes
Actions #3

Updated by Andreas Kienast 6 months ago

  • Related to Task #103375: Implement `@typescript-eslint/no-array-delete` rule added
Actions #4

Updated by Gerrit Code Review 6 months ago

  • Status changed from In Progress to Under Review

Patch set 1 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/84487

Actions #5

Updated by Gerrit Code Review 6 months ago

Patch set 1 for branch 12.4 of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/84488

Actions #6

Updated by Andreas Fernandez 6 months ago

  • Status changed from Under Review to Resolved
  • % Done changed from 0 to 100
Actions #7

Updated by Benni Mack 4 months ago

  • Status changed from Resolved to Closed
Actions

Also available in: Atom PDF