typo3-typescript-sources 13.4.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/sync-and-publish.yml +265 -0
- package/.last-synced-tag +1 -0
- package/LICENSE.txt +339 -0
- package/README-TYPO3.md +166 -0
- package/README.md +28 -0
- package/adminpanel/admin-panel.ts +375 -0
- package/adminpanel/modules/cache.ts +27 -0
- package/adminpanel/modules/preview.ts +75 -0
- package/backend/action-button/abstract-action.ts +22 -0
- package/backend/action-button/deferred-action.ts +41 -0
- package/backend/action-button/immediate-action.ts +31 -0
- package/backend/action-dispatcher.ts +104 -0
- package/backend/ajax-data-handler/message-interface.ts +18 -0
- package/backend/ajax-data-handler/response-interface.ts +20 -0
- package/backend/ajax-data-handler.ts +214 -0
- package/backend/backend-exception.ts +22 -0
- package/backend/broadcast-message.ts +50 -0
- package/backend/broadcast-service.ts +52 -0
- package/backend/browse-database.ts +38 -0
- package/backend/clear-cache.ts +88 -0
- package/backend/clipboard-panel.ts +240 -0
- package/backend/close-current-window.ts +2 -0
- package/backend/code-editor/autocomplete/completion-result.ts +105 -0
- package/backend/code-editor/autocomplete/ts-code-completion.ts +142 -0
- package/backend/code-editor/autocomplete/ts-parser.ts +485 -0
- package/backend/code-editor/autocomplete/ts-ref.ts +164 -0
- package/backend/code-editor/element/code-mirror-element.ts +282 -0
- package/backend/code-editor/language/typoscript.ts +181 -0
- package/backend/code-editor/stream-parser/typoscript.ts +1600 -0
- package/backend/color-picker.ts +158 -0
- package/backend/color-scheme-switch.ts +179 -0
- package/backend/column-selector-button.ts +302 -0
- package/backend/context-help.ts +68 -0
- package/backend/context-menu-actions.ts +322 -0
- package/backend/context-menu.ts +751 -0
- package/backend/copy-to-clipboard.ts +79 -0
- package/backend/date-time-picker.ts +270 -0
- package/backend/document-save-actions.ts +159 -0
- package/backend/drag-tooltip.ts +285 -0
- package/backend/drag-uploader.ts +914 -0
- package/backend/element/alert-element.ts +116 -0
- package/backend/element/dispatch-modal-button.ts +50 -0
- package/backend/element/draggable-resizable-element.ts +249 -0
- package/backend/element/editable-page-title.ts +306 -0
- package/backend/element/icon-element.ts +84 -0
- package/backend/element/immediate-action-element.ts +89 -0
- package/backend/element/pagination.ts +59 -0
- package/backend/element/progress-bar-element.ts +172 -0
- package/backend/element/progress-tracker-element.ts +119 -0
- package/backend/element/pseudo-button.ts +58 -0
- package/backend/element/spinner-element.ts +51 -0
- package/backend/element/thumbnail-element.ts +80 -0
- package/backend/element-browser.ts +182 -0
- package/backend/enum/data-transfer-types.ts +21 -0
- package/backend/enum/icon-types.ts +31 -0
- package/backend/enum/key-types.ts +27 -0
- package/backend/enum/severity.ts +20 -0
- package/backend/enum/viewport/scaffold-identifier.ts +24 -0
- package/backend/event/client-request.ts +25 -0
- package/backend/event/consumable.ts +18 -0
- package/backend/event/consumer-scope.ts +54 -0
- package/backend/event/event-dispatcher.ts +26 -0
- package/backend/event/interaction-request-assignment.ts +24 -0
- package/backend/event/interaction-request-map.ts +75 -0
- package/backend/event/interaction-request.ts +48 -0
- package/backend/event/trigger-request.ts +56 -0
- package/backend/form/submit-interceptor.ts +66 -0
- package/backend/form-engine/container/files-control-container.ts +716 -0
- package/backend/form-engine/container/flex-form-container-container.ts +166 -0
- package/backend/form-engine/container/flex-form-section-container.ts +210 -0
- package/backend/form-engine/container/inline-control-container.ts +1230 -0
- package/backend/form-engine/container/site-language-container.ts +616 -0
- package/backend/form-engine/element/abstract-sortable-select-items.ts +186 -0
- package/backend/form-engine/element/category-element.ts +160 -0
- package/backend/form-engine/element/color-element.ts +81 -0
- package/backend/form-engine/element/datetime-element.ts +66 -0
- package/backend/form-engine/element/extra/char-counter.ts +112 -0
- package/backend/form-engine/element/extra/select-box-filter.ts +85 -0
- package/backend/form-engine/element/folder-element.ts +66 -0
- package/backend/form-engine/element/group-element.ts +47 -0
- package/backend/form-engine/element/json-element.ts +52 -0
- package/backend/form-engine/element/link-element.ts +121 -0
- package/backend/form-engine/element/mfa-info-element.ts +169 -0
- package/backend/form-engine/element/modifier/resizable.ts +27 -0
- package/backend/form-engine/element/modifier/tabbable.ts +29 -0
- package/backend/form-engine/element/online-media-form-element.ts +65 -0
- package/backend/form-engine/element/password-element.ts +71 -0
- package/backend/form-engine/element/select-multiple-side-by-side-element.ts +83 -0
- package/backend/form-engine/element/select-single-element.ts +82 -0
- package/backend/form-engine/element/select-tree-element.ts +148 -0
- package/backend/form-engine/element/select-tree-toolbar.ts +118 -0
- package/backend/form-engine/element/select-tree.ts +210 -0
- package/backend/form-engine/element/slug-element.ts +243 -0
- package/backend/form-engine/element/suggest/result-container.ts +118 -0
- package/backend/form-engine/element/suggest/result-item.ts +90 -0
- package/backend/form-engine/element/table-permission-element.ts +101 -0
- package/backend/form-engine/element/table-wizard-element.ts +427 -0
- package/backend/form-engine/element/text-element.ts +52 -0
- package/backend/form-engine/element/text-table-element.ts +31 -0
- package/backend/form-engine/field-control/add-record.ts +40 -0
- package/backend/form-engine/field-control/edit-popup.ts +64 -0
- package/backend/form-engine/field-control/insert-clipboard.ts +50 -0
- package/backend/form-engine/field-control/link-popup.ts +53 -0
- package/backend/form-engine/field-control/list-module.ts +40 -0
- package/backend/form-engine/field-control/password-generator.ts +102 -0
- package/backend/form-engine/field-control/reset-selection.ts +48 -0
- package/backend/form-engine/field-wizard/localization-state-selector.ts +67 -0
- package/backend/form-engine/field-wizard/value-picker.ts +123 -0
- package/backend/form-engine/field-wizard/value-slider.ts +86 -0
- package/backend/form-engine/inline-relation/ajax-dispatcher.ts +124 -0
- package/backend/form-engine/inline-relation/inline-response-interface.ts +41 -0
- package/backend/form-engine-link-browser-adapter.ts +129 -0
- package/backend/form-engine-review.ts +155 -0
- package/backend/form-engine-suggest.ts +133 -0
- package/backend/form-engine-validation.ts +686 -0
- package/backend/form-engine.ts +1391 -0
- package/backend/global-event-handler.ts +252 -0
- package/backend/grid-editor.ts +1077 -0
- package/backend/hashing/md5.ts +252 -0
- package/backend/helper.ts +24 -0
- package/backend/hotkeys/hotkey-storage.ts +63 -0
- package/backend/hotkeys.ts +216 -0
- package/backend/icons.ts +236 -0
- package/backend/image-manipulation.ts +885 -0
- package/backend/info-window.ts +46 -0
- package/backend/input/clearable.ts +128 -0
- package/backend/input/index.d.ts +8 -0
- package/backend/java-script-module-import-event-handler.ts +19 -0
- package/backend/key-bindings.ts +42 -0
- package/backend/layout-module/drag-drop.ts +359 -0
- package/backend/layout-module/paste.ts +165 -0
- package/backend/link-browser.ts +89 -0
- package/backend/live-search/element/backend-search.ts +34 -0
- package/backend/live-search/element/hint.ts +33 -0
- package/backend/live-search/element/provider/default-result-item.ts +52 -0
- package/backend/live-search/element/provider/page-provider-result-item.ts +52 -0
- package/backend/live-search/element/result/item/action/action-container.ts +135 -0
- package/backend/live-search/element/result/item/action/action.ts +56 -0
- package/backend/live-search/element/result/item/item-container.ts +224 -0
- package/backend/live-search/element/result/item/item.ts +74 -0
- package/backend/live-search/element/result/result-container.ts +110 -0
- package/backend/live-search/element/result/result-detail-container.ts +50 -0
- package/backend/live-search/element/result/result-pagination.ts +122 -0
- package/backend/live-search/element/search-option-item.ts +70 -0
- package/backend/live-search/live-search-configurator.ts +54 -0
- package/backend/live-search/live-search-shortcut.ts +29 -0
- package/backend/live-search/result-types/backend-module-result-type.ts +8 -0
- package/backend/live-search/result-types/default-result-type.ts +21 -0
- package/backend/live-search/result-types/page-result-type.ts +23 -0
- package/backend/localization.ts +390 -0
- package/backend/login-refresh.ts +525 -0
- package/backend/login.ts +179 -0
- package/backend/mail-link-handler.ts +45 -0
- package/backend/modal-interface.ts +19 -0
- package/backend/modal.ts +685 -0
- package/backend/module/iframe.ts +125 -0
- package/backend/module/router.ts +275 -0
- package/backend/module-menu.ts +550 -0
- package/backend/module.ts +133 -0
- package/backend/multi-record-selection-action.ts +44 -0
- package/backend/multi-record-selection-delete-action.ts +108 -0
- package/backend/multi-record-selection-edit-action.ts +56 -0
- package/backend/multi-record-selection.ts +468 -0
- package/backend/multi-step-wizard.ts +568 -0
- package/backend/new-content-element-wizard-button.ts +51 -0
- package/backend/new-multiple-pages.ts +108 -0
- package/backend/new-record-wizard.ts +680 -0
- package/backend/notification.ts +366 -0
- package/backend/offset.ts +40 -0
- package/backend/online-media.ts +110 -0
- package/backend/page-actions.ts +91 -0
- package/backend/page-link-handler.ts +51 -0
- package/backend/pagetsconfig/pagetsconfig-includes.ts +77 -0
- package/backend/popover.ts +165 -0
- package/backend/record-download-button.ts +104 -0
- package/backend/record-link-handler.ts +31 -0
- package/backend/record-search.ts +44 -0
- package/backend/recordlist.ts +230 -0
- package/backend/resource/resource.ts +35 -0
- package/backend/security/element/csp-reports.ts +406 -0
- package/backend/security/element/sudo-mode.ts +249 -0
- package/backend/security/sudo-mode-interceptor.ts +19 -0
- package/backend/settings/editor/editable-setting.ts +231 -0
- package/backend/settings/editor.ts +451 -0
- package/backend/settings/enum/settings-mode.enum.ts +24 -0
- package/backend/settings/type/base.ts +200 -0
- package/backend/settings/type/bool.ts +56 -0
- package/backend/settings/type/color.ts +64 -0
- package/backend/settings/type/int.ts +85 -0
- package/backend/settings/type/number.ts +61 -0
- package/backend/settings/type/page.ts +100 -0
- package/backend/settings/type/string.ts +77 -0
- package/backend/settings/type/stringlist.ts +87 -0
- package/backend/severity.ts +88 -0
- package/backend/site-inline-actions.ts +32 -0
- package/backend/sortable-table.ts +208 -0
- package/backend/storage/abstract-client-storage.ts +76 -0
- package/backend/storage/browser-session.ts +28 -0
- package/backend/storage/client.ts +28 -0
- package/backend/storage/module-state-storage.ts +118 -0
- package/backend/storage/persistent.ts +204 -0
- package/backend/switch-user.ts +82 -0
- package/backend/tabs.ts +72 -0
- package/backend/telephone-link-handler.ts +40 -0
- package/backend/tests/backend/storage/browser-storage-test.ts +87 -0
- package/backend/tests/backend/storage/client-test.ts +87 -0
- package/backend/tests/backend/utility/dom-helper-test.ts +51 -0
- package/backend/tests/backend-exception-test.ts +28 -0
- package/backend/tests/element/immediate-action-element-test.ts +81 -0
- package/backend/tests/form-engine-validation-test.ts +304 -0
- package/backend/tests/grid-editor-test.ts +29 -0
- package/backend/tests/hashing/md5Test.ts +28 -0
- package/backend/tests/icons-test.ts +23 -0
- package/backend/tests/notification-test.ts +161 -0
- package/backend/tests/popover-test.ts +83 -0
- package/backend/toolbar/clear-cache-menu.ts +88 -0
- package/backend/toolbar/live-search.ts +284 -0
- package/backend/toolbar/shortcut-menu.ts +254 -0
- package/backend/toolbar/system-information-menu.ts +161 -0
- package/backend/toolbar.ts +41 -0
- package/backend/tree/file-storage-browser.ts +194 -0
- package/backend/tree/file-storage-tree-container.ts +465 -0
- package/backend/tree/file-storage-tree.ts +42 -0
- package/backend/tree/page-browser.ts +272 -0
- package/backend/tree/page-tree-element.ts +602 -0
- package/backend/tree/page-tree.ts +152 -0
- package/backend/tree/tree-module-state.ts +159 -0
- package/backend/tree/tree-node-toggle.ts +31 -0
- package/backend/tree/tree-node.ts +97 -0
- package/backend/tree/tree-toolbar.ts +117 -0
- package/backend/tree/tree.ts +1595 -0
- package/backend/url-link-handler.ts +36 -0
- package/backend/user-pass-login.ts +255 -0
- package/backend/user-settings-manager.ts +189 -0
- package/backend/utility/collapse-state-persister.ts +205 -0
- package/backend/utility/collapse-state-search.ts +183 -0
- package/backend/utility/dom-helper.ts +91 -0
- package/backend/utility/drag-drop-utility.ts +47 -0
- package/backend/utility/message-utility.ts +45 -0
- package/backend/utility/top-level-module-import.ts +32 -0
- package/backend/utility.ts +194 -0
- package/backend/viewport/abstract-container.ts +22 -0
- package/backend/viewport/content-container.ts +98 -0
- package/backend/viewport/loader.ts +28 -0
- package/backend/viewport/navigation-container.ts +119 -0
- package/backend/viewport/resizable-navigation.ts +176 -0
- package/backend/viewport/toolbar.ts +27 -0
- package/backend/viewport/topbar.ts +39 -0
- package/backend/viewport.ts +46 -0
- package/backend/window-manager.ts +84 -0
- package/backend/wizard/move-content-element.ts +107 -0
- package/backend/wizard/move-page.ts +74 -0
- package/backend/wizard.ts +331 -0
- package/belog/backend-log.ts +88 -0
- package/beuser/backend-user-listing.ts +40 -0
- package/beuser/permissions.ts +291 -0
- package/core/ajax/ajax-request-types.ts +15 -0
- package/core/ajax/ajax-request.ts +202 -0
- package/core/ajax/ajax-response.ts +57 -0
- package/core/ajax/input-transformer.ts +92 -0
- package/core/ajax/simple-response-interface.ts +5 -0
- package/core/authentication/mfa-provider/totp.ts +54 -0
- package/core/cache/dedupe-async-task.ts +95 -0
- package/core/directive/markdown.ts +82 -0
- package/core/directive/nl2br.ts +16 -0
- package/core/document-service.ts +35 -0
- package/core/event/debounce-event.ts +40 -0
- package/core/event/event-interface.ts +24 -0
- package/core/event/regular-event.ts +58 -0
- package/core/event/request-animation-frame-event.ts +42 -0
- package/core/event/throttle-event.ts +54 -0
- package/core/java-script-item-handler.ts +29 -0
- package/core/java-script-item-processor.ts +171 -0
- package/core/lit-helper.ts +126 -0
- package/core/literals.ts +17 -0
- package/core/referrer-refresh.ts +2 -0
- package/core/security-utility.ts +89 -0
- package/core/tests/ajax/ajax-request-test.ts +290 -0
- package/core/tests/ajax/input-transformer-test.ts +64 -0
- package/core/tests/cache/dedupe-async-task-test.ts +152 -0
- package/core/tests/event/throttle-event-test.ts +47 -0
- package/core/tests/literals-test.ts +24 -0
- package/core/tests/security-utility-test.ts +50 -0
- package/core/utility/types.ts +9 -0
- package/dashboard/chart-initializer.ts +136 -0
- package/dashboard/dashboard.ts +1487 -0
- package/extensionmanager/distribution-image.ts +55 -0
- package/extensionmanager/main.ts +291 -0
- package/extensionmanager/repository.ts +195 -0
- package/extensionmanager/update.ts +118 -0
- package/extensionmanager/upload-form.ts +42 -0
- package/filelist/browse-files.ts +148 -0
- package/filelist/browse-folders.ts +94 -0
- package/filelist/context-menu-actions.ts +335 -0
- package/filelist/create-folder.ts +69 -0
- package/filelist/file-delete.ts +69 -0
- package/filelist/file-list-actions.ts +132 -0
- package/filelist/file-list-dragdrop.ts +139 -0
- package/filelist/file-list-rename-handler.ts +128 -0
- package/filelist/file-list-transfer-handler.ts +138 -0
- package/filelist/file-list.ts +396 -0
- package/filelist/file-replace.ts +37 -0
- package/filelist/linkbrowser-file-handler.ts +94 -0
- package/filelist/linkbrowser-folder-handler.ts +74 -0
- package/filelist/rename-file.ts +109 -0
- package/form/backend/form-editor/component/property-grid-editor.ts +340 -0
- package/form/backend/form-editor/core.ts +2104 -0
- package/form/backend/form-editor/helper.ts +226 -0
- package/form/backend/form-editor/inspector-component.ts +2323 -0
- package/form/backend/form-editor/mediator.ts +941 -0
- package/form/backend/form-editor/modals-component.ts +433 -0
- package/form/backend/form-editor/stage-component.ts +908 -0
- package/form/backend/form-editor/tree-component.ts +548 -0
- package/form/backend/form-editor/view-model.ts +1343 -0
- package/form/backend/form-editor.ts +846 -0
- package/form/backend/form-manager/main.ts +39 -0
- package/form/backend/form-manager/view-model.ts +789 -0
- package/form/backend/form-manager.ts +180 -0
- package/form/backend/helper.ts +60 -0
- package/form/frontend/date-picker.ts +38 -0
- package/frontend/default_frontend.ts +82 -0
- package/impexp/context-menu-actions.ts +50 -0
- package/impexp/import-export.ts +62 -0
- package/indexed-search/pagination.ts +26 -0
- package/indexed-search/statistics.ts +50 -0
- package/info/translation-status.ts +48 -0
- package/install/ajax/ajax-queue.ts +83 -0
- package/install/init-install.ts +2 -0
- package/install/init-installer.ts +2 -0
- package/install/install.ts +25 -0
- package/install/installer.ts +458 -0
- package/install/message-interface.ts +18 -0
- package/install/module/abstract-inline-module.ts +27 -0
- package/install/module/abstract-interactable-module.ts +107 -0
- package/install/module/environment/environment-check.ts +92 -0
- package/install/module/environment/folder-structure.ts +145 -0
- package/install/module/environment/image-processing.ts +141 -0
- package/install/module/environment/mail-test.ts +127 -0
- package/install/module/environment/php-info.ts +50 -0
- package/install/module/environment/system-information.ts +50 -0
- package/install/module/maintenance/cache.ts +59 -0
- package/install/module/maintenance/clear-tables.ts +134 -0
- package/install/module/maintenance/clear-typo3temp-files.ts +137 -0
- package/install/module/maintenance/create-admin.ts +126 -0
- package/install/module/maintenance/database-analyzer.ts +266 -0
- package/install/module/maintenance/dump-autoload.ts +58 -0
- package/install/module/maintenance/language-packs.ts +338 -0
- package/install/module/maintenance/reset-backend-user-uc.ts +58 -0
- package/install/module/password-strength.ts +56 -0
- package/install/module/settings/change-install-tool-password.ts +101 -0
- package/install/module/settings/extension-configuration.ts +224 -0
- package/install/module/settings/features.ts +102 -0
- package/install/module/settings/local-configuration.ts +316 -0
- package/install/module/settings/presets.ts +147 -0
- package/install/module/settings/system-maintainer.ts +111 -0
- package/install/module/upgrade/core-update.ts +255 -0
- package/install/module/upgrade/extension-compat-tester.ts +195 -0
- package/install/module/upgrade/extension-scanner.ts +381 -0
- package/install/module/upgrade/tca-ext-tables-check.ts +93 -0
- package/install/module/upgrade/tca-migrations-check.ts +101 -0
- package/install/module/upgrade/upgrade-docs.ts +310 -0
- package/install/module/upgrade/upgrade-wizards.ts +612 -0
- package/install/renderable/clearable.ts +113 -0
- package/install/renderable/flash-message.ts +64 -0
- package/install/renderable/info-box.ts +66 -0
- package/install/renderable/language-packs.ts +304 -0
- package/install/renderable/offset-group.ts +38 -0
- package/install/renderable/severity.ts +49 -0
- package/install/renderable/wrap-group.ts +36 -0
- package/install/router.ts +468 -0
- package/linkvalidator/linkvalidator-modal.ts +45 -0
- package/linkvalidator/linkvalidator.ts +101 -0
- package/lowlevel/query-generator.ts +132 -0
- package/lowlevel/reference-index.ts +44 -0
- package/opendocs/toolbar/opendocs-menu.ts +117 -0
- package/package.json +34 -0
- package/recycler/recycler.ts +539 -0
- package/redirects/event-handler.ts +108 -0
- package/redirects/form-engine-evaluation.ts +34 -0
- package/redirects/redirects-module.ts +58 -0
- package/rte-ckeditor/ckeditor5.ts +402 -0
- package/rte-ckeditor/css-prefixer.ts +94 -0
- package/rte-ckeditor/legacy/ckeditor5-bundle.ts +17 -0
- package/rte-ckeditor/legacy/ckeditor5-inspector.ts +2 -0
- package/rte-ckeditor/plugin/typo3-link.ts +810 -0
- package/rte-ckeditor/plugin/whitespace.ts +114 -0
- package/rte-ckeditor/rte-link-browser.ts +112 -0
- package/rte-ckeditor/tests/css-prefixer-test.ts +314 -0
- package/scheduler/scheduler-add-group.ts +119 -0
- package/scheduler/scheduler-editable-group-name.ts +307 -0
- package/scheduler/scheduler-sortable-groups.ts +59 -0
- package/scheduler/scheduler.ts +466 -0
- package/setup/setup-module.ts +122 -0
- package/styleguide/checkbox-demo.ts +5 -0
- package/styleguide/element/theme-switcher-element.ts +101 -0
- package/styleguide/filter.ts +22 -0
- package/styleguide/find-icons.ts +78 -0
- package/styleguide/processing-indicator.ts +78 -0
- package/styleguide/render-notifications.ts +64 -0
- package/sys-note/element/delete-button.ts +78 -0
- package/tstemplate/constant-editor.ts +64 -0
- package/tstemplate/information-module.ts +31 -0
- package/tstemplate/template-analyzer.ts +77 -0
- package/viewpage/main.ts +253 -0
- package/workspaces/backend.ts +979 -0
- package/workspaces/preview.ts +232 -0
- package/workspaces/renderable/comment-view.ts +79 -0
- package/workspaces/renderable/diff-view.ts +58 -0
- package/workspaces/renderable/history-view.ts +97 -0
- package/workspaces/renderable/record-information.ts +118 -0
- package/workspaces/renderable/record-table.ts +355 -0
- package/workspaces/renderable/send-to-stage-form.ts +108 -0
- package/workspaces/toolbar/workspaces-menu.ts +190 -0
- package/workspaces/utility/icon-helper.ts +57 -0
- package/workspaces/workspaces.ts +136 -0
|
@@ -0,0 +1,846 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of the TYPO3 CMS project.
|
|
3
|
+
*
|
|
4
|
+
* It is free software; you can redistribute it and/or modify it under
|
|
5
|
+
* the terms of the GNU General Public License, either version 2
|
|
6
|
+
* of the License, or any later version.
|
|
7
|
+
*
|
|
8
|
+
* For the full copyright and license information, please read the
|
|
9
|
+
* LICENSE.txt file that was distributed with this source code.
|
|
10
|
+
*
|
|
11
|
+
* The TYPO3 project - inspiring people to share!
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Module: @typo3/form/backend/form-editor
|
|
16
|
+
*/
|
|
17
|
+
import $ from 'jquery';
|
|
18
|
+
import Notification from '@typo3/backend/notification';
|
|
19
|
+
import * as Core from '@typo3/form/backend/form-editor/core';
|
|
20
|
+
import type { JavaScriptItemPayload } from '@typo3/core/java-script-item-processor';
|
|
21
|
+
import type {
|
|
22
|
+
ApplicationStateStack,
|
|
23
|
+
AjaxRequests,
|
|
24
|
+
Endpoints,
|
|
25
|
+
CollectionElementConfiguration,
|
|
26
|
+
CollectionEntry,
|
|
27
|
+
DataBackend,
|
|
28
|
+
Factory,
|
|
29
|
+
FormEditorDefinitions,
|
|
30
|
+
FormElement,
|
|
31
|
+
FormElementDefinition,
|
|
32
|
+
FormElementPropertyValidatorDefinition,
|
|
33
|
+
PublisherSubscriber,
|
|
34
|
+
PropertyCollectionElement,
|
|
35
|
+
PropertyValidationService,
|
|
36
|
+
Repository,
|
|
37
|
+
RootFormElement,
|
|
38
|
+
Utility,
|
|
39
|
+
ValidationResults,
|
|
40
|
+
ValidationResultsWithPath,
|
|
41
|
+
ValidationResultsRecursive,
|
|
42
|
+
Validator
|
|
43
|
+
} from '@typo3/form/backend/form-editor/core';
|
|
44
|
+
|
|
45
|
+
const assert = Core.assert;
|
|
46
|
+
|
|
47
|
+
type AdditionalViewModelModules = JavaScriptItemPayload[];
|
|
48
|
+
|
|
49
|
+
type ViewModel = typeof import('./form-editor/view-model');
|
|
50
|
+
type Mediator = typeof import('./form-editor/mediator');
|
|
51
|
+
|
|
52
|
+
export type FormEditorConfiguration = {
|
|
53
|
+
prototypeName: string,
|
|
54
|
+
endpoints: Endpoints,
|
|
55
|
+
formEditorDefinitions: FormEditorDefinitions,
|
|
56
|
+
formDefinition: FormElementDefinition,
|
|
57
|
+
formPersistenceIdentifier: string,
|
|
58
|
+
additionalViewModelModules: AdditionalViewModelModules,
|
|
59
|
+
maximumUndoSteps: number
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export class FormEditor {
|
|
63
|
+
private isRunning: boolean = false;
|
|
64
|
+
private unsavedContent: boolean = false;
|
|
65
|
+
private readonly configuration: FormEditorConfiguration;
|
|
66
|
+
private readonly mediator: Mediator;
|
|
67
|
+
private readonly viewModel: ViewModel;
|
|
68
|
+
|
|
69
|
+
public constructor(
|
|
70
|
+
configuration: FormEditorConfiguration,
|
|
71
|
+
mediator: Mediator,
|
|
72
|
+
viewModel: ViewModel
|
|
73
|
+
) {
|
|
74
|
+
this.configuration = configuration || {} as FormEditorConfiguration;
|
|
75
|
+
this.mediator = mediator;
|
|
76
|
+
this.viewModel = viewModel;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public getPublisherSubscriber(): PublisherSubscriber {
|
|
80
|
+
return Core.getPublisherSubscriber();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public undoApplicationState(): void {
|
|
84
|
+
this.getApplicationStateStack().incrementCurrentStackPointer();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public redoApplicationState(): void {
|
|
88
|
+
this.getApplicationStateStack().decrementCurrentStackPointer();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public getMaximalApplicationStates(): number {
|
|
92
|
+
return this.getApplicationStateStack().getMaximalStackSize();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
public getCurrentApplicationStates(): number {
|
|
96
|
+
return this.getApplicationStateStack().getCurrentStackSize();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
public getCurrentApplicationStatePosition(): number {
|
|
100
|
+
return this.getApplicationStateStack().getCurrentStackPointer();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @internal
|
|
105
|
+
* @throws 1519855175
|
|
106
|
+
*/
|
|
107
|
+
public setFormDefinition(formDefinition: FormElementDefinition): void {
|
|
108
|
+
assert('object' === $.type(formDefinition), 'Invalid parameter "formDefinition"', 1519855175);
|
|
109
|
+
this.getApplicationStateStack().setCurrentState('formDefinition', this.getFactory().createFormElement(formDefinition, undefined, undefined, true));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* @throws 1475378543
|
|
114
|
+
*/
|
|
115
|
+
public getRunningAjaxRequest<T extends keyof AjaxRequests>(
|
|
116
|
+
type: keyof AjaxRequests
|
|
117
|
+
): AjaxRequests[T] | null {
|
|
118
|
+
assert(this.getUtility().isNonEmptyString(type), 'Invalid parameter "type"', 1475378543);
|
|
119
|
+
return Core.getRunningAjaxRequest(type);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
public getUtility(): Utility {
|
|
123
|
+
return Core.getUtility();
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
public assert(test: boolean|(() => boolean), message: string, messageCode: number): void {
|
|
127
|
+
this.getUtility().assert(test, message, messageCode);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
public buildPropertyPath(
|
|
131
|
+
propertyPath: string,
|
|
132
|
+
collectionElementIdentifier?: string,
|
|
133
|
+
collectionName?: keyof FormEditorDefinitions,
|
|
134
|
+
_formElement?: string | FormElement,
|
|
135
|
+
allowEmptyReturnValue?: boolean
|
|
136
|
+
): string {
|
|
137
|
+
if (this.getUtility().isUndefinedOrNull(_formElement)) {
|
|
138
|
+
_formElement = this.getCurrentlySelectedFormElement();
|
|
139
|
+
}
|
|
140
|
+
const formElement = this.getRepository().findFormElement(_formElement);
|
|
141
|
+
return this.getUtility().buildPropertyPath(
|
|
142
|
+
propertyPath,
|
|
143
|
+
collectionElementIdentifier,
|
|
144
|
+
collectionName,
|
|
145
|
+
formElement,
|
|
146
|
+
allowEmptyReturnValue
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
public addPropertyValidationValidator(validatorIdentifier: string, func: Validator): void {
|
|
151
|
+
this.getPropertyValidationService().addValidator(validatorIdentifier, func);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
public validateCurrentlySelectedFormElementProperty(
|
|
155
|
+
propertyPath: string
|
|
156
|
+
): ValidationResults {
|
|
157
|
+
return this.validateFormElementProperty(
|
|
158
|
+
this.getCurrentlySelectedFormElement(),
|
|
159
|
+
propertyPath
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
public validateFormElementProperty(
|
|
164
|
+
_formElement: FormElement | string,
|
|
165
|
+
propertyPath: string
|
|
166
|
+
): ValidationResults {
|
|
167
|
+
const formElement = this.getRepository().findFormElement(_formElement);
|
|
168
|
+
return this.getPropertyValidationService().validateFormElementProperty(formElement, propertyPath);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
public validateFormElement(
|
|
172
|
+
_formElement: FormElement | string
|
|
173
|
+
): ValidationResultsWithPath {
|
|
174
|
+
const formElement = this.getRepository().findFormElement(_formElement);
|
|
175
|
+
return this.getPropertyValidationService().validateFormElement(formElement);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
public validationResultsHasErrors(
|
|
179
|
+
validationResults: ValidationResultsRecursive
|
|
180
|
+
): boolean {
|
|
181
|
+
return this.getPropertyValidationService().validationResultsHasErrors(validationResults);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
public validateFormElementRecursive(
|
|
185
|
+
_formElement: FormElement | string,
|
|
186
|
+
returnAfterFirstMatch?: boolean
|
|
187
|
+
): ValidationResultsRecursive {
|
|
188
|
+
const formElement = this.getRepository().findFormElement(_formElement);
|
|
189
|
+
return this.getPropertyValidationService().validateFormElementRecursive(formElement, returnAfterFirstMatch);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* @throws 1475378544
|
|
194
|
+
*/
|
|
195
|
+
public setUnsavedContent(unsavedContent: boolean): void {
|
|
196
|
+
assert('boolean' === $.type(unsavedContent), 'Invalid parameter "unsavedContent"', 1475378544);
|
|
197
|
+
this.unsavedContent = unsavedContent;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
public getUnsavedContent(): boolean {
|
|
201
|
+
return this.unsavedContent;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
public getRootFormElement(): RootFormElement {
|
|
205
|
+
return this.getRepository().getRootFormElement();
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
public getCurrentlySelectedFormElement(): FormElement {
|
|
209
|
+
return this.getRepository().findFormElementByIdentifierPath(this.getApplicationStateStack().getCurrentState('currentlySelectedFormElementIdentifierPath'));
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* @publish core/currentlySelectedFormElementChanged
|
|
214
|
+
*/
|
|
215
|
+
public setCurrentlySelectedFormElement(
|
|
216
|
+
_formElement: FormElement | string,
|
|
217
|
+
doNotRefreshCurrentlySelectedPageIndex?: boolean
|
|
218
|
+
): void {
|
|
219
|
+
doNotRefreshCurrentlySelectedPageIndex = !!doNotRefreshCurrentlySelectedPageIndex;
|
|
220
|
+
|
|
221
|
+
const formElement = this.getRepository().findFormElement(_formElement);
|
|
222
|
+
this.getApplicationStateStack().setCurrentState('currentlySelectedFormElementIdentifierPath', formElement.get('__identifierPath'));
|
|
223
|
+
|
|
224
|
+
if (!doNotRefreshCurrentlySelectedPageIndex) {
|
|
225
|
+
this.refreshCurrentlySelectedPageIndex();
|
|
226
|
+
}
|
|
227
|
+
this.getPublisherSubscriber().publish('core/currentlySelectedFormElementChanged', [formElement]);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* @throws 1475378545
|
|
232
|
+
*/
|
|
233
|
+
public getFormElementByIdentifierPath(identifierPath: string): FormElement {
|
|
234
|
+
assert(this.getUtility().isNonEmptyString(identifierPath), 'Invalid parameter "identifierPath"', 1475378545);
|
|
235
|
+
return this.getRepository().findFormElementByIdentifierPath(identifierPath);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
public isFormElementIdentifierUsed(formElementIdentifier: string): boolean {
|
|
239
|
+
return this.getRepository().isFormElementIdentifierUsed(formElementIdentifier);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
public createAndAddFormElement(
|
|
243
|
+
formElementType: string,
|
|
244
|
+
referenceFormElement?: FormElement | string,
|
|
245
|
+
disablePublishersOnSet?: boolean
|
|
246
|
+
): FormElement {
|
|
247
|
+
const formElement = this.addFormElement(
|
|
248
|
+
this.createFormElement(formElementType, disablePublishersOnSet),
|
|
249
|
+
referenceFormElement,
|
|
250
|
+
disablePublishersOnSet
|
|
251
|
+
);
|
|
252
|
+
formElement.set('renderables', formElement.get('renderables'));
|
|
253
|
+
return formElement;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* @throws 1475434337
|
|
258
|
+
*/
|
|
259
|
+
public addFormElement(
|
|
260
|
+
formElement: FormElement,
|
|
261
|
+
_referenceFormElement?: FormElement | string,
|
|
262
|
+
disablePublishersOnSet?: boolean
|
|
263
|
+
): FormElement {
|
|
264
|
+
this.saveApplicationState();
|
|
265
|
+
|
|
266
|
+
if (this.getUtility().isUndefinedOrNull(_referenceFormElement)) {
|
|
267
|
+
_referenceFormElement = this.getCurrentlySelectedFormElement();
|
|
268
|
+
}
|
|
269
|
+
const referenceFormElement = this.getRepository().findFormElement(_referenceFormElement);
|
|
270
|
+
assert('object' === $.type(formElement), 'Invalid parameter "formElement"', 1475434337);
|
|
271
|
+
return this.getRepository().addFormElement(formElement, referenceFormElement, true, disablePublishersOnSet);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* @throws 1475434336
|
|
276
|
+
* @throws 1475435857
|
|
277
|
+
*/
|
|
278
|
+
public createFormElement(
|
|
279
|
+
formElementType: string,
|
|
280
|
+
disablePublishersOnSet: boolean
|
|
281
|
+
): FormElement {
|
|
282
|
+
assert(this.getUtility().isNonEmptyString(formElementType), 'Invalid parameter "formElementType"', 1475434336);
|
|
283
|
+
|
|
284
|
+
const identifier = this.getRepository().getNextFreeFormElementIdentifier(formElementType);
|
|
285
|
+
const formElementDefinition = this.getFormElementDefinitionByType(formElementType, undefined);
|
|
286
|
+
return this.getFactory().createFormElement({
|
|
287
|
+
type: formElementType,
|
|
288
|
+
identifier: identifier,
|
|
289
|
+
label: formElementDefinition.label || formElementType
|
|
290
|
+
}, undefined, undefined, undefined, disablePublishersOnSet);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
public removeFormElement(
|
|
294
|
+
_formElementToRemove: FormElement | string,
|
|
295
|
+
disablePublishersOnSet?: boolean
|
|
296
|
+
): FormElement {
|
|
297
|
+
this.saveApplicationState();
|
|
298
|
+
|
|
299
|
+
const formElementToRemove = this.getRepository().findFormElement(_formElementToRemove);
|
|
300
|
+
const parentFormElement = formElementToRemove.get('__parentRenderable');
|
|
301
|
+
this.getRepository().removeFormElement(formElementToRemove, true, disablePublishersOnSet);
|
|
302
|
+
return parentFormElement;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* @throws 1475378551
|
|
307
|
+
*/
|
|
308
|
+
public moveFormElement(
|
|
309
|
+
_formElementToMove: FormElement | string,
|
|
310
|
+
position: string,
|
|
311
|
+
_referenceFormElement: FormElement | string,
|
|
312
|
+
disablePublishersOnSet?: boolean
|
|
313
|
+
): FormElement {
|
|
314
|
+
this.saveApplicationState();
|
|
315
|
+
|
|
316
|
+
let formElementToMove = this.getRepository().findFormElement(_formElementToMove);
|
|
317
|
+
const referenceFormElement = this.getRepository().findFormElement(_referenceFormElement);
|
|
318
|
+
|
|
319
|
+
assert('after' === position || 'before' === position || 'inside' === position, 'Invalid position "' + position + '"', 1475378551);
|
|
320
|
+
|
|
321
|
+
formElementToMove = this.getRepository().moveFormElement(formElementToMove, position, referenceFormElement, true);
|
|
322
|
+
disablePublishersOnSet = !!disablePublishersOnSet;
|
|
323
|
+
if (!disablePublishersOnSet) {
|
|
324
|
+
formElementToMove.get('__parentRenderable').set('renderables', formElementToMove.get('__parentRenderable').get('renderables'));
|
|
325
|
+
}
|
|
326
|
+
return formElementToMove;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* @throws 1475378555
|
|
331
|
+
* @throws 1475378556
|
|
332
|
+
* @throws 1475446108
|
|
333
|
+
*/
|
|
334
|
+
public getPropertyCollectionElementConfiguration(
|
|
335
|
+
collectionElementIdentifier: string,
|
|
336
|
+
collectionName: keyof FormEditorDefinitions,
|
|
337
|
+
_formElement?: string | FormElement
|
|
338
|
+
): CollectionEntry {
|
|
339
|
+
let collection, collectionElement;
|
|
340
|
+
if (this.getUtility().isUndefinedOrNull(_formElement)) {
|
|
341
|
+
_formElement = this.getCurrentlySelectedFormElement();
|
|
342
|
+
}
|
|
343
|
+
const formElement = this.getRepository().findFormElement(_formElement);
|
|
344
|
+
|
|
345
|
+
assert(this.getUtility().isNonEmptyString(collectionElementIdentifier), 'Invalid parameter "collectionElementIdentifier"', 1475378555);
|
|
346
|
+
assert(this.getUtility().isNonEmptyString(collectionName), 'Invalid parameter "collectionName"', 1475378556);
|
|
347
|
+
|
|
348
|
+
const formElementDefinition = this.getFormElementDefinitionByType(formElement.get('type'), undefined);
|
|
349
|
+
if (!this.getUtility().isUndefinedOrNull(formElementDefinition.propertyCollections)) {
|
|
350
|
+
collection = formElementDefinition.propertyCollections[collectionName];
|
|
351
|
+
assert(!this.getUtility().isUndefinedOrNull(collection), 'Invalid collection name "' + collectionName + '"', 1475446108);
|
|
352
|
+
collectionElement = this.getRepository().findCollectionElementByIdentifierPath(collectionElementIdentifier, collection);
|
|
353
|
+
// Return a dereferenced object
|
|
354
|
+
return $.extend(true, {}, collectionElement);
|
|
355
|
+
} else {
|
|
356
|
+
return {} as CollectionEntry;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* @throws 1475378557
|
|
362
|
+
* @throws 1475378558
|
|
363
|
+
*/
|
|
364
|
+
public getIndexFromPropertyCollectionElement(
|
|
365
|
+
collectionElementIdentifier: string,
|
|
366
|
+
collectionName: keyof FormEditorDefinitions,
|
|
367
|
+
_formElement?: string | FormElement
|
|
368
|
+
): number {
|
|
369
|
+
if (this.getUtility().isUndefinedOrNull(_formElement)) {
|
|
370
|
+
_formElement = this.getCurrentlySelectedFormElement();
|
|
371
|
+
}
|
|
372
|
+
const formElement = this.getRepository().findFormElement(_formElement);
|
|
373
|
+
|
|
374
|
+
assert(this.getUtility().isNonEmptyString(collectionElementIdentifier), 'Invalid parameter "collectionElementIdentifier"', 1475378557);
|
|
375
|
+
assert(this.getUtility().isNonEmptyString(collectionName), 'Invalid parameter "collectionName"', 1475378558);
|
|
376
|
+
|
|
377
|
+
const indexFromPropertyCollectionElement = this.getRepository().getIndexFromPropertyCollectionElementByIdentifier(
|
|
378
|
+
collectionElementIdentifier,
|
|
379
|
+
collectionName,
|
|
380
|
+
formElement
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
return indexFromPropertyCollectionElement;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
public createAndAddPropertyCollectionElement(
|
|
387
|
+
collectionElementIdentifier: string,
|
|
388
|
+
collectionName: keyof FormEditorDefinitions,
|
|
389
|
+
formElement: FormElement,
|
|
390
|
+
collectionElementConfiguration: CollectionElementConfiguration,
|
|
391
|
+
referenceCollectionElementIdentifier: string
|
|
392
|
+
): FormElement {
|
|
393
|
+
return this.addPropertyCollectionElement(
|
|
394
|
+
this.createPropertyCollectionElement(
|
|
395
|
+
collectionElementIdentifier,
|
|
396
|
+
collectionName,
|
|
397
|
+
collectionElementConfiguration
|
|
398
|
+
),
|
|
399
|
+
collectionName,
|
|
400
|
+
formElement,
|
|
401
|
+
referenceCollectionElementIdentifier
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* @throws 1475443300
|
|
407
|
+
* @throws 1475443301
|
|
408
|
+
*/
|
|
409
|
+
public addPropertyCollectionElement(
|
|
410
|
+
collectionElement: CollectionEntry,
|
|
411
|
+
collectionName: keyof FormEditorDefinitions,
|
|
412
|
+
_formElement?: FormElement | string,
|
|
413
|
+
referenceCollectionElementIdentifier?: string
|
|
414
|
+
): FormElement {
|
|
415
|
+
let collection;
|
|
416
|
+
this.saveApplicationState();
|
|
417
|
+
|
|
418
|
+
if (this.getUtility().isUndefinedOrNull(_formElement)) {
|
|
419
|
+
_formElement = this.getCurrentlySelectedFormElement();
|
|
420
|
+
}
|
|
421
|
+
const formElement = this.getRepository().findFormElement(_formElement);
|
|
422
|
+
|
|
423
|
+
assert('object' === $.type(collectionElement), 'Invalid parameter "collectionElement"', 1475443301);
|
|
424
|
+
assert(this.getUtility().isNonEmptyString(collectionName), 'Invalid parameter "collectionName"', 1475443300);
|
|
425
|
+
|
|
426
|
+
if (this.getUtility().isUndefinedOrNull(referenceCollectionElementIdentifier)) {
|
|
427
|
+
collection = formElement.get(collectionName);
|
|
428
|
+
if ('array' === $.type(collection) && collection.length > 0) {
|
|
429
|
+
referenceCollectionElementIdentifier = collection[collection.length - 1].identifier;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
return this.getRepository().addPropertyCollectionElement(
|
|
434
|
+
collectionElement,
|
|
435
|
+
collectionName,
|
|
436
|
+
formElement,
|
|
437
|
+
referenceCollectionElementIdentifier,
|
|
438
|
+
false
|
|
439
|
+
);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* @throws 1475378559
|
|
444
|
+
* @throws 1475378560
|
|
445
|
+
*/
|
|
446
|
+
public createPropertyCollectionElement(
|
|
447
|
+
collectionElementIdentifier: string,
|
|
448
|
+
collectionName: keyof FormEditorDefinitions,
|
|
449
|
+
collectionElementConfiguration: CollectionElementConfiguration
|
|
450
|
+
): PropertyCollectionElement {
|
|
451
|
+
assert(this.getUtility().isNonEmptyString(collectionElementIdentifier), 'Invalid parameter "collectionElementIdentifier"', 1475378559);
|
|
452
|
+
assert(this.getUtility().isNonEmptyString(collectionName), 'Invalid parameter "collectionName"', 1475378560);
|
|
453
|
+
if ('object' !== $.type(collectionElementConfiguration)) {
|
|
454
|
+
collectionElementConfiguration = {} as CollectionElementConfiguration;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
return this.getFactory().createPropertyCollectionElement(
|
|
458
|
+
collectionElementIdentifier,
|
|
459
|
+
collectionElementConfiguration,
|
|
460
|
+
collectionName
|
|
461
|
+
);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* @throws 1475378561
|
|
466
|
+
* @throws 1475378562
|
|
467
|
+
*/
|
|
468
|
+
public removePropertyCollectionElement(
|
|
469
|
+
collectionElementIdentifier: string,
|
|
470
|
+
collectionName: keyof FormEditorDefinitions,
|
|
471
|
+
_formElement?: FormElement | string,
|
|
472
|
+
disablePublishersOnSet?: boolean
|
|
473
|
+
): void {
|
|
474
|
+
this.saveApplicationState();
|
|
475
|
+
|
|
476
|
+
if (this.getUtility().isUndefinedOrNull(_formElement)) {
|
|
477
|
+
_formElement = this.getCurrentlySelectedFormElement();
|
|
478
|
+
}
|
|
479
|
+
const formElement = this.getRepository().findFormElement(_formElement);
|
|
480
|
+
|
|
481
|
+
assert(this.getUtility().isNonEmptyString(collectionElementIdentifier), 'Invalid parameter "collectionElementIdentifier"', 1475378561);
|
|
482
|
+
assert(this.getUtility().isNonEmptyString(collectionName), 'Invalid parameter "collectionName"', 1475378562);
|
|
483
|
+
|
|
484
|
+
this.getRepository().removePropertyCollectionElementByIdentifier(
|
|
485
|
+
formElement,
|
|
486
|
+
collectionElementIdentifier,
|
|
487
|
+
collectionName,
|
|
488
|
+
true
|
|
489
|
+
);
|
|
490
|
+
|
|
491
|
+
disablePublishersOnSet = !!disablePublishersOnSet;
|
|
492
|
+
if (!disablePublishersOnSet) {
|
|
493
|
+
this.getPublisherSubscriber().publish('core/formElement/somePropertyChanged', ['__fakeProperty']);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* @throws 1477404352
|
|
499
|
+
* @throws 1477404353
|
|
500
|
+
* @throws 1477404354
|
|
501
|
+
* @throws 1477404355
|
|
502
|
+
*/
|
|
503
|
+
public movePropertyCollectionElement(
|
|
504
|
+
collectionElementToMove: string,
|
|
505
|
+
position: string,
|
|
506
|
+
referenceCollectionElement: string,
|
|
507
|
+
collectionName: keyof FormEditorDefinitions,
|
|
508
|
+
formElement: FormElement,
|
|
509
|
+
disablePublishersOnSet?: boolean
|
|
510
|
+
): void {
|
|
511
|
+
this.saveApplicationState();
|
|
512
|
+
|
|
513
|
+
formElement = this.getRepository().findFormElement(formElement);
|
|
514
|
+
|
|
515
|
+
assert('string' === $.type(collectionElementToMove), 'Invalid parameter "collectionElementToMove"', 1477404352);
|
|
516
|
+
assert('string' === $.type(referenceCollectionElement), 'Invalid parameter "referenceCollectionElement"', 1477404353);
|
|
517
|
+
assert('after' === position || 'before' === position, 'Invalid position "' + position + '"', 1477404354);
|
|
518
|
+
assert(this.getUtility().isNonEmptyString(collectionName), 'Invalid parameter "collectionName"', 1477404355);
|
|
519
|
+
|
|
520
|
+
this.getRepository().movePropertyCollectionElement(collectionElementToMove, position, referenceCollectionElement, collectionName, formElement, disablePublishersOnSet);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* @throws 1475378563
|
|
525
|
+
*/
|
|
526
|
+
public getFormElementDefinitionByType<T extends undefined | keyof FormElementDefinition, R = T extends keyof FormElementDefinition ? FormElementDefinition[T] : FormElementDefinition>(
|
|
527
|
+
elementType: string,
|
|
528
|
+
formElementDefinitionKey?: T
|
|
529
|
+
): R {
|
|
530
|
+
assert(this.getUtility().isNonEmptyString(elementType), 'Invalid parameter "elementType"', 1475378563);
|
|
531
|
+
|
|
532
|
+
const formElementDefinition = this.getRepository().getFormEditorDefinition('formElements', elementType);
|
|
533
|
+
|
|
534
|
+
if (formElementDefinitionKey !== undefined/* && formElementDefinitionKey !== null*/) {
|
|
535
|
+
const formElementDefinitionEntry = formElementDefinition[formElementDefinitionKey];
|
|
536
|
+
if (formElementDefinitionEntry !== null && (typeof formElementDefinitionEntry === 'object')) {
|
|
537
|
+
return $.extend(true, {}, formElementDefinitionEntry);
|
|
538
|
+
} else {
|
|
539
|
+
return formElementDefinitionEntry as R;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
if (formElementDefinition !== null && (typeof formElementDefinition === 'object')) {
|
|
544
|
+
return $.extend(true, {}, formElementDefinition);
|
|
545
|
+
} else {
|
|
546
|
+
return formElementDefinition as R;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
public getFormElementDefinition<T extends keyof FormElementDefinition>(
|
|
551
|
+
formElement: FormElement | string,
|
|
552
|
+
formElementDefinitionKey?: T
|
|
553
|
+
): T extends keyof FormElementDefinition ? FormElementDefinition[T] : FormElementDefinition {
|
|
554
|
+
formElement = this.getRepository().findFormElement(formElement);
|
|
555
|
+
return this.getFormElementDefinitionByType(formElement.get('type'), formElementDefinitionKey);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
public getFormEditorDefinition<D extends keyof FormEditorDefinitions, S extends keyof FormEditorDefinitions[D]>(
|
|
559
|
+
definitionName: D,
|
|
560
|
+
subject: S
|
|
561
|
+
): FormEditorDefinitions[D][S] {
|
|
562
|
+
return this.getRepository().getFormEditorDefinition(definitionName, subject);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* @throws 1475672362
|
|
567
|
+
*/
|
|
568
|
+
public getFormElementPropertyValidatorDefinition(validatorIdentifier: string): FormElementPropertyValidatorDefinition {
|
|
569
|
+
assert(this.getUtility().isNonEmptyString(validatorIdentifier), 'Invalid parameter "validatorIdentifier"', 1475672362);
|
|
570
|
+
|
|
571
|
+
const validatorDefinition = this.getRepository().getFormEditorDefinition('formElementPropertyValidators', validatorIdentifier);
|
|
572
|
+
// Return a dereferenced object
|
|
573
|
+
return $.extend(true, {}, validatorDefinition);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
public getCurrentlySelectedPageIndex(): number {
|
|
577
|
+
return this.getApplicationStateStack().getCurrentState('currentlySelectedPageIndex');
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
public refreshCurrentlySelectedPageIndex(): void {
|
|
581
|
+
this.getApplicationStateStack().setCurrentState(
|
|
582
|
+
'currentlySelectedPageIndex',
|
|
583
|
+
this.getPageIndexFromFormElement(this.getCurrentlySelectedFormElement())
|
|
584
|
+
);
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* @throws 1477786068
|
|
589
|
+
*/
|
|
590
|
+
public getCurrentlySelectedPage(): FormElement {
|
|
591
|
+
const currentPage = this.getRepository().getRootFormElement().get('renderables')[this.getCurrentlySelectedPageIndex()];
|
|
592
|
+
assert('object' === $.type(currentPage), 'No page found', 1477786068);
|
|
593
|
+
return currentPage;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
public getLastTopLevelElementOnCurrentPage(): FormElement {
|
|
597
|
+
|
|
598
|
+
const renderables = this.getCurrentlySelectedPage().get('renderables');
|
|
599
|
+
if (this.getUtility().isUndefinedOrNull(renderables)) {
|
|
600
|
+
return undefined;
|
|
601
|
+
}
|
|
602
|
+
return renderables[renderables.length - 1];
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
public getLastFormElementWithinParentFormElement(formElement: FormElement): FormElement {
|
|
606
|
+
formElement = this.getRepository().findFormElement(formElement);
|
|
607
|
+
if (formElement.get('__identifierPath') === this.getRootFormElement().get('__identifierPath')) {
|
|
608
|
+
return formElement;
|
|
609
|
+
}
|
|
610
|
+
return formElement.get('__parentRenderable').get('renderables')[formElement.get('__parentRenderable').get('renderables').length - 1];
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
public getPageIndexFromFormElement(formElement: FormElement | string): number {
|
|
614
|
+
formElement = this.getRepository().findFormElement(formElement);
|
|
615
|
+
|
|
616
|
+
return this.getRepository().getIndexForEnclosingCompositeFormElementWhichIsOnTopLevelForFormElement(
|
|
617
|
+
formElement
|
|
618
|
+
);
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
public renderCurrentFormPage(): void {
|
|
622
|
+
this.renderFormPage(this.getCurrentlySelectedPageIndex());
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
/**
|
|
626
|
+
* @throws 1475446442
|
|
627
|
+
*/
|
|
628
|
+
public renderFormPage(pageIndex: number): void {
|
|
629
|
+
assert('number' === $.type(pageIndex), 'Invalid parameter "pageIndex"', 1475446442);
|
|
630
|
+
this.getDataBackend().renderFormDefinitionPage(pageIndex);
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
public findEnclosingCompositeFormElementWhichIsNotOnTopLevel(
|
|
634
|
+
formElement: FormElement | string
|
|
635
|
+
): FormElement | null {
|
|
636
|
+
return this.getRepository().findEnclosingCompositeFormElementWhichIsNotOnTopLevel(
|
|
637
|
+
this.getRepository().findFormElement(formElement)
|
|
638
|
+
);
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/**
|
|
642
|
+
* @todo deprecate, method is unused
|
|
643
|
+
*/
|
|
644
|
+
public findEnclosingGridRowFormElement(
|
|
645
|
+
formElement: FormElement | string
|
|
646
|
+
): FormElement | null {
|
|
647
|
+
return this.getRepository().findEnclosingGridRowFormElement(
|
|
648
|
+
this.getRepository().findFormElement(formElement)
|
|
649
|
+
);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
public getNonCompositeNonToplevelFormElements(): FormElement[] {
|
|
653
|
+
return this.getRepository().getNonCompositeNonToplevelFormElements();
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
public isRootFormElementSelected(): boolean {
|
|
657
|
+
return (this.getCurrentlySelectedFormElement().get('__identifierPath') === this.getRootFormElement().get('__identifierPath'));
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
public getViewModel(): ViewModel {
|
|
661
|
+
return this.viewModel;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
public saveFormDefinition(): void {
|
|
665
|
+
this.getDataBackend().saveFormDefinition();
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
/**
|
|
669
|
+
* @throws 1473200696
|
|
670
|
+
*/
|
|
671
|
+
public run(): FormEditor {
|
|
672
|
+
if (this.isRunning) {
|
|
673
|
+
throw 'You can not run the app twice (1473200696)';
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
try {
|
|
677
|
+
this.bootstrap();
|
|
678
|
+
this.isRunning = true;
|
|
679
|
+
} catch(error: unknown) {
|
|
680
|
+
if (!(error instanceof Error)) {
|
|
681
|
+
throw error;
|
|
682
|
+
}
|
|
683
|
+
Notification.error(
|
|
684
|
+
TYPO3.lang['formEditor.error.headline'],
|
|
685
|
+
TYPO3.lang['formEditor.error.message']
|
|
686
|
+
+ '\r\n'
|
|
687
|
+
+ '\r\n'
|
|
688
|
+
+ TYPO3.lang['formEditor.error.technicalReason']
|
|
689
|
+
+ '\r\n'
|
|
690
|
+
+ error.message);
|
|
691
|
+
}
|
|
692
|
+
return this;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
private saveApplicationState(): void {
|
|
696
|
+
this.getApplicationStateStack().addAndReset({
|
|
697
|
+
formDefinition: this.getApplicationStateStack().getCurrentState('formDefinition').clone(),
|
|
698
|
+
currentlySelectedPageIndex: this.getApplicationStateStack().getCurrentState('currentlySelectedPageIndex'),
|
|
699
|
+
currentlySelectedFormElementIdentifierPath: this.getApplicationStateStack().getCurrentState('currentlySelectedFormElementIdentifierPath')
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
private getDataBackend(): DataBackend {
|
|
704
|
+
return Core.getDataBackend();
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
private getFactory(): Factory {
|
|
708
|
+
return Core.getFactory();
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
private getRepository(): Repository {
|
|
712
|
+
return Core.getRepository();
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
private getPropertyValidationService(): PropertyValidationService {
|
|
716
|
+
return Core.getPropertyValidationService();
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
private getApplicationStateStack(): ApplicationStateStack {
|
|
720
|
+
return Core.getApplicationStateStack();
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* @publish ajax/beforeSend
|
|
725
|
+
* @publish ajax/complete
|
|
726
|
+
*/
|
|
727
|
+
private ajaxSetup(): void {
|
|
728
|
+
$.ajaxSetup({
|
|
729
|
+
beforeSend: () => {
|
|
730
|
+
this.getPublisherSubscriber().publish('ajax/beforeSend');
|
|
731
|
+
},
|
|
732
|
+
complete: () => {
|
|
733
|
+
this.getPublisherSubscriber().publish('ajax/complete');
|
|
734
|
+
}
|
|
735
|
+
});
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
/**
|
|
739
|
+
* @throws 1475379748
|
|
740
|
+
* @throws 1475379749
|
|
741
|
+
* @throws 1475927876
|
|
742
|
+
*/
|
|
743
|
+
private dataBackendSetup(endpoints: Endpoints, prototypeName: string, formPersistenceIdentifier: string): void {
|
|
744
|
+
assert('object' === $.type(endpoints), 'Invalid parameter "endpoints"', 1475379748);
|
|
745
|
+
assert(this.getUtility().isNonEmptyString(prototypeName), 'Invalid parameter "prototypeName"', 1475927876);
|
|
746
|
+
assert(this.getUtility().isNonEmptyString(formPersistenceIdentifier), 'Invalid parameter "formPersistenceIdentifier"', 1475379749);
|
|
747
|
+
|
|
748
|
+
Core.getDataBackend().setEndpoints(endpoints);
|
|
749
|
+
Core.getDataBackend().setPrototypeName(prototypeName);
|
|
750
|
+
Core.getDataBackend().setPersistenceIdentifier(formPersistenceIdentifier);
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
/**
|
|
754
|
+
* @throws 1475379750
|
|
755
|
+
*/
|
|
756
|
+
private repositorySetup(formEditorDefinitions: FormEditorDefinitions): void {
|
|
757
|
+
assert('object' === $.type(formEditorDefinitions), 'Invalid parameter "formEditorDefinitions"', 1475379750);
|
|
758
|
+
|
|
759
|
+
this.getRepository().setFormEditorDefinitions(formEditorDefinitions);
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
/**
|
|
763
|
+
* @throws 1475492374
|
|
764
|
+
*/
|
|
765
|
+
private viewSetup(additionalViewModelModules: AdditionalViewModelModules): void {
|
|
766
|
+
assert('function' === $.type(this.viewModel.bootstrap), 'The view model does not implement the method "bootstrap"', 1475492374);
|
|
767
|
+
|
|
768
|
+
if (this.getUtility().isUndefinedOrNull(additionalViewModelModules)) {
|
|
769
|
+
additionalViewModelModules = [];
|
|
770
|
+
}
|
|
771
|
+
this.viewModel.bootstrap(formEditorInstance, additionalViewModelModules);
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
/**
|
|
775
|
+
* @throws 1475492032
|
|
776
|
+
*/
|
|
777
|
+
private mediatorSetup(): void {
|
|
778
|
+
assert('function' === $.type(this.mediator.bootstrap), 'The mediator does not implement the method "bootstrap"', 1475492032);
|
|
779
|
+
this.mediator.bootstrap(formEditorInstance, this.viewModel);
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
/**
|
|
783
|
+
* @throws 1475379751
|
|
784
|
+
*/
|
|
785
|
+
private applicationStateStackSetup(
|
|
786
|
+
rootFormElement: FormElementDefinition,
|
|
787
|
+
maximumUndoSteps: number
|
|
788
|
+
): void {
|
|
789
|
+
assert('object' === $.type(rootFormElement), 'Invalid parameter "rootFormElement"', 1475379751);
|
|
790
|
+
|
|
791
|
+
if ('number' !== $.type(maximumUndoSteps)) {
|
|
792
|
+
maximumUndoSteps = 10;
|
|
793
|
+
}
|
|
794
|
+
this.getApplicationStateStack().setMaximalStackSize(maximumUndoSteps);
|
|
795
|
+
|
|
796
|
+
this.getApplicationStateStack().addAndReset({
|
|
797
|
+
currentlySelectedPageIndex: 0,
|
|
798
|
+
currentlySelectedFormElementIdentifierPath: rootFormElement.identifier
|
|
799
|
+
}, true);
|
|
800
|
+
|
|
801
|
+
this.getApplicationStateStack().setCurrentState('formDefinition', this.getFactory().createFormElement(rootFormElement, undefined, undefined, true));
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
private bootstrap(): void {
|
|
805
|
+
this.mediatorSetup();
|
|
806
|
+
this.ajaxSetup();
|
|
807
|
+
this.dataBackendSetup(this.configuration.endpoints, this.configuration.prototypeName, this.configuration.formPersistenceIdentifier);
|
|
808
|
+
this.repositorySetup(this.configuration.formEditorDefinitions);
|
|
809
|
+
this.applicationStateStackSetup(this.configuration.formDefinition, this.configuration.maximumUndoSteps);
|
|
810
|
+
this.setCurrentlySelectedFormElement(this.getRepository().getRootFormElement());
|
|
811
|
+
|
|
812
|
+
this.viewSetup(this.configuration.additionalViewModelModules);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
let formEditorInstance: FormEditor = null;
|
|
817
|
+
|
|
818
|
+
/**
|
|
819
|
+
* @public
|
|
820
|
+
* @static
|
|
821
|
+
*
|
|
822
|
+
* Implement the "Singleton Pattern".
|
|
823
|
+
*
|
|
824
|
+
* Return a singleton instance of a
|
|
825
|
+
* "FormEditor" object.
|
|
826
|
+
*/
|
|
827
|
+
export function getInstance(
|
|
828
|
+
configuration: FormEditorConfiguration,
|
|
829
|
+
mediator: Mediator,
|
|
830
|
+
viewModel: ViewModel
|
|
831
|
+
): FormEditor {
|
|
832
|
+
if (formEditorInstance === null) {
|
|
833
|
+
formEditorInstance = new FormEditor(configuration, mediator, viewModel);
|
|
834
|
+
}
|
|
835
|
+
return formEditorInstance;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
declare global {
|
|
839
|
+
interface PublisherSubscriberTopicArgumentsMap {
|
|
840
|
+
'core/currentlySelectedFormElementChanged': readonly [
|
|
841
|
+
formElement: FormElement
|
|
842
|
+
];
|
|
843
|
+
'ajax/beforeSend': undefined;
|
|
844
|
+
'ajax/complete': undefined;
|
|
845
|
+
}
|
|
846
|
+
}
|