[FEATURE] EXT:form - integrate new form framework 11/50311/80
authorRalf Zimmermann <ralf.zimmermann@tritum.de>
Sat, 19 Nov 2016 12:06:19 +0000 (13:06 +0100)
committerChristian Kuhn <lolli@schwarzbu.ch>
Mon, 28 Nov 2016 15:54:32 +0000 (16:54 +0100)
The main purpose of this patch is to integrate a flexible framework for
building forms. It replaces the legacy 'form wizard' based on ExtJS and
the depending frontend rendering system.

The new backend 'form editor' relies on vanilla JS and jQuery.
Different JS patterns have been applied to ensure a modern architecture,
high flexibility and extensibility.

A new backend module lists all existing forms and allows the creation
of new ones. The 'mailform' content element is reworked. It lists
available forms and enables the backend editor to override certain
settings, e.g. 'finisher' settings (formerly known as 'postProcessors').

Till now it was not possible to customize and extend the 'form editor'.
To allow the registration of new finishers, validators and
pre-defined form elements a lot of architectural changes were needed.
After a long conceptional phase the team decided to remove the former
code base, backport the 'form' package of the Flow project and improve
the given concepts. The result is a new form extension. A lot of code
received major improvements and tons of additional features have been
integrated.

The list of features is long and impressive. The documentation - which
is part of a future patch - will explain the ideas, concept and
architecture as well as the functionality in detail.

This patch marks the beginning of a series of patches. Further work is
needed to implement a better UI and more tests. The currently integrated
element tree cannot be finished for now. We plan to use the new TYPO3
SVG tree but have to wait for the drag and drop implementation.
Furthermore, the old form wizard will be moved to a separate extension
for backward compatibility.

