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,2323 @@
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/inspector-component
16
+ */
17
+
18
+ import $ from 'jquery';
19
+ import * as Helper from '@typo3/form/backend/form-editor/helper';
20
+ import Icons from '@typo3/backend/icons';
21
+ import Modal from '@typo3/backend/modal';
22
+ import { MessageUtility } from '@typo3/backend/utility/message-utility';
23
+ import Sortable from 'sortablejs';
24
+ import { selector } from '@typo3/core/literals';
25
+ import { PropertyGridEditorUpdateEvent, type PropertyGridEditorEntry } from '@typo3/form/backend/form-editor/component/property-grid-editor';
26
+
27
+ import type {
28
+ FormEditor,
29
+ } from '@typo3/form/backend/form-editor';
30
+ import type {
31
+ Utility,
32
+ EditorConfiguration,
33
+ FormEditorDefinitions,
34
+ FormElement,
35
+ FormElementDefinition,
36
+ PublisherSubscriber,
37
+ } from '@typo3/form/backend/form-editor/core';
38
+ import type {
39
+ Configuration as HelperConfiguration,
40
+ } from '@typo3/form/backend/form-editor/helper';
41
+ type ViewModel = typeof import('./view-model');
42
+
43
+ interface Configuration extends Partial<HelperConfiguration> {
44
+ isSortable: boolean,
45
+ }
46
+
47
+ type PropertyData = Array<{code: string, message: string}>;
48
+
49
+ const defaultConfiguration: Configuration = {
50
+ domElementClassNames: {
51
+ buttonFormElementRemove: 'formeditor-inspector-element-remove-button',
52
+ collectionElement: 'formeditor-inspector-collection-element',
53
+ finisherEditorPrefix: 't3-form-inspector-finishers-editor-',
54
+ inspectorEditor: 'formeditor-inspector-element',
55
+ inspectorInputGroup: 'input-group',
56
+ validatorEditorPrefix: 'formeditor-inspector-validators-editor-'
57
+ },
58
+ domElementDataAttributeNames: {
59
+ contentElementSelectorTarget: 'data-insert-target',
60
+ finisher: 'data-finisher-identifier',
61
+ validator: 'data-validator-identifier',
62
+ randomId: 'data-random-id',
63
+ randomIdTarget: 'data-random-id-attribute',
64
+ randomIdIndex: 'data-random-id-number',
65
+ maximumFileSize: 'data-maximumFileSize'
66
+ },
67
+ domElementDataAttributeValues: {
68
+ collapse: 'actions-view-table-expand',
69
+ editorControlsInputGroup: 'inspectorEditorControlsGroup',
70
+ editorWrapper: 'editorWrapper',
71
+ editorControlsWrapper: 'inspectorEditorControlsWrapper',
72
+ formElementHeaderEditor: 'inspectorFormElementHeaderEditor',
73
+ formElementSelectorControlsWrapper: 'inspectorEditorFormElementSelectorControlsWrapper',
74
+ formElementSelectorSplitButtonContainer: 'inspectorEditorFormElementSelectorSplitButtonContainer',
75
+ formElementSelectorSplitButtonListContainer: 'inspectorEditorFormElementSelectorSplitButtonListContainer',
76
+ iconNotAvailable: 'actions-close',
77
+ inspector: 'inspector',
78
+ 'Inspector-CheckboxEditor': 'Inspector-CheckboxEditor',
79
+ 'Inspector-CollectionElementHeaderEditor': 'Inspector-CollectionElementHeaderEditor',
80
+ 'Inspector-FinishersEditor': 'Inspector-FinishersEditor',
81
+ 'Inspector-FormElementHeaderEditor': 'Inspector-FormElementHeaderEditor',
82
+ 'Inspector-PropertyGridEditor': 'Inspector-PropertyGridEditor',
83
+ 'Inspector-RemoveElementEditor': 'Inspector-RemoveElementEditor',
84
+ 'Inspector-RequiredValidatorEditor': 'Inspector-RequiredValidatorEditor',
85
+ 'Inspector-SingleSelectEditor': 'Inspector-SingleSelectEditor',
86
+ 'Inspector-MultiSelectEditor': 'Inspector-MultiSelectEditor',
87
+ 'Inspector-GridColumnViewPortConfigurationEditor': 'Inspector-GridColumnViewPortConfigurationEditor',
88
+ 'Inspector-TextareaEditor': 'Inspector-TextareaEditor',
89
+ 'Inspector-TextEditor': 'Inspector-TextEditor',
90
+ 'Inspector-Typo3WinBrowserEditor': 'Inspector-Typo3WinBrowserEditor',
91
+ 'Inspector-ValidatorsEditor': 'Inspector-ValidatorsEditor',
92
+ 'Inspector-ValidationErrorMessageEditor': 'Inspector-ValidationErrorMessageEditor',
93
+
94
+ inspectorFinishers: 'inspectorFinishers',
95
+ inspectorValidators: 'inspectorValidators',
96
+ viewportButton: 'viewportButton'
97
+ },
98
+ domElementIdNames: {
99
+ finisherPrefix: 't3-form-inspector-finishers-',
100
+ validatorPrefix: 't3-form-inspector-validators-'
101
+ },
102
+ isSortable: true
103
+ };
104
+
105
+ let configuration: Configuration = null;
106
+
107
+ let formEditorApp: FormEditor = null;
108
+
109
+ function getFormEditorApp(): FormEditor {
110
+ return formEditorApp;
111
+ }
112
+
113
+ function getViewModel(): ViewModel {
114
+ return getFormEditorApp().getViewModel();
115
+ }
116
+
117
+ function getHelper(_configuration?: HelperConfiguration): typeof Helper {
118
+ if (getUtility().isUndefinedOrNull(_configuration)) {
119
+ return Helper.setConfiguration(configuration);
120
+ }
121
+ return Helper.setConfiguration(_configuration);
122
+ }
123
+
124
+ function getUtility(): Utility {
125
+ return getFormEditorApp().getUtility();
126
+ }
127
+
128
+ function assert(test: boolean|(() => boolean), message: string, messageCode: number): void {
129
+ return getFormEditorApp().assert(test, message, messageCode);
130
+ }
131
+
132
+ function getRootFormElement(): FormElement {
133
+ return getFormEditorApp().getRootFormElement();
134
+ }
135
+
136
+ function getCurrentlySelectedFormElement(): FormElement {
137
+ return getFormEditorApp().getCurrentlySelectedFormElement();
138
+ }
139
+
140
+ function getPublisherSubscriber(): PublisherSubscriber {
141
+ return getFormEditorApp().getPublisherSubscriber();
142
+ }
143
+
144
+ function getFormElementDefinition<T extends keyof FormElementDefinition>(
145
+ formElement: FormElement | string,
146
+ formElementDefinitionKey?: T
147
+ ): T extends keyof FormElementDefinition ? FormElementDefinition[T] : FormElementDefinition {
148
+ return getFormEditorApp().getFormElementDefinition(formElement, formElementDefinitionKey);
149
+ }
150
+
151
+ /**
152
+ * @publish view/inspector/editor/insert/perform
153
+ */
154
+ function renderEditorDispatcher(
155
+ editorConfiguration: EditorConfiguration,
156
+ editorHtml: HTMLElement | JQuery,
157
+ collectionElementIdentifier?: string,
158
+ collectionName?: keyof FormEditorDefinitions
159
+ ): void {
160
+ switch (editorConfiguration.templateName) {
161
+ case 'Inspector-FormElementHeaderEditor':
162
+ renderFormElementHeaderEditor(
163
+ editorConfiguration,
164
+ editorHtml
165
+ );
166
+ break;
167
+ case 'Inspector-CollectionElementHeaderEditor':
168
+ renderCollectionElementHeaderEditor(
169
+ editorConfiguration,
170
+ editorHtml,
171
+ collectionElementIdentifier,
172
+ collectionName
173
+ );
174
+ break;
175
+ case 'Inspector-MaximumFileSizeEditor':
176
+ renderFileMaxSizeEditor(
177
+ editorConfiguration,
178
+ editorHtml
179
+ );
180
+ break;
181
+ case 'Inspector-TextEditor':
182
+ renderTextEditor(
183
+ editorConfiguration,
184
+ editorHtml,
185
+ collectionElementIdentifier,
186
+ collectionName
187
+ );
188
+ break;
189
+ case 'Inspector-FinishersEditor':
190
+ renderCollectionElementSelectionEditor(
191
+ 'finishers',
192
+ editorConfiguration,
193
+ editorHtml
194
+ );
195
+ break;
196
+ case 'Inspector-ValidatorsEditor':
197
+ renderCollectionElementSelectionEditor(
198
+ 'validators',
199
+ editorConfiguration,
200
+ editorHtml
201
+ );
202
+ break;
203
+ case 'Inspector-ValidationErrorMessageEditor':
204
+ renderValidationErrorMessageEditor(
205
+ editorConfiguration,
206
+ editorHtml
207
+ );
208
+ break;
209
+ case 'Inspector-RemoveElementEditor':
210
+ renderRemoveElementEditor(
211
+ editorConfiguration,
212
+ editorHtml,
213
+ collectionElementIdentifier,
214
+ collectionName
215
+ );
216
+ break;
217
+ case 'Inspector-RequiredValidatorEditor':
218
+ renderRequiredValidatorEditor(
219
+ editorConfiguration,
220
+ editorHtml,
221
+ collectionElementIdentifier,
222
+ collectionName
223
+ );
224
+ break;
225
+ case 'Inspector-CheckboxEditor':
226
+ renderCheckboxEditor(
227
+ editorConfiguration,
228
+ editorHtml,
229
+ collectionElementIdentifier,
230
+ collectionName
231
+ );
232
+ break;
233
+ case 'Inspector-CountrySelectEditor':
234
+ renderCountrySelectEditor(
235
+ editorConfiguration,
236
+ editorHtml,
237
+ collectionElementIdentifier,
238
+ collectionName
239
+ );
240
+ break;
241
+ case 'Inspector-SingleSelectEditor':
242
+ renderSingleSelectEditor(
243
+ editorConfiguration,
244
+ editorHtml,
245
+ collectionElementIdentifier,
246
+ collectionName
247
+ );
248
+ break;
249
+ case 'Inspector-MultiSelectEditor':
250
+ renderMultiSelectEditor(
251
+ editorConfiguration,
252
+ editorHtml,
253
+ collectionElementIdentifier,
254
+ collectionName
255
+ );
256
+ break;
257
+ case 'Inspector-GridColumnViewPortConfigurationEditor':
258
+ renderGridColumnViewPortConfigurationEditor(
259
+ editorConfiguration,
260
+ editorHtml
261
+ );
262
+ break;
263
+ case 'Inspector-PropertyGridEditor':
264
+ renderPropertyGridEditor(
265
+ editorConfiguration,
266
+ editorHtml,
267
+ collectionElementIdentifier,
268
+ collectionName
269
+ );
270
+ break;
271
+ case 'Inspector-TextareaEditor':
272
+ renderTextareaEditor(
273
+ editorConfiguration,
274
+ editorHtml,
275
+ collectionElementIdentifier,
276
+ collectionName
277
+ );
278
+ break;
279
+ case 'Inspector-Typo3WinBrowserEditor':
280
+ renderTypo3WinBrowserEditor(
281
+ editorConfiguration,
282
+ editorHtml,
283
+ collectionElementIdentifier,
284
+ collectionName
285
+ );
286
+ break;
287
+ default:
288
+ break;
289
+ }
290
+ getPublisherSubscriber().publish('view/inspector/editor/insert/perform', [
291
+ editorConfiguration, editorHtml, collectionElementIdentifier, collectionName
292
+ ]);
293
+ }
294
+
295
+ /**
296
+ * opens a popup window with the element browser
297
+ */
298
+ function openTypo3WinBrowser(mode: string, params: string): void {
299
+ Modal.advanced({
300
+ type: Modal.types.iframe,
301
+ content: TYPO3.settings.FormEditor.typo3WinBrowserUrl + '&mode=' + mode + '&bparams=' + params,
302
+ size: Modal.sizes.large
303
+ });
304
+ }
305
+
306
+ /**
307
+ * Listens on messages sent by ElementBrowser
308
+ */
309
+ function listenOnElementBrowser(): void {
310
+ window.addEventListener('message', function (e) {
311
+ if (!MessageUtility.verifyOrigin(e.origin)) {
312
+ throw 'Denied message sent by ' + e.origin;
313
+ }
314
+
315
+ if (e.data.actionName === 'typo3:elementBrowser:elementAdded') {
316
+ if (typeof e.data.fieldName === 'undefined') {
317
+ throw 'fieldName not defined in message';
318
+ }
319
+
320
+ if (typeof e.data.value === 'undefined') {
321
+ throw 'value not defined in message';
322
+ }
323
+
324
+ const result = e.data.value.split('_');
325
+ $(getHelper().getDomElementDataAttribute('contentElementSelectorTarget', 'bracesWithKeyValue', [e.data.fieldName]))
326
+ .val(result.pop())
327
+ .trigger('paste');
328
+ }
329
+ });
330
+ }
331
+
332
+ function getCollectionElementClass(
333
+ collectionName: keyof FormEditorDefinitions,
334
+ collectionElementIdentifier: string
335
+ ): string {
336
+ if (collectionName === 'finishers') {
337
+ return getHelper()
338
+ .getDomElementClassName('finisherEditorPrefix') + collectionElementIdentifier;
339
+ } else {
340
+ return getHelper()
341
+ .getDomElementClassName('validatorEditorPrefix') + collectionElementIdentifier;
342
+ }
343
+ }
344
+
345
+ function getCollectionElementId(
346
+ collectionName: keyof FormEditorDefinitions,
347
+ collectionElementIdentifier: string,
348
+ asSelector?: boolean
349
+ ): string {
350
+ if (collectionName === 'finishers') {
351
+ return getHelper()
352
+ .getDomElementIdName('finisherPrefix', asSelector) + collectionElementIdentifier;
353
+ } else {
354
+ return getHelper()
355
+ .getDomElementIdName('validatorPrefix', asSelector) + collectionElementIdentifier;
356
+ }
357
+ }
358
+
359
+ function addSortableCollectionElementsEvents(
360
+ sortableDomElement: JQuery,
361
+ collectionName: keyof FormEditorDefinitions,
362
+ ): void {
363
+ sortableDomElement.addClass(getHelper().getDomElementClassName('sortable'));
364
+ new Sortable(sortableDomElement.get(0), {
365
+ draggable: getHelper().getDomElementClassName('collectionElement', true),
366
+ filter: 'input,textarea,select',
367
+ preventOnFilter: false,
368
+ animation: 200,
369
+ fallbackTolerance: 200,
370
+ swapThreshold: 0.6,
371
+ dragClass: 'formeditor-sortable-drag',
372
+ ghostClass: 'formeditor-sortable-ghost',
373
+ onEnd: function (e) {
374
+ let dataAttributeName;
375
+
376
+ if (collectionName === 'finishers') {
377
+ dataAttributeName = getHelper().getDomElementDataAttribute('finisher');
378
+ } else {
379
+ dataAttributeName = getHelper().getDomElementDataAttribute('validator');
380
+ }
381
+
382
+ const movedCollectionElementIdentifier = $(e.item).attr(dataAttributeName);
383
+ const previousCollectionElementIdentifier = $(e.item)
384
+ .prevAll(getHelper().getDomElementClassName('collectionElement', true))
385
+ .first()
386
+ .attr(dataAttributeName);
387
+ const nextCollectionElementIdentifier = $(e.item)
388
+ .nextAll(getHelper().getDomElementClassName('collectionElement', true))
389
+ .first()
390
+ .attr(dataAttributeName);
391
+
392
+ getPublisherSubscriber().publish('view/inspector/collectionElements/dnd/update', [
393
+ movedCollectionElementIdentifier,
394
+ previousCollectionElementIdentifier,
395
+ nextCollectionElementIdentifier,
396
+ collectionName
397
+ ]);
398
+ }
399
+ });
400
+ }
401
+
402
+ function getEditorWrapperDomElement(editorDomElement: HTMLElement | JQuery): JQuery {
403
+ return $(getHelper().getDomElementDataIdentifierSelector('editorWrapper'), $(editorDomElement));
404
+ }
405
+
406
+ function getEditorControlsWrapperDomElement(editorDomElement: HTMLElement | JQuery): JQuery {
407
+ return $(getHelper().getDomElementDataIdentifierSelector('editorControlsWrapper'), $(editorDomElement));
408
+ }
409
+
410
+ function validateCollectionElement(propertyPath: string, editorHtml: HTMLElement | JQuery): void {
411
+ let hasError, propertyPrefix, validationResults;
412
+
413
+ validationResults = getFormEditorApp().validateCurrentlySelectedFormElementProperty(propertyPath);
414
+
415
+ if (validationResults.length > 0) {
416
+ getHelper()
417
+ .getTemplatePropertyDomElement('validationErrors', editorHtml)
418
+ .html('<span class="text-danger">' + validationResults[0] + '</span>');
419
+ getViewModel().setElementValidationErrorClass(
420
+ getEditorControlsWrapperDomElement(editorHtml),
421
+ 'hasError'
422
+ );
423
+ } else {
424
+ getHelper().getTemplatePropertyDomElement('validationErrors', editorHtml).html('');
425
+ getViewModel().removeElementValidationErrorClass(
426
+ getEditorControlsWrapperDomElement(editorHtml),
427
+ 'hasError'
428
+ );
429
+ }
430
+
431
+ validationResults = getFormEditorApp().validateFormElement(getCurrentlySelectedFormElement());
432
+ propertyPrefix = propertyPath.split('.');
433
+ propertyPrefix = propertyPrefix[0] + '.' + propertyPrefix[1];
434
+
435
+ hasError = false;
436
+ for (let i = 0, len = validationResults.length; i < len; ++i) {
437
+ if (
438
+ validationResults[i].propertyPath.indexOf(propertyPrefix, 0) === 0
439
+ && validationResults[i].validationResults
440
+ && validationResults[i].validationResults.length > 0
441
+ ) {
442
+ hasError = true;
443
+ break;
444
+ }
445
+ }
446
+
447
+ if (hasError) {
448
+ getViewModel().setElementValidationErrorClass(
449
+ getEditorControlsWrapperDomElement(editorHtml).closest(getHelper().getDomElementClassName('collectionElement', true))
450
+ );
451
+ } else {
452
+ getViewModel().removeElementValidationErrorClass(
453
+ getEditorControlsWrapperDomElement(editorHtml).closest(getHelper().getDomElementClassName('collectionElement', true))
454
+ );
455
+ }
456
+ }
457
+
458
+ /**
459
+ * @throws 1489932939
460
+ * @throws 1489932940
461
+ */
462
+ function getFirstAvailableValidationErrorMessage(errorCodes: string[], propertyData: PropertyData): string | null {
463
+ assert(
464
+ 'array' === $.type(errorCodes),
465
+ 'Invalid configuration "errorCodes"',
466
+ 1489932939
467
+ );
468
+ assert(
469
+ 'array' === $.type(propertyData),
470
+ 'Invalid configuration "propertyData"',
471
+ 1489932940
472
+ );
473
+
474
+ for (let i = 0, len1 = errorCodes.length; i < len1; ++i) {
475
+ for (let j = 0, len2 = propertyData.length; j < len2; ++j) {
476
+ if (parseInt(errorCodes[i], 10) === parseInt(propertyData[j].code, 10)) {
477
+ if (getUtility().isNonEmptyString(propertyData[j].message)) {
478
+ return propertyData[j].message;
479
+ }
480
+ }
481
+ }
482
+ }
483
+
484
+ return null;
485
+ }
486
+
487
+ /**
488
+ * @throws 1489932942
489
+ */
490
+ function renewValidationErrorMessages(
491
+ errorCodes: string[],
492
+ propertyData: PropertyData,
493
+ value: string
494
+ ): PropertyData {
495
+ assert(
496
+ 'array' === $.type(propertyData),
497
+ 'Invalid configuration "propertyData"',
498
+ 1489932942
499
+ );
500
+
501
+ if (
502
+ !getUtility().isUndefinedOrNull(errorCodes)
503
+ && 'array' === $.type(errorCodes)
504
+ ) {
505
+ const errorCodeSubset: PropertyData = [];
506
+ for (let i = 0, len1 = errorCodes.length; i < len1; ++i) {
507
+ let errorCodeFound = false;
508
+
509
+ for (let j = 0, len2 = propertyData.length; j < len2; ++j) {
510
+ if (parseInt(errorCodes[i], 10) === parseInt(propertyData[j].code, 10)) {
511
+ errorCodeFound = true;
512
+ if (getUtility().isNonEmptyString(value)) {
513
+ // error code exists and should be updated because message is not empty
514
+ propertyData[j].message = value;
515
+ } else {
516
+ // error code exists but should be removed because message is empty
517
+ propertyData.splice(j, 1);
518
+ --len2;
519
+ }
520
+ }
521
+ }
522
+
523
+ if (!errorCodeFound) {
524
+ // add new codes because message is not empty
525
+ if (getUtility().isNonEmptyString(value)) {
526
+ errorCodeSubset.push({
527
+ code: errorCodes[i],
528
+ message: value
529
+ });
530
+ }
531
+ }
532
+ }
533
+
534
+ propertyData = propertyData.concat(errorCodeSubset);
535
+ }
536
+
537
+ return propertyData;
538
+ }
539
+
540
+ /**
541
+ * @throws 1523904699
542
+ */
543
+ function setRandomIds(html: JQuery): void {
544
+ assert(
545
+ 'object' === $.type(html),
546
+ 'Invalid input "html"',
547
+ 1523904699
548
+ );
549
+
550
+ $(getHelper().getDomElementClassName('inspectorEditor', true)).each(function(this: HTMLElement) {
551
+ const $parent = $(this);
552
+ const idReplacements: Record<string, string> = {};
553
+
554
+ $(getHelper().getDomElementDataAttribute('randomId', 'bracesWithKey'), $parent).each(function(this: HTMLElement) {
555
+ const $element = $(this),
556
+ targetAttribute = $element.attr(getHelper().getDomElementDataAttribute('randomIdTarget')),
557
+ randomIdIndex = $element.attr(getHelper().getDomElementDataAttribute('randomIdIndex'));
558
+
559
+ if ($element.is('[' + targetAttribute + ']')) {
560
+ return;
561
+ }
562
+
563
+ if (!(randomIdIndex in idReplacements)) {
564
+ idReplacements[randomIdIndex] = 'fe' + Math.floor(Math.random() * 42) + Date.now();
565
+ }
566
+ $element.attr(targetAttribute, idReplacements[randomIdIndex]);
567
+ });
568
+ });
569
+ }
570
+
571
+ export function getInspectorDomElement(): JQuery {
572
+ return $(getHelper().getDomElementDataIdentifierSelector('inspector'));
573
+ }
574
+
575
+ export function getFinishersContainerDomElement(): JQuery {
576
+ return $(getHelper().getDomElementDataIdentifierSelector('inspectorFinishers'), getInspectorDomElement());
577
+ }
578
+
579
+ export function getValidatorsContainerDomElement(): JQuery {
580
+ return $(getHelper().getDomElementDataIdentifierSelector('inspectorValidators'), getInspectorDomElement());
581
+ }
582
+
583
+ export function getCollectionElementDomElement(
584
+ collectionName: keyof FormEditorDefinitions,
585
+ collectionElementIdentifier: string
586
+ ): JQuery {
587
+ if (collectionName === 'finishers') {
588
+ return $(getHelper().getDomElementDataAttribute(
589
+ 'finisher',
590
+ 'bracesWithKeyValue',
591
+ [collectionElementIdentifier]
592
+ ), getFinishersContainerDomElement());
593
+ } else {
594
+ return $(getHelper().getDomElementDataAttribute(
595
+ 'validator',
596
+ 'bracesWithKeyValue',
597
+ [collectionElementIdentifier]
598
+ ), getValidatorsContainerDomElement());
599
+ }
600
+ }
601
+
602
+ export function renderEditors(
603
+ formElement?: FormElement | string,
604
+ callback?: () => void
605
+ ): void {
606
+ if (getUtility().isUndefinedOrNull(formElement)) {
607
+ formElement = getCurrentlySelectedFormElement();
608
+ }
609
+
610
+ getInspectorDomElement().off().empty();
611
+
612
+ const formElementTypeDefinition = getFormElementDefinition(formElement, undefined);
613
+ if ('array' !== $.type(formElementTypeDefinition.editors)) {
614
+ return;
615
+ }
616
+
617
+ for (let i = 0, len = formElementTypeDefinition.editors.length; i < len; ++i) {
618
+ const template = getHelper()
619
+ .getTemplate(formElementTypeDefinition.editors[i].templateName)
620
+ .clone();
621
+ if (!template.length) {
622
+ continue;
623
+ }
624
+ const html = $(template.html());
625
+
626
+ $(html)
627
+ .first()
628
+ .addClass(getHelper().getDomElementClassName('inspectorEditor'));
629
+ getInspectorDomElement().append($(html));
630
+
631
+ setRandomIds(html);
632
+ renderEditorDispatcher(formElementTypeDefinition.editors[i], html);
633
+ }
634
+
635
+ if ('function' === $.type(callback)) {
636
+ callback();
637
+ }
638
+ }
639
+
640
+ /**
641
+ * @publish view/inspector/collectionElements/dnd/update
642
+ * @throws 1478354853
643
+ * @throws 1478354854
644
+ */
645
+ export function renderCollectionElementEditors(
646
+ collectionName: keyof FormEditorDefinitions,
647
+ collectionElementIdentifier: string
648
+ ): void {
649
+ let collapseWrapper, collapsePanel, collectionContainer;
650
+
651
+ assert(
652
+ getUtility().isNonEmptyString(collectionName),
653
+ 'Invalid parameter "collectionName"',
654
+ 1478354853
655
+ );
656
+ assert(
657
+ getUtility().isNonEmptyString(collectionElementIdentifier),
658
+ 'Invalid parameter "collectionElementIdentifier"',
659
+ 1478354854
660
+ );
661
+
662
+ const collectionElementConfiguration = getFormEditorApp().getPropertyCollectionElementConfiguration(
663
+ collectionElementIdentifier,
664
+ collectionName
665
+ );
666
+ if ('array' !== $.type(collectionElementConfiguration.editors)) {
667
+ return;
668
+ }
669
+
670
+ const collectionContainerElementWrapper = $('<div></div>')
671
+ .addClass(getHelper().getDomElementClassName('collectionElement'))
672
+ .addClass('panel')
673
+ .addClass('panel-default');
674
+ if (collectionName === 'finishers') {
675
+ collectionContainer = getFinishersContainerDomElement();
676
+ collectionContainerElementWrapper
677
+ .attr(getHelper().getDomElementDataAttribute('finisher'), collectionElementIdentifier);
678
+ } else {
679
+ collectionContainer = getValidatorsContainerDomElement();
680
+ collectionContainerElementWrapper
681
+ .attr(getHelper().getDomElementDataAttribute('validator'), collectionElementIdentifier);
682
+ }
683
+ collectionContainer.append(collectionContainerElementWrapper);
684
+
685
+ const collectionElementEditorsLength = collectionElementConfiguration.editors.length;
686
+ if (
687
+ collectionElementEditorsLength > 0
688
+ && collectionElementConfiguration.editors[0].identifier === 'header'
689
+ ) {
690
+ collapsePanel = document.createElement('div');
691
+ collapsePanel.classList.add('panel-body');
692
+ collapseWrapper = document.createElement('div');
693
+ collapseWrapper.classList.add('panel-collapse', 'collapse');
694
+ collapseWrapper.id = getCollectionElementId(collectionName, collectionElementIdentifier);
695
+ collapseWrapper.appendChild(collapsePanel);
696
+ }
697
+
698
+ for (let i = 0; i < collectionElementEditorsLength; ++i) {
699
+ const template = getHelper()
700
+ .getTemplate(collectionElementConfiguration.editors[i].templateName)
701
+ .clone();
702
+ if (!template.length) {
703
+ continue;
704
+ }
705
+ const html = $(template.html());
706
+
707
+ $(html).first()
708
+ .addClass(getCollectionElementClass(
709
+ collectionName,
710
+ collectionElementConfiguration.editors[i].identifier
711
+ ))
712
+ .addClass(getHelper().getDomElementClassName('inspectorEditor'));
713
+
714
+ if (i === 0 && collapseWrapper) {
715
+ getCollectionElementDomElement(collectionName, collectionElementIdentifier)
716
+ .append(html)
717
+ .append(collapseWrapper);
718
+ } else if (
719
+ i === (collectionElementEditorsLength - 1)
720
+ && collapseWrapper
721
+ && collectionElementConfiguration.editors[i].identifier === 'removeButton'
722
+ ) {
723
+ collapsePanel.append(html.get(0));
724
+ } else if (i > 0 && collapseWrapper) {
725
+ collapsePanel.append(html.get(0));
726
+ } else {
727
+ getCollectionElementDomElement(collectionName, collectionElementIdentifier).append(html);
728
+ }
729
+
730
+ setRandomIds(html);
731
+ renderEditorDispatcher(
732
+ collectionElementConfiguration.editors[i],
733
+ html,
734
+ collectionElementIdentifier,
735
+ collectionName
736
+ );
737
+ }
738
+
739
+ if (
740
+ (
741
+ collectionElementEditorsLength === 2
742
+ && collectionElementConfiguration.editors[0].identifier === 'header'
743
+ && collectionElementConfiguration.editors[1].identifier === 'removeButton'
744
+ ) || (
745
+ collectionElementEditorsLength === 1
746
+ && collectionElementConfiguration.editors[0].identifier === 'header'
747
+ )
748
+ ) {
749
+ $(getHelper().getDomElementDataIdentifierSelector('collapse'), collectionContainerElementWrapper).remove();
750
+ }
751
+
752
+ if (configuration.isSortable) {
753
+ addSortableCollectionElementsEvents(collectionContainer, collectionName);
754
+ }
755
+ }
756
+
757
+ /**
758
+ * @publish view/inspector/collectionElement/existing/selected
759
+ * @publish view/inspector/collectionElement/new/selected
760
+ * @throws 1475423098
761
+ * @throws 1475423099
762
+ * @throws 1475423100
763
+ * @throws 1475423101
764
+ * @throws 1478362968
765
+ */
766
+ export function renderCollectionElementSelectionEditor(
767
+ collectionName: keyof FormEditorDefinitions,
768
+ editorConfiguration: EditorConfiguration,
769
+ editorHtml: HTMLElement | JQuery,
770
+ ): void {
771
+ let alreadySelectedCollectionElements, collectionContainer,
772
+ removeSelectElement;
773
+ assert(
774
+ getUtility().isNonEmptyString(collectionName),
775
+ 'Invalid configuration "collectionName"',
776
+ 1478362968
777
+ );
778
+ assert(
779
+ 'object' === $.type(editorConfiguration),
780
+ 'Invalid parameter "editorConfiguration"',
781
+ 1475423098
782
+ );
783
+ assert(
784
+ 'object' === $.type(editorHtml),
785
+ 'Invalid parameter "editorHtml"',
786
+ 1475423099
787
+ );
788
+ assert(
789
+ getUtility().isNonEmptyString(editorConfiguration.label),
790
+ 'Invalid configuration "label"',
791
+ 1475423100
792
+ );
793
+ assert(
794
+ 'array' === $.type(editorConfiguration.selectOptions),
795
+ 'Invalid configuration "selectOptions"',
796
+ 1475423101
797
+ );
798
+
799
+ if (collectionName === 'finishers') {
800
+ collectionContainer = getFinishersContainerDomElement();
801
+ alreadySelectedCollectionElements = getRootFormElement().get(collectionName);
802
+ } else {
803
+ collectionContainer = getValidatorsContainerDomElement();
804
+ alreadySelectedCollectionElements = getCurrentlySelectedFormElement().get(collectionName);
805
+ }
806
+
807
+ collectionContainer.off().empty();
808
+
809
+ getHelper().getTemplatePropertyDomElement('label', editorHtml).text(editorConfiguration.label);
810
+ const selectElement = getHelper().getTemplatePropertyDomElement('selectOptions', editorHtml);
811
+ const hasAlreadySelectedCollectionElements = (
812
+ !getUtility().isUndefinedOrNull(alreadySelectedCollectionElements) &&
813
+ alreadySelectedCollectionElements.length > 0
814
+ );
815
+
816
+ if (hasAlreadySelectedCollectionElements) {
817
+ for (let i = 0, len = alreadySelectedCollectionElements.length; i < len; ++i) {
818
+ getPublisherSubscriber().publish('view/inspector/collectionElement/existing/selected', [
819
+ alreadySelectedCollectionElements[i].identifier,
820
+ collectionName
821
+ ]);
822
+ }
823
+ }
824
+
825
+ removeSelectElement = true;
826
+ for (let i = 0, len1 = editorConfiguration.selectOptions.length; i < len1; ++i) {
827
+ let appendOption = true;
828
+ if (!getUtility().isUndefinedOrNull(alreadySelectedCollectionElements)) {
829
+ for (let j = 0, len2 = alreadySelectedCollectionElements.length; j < len2; ++j) {
830
+ if (alreadySelectedCollectionElements[j].identifier === editorConfiguration.selectOptions[i].value) {
831
+ appendOption = false;
832
+ break;
833
+ }
834
+ }
835
+ }
836
+ if (appendOption) {
837
+ selectElement.append(new Option(
838
+ editorConfiguration.selectOptions[i].label,
839
+ editorConfiguration.selectOptions[i].value
840
+ ));
841
+ if (editorConfiguration.selectOptions[i].value !== '') {
842
+ removeSelectElement = false;
843
+ }
844
+ }
845
+ }
846
+
847
+ if (removeSelectElement) {
848
+ getHelper()
849
+ .getTemplatePropertyDomElement('select-group', editorHtml)
850
+ .off()
851
+ .empty()
852
+ .remove();
853
+ const labelNoSelect = getHelper()
854
+ .getTemplatePropertyDomElement('label-no-select', editorHtml);
855
+ if (hasAlreadySelectedCollectionElements) {
856
+ labelNoSelect.text(editorConfiguration.label);
857
+ } else {
858
+ labelNoSelect.remove();
859
+ }
860
+ return;
861
+ }
862
+
863
+ getHelper().getTemplatePropertyDomElement('label-no-select', editorHtml).remove();
864
+
865
+ selectElement.on('change', function(this: HTMLSelectElement) {
866
+ if ($(this).val() !== '') {
867
+ const value = $(this).val();
868
+ $(selector`option[value="${value}"]`, $(this)).remove();
869
+
870
+ getFormEditorApp().getPublisherSubscriber().publish(
871
+ 'view/inspector/collectionElement/new/selected',
872
+ [value, collectionName]
873
+ );
874
+ }
875
+ });
876
+ }
877
+
878
+ /**
879
+ * @throws 1475421525
880
+ * @throws 1475421526
881
+ * @throws 1475421527
882
+ * @throws 1475421528
883
+ */
884
+ export function renderFormElementHeaderEditor(
885
+ editorConfiguration: EditorConfiguration,
886
+ editorHtml: HTMLElement | JQuery,
887
+ ): void {
888
+ assert('object' === $.type(editorConfiguration), 'Invalid parameter "editorConfiguration"', 1475421525);
889
+ assert('object' === $.type(editorHtml), 'Invalid parameter "editorHtml"', 1475421526);
890
+
891
+ Icons.getIcon(
892
+ getFormElementDefinition(getCurrentlySelectedFormElement(), 'iconIdentifier'),
893
+ Icons.sizes.small,
894
+ null,
895
+ Icons.states.default
896
+ ).then(function(icon) {
897
+ getHelper().getTemplatePropertyDomElement('header-label', editorHtml)
898
+ .append($(icon).addClass(getHelper().getDomElementClassName('icon')))
899
+ .append(buildTitleByFormElement())
900
+ .append('<code>' + getCurrentlySelectedFormElement().get('identifier') + '</code>');
901
+ });
902
+ }
903
+
904
+ /**
905
+ * @throws 1475421257
906
+ * @throws 1475421258
907
+ * @throws 1475421259
908
+ */
909
+ export function renderCollectionElementHeaderEditor(
910
+ editorConfiguration: EditorConfiguration,
911
+ editorHtml: HTMLElement | JQuery,
912
+ collectionElementIdentifier: string,
913
+ collectionName: keyof FormEditorDefinitions
914
+ ): void {
915
+ assert(
916
+ 'object' === $.type(editorConfiguration),
917
+ 'Invalid parameter "editorConfiguration"',
918
+ 1475421258
919
+ );
920
+ assert(
921
+ getUtility().isNonEmptyString(editorConfiguration.label),
922
+ 'Invalid configuration "label"',
923
+ 1475421257
924
+ );
925
+ assert(
926
+ 'object' === $.type(editorHtml),
927
+ 'Invalid parameter "editorHtml"',
928
+ 1475421259
929
+ );
930
+
931
+ const setData = function(icon?: string) {
932
+ const iconPlaceholder = getHelper()
933
+ .getTemplatePropertyDomElement('panel-icon', editorHtml);
934
+ if (icon) {
935
+ iconPlaceholder.replaceWith(icon);
936
+ } else {
937
+ iconPlaceholder.remove();
938
+ }
939
+
940
+ const editors = getFormEditorApp().getPropertyCollectionElementConfiguration(
941
+ collectionElementIdentifier,
942
+ collectionName
943
+ ).editors;
944
+
945
+ if (!(
946
+ (editors.length === 2 && editors[0].identifier === 'header' && editors[1].identifier === 'removeButton') ||
947
+ (editors.length === 1 && editors[0].identifier === 'header')
948
+ )) {
949
+ const button = document.createElement('button');
950
+ button.classList.add('panel-button', 'collapsed');
951
+ button.setAttribute('type', 'button');
952
+ button.setAttribute('data-bs-toggle', 'collapse');
953
+ button.setAttribute('data-bs-target', getCollectionElementId(collectionName, collectionElementIdentifier, true));
954
+ button.setAttribute('aria-expaned', 'false');
955
+ button.setAttribute('aria-controls', getCollectionElementId(collectionName, collectionElementIdentifier));
956
+
957
+ const caret = document.createElement('span');
958
+ caret.classList.add('caret');
959
+ getHelper()
960
+ .getTemplatePropertyDomElement('panel-heading-row', editorHtml)
961
+ .find('.panel-title')
962
+ .before(caret);
963
+ getHelper()
964
+ .getTemplatePropertyDomElement('panel-heading-row', editorHtml)
965
+ .wrapInner(button);
966
+ }
967
+
968
+ // Move delete button
969
+ const collectionElement = getCollectionElementDomElement(collectionName, collectionElementIdentifier).get(0);
970
+ const removeButtonElement = collectionElement.querySelector('.formeditor-inspector-element-remove-button');
971
+ if (removeButtonElement) {
972
+ const removeButton = removeButtonElement.querySelector('button');
973
+ removeButton.classList.add('btn-sm');
974
+ removeButton.querySelector('.btn-label').classList.add('visually-hidden');
975
+ const panelActions = document.createElement('div');
976
+ panelActions.classList.add('panel-actions');
977
+ panelActions.append(removeButton);
978
+ getHelper()
979
+ .getTemplatePropertyDomElement('panel-heading-row', editorHtml)
980
+ .append(panelActions);
981
+ }
982
+ removeButtonElement?.remove();
983
+ };
984
+
985
+ const collectionElementConfiguration = getFormEditorApp().getFormEditorDefinition(collectionName, collectionElementIdentifier);
986
+ if ('iconIdentifier' in collectionElementConfiguration) {
987
+ Icons.getIcon(
988
+ collectionElementConfiguration.iconIdentifier,
989
+ Icons.sizes.small,
990
+ null,
991
+ Icons.states.default
992
+ ).then(function(icon) {
993
+ setData(icon);
994
+ });
995
+ } else {
996
+ setData();
997
+ }
998
+
999
+ if (editorConfiguration.label) {
1000
+ getHelper()
1001
+ .getTemplatePropertyDomElement('panel-title', editorHtml)
1002
+ .removeAttr('data-template-property')
1003
+ .append(editorConfiguration.label);
1004
+ }
1005
+ }
1006
+
1007
+ export function renderFileMaxSizeEditor(
1008
+ editorConfiguration: EditorConfiguration,
1009
+ editorHtml: HTMLElement | JQuery,
1010
+ ): void {
1011
+ assert(
1012
+ 'object' === $.type(editorConfiguration),
1013
+ 'Invalid parameter "editorConfiguration"',
1014
+ 1475421258
1015
+ );
1016
+ assert(
1017
+ getUtility().isNonEmptyString(editorConfiguration.label),
1018
+ 'Invalid configuration "label"',
1019
+ 1475421257
1020
+ );
1021
+ assert(
1022
+ 'object' === $.type(editorHtml),
1023
+ 'Invalid parameter "editorHtml"',
1024
+ 1475421259
1025
+ );
1026
+
1027
+ if (editorConfiguration.label) {
1028
+ const element = getHelper().getTemplatePropertyDomElement('label', editorHtml);
1029
+ const maximumFileSize = element.attr(getHelper().getDomElementDataAttribute('maximumFileSize'));
1030
+ element.append(editorConfiguration.label.replace('{0}', maximumFileSize));
1031
+ }
1032
+ }
1033
+
1034
+ /**
1035
+ * @throws 1475421053
1036
+ * @throws 1475421054
1037
+ * @throws 1475421055
1038
+ * @throws 1475421056
1039
+ */
1040
+ export function renderTextEditor(
1041
+ editorConfiguration: EditorConfiguration,
1042
+ editorHtml: HTMLElement | JQuery,
1043
+ collectionElementIdentifier: string,
1044
+ collectionName: keyof FormEditorDefinitions
1045
+ ): void {
1046
+ assert(
1047
+ 'object' === $.type(editorConfiguration),
1048
+ 'Invalid parameter "editorConfiguration"',
1049
+ 1475421053
1050
+ );
1051
+ assert(
1052
+ 'object' === $.type(editorHtml),
1053
+ 'Invalid parameter "editorHtml"',
1054
+ 1475421054
1055
+ );
1056
+ assert(
1057
+ getUtility().isNonEmptyString(editorConfiguration.label),
1058
+ 'Invalid configuration "label"',
1059
+ 1475421055
1060
+ );
1061
+ assert(
1062
+ getUtility().isNonEmptyString(editorConfiguration.propertyPath),
1063
+ 'Invalid configuration "propertyPath"',
1064
+ 1475421056
1065
+ );
1066
+
1067
+ getHelper()
1068
+ .getTemplatePropertyDomElement('label', editorHtml)
1069
+ .append(editorConfiguration.label);
1070
+ if (getUtility().isNonEmptyString(editorConfiguration.fieldExplanationText)) {
1071
+ getHelper()
1072
+ .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
1073
+ .text(editorConfiguration.fieldExplanationText);
1074
+ } else {
1075
+ getHelper()
1076
+ .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
1077
+ .remove();
1078
+ }
1079
+
1080
+ if (getUtility().isNonEmptyString(editorConfiguration.placeholder)) {
1081
+ getHelper()
1082
+ .getTemplatePropertyDomElement('propertyPath', editorHtml)
1083
+ .attr('placeholder', editorConfiguration.placeholder);
1084
+ }
1085
+
1086
+ const propertyPath = getFormEditorApp().buildPropertyPath(
1087
+ editorConfiguration.propertyPath,
1088
+ collectionElementIdentifier,
1089
+ collectionName
1090
+ );
1091
+ const propertyData = getCurrentlySelectedFormElement().get(propertyPath);
1092
+
1093
+ validateCollectionElement(propertyPath, editorHtml);
1094
+
1095
+ getHelper().getTemplatePropertyDomElement('propertyPath', editorHtml).val(propertyData);
1096
+
1097
+ if (
1098
+ !getUtility().isUndefinedOrNull(editorConfiguration.additionalElementPropertyPaths)
1099
+ && 'array' === $.type(editorConfiguration.additionalElementPropertyPaths)
1100
+ ) {
1101
+ for (let i = 0, len = editorConfiguration.additionalElementPropertyPaths.length; i < len; ++i) {
1102
+ getCurrentlySelectedFormElement().set(editorConfiguration.additionalElementPropertyPaths[i], propertyData);
1103
+ }
1104
+ }
1105
+
1106
+ renderFormElementSelectorEditorAddition(editorConfiguration, editorHtml, propertyPath);
1107
+
1108
+ getHelper().getTemplatePropertyDomElement('propertyPath', editorHtml).on('keyup paste', function(this: HTMLInputElement) {
1109
+ if (
1110
+ !!editorConfiguration.doNotSetIfPropertyValueIsEmpty
1111
+ && !getUtility().isNonEmptyString($(this).val())
1112
+ ) {
1113
+ getCurrentlySelectedFormElement().unset(propertyPath);
1114
+ } else {
1115
+ getCurrentlySelectedFormElement().set(propertyPath, $(this).val());
1116
+ }
1117
+ validateCollectionElement(propertyPath, editorHtml);
1118
+ if (
1119
+ !getUtility().isUndefinedOrNull(editorConfiguration.additionalElementPropertyPaths)
1120
+ && 'array' === $.type(editorConfiguration.additionalElementPropertyPaths)
1121
+ ) {
1122
+ for (let i = 0, len = editorConfiguration.additionalElementPropertyPaths.length; i < len; ++i) {
1123
+ if (
1124
+ !!editorConfiguration.doNotSetIfPropertyValueIsEmpty
1125
+ && !getUtility().isNonEmptyString($(this).val())
1126
+ ) {
1127
+ getCurrentlySelectedFormElement().unset(editorConfiguration.additionalElementPropertyPaths[i]);
1128
+ } else {
1129
+ getCurrentlySelectedFormElement().set(editorConfiguration.additionalElementPropertyPaths[i], $(this).val());
1130
+ }
1131
+ }
1132
+ }
1133
+ });
1134
+ }
1135
+
1136
+ /**
1137
+ * @throws 1489874120
1138
+ * @throws 1489874121
1139
+ * @throws 1489874122
1140
+ * @throws 1489874123
1141
+ */
1142
+ export function renderValidationErrorMessageEditor(
1143
+ editorConfiguration: EditorConfiguration,
1144
+ editorHtml: HTMLElement | JQuery
1145
+ ): void {
1146
+ assert(
1147
+ 'object' === $.type(editorConfiguration),
1148
+ 'Invalid parameter "editorConfiguration"',
1149
+ 1489874121
1150
+ );
1151
+ assert(
1152
+ 'object' === $.type(editorHtml),
1153
+ 'Invalid parameter "editorHtml"',
1154
+ 1489874122
1155
+ );
1156
+ assert(
1157
+ getUtility().isNonEmptyString(editorConfiguration.label),
1158
+ 'Invalid configuration "label"',
1159
+ 1489874123
1160
+ );
1161
+ assert(
1162
+ getUtility().isNonEmptyString(editorConfiguration.propertyPath),
1163
+ 'Invalid configuration "propertyPath"',
1164
+ 1489874124
1165
+ );
1166
+
1167
+ getHelper()
1168
+ .getTemplatePropertyDomElement('label', editorHtml)
1169
+ .append(editorConfiguration.label);
1170
+ if (getUtility().isNonEmptyString(editorConfiguration.fieldExplanationText)) {
1171
+ getHelper()
1172
+ .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
1173
+ .text(editorConfiguration.fieldExplanationText);
1174
+ } else {
1175
+ getHelper()
1176
+ .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
1177
+ .remove();
1178
+ }
1179
+
1180
+ const propertyPath = getFormEditorApp().buildPropertyPath(
1181
+ editorConfiguration.propertyPath
1182
+ );
1183
+
1184
+ let propertyData: PropertyData = getCurrentlySelectedFormElement().get(propertyPath);
1185
+
1186
+ if (
1187
+ !getUtility().isUndefinedOrNull(propertyData)
1188
+ && 'array' === $.type(propertyData)
1189
+ ) {
1190
+ const validationErrorMessage = getFirstAvailableValidationErrorMessage(editorConfiguration.errorCodes, propertyData);
1191
+
1192
+ if (!getUtility().isUndefinedOrNull(validationErrorMessage)) {
1193
+ getHelper().getTemplatePropertyDomElement('propertyPath', editorHtml).val(validationErrorMessage);
1194
+ }
1195
+ }
1196
+
1197
+ getHelper().getTemplatePropertyDomElement('propertyPath', editorHtml).on('keyup paste', function(this: HTMLInputElement) {
1198
+ propertyData = getCurrentlySelectedFormElement().get(propertyPath);
1199
+ if (getUtility().isUndefinedOrNull(propertyData)) {
1200
+ propertyData = [];
1201
+ }
1202
+ getCurrentlySelectedFormElement().set(propertyPath, renewValidationErrorMessages(
1203
+ editorConfiguration.errorCodes,
1204
+ propertyData,
1205
+ $(this).val()
1206
+ ));
1207
+ });
1208
+ }
1209
+
1210
+ /**
1211
+ * @throws 1674826430
1212
+ * @throws 1674826431
1213
+ * @throws 1674826432
1214
+ */
1215
+ export function renderCountrySelectEditor(
1216
+ editorConfiguration: EditorConfiguration,
1217
+ editorHtml: HTMLElement | JQuery,
1218
+ collectionElementIdentifier: string,
1219
+ collectionName: keyof FormEditorDefinitions
1220
+ ): void {
1221
+ assert(
1222
+ 'object' === $.type(editorConfiguration),
1223
+ 'Invalid parameter "editorConfiguration"',
1224
+ 1674826430
1225
+ );
1226
+ assert(
1227
+ 'object' === $.type(editorHtml),
1228
+ 'Invalid parameter "editorHtml"',
1229
+ 1674826431
1230
+ );
1231
+ assert(
1232
+ getUtility().isNonEmptyString(editorConfiguration.label),
1233
+ 'Invalid configuration "label"',
1234
+ 1674826432
1235
+ );
1236
+
1237
+ const propertyPath = getFormEditorApp().buildPropertyPath(
1238
+ editorConfiguration.propertyPath,
1239
+ collectionElementIdentifier,
1240
+ collectionName
1241
+ );
1242
+
1243
+ getHelper()
1244
+ .getTemplatePropertyDomElement('label', editorHtml)
1245
+ .append(editorConfiguration.label);
1246
+
1247
+ const selectElement = getHelper()
1248
+ .getTemplatePropertyDomElement('selectOptions', editorHtml);
1249
+
1250
+ const propertyData: Record<string, string> = getCurrentlySelectedFormElement().get(propertyPath) || {};
1251
+ validateCollectionElement(propertyPath, editorHtml);
1252
+
1253
+ const options = $('option', selectElement);
1254
+ selectElement.empty();
1255
+
1256
+ for (let i = 0, len = options.length; i < len; ++i) {
1257
+ let selected = false;
1258
+
1259
+ for (const propertyDataKey of Object.keys(propertyData)) {
1260
+ if ((options[i] as HTMLOptionElement).value === propertyData[propertyDataKey]) {
1261
+ selected = true;
1262
+ break;
1263
+ }
1264
+ }
1265
+
1266
+ const option = new Option((options[i] as HTMLOptionElement).text, i.toString(), false, selected);
1267
+ $(option).data({ value: (options[i] as HTMLOptionElement).value });
1268
+ selectElement.append(option);
1269
+ }
1270
+
1271
+ selectElement.on('change', function(this: HTMLSelectElement) {
1272
+ const selectValues: string[] = [];
1273
+ $('option:selected', $(this)).each(function(this: HTMLOptionElement) {
1274
+ selectValues.push($(this).data('value'));
1275
+ });
1276
+
1277
+ getCurrentlySelectedFormElement().set(propertyPath, selectValues);
1278
+ validateCollectionElement(propertyPath, editorHtml);
1279
+ });
1280
+ }
1281
+
1282
+ /**
1283
+ * @throws 1475421048
1284
+ * @throws 1475421049
1285
+ * @throws 1475421050
1286
+ * @throws 1475421051
1287
+ * @throws 1475421052
1288
+ */
1289
+ export function renderSingleSelectEditor(
1290
+ editorConfiguration: EditorConfiguration,
1291
+ editorHtml: HTMLElement | JQuery,
1292
+ collectionElementIdentifier: string,
1293
+ collectionName: keyof FormEditorDefinitions
1294
+ ): void {
1295
+ assert(
1296
+ 'object' === $.type(editorConfiguration),
1297
+ 'Invalid parameter "editorConfiguration"',
1298
+ 1475421048
1299
+ );
1300
+ assert(
1301
+ 'object' === $.type(editorHtml),
1302
+ 'Invalid parameter "editorHtml"',
1303
+ 1475421049
1304
+ );
1305
+ assert(
1306
+ getUtility().isNonEmptyString(editorConfiguration.label),
1307
+ 'Invalid configuration "label"',
1308
+ 1475421050
1309
+ );
1310
+ assert(
1311
+ getUtility().isNonEmptyString(editorConfiguration.propertyPath),
1312
+ 'Invalid configuration "propertyPath"',
1313
+ 1475421051
1314
+ );
1315
+ assert(
1316
+ 'array' === $.type(editorConfiguration.selectOptions),
1317
+ 'Invalid configuration "selectOptions"',
1318
+ 1475421052
1319
+ );
1320
+
1321
+ const propertyPath = getFormEditorApp().buildPropertyPath(
1322
+ editorConfiguration.propertyPath,
1323
+ collectionElementIdentifier,
1324
+ collectionName
1325
+ );
1326
+
1327
+ getHelper()
1328
+ .getTemplatePropertyDomElement('label', editorHtml)
1329
+ .append(editorConfiguration.label);
1330
+
1331
+ const selectElement = getHelper()
1332
+ .getTemplatePropertyDomElement('selectOptions', editorHtml);
1333
+
1334
+ const propertyData = getCurrentlySelectedFormElement().get(propertyPath);
1335
+ validateCollectionElement(propertyPath, editorHtml);
1336
+
1337
+ for (let i = 0, len = editorConfiguration.selectOptions.length; i < len; ++i) {
1338
+ let option;
1339
+
1340
+ if (editorConfiguration.selectOptions[i].value === propertyData) {
1341
+ option = new Option(editorConfiguration.selectOptions[i].label, i.toString(), false, true);
1342
+ } else {
1343
+ option = new Option(editorConfiguration.selectOptions[i].label, i.toString());
1344
+ }
1345
+ $(option).data({ value: editorConfiguration.selectOptions[i].value });
1346
+ selectElement.append(option);
1347
+ }
1348
+
1349
+ selectElement.on('change', function(this: HTMLSelectElement) {
1350
+ getCurrentlySelectedFormElement().set(propertyPath, $('option:selected', $(this)).data('value'));
1351
+ validateCollectionElement(propertyPath, editorHtml);
1352
+ });
1353
+ }
1354
+
1355
+ /**
1356
+ * @throws 1485712399
1357
+ * @throws 1485712400
1358
+ * @throws 1485712401
1359
+ * @throws 1485712402
1360
+ * @throws 1485712403
1361
+ */
1362
+ export function renderMultiSelectEditor(
1363
+ editorConfiguration: EditorConfiguration,
1364
+ editorHtml: HTMLElement | JQuery,
1365
+ collectionElementIdentifier: string,
1366
+ collectionName: keyof FormEditorDefinitions
1367
+ ): void {
1368
+ assert(
1369
+ 'object' === $.type(editorConfiguration),
1370
+ 'Invalid parameter "editorConfiguration"',
1371
+ 1485712399
1372
+ );
1373
+ assert(
1374
+ 'object' === $.type(editorHtml),
1375
+ 'Invalid parameter "editorHtml"',
1376
+ 1485712400
1377
+ );
1378
+ assert(
1379
+ getUtility().isNonEmptyString(editorConfiguration.label),
1380
+ 'Invalid configuration "label"',
1381
+ 1485712401
1382
+ );
1383
+ assert(
1384
+ getUtility().isNonEmptyString(editorConfiguration.propertyPath),
1385
+ 'Invalid configuration "propertyPath"',
1386
+ 1485712402
1387
+ );
1388
+ assert(
1389
+ 'array' === $.type(editorConfiguration.selectOptions),
1390
+ 'Invalid configuration "selectOptions"',
1391
+ 1485712403
1392
+ );
1393
+
1394
+ const propertyPath = getFormEditorApp().buildPropertyPath(
1395
+ editorConfiguration.propertyPath,
1396
+ collectionElementIdentifier,
1397
+ collectionName
1398
+ );
1399
+
1400
+ getHelper()
1401
+ .getTemplatePropertyDomElement('label', editorHtml)
1402
+ .append(editorConfiguration.label);
1403
+
1404
+ const selectElement = getHelper()
1405
+ .getTemplatePropertyDomElement('selectOptions', editorHtml);
1406
+
1407
+ const propertyData: Record<string, string> = getCurrentlySelectedFormElement().get(propertyPath) || {};
1408
+ validateCollectionElement(propertyPath, editorHtml);
1409
+
1410
+ for (let i = 0, len1 = editorConfiguration.selectOptions.length; i < len1; ++i) {
1411
+ let option = null;
1412
+ for (const propertyDataKey of Object.keys(propertyData)) {
1413
+ if (editorConfiguration.selectOptions[i].value === propertyData[propertyDataKey]) {
1414
+ option = new Option(editorConfiguration.selectOptions[i].label, i.toString(), false, true);
1415
+ break;
1416
+ }
1417
+ }
1418
+
1419
+ if (!option) {
1420
+ option = new Option(editorConfiguration.selectOptions[i].label, i.toString());
1421
+ }
1422
+
1423
+ $(option).data({ value: editorConfiguration.selectOptions[i].value });
1424
+
1425
+ selectElement.append(option);
1426
+ }
1427
+
1428
+ selectElement.on('change', function(this: HTMLSelectElement) {
1429
+ const selectValues: string[] = [];
1430
+ $('option:selected', $(this)).each(function(this: HTMLOptionElement) {
1431
+ selectValues.push($(this).data('value'));
1432
+ });
1433
+
1434
+ getCurrentlySelectedFormElement().set(propertyPath, selectValues);
1435
+ validateCollectionElement(propertyPath, editorHtml);
1436
+ });
1437
+ }
1438
+
1439
+ /**
1440
+ * @throws 1489528242
1441
+ * @throws 1489528243
1442
+ * @throws 1489528244
1443
+ * @throws 1489528245
1444
+ * @throws 1489528246
1445
+ * @throws 1489528247
1446
+ */
1447
+ export function renderGridColumnViewPortConfigurationEditor(
1448
+ editorConfiguration: EditorConfiguration,
1449
+ editorHtml: HTMLElement | JQuery
1450
+ ): void {
1451
+ assert(
1452
+ 'object' === $.type(editorConfiguration),
1453
+ 'Invalid parameter "editorConfiguration"',
1454
+ 1489528242
1455
+ );
1456
+ assert(
1457
+ 'object' === $.type(editorHtml),
1458
+ 'Invalid parameter "editorHtml"',
1459
+ 1489528243
1460
+ );
1461
+ assert(
1462
+ getUtility().isNonEmptyString(editorConfiguration.label),
1463
+ 'Invalid configuration "label"',
1464
+ 1489528244
1465
+ );
1466
+ assert(
1467
+ 'array' === $.type(editorConfiguration.configurationOptions.viewPorts),
1468
+ 'Invalid configurationOptions "viewPorts"',
1469
+ 1489528245
1470
+ );
1471
+ assert(
1472
+ !getUtility().isUndefinedOrNull(editorConfiguration.configurationOptions.numbersOfColumnsToUse.label),
1473
+ 'Invalid configurationOptions "numbersOfColumnsToUse"',
1474
+ 1489528246
1475
+ );
1476
+ assert(
1477
+ !getUtility().isUndefinedOrNull(editorConfiguration.configurationOptions.numbersOfColumnsToUse.propertyPath),
1478
+ 'Invalid configuration "selectOptions"',
1479
+ 1489528247
1480
+ );
1481
+
1482
+ if (!getFormElementDefinition(getCurrentlySelectedFormElement().get('__parentRenderable'), '_isGridRowFormElement')) {
1483
+ editorHtml.remove();
1484
+ return;
1485
+ }
1486
+
1487
+ getHelper()
1488
+ .getTemplatePropertyDomElement('label', editorHtml)
1489
+ .append(editorConfiguration.label);
1490
+
1491
+
1492
+ const viewportButtonTemplate = $(getHelper()
1493
+ .getDomElementDataIdentifierSelector('viewportButton'), $(editorHtml))
1494
+ .clone();
1495
+
1496
+ $(getHelper()
1497
+ .getDomElementDataIdentifierSelector('viewportButton'), $(editorHtml))
1498
+ .remove();
1499
+
1500
+ const numbersOfColumnsTemplate = getHelper()
1501
+ .getTemplatePropertyDomElement('numbersOfColumnsToUse', $(editorHtml))
1502
+ .clone();
1503
+
1504
+ getHelper()
1505
+ .getTemplatePropertyDomElement('numbersOfColumnsToUse', $(editorHtml))
1506
+ .remove();
1507
+
1508
+ const editorControlsWrapper = getEditorControlsWrapperDomElement(editorHtml);
1509
+
1510
+ const initNumbersOfColumnsField = function(element: JQuery) {
1511
+ getHelper().getTemplatePropertyDomElement('numbersOfColumnsToUse', $(editorHtml))
1512
+ .off()
1513
+ .empty()
1514
+ .remove();
1515
+
1516
+ const numbersOfColumnsTemplateClone = $(numbersOfColumnsTemplate).clone(true, true);
1517
+ getEditorWrapperDomElement(editorHtml).after(numbersOfColumnsTemplateClone);
1518
+
1519
+ $('input', numbersOfColumnsTemplateClone).focus();
1520
+
1521
+ getHelper()
1522
+ .getTemplatePropertyDomElement('numbersOfColumnsToUse-label', numbersOfColumnsTemplateClone)
1523
+ .append(
1524
+ editorConfiguration.configurationOptions.numbersOfColumnsToUse.label
1525
+ .replace('{@viewPortLabel}', element.data('viewPortLabel'))
1526
+ );
1527
+
1528
+ getHelper()
1529
+ .getTemplatePropertyDomElement('numbersOfColumnsToUse-fieldExplanationText', numbersOfColumnsTemplateClone)
1530
+ .append(editorConfiguration.configurationOptions.numbersOfColumnsToUse.fieldExplanationText);
1531
+
1532
+ const propertyPath = editorConfiguration.configurationOptions.numbersOfColumnsToUse.propertyPath
1533
+ .replace('{@viewPortIdentifier}', element.data('viewPortIdentifier'));
1534
+
1535
+ getHelper()
1536
+ .getTemplatePropertyDomElement('numbersOfColumnsToUse-propertyPath', numbersOfColumnsTemplateClone)
1537
+ .val(getCurrentlySelectedFormElement().get(propertyPath));
1538
+
1539
+ getHelper().getTemplatePropertyDomElement('numbersOfColumnsToUse-propertyPath', numbersOfColumnsTemplateClone).on('keyup paste change', function(this: HTMLInputElement) {
1540
+ const that = $(this);
1541
+ if (!$.isNumeric(that.val())) {
1542
+ that.val('');
1543
+ }
1544
+ getCurrentlySelectedFormElement().set(propertyPath, that.val());
1545
+ });
1546
+ };
1547
+
1548
+ for (let i = 0, len = editorConfiguration.configurationOptions.viewPorts.length; i < len; ++i) {
1549
+ const viewPortIdentifier = editorConfiguration.configurationOptions.viewPorts[i].viewPortIdentifier;
1550
+ const viewPortLabel = editorConfiguration.configurationOptions.viewPorts[i].label;
1551
+
1552
+ const viewportButtonTemplateClone = $(viewportButtonTemplate).clone(true, true);
1553
+ viewportButtonTemplateClone.text(viewPortIdentifier);
1554
+ viewportButtonTemplateClone.data('viewPortIdentifier', viewPortIdentifier);
1555
+ viewportButtonTemplateClone.data('viewPortLabel', viewPortLabel);
1556
+ viewportButtonTemplateClone.attr('title', viewPortLabel);
1557
+ editorControlsWrapper.append(viewportButtonTemplateClone);
1558
+
1559
+ if (i === (len - 1)) {
1560
+ const numbersOfColumnsTemplateClone = $(numbersOfColumnsTemplate).clone(true, true);
1561
+ getEditorWrapperDomElement(editorHtml).after(numbersOfColumnsTemplateClone);
1562
+ initNumbersOfColumnsField(viewportButtonTemplateClone);
1563
+ viewportButtonTemplateClone.addClass(getHelper().getDomElementClassName('active'));
1564
+ }
1565
+
1566
+ $('button', editorControlsWrapper).on('click', function(this: HTMLButtonElement) {
1567
+ const that = $(this);
1568
+
1569
+ $('button', editorControlsWrapper).removeClass(getHelper().getDomElementClassName('active'));
1570
+ that.addClass(getHelper().getDomElementClassName('active'));
1571
+
1572
+ initNumbersOfColumnsField(that);
1573
+ });
1574
+ }
1575
+ }
1576
+
1577
+ /**
1578
+ * @throws 1475419226
1579
+ * @throws 1475419227
1580
+ * @throws 1475419228
1581
+ * @throws 1475419229
1582
+ * @throws 1475419230
1583
+ * @throws 1475419231
1584
+ * @throws 1475419232
1585
+ */
1586
+ export function renderPropertyGridEditor(
1587
+ editorConfiguration: EditorConfiguration,
1588
+ editorHtml: HTMLElement | JQuery,
1589
+ collectionElementIdentifier: string,
1590
+ collectionName: keyof FormEditorDefinitions
1591
+ ): void {
1592
+ assert(
1593
+ 'object' === $.type(editorConfiguration),
1594
+ 'Invalid parameter "editorConfiguration"',
1595
+ 1475419226
1596
+ );
1597
+ assert(
1598
+ 'object' === $.type(editorHtml),
1599
+ 'Invalid parameter "editorHtml"',
1600
+ 1475419227
1601
+ );
1602
+ assert(
1603
+ 'boolean' === $.type(editorConfiguration.enableAddRow),
1604
+ 'Invalid configuration "enableAddRow"',
1605
+ 1475419228
1606
+ );
1607
+ assert(
1608
+ 'boolean' === $.type(editorConfiguration.enableDeleteRow),
1609
+ 'Invalid configuration "enableDeleteRow"',
1610
+ 1475419230
1611
+ );
1612
+ assert(
1613
+ 'boolean' === $.type(editorConfiguration.isSortable),
1614
+ 'Invalid configuration "isSortable"',
1615
+ 1475419229
1616
+ );
1617
+ assert(
1618
+ getUtility().isNonEmptyString(editorConfiguration.propertyPath),
1619
+ 'Invalid configuration "propertyPath"',
1620
+ 1475419231
1621
+ );
1622
+ assert(
1623
+ getUtility().isNonEmptyString(editorConfiguration.label),
1624
+ 'Invalid configuration "label"',
1625
+ 1475419232
1626
+ );
1627
+
1628
+ getHelper().getTemplatePropertyDomElement('label', editorHtml)
1629
+ .append(editorConfiguration.label);
1630
+ if (getUtility().isNonEmptyString(editorConfiguration.fieldExplanationText)) {
1631
+ getHelper()
1632
+ .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
1633
+ .text(editorConfiguration.fieldExplanationText);
1634
+ } else {
1635
+ getHelper()
1636
+ .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
1637
+ .remove();
1638
+ }
1639
+
1640
+ const propertyPathPrefix = (() => {
1641
+ const path = getFormEditorApp().buildPropertyPath(undefined, collectionElementIdentifier, collectionName, undefined, true);
1642
+ return getUtility().isNonEmptyString(path) ? path + '.' : path;
1643
+ })();
1644
+
1645
+ const multiSelection: boolean = getUtility().isUndefinedOrNull(editorConfiguration.multiSelection)
1646
+ ? false
1647
+ : !!editorConfiguration.multiSelection;
1648
+
1649
+ const enableSelection = getUtility().isNonEmptyArray(editorConfiguration.gridColumns)
1650
+ ? editorConfiguration.gridColumns.some(item => item.name === 'selected')
1651
+ : true;
1652
+
1653
+ const defaultValue: Record<string, string> = (() => {
1654
+ const val = getCurrentlySelectedFormElement().get(propertyPathPrefix + 'defaultValue');
1655
+ return !getUtility().isUndefinedOrNull(val)
1656
+ ? multiSelection ? val : { '0': val }
1657
+ : {};
1658
+ })();
1659
+
1660
+ const propertyData = (() : PropertyGridEditorEntry[] => {
1661
+ const formElement = getCurrentlySelectedFormElement();
1662
+ const fullPropertyPath = propertyPathPrefix + editorConfiguration.propertyPath;
1663
+ const rawData = formElement.get(fullPropertyPath) || {};
1664
+ let propertyEntries: PropertyGridEditorEntry[];
1665
+
1666
+ if (Array.isArray(rawData)) {
1667
+ // Handle array of objects: [{_label, _value}] or raw values
1668
+ propertyEntries = rawData.map((item, index): PropertyGridEditorEntry => ({
1669
+ id: 'fe' + Math.floor(Math.random() * 42) + Date.now(),
1670
+ label: getUtility().isUndefinedOrNull(item._label) ? item : item._label,
1671
+ value: getUtility().isUndefinedOrNull(item._label) ? index : item._value,
1672
+ selected: false,
1673
+ }));
1674
+ } else if (typeof rawData === 'object') {
1675
+ // Handle object case: { value: label }
1676
+ propertyEntries = Object.entries(rawData).map(([value, label]: [string, string]): PropertyGridEditorEntry => ({
1677
+ id: 'fe' + Math.floor(Math.random() * 42) + Date.now(),
1678
+ label,
1679
+ value,
1680
+ selected: false,
1681
+ }));
1682
+ }
1683
+
1684
+ return propertyEntries.map(entry => {
1685
+ for (const defaultValueKey of Object.keys(defaultValue)) {
1686
+ if (defaultValue[defaultValueKey] === entry.value) {
1687
+ entry.selected = true;
1688
+ break;
1689
+ }
1690
+ }
1691
+ return entry;
1692
+ });
1693
+ })();
1694
+
1695
+ const useLabelAsFallbackValue = getUtility().isUndefinedOrNull(editorConfiguration.useLabelAsFallbackValue)
1696
+ ? true
1697
+ : editorConfiguration.useLabelAsFallbackValue;
1698
+
1699
+ const propertyGridEditor = editorHtml instanceof HTMLElement ?
1700
+ editorHtml.querySelector('typo3-form-property-grid-editor') :
1701
+ editorHtml.get(0).querySelector('typo3-form-property-grid-editor');
1702
+ propertyGridEditor.enableAddRow = editorConfiguration.enableAddRow;
1703
+ propertyGridEditor.enableSelection = enableSelection;
1704
+ propertyGridEditor.enableMultiSelection = multiSelection;
1705
+ propertyGridEditor.enableSorting = editorConfiguration.isSortable ?? false;
1706
+ propertyGridEditor.enableDeleteRow = editorConfiguration.enableDeleteRow ?? false;
1707
+ propertyGridEditor.enableLabelAsFallbackValue = useLabelAsFallbackValue;
1708
+ propertyGridEditor.entries = propertyData;
1709
+
1710
+ if (getUtility().isNonEmptyArray(editorConfiguration.gridColumns)) {
1711
+ editorConfiguration.gridColumns.forEach(gridColumnConfig => {
1712
+ if (gridColumnConfig.name === 'label') {
1713
+ propertyGridEditor.labelLabel = gridColumnConfig.title;
1714
+ }
1715
+ if (gridColumnConfig.name === 'value') {
1716
+ propertyGridEditor.labelValue = gridColumnConfig.title;
1717
+ }
1718
+ if (gridColumnConfig.name === 'selected') {
1719
+ propertyGridEditor.labelSelected = gridColumnConfig.title;
1720
+ }
1721
+ });
1722
+ }
1723
+
1724
+ propertyGridEditor.addEventListener(PropertyGridEditorUpdateEvent.eventName, (event: PropertyGridEditorUpdateEvent) => {
1725
+ const entries = event.data;
1726
+ const defaultValues: (string | number)[] = [];
1727
+ const newData: Array<{_label: string, _value: string | number}> = [];
1728
+
1729
+ for (const entry of entries) {
1730
+ const entryLabel = entry.label;
1731
+ const entryValue = entry.value === ''
1732
+ ? entry.label
1733
+ : getUtility().canBeInterpretedAsInteger(entry.value)
1734
+ ? parseInt(entry.value, 10)
1735
+ : entry.value;
1736
+ if (entry.selected) {
1737
+ defaultValues.push(entryValue);
1738
+ }
1739
+ newData.push({
1740
+ _label: entryLabel,
1741
+ _value: entryValue
1742
+ });
1743
+ }
1744
+
1745
+ if (multiSelection) {
1746
+ getCurrentlySelectedFormElement().set(propertyPathPrefix + 'defaultValue', defaultValues);
1747
+ } else {
1748
+ getCurrentlySelectedFormElement().set(propertyPathPrefix + 'defaultValue', defaultValues[0] ?? '', true);
1749
+ }
1750
+
1751
+ getCurrentlySelectedFormElement().set(propertyPathPrefix + editorConfiguration.propertyPath, newData);
1752
+ validateCollectionElement(propertyPathPrefix + editorConfiguration.propertyPath, editorHtml);
1753
+ });
1754
+
1755
+ validateCollectionElement(propertyPathPrefix + editorConfiguration.propertyPath, editorHtml);
1756
+ }
1757
+
1758
+ /**
1759
+ * @publish view/inspector/collectionElement/new/selected
1760
+ * @publish view/inspector/removeCollectionElement/perform
1761
+ * @throws 1475417093
1762
+ * @throws 1475417094
1763
+ * @throws 1475417095
1764
+ * @throws 1475417096
1765
+ */
1766
+ export function renderRequiredValidatorEditor(
1767
+ editorConfiguration: EditorConfiguration,
1768
+ editorHtml: HTMLElement | JQuery,
1769
+ collectionElementIdentifier: string,
1770
+ collectionName: keyof FormEditorDefinitions
1771
+ ): void {
1772
+ assert(
1773
+ 'object' === $.type(editorConfiguration),
1774
+ 'Invalid parameter "editorConfiguration"',
1775
+ 1475417093
1776
+ );
1777
+ assert(
1778
+ 'object' === $.type(editorHtml),
1779
+ 'Invalid parameter "editorHtml"',
1780
+ 1475417094
1781
+ );
1782
+ assert(
1783
+ getUtility().isNonEmptyString(editorConfiguration.validatorIdentifier),
1784
+ 'Invalid configuration "validatorIdentifier"',
1785
+ 1475417095
1786
+ );
1787
+ assert(
1788
+ getUtility().isNonEmptyString(editorConfiguration.label),
1789
+ 'Invalid configuration "label"',
1790
+ 1475417096
1791
+ );
1792
+
1793
+ const validatorIdentifier = editorConfiguration.validatorIdentifier;
1794
+ getHelper().getTemplatePropertyDomElement('label', editorHtml).append(editorConfiguration.label);
1795
+
1796
+ let propertyValue: string;
1797
+ let propertyPath: string;
1798
+ let propertyData: PropertyData;
1799
+ if (getUtility().isNonEmptyString(editorConfiguration.propertyPath)) {
1800
+ propertyPath = getFormEditorApp()
1801
+ .buildPropertyPath(editorConfiguration.propertyPath, collectionElementIdentifier, collectionName);
1802
+ }
1803
+ if (getUtility().isNonEmptyString(editorConfiguration.propertyValue)) {
1804
+ propertyValue = editorConfiguration.propertyValue;
1805
+ } else {
1806
+ propertyValue = '';
1807
+ }
1808
+
1809
+ const validationErrorMessagePropertyPath = getFormEditorApp()
1810
+ .buildPropertyPath(editorConfiguration.configurationOptions.validationErrorMessage.propertyPath);
1811
+
1812
+ const validationErrorMessageTemplate = getHelper()
1813
+ .getTemplatePropertyDomElement('validationErrorMessage', $(editorHtml))
1814
+ .clone();
1815
+
1816
+ getHelper()
1817
+ .getTemplatePropertyDomElement('validationErrorMessage', $(editorHtml))
1818
+ .remove();
1819
+
1820
+ const showValidationErrorMessage = function() {
1821
+ const validationErrorMessageTemplateClone = $(validationErrorMessageTemplate).clone(true, true);
1822
+ getEditorWrapperDomElement(editorHtml).after(validationErrorMessageTemplateClone);
1823
+
1824
+ getHelper()
1825
+ .getTemplatePropertyDomElement('validationErrorMessage-label', validationErrorMessageTemplateClone)
1826
+ .append(editorConfiguration.configurationOptions.validationErrorMessage.label);
1827
+
1828
+ getHelper()
1829
+ .getTemplatePropertyDomElement('validationErrorMessage-fieldExplanationText', validationErrorMessageTemplateClone)
1830
+ .append(editorConfiguration.configurationOptions.validationErrorMessage.fieldExplanationText);
1831
+
1832
+ propertyData = getCurrentlySelectedFormElement().get(validationErrorMessagePropertyPath);
1833
+ if (getUtility().isUndefinedOrNull(propertyData)) {
1834
+ propertyData = [];
1835
+ }
1836
+
1837
+ const validationErrorMessage = getFirstAvailableValidationErrorMessage(
1838
+ editorConfiguration.configurationOptions.validationErrorMessage.errorCodes,
1839
+ propertyData
1840
+ );
1841
+ if (!getUtility().isUndefinedOrNull(validationErrorMessage)) {
1842
+ getHelper()
1843
+ .getTemplatePropertyDomElement('validationErrorMessage-propertyPath', validationErrorMessageTemplateClone)
1844
+ .val(validationErrorMessage);
1845
+ }
1846
+
1847
+ getHelper().getTemplatePropertyDomElement('validationErrorMessage-propertyPath', validationErrorMessageTemplateClone).on('keyup paste', function(this: HTMLInputElement) {
1848
+ let propertyData = getCurrentlySelectedFormElement().get(validationErrorMessagePropertyPath);
1849
+ if (getUtility().isUndefinedOrNull(propertyData)) {
1850
+ propertyData = [];
1851
+ }
1852
+
1853
+ getCurrentlySelectedFormElement().set(validationErrorMessagePropertyPath, renewValidationErrorMessages(
1854
+ editorConfiguration.configurationOptions.validationErrorMessage.errorCodes,
1855
+ propertyData,
1856
+ $(this).val()
1857
+ ));
1858
+ });
1859
+ };
1860
+
1861
+ if (-1 !== getFormEditorApp().getIndexFromPropertyCollectionElement(validatorIdentifier, 'validators')) {
1862
+ $('input[type="checkbox"]', $(editorHtml)).prop('checked', true);
1863
+ showValidationErrorMessage();
1864
+ }
1865
+
1866
+ $('input[type="checkbox"]', $(editorHtml)).on('change', function(this: HTMLInputElement) {
1867
+ getHelper().getTemplatePropertyDomElement('validationErrorMessage', $(editorHtml))
1868
+ .off()
1869
+ .empty()
1870
+ .remove();
1871
+
1872
+ if ($(this).is(':checked')) {
1873
+ showValidationErrorMessage();
1874
+ getPublisherSubscriber().publish(
1875
+ 'view/inspector/collectionElement/new/selected',
1876
+ [validatorIdentifier, 'validators']
1877
+ );
1878
+
1879
+ if (getUtility().isNonEmptyString(propertyPath)) {
1880
+ getCurrentlySelectedFormElement().set(propertyPath, propertyValue);
1881
+ }
1882
+ } else {
1883
+ getPublisherSubscriber().publish(
1884
+ 'view/inspector/removeCollectionElement/perform',
1885
+ [validatorIdentifier, 'validators']
1886
+ );
1887
+ if (getUtility().isNonEmptyString(propertyPath)) {
1888
+ getCurrentlySelectedFormElement().unset(propertyPath);
1889
+ }
1890
+
1891
+ propertyData = getCurrentlySelectedFormElement().get(validationErrorMessagePropertyPath);
1892
+ if (getUtility().isUndefinedOrNull(propertyData)) {
1893
+ propertyData = [];
1894
+ }
1895
+
1896
+ getCurrentlySelectedFormElement().set(validationErrorMessagePropertyPath, renewValidationErrorMessages(
1897
+ editorConfiguration.configurationOptions.validationErrorMessage.errorCodes,
1898
+ propertyData,
1899
+ ''
1900
+ ));
1901
+ }
1902
+ });
1903
+ }
1904
+
1905
+ /**
1906
+ * @throws 1476218671
1907
+ * @throws 1476218672
1908
+ * @throws 1476218673
1909
+ * @throws 1476218674
1910
+ */
1911
+ export function renderCheckboxEditor(
1912
+ editorConfiguration: EditorConfiguration,
1913
+ editorHtml: HTMLElement | JQuery,
1914
+ collectionElementIdentifier: string,
1915
+ collectionName: keyof FormEditorDefinitions
1916
+ ): void {
1917
+ assert(
1918
+ 'object' === $.type(editorConfiguration),
1919
+ 'Invalid parameter "editorConfiguration"',
1920
+ 1476218671
1921
+ );
1922
+ assert(
1923
+ 'object' === $.type(editorHtml),
1924
+ 'Invalid parameter "editorHtml"',
1925
+ 1476218672
1926
+ );
1927
+ assert(
1928
+ getUtility().isNonEmptyString(editorConfiguration.label),
1929
+ 'Invalid configuration "label"',
1930
+ 1476218673
1931
+ );
1932
+ assert(
1933
+ getUtility().isNonEmptyString(editorConfiguration.propertyPath),
1934
+ 'Invalid configuration "propertyPath"',
1935
+ 1476218674
1936
+ );
1937
+
1938
+ getHelper()
1939
+ .getTemplatePropertyDomElement('label', editorHtml)
1940
+ .append(editorConfiguration.label);
1941
+ if (getUtility().isNonEmptyString(editorConfiguration.fieldExplanationText)) {
1942
+ getHelper()
1943
+ .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
1944
+ .text(editorConfiguration.fieldExplanationText);
1945
+ } else {
1946
+ getHelper()
1947
+ .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
1948
+ .remove();
1949
+ }
1950
+
1951
+ const propertyPath = getFormEditorApp()
1952
+ .buildPropertyPath(editorConfiguration.propertyPath, collectionElementIdentifier, collectionName);
1953
+ const propertyData = getCurrentlySelectedFormElement().get(propertyPath);
1954
+
1955
+ if (
1956
+ ('boolean' === $.type(propertyData) && propertyData)
1957
+ || propertyData === 'true'
1958
+ || propertyData === 1
1959
+ || propertyData === '1'
1960
+ ) {
1961
+ $('input[type="checkbox"]', $(editorHtml)).prop('checked', true);
1962
+ }
1963
+
1964
+ $('input[type="checkbox"]', $(editorHtml)).on('change', function(this: HTMLInputElement) {
1965
+ if ($(this).is(':checked')) {
1966
+ getCurrentlySelectedFormElement().set(propertyPath, true);
1967
+ } else {
1968
+ getCurrentlySelectedFormElement().set(propertyPath, false);
1969
+ }
1970
+ });
1971
+ }
1972
+
1973
+ /**
1974
+ * @throws 1475412567
1975
+ * @throws 1475412568
1976
+ * @throws 1475416098
1977
+ * @throws 1475416099
1978
+ */
1979
+ export function renderTextareaEditor(
1980
+ editorConfiguration: EditorConfiguration,
1981
+ editorHtml: HTMLElement | JQuery,
1982
+ collectionElementIdentifier: string,
1983
+ collectionName: keyof FormEditorDefinitions
1984
+ ): void {
1985
+ assert(
1986
+ 'object' === $.type(editorConfiguration),
1987
+ 'Invalid parameter "editorConfiguration"',
1988
+ 1475412567
1989
+ );
1990
+ assert(
1991
+ 'object' === $.type(editorHtml),
1992
+ 'Invalid parameter "editorHtml"',
1993
+ 1475412568
1994
+ );
1995
+ assert(
1996
+ getUtility().isNonEmptyString(editorConfiguration.propertyPath),
1997
+ 'Invalid configuration "propertyPath"',
1998
+ 1475416098
1999
+ );
2000
+ assert(
2001
+ getUtility().isNonEmptyString(editorConfiguration.label),
2002
+ 'Invalid configuration "label"',
2003
+ 1475416099
2004
+ );
2005
+
2006
+ const propertyPath = getFormEditorApp()
2007
+ .buildPropertyPath(editorConfiguration.propertyPath, collectionElementIdentifier, collectionName);
2008
+
2009
+ getHelper()
2010
+ .getTemplatePropertyDomElement('label', editorHtml).append(editorConfiguration.label);
2011
+
2012
+ if (getUtility().isNonEmptyString(editorConfiguration.fieldExplanationText)) {
2013
+ getHelper()
2014
+ .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
2015
+ .text(editorConfiguration.fieldExplanationText);
2016
+ } else {
2017
+ getHelper()
2018
+ .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
2019
+ .remove();
2020
+ }
2021
+
2022
+ const propertyData = getCurrentlySelectedFormElement().get(propertyPath);
2023
+ $('textarea', $(editorHtml)).val(propertyData);
2024
+ validateCollectionElement(propertyPath, editorHtml);
2025
+
2026
+ $('textarea', $(editorHtml)).on('keyup paste', function(this: HTMLTextAreaElement) {
2027
+ getCurrentlySelectedFormElement().set(propertyPath, $(this).val());
2028
+ validateCollectionElement(propertyPath, editorHtml);
2029
+ });
2030
+ }
2031
+
2032
+ /**
2033
+ * @throws 1477300587
2034
+ * @throws 1477300588
2035
+ * @throws 1477300589
2036
+ * @throws 1477300590
2037
+ * @throws 1477318981
2038
+ * @throws 1477319859
2039
+ */
2040
+ export function renderTypo3WinBrowserEditor(
2041
+ editorConfiguration: EditorConfiguration,
2042
+ editorHtml: HTMLElement | JQuery,
2043
+ collectionElementIdentifier: string,
2044
+ collectionName: keyof FormEditorDefinitions
2045
+ ): void {
2046
+ assert(
2047
+ 'object' === $.type(editorConfiguration),
2048
+ 'Invalid parameter "editorConfiguration"',
2049
+ 1477300587
2050
+ );
2051
+ assert(
2052
+ 'object' === $.type(editorHtml),
2053
+ 'Invalid parameter "editorHtml"',
2054
+ 1477300588
2055
+ );
2056
+ assert(
2057
+ getUtility().isNonEmptyString(editorConfiguration.label),
2058
+ 'Invalid configuration "label"',
2059
+ 1477300589
2060
+ );
2061
+ assert(
2062
+ getUtility().isNonEmptyString(editorConfiguration.buttonLabel),
2063
+ 'Invalid configuration "buttonLabel"',
2064
+ 1477318981
2065
+ );
2066
+ assert(
2067
+ getUtility().isNonEmptyString(editorConfiguration.propertyPath),
2068
+ 'Invalid configuration "propertyPath"',
2069
+ 1477300590
2070
+ );
2071
+
2072
+ getHelper()
2073
+ .getTemplatePropertyDomElement('label', editorHtml)
2074
+ .append(editorConfiguration.label);
2075
+ getHelper()
2076
+ .getTemplatePropertyDomElement('buttonLabel', editorHtml)
2077
+ .append(editorConfiguration.buttonLabel);
2078
+
2079
+ if (getUtility().isNonEmptyString(editorConfiguration.fieldExplanationText)) {
2080
+ getHelper()
2081
+ .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
2082
+ .text(editorConfiguration.fieldExplanationText);
2083
+ } else {
2084
+ getHelper()
2085
+ .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
2086
+ .remove();
2087
+ }
2088
+
2089
+ $('form', $(editorHtml)).prop('name', editorConfiguration.propertyPath);
2090
+
2091
+ Icons.getIcon(editorConfiguration.iconIdentifier, Icons.sizes.small).then(function(icon) {
2092
+ getHelper().getTemplatePropertyDomElement('image', editorHtml).append($(icon));
2093
+ });
2094
+
2095
+ getHelper().getTemplatePropertyDomElement('onclick', editorHtml).on('click', function(this: HTMLElement) {
2096
+ const randomIdentifier = Math.floor((Math.random() * 100000) + 1);
2097
+ const insertTarget = $(this)
2098
+ .closest(getHelper().getDomElementDataIdentifierSelector('editorControlsWrapper'))
2099
+ .find(getHelper().getDomElementDataAttribute('contentElementSelectorTarget', 'bracesWithKey'));
2100
+
2101
+ insertTarget.attr(getHelper().getDomElementDataAttribute('contentElementSelectorTarget'), randomIdentifier);
2102
+ openTypo3WinBrowser('db', randomIdentifier + '|||' + editorConfiguration.browsableType);
2103
+ });
2104
+
2105
+ listenOnElementBrowser();
2106
+
2107
+ const propertyPath = getFormEditorApp().buildPropertyPath(editorConfiguration.propertyPath, collectionElementIdentifier, collectionName);
2108
+ const propertyData = getCurrentlySelectedFormElement().get(propertyPath);
2109
+
2110
+ validateCollectionElement(propertyPath, editorHtml);
2111
+ getHelper()
2112
+ .getTemplatePropertyDomElement('propertyPath', editorHtml)
2113
+ .val(propertyData);
2114
+
2115
+ getHelper().getTemplatePropertyDomElement('propertyPath', editorHtml).on('keyup paste', function(this: HTMLInputElement) {
2116
+ getCurrentlySelectedFormElement().set(propertyPath, $(this).val());
2117
+ validateCollectionElement(propertyPath, editorHtml);
2118
+ });
2119
+ }
2120
+
2121
+ /**
2122
+ * @throws 1475412563
2123
+ * @throws 1475412564
2124
+ */
2125
+ export function renderRemoveElementEditor(
2126
+ editorConfiguration: EditorConfiguration,
2127
+ editorHtml: HTMLElement | JQuery,
2128
+ collectionElementIdentifier: string,
2129
+ collectionName: keyof FormEditorDefinitions
2130
+ ): void {
2131
+ assert('object' === $.type(editorConfiguration), 'Invalid parameter "editorConfiguration"', 1475412563);
2132
+ assert('object' === $.type(editorHtml), 'Invalid parameter "editorHtml"', 1475412564);
2133
+
2134
+ if (getUtility().isUndefinedOrNull(collectionElementIdentifier)) {
2135
+
2136
+ $('button', $(editorHtml))
2137
+ .addClass(
2138
+ getHelper().getDomElementClassName('buttonFormElementRemove') + ' ' +
2139
+ getHelper().getDomElementClassName('buttonFormEditor')
2140
+ );
2141
+ } else {
2142
+ $('button', $(editorHtml)).addClass(
2143
+ getHelper().getDomElementClassName('buttonCollectionElementRemove')
2144
+ );
2145
+ }
2146
+
2147
+ $('button', $(editorHtml)).on('click', function() {
2148
+ if (getUtility().isUndefinedOrNull(collectionElementIdentifier)) {
2149
+ getViewModel().showRemoveFormElementModal();
2150
+ } else {
2151
+ getViewModel().showRemoveCollectionElementModal(collectionElementIdentifier, collectionName);
2152
+ }
2153
+ });
2154
+ }
2155
+
2156
+ /**
2157
+ * @throws 1484574704
2158
+ * @throws 1484574705
2159
+ * @throws 1484574706
2160
+ */
2161
+ export function renderFormElementSelectorEditorAddition(
2162
+ editorConfiguration: EditorConfiguration,
2163
+ editorHtml: HTMLElement | JQuery,
2164
+ propertyPath: string
2165
+ ): void {
2166
+ assert(
2167
+ 'object' === $.type(editorConfiguration),
2168
+ 'Invalid parameter "editorConfiguration"',
2169
+ 1484574704
2170
+ );
2171
+ assert(
2172
+ 'object' === $.type(editorHtml),
2173
+ 'Invalid parameter "editorHtml"',
2174
+ 1484574705
2175
+ );
2176
+ assert(
2177
+ getUtility().isNonEmptyString(propertyPath),
2178
+ 'Invalid parameter "propertyPath"',
2179
+ 1484574706
2180
+ );
2181
+
2182
+ const formElementSelectorControlsWrapper = $(
2183
+ getHelper().getDomElementDataIdentifierSelector('formElementSelectorControlsWrapper'), editorHtml
2184
+ );
2185
+
2186
+ if (editorConfiguration.enableFormelementSelectionButton === true) {
2187
+ if (formElementSelectorControlsWrapper.length === 0) {
2188
+ return;
2189
+ }
2190
+
2191
+ const formElementSelectorSplitButtonListContainer = $(
2192
+ getHelper().getDomElementDataIdentifierSelector('formElementSelectorSplitButtonListContainer'), editorHtml
2193
+ );
2194
+
2195
+ formElementSelectorSplitButtonListContainer.off().empty();
2196
+ const nonCompositeNonToplevelFormElements = getFormEditorApp().getNonCompositeNonToplevelFormElements();
2197
+
2198
+ if (nonCompositeNonToplevelFormElements.length === 0) {
2199
+ Icons.getIcon(
2200
+ getHelper().getDomElementDataAttributeValue('iconNotAvailable'),
2201
+ Icons.sizes.small,
2202
+ null,
2203
+ Icons.states.default
2204
+ ).then(function(icon) {
2205
+ const itemTemplate = $('<li data-no-sorting>'
2206
+ + '<span class="dropdown-item"></span>'
2207
+ + '</li>');
2208
+
2209
+ itemTemplate.find('span')
2210
+ .append($(icon))
2211
+ .append(' ' + getFormElementDefinition(getRootFormElement(), 'inspectorEditorFormElementSelectorNoElements'));
2212
+ formElementSelectorSplitButtonListContainer.append(itemTemplate);
2213
+ });
2214
+ } else {
2215
+ $.each(nonCompositeNonToplevelFormElements, function(i, nonCompositeNonToplevelFormElement) {
2216
+ Icons.getIcon(
2217
+ getFormElementDefinition(nonCompositeNonToplevelFormElement, 'iconIdentifier'),
2218
+ Icons.sizes.small,
2219
+ null,
2220
+ Icons.states.default
2221
+ ).then(function(icon) {
2222
+ const itemTemplate = $('<li data-no-sorting>'
2223
+ + '<a href="#" class="dropdown-item" data-formelement-identifier="' + nonCompositeNonToplevelFormElement.get('identifier') + '">'
2224
+ + '</a>'
2225
+ + '</li>');
2226
+
2227
+ $(selector`[data-formelement-identifier="${nonCompositeNonToplevelFormElement.get('identifier')}"]`, itemTemplate)
2228
+ .append($(icon))
2229
+ .append(' ' + nonCompositeNonToplevelFormElement.get('label'));
2230
+
2231
+ $('a', itemTemplate).on('click', function(this: HTMLElement) {
2232
+ let propertyData;
2233
+
2234
+ propertyData = getCurrentlySelectedFormElement().get(propertyPath) || '';
2235
+
2236
+ if (propertyData.length === 0) {
2237
+ propertyData = '{' + $(this).attr('data-formelement-identifier') + '}';
2238
+ } else {
2239
+ propertyData = propertyData + ' ' + '{' + $(this).attr('data-formelement-identifier') + '}';
2240
+ }
2241
+
2242
+ getCurrentlySelectedFormElement().set(propertyPath, propertyData);
2243
+ getHelper().getTemplatePropertyDomElement('propertyPath', editorHtml).val(propertyData);
2244
+ validateCollectionElement(propertyPath, editorHtml);
2245
+ });
2246
+
2247
+ formElementSelectorSplitButtonListContainer.append(itemTemplate);
2248
+ });
2249
+ });
2250
+ }
2251
+ } else {
2252
+ $(getHelper().getDomElementDataIdentifierSelector('editorControlsInputGroup'), editorHtml)
2253
+ .removeClass(getHelper().getDomElementClassName('inspectorInputGroup'));
2254
+ formElementSelectorControlsWrapper.off().empty().remove();
2255
+ }
2256
+ }
2257
+
2258
+ /**
2259
+ * @throws 1478967319
2260
+ */
2261
+ export function buildTitleByFormElement(formElement?: FormElement): HTMLElement {
2262
+ if (getUtility().isUndefinedOrNull(formElement)) {
2263
+ formElement = getCurrentlySelectedFormElement();
2264
+ }
2265
+ assert('object' === $.type(formElement), 'Invalid parameter "formElement"', 1478967319);
2266
+
2267
+ let label;
2268
+ if (formElement.get('type') === 'Form') {
2269
+ label = formElement.get('type');
2270
+ } else {
2271
+ label = getFormElementDefinition(formElement, 'label')
2272
+ ? getFormElementDefinition(formElement, 'label')
2273
+ : formElement.get('identifier');
2274
+ }
2275
+
2276
+ const span = document.createElement('span');
2277
+ span.textContent = label;
2278
+ return span;
2279
+ }
2280
+
2281
+ export function bootstrap(
2282
+ this: typeof import('./inspector-component'),
2283
+ _formEditorApp: FormEditor,
2284
+ customConfiguration?: Configuration
2285
+ ): typeof import('./inspector-component') {
2286
+ formEditorApp = _formEditorApp;
2287
+ configuration = $.extend(true, defaultConfiguration, customConfiguration || {});
2288
+ Helper.bootstrap(formEditorApp);
2289
+ return this;
2290
+ }
2291
+
2292
+ declare global {
2293
+ interface PublisherSubscriberTopicArgumentsMap {
2294
+ 'view/inspector/removeCollectionElement/perform': readonly [
2295
+ validatorIdentifier: string,
2296
+ info: 'validators',
2297
+ // @todo formElement is never published, but used by
2298
+ // media subscribe('view/inspector/removeCollectionElement/perform', .)
2299
+ // Can this be removed or is it possibly used by extensions?
2300
+ formElement?: FormElement,
2301
+ ];
2302
+ 'view/inspector/collectionElement/new/selected': readonly [
2303
+ value: string,
2304
+ collectionName: keyof FormEditorDefinitions
2305
+ ];
2306
+ 'view/inspector/collectionElement/existing/selected': readonly [
2307
+ alreadySelectedCollectionElementIdentifier: string,
2308
+ collectionName: keyof FormEditorDefinitions
2309
+ ];
2310
+ 'view/inspector/collectionElements/dnd/update': readonly [
2311
+ movedCollectionElementIdentifier: string,
2312
+ previousCollectionElementIdentifier: string,
2313
+ nextCollectionElementIdentifier: string,
2314
+ collectionName: keyof FormEditorDefinitions
2315
+ ];
2316
+ 'view/inspector/editor/insert/perform': readonly [
2317
+ editorConfiguration: EditorConfiguration,
2318
+ editorHtml: HTMLElement | JQuery,
2319
+ collectionElementIdentifier: string,
2320
+ collectionName: keyof FormEditorDefinitions
2321
+ ];
2322
+ }
2323
+ }