From 42b49a9990f4ed8515464d77ddcfa84903032680 Mon Sep 17 00:00:00 2001
From: Benjamin Franzke <ben@bnf.dev>
Date: Wed, 9 Aug 2023 13:39:16 +0200
Subject: [PATCH] [TASK] Migrate @typo3/form/backend/form-editor/mediator to
 TypeScript

Resolves: #101738
Related: #82577
Releases: main, 12.4
Change-Id: Id857430ae81322cf9197ba6df422780695f59f50
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/80728
Tested-by: Benjamin Franzke <ben@bnf.dev>
Tested-by: core-ci <typo3@b13.com>
Reviewed-by: Benjamin Franzke <ben@bnf.dev>
---
 .../TypeScript/form/backend/form-editor.ts    |    5 +-
 .../form/backend/form-editor/mediator.ts      |  931 ++++++++++++++
 .../Sources/TypeScript/form/backend/helper.ts |    2 +-
 .../backend/form-editor/mediator.js           | 1091 +----------------
 4 files changed, 934 insertions(+), 1095 deletions(-)
 create mode 100644 Build/Sources/TypeScript/form/backend/form-editor/mediator.ts

diff --git a/Build/Sources/TypeScript/form/backend/form-editor.ts b/Build/Sources/TypeScript/form/backend/form-editor.ts
index 9b3a11f750c1..0baab2f5811a 100644
--- a/Build/Sources/TypeScript/form/backend/form-editor.ts
+++ b/Build/Sources/TypeScript/form/backend/form-editor.ts
@@ -47,10 +47,7 @@ const assert = Core.assert;
 type AdditionalViewModelModules = JavaScriptItemPayload[];
 
 type ViewModel = typeof import('./form-editor/view-model');
