From 5ff4de8fd2aac8018a5d0e0e58e69225909ac64c Mon Sep 17 00:00:00 2001
From: Nikita Hovratov <nikita.h@live.de>
Date: Fri, 17 Jun 2022 20:52:05 +0200
Subject: [PATCH] [BUGFIX] Toggle inline controls only in own scope
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The former approach in #91808 to fix scoped toggling didn't
work with levelLinksPosition "bottom", as the querySelector
could find another control container inside another child
inline field first.

Another solution, which is now possible, works with the
":scope" selector. Only nodes with a direct parent will be
found this way.

In addition, a new helper class is added for the top control
container, as it is wrapped in another div. This enables
toggling of both buttons, in case levelLinksPosition "both"
is set.

Resolves: #97786
Related: #91808
Related: #92382
Releases: main, 11.5
Change-Id: I67146c372d183cd647db847b3e3d83d986585577
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/74928
Tested-by: core-ci <typo3@b13.com>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Stefan Bürk <stefan@buerk.tech>
Tested-by: Nikita Hovratov <nikita.h@live.de>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Stefan Bürk <stefan@buerk.tech>
Reviewed-by: Nikita Hovratov <nikita.h@live.de>
---
 .../container/inline-control-container.ts          | 14 ++++++++++----
 .../Form/Container/InlineControlContainer.php      |  2 +-
 .../container/inline-control-container.js          |  2 +-
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/Build/Sources/TypeScript/backend/form-engine/container/inline-control-container.ts b/Build/Sources/TypeScript/backend/form-engine/container/inline-control-container.ts
index 4d1e7c57047d..ac0261e2bd6a 100644
--- a/Build/Sources/TypeScript/backend/form-engine/container/inline-control-container.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/container/inline-control-container.ts
@@ -40,6 +40,7 @@ enum Selectors {
   uniqueValueSelectors = 'select.t3js-inline-unique',
   revertUniqueness = '.t3js-revert-unique',
   controlContainer = '.t3js-inline-controls',
+  controlTopOuterContainer = '.t3js-inline-controls-top-outer-container',
 }
 
 enum States {
@@ -789,13 +790,18 @@ class InlineControlContainer {
    * @param {boolean} visible
    */
   private toggleContainerControls(visible: boolean): void {
-    const controlContainer = this.container.querySelector(Selectors.controlContainer);
+    const controlContainer = this.container.querySelectorAll(
+      ':scope > ' + Selectors.controlContainer + ', '
+      + ':scope > ' + Selectors.controlTopOuterContainer + ' ' + Selectors.controlContainer
+    );
     if (controlContainer === null) {
       return;
     }
-    const controlContainerButtons = controlContainer.querySelectorAll('button, a');
-    controlContainerButtons.forEach((button: HTMLElement): void => {
-      button.style.display = visible ? null : 'none';
+    controlContainer.forEach((container: HTMLElement): void => {
+      let controlContainerButtons = container.querySelectorAll('button, a');
+      controlContainerButtons.forEach((button: HTMLElement): void => {
+        button.style.display = visible ? null : 'none';
+      });
     });
   }
 
diff --git a/typo3/sysext/backend/Classes/Form/Container/InlineControlContainer.php b/typo3/sysext/backend/Classes/Form/Container/InlineControlContainer.php
index c6e0139ebb79..cc8e8934f617 100644
--- a/typo3/sysext/backend/Classes/Form/Container/InlineControlContainer.php
+++ b/typo3/sysext/backend/Classes/Form/Container/InlineControlContainer.php
@@ -311,7 +311,7 @@ class InlineControlContainer extends AbstractContainer
 
         // Add the level buttons before all child records:
         if (in_array($config['appearance']['levelLinksPosition'] ?? null, ['both', 'top'], true)) {
-            $html .= '<div class="form-group t3js-formengine-validation-marker">' . $newRecordButton . $localizationButtons . '</div>';
+            $html .= '<div class="form-group t3js-formengine-validation-marker t3js-inline-controls-top-outer-container">' . $newRecordButton . $localizationButtons . '</div>';
         }
 
         // If it's required to select from possible child records (reusable children), add a selector box
diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/form-engine/container/inline-control-container.js b/typo3/sysext/backend/Resources/Public/JavaScript/form-engine/container/inline-control-container.js
index e70427ed59c4..73bd16dde576 100644
--- a/typo3/sysext/backend/Resources/Public/JavaScript/form-engine/container/inline-control-container.js
+++ b/typo3/sysext/backend/Resources/Public/JavaScript/form-engine/container/inline-control-container.js
@@ -10,4 +10,4 @@
  *
  * The TYPO3 project - inspiring people to share!
  */
-import{MessageUtility}from"@typo3/backend/utility/message-utility.js";import{AjaxDispatcher}from"@typo3/backend/form-engine/inline-relation/ajax-dispatcher.js";import DocumentService from"@typo3/core/document-service.js";import NProgress from"nprogress";import Sortable from"sortablejs";import FormEngine from"@typo3/backend/form-engine.js";import FormEngineValidation from"@typo3/backend/form-engine-validation.js";import Icons from"@typo3/backend/icons.js";import InfoWindow from"@typo3/backend/info-window.js";import Modal from"@typo3/backend/modal.js";import Notification from"@typo3/backend/notification.js";import RegularEvent from"@typo3/core/event/regular-event.js";import Severity from"@typo3/backend/severity.js";import Utility from"@typo3/backend/utility.js";var Selectors,States,Separators,SortDirections;!function(e){e.toggleSelector='[data-bs-toggle="formengine-inline"]',e.controlSectionSelector=".t3js-formengine-irre-control",e.createNewRecordButtonSelector=".t3js-create-new-button",e.createNewRecordBySelectorSelector=".t3js-create-new-selector",e.deleteRecordButtonSelector=".t3js-editform-delete-inline-record",e.enableDisableRecordButtonSelector=".t3js-toggle-visibility-button",e.infoWindowButton='[data-action="infowindow"]',e.synchronizeLocalizeRecordButtonSelector=".t3js-synchronizelocalize-button",e.uniqueValueSelectors="select.t3js-inline-unique",e.revertUniqueness=".t3js-revert-unique",e.controlContainer=".t3js-inline-controls"}(Selectors||(Selectors={})),function(e){e.new="inlineIsNewRecord",e.visible="panel-visible",e.collapsed="panel-collapsed",e.notLoaded="t3js-not-loaded"}(States||(States={})),function(e){e.structureSeparator="-"}(Separators||(Separators={})),function(e){e.DOWN="down",e.UP="up"}(SortDirections||(SortDirections={}));class InlineControlContainer{constructor(e){this.container=null,this.ajaxDispatcher=null,this.appearance=null,this.requestQueue={},this.progessQueue={},this.noTitleString=TYPO3.lang?TYPO3.lang["FormEngine.noRecordTitle"]:"[No title]",this.handlePostMessage=e=>{if(!MessageUtility.verifyOrigin(e.origin))throw"Denied message sent by "+e.origin;if("typo3:foreignRelation:insert"===e.data.actionName){if(void 0===e.data.objectGroup)throw"No object group defined for message";if(e.data.objectGroup!==this.container.dataset.objectGroup)return;if(this.isUniqueElementUsed(parseInt(e.data.uid,10),e.data.table))return void Notification.error("There is already a relation to the selected element");this.importRecord([e.data.objectGroup,e.data.uid]).then(()=>{if(e.source){const t={actionName:"typo3:foreignRelation:inserted",objectGroup:e.data.objectId,table:e.data.table,uid:e.data.uid};MessageUtility.send(t,e.source)}})}},DocumentService.ready().then(t=>{this.container=t.getElementById(e),this.ajaxDispatcher=new AjaxDispatcher(this.container.dataset.objectGroup),this.registerEvents()})}static getInlineRecordContainer(e){return document.querySelector('[data-object-id="'+e+'"]')}static getCollapseButton(e){return document.querySelector('[aria-controls="'+e+'_fields"]')}static toggleElement(e){const t=InlineControlContainer.getInlineRecordContainer(e);t.classList.contains(States.collapsed)?InlineControlContainer.expandElement(t,e):InlineControlContainer.collapseElement(t,e)}static collapseElement(e,t){const n=InlineControlContainer.getCollapseButton(t);e.classList.remove(States.visible),e.classList.add(States.collapsed),n.setAttribute("aria-expanded","false")}static expandElement(e,t){const n=InlineControlContainer.getCollapseButton(t);e.classList.remove(States.collapsed),e.classList.add(States.visible),n.setAttribute("aria-expanded","true")}static isNewRecord(e){return InlineControlContainer.getInlineRecordContainer(e).classList.contains(States.new)}static updateExpandedCollapsedStateLocally(e,t){const n=InlineControlContainer.getInlineRecordContainer(e),o="uc[inlineView]["+n.dataset.topmostParentTable+"]["+n.dataset.topmostParentUid+"]"+n.dataset.fieldName,i=document.getElementsByName(o);i.length&&(i[0].value=t?"1":"0")}static getValuesFromHashMap(e){return Object.keys(e).map(t=>e[t])}static selectOptionValueExists(e,t){return null!==e.querySelector('option[value="'+t+'"]')}static removeSelectOptionByValue(e,t){const n=e.querySelector('option[value="'+t+'"]');null!==n&&n.remove()}static reAddSelectOption(e,t,n){if(InlineControlContainer.selectOptionValueExists(e,t))return;const o=e.querySelectorAll("option");let i=-1;for(let e of Object.keys(n.possible)){if(e===t)break;for(let t=0;t<o.length;++t){if(o[t].value===e){i=t;break}}}-1===i?i=0:i<o.length&&i++;const r=document.createElement("option");r.text=n.possible[t],r.value=t,e.insertBefore(r,e.options[i])}registerEvents(){if(this.registerInfoButton(),this.registerSort(),this.registerCreateRecordButton(),this.registerEnableDisableButton(),this.registerDeleteButton(),this.registerSynchronizeLocalize(),this.registerRevertUniquenessAction(),this.registerToggle(),this.registerCreateRecordBySelector(),this.registerUniqueSelectFieldChanged(),new RegularEvent("message",this.handlePostMessage).bindTo(window),this.getAppearance().useSortable){const e=document.getElementById(this.container.getAttribute("id")+"_records");new Sortable(e,{group:e.getAttribute("id"),handle:".sortableHandle",onSort:()=>{this.updateSorting()}})}}registerToggle(){const e=this;new RegularEvent("click",(function(t){t.preventDefault(),t.stopImmediatePropagation(),e.loadRecordDetails(this.closest(Selectors.toggleSelector).parentElement.dataset.objectId)})).delegateTo(this.container,`${Selectors.toggleSelector} .form-irre-header-cell:not(${Selectors.controlSectionSelector}`)}registerSort(){const e=this;new RegularEvent("click",(function(t){t.preventDefault(),t.stopImmediatePropagation(),e.changeSortingByButton(this.closest("[data-object-id]").dataset.objectId,this.dataset.direction)})).delegateTo(this.container,Selectors.controlSectionSelector+' [data-action="sort"]')}registerCreateRecordButton(){const e=this;new RegularEvent("click",(function(t){if(t.preventDefault(),t.stopImmediatePropagation(),e.isBelowMax()){let t=e.container.dataset.objectGroup;void 0!==this.dataset.recordUid&&(t+=Separators.structureSeparator+this.dataset.recordUid),e.importRecord([t,e.container.querySelector(Selectors.createNewRecordBySelectorSelector)?.value],this.dataset.recordUid??null)}})).delegateTo(this.container,Selectors.createNewRecordButtonSelector)}registerCreateRecordBySelector(){const e=this;new RegularEvent("change",(function(t){t.preventDefault(),t.stopImmediatePropagation();const n=this.options[this.selectedIndex].getAttribute("value");e.importRecord([e.container.dataset.objectGroup,n])})).delegateTo(this.container,Selectors.createNewRecordBySelectorSelector)}createRecord(e,t,n=null,o=null){let i=this.container.dataset.objectGroup;null!==n&&(i+=Separators.structureSeparator+n),null!==n?(InlineControlContainer.getInlineRecordContainer(i).insertAdjacentHTML("afterend",t),this.memorizeAddRecord(e,n,o)):(document.getElementById(this.container.getAttribute("id")+"_records").insertAdjacentHTML("beforeend",t),this.memorizeAddRecord(e,null,o))}async importRecord(e,t){return this.ajaxDispatcher.send(this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("record_inline_create")),e).then(async e=>{this.isBelowMax()&&this.createRecord(e.compilerInput.uid,e.data,void 0!==t?t:null,void 0!==e.compilerInput.childChildUid?e.compilerInput.childChildUid:null)})}registerEnableDisableButton(){new RegularEvent("click",(e,t)=>{e.preventDefault(),e.stopImmediatePropagation();const n=t.closest("[data-object-id]").dataset.objectId,o=InlineControlContainer.getInlineRecordContainer(n),i="data"+o.dataset.fieldName+"["+t.dataset.hiddenField+"]",r=document.querySelector('[data-formengine-input-name="'+i+'"'),a=document.querySelector('[name="'+i+'"');null!==r&&null!==a&&(r.checked=!r.checked,a.value=r.checked?"1":"0",FormEngineValidation.markFieldAsChanged(r));const s="t3-form-field-container-inline-hidden";let l;o.classList.contains(s)?(l="actions-edit-hide",o.classList.remove(s)):(l="actions-edit-unhide",o.classList.add(s)),Icons.getIcon(l,Icons.sizes.small).then(e=>{t.replaceChild(document.createRange().createContextualFragment(e),t.querySelector(".t3js-icon"))})}).delegateTo(this.container,Selectors.enableDisableRecordButtonSelector)}registerInfoButton(){new RegularEvent("click",(function(e){e.preventDefault(),e.stopImmediatePropagation(),InfoWindow.showItem(this.dataset.infoTable,this.dataset.infoUid)})).delegateTo(this.container,Selectors.infoWindowButton)}registerDeleteButton(){const e=this;new RegularEvent("click",(function(t){t.preventDefault(),t.stopImmediatePropagation();const n=TYPO3.lang["label.confirm.delete_record.title"]||"Delete this record?",o=(TYPO3.lang["label.confirm.delete_record.content"]||"Are you sure you want to delete the record '%s'?").replace("%s",this.dataset.recordInfo);Modal.confirm(n,o,Severity.warning,[{text:TYPO3.lang["buttons.confirm.delete_record.no"]||"Cancel",active:!0,btnClass:"btn-default",name:"no"},{text:TYPO3.lang["buttons.confirm.delete_record.yes"]||"Yes, delete this record",btnClass:"btn-warning",name:"yes"}]).on("button.clicked",t=>{if("yes"===t.target.name){const t=this.closest("[data-object-id]").dataset.objectId;e.deleteRecord(t)}Modal.dismiss()})})).delegateTo(this.container,Selectors.deleteRecordButtonSelector)}registerSynchronizeLocalize(){const e=this;new RegularEvent("click",(function(t){t.preventDefault(),t.stopImmediatePropagation(),e.ajaxDispatcher.send(e.ajaxDispatcher.newRequest(e.ajaxDispatcher.getEndpoint("record_inline_synchronizelocalize")),[e.container.dataset.objectGroup,this.dataset.type]).then(async t=>{document.getElementById(e.container.getAttribute("id")+"_records").insertAdjacentHTML("beforeend",t.data);const n=e.container.dataset.objectGroup+Separators.structureSeparator;for(let o of t.compilerInput.delete)e.deleteRecord(n+o,!0);for(let o of Object.values(t.compilerInput.localize)){if(void 0!==o.remove){const e=InlineControlContainer.getInlineRecordContainer(n+o.remove);e.parentElement.removeChild(e)}e.memorizeAddRecord(o.uid,null,o.selectedValue)}})})).delegateTo(this.container,Selectors.synchronizeLocalizeRecordButtonSelector)}registerUniqueSelectFieldChanged(){const e=this;new RegularEvent("change",(function(t){t.preventDefault(),t.stopImmediatePropagation();const n=this.closest("[data-object-id]");if(null!==n){const t=n.dataset.objectId,o=n.dataset.objectUid;e.handleChangedField(this,t);const i=e.getFormFieldForElements();if(null===i)return;e.updateUnique(this,i,o)}})).delegateTo(this.container,Selectors.uniqueValueSelectors)}registerRevertUniquenessAction(){const e=this;new RegularEvent("click",(function(t){t.preventDefault(),t.stopImmediatePropagation(),e.revertUnique(this.dataset.uid)})).delegateTo(this.container,Selectors.revertUniqueness)}loadRecordDetails(e){const t=document.getElementById(e+"_fields"),n=InlineControlContainer.getInlineRecordContainer(e),o=void 0!==this.requestQueue[e];if(null!==t&&!n.classList.contains(States.notLoaded))this.collapseExpandRecord(e);else{const i=this.getProgress(e,n.dataset.objectIdHash);if(o)this.requestQueue[e].abort(),delete this.requestQueue[e],delete this.progessQueue[e],i.done();else{const o=this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("record_inline_details"));this.ajaxDispatcher.send(o,[e]).then(async o=>{if(delete this.requestQueue[e],delete this.progessQueue[e],n.classList.remove(States.notLoaded),t.innerHTML=o.data,this.collapseExpandRecord(e),i.done(),FormEngine.reinitialize(),FormEngineValidation.initializeInputFields(),FormEngineValidation.validate(this.container),this.hasObjectGroupDefinedUniqueConstraints()){const t=InlineControlContainer.getInlineRecordContainer(e);this.removeUsed(t)}}),this.requestQueue[e]=o,i.start()}}}collapseExpandRecord(e){const t=InlineControlContainer.getInlineRecordContainer(e),n=!0===this.getAppearance().expandSingle,o=t.classList.contains(States.collapsed);let i=[];const r=[];n&&o&&(i=this.collapseAllRecords(t.dataset.objectUid)),InlineControlContainer.toggleElement(e),InlineControlContainer.isNewRecord(e)?InlineControlContainer.updateExpandedCollapsedStateLocally(e,o):o?r.push(t.dataset.objectUid):o||i.push(t.dataset.objectUid),this.ajaxDispatcher.send(this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("record_inline_expandcollapse")),[e,r.join(","),i.join(",")])}memorizeAddRecord(e,t=null,n=null){const o=this.getFormFieldForElements();if(null===o)return;let i=Utility.trimExplode(",",o.value);if(t){const n=[];for(let o=0;o<i.length;o++)i[o].length&&n.push(i[o]),t===i[o]&&n.push(e);i=n}else i.push(e);o.value=i.join(","),o.classList.add("has-change"),document.dispatchEvent(new Event("change")),this.redrawSortingButtons(this.container.dataset.objectGroup,i),this.setUnique(e,n),this.isBelowMax()||this.toggleContainerControls(!1),FormEngine.reinitialize(),FormEngineValidation.initializeInputFields(),FormEngineValidation.validate(this.container)}memorizeRemoveRecord(e){const t=this.getFormFieldForElements();if(null===t)return[];let n=Utility.trimExplode(",",t.value);const o=n.indexOf(e);return o>-1&&(delete n[o],t.value=n.join(","),t.classList.add("has-change"),document.dispatchEvent(new Event("change")),this.redrawSortingButtons(this.container.dataset.objectGroup,n)),n}changeSortingByButton(e,t){const n=InlineControlContainer.getInlineRecordContainer(e),o=n.dataset.objectUid,i=document.getElementById(this.container.getAttribute("id")+"_records"),r=Array.from(i.children).map(e=>e.dataset.objectUid);let a=r.indexOf(o),s=!1;if(t===SortDirections.UP&&a>0?(r[a]=r[a-1],r[a-1]=o,s=!0):t===SortDirections.DOWN&&a<r.length-1&&(r[a]=r[a+1],r[a+1]=o,s=!0),s){const e=this.container.dataset.objectGroup+Separators.structureSeparator,o=t===SortDirections.UP?1:0;n.parentElement.insertBefore(InlineControlContainer.getInlineRecordContainer(e+r[a-o]),InlineControlContainer.getInlineRecordContainer(e+r[a+1-o])),this.updateSorting()}}updateSorting(){const e=this.getFormFieldForElements();if(null===e)return;const t=document.getElementById(this.container.getAttribute("id")+"_records"),n=Array.from(t.querySelectorAll('[data-object-parent-group="'+this.container.dataset.objectGroup+'"][data-placeholder-record="0"]')).map(e=>e.dataset.objectUid);e.value=n.join(","),e.classList.add("has-change"),document.dispatchEvent(new Event("inline:sorting-changed")),document.dispatchEvent(new Event("change")),this.redrawSortingButtons(this.container.dataset.objectGroup,n)}deleteRecord(e,t=!1){const n=InlineControlContainer.getInlineRecordContainer(e),o=n.dataset.objectUid;if(n.classList.add("t3js-inline-record-deleted"),!InlineControlContainer.isNewRecord(e)&&!t){const e=this.container.querySelector('[name="cmd'+n.dataset.fieldName+'[delete]"]');e.removeAttribute("disabled"),n.parentElement.insertAdjacentElement("afterbegin",e)}new RegularEvent("transitionend",()=>{n.parentElement.removeChild(n),FormEngineValidation.validate(this.container)}).bindTo(n),this.revertUnique(o),this.memorizeRemoveRecord(o),n.classList.add("form-irre-object--deleted"),this.isBelowMax()&&this.toggleContainerControls(!0)}toggleContainerControls(e){const t=this.container.querySelector(Selectors.controlContainer);if(null===t)return;t.querySelectorAll("button, a").forEach(t=>{t.style.display=e?null:"none"})}getProgress(e,t){const n="#"+t+"_header";let o;return void 0!==this.progessQueue[e]?o=this.progessQueue[e]:(o=NProgress,o.configure({parent:n,showSpinner:!1}),this.progessQueue[e]=o),o}collapseAllRecords(e){const t=this.getFormFieldForElements(),n=[];if(null!==t){const o=Utility.trimExplode(",",t.value);for(let t of o){if(t===e)continue;const o=this.container.dataset.objectGroup+Separators.structureSeparator+t,i=InlineControlContainer.getInlineRecordContainer(o);i.classList.contains(States.visible)&&(InlineControlContainer.collapseElement(i,o),InlineControlContainer.isNewRecord(o)?InlineControlContainer.updateExpandedCollapsedStateLocally(o,!1):n.push(t))}}return n}getFormFieldForElements(){const e=document.getElementsByName(this.container.dataset.formField);return e.length>0?e[0]:null}redrawSortingButtons(e,t=[]){if(0===t.length){const e=this.getFormFieldForElements();null!==e&&(t=Utility.trimExplode(",",e.value))}0!==t.length&&t.forEach((n,o)=>{const i=InlineControlContainer.getInlineRecordContainer(e+Separators.structureSeparator+n).dataset.objectIdHash+"_header",r=document.getElementById(i),a=r.querySelector('[data-action="sort"][data-direction="'+SortDirections.UP+'"]');if(null!==a){let e="actions-move-up";0===o?(a.classList.add("disabled"),e="empty-empty"):a.classList.remove("disabled"),Icons.getIcon(e,Icons.sizes.small).then(e=>{a.replaceChild(document.createRange().createContextualFragment(e),a.querySelector(".t3js-icon"))})}const s=r.querySelector('[data-action="sort"][data-direction="'+SortDirections.DOWN+'"]');if(null!==s){let e="actions-move-down";o===t.length-1?(s.classList.add("disabled"),e="empty-empty"):s.classList.remove("disabled"),Icons.getIcon(e,Icons.sizes.small).then(e=>{s.replaceChild(document.createRange().createContextualFragment(e),s.querySelector(".t3js-icon"))})}})}isBelowMax(){const e=this.getFormFieldForElements();if(null===e)return!0;if(void 0!==TYPO3.settings.FormEngineInline.config[this.container.dataset.objectGroup]){if(Utility.trimExplode(",",e.value).length>=TYPO3.settings.FormEngineInline.config[this.container.dataset.objectGroup].max)return!1;if(this.hasObjectGroupDefinedUniqueConstraints()){const e=TYPO3.settings.FormEngineInline.unique[this.container.dataset.objectGroup];if(e.used.length>=e.max&&e.max>=0)return!1}}return!0}isUniqueElementUsed(e,t){if(!this.hasObjectGroupDefinedUniqueConstraints())return!1;const n=TYPO3.settings.FormEngineInline.unique[this.container.dataset.objectGroup],o=InlineControlContainer.getValuesFromHashMap(n.used);if("select"===n.type&&-1!==o.indexOf(e))return!0;if("groupdb"===n.type)for(let n=o.length-1;n>=0;n--)if(o[n].table===t&&o[n].uid===e)return!0;return!1}removeUsed(e){if(!this.hasObjectGroupDefinedUniqueConstraints())return;const t=TYPO3.settings.FormEngineInline.unique[this.container.dataset.objectGroup];if("select"!==t.type)return;let n=e.querySelector('[name="data['+t.table+"]["+e.dataset.objectUid+"]["+t.field+']"]');const o=InlineControlContainer.getValuesFromHashMap(t.used);if(null!==n){const e=n.options[n.selectedIndex].value;for(let t of o)t!==e&&InlineControlContainer.removeSelectOptionByValue(n,t)}}setUnique(e,t){if(!this.hasObjectGroupDefinedUniqueConstraints())return;const n=document.getElementById(this.container.dataset.objectGroup+"_selector"),o=TYPO3.settings.FormEngineInline.unique[this.container.dataset.objectGroup];if("select"===o.type){if(!o.selector||-1!==o.max){const i=this.getFormFieldForElements(),r=this.container.dataset.objectGroup+Separators.structureSeparator+e;let a=InlineControlContainer.getInlineRecordContainer(r).querySelector('[name="data['+o.table+"]["+e+"]["+o.field+']"]');const s=InlineControlContainer.getValuesFromHashMap(o.used);if(null!==n){if(null!==a){for(let e of s)InlineControlContainer.removeSelectOptionByValue(a,e);o.selector||(t=a.options[0].value,a.options[0].selected=!0,this.updateUnique(a,i,e),this.handleChangedField(a,this.container.dataset.objectGroup+"["+e+"]"))}for(let e of s)InlineControlContainer.removeSelectOptionByValue(a,e);void 0!==o.used.length&&(o.used={}),o.used[e]={table:o.elTable,uid:t}}if(null!==i&&InlineControlContainer.selectOptionValueExists(n,t)){const n=Utility.trimExplode(",",i.value);for(let i of n)a=document.querySelector('[name="data['+o.table+"]["+i+"]["+o.field+']"]'),null!==a&&i!==e&&InlineControlContainer.removeSelectOptionByValue(a,t)}}}else"groupdb"===o.type&&(o.used[e]={table:o.elTable,uid:t});"select"===o.selector&&InlineControlContainer.selectOptionValueExists(n,t)&&(InlineControlContainer.removeSelectOptionByValue(n,t),o.used[e]={table:o.elTable,uid:t})}updateUnique(e,t,n){if(!this.hasObjectGroupDefinedUniqueConstraints())return;const o=TYPO3.settings.FormEngineInline.unique[this.container.dataset.objectGroup],i=o.used[n];if("select"===o.selector){const t=document.getElementById(this.container.dataset.objectGroup+"_selector");InlineControlContainer.removeSelectOptionByValue(t,e.value),void 0!==i&&InlineControlContainer.reAddSelectOption(t,i,o)}if(o.selector&&-1===o.max)return;if(!o||null===t)return;const r=Utility.trimExplode(",",t.value);let a;for(let t of r)a=document.querySelector('[name="data['+o.table+"]["+t+"]["+o.field+']"]'),null!==a&&a!==e&&(InlineControlContainer.removeSelectOptionByValue(a,e.value),void 0!==i&&InlineControlContainer.reAddSelectOption(a,i,o));o.used[n]=e.value}revertUnique(e){if(!this.hasObjectGroupDefinedUniqueConstraints())return;const t=TYPO3.settings.FormEngineInline.unique[this.container.dataset.objectGroup],n=this.container.dataset.objectGroup+Separators.structureSeparator+e,o=InlineControlContainer.getInlineRecordContainer(n);let i=o.querySelector('[name="data['+t.table+"]["+o.dataset.objectUid+"]["+t.field+']"]');if("select"===t.type){let n;if(null!==i)n=i.value;else{if(""===o.dataset.tableUniqueOriginalValue)return;n=o.dataset.tableUniqueOriginalValue}if("select"===t.selector&&!isNaN(parseInt(n,10))){const e=document.getElementById(this.container.dataset.objectGroup+"_selector");InlineControlContainer.reAddSelectOption(e,n,t)}if(t.selector&&-1===t.max)return;const r=this.getFormFieldForElements();if(null===r)return;const a=Utility.trimExplode(",",r.value);let s;for(let e=0;e<a.length;e++)s=document.querySelector('[name="data['+t.table+"]["+a[e]+"]["+t.field+']"]'),null!==s&&InlineControlContainer.reAddSelectOption(s,n,t);delete t.used[e]}else"groupdb"===t.type&&delete t.used[e]}hasObjectGroupDefinedUniqueConstraints(){return void 0!==TYPO3.settings.FormEngineInline.unique&&void 0!==TYPO3.settings.FormEngineInline.unique[this.container.dataset.objectGroup]}handleChangedField(e,t){let n;n=e instanceof HTMLSelectElement?e.options[e.selectedIndex].text:e.value,document.getElementById(t+"_label").textContent=n.length?n:this.noTitleString}getAppearance(){if(null===this.appearance&&(this.appearance={},"string"==typeof this.container.dataset.appearance))try{this.appearance=JSON.parse(this.container.dataset.appearance)}catch(e){console.error(e)}return this.appearance}}export default InlineControlContainer;
\ No newline at end of file
+import{MessageUtility}from"@typo3/backend/utility/message-utility.js";import{AjaxDispatcher}from"@typo3/backend/form-engine/inline-relation/ajax-dispatcher.js";import DocumentService from"@typo3/core/document-service.js";import NProgress from"nprogress";import Sortable from"sortablejs";import FormEngine from"@typo3/backend/form-engine.js";import FormEngineValidation from"@typo3/backend/form-engine-validation.js";import Icons from"@typo3/backend/icons.js";import InfoWindow from"@typo3/backend/info-window.js";import Modal from"@typo3/backend/modal.js";import Notification from"@typo3/backend/notification.js";import RegularEvent from"@typo3/core/event/regular-event.js";import Severity from"@typo3/backend/severity.js";import Utility from"@typo3/backend/utility.js";var Selectors,States,Separators,SortDirections;!function(e){e.toggleSelector='[data-bs-toggle="formengine-inline"]',e.controlSectionSelector=".t3js-formengine-irre-control",e.createNewRecordButtonSelector=".t3js-create-new-button",e.createNewRecordBySelectorSelector=".t3js-create-new-selector",e.deleteRecordButtonSelector=".t3js-editform-delete-inline-record",e.enableDisableRecordButtonSelector=".t3js-toggle-visibility-button",e.infoWindowButton='[data-action="infowindow"]',e.synchronizeLocalizeRecordButtonSelector=".t3js-synchronizelocalize-button",e.uniqueValueSelectors="select.t3js-inline-unique",e.revertUniqueness=".t3js-revert-unique",e.controlContainer=".t3js-inline-controls",e.controlTopOuterContainer=".t3js-inline-controls-top-outer-container"}(Selectors||(Selectors={})),function(e){e.new="inlineIsNewRecord",e.visible="panel-visible",e.collapsed="panel-collapsed",e.notLoaded="t3js-not-loaded"}(States||(States={})),function(e){e.structureSeparator="-"}(Separators||(Separators={})),function(e){e.DOWN="down",e.UP="up"}(SortDirections||(SortDirections={}));class InlineControlContainer{constructor(e){this.container=null,this.ajaxDispatcher=null,this.appearance=null,this.requestQueue={},this.progessQueue={},this.noTitleString=TYPO3.lang?TYPO3.lang["FormEngine.noRecordTitle"]:"[No title]",this.handlePostMessage=e=>{if(!MessageUtility.verifyOrigin(e.origin))throw"Denied message sent by "+e.origin;if("typo3:foreignRelation:insert"===e.data.actionName){if(void 0===e.data.objectGroup)throw"No object group defined for message";if(e.data.objectGroup!==this.container.dataset.objectGroup)return;if(this.isUniqueElementUsed(parseInt(e.data.uid,10),e.data.table))return void Notification.error("There is already a relation to the selected element");this.importRecord([e.data.objectGroup,e.data.uid]).then(()=>{if(e.source){const t={actionName:"typo3:foreignRelation:inserted",objectGroup:e.data.objectId,table:e.data.table,uid:e.data.uid};MessageUtility.send(t,e.source)}})}},DocumentService.ready().then(t=>{this.container=t.getElementById(e),this.ajaxDispatcher=new AjaxDispatcher(this.container.dataset.objectGroup),this.registerEvents()})}static getInlineRecordContainer(e){return document.querySelector('[data-object-id="'+e+'"]')}static getCollapseButton(e){return document.querySelector('[aria-controls="'+e+'_fields"]')}static toggleElement(e){const t=InlineControlContainer.getInlineRecordContainer(e);t.classList.contains(States.collapsed)?InlineControlContainer.expandElement(t,e):InlineControlContainer.collapseElement(t,e)}static collapseElement(e,t){const n=InlineControlContainer.getCollapseButton(t);e.classList.remove(States.visible),e.classList.add(States.collapsed),n.setAttribute("aria-expanded","false")}static expandElement(e,t){const n=InlineControlContainer.getCollapseButton(t);e.classList.remove(States.collapsed),e.classList.add(States.visible),n.setAttribute("aria-expanded","true")}static isNewRecord(e){return InlineControlContainer.getInlineRecordContainer(e).classList.contains(States.new)}static updateExpandedCollapsedStateLocally(e,t){const n=InlineControlContainer.getInlineRecordContainer(e),o="uc[inlineView]["+n.dataset.topmostParentTable+"]["+n.dataset.topmostParentUid+"]"+n.dataset.fieldName,i=document.getElementsByName(o);i.length&&(i[0].value=t?"1":"0")}static getValuesFromHashMap(e){return Object.keys(e).map(t=>e[t])}static selectOptionValueExists(e,t){return null!==e.querySelector('option[value="'+t+'"]')}static removeSelectOptionByValue(e,t){const n=e.querySelector('option[value="'+t+'"]');null!==n&&n.remove()}static reAddSelectOption(e,t,n){if(InlineControlContainer.selectOptionValueExists(e,t))return;const o=e.querySelectorAll("option");let i=-1;for(let e of Object.keys(n.possible)){if(e===t)break;for(let t=0;t<o.length;++t){if(o[t].value===e){i=t;break}}}-1===i?i=0:i<o.length&&i++;const r=document.createElement("option");r.text=n.possible[t],r.value=t,e.insertBefore(r,e.options[i])}registerEvents(){if(this.registerInfoButton(),this.registerSort(),this.registerCreateRecordButton(),this.registerEnableDisableButton(),this.registerDeleteButton(),this.registerSynchronizeLocalize(),this.registerRevertUniquenessAction(),this.registerToggle(),this.registerCreateRecordBySelector(),this.registerUniqueSelectFieldChanged(),new RegularEvent("message",this.handlePostMessage).bindTo(window),this.getAppearance().useSortable){const e=document.getElementById(this.container.getAttribute("id")+"_records");new Sortable(e,{group:e.getAttribute("id"),handle:".sortableHandle",onSort:()=>{this.updateSorting()}})}}registerToggle(){const e=this;new RegularEvent("click",(function(t){t.preventDefault(),t.stopImmediatePropagation(),e.loadRecordDetails(this.closest(Selectors.toggleSelector).parentElement.dataset.objectId)})).delegateTo(this.container,`${Selectors.toggleSelector} .form-irre-header-cell:not(${Selectors.controlSectionSelector}`)}registerSort(){const e=this;new RegularEvent("click",(function(t){t.preventDefault(),t.stopImmediatePropagation(),e.changeSortingByButton(this.closest("[data-object-id]").dataset.objectId,this.dataset.direction)})).delegateTo(this.container,Selectors.controlSectionSelector+' [data-action="sort"]')}registerCreateRecordButton(){const e=this;new RegularEvent("click",(function(t){if(t.preventDefault(),t.stopImmediatePropagation(),e.isBelowMax()){let t=e.container.dataset.objectGroup;void 0!==this.dataset.recordUid&&(t+=Separators.structureSeparator+this.dataset.recordUid),e.importRecord([t,e.container.querySelector(Selectors.createNewRecordBySelectorSelector)?.value],this.dataset.recordUid??null)}})).delegateTo(this.container,Selectors.createNewRecordButtonSelector)}registerCreateRecordBySelector(){const e=this;new RegularEvent("change",(function(t){t.preventDefault(),t.stopImmediatePropagation();const n=this.options[this.selectedIndex].getAttribute("value");e.importRecord([e.container.dataset.objectGroup,n])})).delegateTo(this.container,Selectors.createNewRecordBySelectorSelector)}createRecord(e,t,n=null,o=null){let i=this.container.dataset.objectGroup;null!==n&&(i+=Separators.structureSeparator+n),null!==n?(InlineControlContainer.getInlineRecordContainer(i).insertAdjacentHTML("afterend",t),this.memorizeAddRecord(e,n,o)):(document.getElementById(this.container.getAttribute("id")+"_records").insertAdjacentHTML("beforeend",t),this.memorizeAddRecord(e,null,o))}async importRecord(e,t){return this.ajaxDispatcher.send(this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("record_inline_create")),e).then(async e=>{this.isBelowMax()&&this.createRecord(e.compilerInput.uid,e.data,void 0!==t?t:null,void 0!==e.compilerInput.childChildUid?e.compilerInput.childChildUid:null)})}registerEnableDisableButton(){new RegularEvent("click",(e,t)=>{e.preventDefault(),e.stopImmediatePropagation();const n=t.closest("[data-object-id]").dataset.objectId,o=InlineControlContainer.getInlineRecordContainer(n),i="data"+o.dataset.fieldName+"["+t.dataset.hiddenField+"]",r=document.querySelector('[data-formengine-input-name="'+i+'"'),a=document.querySelector('[name="'+i+'"');null!==r&&null!==a&&(r.checked=!r.checked,a.value=r.checked?"1":"0",FormEngineValidation.markFieldAsChanged(r));const s="t3-form-field-container-inline-hidden";let l;o.classList.contains(s)?(l="actions-edit-hide",o.classList.remove(s)):(l="actions-edit-unhide",o.classList.add(s)),Icons.getIcon(l,Icons.sizes.small).then(e=>{t.replaceChild(document.createRange().createContextualFragment(e),t.querySelector(".t3js-icon"))})}).delegateTo(this.container,Selectors.enableDisableRecordButtonSelector)}registerInfoButton(){new RegularEvent("click",(function(e){e.preventDefault(),e.stopImmediatePropagation(),InfoWindow.showItem(this.dataset.infoTable,this.dataset.infoUid)})).delegateTo(this.container,Selectors.infoWindowButton)}registerDeleteButton(){const e=this;new RegularEvent("click",(function(t){t.preventDefault(),t.stopImmediatePropagation();const n=TYPO3.lang["label.confirm.delete_record.title"]||"Delete this record?",o=(TYPO3.lang["label.confirm.delete_record.content"]||"Are you sure you want to delete the record '%s'?").replace("%s",this.dataset.recordInfo);Modal.confirm(n,o,Severity.warning,[{text:TYPO3.lang["buttons.confirm.delete_record.no"]||"Cancel",active:!0,btnClass:"btn-default",name:"no"},{text:TYPO3.lang["buttons.confirm.delete_record.yes"]||"Yes, delete this record",btnClass:"btn-warning",name:"yes"}]).on("button.clicked",t=>{if("yes"===t.target.name){const t=this.closest("[data-object-id]").dataset.objectId;e.deleteRecord(t)}Modal.dismiss()})})).delegateTo(this.container,Selectors.deleteRecordButtonSelector)}registerSynchronizeLocalize(){const e=this;new RegularEvent("click",(function(t){t.preventDefault(),t.stopImmediatePropagation(),e.ajaxDispatcher.send(e.ajaxDispatcher.newRequest(e.ajaxDispatcher.getEndpoint("record_inline_synchronizelocalize")),[e.container.dataset.objectGroup,this.dataset.type]).then(async t=>{document.getElementById(e.container.getAttribute("id")+"_records").insertAdjacentHTML("beforeend",t.data);const n=e.container.dataset.objectGroup+Separators.structureSeparator;for(let o of t.compilerInput.delete)e.deleteRecord(n+o,!0);for(let o of Object.values(t.compilerInput.localize)){if(void 0!==o.remove){const e=InlineControlContainer.getInlineRecordContainer(n+o.remove);e.parentElement.removeChild(e)}e.memorizeAddRecord(o.uid,null,o.selectedValue)}})})).delegateTo(this.container,Selectors.synchronizeLocalizeRecordButtonSelector)}registerUniqueSelectFieldChanged(){const e=this;new RegularEvent("change",(function(t){t.preventDefault(),t.stopImmediatePropagation();const n=this.closest("[data-object-id]");if(null!==n){const t=n.dataset.objectId,o=n.dataset.objectUid;e.handleChangedField(this,t);const i=e.getFormFieldForElements();if(null===i)return;e.updateUnique(this,i,o)}})).delegateTo(this.container,Selectors.uniqueValueSelectors)}registerRevertUniquenessAction(){const e=this;new RegularEvent("click",(function(t){t.preventDefault(),t.stopImmediatePropagation(),e.revertUnique(this.dataset.uid)})).delegateTo(this.container,Selectors.revertUniqueness)}loadRecordDetails(e){const t=document.getElementById(e+"_fields"),n=InlineControlContainer.getInlineRecordContainer(e),o=void 0!==this.requestQueue[e];if(null!==t&&!n.classList.contains(States.notLoaded))this.collapseExpandRecord(e);else{const i=this.getProgress(e,n.dataset.objectIdHash);if(o)this.requestQueue[e].abort(),delete this.requestQueue[e],delete this.progessQueue[e],i.done();else{const o=this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("record_inline_details"));this.ajaxDispatcher.send(o,[e]).then(async o=>{if(delete this.requestQueue[e],delete this.progessQueue[e],n.classList.remove(States.notLoaded),t.innerHTML=o.data,this.collapseExpandRecord(e),i.done(),FormEngine.reinitialize(),FormEngineValidation.initializeInputFields(),FormEngineValidation.validate(this.container),this.hasObjectGroupDefinedUniqueConstraints()){const t=InlineControlContainer.getInlineRecordContainer(e);this.removeUsed(t)}}),this.requestQueue[e]=o,i.start()}}}collapseExpandRecord(e){const t=InlineControlContainer.getInlineRecordContainer(e),n=!0===this.getAppearance().expandSingle,o=t.classList.contains(States.collapsed);let i=[];const r=[];n&&o&&(i=this.collapseAllRecords(t.dataset.objectUid)),InlineControlContainer.toggleElement(e),InlineControlContainer.isNewRecord(e)?InlineControlContainer.updateExpandedCollapsedStateLocally(e,o):o?r.push(t.dataset.objectUid):o||i.push(t.dataset.objectUid),this.ajaxDispatcher.send(this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("record_inline_expandcollapse")),[e,r.join(","),i.join(",")])}memorizeAddRecord(e,t=null,n=null){const o=this.getFormFieldForElements();if(null===o)return;let i=Utility.trimExplode(",",o.value);if(t){const n=[];for(let o=0;o<i.length;o++)i[o].length&&n.push(i[o]),t===i[o]&&n.push(e);i=n}else i.push(e);o.value=i.join(","),o.classList.add("has-change"),document.dispatchEvent(new Event("change")),this.redrawSortingButtons(this.container.dataset.objectGroup,i),this.setUnique(e,n),this.isBelowMax()||this.toggleContainerControls(!1),FormEngine.reinitialize(),FormEngineValidation.initializeInputFields(),FormEngineValidation.validate(this.container)}memorizeRemoveRecord(e){const t=this.getFormFieldForElements();if(null===t)return[];let n=Utility.trimExplode(",",t.value);const o=n.indexOf(e);return o>-1&&(delete n[o],t.value=n.join(","),t.classList.add("has-change"),document.dispatchEvent(new Event("change")),this.redrawSortingButtons(this.container.dataset.objectGroup,n)),n}changeSortingByButton(e,t){const n=InlineControlContainer.getInlineRecordContainer(e),o=n.dataset.objectUid,i=document.getElementById(this.container.getAttribute("id")+"_records"),r=Array.from(i.children).map(e=>e.dataset.objectUid);let a=r.indexOf(o),s=!1;if(t===SortDirections.UP&&a>0?(r[a]=r[a-1],r[a-1]=o,s=!0):t===SortDirections.DOWN&&a<r.length-1&&(r[a]=r[a+1],r[a+1]=o,s=!0),s){const e=this.container.dataset.objectGroup+Separators.structureSeparator,o=t===SortDirections.UP?1:0;n.parentElement.insertBefore(InlineControlContainer.getInlineRecordContainer(e+r[a-o]),InlineControlContainer.getInlineRecordContainer(e+r[a+1-o])),this.updateSorting()}}updateSorting(){const e=this.getFormFieldForElements();if(null===e)return;const t=document.getElementById(this.container.getAttribute("id")+"_records"),n=Array.from(t.querySelectorAll('[data-object-parent-group="'+this.container.dataset.objectGroup+'"][data-placeholder-record="0"]')).map(e=>e.dataset.objectUid);e.value=n.join(","),e.classList.add("has-change"),document.dispatchEvent(new Event("inline:sorting-changed")),document.dispatchEvent(new Event("change")),this.redrawSortingButtons(this.container.dataset.objectGroup,n)}deleteRecord(e,t=!1){const n=InlineControlContainer.getInlineRecordContainer(e),o=n.dataset.objectUid;if(n.classList.add("t3js-inline-record-deleted"),!InlineControlContainer.isNewRecord(e)&&!t){const e=this.container.querySelector('[name="cmd'+n.dataset.fieldName+'[delete]"]');e.removeAttribute("disabled"),n.parentElement.insertAdjacentElement("afterbegin",e)}new RegularEvent("transitionend",()=>{n.parentElement.removeChild(n),FormEngineValidation.validate(this.container)}).bindTo(n),this.revertUnique(o),this.memorizeRemoveRecord(o),n.classList.add("form-irre-object--deleted"),this.isBelowMax()&&this.toggleContainerControls(!0)}toggleContainerControls(e){const t=this.container.querySelectorAll(":scope > "+Selectors.controlContainer+", :scope > "+Selectors.controlTopOuterContainer+" "+Selectors.controlContainer);null!==t&&t.forEach(t=>{t.querySelectorAll("button, a").forEach(t=>{t.style.display=e?null:"none"})})}getProgress(e,t){const n="#"+t+"_header";let o;return void 0!==this.progessQueue[e]?o=this.progessQueue[e]:(o=NProgress,o.configure({parent:n,showSpinner:!1}),this.progessQueue[e]=o),o}collapseAllRecords(e){const t=this.getFormFieldForElements(),n=[];if(null!==t){const o=Utility.trimExplode(",",t.value);for(let t of o){if(t===e)continue;const o=this.container.dataset.objectGroup+Separators.structureSeparator+t,i=InlineControlContainer.getInlineRecordContainer(o);i.classList.contains(States.visible)&&(InlineControlContainer.collapseElement(i,o),InlineControlContainer.isNewRecord(o)?InlineControlContainer.updateExpandedCollapsedStateLocally(o,!1):n.push(t))}}return n}getFormFieldForElements(){const e=document.getElementsByName(this.container.dataset.formField);return e.length>0?e[0]:null}redrawSortingButtons(e,t=[]){if(0===t.length){const e=this.getFormFieldForElements();null!==e&&(t=Utility.trimExplode(",",e.value))}0!==t.length&&t.forEach((n,o)=>{const i=InlineControlContainer.getInlineRecordContainer(e+Separators.structureSeparator+n).dataset.objectIdHash+"_header",r=document.getElementById(i),a=r.querySelector('[data-action="sort"][data-direction="'+SortDirections.UP+'"]');if(null!==a){let e="actions-move-up";0===o?(a.classList.add("disabled"),e="empty-empty"):a.classList.remove("disabled"),Icons.getIcon(e,Icons.sizes.small).then(e=>{a.replaceChild(document.createRange().createContextualFragment(e),a.querySelector(".t3js-icon"))})}const s=r.querySelector('[data-action="sort"][data-direction="'+SortDirections.DOWN+'"]');if(null!==s){let e="actions-move-down";o===t.length-1?(s.classList.add("disabled"),e="empty-empty"):s.classList.remove("disabled"),Icons.getIcon(e,Icons.sizes.small).then(e=>{s.replaceChild(document.createRange().createContextualFragment(e),s.querySelector(".t3js-icon"))})}})}isBelowMax(){const e=this.getFormFieldForElements();if(null===e)return!0;if(void 0!==TYPO3.settings.FormEngineInline.config[this.container.dataset.objectGroup]){if(Utility.trimExplode(",",e.value).length>=TYPO3.settings.FormEngineInline.config[this.container.dataset.objectGroup].max)return!1;if(this.hasObjectGroupDefinedUniqueConstraints()){const e=TYPO3.settings.FormEngineInline.unique[this.container.dataset.objectGroup];if(e.used.length>=e.max&&e.max>=0)return!1}}return!0}isUniqueElementUsed(e,t){if(!this.hasObjectGroupDefinedUniqueConstraints())return!1;const n=TYPO3.settings.FormEngineInline.unique[this.container.dataset.objectGroup],o=InlineControlContainer.getValuesFromHashMap(n.used);if("select"===n.type&&-1!==o.indexOf(e))return!0;if("groupdb"===n.type)for(let n=o.length-1;n>=0;n--)if(o[n].table===t&&o[n].uid===e)return!0;return!1}removeUsed(e){if(!this.hasObjectGroupDefinedUniqueConstraints())return;const t=TYPO3.settings.FormEngineInline.unique[this.container.dataset.objectGroup];if("select"!==t.type)return;let n=e.querySelector('[name="data['+t.table+"]["+e.dataset.objectUid+"]["+t.field+']"]');const o=InlineControlContainer.getValuesFromHashMap(t.used);if(null!==n){const e=n.options[n.selectedIndex].value;for(let t of o)t!==e&&InlineControlContainer.removeSelectOptionByValue(n,t)}}setUnique(e,t){if(!this.hasObjectGroupDefinedUniqueConstraints())return;const n=document.getElementById(this.container.dataset.objectGroup+"_selector"),o=TYPO3.settings.FormEngineInline.unique[this.container.dataset.objectGroup];if("select"===o.type){if(!o.selector||-1!==o.max){const i=this.getFormFieldForElements(),r=this.container.dataset.objectGroup+Separators.structureSeparator+e;let a=InlineControlContainer.getInlineRecordContainer(r).querySelector('[name="data['+o.table+"]["+e+"]["+o.field+']"]');const s=InlineControlContainer.getValuesFromHashMap(o.used);if(null!==n){if(null!==a){for(let e of s)InlineControlContainer.removeSelectOptionByValue(a,e);o.selector||(t=a.options[0].value,a.options[0].selected=!0,this.updateUnique(a,i,e),this.handleChangedField(a,this.container.dataset.objectGroup+"["+e+"]"))}for(let e of s)InlineControlContainer.removeSelectOptionByValue(a,e);void 0!==o.used.length&&(o.used={}),o.used[e]={table:o.elTable,uid:t}}if(null!==i&&InlineControlContainer.selectOptionValueExists(n,t)){const n=Utility.trimExplode(",",i.value);for(let i of n)a=document.querySelector('[name="data['+o.table+"]["+i+"]["+o.field+']"]'),null!==a&&i!==e&&InlineControlContainer.removeSelectOptionByValue(a,t)}}}else"groupdb"===o.type&&(o.used[e]={table:o.elTable,uid:t});"select"===o.selector&&InlineControlContainer.selectOptionValueExists(n,t)&&(InlineControlContainer.removeSelectOptionByValue(n,t),o.used[e]={table:o.elTable,uid:t})}updateUnique(e,t,n){if(!this.hasObjectGroupDefinedUniqueConstraints())return;const o=TYPO3.settings.FormEngineInline.unique[this.container.dataset.objectGroup],i=o.used[n];if("select"===o.selector){const t=document.getElementById(this.container.dataset.objectGroup+"_selector");InlineControlContainer.removeSelectOptionByValue(t,e.value),void 0!==i&&InlineControlContainer.reAddSelectOption(t,i,o)}if(o.selector&&-1===o.max)return;if(!o||null===t)return;const r=Utility.trimExplode(",",t.value);let a;for(let t of r)a=document.querySelector('[name="data['+o.table+"]["+t+"]["+o.field+']"]'),null!==a&&a!==e&&(InlineControlContainer.removeSelectOptionByValue(a,e.value),void 0!==i&&InlineControlContainer.reAddSelectOption(a,i,o));o.used[n]=e.value}revertUnique(e){if(!this.hasObjectGroupDefinedUniqueConstraints())return;const t=TYPO3.settings.FormEngineInline.unique[this.container.dataset.objectGroup],n=this.container.dataset.objectGroup+Separators.structureSeparator+e,o=InlineControlContainer.getInlineRecordContainer(n);let i=o.querySelector('[name="data['+t.table+"]["+o.dataset.objectUid+"]["+t.field+']"]');if("select"===t.type){let n;if(null!==i)n=i.value;else{if(""===o.dataset.tableUniqueOriginalValue)return;n=o.dataset.tableUniqueOriginalValue}if("select"===t.selector&&!isNaN(parseInt(n,10))){const e=document.getElementById(this.container.dataset.objectGroup+"_selector");InlineControlContainer.reAddSelectOption(e,n,t)}if(t.selector&&-1===t.max)return;const r=this.getFormFieldForElements();if(null===r)return;const a=Utility.trimExplode(",",r.value);let s;for(let e=0;e<a.length;e++)s=document.querySelector('[name="data['+t.table+"]["+a[e]+"]["+t.field+']"]'),null!==s&&InlineControlContainer.reAddSelectOption(s,n,t);delete t.used[e]}else"groupdb"===t.type&&delete t.used[e]}hasObjectGroupDefinedUniqueConstraints(){return void 0!==TYPO3.settings.FormEngineInline.unique&&void 0!==TYPO3.settings.FormEngineInline.unique[this.container.dataset.objectGroup]}handleChangedField(e,t){let n;n=e instanceof HTMLSelectElement?e.options[e.selectedIndex].text:e.value,document.getElementById(t+"_label").textContent=n.length?n:this.noTitleString}getAppearance(){if(null===this.appearance&&(this.appearance={},"string"==typeof this.container.dataset.appearance))try{this.appearance=JSON.parse(this.container.dataset.appearance)}catch(e){console.error(e)}return this.appearance}}export default InlineControlContainer;
\ No newline at end of file
-- 
GitLab