Resolves: #77910
Releases: master
Change-Id: Idde8453bc573da835959fa3e51e30f57792d98b0
Reviewed-on: https://review.typo3.org/50311
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Bjoern Jacob <bjoern.jacob@tritum.de>
Tested-by: Bjoern Jacob <bjoern.jacob@tritum.de>
Reviewed-by: Ralf Zimmermann <ralf.zimmermann@tritum.de>
Tested-by: Ralf Zimmermann <ralf.zimmermann@tritum.de>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Reviewed-by: Frank Naegler <frank.naegler@typo3.org>
Tested-by: Frank Naegler <frank.naegler@typo3.org>
Reviewed-by: Alexander Opitz <opitz.alexander@googlemail.com>
Tested-by: Alexander Opitz <opitz.alexander@googlemail.com>
Reviewed-by: Andreas Häfner <andreas.haefner@tritum.de>
Tested-by: Andreas Häfner <andreas.haefner@tritum.de>
Reviewed-by: Benni Mack <benni@typo3.org>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
753 files changed:
Build/Resources/Public/Less/form.less
composer.json
composer.lock
typo3/sysext/core/Documentation/Changelog/master/Feature-77910-EXTform-IntroduceNewFormFramework.rst [new file with mode: 0644]
typo3/sysext/form/Classes/ContentObject/FormContentObject.php [deleted file]
typo3/sysext/form/Classes/Controller/AbstractBackendController.php [new file with mode: 0644]
typo3/sysext/form/Classes/Controller/FormEditorController.php [new file with mode: 0644]
typo3/sysext/form/Classes/Controller/FormFrontendController.php [new file with mode: 0644]
typo3/sysext/form/Classes/Controller/FormManagerController.php [new file with mode: 0644]
typo3/sysext/form/Classes/Controller/FrontendController.php [deleted file]
typo3/sysext/form/Classes/Controller/WizardController.php [deleted file]
typo3/sysext/form/Classes/Domain/Builder/ElementBuilder.php [deleted file]
typo3/sysext/form/Classes/Domain/Builder/FormBuilder.php [deleted file]
typo3/sysext/form/Classes/Domain/Builder/ValidationBuilder.php [deleted file]
typo3/sysext/form/Classes/Domain/Configuration/ConfigurationService.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Configuration/Exception/PrototypeNotFoundException.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Exception.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Exception/IdentifierNotValidException.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Exception/RenderingException.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Exception/TypeDefinitionNotFoundException.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Exception/TypeDefinitionNotValidException.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Exception/UnknownCompositRenderableException.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Factory/AbstractFormFactory.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Factory/ArrayFormFactory.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Factory/FormFactoryInterface.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Factory/JsonToTypoScript.php [deleted file]
typo3/sysext/form/Classes/Domain/Filter/AbstractFilter.php [deleted file]
typo3/sysext/form/Classes/Domain/Filter/AlphabeticFilter.php [deleted file]
typo3/sysext/form/Classes/Domain/Filter/AlphanumericFilter.php [deleted file]
typo3/sysext/form/Classes/Domain/Filter/CurrencyFilter.php [deleted file]
typo3/sysext/form/Classes/Domain/Filter/DigitFilter.php [deleted file]
typo3/sysext/form/Classes/Domain/Filter/FilterInterface.php [deleted file]
typo3/sysext/form/Classes/Domain/Filter/IntegerFilter.php [deleted file]
typo3/sysext/form/Classes/Domain/Filter/LowerCaseFilter.php [deleted file]
typo3/sysext/form/Classes/Domain/Filter/RegExpFilter.php [deleted file]
typo3/sysext/form/Classes/Domain/Filter/RemoveXssFilter.php [deleted file]
typo3/sysext/form/Classes/Domain/Filter/StripNewLinesFilter.php [deleted file]
typo3/sysext/form/Classes/Domain/Filter/TitleCaseFilter.php [deleted file]
typo3/sysext/form/Classes/Domain/Filter/TrimFilter.php [deleted file]
typo3/sysext/form/Classes/Domain/Filter/UpperCaseFilter.php [deleted file]
typo3/sysext/form/Classes/Domain/Finishers/AbstractFinisher.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Finishers/ClosureFinisher.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Finishers/ConfirmationFinisher.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Finishers/DeleteUploadsFinisher.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Finishers/EmailFinisher.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Finishers/Exception/FinisherException.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Finishers/FinisherContext.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Finishers/FinisherInterface.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Finishers/FlashMessageFinisher.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Finishers/RedirectFinisher.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Finishers/SaveToDatabaseFinisher.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Model/Configuration.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Content.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Element.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Exception.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Model/Exception/DuplicateFormElementException.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Model/Exception/FinisherPresetNotFoundException.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Model/Exception/FormDefinitionConsistencyException.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Model/Exception/ValidatorPresetNotFoundException.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Model/FormDefinition.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Model/FormElements/AbstractFormElement.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Model/FormElements/AbstractSection.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Model/FormElements/AdvancedPassword.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Model/FormElements/DatePicker.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Model/FormElements/FileUpload.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Model/FormElements/FormElementInterface.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Model/FormElements/GenericFormElement.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Model/FormElements/Page.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Model/FormElements/Section.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Model/FormElements/UnknownFormElement.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Model/Json/AbstractJsonElement.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Json/ButtonJsonElement.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Json/CheckboxGroupJsonElement.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Json/CheckboxJsonElement.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Json/ContainerJsonElement.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Json/FieldsetJsonElement.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Json/FileuploadJsonElement.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Json/FormJsonElement.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Json/HeaderJsonElement.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Json/HiddenJsonElement.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Json/NameJsonElement.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Json/PasswordJsonElement.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Json/RadioGroupJsonElement.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Json/RadioJsonElement.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Json/ResetJsonElement.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Json/SelectJsonElement.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Json/SubmitJsonElement.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Json/TextareaJsonElement.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Json/TextblockJsonElement.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Json/TextlineJsonElement.php [deleted file]
typo3/sysext/form/Classes/Domain/Model/Renderable/AbstractCompositeRenderable.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Model/Renderable/AbstractRenderable.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Model/Renderable/CompositeRenderableInterface.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Model/Renderable/RenderableInterface.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Model/Renderable/RootRenderableInterface.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Model/ValidationElement.php [deleted file]
typo3/sysext/form/Classes/Domain/Property/TypeConverter/ArrayToValidationElementConverter.php [deleted file]
typo3/sysext/form/Classes/Domain/Renderer/AbstractElementRenderer.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Renderer/FluidFormRenderer.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Renderer/RendererInterface.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Renderer/UnknownFormElementRenderer.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Repository/ContentRepository.php [deleted file]
typo3/sysext/form/Classes/Domain/Repository/TypoScriptRepository.php [deleted file]
typo3/sysext/form/Classes/Domain/Runtime/Exception/PropertyMappingException.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Runtime/FormRuntime.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Runtime/FormState.php [new file with mode: 0644]
typo3/sysext/form/Classes/Domain/Validator/AbstractValidator.php [deleted file]
typo3/sysext/form/Classes/Domain/Validator/AlphabeticValidator.php [deleted file]
typo3/sysext/form/Classes/Domain/Validator/AlphanumericValidator.php [deleted file]
typo3/sysext/form/Classes/Domain/Validator/BetweenValidator.php [deleted file]
typo3/sysext/form/Classes/Domain/Validator/DateValidator.php [deleted file]
typo3/sysext/form/Classes/Domain/Validator/DigitValidator.php [deleted file]
typo3/sysext/form/Classes/Domain/Validator/EmailValidator.php [deleted file]
typo3/sysext/form/Classes/Domain/Validator/EqualsValidator.php [deleted file]
typo3/sysext/form/Classes/Domain/Validator/FileAllowedTypesValidator.php [deleted file]
typo3/sysext/form/Classes/Domain/Validator/FileMaximumSizeValidator.php [deleted file]
typo3/sysext/form/Classes/Domain/Validator/FileMinimumSizeValidator.php [deleted file]
typo3/sysext/form/Classes/Domain/Validator/FloatValidator.php [deleted file]
typo3/sysext/form/Classes/Domain/Validator/GreaterThanValidator.php [deleted file]
typo3/sysext/form/Classes/Domain/Validator/InArrayValidator.php [deleted file]
typo3/sysext/form/Classes/Domain/Validator/IntegerValidator.php [deleted file]
typo3/sysext/form/Classes/Domain/Validator/IpValidator.php [deleted file]
typo3/sysext/form/Classes/Domain/Validator/LengthValidator.php [deleted file]
typo3/sysext/form/Classes/Domain/Validator/LessThanValidator.php [deleted file]
typo3/sysext/form/Classes/Domain/Validator/RegExpValidator.php [deleted file]
typo3/sysext/form/Classes/Domain/Validator/RequiredValidator.php [deleted file]
typo3/sysext/form/Classes/Domain/Validator/UriValidator.php [deleted file]
typo3/sysext/form/Classes/Domain/Validator/ValidationElementValidator.php [deleted file]
typo3/sysext/form/Classes/Exception.php [new file with mode: 0644]
typo3/sysext/form/Classes/Hooks/DataStructureIdentifierHook.php [new file with mode: 0644]
typo3/sysext/form/Classes/Hooks/HandleIncomingFormValues.php [deleted file]
typo3/sysext/form/Classes/Hooks/PageLayoutView/MailformPreviewRenderer.php [deleted file]
typo3/sysext/form/Classes/Hooks/SoftReferenceParserHook.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/Configuration/ConfigurationManager.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/Configuration/ConfigurationManagerInterface.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/Configuration/Exception.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/Configuration/Exception/CycleInheritancesException.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/Configuration/Exception/ExtensionNameRequiredException.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/Configuration/Exception/NoSuchFileException.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/Configuration/Exception/ParseErrorException.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/Configuration/InheritancesResolverService.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/Configuration/TypoScriptService.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/Configuration/YamlSource.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/Controller/ControllerContext.php [deleted file]
typo3/sysext/form/Classes/Mvc/Persistence/Exception.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/Persistence/Exception/NoUniqueIdentifierException.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/Persistence/Exception/NoUniquePersistenceIdentifierException.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/Persistence/Exception/PersistenceManagerException.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/Persistence/FormPersistenceManager.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/Persistence/FormPersistenceManagerInterface.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/ProcessingRule.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/Property/TypeConverter/UploadedFileReferenceConverter.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/Validation/CountValidator.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/Validation/EmptyValidator.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/Validation/Exception/InvalidValidationOptionsException.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/Validation/MimeTypeValidator.php [new file with mode: 0644]
typo3/sysext/form/Classes/Mvc/View/FormView.php [new file with mode: 0644]
typo3/sysext/form/Classes/PostProcess/AbstractPostProcessor.php [deleted file]
typo3/sysext/form/Classes/PostProcess/MailPostProcessor.php [deleted file]
typo3/sysext/form/Classes/PostProcess/PostProcessor.php [deleted file]
typo3/sysext/form/Classes/PostProcess/PostProcessorInterface.php [deleted file]
typo3/sysext/form/Classes/PostProcess/RedirectPostProcessor.php [deleted file]
typo3/sysext/form/Classes/Service/TranslationService.php [new file with mode: 0644]
typo3/sysext/form/Classes/Utility/ArrayUtility.php [new file with mode: 0644]
typo3/sysext/form/Classes/Utility/ElementCounter.php [deleted file]
typo3/sysext/form/Classes/Utility/FormUtility.php [deleted file]
typo3/sysext/form/Classes/Utility/SessionUtility.php [deleted file]
typo3/sysext/form/Classes/Utility/TypoScriptToJsonConverter.php [deleted file]
typo3/sysext/form/Classes/View/Wizard/Element/FormWizardElement.php [deleted file]
typo3/sysext/form/Classes/ViewHelpers/AggregateSelectOptionsViewHelper.php [deleted file]
typo3/sysext/form/Classes/ViewHelpers/Be/PageRendererViewHelper.php [new file with mode: 0644]
typo3/sysext/form/Classes/ViewHelpers/Be/RenderContentElementPreviewViewHelper.php [new file with mode: 0644]
typo3/sysext/form/Classes/ViewHelpers/Form/CheckboxViewHelper.php [new file with mode: 0644]
typo3/sysext/form/Classes/ViewHelpers/Form/DatePickerViewHelper.php [new file with mode: 0644]
typo3/sysext/form/Classes/ViewHelpers/Form/TimePickerViewHelper.php [new file with mode: 0644]
typo3/sysext/form/Classes/ViewHelpers/Form/UploadedResourceViewHelper.php [new file with mode: 0644]
typo3/sysext/form/Classes/ViewHelpers/FormViewHelper.php [new file with mode: 0644]
typo3/sysext/form/Classes/ViewHelpers/PlainMailViewHelper.php [deleted file]
typo3/sysext/form/Classes/ViewHelpers/PlainTextMailViewHelper.php [new file with mode: 0644]
typo3/sysext/form/Classes/ViewHelpers/RenderAllFormValuesViewHelper.php [new file with mode: 0644]
typo3/sysext/form/Classes/ViewHelpers/RenderRenderableViewHelper.php [new file with mode: 0644]
typo3/sysext/form/Classes/ViewHelpers/RenderViewHelper.php [new file with mode: 0644]
typo3/sysext/form/Classes/ViewHelpers/SelectViewHelper.php [deleted file]
typo3/sysext/form/Classes/ViewHelpers/TranslateElementPropertyViewHelper.php [new file with mode: 0644]
typo3/sysext/form/Configuration/Backend/AjaxRoutes.php [deleted file]
typo3/sysext/form/Configuration/FlexForms/FormFramework.xml [new file with mode: 0644]
typo3/sysext/form/Configuration/PageTS/modWizards.ts
typo3/sysext/form/Configuration/TCA/Overrides/sys_template.php [deleted file]
typo3/sysext/form/Configuration/TCA/Overrides/tt_content.php
typo3/sysext/form/Configuration/TypoScript/Elements/Button.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Buttontag.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Checkbox.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Checkboxgroup.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Contentelement.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Fieldset.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Fileupload.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Form.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Header.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Hidden.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Input.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Inputtypebutton.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Label.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Optgroup.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Option.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Password.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Radio.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Radiogroup.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Reset.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Select.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Submit.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Textarea.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Textblock.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Elements/Textline.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Filters/Filters.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/Validators/Validators.ts [deleted file]
typo3/sysext/form/Configuration/TypoScript/backend.txt [new file with mode: 0644]
typo3/sysext/form/Configuration/TypoScript/constants.txt [deleted file]
typo3/sysext/form/Configuration/TypoScript/setup.txt
typo3/sysext/form/Configuration/UserTSconfig/userTSConfig.txt [deleted file]
typo3/sysext/form/Configuration/Yaml/BaseSetup.yaml [new file with mode: 0644]
typo3/sysext/form/Configuration/Yaml/FormEditorSetup.yaml [new file with mode: 0644]
typo3/sysext/form/Configuration/Yaml/FormEngineSetup.yaml [new file with mode: 0644]
typo3/sysext/form/Documentation/.gitignore [deleted file]
typo3/sysext/form/Documentation/Administration/DefaultNewRecord/Index.rst [deleted file]
typo3/sysext/form/Documentation/Administration/Index.rst [deleted file]
typo3/sysext/form/Documentation/Administration/WizardSettings/DefaultsReference/ElementsTab/Index.rst [deleted file]
typo3/sysext/form/Documentation/Administration/WizardSettings/DefaultsReference/FormTab/Index.rst [deleted file]
typo3/sysext/form/Documentation/Administration/WizardSettings/DefaultsReference/Index.rst [deleted file]
typo3/sysext/form/Documentation/Administration/WizardSettings/DefaultsReference/OptionsTab/Index.rst [deleted file]
typo3/sysext/form/Documentation/Administration/WizardSettings/DefaultsReference/ShowTabs/Index.rst [deleted file]
typo3/sysext/form/Documentation/Administration/WizardSettings/ElementsReference/Index.rst [deleted file]
typo3/sysext/form/Documentation/Administration/WizardSettings/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Filters/Alphabetic/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Filters/Alphanumeric/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Filters/Currency/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Filters/Digit/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Filters/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Filters/Integer/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Filters/Lowercase/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Filters/Regexp/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Filters/Stripnewlines/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Filters/Titlecase/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Filters/Trim/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Filters/Uppercase/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Layout/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Layout/LayoutObjectSpecific/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Layout/LayoutViewSpecific/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Layout/LayoutWholeForm/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Objects/Button/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Objects/Checkbox/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Objects/Fieldset/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Objects/Fileupload/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Objects/Form/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Objects/Header/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Objects/Hidden/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Objects/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Objects/ObjectAttributes/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Objects/Optgroup/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Objects/Option/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Objects/Password/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Objects/Radio/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Objects/Reset/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Objects/Select/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Objects/Submit/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Objects/Textarea/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Objects/Textblock/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Objects/Textline/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Postprocessors/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Postprocessors/Mail/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Postprocessors/Redirect/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Rules/Alphabetic/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Rules/Alphanumeric/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Rules/Between/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Rules/Date/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Rules/Digit/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Rules/Email/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Rules/Equals/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Rules/Float/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Rules/Greaterthan/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Rules/Inarray/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Rules/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Rules/Integer/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Rules/Ip/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Rules/Length/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Rules/Lessthan/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Rules/Regexp/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Rules/Required/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Rules/Uri/Index.rst [deleted file]
typo3/sysext/form/Documentation/Configuration/Rules/ValidationAttributes/Index.rst [deleted file]
typo3/sysext/form/Documentation/Images/FormCreationWizard.png [deleted file]
typo3/sysext/form/Documentation/Images/FormCreationWizardElementsTab.png [deleted file]
typo3/sysext/form/Documentation/Images/FormCreationWizardFormTab.png [deleted file]
typo3/sysext/form/Documentation/Images/FormCreationWizardOptionsTab.png [deleted file]
typo3/sysext/form/Documentation/Images/FormCreationWizardShowTabs.png [deleted file]
typo3/sysext/form/Documentation/Includes.txt [deleted file]
typo3/sysext/form/Documentation/Index.rst [deleted file]
typo3/sysext/form/Documentation/Introduction/Index.rst [deleted file]
typo3/sysext/form/Documentation/Settings.cfg [deleted file]
typo3/sysext/form/Documentation/Targets.rst [deleted file]
typo3/sysext/form/Documentation/Tests/Attributes/button.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Attributes/checkbox.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Attributes/checkboxgroup.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Attributes/fieldset.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Attributes/hidden.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Attributes/optgroup.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Attributes/option.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Attributes/password.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Attributes/radio.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Attributes/radiogroup.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Attributes/reset.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Attributes/select.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Attributes/submit.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Attributes/textarea.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Attributes/textline.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Filter/alphabetic.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Filter/alphanumeric.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Filter/currency.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Filter/digit.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Filter/integer.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Filter/lowercase.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Filter/regexp.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Filter/stripnewlines.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Filter/titlecase.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Filter/trim.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Filter/uppercase.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Request/checkbox.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Request/option.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Request/radio.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Validation/alphabetic.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Validation/alphanumeric.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Validation/between.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Validation/combined.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Validation/date.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Validation/digit.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Validation/email.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Validation/equals.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Validation/float.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Validation/greaterthan.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Validation/inarray.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Validation/integer.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Validation/ip.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Validation/length.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Validation/lessthan.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Validation/regexp.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Validation/required.txt [deleted file]
typo3/sysext/form/Documentation/Tests/Validation/uri.txt [deleted file]
typo3/sysext/form/Resources/Private/Backend/Layouts/FormEditor.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Layouts/FormManager.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Partials/FormEditor/Stage/FileUploadTemplate.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Partials/FormEditor/Stage/SelectTemplate.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Partials/FormEditor/Stage/SimpleTemplate.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Index.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Inspector/CheckboxEditor.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Inspector/CollectionElementHeaderEditor.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Inspector/FinishersEditor.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Inspector/FormElementHeaderEditor.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Inspector/PropertyGridEditor.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Inspector/RemoveElementEditor.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Inspector/RequiredValidatorEditor.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Inspector/SingleSelectEditor.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Inspector/TextEditor.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Inspector/TextareaEditor.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Inspector/Typo3WinBrowserEditor.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Inspector/ValidatorsEditor.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Modals/InsertElements.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Modals/InsertPages.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Modals/ValidationErrors.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Stage/AdvancedPassword.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Stage/Checkbox.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Stage/ContentElement.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Stage/DatePicker.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Stage/Fieldset.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Stage/FileUpload.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Stage/Hidden.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Stage/ImageUpload.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Stage/MultiCheckbox.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Stage/MultiSelect.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Stage/Page.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Stage/Password.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Stage/RadioButton.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Stage/SingleSelect.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Stage/StaticText.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Stage/SummaryPage.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Stage/Text.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Stage/Textarea.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Stage/_ElementToolbar.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Stage/_UnknownElement.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Yaml/NewForms/BlankForm.yaml [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Yaml/NewForms/SimpleContactForm.yaml [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Backend/Templates/FormManager/Index.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Layouts/FormElements/Field.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Partials/FormElements/Field/Required.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Partials/FormElements/Form/Navigation.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/Finishers/Email/Html.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/Finishers/Email/Plaintext.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/FormElements/AdvancedPassword.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/FormElements/Checkbox.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/FormElements/ContentElement.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/FormElements/DatePicker.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/FormElements/Fieldset.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/FormElements/FileUpload.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/FormElements/Form.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/FormElements/Hidden.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/FormElements/Honeypot.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/FormElements/ImageUpload.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/FormElements/MultiCheckbox.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/FormElements/MultiSelect.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/FormElements/Page.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/FormElements/Password.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/FormElements/RadioButton.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/FormElements/SingleSelect.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/FormElements/StaticText.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/FormElements/SummaryPage.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/FormElements/Text.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/FormElements/Textarea.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Frontend/Templates/Render.html [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Language/Database.xlf
typo3/sysext/form/Resources/Private/Language/locallang.xlf
typo3/sysext/form/Resources/Private/Language/locallang_formManager_javascript.xlf [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Language/locallang_module.xlf [new file with mode: 0644]
typo3/sysext/form/Resources/Private/Language/locallang_wizard.xlf [deleted file]
typo3/sysext/form/Resources/Private/Layouts/Default.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/AdditionalElements/Label.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/AdditionalElements/Legend.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/ContainerElements/Checkboxgroup.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/ContainerElements/Fieldset.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/ContainerElements/Form.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/ContainerElements/Radiogroup.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/FlatElements/Button.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/FlatElements/ButtonTag.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/FlatElements/Checkbox.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/FlatElements/ContentElement.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/FlatElements/Header.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/FlatElements/Hidden.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/FlatElements/Imagebutton.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/FlatElements/Input.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/FlatElements/InputTypeButton.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/FlatElements/Password.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/FlatElements/Radio.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/FlatElements/Reset.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/FlatElements/Select.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/FlatElements/Submit.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/FlatElements/Textarea.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/FlatElements/Textblock.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/FlatElements/Textfield.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Confirmation/FlatElements/Upload.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/AdditionalElements/Label.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/AdditionalElements/Legend.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/ContainerElements/Checkboxgroup.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/ContainerElements/Fieldset.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/ContainerElements/Form.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/ContainerElements/Radiogroup.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/FlatElements/Button.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/FlatElements/ButtonTag.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/FlatElements/Checkbox.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/FlatElements/ContentElement.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/FlatElements/Header.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/FlatElements/Hidden.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/FlatElements/Imagebutton.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/FlatElements/Input.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/FlatElements/InputTypeButton.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/FlatElements/Password.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/FlatElements/Radio.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/FlatElements/Reset.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/FlatElements/Select.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/FlatElements/Submit.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/FlatElements/Textarea.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/FlatElements/Textblock.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/FlatElements/Textfield.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Html/FlatElements/Upload.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Plain/ContainerElements/Checkboxgroup.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Plain/ContainerElements/Fieldset.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Plain/ContainerElements/Form.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Plain/ContainerElements/Radiogroup.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Plain/FlatElements/Button.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Plain/FlatElements/ButtonTag.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Plain/FlatElements/Checkbox.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Plain/FlatElements/ContentElement.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Plain/FlatElements/Header.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Plain/FlatElements/Hidden.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Plain/FlatElements/Imagebutton.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Plain/FlatElements/Input.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Plain/FlatElements/InputTypeButton.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Plain/FlatElements/Password.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Plain/FlatElements/Radio.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Plain/FlatElements/Reset.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Plain/FlatElements/Select.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Plain/FlatElements/Submit.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Plain/FlatElements/Textarea.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Plain/FlatElements/Textblock.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Plain/FlatElements/Textfield.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/PostProcessor/Mail/Plain/FlatElements/Upload.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/AdditionalElements/ErrorValidationMessage.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/AdditionalElements/Label.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/AdditionalElements/Legend.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/AdditionalElements/MandatoryValidationMessage.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/ContainerElements/Checkboxgroup.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/ContainerElements/Fieldset.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/ContainerElements/Form.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/ContainerElements/Radiogroup.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/FlatElements/Button.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/FlatElements/ButtonTag.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/FlatElements/Checkbox.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/FlatElements/ContentElement.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/FlatElements/Header.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/FlatElements/Hidden.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/FlatElements/Imagebutton.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/FlatElements/Input.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/FlatElements/InputTypeButton.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/FlatElements/Password.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/FlatElements/Radio.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/FlatElements/Reset.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/FlatElements/Select.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/FlatElements/Submit.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/FlatElements/Textarea.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/FlatElements/Textblock.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/FlatElements/Textfield.html [deleted file]
typo3/sysext/form/Resources/Private/Partials/Default/Show/FlatElements/Upload.html [deleted file]
typo3/sysext/form/Resources/Private/Templates/Frontend/AfterProcess.html [deleted file]
typo3/sysext/form/Resources/Private/Templates/Frontend/Confirmation.html [deleted file]
typo3/sysext/form/Resources/Private/Templates/Frontend/Show.html [deleted file]
typo3/sysext/form/Resources/Private/Templates/PostProcessor/Mail/Default/Html.html [deleted file]
typo3/sysext/form/Resources/Private/Templates/PostProcessor/Mail/Default/Plain.html [deleted file]
typo3/sysext/form/Resources/Private/Templates/Wizard.html [deleted file]
typo3/sysext/form/Resources/Public/Css/form.css
typo3/sysext/form/Resources/Public/Images/advanced-password.svg [new file with mode: 0644]
typo3/sysext/form/Resources/Public/Images/broom.png [deleted file]
typo3/sysext/form/Resources/Public/Images/captcha.jpg [deleted file]
typo3/sysext/form/Resources/Public/Images/checkbox.svg [new file with mode: 0644]
typo3/sysext/form/Resources/Public/Images/content-element.svg [new file with mode: 0644]
typo3/sysext/form/Resources/Public/Images/cursor-move.png [deleted file]
typo3/sysext/form/Resources/Public/Images/date-picker.svg [new file with mode: 0644]
typo3/sysext/form/Resources/Public/Images/drive-upload.png [deleted file]
typo3/sysext/form/Resources/Public/Images/duplicate.svg [new file with mode: 0644]
typo3/sysext/form/Resources/Public/Images/edit-heading.png [deleted file]
typo3/sysext/form/Resources/Public/Images/edit-textblock.png [deleted file]
typo3/sysext/form/Resources/Public/Images/fieldset.svg [new file with mode: 0644]
typo3/sysext/form/Resources/Public/Images/file-upload.svg [new file with mode: 0644]
typo3/sysext/form/Resources/Public/Images/finisher.svg [new file with mode: 0644]
typo3/sysext/form/Resources/Public/Images/image-upload.svg [new file with mode: 0644]
typo3/sysext/form/Resources/Public/Images/insert-after.svg [new file with mode: 0644]
typo3/sysext/form/Resources/Public/Images/insert-in.svg [new file with mode: 0644]
typo3/sysext/form/Resources/Public/Images/mail.png [deleted file]
typo3/sysext/form/Resources/Public/Images/module-menu-down.png [deleted file]
typo3/sysext/form/Resources/Public/Images/module-menu-right.png [deleted file]
typo3/sysext/form/Resources/Public/Images/multi-checkbox.svg [new file with mode: 0644]
typo3/sysext/form/Resources/Public/Images/multi-select.svg [new file with mode: 0644]
typo3/sysext/form/Resources/Public/Images/page.svg [new file with mode: 0644]
typo3/sysext/form/Resources/Public/Images/password.svg [new file with mode: 0644]
typo3/sysext/form/Resources/Public/Images/radio-button.svg [new file with mode: 0644]
typo3/sysext/form/Resources/Public/Images/remove.gif [deleted file]
typo3/sysext/form/Resources/Public/Images/single-select.svg [new file with mode: 0644]
typo3/sysext/form/Resources/Public/Images/static-text.svg [new file with mode: 0644]
typo3/sysext/form/Resources/Public/Images/submit-trigger.gif [deleted file]
typo3/sysext/form/Resources/Public/Images/summary-page.svg [new file with mode: 0644]
typo3/sysext/form/Resources/Public/Images/text.svg [new file with mode: 0644]
typo3/sysext/form/Resources/Public/Images/textarea.svg [new file with mode: 0644]
typo3/sysext/form/Resources/Public/Images/tooltip.png [deleted file]
typo3/sysext/form/Resources/Public/Images/ui-button-default.png [deleted file]
typo3/sysext/form/Resources/Public/Images/ui-button.png [deleted file]
typo3/sysext/form/Resources/Public/Images/ui-check-box.png [deleted file]
typo3/sysext/form/Resources/Public/Images/ui-check-boxes.png [deleted file]
typo3/sysext/form/Resources/Public/Images/ui-combo-box.png [deleted file]
typo3/sysext/form/Resources/Public/Images/ui-group-box.png [deleted file]
typo3/sysext/form/Resources/Public/Images/ui-labels.png [deleted file]
typo3/sysext/form/Resources/Public/Images/ui-radio-button.png [deleted file]
typo3/sysext/form/Resources/Public/Images/ui-radio-buttons.png [deleted file]
typo3/sysext/form/Resources/Public/Images/ui-scroll-pane-text.png [deleted file]
typo3/sysext/form/Resources/Public/Images/ui-text-field-hidden.png [deleted file]
typo3/sysext/form/Resources/Public/Images/ui-text-field-password.png [deleted file]
typo3/sysext/form/Resources/Public/Images/ui-text-field.png [deleted file]
typo3/sysext/form/Resources/Public/Images/user-silhouette.png [deleted file]
typo3/sysext/form/Resources/Public/Images/validator.svg [new file with mode: 0644]
typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor.js [new file with mode: 0644]
typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/Core.js [new file with mode: 0644]
typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/Helper.js [new file with mode: 0644]
typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/InspectorComponent.js [new file with mode: 0644]
typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/Mediator.js [new file with mode: 0644]
typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/ModalsComponent.js [new file with mode: 0644]
typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/StageComponent.js [new file with mode: 0644]
typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/TreeComponent.js [new file with mode: 0644]
typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/ViewModel.js [new file with mode: 0644]
typo3/sysext/form/Resources/Public/JavaScript/Backend/FormManager.js [new file with mode: 0644]
typo3/sysext/form/Resources/Public/JavaScript/Backend/FormManager/ViewModel.js [new file with mode: 0644]
typo3/sysext/form/Resources/Public/JavaScript/Backend/Vendor/jquery.mjs.nestedSortable.js [new file with mode: 0644]
typo3/sysext/form/Resources/Public/JavaScript/Wizard.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/Basic/Button.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/Basic/Checkbox.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/Basic/Fieldset.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/Basic/Fileupload.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/Basic/Form.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/Basic/Hidden.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/Basic/Password.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/Basic/Radio.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/Basic/Reset.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/Basic/Select.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/Basic/Submit.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/Basic/Textarea.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/Basic/Textline.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/ButtonGroup.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/Container.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/Content/Header.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/Content/Textblock.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/Dummy.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/Elements.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/Predefined/CheckboxGroup.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/Predefined/Email.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/Predefined/Name.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Elements/Predefined/RadioGroup.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Helpers/Element.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Helpers/History.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Ux/Ext.ux.form.FakeFormPanel.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Ux/Ext.ux.form.ValueCheckbox.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Ux/Ext.ux.form.spinnerfield.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Ux/Ext.ux.form.textfieldsubmit.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Ux/Ext.ux.grid.CheckColumn.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Ux/Ext.ux.grid.ItemDeleter.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Ux/Ext.ux.grid.SingleSelectCheckColumn.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Ux/Ext.ux.isemptyobject.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Ux/Ext.ux.merge.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Ux/Ext.ux.spinner.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Elements.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Elements/Basic.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Elements/ButtonGroup.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Elements/Content.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Elements/Predefined.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Form.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Form/Attributes.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Form/Behaviour.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Form/PostProcessor.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Form/PostProcessors/Dummy.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Form/PostProcessors/Mail.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Form/PostProcessors/PostProcessor.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Form/PostProcessors/Redirect.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Form/Prefix.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Dummy.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Attributes.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Filters.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Filters/Alphabetic.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Filters/Alphanumeric.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Filters/Currency.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Filters/Digit.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Filters/Dummy.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Filters/Filter.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Filters/Integer.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Filters/LowerCase.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Filters/RegExp.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Filters/StripNewLines.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Filters/TitleCase.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Filters/Trim.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Filters/UpperCase.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Label.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Legend.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Options.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation/Alphabetic.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation/Alphanumeric.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation/Between.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation/Date.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation/Digit.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation/Dummy.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation/Email.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation/Equals.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation/FileAllowedTypes.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation/FileMaximumSize.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation/FileMinimumSize.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation/Float.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation/GreaterThan.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation/InArray.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation/Integer.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation/Ip.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation/Length.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation/LessThan.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation/RegExp.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation/Required.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation/Rule.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Validation/Uri.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Forms/Various.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Left/Options/Panel.js [deleted file]
typo3/sysext/form/Resources/Public/JavaScript/Wizard/Viewport/Right.js [deleted file]
typo3/sysext/form/Tests/Unit/Controller/AbstractBackendControllerTest.php [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/Controller/Fixtures/BackendUtilityFixture.php [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/Controller/Fixtures/BlankForm.yaml [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/Controller/Fixtures/SimpleContactForm.yaml [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/Controller/FormEditorControllerTest.php [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/Controller/FormFrontendControllerTest.php [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/Controller/FormManagerControllerTest.php [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/Domain/Configuration/ConfigurationServiceTest.php [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/Domain/Model/ConfigurationTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Filter/AlphabeticFilterTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Filter/AlphanumericFilterTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Filter/CurrencyFilterTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Filter/DigitFilterTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Filter/IntegerFilterTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Filter/LowerCaseFilterTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Filter/RegExpFilterTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Filter/StripNewLinesFilterTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Filter/TitleCaseFilterTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Filter/TrimFilterTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Filter/UpperCaseFilterTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Fixtures/PostProcessorWithFormPrefixFixture.php [deleted file]
typo3/sysext/form/Tests/Unit/Fixtures/PostProcessorWithoutFormPrefixFixture.php [deleted file]
typo3/sysext/form/Tests/Unit/Fixtures/PostProcessorWithoutInterfaceFixture.php [deleted file]
typo3/sysext/form/Tests/Unit/Hooks/DataStructureIdentifierHookTest.php [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/Mvc/Configuration/Fixtures/Header.yaml [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/Mvc/Configuration/Fixtures/Invalid.yaml [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/Mvc/Configuration/InheritancesResolverServiceTest.php [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/Mvc/Configuration/TypoScriptServiceTest.php [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/Mvc/Configuration/YamlSourceTest.php [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/Mvc/Persistence/Fixtures/BlankForm.txt [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/Mvc/Persistence/Fixtures/BlankForm.yaml [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/Mvc/Persistence/FormPersistenceManagerTest.php [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/Mvc/ProcessingRuleTest.php [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/Mvc/Validation/CountValidatorTest.php [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/Mvc/Validation/EmptyValidatorTest.php [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/Mvc/Validation/Fixtures/TestValidator.php [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/Mvc/Validation/MimeTypeValidatorTest.php [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/PostProcess/MailPostProcessorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/PostProcess/PostProcessorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Utility/ArrayUtilityTest.php [new file with mode: 0644]
typo3/sysext/form/Tests/Unit/Utility/TypoScriptToJsonConverterTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Validator/AbstractValidatorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Validator/AlphabeticValidatorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Validator/AlphanumericValidatorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Validator/BetweenValidatorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Validator/DateValidatorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Validator/DigitValidatorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Validator/EmailValidatorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Validator/EqualsValidatorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Validator/FileAllowedTypesValidatorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Validator/FileMaximumSizeValidatorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Validator/FileMinimumSizeValidatorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Validator/FloatValidatorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Validator/GreaterThanValidatorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Validator/InArrayValidatorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Validator/IntegerValidatorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Validator/IpValidatorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Validator/LengthValidatorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Validator/LessThanValidatorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Validator/RegExpValidatorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Validator/RequiredValidatorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/Validator/UriValidatorTest.php [deleted file]
typo3/sysext/form/Tests/Unit/ViewHelpers/Form/DatePickerViewHelperTest.php [new file with mode: 0644]
typo3/sysext/form/composer.json
typo3/sysext/form/ext_emconf.php
typo3/sysext/form/ext_localconf.php
typo3/sysext/form/ext_tables.php [new file with mode: 0644]
typo3/sysext/form/ext_tables.sql [deleted file]
typo3/sysext/form/ext_typoscript_setup.txt [new file with mode: 0644]

index 92969d2..b7d0033 100644 (file)
 @charset "UTF-8";
 
-.std-em-selector {
-  font-size: 90%;
-  font-style: normal;
+//
+// Variables
+//
+// @toDo remove these variables after including this file in backend.less
+// Bootstrap: variables.less
+@panel-default-text: @gray-dark;
+
+// /Build/Resources/Public/Less/cropper/variables.less
+@screen-lg: 1200px; // Large screen / wide desktop
+
+// /Build/Resources/Public/Less/_variables.less
+@gray-dark: rgb(90, 90, 90);
+@gray: rgb(115, 115, 115);
+@brand-primary: #0078e6;
+@brand-success: #79a548;
+@brand-info: #6daae0;
+@brand-warning: #e8a33d;
+@brand-danger: #c83c3c;
+@table-bg: #fafafa;
+@table-bg-hover: darken(@table-bg, 5%);
+@panel-default-heading-bg: #ddd;
+@text-color: #000;
+@btn-default-bg: #eee;
+@btn-default-border: #bbb;
+
+// /Build/Resources/Public/Less/Component/module.less
+@module-docheader-height: 65px;
+@module-docheader-border: #c3c3c3;
+
+// /Build/Resources/Public/Less/TYPO3/_module_web_page.less
+@page-ce-header-hover-bg: #d0d0d0;
+
+// /Build/Resources/Public/Less/TYPO3/_element_tree.less
+@navigation-bg: #f5f5f5;
+
+// Form Variables
+@stage-max-width: 600px;
+@stage-abstract-element-height: 62px;
+@stage-abstract-element-toolbar-height: 35px;
+@stage-icon-container-width: 40px;
+@stage-validation-list-width: 100px;
+@stage-breakpoint: (@screen-lg + 100);
+@stage-validation-transition-time-in: 0.2s;
+@stage-validation-transition-time-out: 0.3s;
+
+@stage-background-color: #fafafa;
+@stage-element-toolbar-background: #d0d0d0;
+@collection-element-background: @page-ce-header-hover-bg;
+
+//
+// Mixins
+//
+
+.fade-out-gradient-effect-bottom (@color, @gradient-start-height, @gradient-height) {
+  &:before, &:after {
+    display: block;
+    content: '';
+    position: absolute;
+    bottom: 0;
+    right: 0;
+    left: 0;
+  }
+  &:before {
+    height: @gradient-start-height;
+    background: @color;
+  }
+  &:after {
+    bottom: @gradient-start-height;
+    height: @gradient-height;
+    background: linear-gradient(to bottom, rgba(red(@color), green(@color), blue(@color), 0) 0%, @color 100%);
+  }
 }
 
-.std-strong-selector {
-  display: block;
-  font-size: 90%;
-  font-weight: normal;
-  color: #C00;
+.selected-button-style-primary () {
+  .btn {
+    background-color: #fff;
+    border-color: #fff;
+    &:hover, &.active {
+      background-color: lighten(@brand-info, 30%);
+    }
+  }
+  .icon {
+    svg path {
+      fill: @brand-primary;
+    }
+  }
 }
 
-.std-li-selector{
-  float: none;
-  width: auto;
-  margin-right: 0;
-  margin-left: 1em;
+.collapsed-icon-animation () {
+  transform: rotate(0deg);
+  transition: transform 0.2s;
 }
-#fake-form {
-
-  ol {
-    padding-left: 0 !important;
-    list-style: none !important;
-  }
 
-  /* style for each form element */
-  li {
-    overflow: hidden;
-    padding: 0.5em;
-    margin-bottom: 0.5em;
-
-    &#element-placeholder{
-      padding: 0;
-      margin: 0;
-    }
+.expanded-icon-animation () {
+  transform: rotate(90deg);
+  transition: transform 0.2s;
+}
 
-    input + label,
-    textarea + label,
-    select + label {
-      .std-li-selector;
-    }
+//
+// X-Component
+//
+.t3-form-x-component {
+  position: absolute;
+  top: 0;
+  height: 100%;
+  line-height: normal;
+  background: @navigation-bg;
 
-    textarea + label {
-      vertical-align: top;
-    }
+  a {
+    text-decoration: none;
   }
-
-  textarea, input[type=text]{
-    border: 1px solid #c0c0c0;
+  ol,
+  ul {
+    list-style: none;
+    padding: 0;
   }
-
-  input[type=text]{
-    // equal width like textareas
-    width:300px;
-    padding: 3px;
+  .ui-sortable-placeholder {
+    outline-offset: -1px !important;
   }
+}
 
-  label {
-    display:block;
-    margin-right: 1em;
-    vertical-align: baseline;
+.t3-form-x-component-inner-wrapper {
+  padding: 1.5em;
+}
 
-    em{
-      .std-em-selector;
-    }
+//
+// Structure Tree
+//
+#t3-form-navigation-component {
+  overflow: hidden;
+  left: 0;
+}
 
-    strong{
-      .std-strong-selector;
-    }
-  }
+#t3-form-structure-panel {
+  overflow: auto;
+  padding-top: @module-docheader-height;
+  height: 100%;
 
-  .x-checkbox, .x-radio{
-    label{
-      display:inline-block;
-    }
+  .icon {
+    z-index: 1;
   }
-
-  legend {
-    border-bottom:0;
-    em{
-      .std-em-selector;
-    }
-
-    strong{
-      .std-strong-selector;
-    }
+  #t3-form-navigation-component-tree-root-container, .tree li > div {
+    border: 1px solid transparent;
+    cursor: pointer;
   }
-
-  fieldset {
-    position: relative;
-    margin: 0;
-    padding: 0;
-
-    &.submit {
-      border-style: none;
-    }
-
-    &.fieldset-horizontal {
-      border-width: 0;
-
-      &.label-below label {
-        display: block;
-        margin-left: 0;
-        margin-top: 0.2em;
-        font-size: 90%;
-        text-align: left;
-        color: #999999;
-      }
-
-      label{
-        em {
-          display: inline;
-        }
-      }
-
-      ol {
-        padding: 0;
+  .tree {
+    .svg-wrapper {
+      svg {
+        overflow: visible;
+        position: relative;
+        top: -0.8em;
+        left: 0.6em;
       }
-
-      li {
-        float: left;
-        margin-right: 1em;
-        padding: 0;
+      path {
+        fill: none;
+        shape-rendering: crispEdges;
+        stroke: rgb(221, 221, 221);
+        stroke-width: 1;
       }
     }
-
-    &.fieldset-subgroup {
-      margin-bottom: -2em;
-      border-style: none;
-
-      ol {
-        position: relative;
-        top: -1.4em;
-        padding: 0;
-      }
-
-      li {
-        padding: 0;
+    li {
+      white-space: nowrap;
+      .icon-actions-pagetree-collapse {
+        margin-right: 0.3em;
+        img {
+          .expanded-icon-animation ();
+        }
       }
-
-      legend {
-        margin-left: 0;
-        padding: 0;
+      &.mjs-nestedSortable-collapsed {
+        > ol {
+          display: none;
+        }
+        .icon-actions-pagetree-collapse img {
+          .collapsed-icon-animation ();
+        }
       }
-
-      input + label {
-        float: none;
-        width: auto;
-        display: inline;
-        margin: 0 0 0 1em;
+      small {
+        padding-left: 0.5em;
+        font-size: 80%;
       }
     }
-  }
-
-  legend {
-    font-size: 12px;
-    font-weight: bold;
-    color: #000000;
-
-    em {
-      position: absolute;
-    }
-
-    strong {
-      position: absolute;
-      top: 1.4em;
+    .t3-form-icon {
+      margin-right: 0.5em;
+      margin-left: 0.5em;
     }
-  }
-
-  /* labels as block, labels displayed above or below the input fields */
-  .labels-block{
-    label {
-      display: block;
-      float: none;
-      margin: 0 0 0.5em;
-      width: auto;
+    .t3-form-element-has-children > div .t3-form-icon {
+      margin-left: 0.1em;
     }
-
-    input + label,
-    textarea + label{
-      margin: 0.5em 0 0;
+    .sortable-hover {
+      outline: 1px solid darken(@panel-default-heading-bg, 20%);
     }
-
+  }
+  .tree li > div:hover,
+  .t3-form-form-element-selected,
+  #t3-form-navigation-component-tree-root-container:hover,
+  .t3-form-root-element-selected {
+    background-color: darken(@navigation-bg, 1%);
+    border-color: darken(@navigation-bg, 10%);
+    border-radius: 2px;
+    margin-left: -2em;
+    padding-left: 2em;
+    margin-right: -1.3em;
+  }
+  .tree li > .t3-form-form-element-selected,
+  .tree li > .t3-form-form-element-selected:hover,
+  #t3-form-navigation-component-tree-root-container.t3-form-root-element-selected,
+  #t3-form-navigation-component-tree-root-container.t3-form-root-element-selected:hover {
+    background-color: #fff;
+    border-color: darken(@navigation-bg, 10%);
+  }
+  .t3-form-x-component-inner-wrapper {
+    padding-top: 2.5em;
   }
 }
 
-/* labels alignment right */
-#fake-form .labels-alignment-right label,
-#fake-form .labels-alignment-right .fieldset-subgroup legend,
-#fake-form .labels-alignment-right.fieldset-subgroup legend {
-  text-align: right;
-}
-
-#fake-form .labels-block fieldset.fieldset-subgroup,
-#fake-form fieldset.labels-block.fieldset-subgroup {
-  margin-bottom: 0;
-}
-
-#fake-form .labels-block .fieldset-subgroup legend,
-#fake-form .labels-block.fieldset-subgroup legend {
-  width: auto;
-}
-
-#fake-form .labels-block .fieldset-subgroup legend em,
-#fake-form .labels-block.fieldset-subgroup legend em {
-  position: relative;
-}
-
-#fake-form .labels-block .fieldset-subgroup legend strong,
-#fake-form .labels-block.fieldset-subgroup legend strong {
-  position: relative;
-  top: 0;
-}
-
-#fake-form .labels-block .fieldset-subgroup ol,
-#fake-form .labels-block.fieldset-subgroup ol {
-  top: 0;
-  margin: 0;
-  padding: 0.5em 0 0;
-}
-
-/* element HIDDEN */
-#fake-form .formwizard-element.hidden-element {
-  cursor: default;
-}
-
-#fake-form .formwizard-element .hidden-dummy-element {
-  margin: 0;
-  padding: 5px;
-  border:1px dotted #A9A9A9;
+//
+// Inspector
+//
+.form-group.t3-form-collection-element-remove-button,
+.t3-form-inspector-finishers-editor-removeButton,
+.form-group.t3-form-inspector-validators-editor-removeButton {
+  margin: 0 !important;
+  font-size: 0;
 }
 
-/* styles for drag and drop content */
-.x-dd-drag-ghost .formwizard-element {
-  list-style:none;
+#t3-form-inspector-panels-container {
+  overflow: hidden;
+  right: 0;
+  padding-top: @module-docheader-height;
 }
 
-.x-dd-drop-icon {
-  top: 7px;
+#t3-form-inspector-panels {
+  overflow: auto;
+  height: 100%;
 }
 
-.x-dd-drag-ghost ol {
-  margin: 5px 0;
-  padding: 0;
-  list-style: none;
-}
+#t3-form-inspector {
+  padding: 1em 0.5em;
 
-.x-dd-drag-ghost .buttongroup,
-.x-dd-drag-ghost label em,
-.x-dd-drag-ghost label strong {
-  display: none;
+  h2,
+  h3,
+  h4 {
+    margin: 0;
+    padding: 0.1em 0.2em 0.2em 0.5em;
+    border-top: 1px solid @module-docheader-border;
+    clear: both;
+    font: inherit;
+    font-weight: bold;
+  }
+  h2 {
+    padding-bottom: 1em;
+    border: none;
+    border-bottom: 1px solid @module-docheader-border;
+  }
+  > h2:first-child {
+    border-top: none;
+  }
+  h3 {
+    color: @text-color;
+    padding-top: 0.3em;
+    border: none;
+  }
+  h4 {
+    padding: 0.8em 3em 0.8em 2.5em;
+    font-weight: 500;
+    background-color: @panel-default-heading-bg;
+    span[data-template-property="label"] {
+      vertical-align: top;
+    }
+  }
+  .t3-form-remove-element-button {
+    position: absolute;
+    top: 90px;
+    right: 2.5em;
+  }
+  .t3-form-control-group,
+  .t3-form-add-collection-element {
+    margin: 1.5em 0.5em;
+    clear: both;
+  }
+  .t3-form-inspector-editor-requiredValidator {
+    label {
+      cursor: pointer;
+    }
+  }
 }
 
-.x-dd-drag-ghost label {
-  margin: 0 10px 0 5px;
+//
+// Inspector Collection
+//
+.t3-form-add-collection-element {
+  padding-bottom: 1em;
 }
 
-.x-dd-drag-ghost legend {
-  margin: 0 5px;
-  font-size: 14px;
-  font-weight: bold;
-  color: #000;
-  border: none;
-}
+.t3-form-collection-container {
+  margin-top: -1em;
+  padding: 0.6em;
 
-.x-grid-panel .remove {
-  background-image: url("../Images/remove.gif");
-  width: 15px;
-  height: 16px;
+  .ui-sortable-handle {
+    cursor: auto;
+  }
+  h4 {
+    cursor: move;
+  }
+  .icon-actions-view-table-expand {
+    position: absolute;
+    left: 0.5em;
+  }
+  a.collapsed {
+    .icon-actions-view-table-expand svg {
+      .collapsed-icon-animation ();
+    }
+  }
+  a:not(.collapsed) {
+    .icon-actions-view-table-expand svg {
+      .expanded-icon-animation ();
+    }
+  }
 }
 
-.x-dd-drag-proxy,
-.x-dd-drop-nodrop {
-  background-color: #fff;
-  border-color: #c0c0c0;
+.t3-form-collection-element {
+  position: relative;
+  margin-bottom: 0.5em;
+  border: 1px solid @module-docheader-border;
+  border-top: none;
+  background: @navigation-bg;
+
+  .t3-form-collection-element-remove-button {
+    position: absolute;
+    right: 0.5em;
+    top: 0.6em;
+  }
 }
-.tab-content{
-  fieldset{
 
-    #formwizard{
-      display:inherit;
+//
+// Inspector Property Grid
+//
+.property-grid {
+  .form-control {
+    min-width: initial;
+    min-width: auto;
+    font-size: 0.9em;
+  }
+  .table {
+    th {
+      font-size: 0.9em;
     }
-
-    &.form-section{
-      float: left;
-      min-width: 380px;
-      width: 100%;
-      padding-bottom: 15px;
-
-      &:last-child{
-        margin-bottom: 1em;
+    > tbody > tr {
+      cursor: pointer;
+      background-color: @table-bg;
+      &:last-child {
+        cursor: auto;
       }
-
-      ol{
-        &#formwizard-right{
-          // overwrite inline-style "auto"
-          width:100vw !important;
-          overflow: visible !important;
-          position: relative;
-          float:none;
-          left:5px !important;
-          padding-top:0;
-          padding-left:0;
-          margin-right: 10px;
-          top:30px !important;
-          display: table-cell;
-          height:auto !important;
-          list-style: none;
-          border-top-style: none;
-
-          &.hover{
-            left:0;
-            width:auto;
-          }
+      > td {
+        padding: 0.6em 0.3em;
+        text-align: center;
+        &:first-child {
+          width: 35px;
+        }
+        &:nth-child(2), &:nth-child(3) {
+          width: 75px;
+        }
+        &:nth-child(4) {
+          width: 65px;
+        }
+        &:nth-child(5) {
+          width: 35px;
         }
       }
     }
+    .btn {
+      background-color: @btn-default-bg;
+      border-color: @btn-default-border;
+    }
   }
-}
-
-/* outer wrapper of whole wizard */
-#form-wizard-element {
-  z-index: 1;
-
-  #formwizard-left{
-    display: table-cell;
-    float:left !important;
-    margin-right: -1px;
-
-    .x-tab-panel-body{
-      // overwrite inline-styles with important ;(
-      height:100% !important;
-      overflow:visible !important;
+  .sort-row-field {
+    cursor: move;
+  }
+  .ui-sortable-helper {
+    td {
+      border: none;
     }
   }
+  .ui-sortable-placeholder {
+    height: 45px;
+    border-left: 1px solid @module-docheader-border !important;
+    border-right: 1px solid @module-docheader-border !important;
+    outline-offset: -5px !important;
+  }
 }
 
-/* inner wrapper of whole wizard */
-#formwizard {
-  background-color: #F8F8F8;
-}
-
-/* applied when a element is moved */
-#formwizard.hover-move {
-  cursor: move;
+//
+// Stage
+//
+#t3-form-stage-inner-container {
+  display: inline-block;
+  width: 90%;
+  text-align: left;
+  @media (min-width: @stage-breakpoint) {
+    width: @stage-max-width;
+  }
 }
 
-/* left panel */
-#formwizard-left.x-border-panel {
+#t3-form-stage-container {
+  overflow: auto;
   position: relative;
-  left: auto;
-  top: auto;
-}
-
-/* tabs */
-#formwizard-left .x-tab-panel-header {
-  background-color: transparent;
-}
-
-/* tabs inner */
-#formwizard-left .x-tab-strip {
-  margin-bottom: 0;
-}
-
-#formwizard-left .x-tab-strip-top .x-tab-left {
-  padding-right: 20px;
-}
-
-#formwizard-left .x-tab-strip-top .x-tab-right {
-  padding: 5px 10px 2px;
-  background-color: #EDEDED;
-  border-radius: 0;
-}
-
-#formwizard-left .x-tab-strip-top .x-tab-strip-active .x-tab-right,
-#formwizard-left .x-tab-strip-top .x-tab-strip-active.x-tab-strip-over .x-tab-right{
-  background-color: transparent;
-  border-bottom-color: #F8F8F8;
-}
-
-#formwizard-left .x-tab-strip-top .x-tab-strip-over .x-tab-right {
-  background-color: #E1E1E1;
-}
-
-#formwizard-left li.validation-error .x-tab-left,
-#formwizard-left div.validation-error .x-accordion-hd {
-  margin-right: 14px;
-  background-image: url("../../../../../t3skin/extjs/images/form/exclamation.gif");
-  background-position: right 1px;
-  background-repeat: no-repeat;
-}
-
-/* content below tabs */
-#formwizard-left .x-tab-panel-body-content {
-  min-height: 330px;
-  padding: 10px;
-  background: transparent;
-  border: 1px solid #C0C0C0;
-  border-top-width: 0;
-}
-
-/* info messages (also for drag and drop) */
-#formwizard-left .message-information,
-#fake-form .message-information,
-.x-dd-drag-ghost .message-information {
-  margin: 10px 0 15px 16px;
-  padding: 12px 10px;
-  background-image: none;
-  border-radius: 0;
-  box-shadow: none;
-}
-
-#formwizard-left .message-information p,
-#fake-form .message-information p,
-.x-dd-drag-ghost .message-information {
-  margin: 0;
-}
-
-/* intro info messages */
-#formwizard-left #formwizard-left-elements-intro,
-#formwizard-left #formwizard-left-options-dummy,
-#fake-form .message-information {
-  margin: 0 0 10px;
-}
-
-#formwizard-left .x-tab-panel-body,
-#formwizard-left .x-accordion-hd {
-  background: transparent none;
-  border-width: 0;
-}
-
-/* accordion */
-#formwizard-left .x-panel-accordion {
-  border-bottom: 1px solid #C7C7C7;
-}
-
-#formwizard-left .x-panel-accordion:last-child {
-  border-bottom: medium none;
-}
-
-/* headline of accordion */
-#formwizard-left .x-accordion-hd {
-  padding-left: 0;
-}
-
-/* toggle icon of accordion */
-#formwizard-left .x-accordion-hd .x-tool-toggle {
-  margin: 0;
-  float: left;
-  background-image: url("../Images/module-menu-down.png");
-  background-position: 0 4px;
-}
-
-#formwizard-left .x-panel-collapsed .x-accordion-hd .x-tool-toggle {
-  background-image: url("../Images/module-menu-right.png");
-  background-position: 1px 3px;
-}
-
-#formwizard-left .x-accordion-hd .x-panel-header-text {
-  font-weight: bold;
-}
-
-#formwizard-left .x-accordion-hd .x-panel-body {
-  padding-left: 15px;
-}
-
-/* element inside accordion */
-#formwizard-left .x-form {
-  margin-left: 15px;
-  margin-top: 10px;
-}
-
-#formwizard-left .x-form fieldset {
-  padding: 0;
-  border: none;
-}
-#formwizard-left .x-form fieldset legend {
-  padding: 0;
-  font-size: 12px;
-  color: #222222;
-}
-
-#formwizard-left .x-panel-tbar {
-  margin-top: 10px;
-  padding-left: 15px;
-  padding-bottom: 0;
-  border-width: 0;
-}
-
-#formwizard-left .x-panel-tbar .x-toolbar {
-  padding: 0;
-}
-
-#formwizard-left .x-table-layout {
-  margin-bottom: 10px;
-}
-
-/* generic element like textfield */
-#formwizard-left .formwizard-element {
-  margin-left: 12px;
-  background-color: transparent;
-  background-image: none;
-  border-color: transparent;
-}
-
-#formwizard-left .formwizard-element.x-btn-over {
-  background-color: #D5D5D5;
-  background-image: -moz-linear-gradient(center top , #F6F6F6 10%, #D5D5D5 90%);
-  border-color: #C0C0C0;
-  border-radius: 0;
-}
-
-#formwizard-left .formwizard-element .x-btn-mc {
+  height: 100%;
   text-align: left;
-}
-
-/* form elements in left panel */
-.formwizard-left-elements-basic-button {
-  background-image: url("../Images/ui-button.png");
-}
-
-.formwizard-left-elements-basic-checkbox {
-  background-image: url("../Images/ui-check-box.png");
-}
-
-.formwizard-left-elements-basic-fieldset {
-  background-image: url("../Images/ui-group-box.png");
-}
-
-.formwizard-left-elements-basic-fileupload {
-  background-image: url("../Images/drive-upload.png");
-}
-
-.formwizard-left-elements-basic-hidden {
-  background-image: url("../Images/ui-text-field-hidden.png");
-}
-
-.formwizard-left-elements-basic-password {
-  background-image: url("../Images/ui-text-field-password.png");
-}
-
-.formwizard-left-elements-basic-radio {
-  background-image: url("../Images/ui-radio-button.png");
-}
-
-.formwizard-left-elements-basic-reset {
-  background-image: url("../Images/broom.png");
-}
-
-.formwizard-left-elements-basic-select {
-  background-image: url("../Images/ui-combo-box.png");
-}
-
-.formwizard-left-elements-basic-submit {
-  background-image: url("../Images/ui-button-default.png");
-}
-
-.formwizard-left-elements-basic-textarea {
-  background-image: url("../Images/ui-scroll-pane-text.png");
-}
-
-.formwizard-left-elements-basic-textline {
-  background-image: url("../Images/ui-text-field.png");
-}
-
-.formwizard-left-elements-predefined-checkboxgroup {
-  background-image: url("../Images/ui-check-boxes.png");
-}
-
-.formwizard-left-elements-predefined-email {
-  background-image: url("../Images/mail.png");
-}
-
-.formwizard-left-elements-predefined-name {
-  background-image: url("../Images/user-silhouette.png");
-}
-
-.formwizard-left-elements-predefined-radiogroup {
-  background-image: url("../Images/ui-radio-buttons.png");
-}
-
-.formwizard-left-elements-content-header {
-  background-image: url("../Images/edit-heading.png");
-}
-
-.formwizard-left-elements-content-textblock {
-  background-image: url("../Images/edit-textblock.png");
-}
-
-#formwizard-left .x-form-text {
-  height: 17px;
-}
-
-#formwizard-left .x-btn-text-icon .x-btn-icon-small-left .x-btn-text {
-  color: black;
-}
-
-#formwizard-left .x-small-editor .x-form-text {
-  height: 13px !important;
-}
-
-/* icon in element field for applying entered text */
-#formwizard-left .x-form-field-wrap .x-form-submit-trigger {
-  background-image: url("../Images/submit-trigger.gif");
-}
-
-/* right panel */
-#formwizard-right {
-  min-height: 350px;
-  padding: 30px 0 10px 2px;
-  overflow: visible;
-}
-
-#fake-form {
-  padding: 10px;
-  background-color: tansparent;
-  border: 1px solid #C0C0C0;
-}
-
-#fake-form li {
-  overflow: visible;
-}
-
-/* visible area of element on right panel */
-#fake-form div.overflow-hidden {
-  overflow: hidden;
-
-  input{
-    margin-left: 1px;
+  @media (min-width: @stage-breakpoint) {
+    text-align: center;
   }
-}
 
-/* wrap around all elements on right panel */
-#fake-form .formwizard-element {
-  border: 1px solid transparent;
-  position: relative;
-}
+  ol,
+  ul {
+    list-style: none;
+  }
+  .form-section {
+    border: none;
+  }
+  .panel-heading {
+    button {
+      outline: none;
+    }
+    .paginiation-label {
+      margin-right: 1em;
+    }
+  }
+  .t3-form-new-element-container {
+    height: @stage-abstract-element-height;
+    border: 1px dashed @panel-default-heading-bg;
+    text-align: center;
+    padding-top: @stage-abstract-element-height/2;
+    .btn {
+      transform: translateY(-50%);
+    }
+  }
 
-#fake-form .formwizard-element.hover,
-#fake-form .formwizard-element.hidden.hover {
-  background-color: #F9FCFF;
-  border: 1px solid #C5DBE6;
-}
+  // Abstract
+  &.t3-form-stage-viewmode-abstract {
+    ol,
+    ul {
+      padding-left: @stage-icon-container-width;
+      padding-right: 1em;
+    }
+    .t3-form-page-title {
+      margin: 0 0 0.5em;
+    }
+    #t3-form-stage-inner-container {
+      overflow: hidden;
+    }
+    .t3-form-element-composit {
+      &:not(.t3-form-element-toplevel) {
+        margin-bottom: 1em;
+        padding-bottom: 1px;
+        outline: 1px solid #dddddd;
+        outline-offset: -1px;
+      }
+      .sortable-hover {
+        outline-color: darken(@panel-default-heading-bg, 40%);
+      }
+      .t3-form-form-composit-element-selected {
+        outline-color: @brand-primary;
+      }
+    }
+    .t3-form-element-composit.sortable-hover > .ui-sortable-handle,
+    .ui-sortable-handle:hover {
+      border-color: darken(@panel-default-heading-bg, 40%);
+      .t3-form-icon-container {
+        background-color: darken(@panel-default-heading-bg, 40%);
+        path {
+          fill: #fff;
+        }
+      }
+    }
+    .ui-sortable {
+      fieldset {
+        position: relative;
+        min-height: 130px;
+        padding-top: 5em;
+        legend {
+          position: absolute;
+          top: 1em;
+          display: inline-block;
+          width: 95%;
+        }
+      }
+    }
+    .ui-sortable-handle {
+      overflow: hidden;
+      position: relative;
+      height: @stage-abstract-element-height;
+      margin-bottom: 1em;
+      border: 1px solid @panel-default-heading-bg;
+      background-color: #fff;
+
+      &:hover {
+        .t3-form-validator-list {
+          right: 0;
+          transition: right @stage-validation-transition-time-in;
+        }
+        .t3-form-element-info .element-content {
+          span, div {
+            color: @gray-dark;
+          }
+        }
+        .t3-form-validator-info .t3-form-icon {
+          margin-right: (@stage-validation-list-width - 25);
+          transition: margin @stage-validation-transition-time-in;
+        }
+      }
+      &:has (.ui-sortable-handle:hover) {
+        border-color: transparent;
+      }
+      span {
+        color: @gray-dark;
+      }
+    }
+    .ui-state-disabled {
+      cursor: auto;
+      &:hover {
+        background: none;
+      }
+    }
+    .ui-sortable-placeholder {
+      margin-bottom: 1em;
+    }
+    .t3-form-icon-container {
+      float: left;
+      width: @stage-icon-container-width;
+      height: 100%;
+      padding: 1em;
+      cursor: move;
+      background-color: @panel-default-heading-bg;
+      .t3-form-icon {
+        height: 100%;
+      }
+    }
+    .t3-form-form-element-body {
+      height: 100%;
+    }
+    .t3-form-element-info {
+      position: relative;
+      float: left;
+      width: 55%;
+      height: 100%;
+      padding-left: 1em;
+      .fade-out-gradient-effect-bottom (#fff, 0.8em, 1em);
+      .element-label-container {
+        float: left;
+        position: relative;
+        width: 45%;
+        height: 100%;
+        .element-label {
+          overflow: hidden;
+          position: absolute;
+          top: 50%;
+          width: 100%;
+          text-overflow: ellipsis;
+          transform: translateY(-50%);
+        }
+      }
+      .element-content {
+        padding-top: 1em;
+        white-space: nowrap;
+        font-size: 0.8em;
+        span, div {
+          color: @panel-default-heading-bg;
+        }
+      }
+    }
+    .t3-form-validator-info {
+      position: relative;
+      overflow: hidden;
+      float: right;
+      height: 100%;
+      .t3-form-icon {
+        height: 100%;
+        z-index: 1;
+        margin-left: 1em;
+        transition: margin @stage-validation-transition-time-out;
+        filter: grayscale(100%);
+      }
+      .t3-form-validator-list {
+        .fade-out-gradient-effect-bottom(@panel-default-heading-bg, 1em, 1em);
+        position: absolute;
+        top: 0;
+        right: -@stage-validation-list-width;
+        width: @stage-validation-list-width;
+        height: 100%;
+        padding: 1em 1em 1em (@stage-validation-list-width - 65);
+        font-size: 0.8em;
+        transition: right @stage-validation-transition-time-out;
+        background-color: @panel-default-heading-bg;
+      }
+      .validator-label {
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        color: @gray-dark;
+      }
+    }
+    #t3-form-stage .t3-form-form-element-selected {
+      position: relative;
+      padding-top: @stage-abstract-element-toolbar-height;
+      height: @stage-abstract-element-height + @stage-abstract-element-toolbar-height;
+      border: none;
+
+      .t3-form-form-element-body {
+        border: 1px solid @brand-primary;
+      }
+      .t3-form-icon-container {
+        background-color: @brand-primary;
+      }
+      .t3-form-element-info .element-content {
+        span, div {
+          color: @gray-dark;
+        }
+      }
+      .t3-form-validator-list {
+        @validation-list-background: lighten(@brand-info, 30%);
+        right: 0;
+        transition: right @stage-validation-transition-time-in;
+        background-color: @validation-list-background;
+        &:before {
+          background-color: @validation-list-background;
+        }
+        &:after {
+          background: linear-gradient(to bottom, rgba(red(@validation-list-background), green(@validation-list-background), blue(@validation-list-background), 0) 0%, @validation-list-background 100%);
+        }
+      }
+      .t3-form-validator-info .t3-form-icon {
+        margin-right: (@stage-validation-list-width - 25);
+        filter: none;
+      }
+      .btn-toolbar-container {
+        position: absolute;
+        top: 0;
+        right: 0;
+        width: 100%;
+        height: @stage-abstract-element-toolbar-height;
+        border: 1px solid @brand-primary;
+        background-color: @brand-primary;
+        padding-right: 0.7em;
+        padding-top: 0.4em;
+        &:before, &:after {
+          position: absolute;
+          top: 0;
+          display: block;
+          width: 1px;
+          height: 100%;
+          content: ' ';
+          background-color: @brand-primary;
+        }
+        &:before {
+          left: -1px;
+        }
+        &:after {
+          right: -1px;
+        }
+        .dropdown-menu {
+          left: auto;
+          left: initial;
+          min-width: initial;
+          right: 0;
+          padding-left: 0;
+          padding-right: 0;
+          background-color: darken(@brand-primary, 10%);
+          > li a:hover {
+            background-color: darken(@brand-primary, 5%);
+          }
+        }
+        .caret {
+          color: @brand-primary;
+        }
+        .t3-form-dropdown-buttons {
+          .icon {
+            margin-right: 0.5em;
+          }
+        }
+        .btn-toolbar {
+          float: right;
+          .selected-button-style-primary;
+        }
+      }
+      .meta-label {
+        display: inline-block;
+        top: 1em;
+        left: 5em;
+        bottom: auto;
+        font-size: 0.9em;
+        color: #fff;
+        span {
+          color: #fff;
+        }
+      }
+    }
+    .panel.t3-form-form-stage-selected {
+      border-color: @brand-primary;
+      > .panel-heading {
+        background-color: @brand-primary;
+        border-color: @brand-primary;
+        color: #fff;
+        .selected-button-style-primary;
+      }
+    }
+  }
 
-#fake-form .formwizard-element.active,
-#fake-form .formwizard-element.hidden.active {
-  background-color: #EAF7FF;
-  border: 1px solid #C5DBE6;
-}
+  // Preview
+  &.t3-form-stage-viewmode-preview {
+    input[type="text"], input[type="date"], input[type="password"], textarea, select {
+      color: #000;
+      background-color: lighten(@panel-default-heading-bg, 3%);
+    }
+    ::placeholder {
+      color: @gray;
+      font-style: italic;
+    }
+    input[type="date"] {
+      display: block;
+      width: 100%;
+      height: 32px;
+      padding: 0.6em;
+      font-size: 12px;
+      line-height: 1.5;
+      background-image: none;
+      border: 1px solid @module-docheader-border;
+      border-radius: 2px;
+      box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+      transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+    }
+    select[multiple="multiple"] {
+      height: auto;
+      min-height: 32px;
+    }
+    textarea {
+      min-height: 100px;
+    }
+    legend.t3-form-form-element-selected {
+      border-color: @module-docheader-border;
+    }
+    .form-navigation {
+      .btn-group {
+        span, button {
+          display: inline-block;
+          margin-right: 1em;
+        }
+      }
+    }
+    .preview-table-first-col {
+      width: 30%;
+    }
+    .t3-form-element-preview {
+      position: relative;
+      display: inline-block;
+      width: 100%;
+    }
+    .t3-form-new-element-container {
+      display: none;
+    }
+    .t3-form-element-toplevel > form > .tooltip {
+        top: 100px !important;
+    }
+  }
 
-#fake-form .formwizard-element.hidden {
-  min-height: 1em;
-  background-color: transparent;
-  border: 1px dotted #C5DBE6;
+  #t3-form-stage {
+    margin-bottom: 0;
+    padding-top: 0.5em;
+    > ol, > ol > li > ol {
+      padding-left: 0;
+      padding-right: 0;
+    }
+    .t3-form-element-toplevel {
+      > .t3-form-form-element-selected {
+        height: auto;
+        padding-top: 0;
+      }
+      > .t3-form-form-element-selected .btn-toolbar-container {
+        display: none;
+      }
+    }
+  }
 }
 
