typo3-typescript-sources 14.3.8 → 14.3.9

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 (175) hide show
  1. package/.github/workflows/sync-and-publish.yml +240 -191
  2. package/.last-synced-tag +1 -1
  3. package/README.md +13 -5
  4. package/adminpanel/admin-panel.ts +22 -22
  5. package/adminpanel/modules/cache.ts +3 -3
  6. package/backend/action-dispatcher.ts +8 -3
  7. package/backend/bookmark/bookmark-store.ts +5 -5
  8. package/backend/clipboard-panel.ts +2 -2
  9. package/backend/code-editor/element/code-mirror-element.ts +1 -1
  10. package/backend/code-editor/language/typoscript.ts +3 -3
  11. package/backend/code-editor/stream-parser/typoscript.ts +2 -2
  12. package/backend/color-picker.ts +2 -2
  13. package/backend/column-selector-button.ts +6 -6
  14. package/backend/context-help.ts +3 -3
  15. package/backend/context-menu.ts +8 -3
  16. package/backend/drag-tooltip.ts +9 -4
  17. package/backend/drag-uploader.ts +4 -4
  18. package/backend/element/draggable-resizable-element.ts +18 -12
  19. package/backend/element/icon-element.ts +2 -2
  20. package/backend/element/thumbnail-element.ts +2 -2
  21. package/backend/element-browser.ts +1 -1
  22. package/backend/event/consumer-scope.ts +2 -2
  23. package/backend/event/interaction-request-assignment.ts +1 -1
  24. package/backend/event/interaction-request-map.ts +3 -3
  25. package/backend/form-engine/container/flex-form-container-container.ts +2 -2
  26. package/backend/form-engine/container/flex-form-section-container.ts +1 -1
  27. package/backend/form-engine/container/inline-control-container.ts +14 -14
  28. package/backend/form-engine/element/abstract-sortable-select-items.ts +3 -3
  29. package/backend/form-engine/element/color-element.ts +1 -1
  30. package/backend/form-engine/element/datetime-element.ts +1 -1
  31. package/backend/form-engine/element/extra/char-counter.ts +2 -2
  32. package/backend/form-engine/element/extra/select-box-filter.ts +1 -1
  33. package/backend/form-engine/element/mfa-info-element.ts +2 -2
  34. package/backend/form-engine/element/online-media-form-element.ts +5 -1
  35. package/backend/form-engine/element/select-multiple-side-by-side-element.ts +2 -2
  36. package/backend/form-engine/element/select-tree.ts +3 -3
  37. package/backend/form-engine/element/slug-element.ts +7 -7
  38. package/backend/form-engine/element/suggest/result-container.ts +1 -1
  39. package/backend/form-engine/element/table-wizard-element.ts +4 -4
  40. package/backend/form-engine/inline-relation/ajax-dispatcher.ts +3 -3
  41. package/backend/form-engine-validation.ts +11 -5
  42. package/backend/form-engine.ts +11 -11
  43. package/backend/global-event-handler.ts +1 -1
  44. package/backend/hotkeys/hotkey-struct.ts +1 -1
  45. package/backend/hotkeys.ts +3 -3
  46. package/backend/image-manipulation.ts +19 -19
  47. package/backend/layout-module/drag-drop.ts +4 -4
  48. package/backend/layout-module/paste.ts +1 -1
  49. package/backend/live-search/element/result/item/action/action-container.ts +1 -1
  50. package/backend/live-search/element/result/item/item-container.ts +4 -4
  51. package/backend/live-search/element/result/result-container.ts +5 -0
  52. package/backend/live-search/element/result/result-pagination.ts +1 -1
  53. package/backend/live-search/live-search.ts +2 -2
  54. package/backend/localization/label-provider.ts +4 -4
  55. package/backend/localization/localization-wizard.ts +4 -4
  56. package/backend/localization/steps/content-record-selection-step.ts +8 -8
  57. package/backend/localization/steps/handler-selection-step.ts +4 -4
  58. package/backend/localization/steps/mode-step.ts +4 -4
  59. package/backend/localization/steps/source-language-step.ts +4 -4
  60. package/backend/localization/steps/target-language-step.ts +4 -4
  61. package/backend/login.ts +2 -2
  62. package/backend/module/iframe.ts +10 -0
  63. package/backend/module/router.ts +10 -0
  64. package/backend/module-menu.ts +3 -3
  65. package/backend/multi-record-selection-action.ts +1 -1
  66. package/backend/multi-record-selection-delete-action.ts +1 -1
  67. package/backend/multi-record-selection.ts +14 -14
  68. package/backend/multi-step-wizard.ts +9 -2
  69. package/backend/new-multiple-pages.ts +2 -2
  70. package/backend/new-record-wizard.ts +15 -15
  71. package/backend/page-wizard/page-wizard.ts +2 -2
  72. package/backend/page-wizard/steps/doktype-step.ts +5 -5
  73. package/backend/pagetsconfig/pagetsconfig-includes.ts +1 -1
  74. package/backend/popover.ts +5 -5
  75. package/backend/record-download-button.ts +1 -1
  76. package/backend/recordlist.ts +6 -6
  77. package/backend/security/element/csp-reports.ts +8 -8
  78. package/backend/setup-module.ts +2 -2
  79. package/backend/sortable-table.ts +10 -4
  80. package/backend/storage/abstract-client-storage.ts +2 -2
  81. package/backend/storage/module-state-storage.ts +2 -2
  82. package/backend/tests/backend/utility/dom-helper-test.ts +2 -2
  83. package/backend/tests/form-engine/element/extra/select-box-filter-test.ts +3 -3
  84. package/backend/tests/form-engine-validation-test.ts +1 -1
  85. package/backend/tests/tree/tree-test.ts +41 -0
  86. package/backend/tree/file-storage-browser.ts +1 -1
  87. package/backend/tree/file-storage-tree-container.ts +4 -4
  88. package/backend/tree/page-browser.ts +1 -1
  89. package/backend/tree/page-position-select.ts +1 -1
  90. package/backend/tree/page-tree-element.ts +1 -1
  91. package/backend/tree/page-tree.ts +7 -1
  92. package/backend/tree/tree-module-state.ts +5 -5
  93. package/backend/tree/tree.ts +15 -8
  94. package/backend/user-pass-login.ts +2 -2
  95. package/backend/utility/collapse-state-persister.ts +1 -1
  96. package/backend/utility/collapse-state-search.ts +6 -6
  97. package/backend/utility/dom-helper.ts +3 -3
  98. package/backend/utility.ts +6 -6
  99. package/backend/viewport/content-navigation.ts +5 -0
  100. package/backend/viewport/navigation-container.ts +1 -1
  101. package/backend/viewport/toolbar.ts +3 -3
  102. package/backend/window-manager.ts +2 -2
  103. package/backend/wizard/events/auto-advance-event.ts +6 -0
  104. package/backend/wizard/events/before-next-step-event.ts +6 -0
  105. package/backend/wizard/events/step-summary-event.ts +6 -0
  106. package/backend/wizard/move-content-element.ts +1 -1
  107. package/backend/wizard/wizard.ts +8 -10
  108. package/belog/backend-log.ts +2 -2
  109. package/beuser/permissions.ts +2 -2
  110. package/core/ajax/ajax-response.ts +1 -1
  111. package/core/ajax/input-transformer.ts +1 -1
  112. package/core/event/debounce-event.ts +4 -4
  113. package/core/event/event-interface.ts +3 -3
  114. package/core/event/regular-event.ts +7 -7
  115. package/core/event/request-animation-frame-event.ts +4 -4
  116. package/core/event/throttle-event.ts +4 -4
  117. package/core/java-script-item-processor.ts +6 -0
  118. package/core/referrer-refresh.ts +2 -2
  119. package/core/security-utility.ts +1 -1
  120. package/dashboard/dashboard-wizard.ts +2 -2
  121. package/dashboard/dashboard.ts +5 -5
  122. package/dashboard/wizard/steps/preset-step.ts +3 -3
  123. package/extensionmanager/main.ts +7 -7
  124. package/filelist/browse-files.ts +1 -1
  125. package/filelist/browse-folders.ts +2 -2
  126. package/filelist/file-list-dragdrop.ts +5 -5
  127. package/filelist/file-list-transfer-handler.ts +2 -2
  128. package/filelist/file-list.ts +5 -5
  129. package/form/backend/form-editor/component/date-editor.ts +4 -0
  130. package/form/backend/form-editor/component/form-element-selector.ts +4 -0
  131. package/form/backend/form-editor/inspector-component.ts +6 -6
  132. package/form/backend/form-editor/mediator.ts +36 -36
  133. package/form/backend/form-editor/modals-component.ts +1 -1
  134. package/form/backend/form-editor/stage-component.ts +4 -4
  135. package/form/backend/form-editor/view-model.ts +7 -7
  136. package/form/backend/form-manager/view-model.ts +5 -5
  137. package/form/backend/form-wizard/form-wizard.ts +2 -2
  138. package/form/backend/form-wizard/steps/storage-step.ts +1 -1
  139. package/impexp/import-export.ts +1 -1
  140. package/info/translation-status.ts +2 -2
  141. package/install/ajax/ajax-queue.ts +1 -1
  142. package/install/module/abstract-interactable-module.ts +2 -2
  143. package/install/module/environment/image-processing.ts +4 -4
  144. package/install/module/environment/mail-test.ts +2 -2
  145. package/install/module/maintenance/clear-tables.ts +3 -3
  146. package/install/module/maintenance/clear-typo3temp-files.ts +8 -8
  147. package/install/module/maintenance/create-admin.ts +3 -3
  148. package/install/module/maintenance/database-analyzer.ts +9 -7
  149. package/install/module/maintenance/language-packs.ts +4 -4
  150. package/install/module/maintenance/reference-index.ts +1 -1
  151. package/install/module/settings/change-install-tool-password.ts +1 -1
  152. package/install/module/settings/extension-configuration.ts +5 -5
  153. package/install/module/settings/features.ts +1 -1
  154. package/install/module/settings/local-configuration.ts +5 -5
  155. package/install/module/settings/presets.ts +2 -2
  156. package/install/module/settings/system-maintainer.ts +1 -1
  157. package/install/module/upgrade/extension-scanner.ts +5 -5
  158. package/install/module/upgrade/tca-migrations-check.ts +1 -1
  159. package/install/module/upgrade/upgrade-docs.ts +16 -16
  160. package/install/module/upgrade/upgrade-wizards.ts +7 -8
  161. package/install/renderable/language-packs.ts +8 -2
  162. package/lowlevel/query-generator.ts +2 -2
  163. package/package.json +2 -2
  164. package/redirects/event-handler.ts +6 -0
  165. package/rte-ckeditor/ckeditor5.ts +7 -3
  166. package/rte-ckeditor/tests/ckeditor5-test.ts +68 -0
  167. package/scheduler/form-engine/element/timing-options-element.ts +1 -1
  168. package/scheduler/scheduler.ts +2 -2
  169. package/styleguide/checkbox-demo.ts +1 -1
  170. package/tstemplate/template-analyzer.ts +1 -1
  171. package/viewpage/main.ts +1 -1
  172. package/workspaces/backend.ts +5 -5
  173. package/workspaces/preview.ts +2 -2
  174. package/workspaces/renderable/record-table.ts +1 -1
  175. package/workspaces/renderable/send-to-stage-form.ts +1 -1
