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.
Files changed (415) hide show
  1. package/.github/workflows/sync-and-publish.yml +265 -0
  2. package/.last-synced-tag +1 -0
  3. package/LICENSE.txt +339 -0
  4. package/README-TYPO3.md +166 -0
  5. package/README.md +28 -0
  6. package/adminpanel/admin-panel.ts +375 -0
  7. package/adminpanel/modules/cache.ts +27 -0
  8. package/adminpanel/modules/preview.ts +75 -0
  9. package/backend/action-button/abstract-action.ts +22 -0
  10. package/backend/action-button/deferred-action.ts +41 -0
  11. package/backend/action-button/immediate-action.ts +31 -0
  12. package/backend/action-dispatcher.ts +104 -0
  13. package/backend/ajax-data-handler/message-interface.ts +18 -0
  14. package/backend/ajax-data-handler/response-interface.ts +20 -0
  15. package/backend/ajax-data-handler.ts +214 -0
  16. package/backend/backend-exception.ts +22 -0
  17. package/backend/broadcast-message.ts +50 -0
  18. package/backend/broadcast-service.ts +52 -0
  19. package/backend/browse-database.ts +38 -0
  20. package/backend/clear-cache.ts +88 -0
  21. package/backend/clipboard-panel.ts +240 -0
  22. package/backend/close-current-window.ts +2 -0
  23. package/backend/code-editor/autocomplete/completion-result.ts +105 -0
  24. package/backend/code-editor/autocomplete/ts-code-completion.ts +142 -0
  25. package/backend/code-editor/autocomplete/ts-parser.ts +485 -0
  26. package/backend/code-editor/autocomplete/ts-ref.ts +164 -0
  27. package/backend/code-editor/element/code-mirror-element.ts +282 -0
  28. package/backend/code-editor/language/typoscript.ts +181 -0
  29. package/backend/code-editor/stream-parser/typoscript.ts +1600 -0
  30. package/backend/color-picker.ts +158 -0
  31. package/backend/color-scheme-switch.ts +179 -0
  32. package/backend/column-selector-button.ts +302 -0
  33. package/backend/context-help.ts +68 -0
  34. package/backend/context-menu-actions.ts +322 -0
  35. package/backend/context-menu.ts +751 -0
  36. package/backend/copy-to-clipboard.ts +79 -0
  37. package/backend/date-time-picker.ts +270 -0
  38. package/backend/document-save-actions.ts +159 -0
  39. package/backend/drag-tooltip.ts +285 -0
  40. package/backend/drag-uploader.ts +914 -0
  41. package/backend/element/alert-element.ts +116 -0
  42. package/backend/element/dispatch-modal-button.ts +50 -0
  43. package/backend/element/draggable-resizable-element.ts +249 -0
  44. package/backend/element/editable-page-title.ts +306 -0
  45. package/backend/element/icon-element.ts +84 -0
  46. package/backend/element/immediate-action-element.ts +89 -0
  47. package/backend/element/pagination.ts +59 -0
  48. package/backend/element/progress-bar-element.ts +172 -0
  49. package/backend/element/progress-tracker-element.ts +119 -0
  50. package/backend/element/pseudo-button.ts +58 -0
  51. package/backend/element/spinner-element.ts +51 -0
  52. package/backend/element/thumbnail-element.ts +80 -0
  53. package/backend/element-browser.ts +182 -0
  54. package/backend/enum/data-transfer-types.ts +21 -0
  55. package/backend/enum/icon-types.ts +31 -0
  56. package/backend/enum/key-types.ts +27 -0
  57. package/backend/enum/severity.ts +20 -0
  58. package/backend/enum/viewport/scaffold-identifier.ts +24 -0
  59. package/backend/event/client-request.ts +25 -0
  60. package/backend/event/consumable.ts +18 -0
  61. package/backend/event/consumer-scope.ts +54 -0
  62. package/backend/event/event-dispatcher.ts +26 -0
  63. package/backend/event/interaction-request-assignment.ts +24 -0
  64. package/backend/event/interaction-request-map.ts +75 -0
  65. package/backend/event/interaction-request.ts +48 -0
  66. package/backend/event/trigger-request.ts +56 -0
  67. package/backend/form/submit-interceptor.ts +66 -0
  68. package/backend/form-engine/container/files-control-container.ts +716 -0
  69. package/backend/form-engine/container/flex-form-container-container.ts +166 -0
  70. package/backend/form-engine/container/flex-form-section-container.ts +210 -0
  71. package/backend/form-engine/container/inline-control-container.ts +1230 -0
  72. package/backend/form-engine/container/site-language-container.ts +616 -0
  73. package/backend/form-engine/element/abstract-sortable-select-items.ts +186 -0
  74. package/backend/form-engine/element/category-element.ts +160 -0
  75. package/backend/form-engine/element/color-element.ts +81 -0
  76. package/backend/form-engine/element/datetime-element.ts +66 -0
  77. package/backend/form-engine/element/extra/char-counter.ts +112 -0
  78. package/backend/form-engine/element/extra/select-box-filter.ts +85 -0
  79. package/backend/form-engine/element/folder-element.ts +66 -0
  80. package/backend/form-engine/element/group-element.ts +47 -0
  81. package/backend/form-engine/element/json-element.ts +52 -0
  82. package/backend/form-engine/element/link-element.ts +121 -0
  83. package/backend/form-engine/element/mfa-info-element.ts +169 -0
  84. package/backend/form-engine/element/modifier/resizable.ts +27 -0
  85. package/backend/form-engine/element/modifier/tabbable.ts +29 -0
  86. package/backend/form-engine/element/online-media-form-element.ts +65 -0
  87. package/backend/form-engine/element/password-element.ts +71 -0
  88. package/backend/form-engine/element/select-multiple-side-by-side-element.ts +83 -0
  89. package/backend/form-engine/element/select-single-element.ts +82 -0
  90. package/backend/form-engine/element/select-tree-element.ts +148 -0
  91. package/backend/form-engine/element/select-tree-toolbar.ts +118 -0
  92. package/backend/form-engine/element/select-tree.ts +210 -0
  93. package/backend/form-engine/element/slug-element.ts +243 -0
  94. package/backend/form-engine/element/suggest/result-container.ts +118 -0
  95. package/backend/form-engine/element/suggest/result-item.ts +90 -0
  96. package/backend/form-engine/element/table-permission-element.ts +101 -0
  97. package/backend/form-engine/element/table-wizard-element.ts +427 -0
  98. package/backend/form-engine/element/text-element.ts +52 -0
  99. package/backend/form-engine/element/text-table-element.ts +31 -0
  100. package/backend/form-engine/field-control/add-record.ts +40 -0
  101. package/backend/form-engine/field-control/edit-popup.ts +64 -0
  102. package/backend/form-engine/field-control/insert-clipboard.ts +50 -0
  103. package/backend/form-engine/field-control/link-popup.ts +53 -0
  104. package/backend/form-engine/field-control/list-module.ts +40 -0
  105. package/backend/form-engine/field-control/password-generator.ts +102 -0
  106. package/backend/form-engine/field-control/reset-selection.ts +48 -0
  107. package/backend/form-engine/field-wizard/localization-state-selector.ts +67 -0
  108. package/backend/form-engine/field-wizard/value-picker.ts +123 -0
  109. package/backend/form-engine/field-wizard/value-slider.ts +86 -0
  110. package/backend/form-engine/inline-relation/ajax-dispatcher.ts +124 -0
  111. package/backend/form-engine/inline-relation/inline-response-interface.ts +41 -0
  112. package/backend/form-engine-link-browser-adapter.ts +129 -0
  113. package/backend/form-engine-review.ts +155 -0
  114. package/backend/form-engine-suggest.ts +133 -0
  115. package/backend/form-engine-validation.ts +686 -0
  116. package/backend/form-engine.ts +1391 -0
  117. package/backend/global-event-handler.ts +252 -0
  118. package/backend/grid-editor.ts +1077 -0
  119. package/backend/hashing/md5.ts +252 -0
  120. package/backend/helper.ts +24 -0
  121. package/backend/hotkeys/hotkey-storage.ts +63 -0
  122. package/backend/hotkeys.ts +216 -0
  123. package/backend/icons.ts +236 -0
  124. package/backend/image-manipulation.ts +885 -0
  125. package/backend/info-window.ts +46 -0
  126. package/backend/input/clearable.ts +128 -0
  127. package/backend/input/index.d.ts +8 -0
  128. package/backend/java-script-module-import-event-handler.ts +19 -0
  129. package/backend/key-bindings.ts +42 -0
  130. package/backend/layout-module/drag-drop.ts +359 -0
  131. package/backend/layout-module/paste.ts +165 -0
  132. package/backend/link-browser.ts +89 -0
  133. package/backend/live-search/element/backend-search.ts +34 -0
  134. package/backend/live-search/element/hint.ts +33 -0
  135. package/backend/live-search/element/provider/default-result-item.ts +52 -0
  136. package/backend/live-search/element/provider/page-provider-result-item.ts +52 -0
  137. package/backend/live-search/element/result/item/action/action-container.ts +135 -0
  138. package/backend/live-search/element/result/item/action/action.ts +56 -0
  139. package/backend/live-search/element/result/item/item-container.ts +224 -0
  140. package/backend/live-search/element/result/item/item.ts +74 -0
  141. package/backend/live-search/element/result/result-container.ts +110 -0
  142. package/backend/live-search/element/result/result-detail-container.ts +50 -0
  143. package/backend/live-search/element/result/result-pagination.ts +122 -0
  144. package/backend/live-search/element/search-option-item.ts +70 -0
  145. package/backend/live-search/live-search-configurator.ts +54 -0
  146. package/backend/live-search/live-search-shortcut.ts +29 -0
  147. package/backend/live-search/result-types/backend-module-result-type.ts +8 -0
  148. package/backend/live-search/result-types/default-result-type.ts +21 -0
  149. package/backend/live-search/result-types/page-result-type.ts +23 -0
  150. package/backend/localization.ts +390 -0
  151. package/backend/login-refresh.ts +525 -0
  152. package/backend/login.ts +179 -0
  153. package/backend/mail-link-handler.ts +45 -0
  154. package/backend/modal-interface.ts +19 -0
  155. package/backend/modal.ts +685 -0
  156. package/backend/module/iframe.ts +125 -0
  157. package/backend/module/router.ts +275 -0
  158. package/backend/module-menu.ts +550 -0
  159. package/backend/module.ts +133 -0
  160. package/backend/multi-record-selection-action.ts +44 -0
  161. package/backend/multi-record-selection-delete-action.ts +108 -0
  162. package/backend/multi-record-selection-edit-action.ts +56 -0
  163. package/backend/multi-record-selection.ts +468 -0
  164. package/backend/multi-step-wizard.ts +568 -0
  165. package/backend/new-content-element-wizard-button.ts +51 -0
  166. package/backend/new-multiple-pages.ts +108 -0
  167. package/backend/new-record-wizard.ts +680 -0
  168. package/backend/notification.ts +366 -0
  169. package/backend/offset.ts +40 -0
  170. package/backend/online-media.ts +110 -0
  171. package/backend/page-actions.ts +91 -0
  172. package/backend/page-link-handler.ts +51 -0
  173. package/backend/pagetsconfig/pagetsconfig-includes.ts +77 -0
  174. package/backend/popover.ts +165 -0
  175. package/backend/record-download-button.ts +104 -0
  176. package/backend/record-link-handler.ts +31 -0
  177. package/backend/record-search.ts +44 -0
  178. package/backend/recordlist.ts +230 -0
  179. package/backend/resource/resource.ts +35 -0
  180. package/backend/security/element/csp-reports.ts +406 -0
  181. package/backend/security/element/sudo-mode.ts +249 -0
  182. package/backend/security/sudo-mode-interceptor.ts +19 -0
  183. package/backend/settings/editor/editable-setting.ts +231 -0
  184. package/backend/settings/editor.ts +451 -0
  185. package/backend/settings/enum/settings-mode.enum.ts +24 -0
  186. package/backend/settings/type/base.ts +200 -0
  187. package/backend/settings/type/bool.ts +56 -0
  188. package/backend/settings/type/color.ts +64 -0
  189. package/backend/settings/type/int.ts +85 -0
  190. package/backend/settings/type/number.ts +61 -0
  191. package/backend/settings/type/page.ts +100 -0
  192. package/backend/settings/type/string.ts +77 -0
  193. package/backend/settings/type/stringlist.ts +87 -0
  194. package/backend/severity.ts +88 -0
  195. package/backend/site-inline-actions.ts +32 -0
  196. package/backend/sortable-table.ts +208 -0
  197. package/backend/storage/abstract-client-storage.ts +76 -0
  198. package/backend/storage/browser-session.ts +28 -0
  199. package/backend/storage/client.ts +28 -0
  200. package/backend/storage/module-state-storage.ts +118 -0
  201. package/backend/storage/persistent.ts +204 -0
  202. package/backend/switch-user.ts +82 -0
  203. package/backend/tabs.ts +72 -0
  204. package/backend/telephone-link-handler.ts +40 -0
  205. package/backend/tests/backend/storage/browser-storage-test.ts +87 -0
  206. package/backend/tests/backend/storage/client-test.ts +87 -0
  207. package/backend/tests/backend/utility/dom-helper-test.ts +51 -0
  208. package/backend/tests/backend-exception-test.ts +28 -0
  209. package/backend/tests/element/immediate-action-element-test.ts +81 -0
  210. package/backend/tests/form-engine-validation-test.ts +304 -0
  211. package/backend/tests/grid-editor-test.ts +29 -0
  212. package/backend/tests/hashing/md5Test.ts +28 -0
  213. package/backend/tests/icons-test.ts +23 -0
  214. package/backend/tests/notification-test.ts +161 -0
  215. package/backend/tests/popover-test.ts +83 -0
  216. package/backend/toolbar/clear-cache-menu.ts +88 -0
  217. package/backend/toolbar/live-search.ts +284 -0
  218. package/backend/toolbar/shortcut-menu.ts +254 -0
  219. package/backend/toolbar/system-information-menu.ts +161 -0
  220. package/backend/toolbar.ts +41 -0
  221. package/backend/tree/file-storage-browser.ts +194 -0
  222. package/backend/tree/file-storage-tree-container.ts +465 -0
  223. package/backend/tree/file-storage-tree.ts +42 -0
  224. package/backend/tree/page-browser.ts +272 -0
  225. package/backend/tree/page-tree-element.ts +602 -0
  226. package/backend/tree/page-tree.ts +152 -0
  227. package/backend/tree/tree-module-state.ts +159 -0
  228. package/backend/tree/tree-node-toggle.ts +31 -0
  229. package/backend/tree/tree-node.ts +97 -0
  230. package/backend/tree/tree-toolbar.ts +117 -0
  231. package/backend/tree/tree.ts +1595 -0
  232. package/backend/url-link-handler.ts +36 -0
  233. package/backend/user-pass-login.ts +255 -0
  234. package/backend/user-settings-manager.ts +189 -0
  235. package/backend/utility/collapse-state-persister.ts +205 -0
  236. package/backend/utility/collapse-state-search.ts +183 -0
  237. package/backend/utility/dom-helper.ts +91 -0
  238. package/backend/utility/drag-drop-utility.ts +47 -0
  239. package/backend/utility/message-utility.ts +45 -0
  240. package/backend/utility/top-level-module-import.ts +32 -0
  241. package/backend/utility.ts +194 -0
  242. package/backend/viewport/abstract-container.ts +22 -0
  243. package/backend/viewport/content-container.ts +98 -0
  244. package/backend/viewport/loader.ts +28 -0
  245. package/backend/viewport/navigation-container.ts +119 -0
  246. package/backend/viewport/resizable-navigation.ts +176 -0
  247. package/backend/viewport/toolbar.ts +27 -0
  248. package/backend/viewport/topbar.ts +39 -0
  249. package/backend/viewport.ts +46 -0
  250. package/backend/window-manager.ts +84 -0
  251. package/backend/wizard/move-content-element.ts +107 -0
  252. package/backend/wizard/move-page.ts +74 -0
  253. package/backend/wizard.ts +331 -0
  254. package/belog/backend-log.ts +88 -0
  255. package/beuser/backend-user-listing.ts +40 -0
  256. package/beuser/permissions.ts +291 -0
  257. package/core/ajax/ajax-request-types.ts +15 -0
  258. package/core/ajax/ajax-request.ts +202 -0
  259. package/core/ajax/ajax-response.ts +57 -0
  260. package/core/ajax/input-transformer.ts +92 -0
  261. package/core/ajax/simple-response-interface.ts +5 -0
  262. package/core/authentication/mfa-provider/totp.ts +54 -0
  263. package/core/cache/dedupe-async-task.ts +95 -0
  264. package/core/directive/markdown.ts +82 -0
  265. package/core/directive/nl2br.ts +16 -0
  266. package/core/document-service.ts +35 -0
  267. package/core/event/debounce-event.ts +40 -0
  268. package/core/event/event-interface.ts +24 -0
  269. package/core/event/regular-event.ts +58 -0
  270. package/core/event/request-animation-frame-event.ts +42 -0
  271. package/core/event/throttle-event.ts +54 -0
  272. package/core/java-script-item-handler.ts +29 -0
  273. package/core/java-script-item-processor.ts +171 -0
  274. package/core/lit-helper.ts +126 -0
  275. package/core/literals.ts +17 -0
  276. package/core/referrer-refresh.ts +2 -0
  277. package/core/security-utility.ts +89 -0
  278. package/core/tests/ajax/ajax-request-test.ts +290 -0
  279. package/core/tests/ajax/input-transformer-test.ts +64 -0
  280. package/core/tests/cache/dedupe-async-task-test.ts +152 -0
  281. package/core/tests/event/throttle-event-test.ts +47 -0
  282. package/core/tests/literals-test.ts +24 -0
  283. package/core/tests/security-utility-test.ts +50 -0
  284. package/core/utility/types.ts +9 -0
  285. package/dashboard/chart-initializer.ts +136 -0
  286. package/dashboard/dashboard.ts +1487 -0
  287. package/extensionmanager/distribution-image.ts +55 -0
  288. package/extensionmanager/main.ts +291 -0
  289. package/extensionmanager/repository.ts +195 -0
  290. package/extensionmanager/update.ts +118 -0
  291. package/extensionmanager/upload-form.ts +42 -0
  292. package/filelist/browse-files.ts +148 -0
  293. package/filelist/browse-folders.ts +94 -0
  294. package/filelist/context-menu-actions.ts +335 -0
  295. package/filelist/create-folder.ts +69 -0
  296. package/filelist/file-delete.ts +69 -0
  297. package/filelist/file-list-actions.ts +132 -0
  298. package/filelist/file-list-dragdrop.ts +139 -0
  299. package/filelist/file-list-rename-handler.ts +128 -0
  300. package/filelist/file-list-transfer-handler.ts +138 -0
  301. package/filelist/file-list.ts +396 -0
  302. package/filelist/file-replace.ts +37 -0
  303. package/filelist/linkbrowser-file-handler.ts +94 -0
  304. package/filelist/linkbrowser-folder-handler.ts +74 -0
  305. package/filelist/rename-file.ts +109 -0
  306. package/form/backend/form-editor/component/property-grid-editor.ts +340 -0
  307. package/form/backend/form-editor/core.ts +2104 -0
  308. package/form/backend/form-editor/helper.ts +226 -0
  309. package/form/backend/form-editor/inspector-component.ts +2323 -0
  310. package/form/backend/form-editor/mediator.ts +941 -0
  311. package/form/backend/form-editor/modals-component.ts +433 -0
  312. package/form/backend/form-editor/stage-component.ts +908 -0
  313. package/form/backend/form-editor/tree-component.ts +548 -0
  314. package/form/backend/form-editor/view-model.ts +1343 -0
  315. package/form/backend/form-editor.ts +846 -0
  316. package/form/backend/form-manager/main.ts +39 -0
  317. package/form/backend/form-manager/view-model.ts +789 -0
  318. package/form/backend/form-manager.ts +180 -0
  319. package/form/backend/helper.ts +60 -0
  320. package/form/frontend/date-picker.ts +38 -0
  321. package/frontend/default_frontend.ts +82 -0
  322. package/impexp/context-menu-actions.ts +50 -0
  323. package/impexp/import-export.ts +62 -0
  324. package/indexed-search/pagination.ts +26 -0
  325. package/indexed-search/statistics.ts +50 -0
  326. package/info/translation-status.ts +48 -0
  327. package/install/ajax/ajax-queue.ts +83 -0
  328. package/install/init-install.ts +2 -0
  329. package/install/init-installer.ts +2 -0
  330. package/install/install.ts +25 -0
  331. package/install/installer.ts +458 -0
  332. package/install/message-interface.ts +18 -0
  333. package/install/module/abstract-inline-module.ts +27 -0
  334. package/install/module/abstract-interactable-module.ts +107 -0
  335. package/install/module/environment/environment-check.ts +92 -0
  336. package/install/module/environment/folder-structure.ts +145 -0
  337. package/install/module/environment/image-processing.ts +141 -0
  338. package/install/module/environment/mail-test.ts +127 -0
  339. package/install/module/environment/php-info.ts +50 -0
  340. package/install/module/environment/system-information.ts +50 -0
  341. package/install/module/maintenance/cache.ts +59 -0
  342. package/install/module/maintenance/clear-tables.ts +134 -0
  343. package/install/module/maintenance/clear-typo3temp-files.ts +137 -0
  344. package/install/module/maintenance/create-admin.ts +126 -0
  345. package/install/module/maintenance/database-analyzer.ts +266 -0
  346. package/install/module/maintenance/dump-autoload.ts +58 -0
  347. package/install/module/maintenance/language-packs.ts +338 -0
  348. package/install/module/maintenance/reset-backend-user-uc.ts +58 -0
  349. package/install/module/password-strength.ts +56 -0
  350. package/install/module/settings/change-install-tool-password.ts +101 -0
  351. package/install/module/settings/extension-configuration.ts +224 -0
  352. package/install/module/settings/features.ts +102 -0
  353. package/install/module/settings/local-configuration.ts +316 -0
  354. package/install/module/settings/presets.ts +147 -0
  355. package/install/module/settings/system-maintainer.ts +111 -0
  356. package/install/module/upgrade/core-update.ts +255 -0
  357. package/install/module/upgrade/extension-compat-tester.ts +195 -0
  358. package/install/module/upgrade/extension-scanner.ts +381 -0
  359. package/install/module/upgrade/tca-ext-tables-check.ts +93 -0
  360. package/install/module/upgrade/tca-migrations-check.ts +101 -0
  361. package/install/module/upgrade/upgrade-docs.ts +310 -0
  362. package/install/module/upgrade/upgrade-wizards.ts +612 -0
  363. package/install/renderable/clearable.ts +113 -0
  364. package/install/renderable/flash-message.ts +64 -0
  365. package/install/renderable/info-box.ts +66 -0
  366. package/install/renderable/language-packs.ts +304 -0
  367. package/install/renderable/offset-group.ts +38 -0
  368. package/install/renderable/severity.ts +49 -0
  369. package/install/renderable/wrap-group.ts +36 -0
  370. package/install/router.ts +468 -0
  371. package/linkvalidator/linkvalidator-modal.ts +45 -0
  372. package/linkvalidator/linkvalidator.ts +101 -0
  373. package/lowlevel/query-generator.ts +132 -0
  374. package/lowlevel/reference-index.ts +44 -0
  375. package/opendocs/toolbar/opendocs-menu.ts +117 -0
  376. package/package.json +34 -0
  377. package/recycler/recycler.ts +539 -0
  378. package/redirects/event-handler.ts +108 -0
  379. package/redirects/form-engine-evaluation.ts +34 -0
  380. package/redirects/redirects-module.ts +58 -0
  381. package/rte-ckeditor/ckeditor5.ts +402 -0
  382. package/rte-ckeditor/css-prefixer.ts +94 -0
  383. package/rte-ckeditor/legacy/ckeditor5-bundle.ts +17 -0
  384. package/rte-ckeditor/legacy/ckeditor5-inspector.ts +2 -0
  385. package/rte-ckeditor/plugin/typo3-link.ts +810 -0
  386. package/rte-ckeditor/plugin/whitespace.ts +114 -0
  387. package/rte-ckeditor/rte-link-browser.ts +112 -0
  388. package/rte-ckeditor/tests/css-prefixer-test.ts +314 -0
  389. package/scheduler/scheduler-add-group.ts +119 -0
  390. package/scheduler/scheduler-editable-group-name.ts +307 -0
  391. package/scheduler/scheduler-sortable-groups.ts +59 -0
  392. package/scheduler/scheduler.ts +466 -0
  393. package/setup/setup-module.ts +122 -0
  394. package/styleguide/checkbox-demo.ts +5 -0
  395. package/styleguide/element/theme-switcher-element.ts +101 -0
  396. package/styleguide/filter.ts +22 -0
  397. package/styleguide/find-icons.ts +78 -0
  398. package/styleguide/processing-indicator.ts +78 -0
  399. package/styleguide/render-notifications.ts +64 -0
  400. package/sys-note/element/delete-button.ts +78 -0
  401. package/tstemplate/constant-editor.ts +64 -0
  402. package/tstemplate/information-module.ts +31 -0
  403. package/tstemplate/template-analyzer.ts +77 -0
  404. package/viewpage/main.ts +253 -0
  405. package/workspaces/backend.ts +979 -0
  406. package/workspaces/preview.ts +232 -0
  407. package/workspaces/renderable/comment-view.ts +79 -0
  408. package/workspaces/renderable/diff-view.ts +58 -0
  409. package/workspaces/renderable/history-view.ts +97 -0
  410. package/workspaces/renderable/record-information.ts +118 -0
  411. package/workspaces/renderable/record-table.ts +355 -0
  412. package/workspaces/renderable/send-to-stage-form.ts +108 -0
  413. package/workspaces/toolbar/workspaces-menu.ts +190 -0
  414. package/workspaces/utility/icon-helper.ts +57 -0
  415. 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
+ }