-
-export interface Mediator {
-  bootstrap(formEditorInstance: FormEditor, viewModel: ViewModel): void;
-}
+type Mediator = typeof import('./form-editor/mediator');
 
 export type FormEditorConfiguration = {
   prototypeName: string,
diff --git a/Build/Sources/TypeScript/form/backend/form-editor/mediator.ts b/Build/Sources/TypeScript/form/backend/form-editor/mediator.ts
new file mode 100644
index 000000000000..eeafcda8f4d7
--- /dev/null
+++ b/Build/Sources/TypeScript/form/backend/form-editor/mediator.ts
@@ -0,0 +1,931 @@
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+/**
+ * Module: @typo3/form/backend/form-editor/mediator
+ */
+import $ from 'jquery';
+import * as Helper from '@typo3/form/backend/form-editor/helper';
+
+import type {
+  FormEditor,
+} from '@typo3/form/backend/form-editor';
+import type {
+  ApplicationState,
+  Utility,
+  FormEditorDefinitions,
+  FormElement,
+  FormElementDefinition,
+  PublisherSubscriber,
+} from '@typo3/form/backend/form-editor/core';
+import type {
+  Configuration as HelperConfiguration,
+} from '@typo3/form/backend/form-editor/helper';
+import type {
+  InsertElementsModalConfiguration
+} from '@typo3/form/backend/form-editor/modals-component';
+
+type ViewModel = typeof import('./view-model');
+
+let formEditorApp: FormEditor = null;
+
+let viewModel: ViewModel = null;
+
+
+function getFormEditorApp(): FormEditor {
+  return formEditorApp;
+}
+
+function getViewModel(): ViewModel {
+  return viewModel;
+}
+
+function getUtility(): Utility {
+  return getFormEditorApp().getUtility();
+}
+
+function assert(test: boolean|(() => boolean), message: string, messageCode: number): void {
+  return getFormEditorApp().assert(test, message, messageCode);
+}
+
+function getHelper(_configuration?: HelperConfiguration): typeof Helper {
+  if (getUtility().isUndefinedOrNull(_configuration)) {
+    return Helper.setConfiguration(getViewModel().getConfiguration());
+  }
+  return Helper.setConfiguration(_configuration);
+}
+
+function getCurrentlySelectedFormElement(): FormElement {
+  return getFormEditorApp().getCurrentlySelectedFormElement();
+}
+
+function getPublisherSubscriber(): PublisherSubscriber {
+  return getFormEditorApp().getPublisherSubscriber();
+}
+
+function getRootFormElement(): FormElement {
+  return getFormEditorApp().getRootFormElement();
+}
+
+function subscribeEvents(): void {
+
+  /* *********************************************************
+   * Misc
+   * ********************************************************/
+
+  window.onbeforeunload = function(e): undefined | string {
+    if (!getFormEditorApp().getUnsavedContent()) {
+      return undefined;
+    }
+    e = e || window.event;
+    if (e) {
+      e.returnValue = getFormEditorApp().getFormElementDefinition(getRootFormElement(), 'modalCloseDialogMessage');
+    }
+    return getFormEditorApp().getFormElementDefinition(getRootFormElement(), 'modalCloseDialogTitle');
+  };
+
+  /**
+   * @subscribe view/ready
+   */
+  getPublisherSubscriber().subscribe('view/ready', (): void => {
+    getViewModel().onViewReadyBatch();
+  });
+
+  /**
+   * @subscribe core/applicationState/add
+   */
+  getPublisherSubscriber().subscribe('core/applicationState/add', (
+    topic: string,
+    [
+      applicationState, // eslint-disable-line @typescript-eslint/no-unused-vars
+      currentStackPointer,
+      currentStackSize
+    ]: [
+      ApplicationState,
+      number,
+      number
+    ]
+  ): void => {
+    getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderRedo')));
+    if (currentStackSize > 1 && currentStackPointer <= currentStackSize) {
+      getViewModel().enableButton($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderUndo')));
+    } else {
+      getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderUndo')));
+    }
+  });
+
+  /* *********************************************************
+   * Ajax
+   * ********************************************************/
+
+  /**
+   * @subscribe core/ajax/saveFormDefinition/success
+   */
+  getPublisherSubscriber().subscribe('core/ajax/saveFormDefinition/success', (
+    topic: string,
+    [data]: [{ status: string, formDefinition: FormElementDefinition }]
+  ): void => {
+    getFormEditorApp().setUnsavedContent(false);
+    getViewModel().showSaveSuccessMessage();
+    getViewModel().showSaveButtonSaveIcon();
+
+    getFormEditorApp().setFormDefinition(data.formDefinition);
+
+    getViewModel().addStructureRootElementSelection();
+    getFormEditorApp().setCurrentlySelectedFormElement(getRootFormElement());
+    getViewModel().setStructureRootElementTitle();
+    getViewModel().setStageHeadline();
+    getViewModel().renderAbstractStageArea();
+    getViewModel().renewStructure();
+    getViewModel().renderPagination();
+    getViewModel().renderInspectorEditors();
+  });
+
+  /**
+   * @subscribe core/ajax/saveFormDefinition/error
+   */
+  getPublisherSubscriber().subscribe('core/ajax/saveFormDefinition/error', (
+    topic: string,
+    [data]: [{ status: string, message: string, code: number }]
+  ): void => {
+    getViewModel().showSaveButtonSaveIcon();
+    getViewModel().showSaveErrorMessage({ message: data.message });
+  });
+
+  /**
+   * @subscribe core/ajax/renderFormDefinitionPage/success
+   */
+  getPublisherSubscriber().subscribe('core/ajax/renderFormDefinitionPage/success', (
+    topic: string,
+    [htmldata, pageIndex]: [string, number] // eslint-disable-line @typescript-eslint/no-unused-vars
+  ): void => {
+    getViewModel().renderPreviewStageArea(htmldata);
+  });
+
+  /**
+   * @subscribe core/ajax/saveFormDefinition/error
+   */
+  getPublisherSubscriber().subscribe('core/ajax/error', (
+    topic: string,
+    [jqXHR, textStatus, errorThrown]: [JQueryXHR, string, string]
+  ): void => {
+    if (jqXHR.status !== 0) {
+      getViewModel().showErrorFlashMessage(textStatus, errorThrown);
+      getViewModel().renderPreviewStageArea(jqXHR.responseText);
+    }
+  });
+
+  /* *********************************************************
+   * Header
+   * ********************************************************/
+
+  /**
+   * @subscribe view/header/button/save/clicked
+   */
+  getPublisherSubscriber().subscribe('view/header/button/save/clicked', (): void => {
+    if (getFormEditorApp().validationResultsHasErrors(getFormEditorApp().validateFormElementRecursive(getRootFormElement(), true))) {
+      getViewModel().showValidationErrorsModal();
+    } else {
+      getViewModel().showSaveButtonSpinnerIcon();
+      getFormEditorApp().saveFormDefinition();
+    }
+  });
+
+  /**
+   * @subscribe view/header/formSettings/clicked
+   */
+  getPublisherSubscriber().subscribe('view/header/formSettings/clicked', (): void => {
+    getViewModel().addStructureRootElementSelection();
+    getFormEditorApp().setCurrentlySelectedFormElement(getRootFormElement());
+    getViewModel().renderAbstractStageArea();
+    getViewModel().renewStructure();
+    getViewModel().renderPagination();
+    getViewModel().renderInspectorEditors();
+  });
+
+  /**
+   * @subscribe view/header/button/newPage/clicked
+   */
+  getPublisherSubscriber().subscribe('view/header/button/newPage/clicked', (
+    topic: string,
+    [targetEvent]: ['view/insertPages/perform']
+  ): void => {
+    if (getFormEditorApp().isRootFormElementSelected()) {
+      getViewModel().selectPageBatch(0);
+    }
+    getViewModel().showInsertPagesModal(targetEvent);
+  });
+
+  /**
+   * @subscribe view/header/button/close/clicked
+   */
+  getPublisherSubscriber().subscribe('view/header/button/close/clicked', (): void => {
+    getViewModel().showCloseConfirmationModal();
+  });
+
+  /**
+   * @subscribe view/undoButton/clicked
+   */
+  getPublisherSubscriber().subscribe('view/undoButton/clicked', (): void => {
+    getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderUndo')));
+    getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderRedo')));
+    getFormEditorApp().undoApplicationState();
+
+    if (getViewModel().getPreviewMode()) {
+      getFormEditorApp().renderCurrentFormPage();
+    } else {
+      getViewModel().renderAbstractStageArea();
+    }
+    getFormEditorApp().setUnsavedContent(true);
+
+    getViewModel().renewStructure();
+    getViewModel().renderPagination();
+    getViewModel().renderInspectorEditors();
+  });
+
+  /**
+   * @subscribe view/redoButton/clicked
+   */
+  getPublisherSubscriber().subscribe('view/redoButton/clicked', (): void => {
+    getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderUndo')));
+    getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderRedo')));
+    getFormEditorApp().redoApplicationState();
+
+    if (getViewModel().getPreviewMode()) {
+      getFormEditorApp().renderCurrentFormPage();
+    } else {
+      getViewModel().renderAbstractStageArea();
+    }
+    getFormEditorApp().setUnsavedContent(true);
+
+    getViewModel().renewStructure();
+    getViewModel().renderPagination();
+    getViewModel().renderInspectorEditors();
+  });
+
+  /* *********************************************************
+   * Stage
+   * ********************************************************/
+
+  /**
+   * @subscribe view/stage/element/clicked
+   */
+  getPublisherSubscriber().subscribe('view/stage/element/clicked', (
+    topic: string,
+    [formElementIdentifierPath]: [string]
+  ): void => {
+    if (getCurrentlySelectedFormElement().get('__identifierPath') !== formElementIdentifierPath) {
+      getFormEditorApp().setCurrentlySelectedFormElement(formElementIdentifierPath);
+      getViewModel().renewStructure();
+      getViewModel().refreshSelectedElementItemsBatch();
+      getViewModel().addAbstractViewValidationResults();
+      getViewModel().renderInspectorEditors();
+    }
+  });
+
+  /**
+   * @subscribe view/stage/abstract/elementToolbar/button/newElement/clicked
+   */
+  getPublisherSubscriber().subscribe('view/stage/abstract/elementToolbar/button/newElement/clicked', (
+    topic: string,
+    [
+      targetEvent,
+      modalConfiguration
+    ]: [
+      'view/insertElements/perform/after' | 'view/insertElements/perform/inside',
+      InsertElementsModalConfiguration
+    ]
+  ): void => {
+    if (getFormEditorApp().isRootFormElementSelected()) {
+      getViewModel().selectPageBatch(0);
+    }
+    getViewModel().showInsertElementsModal(targetEvent, modalConfiguration);
+  });
+
+  /**
+   * @subscribe view/newElementButton/clicked
+   */
+  getPublisherSubscriber().subscribe('view/stage/abstract/button/newElement/clicked', (
+    topic: string,
+    [
+      targetEvent,
+      modalConfiguration
+    ]: [
+      'view/insertElements/perform/after' | 'view/insertElements/perform/inside',
+      InsertElementsModalConfiguration?
+    ]
+  ): void => {
+    if (getFormEditorApp().isRootFormElementSelected()) {
+      getViewModel().selectPageBatch(0);
+    }
+    getViewModel().showInsertElementsModal(targetEvent, modalConfiguration || undefined);
+  });
+
+  /**
+   * @subscribe view/stage/abstract/dnd/start
+   */
+  getPublisherSubscriber().subscribe('view/stage/abstract/dnd/start', (
+    topic: string,
+    [
+      draggedFormElementDomElement,
+      draggedFormPlaceholderDomElement
+    ]: [
+      HTMLElement | JQuery,
+      HTMLElement | JQuery
+    ]
+  ): void => {
+    getViewModel().onAbstractViewDndStartBatch(
+      draggedFormElementDomElement,
+      draggedFormPlaceholderDomElement
+    );
+  });
+
+  /**
+   * @subscribe view/stage/abstract/dnd/stop
+   */
+  getPublisherSubscriber().subscribe('view/stage/abstract/dnd/stop', (
+    topic: string,
+    [draggedFormElementIdentifierPath]: [string]
+  ): void => {
+    getFormEditorApp().setCurrentlySelectedFormElement(draggedFormElementIdentifierPath);
+    getViewModel().renewStructure();
+    getViewModel().renderAbstractStageArea(false, false);
+    getViewModel().refreshSelectedElementItemsBatch();
+    getViewModel().addAbstractViewValidationResults();
+    getViewModel().renderInspectorEditors();
+  });
+
+  /**
+   * @subscribe view/stage/abstract/dnd/change
+   */
+  getPublisherSubscriber().subscribe('view/stage/abstract/dnd/change', (
+    topic: string,
+    [
+      placeholderDomElement,
+      parentFormElementIdentifierPath,
+      enclosingCompositeFormElement
+    ]: [
+      JQuery,
+      string,
+      FormElement
+    ]
+  ): void => {
+    getViewModel().onAbstractViewDndChangeBatch(
+      placeholderDomElement,
+      parentFormElementIdentifierPath,
+      enclosingCompositeFormElement
+    );
+  });
+
+  /**
+   * @subscribe view/stage/abstract/dnd/update
+   */
+  getPublisherSubscriber().subscribe('view/stage/abstract/dnd/update', (
+    topic: string,
+    [
+      movedDomElement,
+      movedFormElementIdentifierPath,
+      previousFormElementIdentifierPath,
+      nextFormElementIdentifierPath
+    ]: [
+      JQuery,
+      string,
+      string,
+      string
+    ]
+  ): void => {
+    getViewModel().onAbstractViewDndUpdateBatch(
+      movedDomElement,
+      movedFormElementIdentifierPath,
+      previousFormElementIdentifierPath,
+      nextFormElementIdentifierPath
+    );
+  });
+
+  /**
+   * @subscribe view/viewModeButton/abstract/clicked
+   */
+  getPublisherSubscriber().subscribe('view/viewModeButton/abstract/clicked', (): void => {
+    if (getViewModel().getPreviewMode()) {
+      getViewModel().setPreviewMode(false);
+      getViewModel().renderAbstractStageArea();
+    }
+  });
+
+  /**
+   * @subscribe view/viewModeButton/preview/clicked
+   */
+  getPublisherSubscriber().subscribe('view/viewModeButton/preview/clicked', (): void => {
+    if (!getViewModel().getPreviewMode()) {
+      getViewModel().setPreviewMode(true);
+      getFormEditorApp().renderCurrentFormPage();
+    }
+  });
+
+  /**
+   * @subscribe view/paginationPrevious/clicked
+   */
+  getPublisherSubscriber().subscribe('view/paginationPrevious/clicked', (): void => {
+    getViewModel().selectPageBatch(getFormEditorApp().getCurrentlySelectedPageIndex() - 1);
+    if (getViewModel().getPreviewMode()) {
+      getFormEditorApp().renderCurrentFormPage();
+    } else {
+      getViewModel().renderAbstractStageArea();
+    }
+  });
+
+  /**
+   * @subscribe view/paginationNext/clicked
+   */
+  getPublisherSubscriber().subscribe('view/paginationNext/clicked', (): void => {
+    getViewModel().selectPageBatch(getFormEditorApp().getCurrentlySelectedPageIndex() + 1);
+    if (getViewModel().getPreviewMode()) {
+      getFormEditorApp().renderCurrentFormPage();
+    } else {
+      getViewModel().renderAbstractStageArea();
+    }
+  });
+
+  /**
+   * @subscribe view/stage/abstract/render/postProcess
+   */
+  getPublisherSubscriber().subscribe('view/stage/abstract/render/postProcess', (): void => {
+    getViewModel().renderUndoRedo();
+  });
+
+  /**
+   * @subscribe view/stage/preview/render/postProcess
+   */
+  getPublisherSubscriber().subscribe('view/stage/preview/render/postProcess', (): void => {
+    getViewModel().renderUndoRedo();
+  });
+
+  /* *********************************************************
+   * Structure
+   * ********************************************************/
+
+  /**
+   * @subscribe view/tree/node/clicked
+   */
+  getPublisherSubscriber().subscribe('view/tree/node/clicked', (
+    topic: string,
+    [formElementIdentifierPath]: [string]
+  ): void => {
+    let oldPageIndex;
+    if (getCurrentlySelectedFormElement().get('__identifierPath') !== formElementIdentifierPath) {
+      oldPageIndex = getFormEditorApp().getCurrentlySelectedPageIndex();
+      getFormEditorApp().setCurrentlySelectedFormElement(formElementIdentifierPath);
+      if (oldPageIndex !== getFormEditorApp().getCurrentlySelectedPageIndex()) {
+        getViewModel().renderAbstractStageArea();
+      } else {
+        getViewModel().renderAbstractStageArea(false);
+      }
+      getViewModel().renderPagination();
+      getViewModel().renderInspectorEditors();
+    }
+  });
+
+  /**
+   * @subscribe view/tree/node/clicked
+   */
+  getPublisherSubscriber().subscribe('view/tree/node/changed', (
+    topic: string,
+    [formElementIdentifierPath, newLabel]: [string, string]
+  ): void => {
+    const formElement = getFormEditorApp().getFormElementByIdentifierPath(formElementIdentifierPath);
+    formElement.set('label', newLabel);
+    getViewModel().getStructure().setTreeNodeTitle(null, formElement);
+    if(getCurrentlySelectedFormElement().get('__identifierPath') === formElementIdentifierPath) {
+      getViewModel().renderInspectorEditors(formElementIdentifierPath, false);
+    }
+  });
+
+  /**
+   * @subscribe view/structure/root/selected
+   */
+  getPublisherSubscriber().subscribe('view/structure/root/selected', (): void => {
+    if (!getFormEditorApp().isRootFormElementSelected()) {
+      getViewModel().addStructureRootElementSelection();
+      getFormEditorApp().setCurrentlySelectedFormElement(getRootFormElement());
+      getViewModel().renderAbstractStageArea();
+      getViewModel().renewStructure();
+      getViewModel().renderPagination();
+      getViewModel().renderInspectorEditors();
+    }
+  });
+
+  /**
+   * @subscribe view/header/button/newPage/clicked
+   */
+  getPublisherSubscriber().subscribe('view/structure/button/newPage/clicked', (
+    topic: string,
+    [targetEvent]: ['view/insertPages/perform']
+  ): void => {
+    if (getFormEditorApp().isRootFormElementSelected()) {
+      getViewModel().selectPageBatch(0);
+    }
+    getViewModel().showInsertPagesModal(targetEvent);
+  });
+
+  /**
+   * @subscribe view/tree/dnd/stop
+   */
+  getPublisherSubscriber().subscribe('view/tree/dnd/stop', (
+    topic: string,
+    [draggedFormElementIdentifierPath]: [string]
+  ): void => {
+    getFormEditorApp().setCurrentlySelectedFormElement(draggedFormElementIdentifierPath);
+    getViewModel().renewStructure();
+    getViewModel().renderPagination();
+    getViewModel().renderAbstractStageArea();
+    getViewModel().renderInspectorEditors();
+  });
+
+  /**
+   * @subscribe view/tree/dnd/change
+   */
+  getPublisherSubscriber().subscribe('view/tree/dnd/change', (
+    topic: string,
+    [
+      placeholderDomElement,
+      parentFormElementIdentifierPath,
+      enclosingCompositeFormElement
+    ]: [
+      JQuery,
+      string,
+      FormElement
+    ]
+  ): void => {
+    getViewModel().onStructureDndChangeBatch(
+      placeholderDomElement,
+      parentFormElementIdentifierPath,
+      enclosingCompositeFormElement
+    );
+  });
+
+  /**
+   * @subscribe view/tree/dnd/update
+   */
+  getPublisherSubscriber().subscribe('view/tree/dnd/update', (
+    topic: string,
+    [
+      movedDomElement,
+      movedFormElementIdentifierPath,
+      previousFormElementIdentifierPath,
+      nextFormElementIdentifierPath
+    ]: [
+      JQuery,
+      string,
+      string,
+      string
+    ]
+  ): void => {
+    getViewModel().onStructureDndUpdateBatch(
+      movedDomElement,
+      movedFormElementIdentifierPath,
+      previousFormElementIdentifierPath,
+      nextFormElementIdentifierPath
+    );
+  });
+
+  /**
+   * @subscribe view/structure/renew/postProcess
+   */
+  getPublisherSubscriber().subscribe('view/structure/renew/postProcess', (): void => {
+    getViewModel().addStructureValidationResults();
+  });
+
+  /* *********************************************************
+   * Inspector
+   * ********************************************************/
+
+  /**
+   * @subscribe view/inspector/removeCollectionElement/perform
+   */
+  getPublisherSubscriber().subscribe('view/inspector/removeCollectionElement/perform', (
+    topic: string,
+    [
+      collectionElementIdentifier,
+      collectionName,
+      formElement
+    ]: [
+      string,
+      keyof FormEditorDefinitions,
+      FormElement?
+    ]
+  ): void => {
+    getViewModel().removePropertyCollectionElement(
+      collectionElementIdentifier,
+      collectionName,
+      formElement || undefined
+    );
+  });
+
+  /**
+   * @subscribe view/inspector/collectionElement/selected
+   */
+  getPublisherSubscriber().subscribe('view/inspector/collectionElement/new/selected', (
+    topic: string,
+    [
+      collectionElementIdentifier,
+      collectionName,
+    ]: [
+      string,
+      keyof FormEditorDefinitions,
+    ]
+  ): void => {
+    getViewModel().createAndAddPropertyCollectionElement(
+      collectionElementIdentifier,
+      collectionName
+    );
+  });
+
+  /**
+   * @subscribe view/inspector/collectionElement/selected
+   */
+  getPublisherSubscriber().subscribe('view/inspector/collectionElement/existing/selected', (
+    topic: string,
+    [
+      collectionElementIdentifier,
+      collectionName,
+    ]: [
+      string,
+      keyof FormEditorDefinitions,
+    ]
+  ): void => {
+    getViewModel().renderInspectorCollectionElementEditors(
+      collectionName,
+      collectionElementIdentifier
+    );
+  });
+
+  /**
+   * @subscribe view/inspector/collectionElements/dnd/update
+   * @throws 1477407673
+   */
+  getPublisherSubscriber().subscribe('view/inspector/collectionElements/dnd/update', (
+    topic: string,
+    [
+      movedCollectionElementIdentifier,
+      previousCollectionElementIdentifier,
+      nextCollectionElementIdentifier,
+      collectionName
+    ]: [
+      string,
+      string,
+      string,
+      keyof FormEditorDefinitions
+    ]
+  ): void => {
+    if (nextCollectionElementIdentifier) {
+      getViewModel().movePropertyCollectionElement(
+        movedCollectionElementIdentifier,
+        'before',
+        nextCollectionElementIdentifier,
+        collectionName
+      );
+    } else if (previousCollectionElementIdentifier) {
+      getViewModel().movePropertyCollectionElement(
+        movedCollectionElementIdentifier,
+        'after',
+        previousCollectionElementIdentifier,
+        collectionName
+      );
+    } else {
+      assert(false, 'Next element or previous element need to be set.', 1477407673);
+    }
+  });
+
+  /* *********************************************************
+   * Form element
+   * ********************************************************/
+
+  /**
+   * @subscribe core/formElement/somePropertyChanged
+   */
+  getPublisherSubscriber().subscribe('core/formElement/somePropertyChanged', (
+    topic: string,
+    [
+      propertyPath,
+      value, // eslint-disable-line @typescript-eslint/no-unused-vars
+      oldValue, // eslint-disable-line @typescript-eslint/no-unused-vars
+      formElementIdentifierPath
+    ]: [
+      string,
+      unknown | undefined,
+      unknown | undefined,
+      string?,
+    ]
+  ): void => {
+    if ('renderables' !== propertyPath) {
+      if (!getFormEditorApp().isRootFormElementSelected() && 'label' === propertyPath) {
+        getViewModel().getStructure().setTreeNodeTitle();
+      } else if (!getFormEditorApp().getUtility().isUndefinedOrNull(formElementIdentifierPath) && getRootFormElement().get('__identifierPath') === formElementIdentifierPath) {
+        getViewModel().setStructureRootElementTitle();
+        getViewModel().setStageHeadline();
+      }
+
+      if (getViewModel().getPreviewMode()) {
+        getFormEditorApp().renderCurrentFormPage();
+      } else {
+        getViewModel().renderAbstractStageArea(false, false);
+      }
+      getViewModel().addStructureValidationResults();
+    }
+
+    getFormEditorApp().setUnsavedContent(true);
+  });
+
+  /**
+   * @subscribe view/formElement/removed
+   */
+  getPublisherSubscriber().subscribe('view/formElement/removed', (
+    topic: string,
+    [parentFormElement]: [FormElement]
+  ): void => {
+    getFormEditorApp().setCurrentlySelectedFormElement(parentFormElement);
+    getViewModel().renewStructure();
+    getViewModel().renderAbstractStageArea();
+    getViewModel().renderPagination();
+    getViewModel().renderInspectorEditors();
+  });
+
+  /**
+   * @subscribe view/formElement/inserted
+   */
+  getPublisherSubscriber().subscribe('view/formElement/inserted', (
+    topic: string,
+    [newFormElement]: [FormElement]
+  ): void => {
+    getFormEditorApp().setCurrentlySelectedFormElement(newFormElement);
+    getViewModel().renewStructure();
+    getViewModel().renderAbstractStageArea();
+    getViewModel().renderPagination();
+    getViewModel().renderInspectorEditors();
+  });
+
+  /**
+   * @subscribe view/collectionElement/new/added
+   */
+  getPublisherSubscriber().subscribe('view/collectionElement/new/added', (): void => {
+    getViewModel().renderInspectorEditors();
+  });
+
+  /**
+   * @subscribe view/collectionElement/moved
+   */
+  getPublisherSubscriber().subscribe('view/collectionElement/moved', (): void => {
+    getViewModel().renderInspectorEditors(undefined, false);
+  });
+
+  /**
+   * @subscribe view/collectionElement/removed
+   */
+  getPublisherSubscriber().subscribe('view/collectionElement/removed', (): void => {
+    getViewModel().renderInspectorEditors(undefined, false);
+  });
+
+  /**
+   * @subscribe view/insertElements/perform/bottom
+   */
+  getPublisherSubscriber().subscribe('view/insertElements/perform/bottom', (
+    topic: string,
+    [formElementType]: [string]
+  ): void => {
+    const lastRenderable = getFormEditorApp().getLastTopLevelElementOnCurrentPage();
+    if (!lastRenderable) {
+      getViewModel().createAndAddFormElement(formElementType, getFormEditorApp().getCurrentlySelectedPage());
+    } else {
+      if (
+        !getFormEditorApp().getFormElementDefinition(lastRenderable, '_isTopLevelFormElement')
+        && getFormEditorApp().getFormElementDefinition(lastRenderable, '_isCompositeFormElement')
+      ) {
+        getViewModel().createAndAddFormElement(formElementType, getFormEditorApp().getCurrentlySelectedPage());
+      } else {
+        getViewModel().createAndAddFormElement(formElementType, lastRenderable);
+      }
+    }
+  });
+
+  /**
+   * @publish view/formElement/inserted
+   * @subscribe view/insertElements/perform/after
+   */
+  getPublisherSubscriber().subscribe('view/insertElements/perform/after', (
+    topic: string,
+    [formElementType]: [string]
+  ): void => {
+    let newFormElement;
+    newFormElement = getViewModel().createAndAddFormElement(formElementType, undefined, true);
+    newFormElement = getViewModel().moveFormElement(newFormElement, 'after', getFormEditorApp().getCurrentlySelectedFormElement());
+    getPublisherSubscriber().publish('view/formElement/inserted', [newFormElement]);
+  });
+
+  /**
+   * @subscribe view/insertElements/perform/inside
+   */
+  getPublisherSubscriber().subscribe('view/insertElements/perform/inside', (
+    topic: string,
+    [formElementType]: [string]
+  ): void => {
+    getViewModel().createAndAddFormElement(formElementType);
+  });
+
+  /**
+   * @subscribe view/insertElements/perform/after
+   */
+  getPublisherSubscriber().subscribe('view/insertPages/perform', (
+    topic: string,
+    [formElementType]: [string]
+  ): void => {
+    getViewModel().createAndAddFormElement(formElementType);
+  });
+
+  /* *********************************************************
+   * Modals
+   * ********************************************************/
+
+  /**
+   * @subscribe view/modal/close/perform
+   */
+  getPublisherSubscriber().subscribe('view/modal/close/perform', (): void => {
+    getFormEditorApp().setUnsavedContent(false);
+    getViewModel().closeEditor();
+  });
+
+  /**
+   * @subscribe view/modal/removeFormElement/perform
+   */
+  getPublisherSubscriber().subscribe('view/modal/removeFormElement/perform', (
+    topic: string,
+    [formElement]: [FormElement]
+  ): void => {
+    getViewModel().removeFormElement(formElement);
+  });
+
+  /**
+   * @subscribe view/modal/removeCollectionElement/perform
+   */
+  getPublisherSubscriber().subscribe('view/modal/removeCollectionElement/perform', (
+    topic: string,
+    [
+      collectionElementIdentifier,
+      collectionName,
+      formElement,
+    ]: [
+      string,
+      keyof FormEditorDefinitions,
+      FormElement
+    ]
+  ): void => {
+    getViewModel().removePropertyCollectionElement(
+      collectionElementIdentifier,
+      collectionName,
+      formElement,
+    );
+  });
+
+  /**
+   * @subscribe view/modal/validationErrors/element/clicked
+   */
+  getPublisherSubscriber().subscribe('view/modal/validationErrors/element/clicked', (
+    topic: string,
+    [formElementIdentifierPath]: [string]
+  ): void => {
+    let oldPageIndex;
+    if (getCurrentlySelectedFormElement().get('__identifierPath') !== formElementIdentifierPath) {
+      oldPageIndex = getFormEditorApp().getCurrentlySelectedPageIndex();
+      getFormEditorApp().setCurrentlySelectedFormElement(formElementIdentifierPath);
+
+      if (getViewModel().getPreviewMode()) {
+        getViewModel().setPreviewMode(false);
+      }
+
+      if (oldPageIndex !== getFormEditorApp().getCurrentlySelectedPageIndex()) {
+        getViewModel().renderAbstractStageArea();
+      } else {
+        getViewModel().renderAbstractStageArea(false);
+      }
+
+      getViewModel().renderPagination();
+      getViewModel().renderInspectorEditors();
+    }
+  });
+}
+
+export function bootstrap(_formEditorApp: FormEditor, _viewModel: ViewModel): void {
+  formEditorApp = _formEditorApp;
+  viewModel = _viewModel;
+  Helper.bootstrap(formEditorApp);
+  subscribeEvents();
+}
diff --git a/Build/Sources/TypeScript/form/backend/helper.ts b/Build/Sources/TypeScript/form/backend/helper.ts
index 32d08f1ffc2a..08385adf4c6e 100644
--- a/Build/Sources/TypeScript/form/backend/helper.ts
+++ b/Build/Sources/TypeScript/form/backend/helper.ts
@@ -33,7 +33,7 @@ export class Helper {
       ]).then((modules: [any, any, any]) =>
         ((
           app: typeof import('@typo3/form/backend/form-editor'),
-          mediator: import('@typo3/form/backend/form-editor').Mediator,
+          mediator: typeof import('@typo3/form/backend/form-editor/mediator'),
           viewModel: typeof import('@typo3/form/backend/form-editor/view-model')
         ) => {
           window.TYPO3.FORMEDITOR_APP = app.getInstance(options, mediator, viewModel).run();
diff --git a/typo3/sysext/form/Resources/Public/JavaScript/backend/form-editor/mediator.js b/typo3/sysext/form/Resources/Public/JavaScript/backend/form-editor/mediator.js
index 044483d810e6..f5589a1421b1 100644
--- a/typo3/sysext/form/Resources/Public/JavaScript/backend/form-editor/mediator.js
+++ b/typo3/sysext/form/Resources/Public/JavaScript/backend/form-editor/mediator.js
@@ -10,1093 +10,4 @@
  *
  * The TYPO3 project - inspiring people to share!
  */
-
-/**
- * Module: @typo3/form/backend/form-editor/mediator
- */
-import $ from 'jquery';
-import * as Helper from '@typo3/form/backend/form-editor/helper.js';
-
-const {
-  bootstrap
-} = factory($, Helper);
-
-export {
-  bootstrap
-};
-
-function factory($, Helper) {
-  return (function($, Helper) {
-
-    /**
-     * @private
-     *
-     * @var object
-     */
-    var _formEditorApp = null;
-
-    /**
-     * @private
-     *
-     * @var object
-     */
-    var _viewModel = null;
-
-    /* *************************************************************
-     * Private Methods
-     * ************************************************************/
-
-    /**
-     * @private
-     *
-     * @return void
-     * @throws 1478268638
-     */
-    function _helperSetup() {
-      assert('function' === $.type(Helper.bootstrap),
-        'The view model helper does not implement the method "bootstrap"',
-        1478268638
-      );
-      Helper.bootstrap(getFormEditorApp());
-    };
-
-    /**
-     * @private
-     *
-     * @return object
-     */
-    function getFormEditorApp() {
-      return _formEditorApp;
-    };
-
-    /**
-     * @private
-     *
-     * @return object
-     */
-    function getViewModel() {
-      return _viewModel;
-    };
-
-    /**
-     * @private
-     *
-     * @return object
-     */
-    function getUtility() {
-      return getFormEditorApp().getUtility();
-    };
-
-    /**
-     * @private
-     *
-     * @param mixed test
-     * @param string message
-     * @param int messageCode
-     * @return void
-     */
-    function assert(test, message, messageCode) {
-      return getFormEditorApp().assert(test, message, messageCode);
-    };
-
-    /**
-     * @private
-     *
-     * @param object
-     * @return object
-     */
-    function getHelper(configuration) {
-      if (getUtility().isUndefinedOrNull(configuration)) {
-        return Helper.setConfiguration(getViewModel().getConfiguration());
-      }
-      return Helper.setConfiguration(configuration);
-    };
-
-    /**
-     * @private
-     *
-     * @return object
-     */
-    function getCurrentlySelectedFormElement() {
-      return getFormEditorApp().getCurrentlySelectedFormElement();
-    };
-
-    /**
-     * @private
-     *
-     * @return object
-     */
-    function getPublisherSubscriber() {
-      return getFormEditorApp().getPublisherSubscriber();
-    };
-
-    /**
-     * @private
-     *
-     * @return object
-     */
-    function getRootFormElement() {
-      return getFormEditorApp().getRootFormElement();
-    };
-
-    /**
-     * @private
-     *
-     * @return void
-     */
-    function _subscribeEvents() {
-
-      /* *********************************************************
-       * Misc
-       * ********************************************************/
-
-      /**
-       * @private
-       *
-       * @return string
-       */
-      window.onbeforeunload = function(e) {
-        if (!getFormEditorApp().getUnsavedContent()) {
-          return;
-        }
-        e = e || window.event;
-        if (e) {
-          e.returnValue = getFormEditorApp().getFormElementDefinition(getRootFormElement(), 'modalCloseDialogMessage');
-        }
-        return getFormEditorApp().getFormElementDefinition(getRootFormElement(), 'modalCloseDialogTitle');
-      };
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       * @return void
-       * @subscribe view/ready
-       */
-      getPublisherSubscriber().subscribe('view/ready', function(topic, args) {
-        getViewModel().onViewReadyBatch();
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = applicationState
-       *              args[1] = stackPointer
-       *              args[2] = stackSize
-       * @return void
-       * @subscribe core/applicationState/add
-       */
-      getPublisherSubscriber().subscribe('core/applicationState/add', function(topic, args) {
-        getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderRedo')));
-        if (args[2] > 1 && args[1] <= args[2]) {
-          getViewModel().enableButton($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderUndo')));
-        } else {
-          getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderUndo')));
-        }
-      });
-
-      /* *********************************************************
-       * Ajax
-       * ********************************************************/
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = response
-       * @return void
-       * @subscribe core/ajax/saveFormDefinition/success
-       */
-      getPublisherSubscriber().subscribe('core/ajax/saveFormDefinition/success', function(topic, args) {
-        getFormEditorApp().setUnsavedContent(false);
-        getViewModel().showSaveSuccessMessage();
-        getViewModel().showSaveButtonSaveIcon();
-
-        getFormEditorApp().setFormDefinition(args[0]['formDefinition']);
-
-        getViewModel().addStructureRootElementSelection();
-        getFormEditorApp().setCurrentlySelectedFormElement(getRootFormElement());
-        getViewModel().setStructureRootElementTitle();
-        getViewModel().setStageHeadline();
-        getViewModel().renderAbstractStageArea();
-        getViewModel().renewStructure();
-        getViewModel().renderPagination();
-        getViewModel().renderInspectorEditors();
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = object
-       * @return void
-       * @subscribe core/ajax/saveFormDefinition/error
-       */
-      getPublisherSubscriber().subscribe('core/ajax/saveFormDefinition/error', function(topic, args) {
-        getViewModel().showSaveButtonSaveIcon();
-        getViewModel().showSaveErrorMessage(args[0]);
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = html
-       *              args[1] = pageIndex
-       * @return void
-       * @subscribe core/ajax/renderFormDefinitionPage/success
-       */
-      getPublisherSubscriber().subscribe('core/ajax/renderFormDefinitionPage/success', function(topic, args) {
-        getViewModel().renderPreviewStageArea(args[0]);
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = jqXHR
-       *              args[1] = textStatus
-       *              args[2] = errorThrown
-       * @return void
-       * @subscribe core/ajax/saveFormDefinition/error
-       */
-      getPublisherSubscriber().subscribe('core/ajax/error', function(topic, args) {
-        if (args[0].status !== 0) {
-          getViewModel().showErrorFlashMessage(args[1], args[2]);
-          getViewModel().renderPreviewStageArea(args[0].responseText);
-        }
-      });
-
-      /* *********************************************************
-       * Header
-       * ********************************************************/
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       * @return void
-       * @subscribe view/header/button/save/clicked
-       */
-      getPublisherSubscriber().subscribe('view/header/button/save/clicked', function(topic, args) {
-        if (getFormEditorApp().validationResultsHasErrors(getFormEditorApp().validateFormElementRecursive(getRootFormElement(), true))) {
-          getViewModel().showValidationErrorsModal();
-        } else {
-          getViewModel().showSaveButtonSpinnerIcon();
-          getFormEditorApp().saveFormDefinition();
-        }
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       * @return void
-       * @subscribe view/header/formSettings/clicked
-       */
-      getPublisherSubscriber().subscribe('view/header/formSettings/clicked', function(topic, args) {
-        getViewModel().addStructureRootElementSelection();
-        getFormEditorApp().setCurrentlySelectedFormElement(getRootFormElement());
-        getViewModel().renderAbstractStageArea();
-        getViewModel().renewStructure();
-        getViewModel().renderPagination();
-        getViewModel().renderInspectorEditors();
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = targetEvent
-       * @return void
-       * @subscribe view/header/button/newPage/clicked
-       */
-      getPublisherSubscriber().subscribe('view/header/button/newPage/clicked', function(topic, args) {
-        if (getFormEditorApp().isRootFormElementSelected()) {
-          getViewModel().selectPageBatch(0);
-        }
-        getViewModel().showInsertPagesModal(args[0]);
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       * @return void
-       * @subscribe view/header/button/close/clicked
-       */
-      getPublisherSubscriber().subscribe('view/header/button/close/clicked', function(topic, args) {
-        getViewModel().showCloseConfirmationModal();
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       * @return void
-       * @subscribe view/undoButton/clicked
-       */
-      getPublisherSubscriber().subscribe('view/undoButton/clicked', function(topic, args) {
-        getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderUndo')));
-        getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderRedo')));
-        getFormEditorApp().undoApplicationState();
-
-        if (getViewModel().getPreviewMode()) {
-          getFormEditorApp().renderCurrentFormPage();
-        } else {
-          getViewModel().renderAbstractStageArea();
-        }
-        getFormEditorApp().setUnsavedContent(true);
-
-        getViewModel().renewStructure();
-        getViewModel().renderPagination();
-        getViewModel().renderInspectorEditors();
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       * @return void
-       * @subscribe view/redoButton/clicked
-       */
-      getPublisherSubscriber().subscribe('view/redoButton/clicked', function(topic, args) {
-        getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderUndo')));
-        getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderRedo')));
-        getFormEditorApp().redoApplicationState();
-
-        if (getViewModel().getPreviewMode()) {
-          getFormEditorApp().renderCurrentFormPage();
-        } else {
-          getViewModel().renderAbstractStageArea();
-        }
-        getFormEditorApp().setUnsavedContent(true);
-
-        getViewModel().renewStructure();
-        getViewModel().renderPagination();
-        getViewModel().renderInspectorEditors();
-      });
-
-      /* *********************************************************
-       * Stage
-       * ********************************************************/
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = formElementIdentifierPath
-       * @return void
-       * @subscribe view/stage/element/clicked
-       */
-      getPublisherSubscriber().subscribe('view/stage/element/clicked', function(topic, args) {
-        if (getCurrentlySelectedFormElement().get('__identifierPath') !== args[0]) {
-          getFormEditorApp().setCurrentlySelectedFormElement(args[0]);
-          getViewModel().renewStructure();
-          getViewModel().refreshSelectedElementItemsBatch();
-          getViewModel().addAbstractViewValidationResults();
-          getViewModel().renderInspectorEditors();
-        }
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = targetEvent
-       *              args[1] = configuration
-       * @return void
-       * @subscribe view/stage/abstract/elementToolbar/button/newElement/clicked
-       */
-      getPublisherSubscriber().subscribe('view/stage/abstract/elementToolbar/button/newElement/clicked', function(topic, args) {
-        if (getFormEditorApp().isRootFormElementSelected()) {
-          getViewModel().selectPageBatch(0);
-        }
-        getViewModel().showInsertElementsModal(args[0], args[1]);
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = targetEvent
-       *              args[1] = configuration
-       * @return void
-       * @subscribe view/newElementButton/clicked
-       */
-      getPublisherSubscriber().subscribe('view/stage/abstract/button/newElement/clicked', function(topic, args) {
-        if (getFormEditorApp().isRootFormElementSelected()) {
-          getViewModel().selectPageBatch(0);
-        }
-        getViewModel().showInsertElementsModal(args[0], args[1]);
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = draggedFormElementDomElement
-       *              args[1] = draggedFormPlaceholderDomElement
-       * @return void
-       * @subscribe view/stage/abstract/dnd/start
-       */
-      getPublisherSubscriber().subscribe('view/stage/abstract/dnd/start', function(topic, args) {
-        getViewModel().onAbstractViewDndStartBatch(args[0], args[1]);
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = draggedFormElementIdentifierPath
-       * @return void
-       * @subscribe view/stage/abstract/dnd/stop
-       */
-      getPublisherSubscriber().subscribe('view/stage/abstract/dnd/stop', function(topic, args) {
-        getFormEditorApp().setCurrentlySelectedFormElement(args[0]);
-        getViewModel().renewStructure();
-        getViewModel().renderAbstractStageArea(false, false);
-        getViewModel().refreshSelectedElementItemsBatch();
-        getViewModel().addAbstractViewValidationResults();
-        getViewModel().renderInspectorEditors();
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = placeholderDomElement
-       *              args[1] = parentFormElementIdentifierPath
-       *              args[2] = enclosingCompositeFormElement
-       * @return void
-       * @subscribe view/stage/abstract/dnd/change
-       */
-      getPublisherSubscriber().subscribe('view/stage/abstract/dnd/change', function(topic, args) {
-        getViewModel().onAbstractViewDndChangeBatch(args[0], args[1], args[2]);
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = movedDomElement
-       *              args[1] = movedFormElementIdentifierPath
-       *              args[2] = previousFormElementIdentifierPath
-       *              args[3] = nextFormElementIdentifierPath
-       * @return void
-       * @subscribe view/stage/abstract/dnd/update
-       */
-      getPublisherSubscriber().subscribe('view/stage/abstract/dnd/update', function(topic, args) {
-        getViewModel().onAbstractViewDndUpdateBatch(args[0], args[1], args[2], args[3]);
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       * @return void
-       * @subscribe view/viewModeButton/abstract/clicked
-       */
-      getPublisherSubscriber().subscribe('view/viewModeButton/abstract/clicked', function(topic, args) {
-        if (getViewModel().getPreviewMode()) {
-          getViewModel().setPreviewMode(false);
-          getViewModel().renderAbstractStageArea();
-        }
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       * @return void
-       * @subscribe view/viewModeButton/preview/clicked
-       */
-      getPublisherSubscriber().subscribe('view/viewModeButton/preview/clicked', function(topic, args) {
-        if (!getViewModel().getPreviewMode()) {
-          getViewModel().setPreviewMode(true);
-          getFormEditorApp().renderCurrentFormPage();
-        }
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       * @return void
-       * @subscribe view/paginationPrevious/clicked
-       */
-      getPublisherSubscriber().subscribe('view/paginationPrevious/clicked', function(topic, args) {
-        getViewModel().selectPageBatch(getFormEditorApp().getCurrentlySelectedPageIndex() - 1);
-        if (getViewModel().getPreviewMode()) {
-          getFormEditorApp().renderCurrentFormPage();
-        } else {
-          getViewModel().renderAbstractStageArea();
-        }
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       * @return void
-       * @subscribe view/paginationNext/clicked
-       */
-      getPublisherSubscriber().subscribe('view/paginationNext/clicked', function(topic, args) {
-        getViewModel().selectPageBatch(getFormEditorApp().getCurrentlySelectedPageIndex() + 1);
-        if (getViewModel().getPreviewMode()) {
-          getFormEditorApp().renderCurrentFormPage();
-        } else {
-          getViewModel().renderAbstractStageArea();
-        }
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       * @return void
-       * @subscribe view/stage/abstract/render/postProcess
-       */
-      getPublisherSubscriber().subscribe('view/stage/abstract/render/postProcess', function(topic, args) {
-        getViewModel().renderUndoRedo();
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       * @return void
-       * @subscribe view/stage/preview/render/postProcess
-       */
-      getPublisherSubscriber().subscribe('view/stage/preview/render/postProcess', function(topic, args) {
-        getViewModel().renderUndoRedo();
-      });
-
-      /* *********************************************************
-       * Structure
-       * ********************************************************/
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = formElementIdentifierPath
-       * @return void
-       * @subscribe view/tree/node/clicked
-       */
-      getPublisherSubscriber().subscribe('view/tree/node/clicked', function(topic, args) {
-        var oldPageIndex;
-        if (getCurrentlySelectedFormElement().get('__identifierPath') !== args[0]) {
-          oldPageIndex = getFormEditorApp().getCurrentlySelectedPageIndex();
-          getFormEditorApp().setCurrentlySelectedFormElement(args[0]);
-          if (oldPageIndex !== getFormEditorApp().getCurrentlySelectedPageIndex()) {
-            getViewModel().renderAbstractStageArea();
-          } else {
-            getViewModel().renderAbstractStageArea(false);
-          }
-          getViewModel().renderPagination();
-          getViewModel().renderInspectorEditors();
-        }
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = formElementIdentifierPath
-       *              args[1] = newLabel
-       * @return void
-       * @subscribe view/tree/node/clicked
-       */
-      getPublisherSubscriber().subscribe('view/tree/node/changed', function(topic, args) {
-        var formElement = getFormEditorApp().getFormElementByIdentifierPath(args[0]);
-        formElement.set('label', args[1]);
-        getViewModel().getStructure().setTreeNodeTitle(null, formElement);
-        if(getCurrentlySelectedFormElement().get('__identifierPath') === args[0]) {
-          getViewModel().renderInspectorEditors(args[0], false);
-        }
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       * @return void
-       * @subscribe view/structure/root/selected
-       */
-      getPublisherSubscriber().subscribe('view/structure/root/selected', function(topic, args) {
-        if (!getFormEditorApp().isRootFormElementSelected()) {
-          getViewModel().addStructureRootElementSelection();
-          getFormEditorApp().setCurrentlySelectedFormElement(getRootFormElement());
-          getViewModel().renderAbstractStageArea();
-          getViewModel().renewStructure();
-          getViewModel().renderPagination();
-          getViewModel().renderInspectorEditors();
-        }
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = targetEvent
-       * @return void
-       * @subscribe view/header/button/newPage/clicked
-       */
-      getPublisherSubscriber().subscribe('view/structure/button/newPage/clicked', function(topic, args) {
-        if (getFormEditorApp().isRootFormElementSelected()) {
-          getViewModel().selectPageBatch(0);
-        }
-        getViewModel().showInsertPagesModal(args[0]);
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = draggedFormElementIdentifierPath
-       * @return void
-       * @subscribe view/tree/dnd/stop
-       */
-      getPublisherSubscriber().subscribe('view/tree/dnd/stop', function(topic, args) {
-        getFormEditorApp().setCurrentlySelectedFormElement(args[0]);
-        getViewModel().renewStructure();
-        getViewModel().renderPagination();
-        getViewModel().renderAbstractStageArea();
-        getViewModel().renderInspectorEditors();
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = placeholderDomElement
-       *              args[1] = parentFormElementIdentifierPath
-       *              args[2] = enclosingCompositeFormElement
-       * @return void
-       * @subscribe view/tree/dnd/change
-       */
-      getPublisherSubscriber().subscribe('view/tree/dnd/change', function(topic, args) {
-        getViewModel().onStructureDndChangeBatch(args[0], args[1], args[2]);
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = movedDomElement
-       *              args[1] = movedFormElementIdentifierPath
-       *              args[2] = previousFormElementIdentifierPath
-       *              args[3] = nextFormElementIdentifierPath
-       * @return void
-       * @subscribe view/tree/dnd/update
-       */
-      getPublisherSubscriber().subscribe('view/tree/dnd/update', function(topic, args) {
-        getViewModel().onStructureDndUpdateBatch(args[0], args[1], args[2], args[3]);
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       * @return void
-       * @subscribe view/structure/renew/postProcess
-       */
-      getPublisherSubscriber().subscribe('view/structure/renew/postProcess', function(topic, args) {
-        getViewModel().addStructureValidationResults();
-      });
-
-      /* *********************************************************
-       * Inspector
-       * ********************************************************/
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = collectionElementIdentifier
-       *              args[1] = collectionName
-       *              args[2] = formElement
-       * @return void
-       * @subscribe view/inspector/removeCollectionElement/perform
-       */
-      getPublisherSubscriber().subscribe('view/inspector/removeCollectionElement/perform', function(topic, args) {
-        getViewModel().removePropertyCollectionElement(args[0], args[1], args[2]);
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = collectionElementIdentifier
-       *              args[1] = collectionName
-       * @return void
-       * @subscribe view/inspector/collectionElement/selected
-       */
-      getPublisherSubscriber().subscribe('view/inspector/collectionElement/new/selected', function(topic, args) {
-        getViewModel().createAndAddPropertyCollectionElement(args[0], args[1]);
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = collectionElementIdentifier
-       *              args[1] = collectionName
-       * @return void
-       * @subscribe view/inspector/collectionElement/selected
-       */
-      getPublisherSubscriber().subscribe('view/inspector/collectionElement/existing/selected', function(topic, args) {
-        getViewModel().renderInspectorCollectionElementEditors(args[1], args[0]);
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = movedCollectionElementIdentifier
-       *              args[1] = previousCollectionElementIdentifier
-       *              args[2] = nextCollectionElementIdentifier
-       *              args[3] = collectionName
-       * @return void
-       * @subscribe view/inspector/collectionElements/dnd/update
-       * @throws 1477407673
-       */
-      getPublisherSubscriber().subscribe('view/inspector/collectionElements/dnd/update', function(topic, args) {
-        if (args[2]) {
-          getViewModel().movePropertyCollectionElement(args[0], 'before', args[2], args[3]);
-        } else if (args[1]) {
-          getViewModel().movePropertyCollectionElement(args[0], 'after', args[1], args[3]);
-        } else {
-          assert(false, 'Next element or previous element need to be set.', 1477407673);
-        }
-      });
-
-      /* *********************************************************
-       * Form element
-       * ********************************************************/
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = propertyPath
-       *              args[1] = value
-       *              args[2] = oldValue
-       *              args[3] = formElementIdentifierPath
-       * @return void
-       * @subscribe core/formElement/somePropertyChanged
-       */
-      getPublisherSubscriber().subscribe('core/formElement/somePropertyChanged', function(topic, args) {
-        if ('renderables' !== args[0]) {
-          if (!getFormEditorApp().isRootFormElementSelected() && 'label' === args[0]) {
-            getViewModel().getStructure().setTreeNodeTitle();
-          } else if (!getFormEditorApp().getUtility().isUndefinedOrNull(args[3]) && getRootFormElement().get('__identifierPath') === args[3]) {
-            getViewModel().setStructureRootElementTitle();
-            getViewModel().setStageHeadline();
-          }
-
-          if (getViewModel().getPreviewMode()) {
-            getFormEditorApp().renderCurrentFormPage();
-          } else {
-            getViewModel().renderAbstractStageArea(false, false);
-          }
-          getViewModel().addStructureValidationResults();
-        }
-
-        getFormEditorApp().setUnsavedContent(true);
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = parentFormElement
-       * @return void
-       * @subscribe view/formElement/removed
-       */
-      getPublisherSubscriber().subscribe('view/formElement/removed', function(topic, args) {
-        getFormEditorApp().setCurrentlySelectedFormElement(args[0]);
-        getViewModel().renewStructure();
-        getViewModel().renderAbstractStageArea();
-        getViewModel().renderPagination();
-        getViewModel().renderInspectorEditors();
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = newFormElement
-       * @return void
-       * @subscribe view/formElement/inserted
-       */
-      getPublisherSubscriber().subscribe('view/formElement/inserted', function(topic, args) {
-        getFormEditorApp().setCurrentlySelectedFormElement(args[0]);
-        getViewModel().renewStructure();
-        getViewModel().renderAbstractStageArea();
-        getViewModel().renderPagination();
-        getViewModel().renderInspectorEditors();
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = collectionElementIdentifier
-       *              args[1] = collectionName
-       *              args[2] = formElement
-       *              args[3] = collectionElementConfiguration
-       *              args[4] = referenceCollectionElementIdentifier
-       * @return void
-       * @subscribe view/collectionElement/new/added
-       */
-      getPublisherSubscriber().subscribe('view/collectionElement/new/added', function(topic, args) {
-        getViewModel().renderInspectorEditors();
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = movedCollectionElementIdentifier
-       *              args[1] = previousCollectionElementIdentifier
-       *              args[2] = nextCollectionElementIdentifier
-       *              args[3] = collectionName
-       * @return void
-       * @subscribe view/collectionElement/moved
-       * @throws 1477407673
-       */
-      getPublisherSubscriber().subscribe('view/collectionElement/moved', function(topic, args) {
-        getViewModel().renderInspectorEditors(undefined, false);
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = collectionElementIdentifier
-       *              args[1] = collectionName
-       *              args[2] = formElement
-       * @return void
-       * @subscribe view/collectionElement/removed
-       */
-      getPublisherSubscriber().subscribe('view/collectionElement/removed', function(topic, args) {
-        getViewModel().renderInspectorEditors(undefined, false);
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = formElementType
-       * @return void
-       * @subscribe view/insertElements/perform/bottom
-       */
-      getPublisherSubscriber().subscribe('view/insertElements/perform/bottom', function(topic, args) {
-        var lastRenderable;
-
-        lastRenderable = getFormEditorApp().getLastTopLevelElementOnCurrentPage();
-        if (!lastRenderable) {
-          getViewModel().createAndAddFormElement(args[0], getFormEditorApp().getCurrentlySelectedPage());
-        } else {
-          if (
-            !getFormEditorApp().getFormElementDefinition(lastRenderable, '_isTopLevelFormElement')
-            && getFormEditorApp().getFormElementDefinition(lastRenderable, '_isCompositeFormElement')
-          ) {
-            getViewModel().createAndAddFormElement(args[0], getFormEditorApp().getCurrentlySelectedPage());
-          } else {
-            getViewModel().createAndAddFormElement(args[0], lastRenderable);
-          }
-        }
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = formElementType
-       * @return void
-       * @publish view/formElement/inserted
-       * @subscribe view/insertElements/perform/after
-       */
-      getPublisherSubscriber().subscribe('view/insertElements/perform/after', function(topic, args) {
-        var newFormElement;
-        newFormElement = getViewModel().createAndAddFormElement(args[0], undefined, true);
-        newFormElement = getViewModel().moveFormElement(newFormElement, 'after', getFormEditorApp().getCurrentlySelectedFormElement());
-        getPublisherSubscriber().publish('view/formElement/inserted', [newFormElement]);
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = formElementType
-       * @return void
-       * @subscribe view/insertElements/perform/inside
-       */
-      getPublisherSubscriber().subscribe('view/insertElements/perform/inside', function(topic, args) {
-        getViewModel().createAndAddFormElement(args[0]);
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = formElementType
-       * @return void
-       * @subscribe view/insertElements/perform/after
-       */
-      getPublisherSubscriber().subscribe('view/insertPages/perform', function(topic, args) {
-        getViewModel().createAndAddFormElement(args[0]);
-      });
-
-      /* *********************************************************
-       * Modals
-       * ********************************************************/
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       * @return void
-       * @subscribe view/modal/close/perform
-       */
-      getPublisherSubscriber().subscribe('view/modal/close/perform', function(topic, args) {
-        getFormEditorApp().setUnsavedContent(false);
-        getViewModel().closeEditor();
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = formElement
-       * @return void
-       * @subscribe view/modal/removeFormElement/perform
-       */
-      getPublisherSubscriber().subscribe('view/modal/removeFormElement/perform', function(topic, args) {
-        getViewModel().removeFormElement(args[0]);
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = collectionElementIdentifier
-       *              args[1] = collectionName
-       *              args[2] = formElement
-       * @return void
-       * @subscribe view/modal/removeCollectionElement/perform
-       */
-      getPublisherSubscriber().subscribe('view/modal/removeCollectionElement/perform', function(topic, args) {
-        getViewModel().removePropertyCollectionElement(args[0], args[1], args[2]);
-      });
-
-      /**
-       * @private
-       *
-       * @param string
-       * @param array
-       *              args[0] = formElementIdentifierPath
-       * @return void
-       * @subscribe view/modal/validationErrors/element/clicked
-       */
-      getPublisherSubscriber().subscribe('view/modal/validationErrors/element/clicked', function(topic, args) {
-        var oldPageIndex;
-        if (getCurrentlySelectedFormElement().get('__identifierPath') !== args[0]) {
-          oldPageIndex = getFormEditorApp().getCurrentlySelectedPageIndex();
-          getFormEditorApp().setCurrentlySelectedFormElement(args[0]);
-
-          if (getViewModel().getPreviewMode()) {
-            getViewModel().setPreviewMode(false);
-          }
-
-          if (oldPageIndex !== getFormEditorApp().getCurrentlySelectedPageIndex()) {
-            getViewModel().renderAbstractStageArea();
-          } else {
-            getViewModel().renderAbstractStageArea(false);
-          }
-
-          getViewModel().renderPagination();
-          getViewModel().renderInspectorEditors();
-        }
-      });
-    };
-
-    /**
-     * @public
-     *
-     * @param object
-     * @param object
-     * @return void
-     */
-    function bootstrap(formEditorApp, viewModel) {
-      _formEditorApp = formEditorApp;
-      _viewModel = viewModel;
-      _helperSetup();
-      _subscribeEvents();
-    };
-
-    /**
-     * Implements the "Revealing Module Pattern".
-     */
-    return {
-      /**
-       * Publish the public methods.
-       */
-      bootstrap: bootstrap
-    };
-  })($, Helper);
-}
+import $ from"jquery";import*as Helper from"@typo3/form/backend/form-editor/helper.js";let formEditorApp=null,viewModel=null;function getFormEditorApp(){return formEditorApp}function getViewModel(){return viewModel}function getUtility(){return getFormEditorApp().getUtility()}function assert(e,t,r){return getFormEditorApp().assert(e,t,r)}function getHelper(e){return getUtility().isUndefinedOrNull(e)?Helper.setConfiguration(getViewModel().getConfiguration()):Helper.setConfiguration(e)}function getCurrentlySelectedFormElement(){return getFormEditorApp().getCurrentlySelectedFormElement()}function getPublisherSubscriber(){return getFormEditorApp().getPublisherSubscriber()}function getRootFormElement(){return getFormEditorApp().getRootFormElement()}function subscribeEvents(){window.onbeforeunload=function(e){if(getFormEditorApp().getUnsavedContent())return(e=e||window.event)&&(e.returnValue=getFormEditorApp().getFormElementDefinition(getRootFormElement(),"modalCloseDialogMessage")),getFormEditorApp().getFormElementDefinition(getRootFormElement(),"modalCloseDialogTitle")},getPublisherSubscriber().subscribe("view/ready",(()=>{getViewModel().onViewReadyBatch()})),getPublisherSubscriber().subscribe("core/applicationState/add",((e,[t,r,o])=>{getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector("buttonHeaderRedo"))),o>1&&r<=o?getViewModel().enableButton($(getHelper().getDomElementDataIdentifierSelector("buttonHeaderUndo"))):getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector("buttonHeaderUndo")))})),getPublisherSubscriber().subscribe("core/ajax/saveFormDefinition/success",((e,[t])=>{getFormEditorApp().setUnsavedContent(!1),getViewModel().showSaveSuccessMessage(),getViewModel().showSaveButtonSaveIcon(),getFormEditorApp().setFormDefinition(t.formDefinition),getViewModel().addStructureRootElementSelection(),getFormEditorApp().setCurrentlySelectedFormElement(getRootFormElement()),getViewModel().setStructureRootElementTitle(),getViewModel().setStageHeadline(),getViewModel().renderAbstractStageArea(),getViewModel().renewStructure(),getViewModel().renderPagination(),getViewModel().renderInspectorEditors()})),getPublisherSubscriber().subscribe("core/ajax/saveFormDefinition/error",((e,[t])=>{getViewModel().showSaveButtonSaveIcon(),getViewModel().showSaveErrorMessage({message:t.message})})),getPublisherSubscriber().subscribe("core/ajax/renderFormDefinitionPage/success",((e,[t,r])=>{getViewModel().renderPreviewStageArea(t)})),getPublisherSubscriber().subscribe("core/ajax/error",((e,[t,r,o])=>{0!==t.status&&(getViewModel().showErrorFlashMessage(r,o),getViewModel().renderPreviewStageArea(t.responseText))})),getPublisherSubscriber().subscribe("view/header/button/save/clicked",(()=>{getFormEditorApp().validationResultsHasErrors(getFormEditorApp().validateFormElementRecursive(getRootFormElement(),!0))?getViewModel().showValidationErrorsModal():(getViewModel().showSaveButtonSpinnerIcon(),getFormEditorApp().saveFormDefinition())})),getPublisherSubscriber().subscribe("view/header/formSettings/clicked",(()=>{getViewModel().addStructureRootElementSelection(),getFormEditorApp().setCurrentlySelectedFormElement(getRootFormElement()),getViewModel().renderAbstractStageArea(),getViewModel().renewStructure(),getViewModel().renderPagination(),getViewModel().renderInspectorEditors()})),getPublisherSubscriber().subscribe("view/header/button/newPage/clicked",((e,[t])=>{getFormEditorApp().isRootFormElementSelected()&&getViewModel().selectPageBatch(0),getViewModel().showInsertPagesModal(t)})),getPublisherSubscriber().subscribe("view/header/button/close/clicked",(()=>{getViewModel().showCloseConfirmationModal()})),getPublisherSubscriber().subscribe("view/undoButton/clicked",(()=>{getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector("buttonHeaderUndo"))),getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector("buttonHeaderRedo"))),getFormEditorApp().undoApplicationState(),getViewModel().getPreviewMode()?getFormEditorApp().renderCurrentFormPage():getViewModel().renderAbstractStageArea(),getFormEditorApp().setUnsavedContent(!0),getViewModel().renewStructure(),getViewModel().renderPagination(),getViewModel().renderInspectorEditors()})),getPublisherSubscriber().subscribe("view/redoButton/clicked",(()=>{getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector("buttonHeaderUndo"))),getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector("buttonHeaderRedo"))),getFormEditorApp().redoApplicationState(),getViewModel().getPreviewMode()?getFormEditorApp().renderCurrentFormPage():getViewModel().renderAbstractStageArea(),getFormEditorApp().setUnsavedContent(!0),getViewModel().renewStructure(),getViewModel().renderPagination(),getViewModel().renderInspectorEditors()})),getPublisherSubscriber().subscribe("view/stage/element/clicked",((e,[t])=>{getCurrentlySelectedFormElement().get("__identifierPath")!==t&&(getFormEditorApp().setCurrentlySelectedFormElement(t),getViewModel().renewStructure(),getViewModel().refreshSelectedElementItemsBatch(),getViewModel().addAbstractViewValidationResults(),getViewModel().renderInspectorEditors())})),getPublisherSubscriber().subscribe("view/stage/abstract/elementToolbar/button/newElement/clicked",((e,[t,r])=>{getFormEditorApp().isRootFormElementSelected()&&getViewModel().selectPageBatch(0),getViewModel().showInsertElementsModal(t,r)})),getPublisherSubscriber().subscribe("view/stage/abstract/button/newElement/clicked",((e,[t,r])=>{getFormEditorApp().isRootFormElementSelected()&&getViewModel().selectPageBatch(0),getViewModel().showInsertElementsModal(t,r||void 0)})),getPublisherSubscriber().subscribe("view/stage/abstract/dnd/start",((e,[t,r])=>{getViewModel().onAbstractViewDndStartBatch(t,r)})),getPublisherSubscriber().subscribe("view/stage/abstract/dnd/stop",((e,[t])=>{getFormEditorApp().setCurrentlySelectedFormElement(t),getViewModel().renewStructure(),getViewModel().renderAbstractStageArea(!1,!1),getViewModel().refreshSelectedElementItemsBatch(),getViewModel().addAbstractViewValidationResults(),getViewModel().renderInspectorEditors()})),getPublisherSubscriber().subscribe("view/stage/abstract/dnd/change",((e,[t,r,o])=>{getViewModel().onAbstractViewDndChangeBatch(t,r,o)})),getPublisherSubscriber().subscribe("view/stage/abstract/dnd/update",((e,[t,r,o,i])=>{getViewModel().onAbstractViewDndUpdateBatch(t,r,o,i)})),getPublisherSubscriber().subscribe("view/viewModeButton/abstract/clicked",(()=>{getViewModel().getPreviewMode()&&(getViewModel().setPreviewMode(!1),getViewModel().renderAbstractStageArea())})),getPublisherSubscriber().subscribe("view/viewModeButton/preview/clicked",(()=>{getViewModel().getPreviewMode()||(getViewModel().setPreviewMode(!0),getFormEditorApp().renderCurrentFormPage())})),getPublisherSubscriber().subscribe("view/paginationPrevious/clicked",(()=>{getViewModel().selectPageBatch(getFormEditorApp().getCurrentlySelectedPageIndex()-1),getViewModel().getPreviewMode()?getFormEditorApp().renderCurrentFormPage():getViewModel().renderAbstractStageArea()})),getPublisherSubscriber().subscribe("view/paginationNext/clicked",(()=>{getViewModel().selectPageBatch(getFormEditorApp().getCurrentlySelectedPageIndex()+1),getViewModel().getPreviewMode()?getFormEditorApp().renderCurrentFormPage():getViewModel().renderAbstractStageArea()})),getPublisherSubscriber().subscribe("view/stage/abstract/render/postProcess",(()=>{getViewModel().renderUndoRedo()})),getPublisherSubscriber().subscribe("view/stage/preview/render/postProcess",(()=>{getViewModel().renderUndoRedo()})),getPublisherSubscriber().subscribe("view/tree/node/clicked",((e,[t])=>{let r;getCurrentlySelectedFormElement().get("__identifierPath")!==t&&(r=getFormEditorApp().getCurrentlySelectedPageIndex(),getFormEditorApp().setCurrentlySelectedFormElement(t),r!==getFormEditorApp().getCurrentlySelectedPageIndex()?getViewModel().renderAbstractStageArea():getViewModel().renderAbstractStageArea(!1),getViewModel().renderPagination(),getViewModel().renderInspectorEditors())})),getPublisherSubscriber().subscribe("view/tree/node/changed",((e,[t,r])=>{const o=getFormEditorApp().getFormElementByIdentifierPath(t);o.set("label",r),getViewModel().getStructure().setTreeNodeTitle(null,o),getCurrentlySelectedFormElement().get("__identifierPath")===t&&getViewModel().renderInspectorEditors(t,!1)})),getPublisherSubscriber().subscribe("view/structure/root/selected",(()=>{getFormEditorApp().isRootFormElementSelected()||(getViewModel().addStructureRootElementSelection(),getFormEditorApp().setCurrentlySelectedFormElement(getRootFormElement()),getViewModel().renderAbstractStageArea(),getViewModel().renewStructure(),getViewModel().renderPagination(),getViewModel().renderInspectorEditors())})),getPublisherSubscriber().subscribe("view/structure/button/newPage/clicked",((e,[t])=>{getFormEditorApp().isRootFormElementSelected()&&getViewModel().selectPageBatch(0),getViewModel().showInsertPagesModal(t)})),getPublisherSubscriber().subscribe("view/tree/dnd/stop",((e,[t])=>{getFormEditorApp().setCurrentlySelectedFormElement(t),getViewModel().renewStructure(),getViewModel().renderPagination(),getViewModel().renderAbstractStageArea(),getViewModel().renderInspectorEditors()})),getPublisherSubscriber().subscribe("view/tree/dnd/change",((e,[t,r,o])=>{getViewModel().onStructureDndChangeBatch(t,r,o)})),getPublisherSubscriber().subscribe("view/tree/dnd/update",((e,[t,r,o,i])=>{getViewModel().onStructureDndUpdateBatch(t,r,o,i)})),getPublisherSubscriber().subscribe("view/structure/renew/postProcess",(()=>{getViewModel().addStructureValidationResults()})),getPublisherSubscriber().subscribe("view/inspector/removeCollectionElement/perform",((e,[t,r,o])=>{getViewModel().removePropertyCollectionElement(t,r,o||void 0)})),getPublisherSubscriber().subscribe("view/inspector/collectionElement/new/selected",((e,[t,r])=>{getViewModel().createAndAddPropertyCollectionElement(t,r)})),getPublisherSubscriber().subscribe("view/inspector/collectionElement/existing/selected",((e,[t,r])=>{getViewModel().renderInspectorCollectionElementEditors(r,t)})),getPublisherSubscriber().subscribe("view/inspector/collectionElements/dnd/update",((e,[t,r,o,i])=>{o?getViewModel().movePropertyCollectionElement(t,"before",o,i):r?getViewModel().movePropertyCollectionElement(t,"after",r,i):assert(!1,"Next element or previous element need to be set.",1477407673)})),getPublisherSubscriber().subscribe("core/formElement/somePropertyChanged",((e,[t,r,o,i])=>{"renderables"!==t&&(getFormEditorApp().isRootFormElementSelected()||"label"!==t?getFormEditorApp().getUtility().isUndefinedOrNull(i)||getRootFormElement().get("__identifierPath")!==i||(getViewModel().setStructureRootElementTitle(),getViewModel().setStageHeadline()):getViewModel().getStructure().setTreeNodeTitle(),getViewModel().getPreviewMode()?getFormEditorApp().renderCurrentFormPage():getViewModel().renderAbstractStageArea(!1,!1),getViewModel().addStructureValidationResults()),getFormEditorApp().setUnsavedContent(!0)})),getPublisherSubscriber().subscribe("view/formElement/removed",((e,[t])=>{getFormEditorApp().setCurrentlySelectedFormElement(t),getViewModel().renewStructure(),getViewModel().renderAbstractStageArea(),getViewModel().renderPagination(),getViewModel().renderInspectorEditors()})),getPublisherSubscriber().subscribe("view/formElement/inserted",((e,[t])=>{getFormEditorApp().setCurrentlySelectedFormElement(t),getViewModel().renewStructure(),getViewModel().renderAbstractStageArea(),getViewModel().renderPagination(),getViewModel().renderInspectorEditors()})),getPublisherSubscriber().subscribe("view/collectionElement/new/added",(()=>{getViewModel().renderInspectorEditors()})),getPublisherSubscriber().subscribe("view/collectionElement/moved",(()=>{getViewModel().renderInspectorEditors(void 0,!1)})),getPublisherSubscriber().subscribe("view/collectionElement/removed",(()=>{getViewModel().renderInspectorEditors(void 0,!1)})),getPublisherSubscriber().subscribe("view/insertElements/perform/bottom",((e,[t])=>{const r=getFormEditorApp().getLastTopLevelElementOnCurrentPage();r?!getFormEditorApp().getFormElementDefinition(r,"_isTopLevelFormElement")&&getFormEditorApp().getFormElementDefinition(r,"_isCompositeFormElement")?getViewModel().createAndAddFormElement(t,getFormEditorApp().getCurrentlySelectedPage()):getViewModel().createAndAddFormElement(t,r):getViewModel().createAndAddFormElement(t,getFormEditorApp().getCurrentlySelectedPage())})),getPublisherSubscriber().subscribe("view/insertElements/perform/after",((e,[t])=>{let r;r=getViewModel().createAndAddFormElement(t,void 0,!0),r=getViewModel().moveFormElement(r,"after",getFormEditorApp().getCurrentlySelectedFormElement()),getPublisherSubscriber().publish("view/formElement/inserted",[r])})),getPublisherSubscriber().subscribe("view/insertElements/perform/inside",((e,[t])=>{getViewModel().createAndAddFormElement(t)})),getPublisherSubscriber().subscribe("view/insertPages/perform",((e,[t])=>{getViewModel().createAndAddFormElement(t)})),getPublisherSubscriber().subscribe("view/modal/close/perform",(()=>{getFormEditorApp().setUnsavedContent(!1),getViewModel().closeEditor()})),getPublisherSubscriber().subscribe("view/modal/removeFormElement/perform",((e,[t])=>{getViewModel().removeFormElement(t)})),getPublisherSubscriber().subscribe("view/modal/removeCollectionElement/perform",((e,[t,r,o])=>{getViewModel().removePropertyCollectionElement(t,r,o)})),getPublisherSubscriber().subscribe("view/modal/validationErrors/element/clicked",((e,[t])=>{let r;getCurrentlySelectedFormElement().get("__identifierPath")!==t&&(r=getFormEditorApp().getCurrentlySelectedPageIndex(),getFormEditorApp().setCurrentlySelectedFormElement(t),getViewModel().getPreviewMode()&&getViewModel().setPreviewMode(!1),r!==getFormEditorApp().getCurrentlySelectedPageIndex()?getViewModel().renderAbstractStageArea():getViewModel().renderAbstractStageArea(!1),getViewModel().renderPagination(),getViewModel().renderInspectorEditors())}))}export function bootstrap(e,t){formEditorApp=e,viewModel=t,Helper.bootstrap(formEditorApp),subscribeEvents()}
\ No newline at end of file
-- 
GitLab