@@ -98,7 +98,7 @@ class FlexFormSectionContainer {
98
98
 
99
99
  private readonly updateSorting = (e: Sortable.SortableEvent): void => {
100
100
  const actionFields: NodeListOf<HTMLInputElement> = this.container.querySelectorAll(Selectors.actionFieldSelector);
101
- actionFields.forEach((element: HTMLInputElement, key: number): void => {
101
+ actionFields.forEach((element, key): void => {
102
102
  element.value = key.toString();
103
103
  });
104
104
 
@@ -161,7 +161,7 @@ class InlineControlContainer extends HTMLElement {
161
161
  }
162
162
 
163
163
  private static getValuesFromHashMap(hashmap: UniqueDefinitionCollection): Array<any> {
164
- return Object.keys(hashmap).map((key: string) => hashmap[key]);
164
+ return Object.keys(hashmap).map((key) => hashmap[key]);
165
165
  }
166
166
 
167
167
  private static selectOptionValueExists(selectElement: HTMLSelectElement, value: string): boolean {
@@ -449,10 +449,10 @@ class InlineControlContainer extends HTMLElement {
449
449
  * @param {string} afterUid
450
450
  */
451
451
  private async importRecord(params: Array<any>, afterUid?: string): Promise<void> {
452
- return this.ajaxDispatcher.send(
452
+ return this.ajaxDispatcher.send<InlineResponseInterface>(
453
453
  this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint(this.endpoints.create)),
454
454
  params,
455
- ).then(async (response: InlineResponseInterface): Promise<void> => {
455
+ ).then(async (response): Promise<void> => {
456
456
  if (this.isBelowMax()) {
457
457
  this.createRecord(
458
458
  response.compilerInput.uid,
@@ -553,10 +553,10 @@ class InlineControlContainer extends HTMLElement {
553
553
  return;
554
554
  }
555
555
 
556
- this.ajaxDispatcher.send(
556
+ this.ajaxDispatcher.send<InlineResponseInterface>(
557
557
  this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint(this.endpoints.synchronizelocalize)),
558
558
  [this.objectGroup, targetElement.dataset.type],
559
- ).then(async (response: InlineResponseInterface): Promise<void> => {
559
+ ).then(async (response): Promise<void> => {
560
560
  this.recordsContainer.insertAdjacentHTML('beforeend', response.data);
561
561
 
562
562
  const objectIdPrefix = this.objectGroup + Separators.structureSeparator;
@@ -617,9 +617,9 @@ class InlineControlContainer extends HTMLElement {
617
617
 
618
618
  if (!isLoading) {
619
619
  const ajaxRequest = this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint(this.endpoints.details));
620
- const request = this.ajaxDispatcher.send(ajaxRequest, [objectId]);
620
+ const request = this.ajaxDispatcher.send<InlineResponseInterface>(ajaxRequest, [objectId]);
621
621
 
622
- request.then(async (response: InlineResponseInterface): Promise<void> => {
622
+ request.then(async (response): Promise<void> => {
623
623
  delete this.requestQueue[objectId];
624
624
  delete this.progressQueue[objectId];
625
625
 
@@ -762,7 +762,7 @@ class InlineControlContainer extends HTMLElement {
762
762
  const currentRecordContainer = this.getRecordContainer(objectId);
763
763
  const recordUid = currentRecordContainer.dataset.objectUid;
764
764
  const recordListContainer = this.recordsContainer;
765
- const records = Array.from(recordListContainer.children).map((child: HTMLElement) => child.dataset.objectUid);
765
+ const records = Array.from(recordListContainer.children as HTMLCollectionOf<HTMLElement>).map((child) => child.dataset.objectUid);
766
766
  const position = records.indexOf(recordUid);
767
767
  let isChanged = false;
768
768
 
@@ -795,8 +795,8 @@ class InlineControlContainer extends HTMLElement {
795
795
  }
796
796
 
797
797
  const recordListContainer = this.recordsContainer;
798
- const records = Array.from(recordListContainer.querySelectorAll(selector`[data-object-parent-group="${this.objectGroup}"][data-placeholder-record="0"]`))
799
- .map((child: HTMLElement) => child.dataset.objectUid);
798
+ const records = Array.from(recordListContainer.querySelectorAll<HTMLElement>(selector`[data-object-parent-group="${this.objectGroup}"][data-placeholder-record="0"]`))
799
+ .map((child) => child.dataset.objectUid);
800
800
 
801
801
  (<HTMLInputElement>formField).value = records.join(',');
802
802
  FormEngine.markFieldAsChanged(formField);
@@ -841,12 +841,12 @@ class InlineControlContainer extends HTMLElement {
841
841
  * @param {boolean} visible
842
842
  */
843
843
  private toggleContainerControls(visible: boolean): void {
844
- const controlContainer = this.querySelectorAll(
844
+ const controlContainer = this.querySelectorAll<HTMLElement>(
845
845
  ':scope > ' + Selectors.controlContainer
846
846
  );
847
- controlContainer.forEach((container: HTMLElement): void => {
847
+ controlContainer.forEach((container): void => {
848
848
  const controlContainerButtons = container.querySelectorAll<HTMLButtonElement | HTMLAnchorElement>('button, a');
849
- controlContainerButtons.forEach((button: HTMLButtonElement | HTMLAnchorElement): void => {
849
+ controlContainerButtons.forEach((button): void => {
850
850
  button.hidden = !visible;
851
851
  });
852
852
  });
@@ -912,7 +912,7 @@ class InlineControlContainer extends HTMLElement {
912
912
  return;
913
913
  }
914
914
 
915
- records.forEach((recordUid: string, index: number): void => {
915
+ records.forEach((recordUid, index): void => {
916
916
  const recordContainer = this.getRecordContainer(objectId + Separators.structureSeparator + recordUid);
917
917
  if (recordContainer === null) {
918
918
  return;
@@ -25,7 +25,7 @@ export abstract class AbstractSortableSelectItems {
25
25
  * @param {HTMLSelectElement} fieldElement
26
26
  */
27
27
  private static moveOptionToTop(fieldElement: HTMLSelectElement): void {
28
- Array.from(fieldElement.querySelectorAll(':checked')).reverse().forEach((optionEl: HTMLOptionElement): void => {
28
+ Array.from(fieldElement.querySelectorAll<HTMLOptionElement>(':checked')).reverse().forEach((optionEl): void => {
29
29
  fieldElement.insertBefore(optionEl, fieldElement.firstElementChild);
30
30
  });
31
31
  }
@@ -36,7 +36,7 @@ export abstract class AbstractSortableSelectItems {
36
36
  * @param {HTMLSelectElement} fieldElement
37
37
  */
38
38
  private static moveOptionToBottom(fieldElement: HTMLSelectElement): void {
39
- fieldElement.querySelectorAll(':checked').forEach((optionEl: HTMLOptionElement): void => {
39
+ fieldElement.querySelectorAll<HTMLOptionElement>(':checked').forEach((optionEl): void => {
40
40
  fieldElement.insertBefore(optionEl, null);
41
41
  });
42
42
  }
@@ -85,7 +85,7 @@ export abstract class AbstractSortableSelectItems {
85
85
  */
86
86
  private static removeOption(fieldElement: HTMLSelectElement, availableFieldElement: HTMLSelectElement): void {
87
87
  const previousSelectIndex = fieldElement.selectedIndex;
88
- fieldElement.querySelectorAll(':checked').forEach((option: HTMLOptionElement): void => {
88
+ fieldElement.querySelectorAll<HTMLOptionElement>(':checked').forEach((option): void => {
89
89
  const originalOption = <HTMLOptionElement>availableFieldElement.querySelector(selector`option[value="${option.value}"]`);
90
90
  if (originalOption !== null) {
91
91
  originalOption.classList.remove('hidden');
@@ -72,7 +72,7 @@ class ColorElement extends HTMLElement {
72
72
  FormEngineValidation.validateField(e.target as HTMLInputElement);
73
73
  FormEngine.markFieldAsChanged(e.target as HTMLInputElement);
74
74
 
75
- document.querySelectorAll('.module-docheader-bar .btn').forEach((btn: HTMLButtonElement): void => {
75
+ document.querySelectorAll<HTMLButtonElement>('.module-docheader-bar .btn').forEach((btn): void => {
76
76
  btn.classList.remove('disabled');
77
77
  btn.disabled = false;
78
78
  });
@@ -56,7 +56,7 @@ class DatetimeElement extends HTMLElement {
56
56
  FormEngineValidation.validateField(e.target as HTMLInputElement);
57
57
  FormEngine.markFieldAsChanged(e.target as HTMLInputElement);
58
58
 
59
- document.querySelectorAll('.module-docheader-bar .btn').forEach((btn: HTMLButtonElement): void => {
59
+ document.querySelectorAll<HTMLButtonElement>('.module-docheader-bar .btn').forEach((btn): void => {
60
60
  btn.classList.remove('disabled');
61
61
  btn.disabled = false;
62
62
  });
@@ -73,11 +73,11 @@ export class CharCounter extends LitElement {
73
73
  this.targetElement.removeEventListener('blur', this.onBlur);
74
74
  }
75
75
 
76
- private readonly onInput = (e: InputEvent): void => {
76
+ private readonly onInput = (e: Event): void => {
77
77
  this.determineRemainingCharacters(e.target as HTMLInputElement|HTMLTextAreaElement);
78
78
  };
79
79
 
80
- private readonly onFocus = (e: FocusEvent): void => {
80
+ private readonly onFocus = (e: Event): void => {
81
81
  this.determineRemainingCharacters(e.target as HTMLInputElement|HTMLTextAreaElement);
82
82
  this.hidden = false;
83
83
  };
@@ -82,7 +82,7 @@ class SelectBoxFilter {
82
82
  // A plain substring match, no RegExp involved, therefore nothing to escape either
83
83
  const foldedFilterText = TextNormalizer.foldCaseAndDiacritics(TextNormalizer.normalizeInvisibleCharacters(filterText));
84
84
 
85
- this.availableOptions.forEach((option: HTMLOptionElement, index: number): void => {
85
+ this.availableOptions.forEach((option, index): void => {
86
86
  option.hidden = filterText.length > 0 && !this.foldedLabels[index].includes(foldedFilterText);
87
87
  SelectBoxFilter.toggleOptGroup(option);
88
88
  });
@@ -71,7 +71,7 @@ class MfaInfoElement {
71
71
  this.prepareDeactivateRequest(this.deactivteMfaButton);
72
72
  }).bindTo(this.deactivteMfaButton);
73
73
 
74
- this.deactivteProviderButtons.forEach((buttonElement: HTMLButtonElement): void => {
74
+ this.deactivteProviderButtons.forEach((buttonElement): void => {
75
75
  new RegularEvent('click', (e: Event): void => {
76
76
  e.preventDefault();
77
77
  this.prepareDeactivateRequest(buttonElement);
@@ -120,7 +120,7 @@ class MfaInfoElement {
120
120
  }).then(async (response: AjaxResponse): Promise<void> => {
121
121
  const data: Response = await response.resolve();
122
122
  if (data.status.length > 0) {
123
- data.status.forEach((status: Status): void => {
123
+ data.status.forEach((status): void => {
124
124
  if (data.success) {
125
125
  Notification.success(status.title, status.message);
126
126
  } else {
@@ -36,7 +36,7 @@ export class OnlineMediaFormElement extends LitElement {
36
36
  <div class="form-text">
37
37
  ${this.allowedExtensionsHelpText}<br>
38
38
  <ul class="badge-list">
39
- ${this.allowedExtensions.split(',').map((ext: string) => html`
39
+ ${this.allowedExtensions.split(',').map((ext) => html`
40
40
  <li><span class="badge badge-secondary">${ext.trim().toLowerCase()}</span></li>
41
41
  `)}
42
42
  </ul>
@@ -62,4 +62,8 @@ declare global {
62
62
  interface HTMLElementTagNameMap {
63
63
  'typo3-backend-formengine-online-media-form': OnlineMediaFormElement;
64
64
  }
65
+
66
+ interface HTMLElementEventMap {
67
+ 'typo3:formengine:online-media-added': CustomEvent<{ file: number }>;
68
+ }
65
69
  }
@@ -52,9 +52,9 @@ class SelectMultipleSideBySideElement extends AbstractSortableSelectItems {
52
52
  const fieldName = element.dataset.relatedfieldname;
53
53
  if (fieldName) {
54
54
  const exclusiveValues = Utility.trimExplode(',', element.dataset?.exclusivevalues ?? '');
55
- const selectedOptions = element.querySelectorAll('option:checked'); // Yep, :checked finds selected options
55
+ const selectedOptions = element.querySelectorAll<HTMLOptionElement>('option:checked'); // Yep, :checked finds selected options
56
56
  if (selectedOptions.length > 0) {
57
- selectedOptions.forEach((optionElement: HTMLOptionElement): void => {
57
+ selectedOptions.forEach((optionElement): void => {
58
58
  FormEngine.setSelectOptionFromExternalSource(
59
59
  fieldName,
60
60
  optionElement.value,
@@ -65,7 +65,7 @@ export class SelectTree extends Tree
65
65
  * Expand all nodes and refresh view
66
66
  */
67
67
  public expandAll(): void {
68
- this.nodes.forEach((node: TreeNodeInterface) => { this.showChildren(node); });
68
+ this.nodes.forEach((node) => { this.showChildren(node); });
69
69
  }
70
70
 
71
71
  /**
@@ -105,7 +105,7 @@ export class SelectTree extends Tree
105
105
  // A plain substring match, no RegExp involved, therefore nothing to escape either
106
106
  const foldedSearchTerm = SelectTree.fold(searchTerm ?? '');
107
107
 
108
- this.nodes.forEach((node: any) => {
108
+ this.nodes.forEach((node) => {
109
109
  // skip the root node in searches
110
110
  if (node === firstNode) {
111
111
  return;
@@ -190,7 +190,7 @@ export class SelectTree extends Tree
190
190
  */
191
191
  private prepareLoadedNodes(evt: CustomEvent): void {
192
192
  const nodes = evt.detail.nodes as Array<TreeNodeInterface>;
193
- evt.detail.nodes = nodes.map((node: TreeNodeInterface) => {
193
+ evt.detail.nodes = nodes.map((node) => {
194
194
  if (node.selectable === false) {
195
195
  this.settings.unselectableElements.push(node.identifier);
196
196
  }
@@ -88,7 +88,7 @@ class SlugElement {
88
88
  }
89
89
 
90
90
  private registerEvents(): void {
91
- const fieldsToListenOnList = Object.values(this.getAvailableFieldsForProposalGeneration()).map((field: HTMLElement) => field.dataset.slugSelector);
91
+ const fieldsToListenOnList = Object.values(this.getAvailableFieldsForProposalGeneration()).map((field) => field.dataset.slugSelector);
92
92
  const recreateButton: HTMLButtonElement = this.fullElement.querySelector(Selectors.recreateButton);
93
93
 
94
94
  // Listen on 'listenerFieldNames' for new pages. This is typically the 'title' field
@@ -158,7 +158,7 @@ class SlugElement {
158
158
  private sendSlugProposal(mode: ProposalModes): void {
159
159
  const input: Record<string, string> = {};
160
160
  if (mode === ProposalModes.AUTO || mode === ProposalModes.RECREATE) {
161
- Object.entries(this.getAvailableFieldsForProposalGeneration()).forEach((entry: [fieldName: string, field: HTMLInputElement|HTMLSelectElement]) => {
161
+ Object.entries(this.getAvailableFieldsForProposalGeneration()).forEach((entry) => {
162
162
  input[entry[0]] = entry[1].value;
163
163
  });
164
164
  if (this.options.includeUidInValues === true) {
@@ -214,18 +214,18 @@ class SlugElement {
214
214
  *
215
215
  * @return Record<string, string>
216
216
  */
217
- private getAvailableFieldsForProposalGeneration(): { [key: string]: HTMLElement } {
218
- const availableFields: { [key: string]: HTMLElement } = {};
217
+ private getAvailableFieldsForProposalGeneration(): { [key: string]: HTMLInputElement|HTMLSelectElement } {
218
+ const availableFields: { [key: string]: HTMLInputElement|HTMLSelectElement } = {};
219
219
  for (const [fieldName, selector] of Object.entries(this.fieldsToListenOn)) {
220
220
  const selectorCandidates = [
221
221
  '[data-formengine-input-name="' + selector + '"]',
222
222
  // Also check for fields, which do not point to a hidden input field (e.g. "input type=hidden", readOnly, or select fields)
223
223
  '[name="' + selector + '"]'
224
224
  ];
225
- let field: HTMLElement;
225
+ let field: HTMLInputElement|HTMLSelectElement;
226
226
  let usedSelector = '';
227
- selectorCandidates.some((testSelector: string) => {
228
- field = document.querySelector(testSelector) as HTMLElement;
227
+ selectorCandidates.some((testSelector) => {
228
+ field = document.querySelector<HTMLInputElement|HTMLSelectElement>(testSelector);
229
229
  usedSelector = testSelector;
230
230
  return field !== null;
231
231
  });
@@ -44,7 +44,7 @@ export class ResultContainer extends LitElement {
44
44
  if (this.results.length === 0) {
45
45
  content = html`<div class="alert alert-info">${labels.get('search.no_records_found')}</div>`;
46
46
  } else {
47
- content = html`${this.results.map((result: ResultItemInterface) => this.renderResultItem(result))}`;
47
+ content = html`${this.results.map((result) => this.renderResultItem(result))}`;
48
48
  }
49
49
  }
50
50
 
@@ -73,7 +73,7 @@ export class TableWizardElement extends LitElement {
73
73
  const textarea: HTMLTextAreaElement = document.querySelector(this.selectorData);
74
74
  const table: string[][] = [];
75
75
 
76
- textarea.value.split('\n').forEach((row: string) => {
76
+ textarea.value.split('\n').forEach((row) => {
77
77
  if (row !== '') {
78
78
  if(this.enclosure) {
79
79
  row = row.replace(new RegExp(this.enclosure, 'g'), '');
@@ -167,7 +167,7 @@ export class TableWizardElement extends LitElement {
167
167
 
168
168
  private renderTemplate(): TemplateResult {
169
169
  this.provideMinimalTable();
170
- const colIndexes = Object.keys(this.firstRow).map((item: string) => parseInt(item, 10));
170
+ const colIndexes = Object.keys(this.firstRow).map((item) => parseInt(item, 10));
171
171
  const lastColIndex = colIndexes[colIndexes.length - 1];
172
172
  const lastRowIndex = this.table.length - 1;
173
173
 
@@ -176,7 +176,7 @@ export class TableWizardElement extends LitElement {
176
176
  <table class="table table-center">
177
177
  <thead>
178
178
  <th>${this.renderTypeButton()}</th>
179
- ${colIndexes.map((colIndex: number) => html`
179
+ ${colIndexes.map((colIndex) => html`
180
180
  <th>${this.renderColButtons(colIndex, lastColIndex)}</th>
181
181
  `)}
182
182
  </thead>
@@ -184,7 +184,7 @@ export class TableWizardElement extends LitElement {
184
184
  ${this.table.map((row: string[], rowIndex: number) => html`
185
185
  <tr>
186
186
  <td>${this.renderRowButtons(rowIndex, lastRowIndex)}</td>
187
- ${row.map((value: string, colIndex: number) => html`
187
+ ${row.map((value, colIndex) => html`
188
188
  <td>${this.renderDataElement(value, rowIndex, colIndex)}</td>
189
189
  `)}
190
190
  </tr>
@@ -57,9 +57,9 @@ export class AjaxDispatcher {
57
57
  throw 'Undefined endpoint for route "' + routeName + '"';
58
58
  }
59
59
 
60
- public send(request: AjaxRequest, params: Array<string>): Promise<AjaxDispatcherResponse> {
61
- const sentRequest = request.post(this.createRequestBody(params)).then(async (response: AjaxResponse): Promise<AjaxDispatcherResponse> => {
62
- return this.processResponse(await response.resolve());
60
+ public send<T extends AjaxDispatcherResponse = AjaxDispatcherResponse>(request: AjaxRequest, params: Array<string>): Promise<T> {
61
+ const sentRequest = request.post(this.createRequestBody(params)).then(async (response: AjaxResponse): Promise<T> => {
62
+ return this.processResponse(await response.resolve()) as T;
63
63
  });
64
64
  sentRequest.catch((reason: Error): void => {
65
65
  if (reason instanceof DOMException && reason.name === 'AbortError') {
@@ -65,7 +65,7 @@ export default class FormEngineValidation {
65
65
  */
66
66
  public static initialize(formEngine: typeof FormEngine): void {
67
67
  formEngineInstance = formEngine;
68
- formEngineInstance.formElement.querySelectorAll('.' + FormEngineValidation.errorClass).forEach((e: HTMLElement) => e.classList.remove(FormEngineValidation.errorClass));
68
+ formEngineInstance.formElement.querySelectorAll<HTMLElement>('.' + FormEngineValidation.errorClass).forEach((e) => e.classList.remove(FormEngineValidation.errorClass));
69
69
 
70
70
  // Initialize input fields
71
71
  FormEngineValidation.initializeInputFields();
@@ -91,7 +91,7 @@ export default class FormEngineValidation {
91
91
  * Initialize all input fields
92
92
  */
93
93
  public static initializeInputFields(): void {
94
- formEngineInstance.formElement.querySelectorAll(FormEngineValidation.inputSelector).forEach((visibleField: FormEngineFieldElement): void => {
94
+ formEngineInstance.formElement.querySelectorAll<FormEngineFieldElement>(FormEngineValidation.inputSelector).forEach((visibleField): void => {
95
95
  // ignore fields which already have been initialized
96
96
  if ('formengineInputInitialized' in visibleField.dataset) {
97
97
  return;
@@ -500,7 +500,7 @@ export default class FormEngineValidation {
500
500
  */
501
501
  public static validate(section?: Element): void {
502
502
  if (typeof section === 'undefined' || section instanceof Document) {
503
- formEngineInstance.formElement.querySelectorAll(FormEngineValidation.markerSelector + ', [role="tablist"] > .nav-item').forEach((tabMenuItem: HTMLElement): void => {
503
+ formEngineInstance.formElement.querySelectorAll<HTMLElement>(FormEngineValidation.markerSelector + ', [role="tablist"] > .nav-item').forEach((tabMenuItem): void => {
504
504
  tabMenuItem.classList.remove(FormEngineValidation.validationErrorClass);
505
505
  });
506
506
  }
@@ -568,8 +568,8 @@ export default class FormEngineValidation {
568
568
  * Find tab by field and mark it as has-validation-error
569
569
  */
570
570
  public static markParentTab(element: FormEngineFieldElement, isValid: boolean): void {
571
- const panes = DomHelper.parents(element, '.tab-pane');
572
- panes.forEach((pane: HTMLElement): void => {
571
+ const panes = DomHelper.parents<HTMLElement>(element, '.tab-pane');
572
+ panes.forEach((pane): void => {
573
573
  if (isValid) {
574
574
  // If incoming element is valid, check for errors in the same sheet
575
575
  isValid = pane.querySelector('.has-error') === null;
@@ -631,3 +631,9 @@ export default class FormEngineValidation {
631
631
  });
632
632
  }
633
633
  }
634
+
635
+ declare global {
636
+ interface HTMLElementEventMap {
637
+ 't3-formengine-postfieldvalidation': CustomEvent<PostValidationEvent>;
638
+ }
639
+ }
@@ -65,7 +65,7 @@ const enum FormAction {
65
65
  saveAndAddRecord = '_savedokaddrecord',
66
66
  }
67
67
 
68
- type OnChangeFieldHandlerCallback = (data: object, e: Event) => void;
68
+ type OnChangeFieldHandlerCallback = (data: never, e: Event) => void;
69
69
  type PreviewActionCallback = (targetName: string, previewUrl: string, $actionElement: JQuery, modal: ModalElement) => void;
70
70
  type NewActionCallback = (targetName: string, $actionElement: JQuery) => void;
71
71
  type DuplicateActionCallback = (targetName: string, $actionElement: JQuery) => void;
@@ -236,7 +236,7 @@ export default (function() {
236
236
  return Modal.advanced({
237
237
  type: Modal.types.iframe,
238
238
  content: FormEngine.browserUrl + '&' + (new URLSearchParams(queryParams)).toString(),
239
- size: Modal.sizes.large
239
+ size: Modal.sizes.full
240
240
  });
241
241
  };
242
242
 
@@ -318,7 +318,7 @@ export default (function() {
318
318
  }
319
319
 
320
320
  if (reenableOptions && typeof optionEl !== 'undefined') {
321
- optionEl.closest('select').querySelectorAll('[disabled]').forEach(function (disabledOption: HTMLOptionElement) {
321
+ optionEl.closest('select').querySelectorAll<HTMLOptionElement>('[disabled]').forEach(function (disabledOption) {
322
322
  disabledOption.classList.remove('hidden');
323
323
  disabledOption.disabled = false;
324
324
  FormEngine.enableOptGroup(disabledOption);
@@ -394,7 +394,7 @@ export default (function() {
394
394
  * @param {HTMLElement} originalFieldEl the hidden form field
395
395
  */
396
396
  FormEngine.updateHiddenFieldValueFromSelect = function(selectFieldEl: HTMLSelectElement, originalFieldEl: HTMLSelectElement): void {
397
- const selectedValues: string[] = Array.from(selectFieldEl.options).map((el: HTMLOptionElement) => el.value);
397
+ const selectedValues: string[] = Array.from(selectFieldEl.options).map((el) => el.value);
398
398
 
399
399
  // make a comma separated list, if it is a multi-select
400
400
  // set the values to the final hidden field
@@ -672,8 +672,8 @@ export default (function() {
672
672
  }
673
673
  };
674
674
 
675
- const minlengthElements = document.querySelectorAll('[minlength]:not([data-input-type="datetimepicker"]):not(.t3js-charcounter-min-initialized)');
676
- minlengthElements.forEach((field: HTMLInputElement|HTMLTextAreaElement) => {
675
+ const minlengthElements = document.querySelectorAll<HTMLInputElement|HTMLTextAreaElement>('[minlength]:not([data-input-type="datetimepicker"]):not(.t3js-charcounter-min-initialized)');
676
+ minlengthElements.forEach((field) => {
677
677
  field.addEventListener('focus', (event) => {
678
678
  const minCharacterCountLeft = FormEngine.getMinCharacterLeftCount(field);
679
679
  if (minCharacterCountLeft > 0) {
@@ -720,7 +720,7 @@ export default (function() {
720
720
  * Initialize input / text field "null" checkbox CSS overlay if no placeholder is set.
721
721
  */
722
722
  FormEngine.initializeNullNoPlaceholderCheckboxes = function(): void {
723
- document.querySelectorAll('.t3-form-field-eval-null-checkbox').forEach((el: HTMLElement) => {
723
+ document.querySelectorAll<HTMLElement>('.t3-form-field-eval-null-checkbox').forEach((el) => {
724
724
  // Add disabled class to "t3js-formengine-field-item" if the null checkbox is NOT set,
725
725
  // This activates a CSS overlay "disabling" the input field and everything around.
726
726
  const checkbox = el.querySelector('input[type="checkbox"]') as HTMLInputElement;
@@ -735,7 +735,7 @@ export default (function() {
735
735
  * Initialize input / text field "null" checkbox placeholder / real field if placeholder is set.
736
736
  */
737
737
  FormEngine.initializeNullWithPlaceholderCheckboxes = function(): void {
738
- document.querySelectorAll('.t3js-form-field-eval-null-placeholder-checkbox').forEach((el: HTMLElement) => {
738
+ document.querySelectorAll<HTMLElement>('.t3js-form-field-eval-null-placeholder-checkbox').forEach((el) => {
739
739
  FormEngine.toggleCheckboxField(el.querySelector('input[type="checkbox"]'), false);
740
740
  });
741
741
  };
@@ -787,7 +787,7 @@ export default (function() {
787
787
  * Disable the input field on load if localization state selector is set to "parent" or "source"
788
788
  */
789
789
  FormEngine.initializeLocalizationStateSelector = function(): void {
790
- document.querySelectorAll('.t3js-l10n-state-container').forEach((el: HTMLElement) => {
790
+ document.querySelectorAll<HTMLElement>('.t3js-l10n-state-container').forEach((el) => {
791
791
  const input = el.closest('.t3js-formengine-field-item')?.querySelector('[data-formengine-input-name]') as HTMLInputElement|null;
792
792
  if (input === undefined || input === null) {
793
793
  return;
@@ -1011,7 +1011,7 @@ export default (function() {
1011
1011
  items.forEach((item) => {
1012
1012
  const handler = onFieldChangeHandlers.get(item.name);
1013
1013
  if (handler instanceof Function) {
1014
- handler.call(null, item.data || null, evt);
1014
+ handler.call(null, (item.data || null) as never, evt);
1015
1015
  }
1016
1016
  });
1017
1017
  };
@@ -1160,7 +1160,7 @@ export default (function() {
1160
1160
  }
1161
1161
  }
1162
1162
  const contentElement = document.createElement('p');
1163
- contentStrings.forEach((item: string, i: number): void => {
1163
+ contentStrings.forEach((item, i): void => {
1164
1164
  contentElement.append(item);
1165
1165
  if (i !== contentStrings.length - 1) {
1166
1166
  contentElement.append(document.createElement('br'));
@@ -228,7 +228,7 @@ class GlobalEventHandler {
228
228
  private assignHTMLFormChildElementValue(element: HTMLElement, value: string): void {
229
229
  const type: string = element.getAttribute('type');
230
230
  if (element instanceof HTMLSelectElement) {
231
- Array.from(element.options).some((option: HTMLOptionElement, index: number) => {
231
+ Array.from(element.options).some((option, index) => {
232
232
  if (option.value === value) {
233
233
  element.selectedIndex = index;
234
234
  return true;
@@ -34,7 +34,7 @@ export class HotkeyStruct {
34
34
  }
35
35
 
36
36
  public static fromHotkey(hotkey: string[]): HotkeyStruct {
37
- const nonModifierCodes = hotkey.filter((hotkeyPart: string) => !Object.values<string>(ModifierKeys).includes(hotkeyPart));
37
+ const nonModifierCodes = hotkey.filter((hotkeyPart) => !Object.values<string>(ModifierKeys).includes(hotkeyPart));
38
38
  if (nonModifierCodes.length > 1) {
39
39
  throw new Error('Cannot create HotkeyStruct with more than one non-modifier key, "' + nonModifierCodes.join('+') + '" given.');
40
40
  }
@@ -60,12 +60,12 @@ class Hotkeys {
60
60
  }
61
61
 
62
62
  public register(hotkey: Hotkey, handler: (e: KeyboardEvent) => void, options: Partial<Options> = {}): void {
63
- if (hotkey.filter((hotkeyPart: string) => !Object.values<string>(ModifierKeys).includes(hotkeyPart)).length === 0) {
63
+ if (hotkey.filter((hotkeyPart) => !Object.values<string>(ModifierKeys).includes(hotkeyPart)).length === 0) {
64
64
  throw new Error('Attempted to register hotkey "' + hotkey.join('+') + '" without a non-modifier key.');
65
65
  }
66
66
 
67
67
  // Normalize trigger
68
- hotkey = hotkey.map((h: string) => h.toLowerCase());
68
+ hotkey = hotkey.map((h) => h.toLowerCase());
69
69
 
70
70
  const mergedConfiguration: Options = { ...this.defaultOptions, ...options };
71
71
  if (!this.scopedHotkeyMap.has(mergedConfiguration.scope)) {
@@ -161,7 +161,7 @@ class Hotkeys {
161
161
  }
162
162
 
163
163
  // The standard requires to have modifier keys to be at first
164
- parts.sort((a: string, b: string): number => {
164
+ parts.sort((a, b): number => {
165
165
  const aIsModifierKey = Object.values<string>(ModifierKeys).includes(a);
166
166
  const bIsModifierKey = Object.values<string>(ModifierKeys).includes(b);
167
167