-/* toolbar on each element */
-#fake-form .formwizard-element div.buttongroup {
+.meta-label {
+  z-index: 1;
   position: absolute;
-  right: 0;
-  top: -35px;
+  bottom: 1em;
+  left: 5.5em;
   display: none;
-  z-index: 1;
-  padding: 4px 3px 12px;
-  background-image: url("../Images/tooltip.png");
+  color: @brand-primary;
+  line-height: 1.6;
+  font-size: 0.8em;
+  .ui-sortable-handle:hover > & {
+    display: inline-block;
+  }
 }
 
-#fake-form .formwizard-element.hover > div.buttongroup,
-#fake-form .formwizard-element.active > div.buttongroup {
-  display: block;
+.ui-sortable-placeholder,
+.t3-form-element-composit.ui-sortable-placeholder {
+  background-color: #fff !important;
+  border: none !important;
+  outline: 1px dashed lighten(@brand-success, 30%) !important;
+  outline-offset: -2px !important;
+  visibility: visible !important;
 }
 
-#fake-form .formwizard-element div.buttongroup button {
-  width: 16px;
-  height: 16px;
-  background-color: transparent;
-  border: 0 solid transparent;
+//
+// Icons
+//
+.t3-form-icon {
+  margin-right: 1em;
 }
 
-#fake-form .formwizard-element div.buttongroup span {
-  margin: 0 3px;
+//
+// Validation Errors
+//
+.t3-form-validation-child-has-error {
+  color: @brand-danger;
 }
 
-#fake-form .formwizard-element div.buttongroup span.x-btn-over {
-  background-color: transparent;
-  background-image: none;
+.t3-form-validation-errors {
+  #t3-form-navigation-component &,
+  #t3-form-stage-container & {
+    position: relative;
+    color: @brand-danger;
+    &:before {
+      z-index: 1;
+      position: absolute;
+      display: inline-block;
+      width: 15px;
+      height: 15px;
+      font-family: FontAwesome;
+      vertical-align: middle;
+      border-radius: 50%;
+      font-size: 1em;
+      line-height: 1.4;
+      text-align: center;
+      background: none;
+    }
+  }
+  #t3-form-navigation-component & {
+    &:hover:before,
+    &.t3-form-form-element-selected:before {
+      left: 2.4em;
+    }
+    &:before {
+      margin-top: 0.2em;
+      color: #fff;
+      font-size: 10px;
+      font-weight: 800;
+      content: "\f12a";
+      background-color: @brand-danger;
+    }
+  }
+  &#t3-form-navigation-component-tree-root:before {
+    left: -2em !important;
+    margin-top: 0.1em;
+  }
+  #t3-form-stage-container &.ui-sortable-handle {
+    border-color: @brand-danger;
+    &:before {
+      left: 4.5em;
+      margin-top: 1.9em;
+      content:  "\f071";
+    }
+    .element-label {
+      padding-left: 1.5em;
+    }
+  }
+  #t3-form-inspector-panels .t3-form-collection-element & {
+    display: inline-block;
+    color: #fff;
+    font-size: 0.8em;
+    font-weight: 700;
+    background-color: @brand-danger;
+    margin-top: 0.5em;
+    padding: 0.1em 0.5em;
+    border-radius: 2px;
+  }
+  #t3-form-inspector-panels &.t3-form-collection-element {
+    border-color: @brand-danger;
+
+    h4 {
+      border-color: @brand-danger;
+      background-color: @brand-danger;
+      color: #fff;
+      path {
+        fill: #fff;
+      }
+    }
+    .t3-form-collection-element-remove-button {
+      background: #fff;
+      border-color: transparent;
+      path {
+        fill: @brand-danger;
+      }
+    }
+  }
 }
 
-#fake-form .formwizard-element button.t3-icon-edit-delete {
-  background-image: url('../../../../core/Resources/Public/Icons/T3Icons/actions/actions-delete.svg');
+//
+// Loading Editor Spinner
+//
+.form-editor-loading-spinner {
+  width: 150px;
+  margin: 5em auto 0;
+  text-align: center;
 }
 
-#fake-form .formwizard-element button.t3-icon-document-open {
-  background-image: url('../../../../core/Resources/Public/Icons/T3Icons/actions/actions-open.svg');
+//
+// jQuery nestedSortable
+//
+.ui-sortable-handle {
+  cursor: pointer;
 }
 
-@media only screen and (max-width:615px) {
-  .tab-content fieldset.form-section ol#formwizard-right{
-    left:0 !important;
+//
+// Module
+//
+.module[data-module-name="web_FormFormbuilder_FormEditor"] {
+  overflow: hidden;
+  .module-body, div[data-identifier="moduleWrapper"] {
+    height: 100%;
+  }
+  .module-body {
+    padding-bottom: 0.5em;
+  }
+  .module-docheader-bar-column-left {
+    button {
+      &, &:focus, &:active {
+        outline: 0;
+        outline-color: initial;
+        outline-style: initial;
+        outline-width: 0px;
+      }
+    }
+    .btn-group {
+      margin-left: 25px;
+    }
   }
 }
+
+.t3-form-element-new-page-button {
+  position: absolute;
+  left: 0.5em;
+}
\ No newline at end of file
index 784ca9a..7c587ac 100644 (file)
@@ -40,6 +40,7 @@
                "swiftmailer/swiftmailer": "~5.4.3",
                "symfony/console": "^2.7 || ^3.0",
                "symfony/finder": "^2.7 || ^3.0",
+               "symfony/yaml": "^2.7 || ^3.0",
                "doctrine/instantiator": "~1.0.4",
                "typo3/class-alias-loader": "^1.0",
                "typo3/cms-composer-installers": "^1.2.8",
index 51dff21..fe9516c 100644 (file)
@@ -4,8 +4,8 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "90479fd517e730794243c516ef4ba9ae",
-    "content-hash": "9ac01b16aca6a55472ecf320b6dacf31",
+    "hash": "9cc1058ed137d0775741d7c5701e77a1",
+    "content-hash": "2749660dc0a03d1b473808cf28c9cf10",
     "packages": [
         {
             "name": "cogpowered/finediff",
             "time": "2016-05-18 14:26:46"
         },
         {
+            "name": "symfony/yaml",
+            "version": "v3.1.6",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/yaml.git",
+                "reference": "7ff51b06c6c3d5cc6686df69004a42c69df09e27"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/7ff51b06c6c3d5cc6686df69004a42c69df09e27",
+                "reference": "7ff51b06c6c3d5cc6686df69004a42c69df09e27",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.5.9"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.1-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Yaml\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony Yaml Component",
+            "homepage": "https://symfony.com",
+            "time": "2016-10-24 18:41:13"
+        },
+        {
             "name": "typo3/class-alias-loader",
             "version": "1.0.0",
             "source": {
             "time": "2016-06-29 05:41:56"
         },
         {
-            "name": "symfony/yaml",
-            "version": "v3.1.6",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/symfony/yaml.git",
-                "reference": "7ff51b06c6c3d5cc6686df69004a42c69df09e27"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/symfony/yaml/zipball/7ff51b06c6c3d5cc6686df69004a42c69df09e27",
-                "reference": "7ff51b06c6c3d5cc6686df69004a42c69df09e27",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.5.9"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "3.1-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "Symfony\\Component\\Yaml\\": ""
-                },
-                "exclude-from-classmap": [
-                    "/Tests/"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Fabien Potencier",
-                    "email": "fabien@symfony.com"
-                },
-                {
-                    "name": "Symfony Community",
-                    "homepage": "https://symfony.com/contributors"
-                }
-            ],
-            "description": "Symfony Yaml Component",
-            "homepage": "https://symfony.com",
-            "time": "2016-10-24 18:41:13"
-        },
-        {
             "name": "webmozart/assert",
             "version": "1.1.0",
             "source": {
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-77910-EXTform-IntroduceNewFormFramework.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-77910-EXTform-IntroduceNewFormFramework.rst
new file mode 100644 (file)
index 0000000..db99783
--- /dev/null
@@ -0,0 +1,54 @@
+.. include:: ../../Includes.txt
+
+=========================================================
+Feature: #77910 - EXT:form - introduce new form framework
+=========================================================
+
+See :issue:`77910`
+
+Description
+===========
+
+A flexible framework for building forms is integrated. It replaces the legacy 'form wizard' based on ExtJS and the
+depending frontend rendering system.
+
+The new backend 'form editor' relies on vanilla JS and jQuery. Different JS patterns have been applied to ensure
+a modern architecture, high flexibility and extensibility.
+
+A new backend module lists all existing forms and allows the creation of new ones. The 'mailform' content element
+is reworked. It lists available forms and enables the backend editor to override certain settings, e.g. 'finisher'
+settings (formerly known as 'postProcessors').
+
+Till now it was not possible to customize and extend the 'form editor'. To allow the registration of new
+finishers, validators and pre-defined form elements a lot of architectural changes were needed. After a long
+conceptional phase the team decided to remove the former code base, backport the 'form' package of the Flow
+project and improve the given ideas and concepts. The result is a new form extension. A lot of code received
+major improvements and tons of additional features have been integrated.
+
+The list of features is long and impressive. The documentation will explain the ideas, concept and architecture
+as well as the functionality in detail. The following list names some of them:
+
+* YAML as configuration and description language including inheritances and overrides.
+* File based configuration.
+* All JavaScript components of the form wizard (and the wizard itself) can be replaced or extended.
+* Own PHP renderer for form and/ or form elements possible.
+* Create entire forms via API.
+* Create conditions for form elements and validators programmatically.
+* Create 'prototypes' and use them as boilerplate.
+* Create new form elements and use them in the wizard.
+* Uploads are handled as FAL objects.
+* Ships bunch of built-in finishers, like email, redirect, save to database.
+* Create own finishers. Override thos in the content element.
+* Create and apply own validators.
+* Multi language support.
+* Multi step support.
+* Multiple forms per page.
+* Built-in spam protection (honeypot).
+
+
+Impact
+======
+
+Happy little wizard.
+
+.. index:: Frontend, PHP-API, JavaScript, ext:form
\ No newline at end of file
diff --git a/typo3/sysext/form/Classes/ContentObject/FormContentObject.php b/typo3/sysext/form/Classes/ContentObject/FormContentObject.php
deleted file mode 100644 (file)
index e2176de..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-<?php
-namespace TYPO3\CMS\Form\ContentObject;
-
-/*
- * 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!
- */
-
-use TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser;
-use TYPO3\CMS\Core\Utility\ArrayUtility;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Form\Domain\Model\Configuration;
-use TYPO3\CMS\Frontend\ContentObject\AbstractContentObject;
-use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
-
-/**
- * FORM cObject, a wrapper to allow to use 10 = FORM in TypoScript
- * which actually executes the Extbase plugin (marked as non-cached)
- */
-class FormContentObject extends AbstractContentObject
-{
-    /**
-     * Renders the application defined cObject FORM
-     *
-     * The Extbase plugin "Form" is initialized. At this time, the
-     * controller "Frontend" action "show" does the rest.
-     *
-     * @param array $conf TS configuration for this cObject
-     * @return string HTML output
-     * @throws \InvalidArgumentException
-     */
-    public function render($conf = [])
-    {
-        $mergedTypoScript = null;
-        // If the FORM configuration is retrieved from the database
-        // all TypoScript interpretation will be disabled for security.
-        if ($this->cObj->data['CType'] === 'mailform') {
-            // If the FORM configuration is retrieved from the database
-            // and a predefined form is selected then the TypoScript
-            // interpretation is allowed.
-            $renderPredefinedForm = false;
-            $predefinedFormIdentifier = null;
-            if (!empty($this->cObj->data['tx_form_predefinedform'])) {
-                $predefinedFormIdentifier = $this->cObj->data['tx_form_predefinedform'];
-                if (isset($this->getTypoScriptFrontendController()->tmpl->setup['plugin.']['tx_form.']['predefinedForms.'][$predefinedFormIdentifier . '.'])) {
-                    $renderPredefinedForm = true;
-                } else {
-                    throw new \InvalidArgumentException('No FORM configuration for identifier "' . $predefinedFormIdentifier . '" available.', 1466769483);
-                }
-            }
-
-            if ($renderPredefinedForm && $predefinedFormIdentifier) {
-                $mergedTypoScript = $this->getTypoScriptFrontendController()->tmpl->setup['plugin.']['tx_form.']['predefinedForms.'][$predefinedFormIdentifier . '.'];
-                ArrayUtility::mergeRecursiveWithOverrule($mergedTypoScript, $conf);
-            } else {
-                $bodytext = $this->cObj->data['bodytext'];
-                /** @var $typoScriptParser TypoScriptParser */
-                $typoScriptParser = GeneralUtility::makeInstance(TypoScriptParser::class);
-                $typoScriptParser->parse($bodytext);
-                $mergedTypoScript = (array)$typoScriptParser->setup;
-                ArrayUtility::mergeRecursiveWithOverrule($mergedTypoScript, $conf);
-                // Disables TypoScript interpretation since TypoScript is handled that could contain insecure settings:
-                $mergedTypoScript[Configuration::DISABLE_CONTENT_ELEMENT_RENDERING] = true;
-            }
-        }
-
-        // make sure the extbase plugin is marked as Uncached
-        $content = $this->prepareNonCacheableUserFunction(is_array($mergedTypoScript) ? $mergedTypoScript : $conf);
-
-        // Only apply stdWrap to TypoScript that was NOT created by the wizard:
-        if (isset($conf['stdWrap.'])) {
-            $content = $this->cObj->stdWrap($content, $conf['stdWrap.']);
-        }
-        return $content;
-    }
-
-    /**
-     * Set up the extbase plugin to be a non-cacheable user function
-     *
-     * @param array $typoScript
-     * @return string the content as placeholder for USER_INT code
-     */
-    protected function prepareNonCacheableUserFunction($typoScript)
-    {
-        $configuration = [
-            'userFunc' => 'TYPO3\\CMS\\Extbase\\Core\\Bootstrap->run',
-            'pluginName' => 'Form',
-            'extensionName' => 'Form',
-            'vendorName' => 'TYPO3\\CMS',
-            'controller' => 'Frontend',
-            'action' => 'show',
-            'settings' => ['typoscript' => $typoScript],
-            'persistence' => [],
-            'view' => [],
-        ];
-
-        $this->cObj->setUserObjectType(ContentObjectRenderer::OBJECTTYPE_USER_INT);
-        $substKey = 'INT_SCRIPT.' . $this->getTypoScriptFrontendController()->uniqueHash();
-        $content = '<!--' . $substKey . '-->';
-        $this->getTypoScriptFrontendController()->config['INTincScript'][$substKey] = [
-            'conf' => $configuration,
-            'cObj' => serialize($this->cObj),
-            'type' => 'FUNC'
-        ];
-        $this->cObj->setUserObjectType(false);
-        return $content;
-    }
-
-    /**
-     * @return \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
-     */
-    protected function getTypoScriptFrontendController()
-    {
-        return $GLOBALS['TSFE'];
-    }
-}
diff --git a/typo3/sysext/form/Classes/Controller/AbstractBackendController.php b/typo3/sysext/form/Classes/Controller/AbstractBackendController.php
new file mode 100644 (file)
index 0000000..0f028e4
--- /dev/null
@@ -0,0 +1,91 @@
+<?php
+declare(strict_types=1);
+namespace TYPO3\CMS\Form\Controller;
+
+/*
+ * 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!
+ */
+
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\PathUtility;
+use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
+use TYPO3\CMS\Form\Mvc\Configuration\ConfigurationManagerInterface;
+
+/**
+ * The abstract form backend controller
+ *
+ * Scope: backend
+ */
+abstract class AbstractBackendController extends ActionController
+{
+
+    /**
+     * @var array
+     */
+    protected $formSettings;
+
+    /**
+     * @var \TYPO3\CMS\Form\Mvc\Persistence\FormPersistenceManagerInterface
+     */
+    protected $formPersistenceManager;
+
+    /**
+     * @param \TYPO3\CMS\Form\Mvc\Persistence\FormPersistenceManagerInterface $formPersistenceManager
+     * @return void
+     * @internal
+     */
+    public function injectFormPersistenceManager(\TYPO3\CMS\Form\Mvc\Persistence\FormPersistenceManagerInterface $formPersistenceManager)
+    {
+        $this->formPersistenceManager = $formPersistenceManager;
+    }
+
+    /**
+     * @internal
+     */
+    public function initializeObject()
+    {
+        $this->formSettings = $this->objectManager->get(ConfigurationManagerInterface::class)
+            ->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_YAML_SETTINGS, 'form');
+    }
+
+    /**
+     * Convert arrays with EXT: resource paths to web paths
+     *
+     * Input:
+     * [
+     *   100 => 'EXT:form/Resources/Public/Css/form.css'
+     * ]
+     *
+     * Output:
+     *
+     * [
+     *   0 => 'typo3/sysext/form/Resources/Public/Css/form.css'
+     * ]
+     *
+     * @param array $resourcePaths
+     * @return array
+     */
+    protected function resolveResourcePaths(array $resourcePaths): array
+    {
+        $return = [];
+        foreach ($resourcePaths as $resourcePath) {
+            $fullResourcePath = GeneralUtility::getFileAbsFileName($resourcePath);
+            $resourcePath = PathUtility::getAbsoluteWebPath($fullResourcePath);
+            if (empty($resourcePath)) {
+                continue;
+            }
+            $return[] = $resourcePath;
+        }
+
+        return $return;
+    }
+}
diff --git a/typo3/sysext/form/Classes/Controller/FormEditorController.php b/typo3/sysext/form/Classes/Controller/FormEditorController.php
new file mode 100644 (file)
index 0000000..756015c
--- /dev/null
@@ -0,0 +1,445 @@
+<?php
+declare(strict_types=1);
+namespace TYPO3\CMS\Form\Controller;
+
+/*
+ * 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!
+ */
+
+use TYPO3\CMS\Backend\Template\Components\ButtonBar;
+use TYPO3\CMS\Backend\Utility\BackendUtility;
+use TYPO3\CMS\Backend\View\BackendTemplateView;
+use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
+use TYPO3\CMS\Core\Imaging\Icon;
+use TYPO3\CMS\Core\Utility\ArrayUtility as CoreArrayUtility;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Fluid\View\StandaloneView;
+use TYPO3\CMS\Form\Domain\Configuration\ConfigurationService;
+use TYPO3\CMS\Form\Domain\Exception\RenderingException;
+use TYPO3\CMS\Form\Domain\Factory\ArrayFormFactory;
+use TYPO3\CMS\Form\Mvc\Persistence\Exception\PersistenceManagerException;
+use TYPO3\CMS\Form\Service\TranslationService;
+use TYPO3\CMS\Form\Utility\ArrayUtility;
+use TYPO3\CMS\Lang\LanguageService;
+
+/**
+ * The form editor controller
+ *
+ * Scope: backend
+ */
+class FormEditorController extends AbstractBackendController
+{
+
+    /**
+     * Default View Container
+     *
+     * @var BackendTemplateView
+     */
+    protected $defaultViewObjectName = BackendTemplateView::class;
+
+    /**
+     * @var array
+     */
+    protected $prototypeConfiguration;
+
+    /**
+     * Displays the form editor
+     *
+     * @param string $formPersistenceIdentifier
+     * @param string $prototypeName
+     * @return void
+     * @throws PersistenceManagerException
+     * @internal
+     */
+    public function indexAction(string $formPersistenceIdentifier, string $prototypeName = null)
+    {
+        $this->registerDocheaderButtons();
+        $this->view->getModuleTemplate()->setModuleName($this->request->getPluginName() . '_' . $this->request->getControllerName());
+        $this->view->getModuleTemplate()->setFlashMessageQueue($this->controllerContext->getFlashMessageQueue());
+
+        if (
+            strpos($formPersistenceIdentifier, 'EXT:') === 0
+            && !$this->formSettings['persistenceManager']['allowSaveToExtensionPaths']
+        ) {
+            throw new PersistenceManagerException('Edit a extension formDefinition is not allowed.', 1478265661);
+        }
+
+        $formDefinition = $this->formPersistenceManager->load($formPersistenceIdentifier);
+        $formDefinition = ArrayUtility::stripTagsFromValuesRecursive($formDefinition);
+        if (empty($prototypeName)) {
+            $prototypeName = isset($formDefinition['prototypeName']) ? $formDefinition['prototypeName'] : 'standard';
+        }
+        $formDefinition['prototypeName'] = $prototypeName;
+
+        $configurationService = $this->objectManager->get(ConfigurationService::class);
+        $this->prototypeConfiguration = $configurationService->getPrototypeConfiguration($prototypeName);
+
+        $formEditorDefinitions = $this->getFormEditorDefinitions();
+
+        $formEditorAppInitialData = [
+            'formEditorDefinitions' => $formEditorDefinitions,
+            'formDefinition' => $formDefinition,
+            'formPersistenceIdentifier' => $formPersistenceIdentifier,
+            'prototypeName' => $prototypeName,
+            'endpoints' => [
+                'formPageRenderer' => $this->controllerContext->getUriBuilder()->uriFor('renderFormPage'),
+                'saveForm' => $this->controllerContext->getUriBuilder()->uriFor('saveForm')
+            ],
+            'additionalViewModelModules' => $this->prototypeConfiguration['formEditor']['dynamicRequireJsModules']['additionalViewModelModules'],
+            'maximumUndoSteps' => $this->prototypeConfiguration['formEditor']['maximumUndoSteps'],
+        ];
+
+        $this->view->assign('formEditorAppInitialData', json_encode($formEditorAppInitialData));
+        $this->view->assign('stylesheets', $this->resolveResourcePaths($this->prototypeConfiguration['formEditor']['stylesheets']));
+        $this->view->assign('formEditorTemplates', $this->renderFormEditorTemplates(
+            $this->prototypeConfiguration['formEditor']['formEditorTemplates'],
+            $formEditorDefinitions
+        ));
+        $this->view->assign('dynamicRequireJsModules', $this->prototypeConfiguration['formEditor']['dynamicRequireJsModules']);
+
+        $popupWindowWidth  = 700;
+        $popupWindowHeight = 750;
+        $popupWindowSize = ($this->getBackendUser()->getTSConfigVal('options.popupWindowSize'))
+            ? trim($this->getBackendUser()->getTSConfigVal('options.popupWindowSize'))
+            : null;
+        if (!empty($popupWindowSize)) {
+            list($popupWindowWidth, $popupWindowHeight) = GeneralUtility::intExplode('x', $popupWindowSize);
+        }
+
+        $addInlineSettings = [
+            'FormEditor' => [
+                'typo3WinBrowserUrl' => BackendUtility::getModuleUrl('wizard_element_browser'),
+            ],
+            'Popup' => [
+                'PopupWindow' => [
+                    'width' => $popupWindowWidth,
+                    'height' => $popupWindowHeight
+                ],
+            ]
+        ];
+
+        CoreArrayUtility::mergeRecursiveWithOverrule(
+            $addInlineSettings,
+            $this->prototypeConfiguration['formEditor']['addInlineSettings']
+        );
+        $this->view->assign('addInlineSettings', $addInlineSettings);
+    }
+
+    /**
+     * Save a formDefinition which was build by the form editor.
+     *
+     * @param string $formPersistenceIdentifier
+     * @param array $formDefinition
+     * @return string
+     * @internal
+     */
+    public function saveFormAction(string $formPersistenceIdentifier, array $formDefinition): string
+    {
+        $formDefinition = ArrayUtility::stripTagsFromValuesRecursive($formDefinition);
+        $formDefinition = $this->convertJsonArrayToAssociativeArray($formDefinition);
+        $this->formPersistenceManager->save($formPersistenceIdentifier, $formDefinition);
+        return '';
+    }
+
+    /**
+     * Render a page from the formDefinition which was build by the form editor.
+     * Use the frontend rendering and set the form framework to preview mode.
+     *
+     * @param array $formDefinition
+     * @param int $pageIndex
+     * @param string $prototypeName
+     * @return string
+     * @internal
+     */
+    public function renderFormPageAction(array $formDefinition, int $pageIndex, string $prototypeName = null): string
+    {
+        $formDefinition = ArrayUtility::stripTagsFromValuesRecursive($formDefinition);
+        $formDefinition = $this->convertJsonArrayToAssociativeArray($formDefinition);
+        if (empty($prototypeName)) {
+            $prototypeName = isset($formDefinition['prototypeName']) ? $formDefinition['prototypeName'] : 'standard';
+        }
+
+        $formFactory = $this->objectManager->get(ArrayFormFactory::class);
+        $formDefinition = $formFactory->build($formDefinition, $prototypeName);
+        $formDefinition->setRenderingOption('previewMode', true);
+        $form = $formDefinition->bind($this->request, $this->response);
+        $form->overrideCurrentPage($pageIndex);
+        return $form->render();
+    }
+
+    /**
+     * Prepare the formElements.*.formEditor section from the yaml settings.
+     * Sort all formElements into groups and add additional data.
+     *
+     * @param array $formElementsDefinition
+     * @return array
+     */
+    protected function getInsertRenderablesPanelConfiguration(array $formElementsDefinition): array
+    {
+        $formElementGroups = isset($this->prototypeConfiguration['formEditor']['formElementGroups']) ? $this->prototypeConfiguration['formEditor']['formElementGroups'] : [];
+        $formElementsByGroup = [];
+
+        foreach ($formElementsDefinition as $formElementName => $formElementConfiguration) {
+            if (!isset($formElementConfiguration['group'])) {
+                continue;
+            }
+            if (!isset($formElementsByGroup[$formElementConfiguration['group']])) {
+                $formElementsByGroup[$formElementConfiguration['group']] = [];
+            }
+
+            $formElementsByGroup[$formElementConfiguration['group']][] = [
+                'key' => $formElementName,
+                'cssKey' => preg_replace('/[^a-z0-9]/', '-', strtolower($formElementName)),
+                'label' => TranslationService::getInstance()->translate(
+                    $formElementConfiguration['label'],
+                    null,
+                    $this->prototypeConfiguration['formEditor']['translationFile'],
+                    null,
+                    $formElementConfiguration['label']
+                ),
+                'sorting' => $formElementConfiguration['groupSorting'],
+                'iconIdentifier' => $formElementConfiguration['iconIdentifier'],
+            ];
+        }
+
+        $formGroups = [];
+        foreach ($formElementGroups as $groupName => $groupConfiguration) {
+            if (!isset($formElementsByGroup[$groupName])) {
+                continue;
+            }
+
+            usort($formElementsByGroup[$groupName], function ($a, $b) {
+                return $a['sorting'] - $b['sorting'];
+            });
+            unset($formElementsByGroup[$groupName]['sorting']);
+
+            $formGroups[] = [
+                'key' => $groupName,
+                'elements' => $formElementsByGroup[$groupName],
+                'label' => TranslationService::getInstance()->translate(
+                    $groupConfiguration['label'],
+                    null,
+                    $this->prototypeConfiguration['formEditor']['translationFile'],
+                    null,
+                    $groupConfiguration['label']
+                ),
+            ];
+        }
+
+        return $formGroups;
+    }
+
+    /**
+     * Reduce the Yaml settings by the 'formEditor' keyword.
+     *
+     * @return array
+     */
+    protected function getFormEditorDefinitions(): array
+    {
+        $formEditorDefinitions = [];
+        foreach ([$this->prototypeConfiguration, $this->prototypeConfiguration['formEditor']] as $configuration) {
+            foreach ($configuration as $firstLevelItemKey => $firstLevelItemValue) {
+                if (substr($firstLevelItemKey, -10) !== 'Definition') {
+                    continue;
+                }
+                $reducedKey = substr($firstLevelItemKey, 0, -10);
+                foreach ($configuration[$firstLevelItemKey] as $formEditorDefinitionKey => $formEditorDefinitionValue) {
+                    if (isset($formEditorDefinitionValue['formEditor'])) {
+                        $formEditorDefinitionValue = array_intersect_key($formEditorDefinitionValue, array_flip(['formEditor']));
+                        $formEditorDefinitions[$reducedKey][$formEditorDefinitionKey] = $formEditorDefinitionValue['formEditor'];
+                    } else {
+                        $formEditorDefinitions[$reducedKey][$formEditorDefinitionKey] = $formEditorDefinitionValue;
+                    }
+                }
+            }
+        }
+        $formEditorDefinitions = ArrayUtility::reIndexNumericArrayKeysRecursive($formEditorDefinitions);
+        $formEditorDefinitions = TranslationService::getInstance()->translateValuesRecursive(
+            $formEditorDefinitions,
+            $this->prototypeConfiguration['formEditor']['translationFile']
+        );
+        return $formEditorDefinitions;
+    }
+
+    /**
+     * Registers the Icons into the docheader
+     *
+     * @throws \InvalidArgumentException
+     */
+    protected function registerDocheaderButtons()
+    {
+        /** @var ButtonBar $buttonBar */
+        $buttonBar = $this->view->getModuleTemplate()->getDocHeaderComponent()->getButtonBar();
+        $getVars = $this->request->getArguments();
+
+        if (isset($getVars['action']) && $getVars['action'] === 'index') {
+            $newPageButton = $buttonBar->makeInputButton()
+                ->setDataAttributes(['action' => 'formeditor-new-page', 'identifier' => 'headerNewPage'])
+                ->setTitle($this->getLanguageService()->sL('LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.new_page_button'))
+                ->setName('formeditor-new-page')
+                ->setValue('new-page')
+                ->setClasses('t3-form-element-new-page-button hidden')
+                ->setIcon($this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-page-new', Icon::SIZE_SMALL));
+
+            $closeButton = $buttonBar->makeLinkButton()
+                ->setDataAttributes(['identifier' => 'closeButton'])
+                ->setHref(BackendUtility::getModuleUrl('web_FormFormbuilder'))
+                ->setClasses('t3-form-element-close-form-button hidden')
+                ->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.closeDoc'))
+                ->setIcon($this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-document-close', Icon::SIZE_SMALL));
+
+            $saveButton = $buttonBar->makeInputButton()
+                ->setDataAttributes(['identifier' => 'saveButton'])
+                ->setTitle($this->getLanguageService()->sL('LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.save_button'))
+                ->setName('formeditor-save-form')
+                ->setValue('save')
+                ->setClasses('t3-form-element-save-form-button hidden')
+                ->setIcon($this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-document-save', Icon::SIZE_SMALL))
+                ->setShowLabelText(true);
+
+            $undoButton = $buttonBar->makeInputButton()
+                ->setDataAttributes(['identifier' => 'undoButton'])
+                ->setTitle($this->getLanguageService()->sL('LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.undo_button'))
+                ->setName('formeditor-undo-form')
+                ->setValue('undo')
+                ->setClasses('t3-form-element-undo-form-button hidden disabled')
+                ->setIcon($this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-view-go-back', Icon::SIZE_SMALL));
+
+            $redoButton = $buttonBar->makeInputButton()
+                ->setDataAttributes(['identifier' => 'redoButton'])
+                ->setTitle($this->getLanguageService()->sL('LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.redo_button'))
+                ->setName('formeditor-redo-form')
+                ->setValue('redo')
+                ->setClasses('t3-form-element-redo-form-button hidden disabled')
+                ->setIcon($this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-view-go-forward', Icon::SIZE_SMALL));
+
+            $buttonBar->addButton($newPageButton, ButtonBar::BUTTON_POSITION_LEFT, 1);
+            $buttonBar->addButton($closeButton, ButtonBar::BUTTON_POSITION_LEFT, 2);
+            $buttonBar->addButton($saveButton, ButtonBar::BUTTON_POSITION_LEFT, 3);
+            $buttonBar->addButton($undoButton, ButtonBar::BUTTON_POSITION_LEFT, 4);
+            $buttonBar->addButton($redoButton, ButtonBar::BUTTON_POSITION_LEFT, 4);
+        }
+    }
+
+    /**
+     * Some data which is build by the form editor needs a transformation before
+     * it can be used by the framework.
+     * Multivalue elements like select elements produce data like:
+     *
+     * [
+     *   _label => 'label'
+     *   _value => 'value'
+     * ]
+     *
+     * This method transform this into:
+     *
+     * [
+     *   'value' => 'label'
+     * ]
+     *
+     * @param array $input
+     * @return array
+     */
+    protected function convertJsonArrayToAssociativeArray(array $input): array
+    {
+        $output = [];
+        foreach ($input as $key => $value) {
+            if (is_integer($key) && is_array($value) && isset($value['_label']) && isset($value['_value'])) {
+                $key = $value['_value'];
+                $value = $value['_label'];
+            }
+            if (is_array($value)) {
+                $output[$key] = $this->convertJsonArrayToAssociativeArray($value);
+            } else {
+                $output[$key] = $value;
+            }
+        }
+        return $output;
+    }
+
+    /**
+     * Render the "text/x-formeditor-template" templates.
+     *
+     * @param array $formEditorTemplates
+     * @param array $formEditorDefinitions
+     * @return array
+     */
+    protected function renderFormEditorTemplates(array $formEditorTemplates, array $formEditorDefinitions): array
+    {
+        if (
+            !isset($formEditorTemplates['templateRootPaths'])
+            || !is_array($formEditorTemplates['templateRootPaths'])
+        ) {
+            throw new RenderingException(
+                'The option templateRootPaths must be set.',
+                1480294720
+            );
+        }
+        if (
+            !isset($formEditorTemplates['layoutRootPaths'])
+            || !is_array($formEditorTemplates['layoutRootPaths'])
+        ) {
+            throw new RenderingException(
+                'The option layoutRootPaths must be set.',
+                1480294721
+            );
+        }
+        if (
+            !isset($formEditorTemplates['partialRootPaths'])
+            || !is_array($formEditorTemplates['partialRootPaths'])
+        ) {
+            throw new RenderingException(
+                'The option partialRootPaths must be set.',
+                1480294722
+            );
+        }
+
+        $standaloneView = $this->objectManager->get(StandaloneView::class);
+        $standaloneView->setTemplateRootPaths($formEditorTemplates['templateRootPaths']);
+        $standaloneView->setLayoutRootPaths($formEditorTemplates['layoutRootPaths']);
+        $standaloneView->setPartialRootPaths($formEditorTemplates['partialRootPaths']);
+        $standaloneView->assignMultiple([
+            'insertRenderablesPanelConfiguration' => $this->getInsertRenderablesPanelConfiguration($formEditorDefinitions['formElements'])
+        ]);
+
+        unset($formEditorTemplates['templateRootPaths']);
+        unset($formEditorTemplates['layoutRootPaths']);
+        unset($formEditorTemplates['partialRootPaths']);
+
+        $renderedFormEditorTemplates = [];
+        foreach ($formEditorTemplates as $formEditorTemplateName => $formEditorTemplateTemplate) {
+            $renderedFormEditorTemplates[$formEditorTemplateName] = $standaloneView->render($formEditorTemplateTemplate);
+        }
+
+        return $renderedFormEditorTemplates;
+    }
+
+    /**
+     * Returns the current BE user.
+     *
+     * @return BackendUserAuthentication
+     */
+    protected function getBackendUser(): BackendUserAuthentication
+    {
+        return $GLOBALS['BE_USER'];
+    }
+
+    /**
+     * Returns the language service
+     *
+     * @return LanguageService
+     */
+    protected function getLanguageService(): LanguageService
+    {
+        return $GLOBALS['LANG'];
+    }
+}
diff --git a/typo3/sysext/form/Classes/Controller/FormFrontendController.php b/typo3/sysext/form/Classes/Controller/FormFrontendController.php
new file mode 100644 (file)
index 0000000..4158560
--- /dev/null
@@ -0,0 +1,138 @@
+<?php
+declare(strict_types=1);
+namespace TYPO3\CMS\Form\Controller;
+
+/*
+ * 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!
+ */
+
+use TYPO3\CMS\Core\Utility\ArrayUtility;
+use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
+use TYPO3\CMS\Form\Domain\Configuration\ConfigurationService;
+use TYPO3\CMS\Form\Mvc\Configuration\TypoScriptService;
+
+/**
+ * The frontend controller
+ *
+ * Scope: frontend
+ */
+class FormFrontendController extends ActionController
+{
+
+    /**
+     * @var \TYPO3\CMS\Form\Mvc\Persistence\FormPersistenceManagerInterface
+     */
+    protected $formPersistenceManager;
+
+    /**
+     * @param \TYPO3\CMS\Form\Mvc\Persistence\FormPersistenceManagerInterface $formPersistenceManager
+     * @return void
+     * @internal
+     */
+    public function injectFormPersistenceManager(\TYPO3\CMS\Form\Mvc\Persistence\FormPersistenceManagerInterface $formPersistenceManager)
+    {
+        $this->formPersistenceManager = $formPersistenceManager;
+    }
+
+    /**
+     * Take the form which should be rendered from the plugin settings
+     * and overlay the formDefinition with additional data from
+     * flexform and typoscript settings.
+     * This method is used directly to display the first page from the
+     * formDefinition because its cached.
+     *
+     * @return void
+     * @internal
+     */
+    public function renderAction()
+    {
+        $formDefinition = [];
+        if (!empty($this->settings['persistenceIdentifier'])) {
+            $formDefinition = $this->formPersistenceManager->load($this->settings['persistenceIdentifier']);
+            $formDefinition['persistenceIdentifier'] = $this->settings['persistenceIdentifier'];
+            $formDefinition = $this->overrideByFlexFormSettings($formDefinition);
+            $formDefinition = $this->overrideByTypoScriptSettings($formDefinition);
+        }
+        $this->view->assign('formConfiguration', $formDefinition);
+    }
+
+    /**
+     * This method is used to display all pages / finishers except the
+     * first page because its non cached.
+     *
+     * @return void
+     * @internal
+     */
+    public function performAction()
+    {
+        $this->forward('render');
+    }
+
+    /**
+     * Override the formDefinition with additional data from the Flexform
+     * settings. For now, only finisher settings are overridable.
+     *
+     * @param array $formDefinition
+     * @return array
+     */
+    protected function overrideByFlexFormSettings(array $formDefinition): array
+    {
+        if (isset($formDefinition['finishers'])) {
+            foreach ($formDefinition['finishers'] as &$finisherValue) {
+                $finisherIdentifier = $finisherValue['identifier'];
+                if ($this->settings['overrideFinishers'] && isset($this->settings['finishers'][$finisherIdentifier])) {
+                    $prototypeName = isset($formDefinition['prototypeName']) ? $formDefinition['prototypeName'] : 'standard';
+                    $configurationService = $this->objectManager->get(ConfigurationService::class);
+                    $prototypeConfiguration = $configurationService->getPrototypeConfiguration($prototypeName);
+
+                    foreach ($finisherValue['options'] as $optionKey => $optionValue) {
+                        // If a previous overriden finisher property is excluded at some time
+                        // it is still present in the flexform database row.
+                        // To avoid a override from the time the property is excluded, this check is needed
+                        if (!isset($prototypeConfiguration['finishersDefinition'][$finisherIdentifier]['FormEngine']['elements'][$optionKey])) {
+                            continue;
+                        }
+                        if (isset($this->settings['finishers'][$finisherIdentifier][$optionKey])) {
+                            $finisherValue['options'][$optionKey] = $this->settings['finishers'][$finisherIdentifier][$optionKey];
+                        }
+                    }
+                }
+            }
+        }
+        return $formDefinition;
+    }
+
+    /**
+     * Every formDefinition setting are overridable by typoscript.
+     * If the typoscript configuration path
+     * plugin.tx_form.settings.formDefinitionOverrides.<identifier>
+     * exists, this settings are merged into the formDefinition.
+     *
+     * @param array $formDefinition
+     * @return array
+     */
+    protected function overrideByTypoScriptSettings(array $formDefinition): array
+    {
+        if (
+            isset($this->settings['formDefinitionOverrides'][$formDefinition['identifier']])
+            && !empty($this->settings['formDefinitionOverrides'][$formDefinition['identifier']])
+        ) {
+            ArrayUtility::mergeRecursiveWithOverrule(
+                $formDefinition,
+                $this->settings['formDefinitionOverrides'][$formDefinition['identifier']]
+            );
+            $formDefinition = $this->objectManager->get(TypoScriptService::class)
+                ->resolvePossibleTypoScriptConfiguration($formDefinition);
+        }
+        return $formDefinition;
+    }
+}
diff --git a/typo3/sysext/form/Classes/Controller/FormManagerController.php b/typo3/sysext/form/Classes/Controller/FormManagerController.php
new file mode 100644 (file)
index 0000000..a45ada8
--- /dev/null
@@ -0,0 +1,463 @@
+<?php
+declare(strict_types=1);
+namespace TYPO3\CMS\Form\Controller;
+
+/*
+ * 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!
+ */
+
+use Symfony\Component\Yaml\Yaml;
+use TYPO3\CMS\Backend\Template\Components\ButtonBar;
+use TYPO3\CMS\Backend\Utility\BackendUtility;
+use TYPO3\CMS\Backend\View\BackendTemplateView;
+use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
+use TYPO3\CMS\Core\Database\ConnectionPool;
+use TYPO3\CMS\Core\Imaging\Icon;
+use TYPO3\CMS\Core\Imaging\IconFactory;
+use TYPO3\CMS\Core\Messaging\AbstractMessage;
+use TYPO3\CMS\Core\Page\PageRenderer;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Mvc\View\JsonView;
+use TYPO3\CMS\Form\Exception as FormException;
+use TYPO3\CMS\Form\Service\TranslationService;
+use TYPO3\CMS\Form\Utility\ArrayUtility;
+use TYPO3\CMS\Lang\LanguageService;
+
+/**
+ * The form manager controller
+ *
+ * Scope: backend
+ */
+class FormManagerController extends AbstractBackendController
+{
+
+    /**
+     * Default View Container
+     *
+     * @var BackendTemplateView
+     */
+    protected $defaultViewObjectName = BackendTemplateView::class;
+
+    /**
+     * Initialize the references action.
+     * This action use the Fluid JsonView::class as view.
+     *
+     * @return void
+     * @internal
+     */
+    public function initializeReferencesAction()
+    {
+        $this->defaultViewObjectName = JsonView::class;
+    }
+
+    /**
+     * Displays the Form Manager
+     *
+     * @return void
+     * @internal
+     */
+    public function indexAction()
+    {
+        $this->registerDocheaderButtons();
+        $this->view->getModuleTemplate()->setModuleName($this->request->getPluginName() . '_' . $this->request->getControllerName());
+        $this->view->getModuleTemplate()->setFlashMessageQueue($this->controllerContext->getFlashMessageQueue());
+
+        $this->view->assign('forms', $this->getAvailableFormDefinitions());
+        $this->view->assign('stylesheets', $this->resolveResourcePaths($this->formSettings['formManager']['stylesheets']));
+        $this->view->assign('dynamicRequireJsModules', $this->formSettings['formManager']['dynamicRequireJsModules']);
+        $this->view->assign('formManagerAppInitialData', $this->getFormManagerAppInitialData());
+        if (!empty($this->formSettings['formManager']['javaScriptTranslationFile'])) {
+            $this->getPageRenderer()->addInlineLanguageLabelFile($this->formSettings['formManager']['javaScriptTranslationFile']);
+        }
+    }
+
+    /**
+     * Creates a new Form and redirects to the Form Editor
+     *
+     * @param string $formName
+     * @param string $templatePath
+     * @param string $prototypeName
+     * @param string $savePath
+     * @return string
+     * @throws FormException
+     * @internal
+     */
+    public function createAction(string $formName, string $templatePath, string $prototypeName, string $savePath): string
+    {
+        if (!$this->isValidTemplatePath($prototypeName, $templatePath)) {
+            throw new FormException(sprintf('The template path "%s" is not allowed', $templatePath), 1329233410);
+        }
+        if (empty($formName)) {
+            throw new FormException(sprintf('No form name', $templatePath), 1472312204);
+        }
+
+        $templatePath = GeneralUtility::getFileAbsFileName($templatePath);
+        $form = Yaml::parse(file_get_contents($templatePath));
+        $form['label'] = $formName;
+        $form['identifier'] = $this->formPersistenceManager->getUniqueIdentifier($this->convertFormNameToIdentifier($formName));
+        $form['prototypeName'] = $prototypeName;
+
+        $formPersistenceIdentifier = $this->formPersistenceManager->getUniquePersistenceIdentifier($form['identifier'], $savePath);
+        $this->formPersistenceManager->save($formPersistenceIdentifier, $form);
+
+        return $this->controllerContext->getUriBuilder()->uriFor('index', ['formPersistenceIdentifier' => $formPersistenceIdentifier], 'FormEditor');
+    }
+
+    /**
+     * Duplicates a given formDefinition and redirects to the Form Editor
+     *
+     * @param string $formName
+     * @param string $formPersistenceIdentifier persistence identifier of the form to duplicate
+     * @param string $savePath
+     * @return string
+     * @internal
+     */
+    public function duplicateAction(string $formName, string $formPersistenceIdentifier, string $savePath): string
+    {
+        $formToDuplicate = $this->formPersistenceManager->load($formPersistenceIdentifier);
+        $formToDuplicate['label'] = $formName;
+        $formToDuplicate['identifier'] = $this->formPersistenceManager->getUniqueIdentifier($this->convertFormNameToIdentifier($formName));
+
+        $formPersistenceIdentifier = $this->formPersistenceManager->getUniquePersistenceIdentifier($formToDuplicate['identifier'], $savePath);
+        $this->formPersistenceManager->save($formPersistenceIdentifier, $formToDuplicate);
+
+        return $this->controllerContext->getUriBuilder()->uriFor('index', ['formPersistenceIdentifier' => $formPersistenceIdentifier], 'FormEditor');
+    }
+
+    /**
+     * Show references to this persistence identifier
+     *
+     * @param string $formPersistenceIdentifier persistence identifier of the form to duplicate
+     * @return void
+     * @internal
+     */
+    public function referencesAction(string $formPersistenceIdentifier)
+    {
+        $this->view->assign('references', $this->getProcessedReferencesRows($formPersistenceIdentifier));
+        $this->view->assign('formPersistenceIdentifier', $formPersistenceIdentifier);
+        // referencesAction uses the extbase JsonView::class.
+        // That's why we have to set the view variables in this way.
+        $this->view->setVariablesToRender([
+            'references',
+            'formPersistenceIdentifier'
+        ]);
+    }
+
+    /**
+     * Delete a formDefinition identified by the $formPersistenceIdentifier.
+     * Only formDefinitions within storage folders are deletable.
+     *
+     * @param string $formPersistenceIdentifier persistence identifier to delete
+     * @return void
+     * @internal
+     */
+    public function deleteAction(string $formPersistenceIdentifier)
+    {
+        if (
+            empty($this->getReferences($formPersistenceIdentifier))
+            && strpos($formPersistenceIdentifier, 'EXT:') === false
+        ) {
+            $this->formPersistenceManager->delete($formPersistenceIdentifier);
+        } else {
+            $this->addFlashMessage(
+                TranslationService::getInstance()->translate(
+                    $this->formSettings['formManager']['controller']['deleteAction']['errorMessage'],
+                    [$formPersistenceIdentifier],
+                    $this->formSettings['formManager']['translationFile'],
+                    null,
+                    $this->formSettings['formManager']['controller']['deleteAction']['errorMessage']
+                ),
+                TranslationService::getInstance()->translate(
+                    $this->formSettings['formManager']['controller']['deleteAction']['errorTitle'],
+                    null,
+                    $this->formSettings['formManager']['translationFile'],
+                    null,
+                    $this->formSettings['formManager']['controller']['deleteAction']['errorTitle']
+                ),
+                AbstractMessage::ERROR,
+                true
+            );
+        }
+        $this->redirect('index');
+    }
+
+    /**
+     * Return a list of all accessible file mountpoints.
+     *
+     * Only registered mountpoints from
+     * TYPO3.CMS.Form.persistenceManager.allowedFileMounts
+     * are listet. This is list will be reduced by the configured
+     * mountpoints for the current backend user.
+     *
+     * @return array
+     */
+    protected function getAccessibleFormStorageFolders(): array
+    {
+        $preparedAccessibleFormStorageFolders = [];
+        foreach ($this->formPersistenceManager->getAccessibleFormStorageFolders() as $identifier => $folder) {
+            $preparedAccessibleFormStorageFolders[] = [
+                'label' => $folder->getName(),
+                'value' => $identifier
+            ];
+        }
+        return $preparedAccessibleFormStorageFolders;
+    }
+
+    /**
+     * Returns the json encoded data which is used by the form editor
+     * JavaScript app.
+     *
+     * @return string
+     */
+    protected function getFormManagerAppInitialData(): string
+    {
+        $formManagerAppInitialData = [
+            'selectablePrototypesConfiguration' => $this->formSettings['formManager']['selectablePrototypesConfiguration'],
+            'accessibleFormStorageFolders' => $this->getAccessibleFormStorageFolders(),
+            'endpoints' => [
+                'create' => $this->controllerContext->getUriBuilder()->uriFor('create'),
+                'duplicate' => $this->controllerContext->getUriBuilder()->uriFor('duplicate'),
+                'delete' => $this->controllerContext->getUriBuilder()->uriFor('delete'),
+                'references' => $this->controllerContext->getUriBuilder()->uriFor('references')
+            ],
+        ];
+
+        $formManagerAppInitialData = ArrayUtility::reIndexNumericArrayKeysRecursive($formManagerAppInitialData);
+        $formManagerAppInitialData = TranslationService::getInstance()->translateValuesRecursive(
+            $formManagerAppInitialData,
+            $this->formSettings['formManager']['translationFile']
+        );
+        return json_encode($formManagerAppInitialData);
+    }
+
+    /**
+     * List all formDefinitions which can be loaded through t form persistence
+     * manager. Enrich this data by a reference counter.
+     * @return array
+     */
+    protected function getAvailableFormDefinitions(): array
+    {
+        $availableFormDefinitions = [];
+        foreach ($this->formPersistenceManager->listForms() as $formDefinition) {
+            $referenceCount = count($this->getReferences($formDefinition['persistenceIdentifier']));
+            $formDefinition['referenceCount'] = $referenceCount;
+            $availableFormDefinitions[] = $formDefinition;
+        }
+        return $availableFormDefinitions;
+    }
+
+    /**
+     * Returns an array with informations about the references for a
+     * formDefinition identified by $persistenceIdentifier.
+     *
+     * @param string $persistenceIdentifier
+     * @return array
+     * @throws \InvalidArgumentException
+     */
+    protected function getProcessedReferencesRows(string $persistenceIdentifier): array
+    {
+        if (empty($persistenceIdentifier)) {
+            throw new \InvalidArgumentException('$persistenceIdentifier must not be empty.', 1477071939);
+        }
+
+        $references = [];
+        $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
+
+        $referenceRows = $this->getReferences($persistenceIdentifier);
+        foreach ($referenceRows as &$referenceRow) {
+            $record = $this->getBackendUtility()::getRecord($referenceRow['tablename'], $referenceRow['recuid']);
+            if (!$record) {
+                continue;
+            }
+            $pageRecord = $this->getBackendUtility()::getRecord('pages', $record['pid']);
+            $urlParameters = [
+                'edit' => [
+                    $referenceRow['tablename'] => [
+                        $referenceRow['recuid'] => 'edit'
+                    ]
+                ],
+                'returnUrl' => $this->getBackendUtility()::getModuleUrl('web_FormFormbuilder')
+            ];
+
+            $references[] = [
+                'recordPageTitle' => is_array($pageRecord) ? $this->getBackendUtility()::getRecordTitle('pages', $pageRecord) : '',
+                'recordTitle' => $this->getBackendUtility()::getRecordTitle($referenceRow['tablename'], $record, true),
+                'recordIcon' => $iconFactory->getIconForRecord($referenceRow['tablename'], $record, Icon::SIZE_SMALL)->render(),
+                'recordUid' => $referenceRow['recuid'],
+                'recordEditUrl' => $this->getBackendUtility()::getModuleUrl('record_edit', $urlParameters),
+            ];
+        }
+        return $references;
+    }
+
+    /**
+     * Returns an array with all sys_refindex database rows which be
+     * connected to a formDefinition identified by $persistenceIdentifier
+     *
+     * @param string $persistenceIdentifier
+     * @return array
+     * @throws \InvalidArgumentException
+     */
+    protected function getReferences(string $persistenceIdentifier): array
+    {
+        if (empty($persistenceIdentifier)) {
+            throw new \InvalidArgumentException('$persistenceIdentifier must not be empty.', 1472238493);
+        }
+
+        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_refindex');
+        $referenceRows = $queryBuilder
+            ->select('*')
+            ->from('sys_refindex')
+            ->where(
+                $queryBuilder->expr()->eq('deleted', 0),
+                $queryBuilder->expr()->eq('softref_key', $queryBuilder->createNamedParameter('formPersistenceIdentifier', \PDO::PARAM_STR)),
+                $queryBuilder->expr()->eq('ref_string', $queryBuilder->createNamedParameter($persistenceIdentifier, \PDO::PARAM_STR)),
+                $queryBuilder->expr()->eq('tablename', $queryBuilder->createNamedParameter('tt_content', \PDO::PARAM_STR))
+            )
+            ->execute()
+            ->fetchAll();
+        return $referenceRows;
+    }
+
+    /**
+     * Check if a given $templatePath for a given $prototypeName is valid
+     * and accessible.
+     *
+     * Valid template paths has to be configured within
+     * TYPO3.CMS.Form.formManager.selectablePrototypesConfiguration.[('identifier':  $prototypeName)].newFormTemplates.[('templatePath': $templatePath)]
+     *
+     * @param string $prototypeName
+     * @param string $templatePath
+     * @return bool
+     */
+    protected function isValidTemplatePath(string $prototypeName, string $templatePath): bool
+    {
+        $isValid = false;
+        foreach ($this->formSettings['formManager']['selectablePrototypesConfiguration'] as $prototypesConfiguration) {
+            if ($prototypesConfiguration['identifier'] !== $prototypeName) {
+                continue;
+            }
+            foreach ($prototypesConfiguration['newFormTemplates'] as $templatesConfiguration) {
+                if ($templatesConfiguration['templatePath'] !== $templatePath) {
+                    continue;
+                }
+                $isValid = true;
+                break;
+            }
+        }
+
+        $templatePath = GeneralUtility::getFileAbsFileName($templatePath);
+        if (!is_file($templatePath)) {
+            $isValid = false;
+        }
+
+        return $isValid;
+    }
+
+    /**
+     * Registers the Icons into the docheader
+     *
+     * @throws \InvalidArgumentException
+     */
+    protected function registerDocheaderButtons()
+    {
+        /** @var ButtonBar $buttonBar */
+        $buttonBar = $this->view->getModuleTemplate()->getDocHeaderComponent()->getButtonBar();
+        $currentRequest = $this->request;
+        $moduleName = $currentRequest->getPluginName();
+        $getVars = $this->request->getArguments();
+
+        $mayMakeShortcut = $this->getBackendUser()->mayMakeShortcut();
+        if ($mayMakeShortcut) {
+            $extensionName = $currentRequest->getControllerExtensionName();
+            if (count($getVars) === 0) {
+                $modulePrefix = strtolower('tx_' . $extensionName . '_' . $moduleName);
+                $getVars = ['id', 'M', $modulePrefix];
+            }
+
+            $shortcutButton = $buttonBar->makeShortcutButton()
+                ->setModuleName($moduleName)
+                ->setDisplayName($this->getLanguageService()->sL('LLL:EXT:form/Resources/Private/Language/Database.xlf:module.shortcut_name'))
+                ->setGetVariables($getVars);
+            $buttonBar->addButton($shortcutButton);
+        }
+
+        if (isset($getVars['action']) && $getVars['action'] !== 'index') {
+            $backButton = $buttonBar->makeLinkButton()
+                ->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/locallang_common.xlf:back'))
+                ->setIcon($this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-view-go-up', Icon::SIZE_SMALL))
+                ->setHref($this->getBackendUtility()::getModuleUrl($moduleName));
+            $buttonBar->addButton($backButton);
+        } else {
+            $addFormButton = $buttonBar->makeLinkButton()
+                ->setDataAttributes(['identifier' => 'newForm'])
+                ->setHref('#')
+                ->setTitle($this->getLanguageService()->sL('LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.create_new_form'))
+                ->setIcon($this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-document-new', Icon::SIZE_SMALL));
+            $buttonBar->addButton($addFormButton, ButtonBar::BUTTON_POSITION_LEFT);
+        }
+    }
+
+    /**
+     * Returns a form identifier which is the lower cased form name.
+     *
+     * @param string $formName
+     * @return string
+     */
+    protected function convertFormNameToIdentifier(string $formName): string
+    {
+        $formIdentifier = preg_replace('/[^a-zA-Z0-9-_]/', '', $formName);
+        $formIdentifier = lcfirst($formIdentifier);
+        return $formIdentifier;
+    }
+
+    /**
+     * Returns the BackendUtility
+     * This wrapper is needed for unit tests.
+     *
+     * @return string
+     */
+    protected function getBackendUtility(): string
+    {
+        return BackendUtility::class;
+    }
+
+    /**
+     * Returns the current BE user.
+     *
+     * @return BackendUserAuthentication
+     */
+    protected function getBackendUser(): BackendUserAuthentication
+    {
+        return $GLOBALS['BE_USER'];
+    }
+
+    /**
+     * Returns the Language Service
+     *
+     * @return LanguageService
+     */
+    protected function getLanguageService(): LanguageService
+    {
+        return $GLOBALS['LANG'];
+    }
+
+    /**
+     * Returns the page renderer
+     *
+     * @return PageRenderer
+     */
+    protected function getPageRenderer(): PageRenderer
+    {
+        return GeneralUtility::makeInstance(PageRenderer::class);
+    }
+}
diff --git a/typo3/sysext/form/Classes/Controller/FrontendController.php b/typo3/sysext/form/Classes/Controller/FrontendController.php
deleted file mode 100644 (file)
index 43fd203..0000000
+++ /dev/null
@@ -1,342 +0,0 @@
-<?php
-namespace TYPO3\CMS\Form\Controller;
-
-/*
- * 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!
- */
-
-use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
-use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
-use TYPO3\CMS\Form\Domain\Builder\FormBuilder;
-use TYPO3\CMS\Form\Domain\Builder\ValidationBuilder;
-use TYPO3\CMS\Form\Domain\Model\Configuration;
-use TYPO3\CMS\Form\Domain\Model\ValidationElement;
-use TYPO3\CMS\Form\Mvc\Controller\ControllerContext;
-use TYPO3\CMS\Form\Utility\FormUtility;
-
-/**
- * The form wizard controller
- */
-class FrontendController extends ActionController
-{
-    /**
-     * @var FormBuilder
-     */
-    protected $formBuilder;
-
-    /**
-     * @var ValidationBuilder
-     */
-    protected $validationBuilder;
-
-    /**
-     * @var \TYPO3\CMS\Form\Utility\SessionUtility
-     */
-    protected $sessionUtility;
-
-    /**
-     * @var FormUtility
-     */
-    protected $formUtility;
-
-    /**
-     * The TypoScript array
-     *
-     * @var array
-     */
-    protected $typoscript = [];
-
-    /**
-     * TRUE if the validation of the form should be skipped
-     *
-     * @var bool
-     */
-    protected $skipValidation = false;
-
-    /**
-     * @var ControllerContext
-     */
-    protected $controllerContext;
-
-    /**
-     * @var Configuration
-     */
-    protected $configuration;
-
-    /**
-     * @param \TYPO3\CMS\Form\Utility\SessionUtility $sessionUtility
-     * @return void
-     */
-    public function injectSessionUtility(\TYPO3\CMS\Form\Utility\SessionUtility $sessionUtility)
-    {
-        $this->sessionUtility = $sessionUtility;
-    }
-
-    /**
-     * initialize action
-     *
-     * @return void
-     */
-    protected function initializeAction()
-    {
-        $this->configuration = Configuration::create()->setTypoScript($this->settings['typoscript']);
-        $this->formUtility = FormUtility::create($this->configuration);
-        $this->validationBuilder = ValidationBuilder::create($this->configuration);
-        $this->validationBuilder->setFormUtility($this->formUtility);
-        $this->formBuilder = FormBuilder::create($this->configuration);
-        $this->formBuilder->setValidationBuilder($this->validationBuilder);
-        $this->formBuilder->setFormUtility($this->formUtility);
-        $this->typoscript = $this->settings['typoscript'];
-
-            // uploaded file storage
-        $this->sessionUtility->initSession($this->configuration->getPrefix());
-            // move the incoming "formPrefix" data to the $model argument
-            // now we can validate the $model argument
-        if ($this->request->hasArgument($this->configuration->getPrefix())) {
-            $this->skipValidation = false;
-            $argument = $this->request->getArgument($this->configuration->getPrefix());
-            $this->request->setArgument('model', $argument);
-        } else {
-            // If there are more forms at a page we have to skip
-            // the validation of not submitted forms
-            $this->skipValidation = true;
-            $this->request->setArgument('model', []);
-        }
-    }
-
-    /**
-     * initialize show action
-     *
-     * @return void
-     */
-    protected function initializeShowAction()
-    {
-        $validationResults = $this->request->getOriginalRequestMappingResults()->forProperty('model');
-        $this->validationBuilder->buildRules();
-        if ($validationResults->hasErrors()) {
-            $this->formBuilder->setValidationErrors($validationResults);
-        }
-    }
-
-    /**
-     * initialize the confirmation action
-     *
-     * @return void
-     */
-    protected function initializeConfirmationAction()
-    {
-        $this->prepareValidations();
-    }
-
-    /**
-     * initialize the process action
-     *
-     * @return void
-     */
-    protected function initializeProcessAction()
-    {
-        $this->prepareValidations();
-    }
-
-    /**
-     * Builds the controller context by extending
-     * the Extbase context with custom additions.
-     *
-     * @return ControllerContext
-     */
-    protected function buildControllerContext()
-    {
-        $controllerContext = ControllerContext::extend(parent::buildControllerContext())
-            ->setConfiguration($this->configuration);
-        $this->formBuilder->setControllerContext($controllerContext);
-        return $controllerContext;
-    }
-
-    /**
-     * Handles show action, presenting the actual form.
-     *
-     * @param \TYPO3\CMS\Form\Domain\Model\ValidationElement $incomingData
-     * @ignorevalidation $incomingData
-     * @return void
-     */
-    public function showAction(ValidationElement $incomingData = null)
-    {
-        if ($incomingData !== null) {
-            $this->controllerContext->setValidationElement($incomingData);
-        }
-        $form = $this->formBuilder->buildModel();
-        $this->view->assign('model', $form);
-    }
-
-    /**
-     * Handles confirmation action, presenting the user submitted
-     * data again for final confirmation.
-     *
-     * @param \TYPO3\CMS\Form\Domain\Model\ValidationElement $model
-     * @return void
-     */
-    public function confirmationAction(ValidationElement $model)
-    {
-        $this->skipForeignFormProcessing();
-
-        if (count($model->getIncomingFields()) === 0) {
-            $this->sessionUtility->destroySession();
-            $this->forward('show');
-        }
-        $this->controllerContext->setValidationElement($model);
-        $form = $this->formBuilder->buildModel();
-        // store uploaded files
-        $this->sessionUtility->storeSession();
-        $this->view->assign('model', $form);
-
-        $message = $this->formUtility->renderItem(
-            $this->typoscript['confirmation.']['message.'],
-            $this->typoscript['confirmation.']['message'],
-            LocalizationUtility::translate('tx_form_view_confirmation.message', 'form')
-        );
-        $this->view->assign('message', $message);
-    }
-
-    /**
-     * action dispatchConfirmationButtonClick
-     *
-     * @param \TYPO3\CMS\Form\Domain\Model\ValidationElement $model
-     * @return void
-     */
-    public function dispatchConfirmationButtonClickAction(ValidationElement $model)
-    {
-        $this->skipForeignFormProcessing();
-
-        if ($this->request->hasArgument('confirmation-true')) {
-            $this->forward('process', null, null, [$this->configuration->getPrefix() => $this->request->getArgument('model')]);
-        } else {
-            $this->sessionUtility->destroySession();
-            $this->forward('show', null, null, ['incomingData' => $this->request->getArgument('model')]);
-        }
-    }
-
-    /**
-     * Handles process action, actually processing the user
-     * submitted data and forwarding it to post-processors
-     * (e.g. sending out mail messages).
-     *
-     * @param \TYPO3\CMS\Form\Domain\Model\ValidationElement $model
-     * @return void
-     */
-    public function processAction(ValidationElement $model)
-    {
-        $this->skipForeignFormProcessing();
-
-        $this->controllerContext->setValidationElement($model);
-        $form = $this->formBuilder->buildModel();
-        $postProcessorTypoScript = [];
-        if (isset($this->typoscript['postProcessor.'])) {
-            $postProcessorTypoScript = $this->typoscript['postProcessor.'];
-        }
-
-        /** @var $postProcessor \TYPO3\CMS\Form\PostProcess\PostProcessor */
-        $postProcessor = $this->objectManager->get(
-            \TYPO3\CMS\Form\PostProcess\PostProcessor::class,
-            $form, $postProcessorTypoScript
-        );
-        $postProcessor->setControllerContext($this->controllerContext);
-
-        // @todo What is happening here?
-        $content = $postProcessor->process();
-        $this->sessionUtility->destroySession();
-        $this->forward('afterProcess', null, null, ['postProcessorContent' => $content]);
-    }
-
-    /**
-     * action after process
-     *
-     * @param string $postProcessorContent
-     * @return void
-     */
-    public function afterProcessAction($postProcessorContent)
-    {
-        $this->view->assign('postProcessorContent', $postProcessorContent);
-    }
-
-    /**
-     * Skip the processing of foreign forms.
-     * If there is more than one form on a page
-     * we have to be sure that only the submitted form will be
-     * processed. On data submission, the extbase action "confirmation" or
-     * "process" is called. The detection which form is submitted
-     * is done by the form prefix. All forms which do not have any
-     * submitted data are skipped and forwarded to the show action.
-     *
-     * @return void
-     */
-    protected function skipForeignFormProcessing()
-    {
-        if (
-            !$this->request->hasArgument($this->configuration->getPrefix())
-            && !$this->sessionUtility->getSessionData()
-        ) {
-            $this->forward('show');
-        }
-    }
-
-    /**
-     * If the current form should be validated
-     * then set the dynamic validation
-     *
-     * @return void
-     */
-    protected function prepareValidations()
-    {
-        if ($this->skipValidation || !$this->arguments->hasArgument('model')) {
-            return;
-        }
-
-        $this->validationBuilder->buildRules($this->request->getArgument('model'));
-        $this->setDynamicValidation($this->validationBuilder->getRules());
-        $this->skipValidation = false;
-    }
-
-    /**
-     * Sets the dynamic validation rules.
-     *
-     * @param array $toValidate
-     * @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException
-     * @throws \TYPO3\CMS\Extbase\Validation\Exception\NoSuchValidatorException
-     */
-    protected function setDynamicValidation(array $toValidate = [])
-    {
-        // build custom validation chain
-        /** @var \TYPO3\CMS\Extbase\Validation\ValidatorResolver $validatorResolver */
-        $validatorResolver = $this->objectManager->get(\TYPO3\CMS\Extbase\Validation\ValidatorResolver::class);
-
-        /** @var \TYPO3\CMS\Form\Domain\Validator\ValidationElementValidator $modelValidator */
-        $modelValidator = $validatorResolver->createValidator(\TYPO3\CMS\Form\Domain\Validator\ValidationElementValidator::class);
-        foreach ($toValidate as $propertyName => $validations) {
-            foreach ($validations as $validation) {
-                if (empty($validation['validator'])) {
-                    throw new \TYPO3\CMS\Extbase\Validation\Exception\NoSuchValidatorException('Invalid validate configuration for ' . $propertyName . ': Could not resolve class name for validator "' . $validation['validatorName'] . '".', 1441893777);
-                }
-                $modelValidator->addPropertyValidator($propertyName, $validation['validator']);
-            }
-        }
-
-        if ($modelValidator->countPropertyValidators()) {
-            /** @var \TYPO3\CMS\Extbase\Validation\Validator\ConjunctionValidator $baseConjunctionValidator */
-            $baseConjunctionValidator = $this->arguments->getArgument('model')->getValidator();
-            if ($baseConjunctionValidator === null) {
-                $baseConjunctionValidator = $validatorResolver->createValidator(\TYPO3\CMS\Extbase\Validation\Validator\ConjunctionValidator::class);
-                $this->arguments->getArgument('model')->setValidator($baseConjunctionValidator);
-            }
-            $baseConjunctionValidator->addValidator($modelValidator);
-        }
-    }
-}
diff --git a/typo3/sysext/form/Classes/Controller/WizardController.php b/typo3/sysext/form/Classes/Controller/WizardController.php
deleted file mode 100644 (file)
index e7185dc..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-<?php
-namespace TYPO3\CMS\Form\Controller;
-
-/*
- * 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!
- */
-
-use Psr\Http\Message\ResponseInterface;
-use Psr\Http\Message\ServerRequestInterface;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Form\Domain\Repository\ContentRepository;
-
-/**
- * The form wizard controller
- */
-class WizardController
-{
-    /**
-     * The constructor to load the LL file
-     */
-    public function __construct()
-    {
-        $this->getLanguageService()->includeLLFile('EXT:form/Resources/Private/Language/locallang_wizard.xlf');
-    }
-
-    /**
-     * The save action called via AJAX
-     *
-     * The action which should be taken when the form in the wizard is saved
-     *
-     * @param ServerRequestInterface $request
-     * @param ResponseInterface $response
-     * @return ResponseInterface returns a 500 error or a valid JSON response
-     */
-    public function saveAction(ServerRequestInterface $request, ResponseInterface $response)
-    {
-        $repository = $this->getRepository();
-        $typoscript = '';
-        $jsonArray = [];
-
-        // Check if the referenced record is available
-        if ($repository->hasRecord()) {
-            // Save the data
-            $typoscript = $repository->save();
-        }
-
-        if (!$typoscript) {
-            $response = $response->withStatus(500);
-            $message = $this->getLanguageService()->getLL('action_save_message_failed', false);
-        } else {
-            $message = $this->getLanguageService()->getLL('action_save_message_saved', false);
-            $jsonArray['fakeTs'] = $typoscript;
-        }
-
-        $jsonArray['message'] = $message;
-        $response->getBody()->write(json_encode($jsonArray));
-        return $response
-                ->withHeader('Expires', 'Mon, 26 Jul 1997 05:00:00 GMT')
-                ->withHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT')
-                ->withHeader('Cache-Control', 'no-cache, must-revalidate')
-                ->withHeader('Pragma', 'no-cache');
-    }
-
-    /**
-     * Gets the repository object.
-     *
-     * @return ContentRepository
-     */
-    protected function getRepository()
-    {
-        return GeneralUtility::makeInstance(ContentRepository::class);
-    }
-
-    /**
-     * Returns an instance of LanguageService
-     *
-     * @return \TYPO3\CMS\Lang\LanguageService
-     */
-    protected function getLanguageService()
-    {
-        return $GLOBALS['LANG'];
-    }
-}
diff --git a/typo3/sysext/form/Classes/Domain/Builder/ElementBuilder.php b/typo3/sysext/form/Classes/Domain/Builder/ElementBuilder.php
deleted file mode 100644 (file)
index c2b0023..0000000
+++ /dev/null
@@ -1,510 +0,0 @@
-<?php
-namespace TYPO3\CMS\Form\Domain\Builder;
-
-/*
- * 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!
- */
-
-use TYPO3\CMS\Core\Utility\MathUtility;
-use TYPO3\CMS\Form\Domain\Model\Element;
-
-/**
- * Builder for Element domain models.
- */
-class ElementBuilder
-{
-    /**
-     * @param FormBuilder $formBuilder
-     * @param Element $element
-     * @param array $userDefinedTypoScript
-     * @return ElementBuilder
-     */
-    public static function create(FormBuilder $formBuilder, Element $element, array $userDefinedTypoScript)
-    {
-        /** @var ElementBuilder $elementBuilder */
-        $elementBuilder = \TYPO3\CMS\Form\Utility\FormUtility::getObjectManager()->get(self::class);
-        $elementBuilder->setFormBuilder($formBuilder);
-        $elementBuilder->setElement($element);
-        $elementBuilder->setUserConfiguredElementTyposcript($userDefinedTypoScript);
-        return $elementBuilder;
-    }
-
-    /**
-     * @var \TYPO3\CMS\Form\Domain\Repository\TypoScriptRepository
-     */
-    protected $typoScriptRepository;
-
-    /**
-     * @var \TYPO3\CMS\Extbase\Service\TypoScriptService
-     */
-    protected $typoScriptService;
-
-    /**
-     * @var array
-     */
-    protected $userConfiguredElementTyposcript = [];
-
-    /**
-     * @var array
-     */
-    protected $htmlAttributes = [];
-
-    /**
-     * @var array
-     */
-    protected $additionalArguments = [];
-
-    /**
-     * @var array
-     */
-    protected $wildcardPrefixes = [];
-
-    /**
-     * @var FormBuilder
-     */
-    protected $formBuilder;
-
-    /**
-     * @var Element
-     */
-    protected $element;
-
-    /**
-     * @param \TYPO3\CMS\Form\Domain\Repository\TypoScriptRepository $typoScriptRepository
-     * @return void
-     */
-    public function injectTypoScriptRepository(\TYPO3\CMS\Form\Domain\Repository\TypoScriptRepository $typoScriptRepository)
-    {
-        $this->typoScriptRepository = $typoScriptRepository;
-    }
-
-    /**
-     * @param \TYPO3\CMS\Extbase\Service\TypoScriptService $typoScriptService
-     * @return void
-     */
-    public function injectTypoScriptService(\TYPO3\CMS\Extbase\Service\TypoScriptService $typoScriptService)
-    {
-        $this->typoScriptService = $typoScriptService;
-    }
-
-    /**
-     * @param FormBuilder $formBuilder
-     */
-    public function setFormBuilder(FormBuilder $formBuilder)
-    {
-        $this->formBuilder = $formBuilder;
-    }
-
-    /**
-     * @param Element $element
-     */
-    public function setElement(Element $element)
-    {
-        $this->element = $element;
-    }
-
-    /**
-     * Set the fluid partial path to the element
-     *
-     * @return void
-     */
-    public function setPartialPaths()
-    {
-        $this->setElementPartialPath();
-    }
-
-    /**
-     * Set the fluid partial path to the element
-     *
-     * @return void
-     */
-    protected function setElementPartialPath()
-    {
-        if (!isset($this->userConfiguredElementTyposcript['partialPath'])) {
-            $partialPath = $this->typoScriptRepository->getDefaultFluidTemplate($this->element->getElementType());
-        } else {
-            $partialPath = $this->userConfiguredElementTyposcript['partialPath'];
-            unset($this->userConfiguredElementTyposcript['partialPath']);
-        }
-        $this->element->setPartialPath($partialPath);
-    }
-
-    /**
-     * Set the fluid partial path to the element
-     *
-     * @return void
-     */
-    public function setVisibility()
-    {
-        $visibility = false;
-        if ($this->formBuilder->getControllerAction() === 'show') {
-            if (!isset($this->userConfiguredElementTyposcript['visibleInShowAction'])) {
-                $visibility = (bool)$this->typoScriptRepository->getModelConfigurationByScope($this->element->getElementType(), 'visibleInShowAction');
-            } else {
-                $visibility = (bool)$this->userConfiguredElementTyposcript['visibleInShowAction'];
-            }
-        } elseif ($this->formBuilder->getControllerAction() === 'confirmation') {
-            if (!isset($this->userConfiguredElementTyposcript['visibleInConfirmationAction'])) {
-                $visibility = (bool)$this->typoScriptRepository->getModelConfigurationByScope($this->element->getElementType(), 'visibleInConfirmationAction');
-            } else {
-                $visibility = (bool)$this->userConfiguredElementTyposcript['visibleInConfirmationAction'];
-            }
-        } elseif ($this->formBuilder->getControllerAction() === 'process') {
-            if (!isset($this->userConfiguredElementTyposcript['visibleInMail'])) {
-                $visibility = (bool)$this->typoScriptRepository->getModelConfigurationByScope($this->element->getElementType(), 'visibleInMail');
-            } else {
-                $visibility = (bool)$this->userConfiguredElementTyposcript['visibleInMail'];
-            }
-        }
-        $this->element->setShowElement($visibility);
-    }
-
-    /**
-     * Find all prefix-* attributes and return the
-     * found prefixs. Than delete them from the htmlAttributes array
-     *
-     * @return void
-     */
-    public function setHtmlAttributeWildcards()
-    {
-        foreach ($this->htmlAttributes as $attributeName => $attributeValue) {
-            if (strpos($attributeName, '-*') > 0) {
-                $prefix = substr($attributeName, 0, -1);
-                $this->wildcardPrefixes[] = $prefix;
-                unset($this->htmlAttributes[$attributeName]);
-            }
-        }
-    }
-
-    /**
-     * Overlay user defined html attribute values
-     * To determine whats a html attribute, the htmlAttributes
-     * array is used. If a html attribute value is found in userConfiguredElementTyposcript
-     * this value is set to htmlAttributes and removed from userConfiguredElementTyposcript.
-     *
-     * @return void
-     */
-    public function overlayUserdefinedHtmlAttributeValues()
-    {
-        foreach ($this->htmlAttributes as $attributeName => $attributeValue) {
-            $attributeNameWithoutDot = rtrim($attributeName, '.');
-            $attributeNameToSet = $attributeNameWithoutDot;
-
-            if ($this->arrayKeyExists($attributeNameWithoutDot, $this->userConfiguredElementTyposcript)) {
-                $attributeValue = $this->formBuilder->getFormUtility()->renderItem(
-                    $this->userConfiguredElementTyposcript[$attributeNameWithoutDot . '.'],
-                    $this->userConfiguredElementTyposcript[$attributeNameWithoutDot]
-                );
-                $this->htmlAttributes[$attributeNameToSet] = $attributeValue;
-            }
-
-            unset($this->userConfiguredElementTyposcript[$attributeNameWithoutDot . '.']);
-            unset($this->userConfiguredElementTyposcript[$attributeNameWithoutDot]);
-        }
-
-            // the prefix-* magic
-        $ignoreKeys = [];
-        foreach ($this->userConfiguredElementTyposcript as $attributeName => $attributeValue) {
-            // ignore child elements
-            if (
-                MathUtility::canBeInterpretedAsInteger($attributeName)
-                || isset($ignoreKeys[$attributeName])
-            ) {
-                $ignoreKeys[$attributeName . '.'] = true;
-                continue;
-            }
-
-            foreach ($this->wildcardPrefixes as $wildcardPrefix) {
-                if (strpos($attributeName, $wildcardPrefix) !== 0) {
-                    continue;
-                }
-                $attributeNameWithoutDot = rtrim($attributeName, '.');
-                $attributeValue = $this->formBuilder->getFormUtility()->renderItem(
-                    $this->userConfiguredElementTyposcript[$attributeNameWithoutDot . '.'],
-                    $this->userConfiguredElementTyposcript[$attributeNameWithoutDot]
-                );
-                $this->htmlAttributes[$attributeNameWithoutDot] = $attributeValue;
-                $ignoreKeys[$attributeNameWithoutDot . '.'] = true;
-                unset($this->userConfiguredElementTyposcript[$attributeNameWithoutDot . '.']);
-                unset($this->userConfiguredElementTyposcript[$attributeNameWithoutDot]);
-                break;
-            }
-        }
-    }
-
-    /**
-     * If fixedHtmlAttributeValues are defined for this element
-     * then overwrite the html attribute value
-     *
-     * @return void
-     */
-    public function overlayFixedHtmlAttributeValues()
-    {
-        $fixedHtmlAttributeValues = $this->typoScriptRepository->getModelConfigurationByScope($this->element->getElementType(), 'fixedHtmlAttributeValues.');
-        if (is_array($fixedHtmlAttributeValues)) {
-            foreach ($fixedHtmlAttributeValues as $attributeName => $attributeValue) {
-                $this->htmlAttributes[$attributeName] = $attributeValue;
-            }
-        }
-    }
-
-    /**
-     * Move htmlAttributes to additionalArguments that must be passed
-     * as a view helper argument
-     *
-     * @return void
-     */
-    public function moveHtmlAttributesToAdditionalArguments()
-    {
-        $htmlAttributesUsedByTheViewHelperDirectly = $this->typoScriptRepository->getModelConfigurationByScope($this->element->getElementType(), 'htmlAttributesUsedByTheViewHelperDirectly.');
-        if (is_array($htmlAttributesUsedByTheViewHelperDirectly)) {
-            foreach ($htmlAttributesUsedByTheViewHelperDirectly as $attributeName) {
-                if (array_key_exists($attributeName, $this->htmlAttributes)) {
-                    $this->additionalArguments[$attributeName] = $this->htmlAttributes[$attributeName];
-                    unset($this->htmlAttributes[$attributeName]);
-                }
-            }
-        }
-    }
-
-    /**
-     * Set the viewhelper default arguments in the additionalArguments array
-     *
-     * @return void
-     */
-    public function setViewHelperDefaulArgumentsToAdditionalArguments()
-    {
-        $viewHelperDefaultArguments = $this->typoScriptRepository->getModelConfigurationByScope($this->element->getElementType(), 'viewHelperDefaultArguments.');
-        if (is_array($viewHelperDefaultArguments)) {
-            foreach ($viewHelperDefaultArguments as $viewHelperDefaulArgumentName => $viewHelperDefaulArgumentValue) {
-                $viewHelperDefaulArgumentNameWithoutDot = rtrim($viewHelperDefaulArgumentName, '.');
-                $this->additionalArguments[$viewHelperDefaulArgumentNameWithoutDot] = $viewHelperDefaulArgumentValue;
-            }
-        }
-        unset($this->userConfiguredElementTyposcript['viewHelperDefaultArguments']);
-    }
-
-    /**
-     * Move all userdefined properties to the additionalArguments
-     * array. Ignore the child elements
-     *
-     * @return void
-     */
-    public function moveAllOtherUserdefinedPropertiesToAdditionalArguments()
-    {
-        $viewHelperDefaultArguments = $this->typoScriptRepository->getModelConfigurationByScope($this->element->getElementType(), 'viewHelperDefaultArguments.');
-        $ignoreKeys = [];
-
-        foreach ($this->userConfiguredElementTyposcript as $attributeName => $attributeValue) {
-            // ignore child elements
-            if (
-                MathUtility::canBeInterpretedAsInteger($attributeName)
-                || isset($ignoreKeys[$attributeName])
-                || $attributeName == 'postProcessor.'
-                || $attributeName == 'rules.'
-                || $attributeName == 'filters.'
-                || $attributeName == 'layout'
-            ) {
-                $ignoreKeys[$attributeName . '.'] = true;
-                continue;
-            }
-            $attributeNameWithoutDot = rtrim($attributeName, '.');
-            $attributeNameToSet = $attributeNameWithoutDot;
-
-            if (
-                isset($viewHelperDefaultArguments[$attributeName])
-                || isset($viewHelperDefaultArguments[$attributeNameWithoutDot])
-            ) {
-                $this->formBuilder->getFormUtility()->renderArrayItems($attributeValue);
-                $attributeValue = $this->typoScriptService->convertTypoScriptArrayToPlainArray($attributeValue);
-            } else {
-                $attributeValue = $this->formBuilder->getFormUtility()->renderItem(
-                    $this->userConfiguredElementTyposcript[$attributeNameWithoutDot . '.'],
-                    $this->userConfiguredElementTyposcript[$attributeNameWithoutDot]
-                );
-            }
-            $this->additionalArguments[$attributeNameToSet] = $attributeValue;
-            $ignoreKeys[$attributeNameToSet . '.'] = true;
-            $ignoreKeys[$attributeNameToSet] = true;
-
-            unset($this->userConfiguredElementTyposcript[$attributeNameWithoutDot . '.']);
-            unset($this->userConfiguredElementTyposcript[$attributeNameWithoutDot]);
-        }
-            // remove "stdWrap." from "additionalArguments" on
-            // the FORM Element
-        if (
-            !$this->formBuilder->getConfiguration()->getContentElementRendering()
-            && $this->element->getElementType() == 'FORM'
-        ) {
-            unset($this->additionalArguments['stdWrap']);
-            unset($this->additionalArguments['stdWrap.']);
-        }
-    }
-
-    /**
-     * Set the name and id attribute
-     *
-     * @return array
-     */
-    public function setNameAndId()
-    {
-        if (
-            $this->element->getParentElement()
-            && (int)$this->typoScriptRepository->getModelConfigurationByScope($this->element->getParentElement()->getElementType(), 'childrenInheritName') == 1
-        ) {
-            $this->htmlAttributes['name'] = $this->element->getParentElement()->getName();
-            $this->additionalArguments['multiple'] = '1';
-            $name = $this->sanitizeNameAttribute($this->userConfiguredElementTyposcript['name']);
-            $this->element->setName($name);
-        } else {
-            $this->htmlAttributes['name'] = $this->sanitizeNameAttribute($this->htmlAttributes['name']);
-            $this->element->setName($this->htmlAttributes['name']);
-        }
-        $this->htmlAttributes['id'] = $this->sanitizeIdAttribute($this->htmlAttributes['id']);
-        $this->element->setId($this->htmlAttributes['id']);
-    }
-
-    /**
-     * If the name is not defined it is automatically generated
-     * using the following syntax: id-{element_counter}
-     * The name attribute will be transformed if it contains some
-     * non allowed characters:
-     * - spaces are changed into hyphens
-     * - remove all characters except a-z A-Z 0-9 _ -
-     *
-     * @param string $name
-     * @return string
-     */
-    public function sanitizeNameAttribute($name)
-    {
-        $name = $this->formBuilder->getFormUtility()->sanitizeNameAttribute($name);
-        if (empty($name)) {
-            $name = 'id-' . $this->element->getElementCounter();
-        }
-        return $name;
-    }
-
-    /**
-     * If the id is not defined it is automatically generated
-     * using the following syntax: field-{element_counter}
-     * The id attribute will be transformed if it contains some
-     * non allowed characters:
-     * - spaces are changed into hyphens
-     * - if the id start with a integer then transform it to field-{integer}
-     * - remove all characters expect a-z A-Z 0-9 _ - : .
-     *
-     * @param string $id
-     * @return string
-     */
-    protected function sanitizeIdAttribute($id)
-    {
-        $id = $this->formBuilder->getFormUtility()->sanitizeIdAttribute($id);
-        if (empty($id)) {
-            $id = 'field-' . $this->element->getElementCounter();
-        }
-        return $id;
-    }
-
-    /**
-     * Check if a needle exists in a array.
-     *
-     * @param string $needle
-     * @param array $haystack
-     * @return bool TRUE if found
-     */
-    protected function arrayKeyExists($needle, array $haystack = [])
-    {
-        return
-            isset($haystack[$needle]) || isset($haystack[$needle . '.'])
-        ;
-    }
-
-    /**
-     * Get the current html attributes
-     *
-     * @return array
-     */
-    public function getHtmlAttributes()
-    {
-        return $this->htmlAttributes;
-    }
-
-    /**
-     * Set the current html attributes
-     *
-     * @param array $htmlAttributes
-     */
-    public function setHtmlAttributes(array $htmlAttributes)
-    {
-        $this->htmlAttributes = $htmlAttributes;
-    }
-
-    /**
-     * Get the current additional arguments
-     *
-     * @return array
-     */
-    public function getAdditionalArguments()
-    {
-        return $this->additionalArguments;
-    }
-
-    /**
-     * Set the current additional arguments
-     *
-     * @param array $additionalArguments
-     */
-    public function setAdditionalArguments(array $additionalArguments)
-    {
-        $this->additionalArguments = $additionalArguments;
-    }
-
-    /**
-     * Get the current wildcard prefixes
-     *
-     * @return array
-     */
-    public function getWildcardPrefixes()
-    {
-        return $this->wildcardPrefixes;
-    }
-
-    /**
-     * Set the current wildcard prefixes
-     *
-     * @param array $wildcardPrefixes
-     */
-    public function setWildcardPrefixes(array $wildcardPrefixes)
-    {
-        $this->wildcardPrefixes = $wildcardPrefixes;
-    }
-
-    /**
-     * Get the current Element
-     *
-     * @return array
-     */
-    public function getUserConfiguredElementTyposcript()
-    {
-        return $this->userConfiguredElementTyposcript;
-    }
-
-    /**
-     * Set the current Element
-     *
-     * @param array $userConfiguredElementTyposcript
-     */
-    public function setUserConfiguredElementTyposcript(array $userConfiguredElementTyposcript)
-    {
-        $this->userConfiguredElementTyposcript = $userConfiguredElementTyposcript;
-    }
-}
diff --git a/typo3/sysext/form/Classes/Domain/Builder/FormBuilder.php b/typo3/sysext/form/Classes/Domain/Builder/FormBuilder.php
deleted file mode 100644 (file)
index 9f4ddac..0000000
+++ /dev/null
@@ -1,579 +0,0 @@
-<?php
-namespace TYPO3\CMS\Form\Domain\Builder;
-
-/*
- * 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!
- */
-
-use TYPO3\CMS\Core\Utility\ArrayUtility;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Form\Domain\Model\Configuration;
-use TYPO3\CMS\Form\Domain\Model\Element;
-use TYPO3\CMS\Form\Domain\Model\ValidationElement;
-use TYPO3\CMS\Form\Mvc\Controller\ControllerContext;
-use TYPO3\CMS\Form\Utility\FormUtility;
-
-/**
- * TypoScript factory for form
- *
- * Takes the incoming TypoScript and adds all the necessary form objects
- * according to the configuration.
- */
-class FormBuilder
-{
-    /**
-     * @param Configuration $configuration
-     * @return FormBuilder
-     */
-    public static function create(Configuration $configuration)
-    {
-        /** @var FormBuilder $formBuilder */
-        $formBuilder = \TYPO3\CMS\Form\Utility\FormUtility::getObjectManager()->get(self::class);
-        $formBuilder->setConfiguration($configuration);
-        return $formBuilder;
-    }
-
-    /**
-     * @var FormUtility
-     */
-    protected $formUtility;
-
-    /**
-     * @var \TYPO3\CMS\Extbase\Service\TypoScriptService
-     */
-    protected $typoScriptService;
-
-    /**
-     * @var ValidationBuilder
-     */
-    protected $validationBuilder;
-
-    /**
-     * @var \TYPO3\CMS\Form\Domain\Repository\TypoScriptRepository
-     */
-    protected $typoScriptRepository;
-
-    /**
-      * @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher
-      */
-    protected $signalSlotDispatcher;
-
-    /**
-     * @var \TYPO3\CMS\Form\Utility\SessionUtility
-     */
-    protected $sessionUtility;
-
-    /**
-     * @var \TYPO3\CMS\Extbase\Object\ObjectManager
-     */
-    protected $objectManager;
-
-    /**
-     * @var \TYPO3\CMS\Form\Utility\ElementCounter
-     */
-    protected $elementCounter;
-
-    /**
-     * @var NULL|\TYPO3\CMS\Extbase\Error\Result
-     */
-    protected $validationErrors = null;
-
-    /**
-     * @var Configuration;
-     */
-    protected $configuration;
-
-    /**
-     * @var ControllerContext
-     */
-    protected $controllerContext;
-
-    /**
-     * @param \TYPO3\CMS\Extbase\Service\TypoScriptService $typoScriptService
-     * @return void
-     */
-    public function injectTypoScriptService(\TYPO3\CMS\Extbase\Service\TypoScriptService $typoScriptService)
-    {
-        $this->typoScriptService = $typoScriptService;
-    }
-
-    /**
-     * @param \TYPO3\CMS\Form\Domain\Repository\TypoScriptRepository $typoScriptRepository
-     * @return void
-     */
-    public function injectTypoScriptRepository(\TYPO3\CMS\Form\Domain\Repository\TypoScriptRepository $typoScriptRepository)
-    {
-        $this->typoScriptRepository = $typoScriptRepository;
-    }
-
-    /**
-     * @param \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher
-     * @return void
-     */
-    public function injectSignalSlotDispatcher(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher)
-    {
-        $this->signalSlotDispatcher = $signalSlotDispatcher;
-    }
-
-    /**
-     * @param \TYPO3\CMS\Form\Utility\SessionUtility $sessionUtility
-     * @return void
-     */
-    public function injectSessionUtility(\TYPO3\CMS\Form\Utility\SessionUtility $sessionUtility)
-    {
-        $this->sessionUtility = $sessionUtility;
-    }
-
-    /**
-     * @param \TYPO3\CMS\Form\Utility\ElementCounter $elementCounter
-     * @return void
-     */
-    public function injectElementCounter(\TYPO3\CMS\Form\Utility\ElementCounter $elementCounter)
-    {
-        $this->elementCounter = $elementCounter;
-    }
-
-    /**
-     * @param \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager
-     * @return void
-     */
-    public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManager $objectManager)
-    {
-        $this->objectManager = $objectManager;
-    }
-
-    /**
-     * @return Configuration
-     */
-    public function getConfiguration()
-    {
-        return $this->configuration;
-    }
-
-    /**
-     * @param Configuration $configuration
-     */
-    public function setConfiguration(Configuration $configuration)
-    {
-        $this->configuration = $configuration;
-    }
-
-    /**
-     * @return ControllerContext
-     */
-    public function getControllerContext()
-    {
-        return $this->controllerContext;
-    }
-
-    /**
-     * @param ControllerContext $controllerContext
-     */
-    public function setControllerContext(ControllerContext $controllerContext)
-    {
-        $this->controllerContext = $controllerContext;
-    }
-
-    /**
-     * @return FormUtility
-     */
-    public function getFormUtility()
-    {
-        return $this->formUtility;
-    }
-
-    /**
-     * @param FormUtility $formUtility
-     */
-    public function setFormUtility(FormUtility $formUtility)
-    {
-        $this->formUtility = $formUtility;
-    }
-
-    /**
-     * @return ValidationBuilder
-     */
-    public function getValidationBuilder()
-    {
-        return $this->validationBuilder;
-    }
-
-    /**
-     * @param ValidationBuilder $validationBuilder
-     */
-    public function setValidationBuilder(ValidationBuilder $validationBuilder)
-    {
-        $this->validationBuilder = $validationBuilder;
-    }
-
-    /**
-     * Build model from TypoScript
-     * Needed if more than one form exist at a page
-     *
-     * @return NULL|\TYPO3\CMS\Form\Domain\Model\Element The form object containing the child elements
-     */
-    public function buildModel()
-    {
-        $userConfiguredFormTypoScript = $this->configuration->getTypoScript();
-        $form = $this->createElementObject();
-        $this->reviveElement($form, $userConfiguredFormTypoScript, 'FORM');
-        $form->setThemeName($this->configuration->getThemeName());
-        return $form;
-    }
-
-    /**
-     * Create a element
-     *
-     * @return \TYPO3\CMS\Form\Domain\Model\Element
-     */
-    protected function createElementObject()
-    {
-        $element = GeneralUtility::makeInstance(Element::class);
-        return $element;
-    }
-
-    /**
-     * Revive the domain model of the accordant element.
-     *
-     * @param Element $element
-     * @param array $userConfiguredElementTypoScript The configuration array
-     * @param string $elementType The element type (e.g BUTTON)
-     * @return void
-     */
-    protected function reviveElement(Element $element, array $userConfiguredElementTypoScript, $elementType = '')
-    {
-        // @todo Check $userConfiguredElementTypoScript
-
-        $element->setElementType($elementType);
-        $element->setElementCounter($this->elementCounter->getElementId());
-
-        $elementBuilder = ElementBuilder::create($this, $element, $userConfiguredElementTypoScript);
-        $elementBuilder->setPartialPaths();
-        $elementBuilder->setVisibility();
-
-        if ($element->getElementType() == 'CONTENTELEMENT') {
-            $attributeValue = '';
-            if ($this->configuration->getContentElementRendering()) {
-                $attributeValue = $this->formUtility->renderItem(
-                    $userConfiguredElementTypoScript['cObj.'],
-                    $userConfiguredElementTypoScript['cObj']
-                );
-            }
-            $element->setAdditionalArguments([
-                'content' => $attributeValue,
-            ]);
-        } else {
-            $this->setAttributes($elementBuilder, $element, $userConfiguredElementTypoScript);
-            $userConfiguredElementTypoScript = $elementBuilder->getUserConfiguredElementTyposcript();
-            $this->setValidationMessages($element);
-
-            $this->signalSlotDispatcher->dispatch(
-                __CLASS__,
-                'txFormAfterElementCreation',
-                [$element, $this]
-            );
-                // create all child elements
-            $this->setChildElementsByIntegerKey($element, $userConfiguredElementTypoScript);
-        }
-    }
-
-    /**
-     * Rendering of a "numerical array" of Form objects from TypoScript
-     * Creates new object for each element found
-     *
-     * @param Element $element
-     * @param array $userConfiguredElementTypoScript The configuration array
-     * @return void
-     * @throws \InvalidArgumentException
-     */
-    protected function setChildElementsByIntegerKey(Element $element, array $userConfiguredElementTypoScript)
-    {
-        if (is_array($userConfiguredElementTypoScript)) {
-            $keys = ArrayUtility::filterAndSortByNumericKeys($userConfiguredElementTypoScript);
-            foreach ($keys as $key) {
-                if (
-                    (int)$key
-                    && strpos($key, '.') === false
-                ) {
-                    $elementType = $userConfiguredElementTypoScript[$key];
-                    if (isset($userConfiguredElementTypoScript[$key . '.'])) {
-                        $concreteChildElementTypoScript = $userConfiguredElementTypoScript[$key . '.'];
-                    } else {
-                        $concreteChildElementTypoScript = [];
-                    }
-                    $this->distinguishElementType($element, $concreteChildElementTypoScript, $elementType);
-                }
-            }
-        } else {
-            throw new \InvalidArgumentException('Container element with id=' . $element->getElementCounter() . ' has no configuration which means no children.', 1333754854);
-        }
-    }
-
-    /**
-     * Create and add element by type.
-     * If its not a registered form element
-     * try to render it as contentelement with the internal elementType
-     * CONTENTELEMENT
-     *
-     * @param Element $element
-     * @param array $userConfiguredElementTypoScript The configuration array
-     * @param string $elementType The element type (e.g BUTTON)
-     * @return void
-     */
-    protected function distinguishElementType(Element $element, array $userConfiguredElementTypoScript, $elementType = '')
-    {
-        if (in_array($elementType, $this->typoScriptRepository->getRegisteredElementTypes())) {
-            $this->addChildElement($element, $userConfiguredElementTypoScript, $elementType);
-        } elseif ($this->configuration->getContentElementRendering()) {
-            $contentObject = [
-                'cObj' => $elementType,
-                'cObj.' => $userConfiguredElementTypoScript
-            ];
-            $this->addChildElement($element, $contentObject, 'CONTENTELEMENT');
-        }
-    }
-
-    /**
-     * Add child object to this element
-     *
-     * @param Element $element
-     * @param array $userConfiguredElementTypoScript The configuration array
-     * @param string $elementType The element type (e.g BUTTON)
-     * @return void
-     */
-    protected function addChildElement(Element $element, array $userConfiguredElementTypoScript, $elementType = '')
-    {
-        $childElement = $this->createElementObject();
-        $childElement->setParentElement($element);
-        $element->addChildElement($childElement);
-        $this->reviveElement($childElement, $userConfiguredElementTypoScript, $elementType);
-    }
-
-    /**
-     * Set the htmlAttributes and the additionalAttributes
-     * Remap htmlAttributes to additionalAttributes if needed
-     *
-     * @param ElementBuilder $elementBuilder
-     * @param Element $element
-     * @return void
-     */
-    protected function setAttributes(ElementBuilder $elementBuilder, Element $element)
-    {
-        $htmlAttributes = $this->typoScriptRepository->getModelDefinedHtmlAttributes($element->getElementType());
-        $elementBuilder->setHtmlAttributes($htmlAttributes);
-        $elementBuilder->setHtmlAttributeWildcards();
-        $elementBuilder->overlayUserdefinedHtmlAttributeValues();
-        $elementBuilder->setNameAndId();
-        $elementBuilder->overlayFixedHtmlAttributeValues();
-        // remove all NULL values
-        $htmlAttributes = array_filter($elementBuilder->getHtmlAttributes());
-
-        $elementBuilder->setHtmlAttributes($htmlAttributes);
-        $elementBuilder->moveHtmlAttributesToAdditionalArguments();
-        $elementBuilder->setViewHelperDefaulArgumentsToAdditionalArguments();
-        $elementBuilder->moveAllOtherUserdefinedPropertiesToAdditionalArguments();
-        $htmlAttributes = $elementBuilder->getHtmlAttributes();
-        $userConfiguredElementTypoScript = $elementBuilder->getUserConfiguredElementTyposcript();
-        $additionalArguments = $elementBuilder->getAdditionalArguments();
-        $element->setHtmlAttributes($htmlAttributes);
-        $additionalArguments = $this->typoScriptService->convertTypoScriptArrayToPlainArray($additionalArguments);
-        $additionalArguments['prefix'] = $this->configuration->getPrefix();
-        $element->setAdditionalArguments($additionalArguments);
-        $this->handleIncomingValues($element, $userConfiguredElementTypoScript);
-
-        if (
-            $element->getElementType() === 'FORM'
-            && $this->getControllerAction() === 'show'
-        ) {
-            if (empty($element->getHtmlAttribute('action'))) {
-                if (
-                    $element->getAdditionalArgument('confirmation')
-                    && (int)$element->getAdditionalArgument('confirmation') === 1
-                ) {
-                    $element->setAdditionalArgument('action', 'confirmation');
-                } else {
-                    $element->setAdditionalArgument('action', 'process');
-                }
-            } else {
-                $element->setAdditionalArgument('pageUid', $element->getHtmlAttribute('action'));
-                $element->setAdditionalArgument('action', null);
-            }
-        }
-
-        // needed if confirmation page is enabled
-        if (
-            $this->sessionUtility->getSessionData($element->getName())
-            && $element->getAdditionalArgument('uploadedFiles') === null
-        ) {
-            $element->setAdditionalArgument('uploadedFiles', $this->sessionUtility->getSessionData($element->getName()));
-        }
-    }
-
-    /**
-     * Handles the incoming form data
-     *
-     * @param Element $element
-     * @param array $userConfiguredElementTypoScript
-     * @return array
-     */
-    protected function handleIncomingValues(Element $element, array $userConfiguredElementTypoScript)
-    {
-        if (!$this->getIncomingData()) {
-            return;
-        }
-        $elementName = $element->getName();
-        if ($element->getHtmlAttribute('value') !== null) {
-            $modelValue = $element->getHtmlAttribute('value');
-        } else {
-            $modelValue = $element->getAdditionalArgument('value');
-        }
-
-        if ($this->getIncomingData()->getIncomingField($elementName) !== null) {
-            /* filter values and set it back to incoming fields */
-            $filters = isset($userConfiguredElementTypoScript['filters.']) ? $userConfiguredElementTypoScript['filters.'] : [];
-            if (!empty($filters)) {
-                $keys = ArrayUtility::filterAndSortByNumericKeys($filters);
-                foreach ($keys as $key) {
-                    $class = $userConfiguredElementTypoScript['filters.'][$key];
-                    if (
-                        (int)$key
-                        && strpos($key, '.') === false
-                    ) {
-                        $filterArguments = $userConfiguredElementTypoScript['filters.'][$key . '.'];
-                        $filterClassName = $this->typoScriptRepository->getRegisteredClassName((string)$class, 'registeredFilters');
-                        if ($filterClassName !== null) {
-                            // toDo: handel array values
-                            if (is_string($this->getIncomingData()->getIncomingField($elementName))) {
-                                if (is_null($filterArguments)) {
-                                    $filter = $this->objectManager->get($filterClassName);
-                                } else {
-                                    $filter = $this->objectManager->get($filterClassName, $filterArguments);
-                                }
-                                if ($filter) {
-                                    $value = $filter->filter($this->getIncomingData()->getIncomingField($elementName));
-                                    $this->getIncomingData()->setIncomingField($elementName, $value);
-                                } else {
-                                    throw new \RuntimeException('Class "' . $filterClassName . '" could not be loaded.', 1476122052);
-                                }
-                            }
-                        } else {
-                            throw new \RuntimeException('Class "' . $filterClassName . '" not registered via TypoScript.', 1476048485);
-                        }
-                    }
-                }
-            }
-
-            if ($element->getHtmlAttribute('value') !== null) {
-                $element->setHtmlAttribute('value', $this->getIncomingData()->getIncomingField($elementName));
-            } else {
-                $element->setAdditionalArgument('value', $this->getIncomingData()->getIncomingField($elementName));
-            }
-        }
-        $this->signalSlotDispatcher->dispatch(
-            __CLASS__,
-            'txFormHandleIncomingValues',
-            [
-                $element,
-                $this->getIncomingData(),
-                $modelValue,
-                $this
-            ]
-        );
-    }
-
-    /**
-     * Set the rendered mandatory message
-     * and the validation error message if available
-     *
-     * @param Element $element
-     * @return void
-     */
-    protected function setValidationMessages(Element $element)
-    {
-        $elementName = $element->getName();
-        $mandatoryMessages = $this->validationBuilder->getMandatoryValidationMessagesByElementName($elementName);
-        $element->setMandatoryValidationMessages($mandatoryMessages);
-        if (
-            $this->getValidationErrors()
-            && $this->getValidationErrors()->forProperty($elementName)->hasErrors()
-        ) {
-            /** @var \TYPO3\CMS\Extbase\Error\Error[] $errors */
-            $errors = $this->getValidationErrors()->forProperty($elementName)->getErrors();
-            $errorMessages = [];
-            foreach ($errors as $error) {
-                $errorMessages[] = $error->getMessage();
-            }
-            $element->setValidationErrorMessages($errorMessages);
-        }
-    }
-
-    /**
-     * Return the form prefix
-     *
-     * @return string
-     */
-    public function getFormPrefix()
-    {
-        return $this->configuration->getPrefix();
-    }
-
-    /**
-     * TRUE if the content element rendering should be disabled.
-     *
-     * @return bool
-     */
-    public function getDisableContentElementRendering()
-    {
-        return !$this->configuration->getContentElementRendering();
-    }
-
-    /**
-     * TRUE if the content element rendering should be disabled.
-     *
-     * @return string
-     */
-    public function getControllerAction()
-    {
-        return $this->controllerContext->getRequest()->getControllerActionName();
-    }
-
-    /**
-     * Get the incoming flat form data
-     *
-     * @return ValidationElement
-     */
-    public function getIncomingData()
-    {
-        return $this->controllerContext->getValidationElement();
-    }
-
-    /**
-     * Set the validation errors
-     *
-     * @param \TYPO3\CMS\Extbase\Error\Result $validationErrors
-     * @return void
-     */
-    public function setValidationErrors(\TYPO3\CMS\Extbase\Error\Result $validationErrors)
-    {
-        $this->validationErrors = $validationErrors;
-    }
-
-    /**
-     * Get the validation errors
-     *
-     * @return NULL|\TYPO3\CMS\Extbase\Error\Result
-     */
-    public function getValidationErrors()
-    {
-        return $this->validationErrors;
-    }
-}
diff --git a/typo3/sysext/form/Classes/Domain/Builder/ValidationBuilder.php b/typo3/sysext/form/Classes/Domain/Builder/ValidationBuilder.php
deleted file mode 100644 (file)
index f56bccc..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-<?php
-namespace TYPO3\CMS\Form\Domain\Builder;
-
-/*
- * 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!
- */
-
-use TYPO3\CMS\Core\Utility\ArrayUtility;
-use TYPO3\CMS\Form\Domain\Model\Configuration;
-use TYPO3\CMS\Form\Domain\Validator\AbstractValidator;
-use TYPO3\CMS\Form\Utility\FormUtility;
-
-/**