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.
- package/.github/workflows/sync-and-publish.yml +240 -191
- package/.last-synced-tag +1 -1
- package/README.md +13 -5
- package/adminpanel/admin-panel.ts +22 -22
- package/adminpanel/modules/cache.ts +3 -3
- package/backend/action-dispatcher.ts +8 -3
- package/backend/bookmark/bookmark-store.ts +5 -5
- package/backend/clipboard-panel.ts +2 -2
- package/backend/code-editor/element/code-mirror-element.ts +1 -1
- package/backend/code-editor/language/typoscript.ts +3 -3
- package/backend/code-editor/stream-parser/typoscript.ts +2 -2
- package/backend/color-picker.ts +2 -2
- package/backend/column-selector-button.ts +6 -6
- package/backend/context-help.ts +3 -3
- package/backend/context-menu.ts +8 -3
- package/backend/drag-tooltip.ts +9 -4
- package/backend/drag-uploader.ts +4 -4
- package/backend/element/draggable-resizable-element.ts +18 -12
- package/backend/element/icon-element.ts +2 -2
- package/backend/element/thumbnail-element.ts +2 -2
- package/backend/element-browser.ts +1 -1
- package/backend/event/consumer-scope.ts +2 -2
- package/backend/event/interaction-request-assignment.ts +1 -1
- package/backend/event/interaction-request-map.ts +3 -3
- package/backend/form-engine/container/flex-form-container-container.ts +2 -2
- package/backend/form-engine/container/flex-form-section-container.ts +1 -1
- package/backend/form-engine/container/inline-control-container.ts +14 -14
- package/backend/form-engine/element/abstract-sortable-select-items.ts +3 -3
- package/backend/form-engine/element/color-element.ts +1 -1
- package/backend/form-engine/element/datetime-element.ts +1 -1
- package/backend/form-engine/element/extra/char-counter.ts +2 -2
- package/backend/form-engine/element/extra/select-box-filter.ts +1 -1
- package/backend/form-engine/element/mfa-info-element.ts +2 -2
- package/backend/form-engine/element/online-media-form-element.ts +5 -1
- package/backend/form-engine/element/select-multiple-side-by-side-element.ts +2 -2
- package/backend/form-engine/element/select-tree.ts +3 -3
- package/backend/form-engine/element/slug-element.ts +7 -7
- package/backend/form-engine/element/suggest/result-container.ts +1 -1
- package/backend/form-engine/element/table-wizard-element.ts +4 -4
- package/backend/form-engine/inline-relation/ajax-dispatcher.ts +3 -3
- package/backend/form-engine-validation.ts +11 -5
- package/backend/form-engine.ts +11 -11
- package/backend/global-event-handler.ts +1 -1
- package/backend/hotkeys/hotkey-struct.ts +1 -1
- package/backend/hotkeys.ts +3 -3
- package/backend/image-manipulation.ts +19 -19
- package/backend/layout-module/drag-drop.ts +4 -4
- package/backend/layout-module/paste.ts +1 -1
- package/backend/live-search/element/result/item/action/action-container.ts +1 -1
- package/backend/live-search/element/result/item/item-container.ts +4 -4
- package/backend/live-search/element/result/result-container.ts +5 -0
- package/backend/live-search/element/result/result-pagination.ts +1 -1
- package/backend/live-search/live-search.ts +2 -2
- package/backend/localization/label-provider.ts +4 -4
- package/backend/localization/localization-wizard.ts +4 -4
- package/backend/localization/steps/content-record-selection-step.ts +8 -8
- package/backend/localization/steps/handler-selection-step.ts +4 -4
- package/backend/localization/steps/mode-step.ts +4 -4
- package/backend/localization/steps/source-language-step.ts +4 -4
- package/backend/localization/steps/target-language-step.ts +4 -4
- package/backend/login.ts +2 -2
- package/backend/module/iframe.ts +10 -0
- package/backend/module/router.ts +10 -0
- package/backend/module-menu.ts +3 -3
- package/backend/multi-record-selection-action.ts +1 -1
- package/backend/multi-record-selection-delete-action.ts +1 -1
- package/backend/multi-record-selection.ts +14 -14
- package/backend/multi-step-wizard.ts +9 -2
- package/backend/new-multiple-pages.ts +2 -2
- package/backend/new-record-wizard.ts +15 -15
- package/backend/page-wizard/page-wizard.ts +2 -2
- package/backend/page-wizard/steps/doktype-step.ts +5 -5
- package/backend/pagetsconfig/pagetsconfig-includes.ts +1 -1
- package/backend/popover.ts +5 -5
- package/backend/record-download-button.ts +1 -1
- package/backend/recordlist.ts +6 -6
- package/backend/security/element/csp-reports.ts +8 -8
- package/backend/setup-module.ts +2 -2
- package/backend/sortable-table.ts +10 -4
- package/backend/storage/abstract-client-storage.ts +2 -2
- package/backend/storage/module-state-storage.ts +2 -2
- package/backend/tests/backend/utility/dom-helper-test.ts +2 -2
- package/backend/tests/form-engine/element/extra/select-box-filter-test.ts +3 -3
- package/backend/tests/form-engine-validation-test.ts +1 -1
- package/backend/tests/tree/tree-test.ts +41 -0
- package/backend/tree/file-storage-browser.ts +1 -1
- package/backend/tree/file-storage-tree-container.ts +4 -4
- package/backend/tree/page-browser.ts +1 -1
- package/backend/tree/page-position-select.ts +1 -1
- package/backend/tree/page-tree-element.ts +1 -1
- package/backend/tree/page-tree.ts +7 -1
- package/backend/tree/tree-module-state.ts +5 -5
- package/backend/tree/tree.ts +15 -8
- package/backend/user-pass-login.ts +2 -2
- package/backend/utility/collapse-state-persister.ts +1 -1
- package/backend/utility/collapse-state-search.ts +6 -6
- package/backend/utility/dom-helper.ts +3 -3
- package/backend/utility.ts +6 -6
- package/backend/viewport/content-navigation.ts +5 -0
- package/backend/viewport/navigation-container.ts +1 -1
- package/backend/viewport/toolbar.ts +3 -3
- package/backend/window-manager.ts +2 -2
- package/backend/wizard/events/auto-advance-event.ts +6 -0
- package/backend/wizard/events/before-next-step-event.ts +6 -0
- package/backend/wizard/events/step-summary-event.ts +6 -0
- package/backend/wizard/move-content-element.ts +1 -1
- package/backend/wizard/wizard.ts +8 -10
- package/belog/backend-log.ts +2 -2
- package/beuser/permissions.ts +2 -2
- package/core/ajax/ajax-response.ts +1 -1
- package/core/ajax/input-transformer.ts +1 -1
- package/core/event/debounce-event.ts +4 -4
- package/core/event/event-interface.ts +3 -3
- package/core/event/regular-event.ts +7 -7
- package/core/event/request-animation-frame-event.ts +4 -4
- package/core/event/throttle-event.ts +4 -4
- package/core/java-script-item-processor.ts +6 -0
- package/core/referrer-refresh.ts +2 -2
- package/core/security-utility.ts +1 -1
- package/dashboard/dashboard-wizard.ts +2 -2
- package/dashboard/dashboard.ts +5 -5
- package/dashboard/wizard/steps/preset-step.ts +3 -3
- package/extensionmanager/main.ts +7 -7
- package/filelist/browse-files.ts +1 -1
- package/filelist/browse-folders.ts +2 -2
- package/filelist/file-list-dragdrop.ts +5 -5
- package/filelist/file-list-transfer-handler.ts +2 -2
- package/filelist/file-list.ts +5 -5
- package/form/backend/form-editor/component/date-editor.ts +4 -0
- package/form/backend/form-editor/component/form-element-selector.ts +4 -0
- package/form/backend/form-editor/inspector-component.ts +6 -6
- package/form/backend/form-editor/mediator.ts +36 -36
- package/form/backend/form-editor/modals-component.ts +1 -1
- package/form/backend/form-editor/stage-component.ts +4 -4
- package/form/backend/form-editor/view-model.ts +7 -7
- package/form/backend/form-manager/view-model.ts +5 -5
- package/form/backend/form-wizard/form-wizard.ts +2 -2
- package/form/backend/form-wizard/steps/storage-step.ts +1 -1
- package/impexp/import-export.ts +1 -1
- package/info/translation-status.ts +2 -2
- package/install/ajax/ajax-queue.ts +1 -1
- package/install/module/abstract-interactable-module.ts +2 -2
- package/install/module/environment/image-processing.ts +4 -4
- package/install/module/environment/mail-test.ts +2 -2
- package/install/module/maintenance/clear-tables.ts +3 -3
- package/install/module/maintenance/clear-typo3temp-files.ts +8 -8
- package/install/module/maintenance/create-admin.ts +3 -3
- package/install/module/maintenance/database-analyzer.ts +9 -7
- package/install/module/maintenance/language-packs.ts +4 -4
- package/install/module/maintenance/reference-index.ts +1 -1
- package/install/module/settings/change-install-tool-password.ts +1 -1
- package/install/module/settings/extension-configuration.ts +5 -5
- package/install/module/settings/features.ts +1 -1
- package/install/module/settings/local-configuration.ts +5 -5
- package/install/module/settings/presets.ts +2 -2
- package/install/module/settings/system-maintainer.ts +1 -1
- package/install/module/upgrade/extension-scanner.ts +5 -5
- package/install/module/upgrade/tca-migrations-check.ts +1 -1
- package/install/module/upgrade/upgrade-docs.ts +16 -16
- package/install/module/upgrade/upgrade-wizards.ts +7 -8
- package/install/renderable/language-packs.ts +8 -2
- package/lowlevel/query-generator.ts +2 -2
- package/package.json +2 -2
- package/redirects/event-handler.ts +6 -0
- package/rte-ckeditor/ckeditor5.ts +7 -3
- package/rte-ckeditor/tests/ckeditor5-test.ts +68 -0
- package/scheduler/form-engine/element/timing-options-element.ts +1 -1
- package/scheduler/scheduler.ts +2 -2
- package/styleguide/checkbox-demo.ts +1 -1
- package/tstemplate/template-analyzer.ts +1 -1
- package/viewpage/main.ts +1 -1
- package/workspaces/backend.ts +5 -5
- package/workspaces/preview.ts +2 -2
- package/workspaces/renderable/record-table.ts +1 -1
- package/workspaces/renderable/send-to-stage-form.ts +1 -1
|
@@ -280,7 +280,7 @@ class ImageManipulation {
|
|
|
280
280
|
/**
|
|
281
281
|
* Assign EventListener to cropVariantTriggers
|
|
282
282
|
*/
|
|
283
|
-
this.cropVariantTriggers.forEach((el
|
|
283
|
+
this.cropVariantTriggers.forEach((el) =>
|
|
284
284
|
el.addEventListener('click', (e: Event): void => {
|
|
285
285
|
/**
|
|
286
286
|
* Is the current cropVariantTrigger is active, bail out.
|
|
@@ -341,8 +341,8 @@ class ImageManipulation {
|
|
|
341
341
|
new RegularEvent('click', (): void => this.openPreview(this.data))
|
|
342
342
|
.delegateTo(this.currentModal, 'button[name=preview]');
|
|
343
343
|
} else {
|
|
344
|
-
this.currentModal.querySelectorAll('button[name=preview]')
|
|
345
|
-
.forEach((previewButton
|
|
344
|
+
this.currentModal.querySelectorAll<HTMLElement>('button[name=preview]')
|
|
345
|
+
.forEach((previewButton) => previewButton.style.display = 'none');
|
|
346
346
|
}
|
|
347
347
|
|
|
348
348
|
/**
|
|
@@ -400,8 +400,8 @@ class ImageManipulation {
|
|
|
400
400
|
this.syncEnabled = target.checked;
|
|
401
401
|
BrowserSession.set('sync-active-' + imageUid, this.syncEnabled ? 'true' : 'false');
|
|
402
402
|
if (this.syncEnabled) {
|
|
403
|
-
this.currentModal.querySelectorAll('.panel-button[data-exclude-from-sync="true"]')
|
|
404
|
-
.forEach((e
|
|
403
|
+
this.currentModal.querySelectorAll<HTMLElement>('.panel-button[data-exclude-from-sync="true"]')
|
|
404
|
+
.forEach((e) => e.setAttribute('disabled', 'disabled'));
|
|
405
405
|
|
|
406
406
|
// if the currently selected crop variant is now disabled, open the first available one.
|
|
407
407
|
const isDisabled = this.currentModal.querySelector('.panel-button[data-crop-variant-id="' + this.currentCropVariant.id + '"][data-exclude-from-sync="true"]') !== null;
|
|
@@ -412,8 +412,8 @@ class ImageManipulation {
|
|
|
412
412
|
}
|
|
413
413
|
}
|
|
414
414
|
} else {
|
|
415
|
-
this.currentModal.querySelectorAll('.panel-button[data-exclude-from-sync]')
|
|
416
|
-
.forEach((e
|
|
415
|
+
this.currentModal.querySelectorAll<HTMLElement>('.panel-button[data-exclude-from-sync]')
|
|
416
|
+
.forEach((e) => e.removeAttribute('disabled'));
|
|
417
417
|
}
|
|
418
418
|
}
|
|
419
419
|
).delegateTo(this.currentModal, '#sync-crop-variants');
|
|
@@ -446,7 +446,7 @@ class ImageManipulation {
|
|
|
446
446
|
this.imageOriginalSizeFactor = parseInt(image.dataset.originalWidth, 10) / imageData.naturalWidth;
|
|
447
447
|
|
|
448
448
|
// iterate over the crop variants and set up their respective preview
|
|
449
|
-
this.cropVariantTriggers.forEach((elem
|
|
449
|
+
this.cropVariantTriggers.forEach((elem): void => {
|
|
450
450
|
const cropVariantId: string = elem.dataset.cropVariantId;
|
|
451
451
|
const cropArea: Area = this.convertRelativeToAbsoluteCropArea(
|
|
452
452
|
this.data[cropVariantId].cropArea,
|
|
@@ -507,9 +507,9 @@ class ImageManipulation {
|
|
|
507
507
|
|
|
508
508
|
if (this.syncAvailable && this.syncEnabled) {
|
|
509
509
|
const data = this.data;
|
|
510
|
-
Object.keys(this.data).forEach((cropVariant
|
|
510
|
+
Object.keys(this.data).forEach((cropVariant): void => {
|
|
511
511
|
let trigger: HTMLElement = null;
|
|
512
|
-
this.cropVariantTriggers.forEach((e
|
|
512
|
+
this.cropVariantTriggers.forEach((e) => {
|
|
513
513
|
if (e.dataset.cropVariantId === cropVariant) {
|
|
514
514
|
trigger = e;
|
|
515
515
|
}
|
|
@@ -540,9 +540,9 @@ class ImageManipulation {
|
|
|
540
540
|
|
|
541
541
|
if (this.syncAvailable && this.syncEnabled) {
|
|
542
542
|
const data = this.data;
|
|
543
|
-
Object.keys(this.data).forEach((cropVariant
|
|
543
|
+
Object.keys(this.data).forEach((cropVariant): void => {
|
|
544
544
|
let trigger: HTMLElement = null;
|
|
545
|
-
this.cropVariantTriggers.forEach((e
|
|
545
|
+
this.cropVariantTriggers.forEach((e) => {
|
|
546
546
|
if (e.dataset.cropVariantId === cropVariant) {
|
|
547
547
|
trigger = e;
|
|
548
548
|
}
|
|
@@ -579,8 +579,8 @@ class ImageManipulation {
|
|
|
579
579
|
this.setAspectRatio(selectedRatio);
|
|
580
580
|
this.setCropArea(temp.cropArea);
|
|
581
581
|
this.currentCropVariant = Object.assign({}, temp, cropVariant);
|
|
582
|
-
this.cropBox?.querySelectorAll(this.coverAreaSelector)?.forEach((el
|
|
583
|
-
this.cropBox?.querySelectorAll(this.focusAreaSelector)?.forEach((el
|
|
582
|
+
this.cropBox?.querySelectorAll<HTMLElement>(this.coverAreaSelector)?.forEach((el) => el.remove());
|
|
583
|
+
this.cropBox?.querySelectorAll<HTMLElement>(this.focusAreaSelector)?.forEach((el) => el.remove());
|
|
584
584
|
|
|
585
585
|
// check if new cropVariant has focusArea
|
|
586
586
|
if (cropVariant.focusArea) {
|
|
@@ -655,7 +655,7 @@ class ImageManipulation {
|
|
|
655
655
|
* @param {Array<Area>} coverAreas - An array of areas to construct the cover area elements from
|
|
656
656
|
*/
|
|
657
657
|
private initCoverAreas(container: HTMLElement, coverAreas: Area[]): void {
|
|
658
|
-
coverAreas.forEach((coverArea
|
|
658
|
+
coverAreas.forEach((coverArea): void => {
|
|
659
659
|
const styles = {
|
|
660
660
|
height: ImageManipulation.toCssPercent(coverArea.height),
|
|
661
661
|
left: ImageManipulation.toCssPercent(coverArea.x),
|
|
@@ -782,7 +782,7 @@ class ImageManipulation {
|
|
|
782
782
|
return false;
|
|
783
783
|
}
|
|
784
784
|
return coverAreas
|
|
785
|
-
.some((coverArea
|
|
785
|
+
.some((coverArea): boolean => {
|
|
786
786
|
return focusArea.x < coverArea.x + coverArea.width
|
|
787
787
|
&& coverArea.x < focusArea.x + focusArea.width
|
|
788
788
|
&& focusArea.y < coverArea.y + coverArea.height
|
|
@@ -831,7 +831,7 @@ class ImageManipulation {
|
|
|
831
831
|
const imageData: Cropper.ImageData = this.cropper.getImageData();
|
|
832
832
|
|
|
833
833
|
// iterate over the crop variants and set up their respective preview
|
|
834
|
-
Object.keys(data).forEach((cropVariantId
|
|
834
|
+
Object.keys(data).forEach((cropVariantId) => {
|
|
835
835
|
const cropVariant: CropVariant = data[cropVariantId];
|
|
836
836
|
const cropData: Area = this.convertRelativeToAbsoluteCropArea(cropVariant.cropArea, imageData);
|
|
837
837
|
|
|
@@ -956,8 +956,8 @@ class ImageManipulation {
|
|
|
956
956
|
|
|
957
957
|
private renderElements(template: TemplateResult, target: HTMLElement, selector?: string): HTMLElement|null {
|
|
958
958
|
const nodes = renderNodes(template);
|
|
959
|
-
const elements = Array.from(nodes).filter((node
|
|
960
|
-
elements.forEach((element
|
|
959
|
+
const elements = Array.from(nodes).filter((node): node is HTMLElement => node instanceof HTMLElement);
|
|
960
|
+
elements.forEach((element) => target.appendChild(element));
|
|
961
961
|
return selector ? target.querySelector(selector) : null;
|
|
962
962
|
}
|
|
963
963
|
}
|
|
@@ -314,9 +314,9 @@ class DragDrop {
|
|
|
314
314
|
iconIdentifier = contentElementIcon.dataset.identifier;
|
|
315
315
|
}
|
|
316
316
|
|
|
317
|
-
const contentImagePreviews = contentElement.querySelectorAll('.preview-thumbnails-element-image img');
|
|
317
|
+
const contentImagePreviews = contentElement.querySelectorAll<HTMLImageElement>('.preview-thumbnails-element-image img');
|
|
318
318
|
if (contentImagePreviews.length > 0) {
|
|
319
|
-
contentImagePreviews.forEach((image
|
|
319
|
+
contentImagePreviews.forEach((image): void => {
|
|
320
320
|
thumbnails.push({
|
|
321
321
|
src: image.src,
|
|
322
322
|
height: image.height,
|
|
@@ -343,7 +343,7 @@ class DragDrop {
|
|
|
343
343
|
}
|
|
344
344
|
|
|
345
345
|
protected showDropZones(): void {
|
|
346
|
-
document.querySelectorAll(Identifiers.dropZone).forEach((element
|
|
346
|
+
document.querySelectorAll<HTMLElement>(Identifiers.dropZone).forEach((element): void => {
|
|
347
347
|
if (!isContentTypeAllowedInColumn(this.draggedContentType, element.closest('[data-colpos]'))) {
|
|
348
348
|
return;
|
|
349
349
|
}
|
|
@@ -357,7 +357,7 @@ class DragDrop {
|
|
|
357
357
|
}
|
|
358
358
|
|
|
359
359
|
protected hideDropZones(): void {
|
|
360
|
-
document.querySelectorAll(Identifiers.dropZone).forEach((element
|
|
360
|
+
document.querySelectorAll<HTMLElement>(Identifiers.dropZone).forEach((element): void => {
|
|
361
361
|
element.hidden = true;
|
|
362
362
|
const addContentButton = element.parentElement.querySelector(Identifiers.addContent) as HTMLElement;
|
|
363
363
|
if (addContentButton !== null) {
|
|
@@ -99,7 +99,7 @@ class Paste {
|
|
|
99
99
|
*/
|
|
100
100
|
private activatePasteIcons(): void {
|
|
101
101
|
if (this.pasteAfterLinkTemplate && this.pasteIntoLinkTemplate) {
|
|
102
|
-
document.querySelectorAll('.t3js-page-new-ce').forEach((el
|
|
102
|
+
document.querySelectorAll<HTMLElement>('.t3js-page-new-ce').forEach((el): void => {
|
|
103
103
|
if (!isContentTypeAllowedForTarget(this.itemOnClipboardCType, el)) {
|
|
104
104
|
return;
|
|
105
105
|
}
|
|
@@ -31,7 +31,7 @@ export class ActionContainer extends LitElement {
|
|
|
31
31
|
|
|
32
32
|
protected override render(): TemplateResult {
|
|
33
33
|
return html`<typo3-backend-live-search-result-action-list>
|
|
34
|
-
${this.resultItem.actions.map((action
|
|
34
|
+
${this.resultItem.actions.map((action) => this.renderActionItem(this.resultItem, action))}
|
|
35
35
|
</typo3-backend-live-search-result-action-list>`;
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -45,13 +45,13 @@ export class ItemContainer extends LitElement {
|
|
|
45
45
|
|
|
46
46
|
protected override render(): TemplateResult {
|
|
47
47
|
const groupedResults: GroupedResultItems = {};
|
|
48
|
-
const filteredResults = this.results.filter((result
|
|
48
|
+
const filteredResults = this.results.filter((result): boolean => result !== null);
|
|
49
49
|
if (filteredResults.length !== this.results.length) {
|
|
50
50
|
console.warn(
|
|
51
51
|
'The result set contained "null" values, indicating something went wrong while building the search results. Affected values were removed to no break the user interface.'
|
|
52
52
|
);
|
|
53
53
|
}
|
|
54
|
-
filteredResults.forEach((result
|
|
54
|
+
filteredResults.forEach((result): void => {
|
|
55
55
|
if (!(result.typeLabel in groupedResults)) {
|
|
56
56
|
groupedResults[result.typeLabel] = [result];
|
|
57
57
|
} else {
|
|
@@ -69,7 +69,7 @@ export class ItemContainer extends LitElement {
|
|
|
69
69
|
for (const [type, results] of Object.entries(groupedResults)) {
|
|
70
70
|
const countElements = results.length;
|
|
71
71
|
items.push(html`<h6 class="livesearch-result-item-group-label">${type} (${countElements})</h6>`);
|
|
72
|
-
items.push(...results.map((result
|
|
72
|
+
items.push(...results.map((result) => html`${until(
|
|
73
73
|
this.renderResultItem(result),
|
|
74
74
|
html`<typo3-backend-spinner></typo3-backend-spinner>`
|
|
75
75
|
)}`));
|
|
@@ -122,7 +122,7 @@ export class ItemContainer extends LitElement {
|
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
private onScroll(e: Event): void {
|
|
125
|
-
this.querySelectorAll('.livesearch-result-item-group-label').forEach((groupLabel
|
|
125
|
+
this.querySelectorAll<HTMLElement>('.livesearch-result-item-group-label').forEach((groupLabel): void => {
|
|
126
126
|
groupLabel.classList.toggle('sticky', groupLabel.offsetTop <= (e.target as HTMLElement).scrollTop);
|
|
127
127
|
});
|
|
128
128
|
}
|
|
@@ -112,4 +112,9 @@ declare global {
|
|
|
112
112
|
interface HTMLElementTagNameMap {
|
|
113
113
|
'typo3-backend-live-search-result-container': ResultContainer;
|
|
114
114
|
}
|
|
115
|
+
|
|
116
|
+
interface HTMLElementEventMap {
|
|
117
|
+
'livesearch:request-actions': CustomEvent<RequestActionsEventData>;
|
|
118
|
+
'livesearch:invoke-action': CustomEvent<InvokeActionEventData>;
|
|
119
|
+
}
|
|
115
120
|
}
|
|
@@ -57,7 +57,7 @@ export class ResultPagination extends LitElement {
|
|
|
57
57
|
</typo3-backend-live-search-result-page>
|
|
58
58
|
</li>` : nothing}
|
|
59
59
|
${this.pagination.hasLessPages ? html`<li class="page-item disabled"><span class="page-link disabled">…</span></li>` : nothing}
|
|
60
|
-
${this.pagination.allPageNumbers.map((page
|
|
60
|
+
${this.pagination.allPageNumbers.map((page) => html`
|
|
61
61
|
<li class="page-item">
|
|
62
62
|
<typo3-backend-live-search-result-page page="${page}" perPage="${this.pagination.itemsPerPage}" class="page-link ${this.pagination.currentPage === page ? 'active' : ''}">${page}</typo3-backend-live-search-result-page>
|
|
63
63
|
</li>
|
|
@@ -187,7 +187,7 @@ class LiveSearch {
|
|
|
187
187
|
* // do stuff here
|
|
188
188
|
* });
|
|
189
189
|
*/
|
|
190
|
-
['modal-loaded', 'typo3-modal-shown'].forEach((eventToListenOn
|
|
190
|
+
['modal-loaded', 'typo3-modal-shown'].forEach((eventToListenOn) => {
|
|
191
191
|
modal.addEventListener(eventToListenOn, () => {
|
|
192
192
|
const searchField = modal.querySelector('input[type="search"]') as HTMLInputElement|null;
|
|
193
193
|
if (searchField !== null) {
|
|
@@ -200,7 +200,7 @@ class LiveSearch {
|
|
|
200
200
|
|
|
201
201
|
private composeSearchOptions(searchOptions: SearchOption[]): { [key: string]: string[] } {
|
|
202
202
|
const composedSearchOptions: { [key: string]: string[] } = {};
|
|
203
|
-
searchOptions.forEach((searchOption
|
|
203
|
+
searchOptions.forEach((searchOption): void => {
|
|
204
204
|
if (composedSearchOptions[searchOption.key] === undefined) {
|
|
205
205
|
composedSearchOptions[searchOption.key] = [];
|
|
206
206
|
}
|
|
@@ -129,8 +129,8 @@ function createFormatter(label: string): IntlMessageFormat {
|
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
const formatters: Formatters = {
|
|
132
|
-
getNumberFormat: memoize('number', (locale, opts) => new Intl.NumberFormat(locale, opts)),
|
|
133
|
-
getDateTimeFormat: memoize('datetime', (locale, opts) => {
|
|
132
|
+
getNumberFormat: memoize('number', (locale?: string | string[], opts?: Intl.NumberFormatOptions) => new Intl.NumberFormat(locale, opts)),
|
|
133
|
+
getDateTimeFormat: memoize('datetime', (locale?: Intl.LocalesArgument, opts?: Intl.DateTimeFormatOptions) => {
|
|
134
134
|
const { dateStyle, timeStyle, timeZone } = opts;
|
|
135
135
|
|
|
136
136
|
// Apply configured TYPO3 date format to the "medium" preset
|
|
@@ -152,10 +152,10 @@ const formatters: Formatters = {
|
|
|
152
152
|
|
|
153
153
|
return new Intl.DateTimeFormat(locale, { dateStyle, timeStyle, timeZone });
|
|
154
154
|
}),
|
|
155
|
-
getPluralRules: memoize('date', (locale, opts) => new Intl.PluralRules(locale, opts)),
|
|
155
|
+
getPluralRules: memoize('date', (locale?: Intl.LocalesArgument, opts?: Intl.PluralRulesOptions) => new Intl.PluralRules(locale, opts)),
|
|
156
156
|
};
|
|
157
157
|
|
|
158
|
-
type Factory = (...args:
|
|
158
|
+
type Factory = (...args: never[]) => object;
|
|
159
159
|
const cache: Record<string, object> = {};
|
|
160
160
|
/**
|
|
161
161
|
* Cache the (object) result of a factory function,
|
|
@@ -48,7 +48,7 @@ export interface LocalizationDataStore extends DataStore {
|
|
|
48
48
|
type LocalizationDataStoreKey = keyof LocalizationDataStore;
|
|
49
49
|
|
|
50
50
|
export interface LocalizationContext {
|
|
51
|
-
wizard: Wizard
|
|
51
|
+
wizard: Wizard<LocalizationDataStore>;
|
|
52
52
|
targetLanguage: number;
|
|
53
53
|
recordType: string;
|
|
54
54
|
recordUid: number;
|
|
@@ -72,13 +72,13 @@ export class LocalizationWizard extends LitElement {
|
|
|
72
72
|
@property({ type: Number, attribute: 'record-uid' }) recordUid: number;
|
|
73
73
|
@property({ type: Number, attribute: 'target-language' }) targetLanguage?: number;
|
|
74
74
|
|
|
75
|
-
@query('typo3-backend-wizard') wizard!: Wizard
|
|
75
|
+
@query('typo3-backend-wizard') wizard!: Wizard<LocalizationDataStore>;
|
|
76
76
|
|
|
77
77
|
@state() steps: WizardStepInterface[] = [];
|
|
78
78
|
@state() submissionService: SubmissionServiceInterface;
|
|
79
79
|
|
|
80
80
|
protected readonly recordInfoTask = new Task(this, {
|
|
81
|
-
task: async ([recordType, recordUid]
|
|
81
|
+
task: async ([recordType, recordUid]): Promise<RecordInfo> => {
|
|
82
82
|
try {
|
|
83
83
|
const response = await new AjaxRequest(TYPO3.settings.ajaxUrls.wizard_localization_get_record).withQueryArguments({
|
|
84
84
|
recordType: recordType,
|
|
@@ -97,7 +97,7 @@ export class LocalizationWizard extends LitElement {
|
|
|
97
97
|
throw error;
|
|
98
98
|
}
|
|
99
99
|
},
|
|
100
|
-
args: () => [this.recordType, this.recordUid],
|
|
100
|
+
args: () => [this.recordType, this.recordUid] as const,
|
|
101
101
|
});
|
|
102
102
|
|
|
103
103
|
override connectedCallback() {
|
|
@@ -72,7 +72,7 @@ export class ContentRecordSelectionStep implements WizardStepInterface, WizardSt
|
|
|
72
72
|
|
|
73
73
|
constructor(private readonly context: LocalizationContext) {
|
|
74
74
|
this.task = new Task(this.context.wizard, {
|
|
75
|
-
task: async ([pageUid, targetLanguage, sourceLanguage]
|
|
75
|
+
task: async ([pageUid, targetLanguage, sourceLanguage]): Promise<PageRecordSelection> => {
|
|
76
76
|
const response = await new AjaxRequest(TYPO3.settings.ajaxUrls.wizard_localization_get_content).withQueryArguments({
|
|
77
77
|
pageUid: pageUid,
|
|
78
78
|
targetLanguage: targetLanguage,
|
|
@@ -82,7 +82,7 @@ export class ContentRecordSelectionStep implements WizardStepInterface, WizardSt
|
|
|
82
82
|
|
|
83
83
|
return result;
|
|
84
84
|
},
|
|
85
|
-
args: () => [this.context.recordUid, this.context.getStoreData('targetLanguage'), this.context.getStoreData('sourceLanguage')],
|
|
85
|
+
args: () => [this.context.recordUid, this.context.getStoreData('targetLanguage'), this.context.getStoreData('sourceLanguage')] as const,
|
|
86
86
|
autoRun: false
|
|
87
87
|
});
|
|
88
88
|
}
|
|
@@ -194,9 +194,9 @@ export class ContentRecordSelectionStep implements WizardStepInterface, WizardSt
|
|
|
194
194
|
const records: ContentRecord[] = [];
|
|
195
195
|
|
|
196
196
|
if (this.task.value) {
|
|
197
|
-
this.task.value.layout.rows.forEach((row
|
|
198
|
-
row.columns.forEach((column
|
|
199
|
-
column.records.forEach((record
|
|
197
|
+
this.task.value.layout.rows.forEach((row) => {
|
|
198
|
+
row.columns.forEach((column) => {
|
|
199
|
+
column.records.forEach((record) => {
|
|
200
200
|
if (selectedUids.includes(record.uid)) {
|
|
201
201
|
records.push(record);
|
|
202
202
|
}
|
|
@@ -355,9 +355,9 @@ export class ContentRecordSelectionStep implements WizardStepInterface, WizardSt
|
|
|
355
355
|
|
|
356
356
|
private getAllRecordUids(layout: BackendLayoutStructure): number[] {
|
|
357
357
|
const allUids: number[] = [];
|
|
358
|
-
layout.rows.forEach((row
|
|
359
|
-
row.columns.forEach((column
|
|
360
|
-
column.records.forEach((record
|
|
358
|
+
layout.rows.forEach((row) => {
|
|
359
|
+
row.columns.forEach((column) => {
|
|
360
|
+
column.records.forEach((record) => {
|
|
361
361
|
allUids.push(record.uid);
|
|
362
362
|
});
|
|
363
363
|
});
|
|
@@ -40,7 +40,7 @@ export class HandlerSelectionStep implements WizardStepInterface, WizardStepValu
|
|
|
40
40
|
|
|
41
41
|
constructor(private readonly context: LocalizationContext) {
|
|
42
42
|
this.task = new Task(this.context.wizard, {
|
|
43
|
-
task: async ([recordType, recordUid, sourceLanguage, targetLanguage, mode]
|
|
43
|
+
task: async ([recordType, recordUid, sourceLanguage, targetLanguage, mode]): Promise<LocalizationHandler[]> => {
|
|
44
44
|
if (sourceLanguage == null || targetLanguage == null || mode == null) {
|
|
45
45
|
return [];
|
|
46
46
|
}
|
|
@@ -58,7 +58,7 @@ export class HandlerSelectionStep implements WizardStepInterface, WizardStepValu
|
|
|
58
58
|
|
|
59
59
|
return handlers;
|
|
60
60
|
},
|
|
61
|
-
args: () => [this.context.recordType, this.context.recordUid, this.context.getStoreData('sourceLanguage'), this.context.getStoreData('targetLanguage'), this.context.getStoreData('localizationMode')],
|
|
61
|
+
args: () => [this.context.recordType, this.context.recordUid, this.context.getStoreData('sourceLanguage'), this.context.getStoreData('targetLanguage'), this.context.getStoreData('localizationMode')] as const,
|
|
62
62
|
autoRun: false
|
|
63
63
|
});
|
|
64
64
|
}
|
|
@@ -114,7 +114,7 @@ export class HandlerSelectionStep implements WizardStepInterface, WizardStepValu
|
|
|
114
114
|
<h2 class="h4">${localizationWizardLabels.get('step.handler_selection.headline')}</h2>
|
|
115
115
|
<p>${localizationWizardLabels.get('step.handler_selection.description')}</p>
|
|
116
116
|
<div class="form-check-card-container">
|
|
117
|
-
${handlers.map((handler
|
|
117
|
+
${handlers.map((handler) => this.renderHandlerOption(handler))}
|
|
118
118
|
</div>
|
|
119
119
|
</div>
|
|
120
120
|
`;
|
|
@@ -147,7 +147,7 @@ export class HandlerSelectionStep implements WizardStepInterface, WizardStepValu
|
|
|
147
147
|
return [];
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
const handler = this.task.value.find((h
|
|
150
|
+
const handler = this.task.value.find((h) => h.identifier === selectedHandler);
|
|
151
151
|
if (!handler) {
|
|
152
152
|
return [];
|
|
153
153
|
}
|
|
@@ -41,7 +41,7 @@ export class ModeStep implements WizardStepInterface, WizardStepValueInterface,
|
|
|
41
41
|
|
|
42
42
|
constructor(private readonly context: LocalizationContext) {
|
|
43
43
|
this.task = new Task(this.context.wizard, {
|
|
44
|
-
task: async ([recordType, recordUid, targetLanguage, sourceLanguage]
|
|
44
|
+
task: async ([recordType, recordUid, targetLanguage, sourceLanguage]): Promise<LocalizationMode[]> => {
|
|
45
45
|
if (targetLanguage == null || sourceLanguage == null) {
|
|
46
46
|
return [];
|
|
47
47
|
}
|
|
@@ -56,7 +56,7 @@ export class ModeStep implements WizardStepInterface, WizardStepValueInterface,
|
|
|
56
56
|
|
|
57
57
|
return modes;
|
|
58
58
|
},
|
|
59
|
-
args: () => [this.context.recordType, this.context.recordUid, this.context.getStoreData('targetLanguage'), this.context.getStoreData('sourceLanguage')],
|
|
59
|
+
args: () => [this.context.recordType, this.context.recordUid, this.context.getStoreData('targetLanguage'), this.context.getStoreData('sourceLanguage')] as const,
|
|
60
60
|
autoRun: false
|
|
61
61
|
});
|
|
62
62
|
}
|
|
@@ -110,7 +110,7 @@ export class ModeStep implements WizardStepInterface, WizardStepValueInterface,
|
|
|
110
110
|
content = html`
|
|
111
111
|
<p>${localizationWizardLabels.get('step.modes.description')}</p>
|
|
112
112
|
<div class="form-check-card-container">
|
|
113
|
-
${modes.map((mode
|
|
113
|
+
${modes.map((mode) => html`
|
|
114
114
|
<div class="form-check form-check-type-card">
|
|
115
115
|
<input
|
|
116
116
|
class="form-check-input"
|
|
@@ -171,7 +171,7 @@ export class ModeStep implements WizardStepInterface, WizardStepValueInterface,
|
|
|
171
171
|
return [];
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
const mode = this.task.value.find((m
|
|
174
|
+
const mode = this.task.value.find((m) => m.key === selectedMode);
|
|
175
175
|
if (!mode) {
|
|
176
176
|
return [];
|
|
177
177
|
}
|
|
@@ -33,7 +33,7 @@ export class SourceLanguageStep implements WizardStepInterface, WizardStepValueI
|
|
|
33
33
|
|
|
34
34
|
constructor(private readonly context: LocalizationContext) {
|
|
35
35
|
this.task = new Task(this.context.wizard, {
|
|
36
|
-
task: async ([recordType, recordUid, targetLanguageId]
|
|
36
|
+
task: async ([recordType, recordUid, targetLanguageId]): Promise<LocalizationLanguageRecord[]> => {
|
|
37
37
|
if (targetLanguageId == null) {
|
|
38
38
|
return [];
|
|
39
39
|
}
|
|
@@ -47,7 +47,7 @@ export class SourceLanguageStep implements WizardStepInterface, WizardStepValueI
|
|
|
47
47
|
|
|
48
48
|
return sourceLanguages;
|
|
49
49
|
},
|
|
50
|
-
args: () => [this.context.recordType, this.context.recordUid, this.context.getStoreData('targetLanguage')],
|
|
50
|
+
args: () => [this.context.recordType, this.context.recordUid, this.context.getStoreData('targetLanguage')] as const,
|
|
51
51
|
autoRun: false
|
|
52
52
|
});
|
|
53
53
|
}
|
|
@@ -108,7 +108,7 @@ export class SourceLanguageStep implements WizardStepInterface, WizardStepValueI
|
|
|
108
108
|
<h2 class="h4">${localizationWizardLabels.get('step.source_language.headline')}</h2>
|
|
109
109
|
<p>${localizationWizardLabels.get('step.source_language.description')}</p>
|
|
110
110
|
<div class="form-check-card-container">
|
|
111
|
-
${languages.map((language
|
|
111
|
+
${languages.map((language) => html`
|
|
112
112
|
<div class="form-check form-check-type-card">
|
|
113
113
|
<input
|
|
114
114
|
class="form-check-input"
|
|
@@ -159,7 +159,7 @@ export class SourceLanguageStep implements WizardStepInterface, WizardStepValueI
|
|
|
159
159
|
return [];
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
-
const selectedLanguage = this.task.value.find((lang
|
|
162
|
+
const selectedLanguage = this.task.value.find((lang) => lang.uid === selectedSourceLanguage);
|
|
163
163
|
if (!selectedLanguage) {
|
|
164
164
|
return [];
|
|
165
165
|
}
|
|
@@ -36,7 +36,7 @@ export class TargetLanguageStep implements WizardStepInterface, WizardStepValueI
|
|
|
36
36
|
|
|
37
37
|
constructor(private readonly context: LocalizationContext) {
|
|
38
38
|
this.task = new Task(this.context.wizard, {
|
|
39
|
-
task: async ([recordType, recordUid]
|
|
39
|
+
task: async ([recordType, recordUid]): Promise<LocalizationLanguageRecord[]> => {
|
|
40
40
|
const response = await new AjaxRequest(TYPO3.settings.ajaxUrls.wizard_localization_get_targets).withQueryArguments({
|
|
41
41
|
recordType: recordType,
|
|
42
42
|
recordUid: recordUid,
|
|
@@ -51,7 +51,7 @@ export class TargetLanguageStep implements WizardStepInterface, WizardStepValueI
|
|
|
51
51
|
|
|
52
52
|
return targetLanguages;
|
|
53
53
|
},
|
|
54
|
-
args: () => [this.context.recordType, this.context.recordUid],
|
|
54
|
+
args: () => [this.context.recordType, this.context.recordUid] as const,
|
|
55
55
|
autoRun: false
|
|
56
56
|
});
|
|
57
57
|
}
|
|
@@ -120,7 +120,7 @@ export class TargetLanguageStep implements WizardStepInterface, WizardStepValueI
|
|
|
120
120
|
<h2 class="h4">${localizationWizardLabels.get('step.target_language.headline')}</h2>
|
|
121
121
|
<p>${localizationWizardLabels.get('step.target_language.description')}</p>
|
|
122
122
|
<div class="form-check-card-container">
|
|
123
|
-
${languages.map((language
|
|
123
|
+
${languages.map((language) => html`
|
|
124
124
|
<div class="form-check form-check-type-card">
|
|
125
125
|
<input
|
|
126
126
|
class="form-check-input"
|
|
@@ -171,7 +171,7 @@ export class TargetLanguageStep implements WizardStepInterface, WizardStepValueI
|
|
|
171
171
|
return [];
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
const selectedLanguage = this.task.value.find((lang
|
|
174
|
+
const selectedLanguage = this.task.value.find((lang) => lang.uid === selectedTargetLanguage);
|
|
175
175
|
if (!selectedLanguage) {
|
|
176
176
|
return [];
|
|
177
177
|
}
|
package/backend/login.ts
CHANGED
|
@@ -117,7 +117,7 @@ class BackendLogin {
|
|
|
117
117
|
const result = await response.resolve('application/json') as PreflightResponse;
|
|
118
118
|
if (result.capabilities.referrer !== true) {
|
|
119
119
|
document.querySelectorAll(this.options.errorNoReferrer)
|
|
120
|
-
.forEach((element
|
|
120
|
+
.forEach((element): void => element.classList.remove('hidden'));
|
|
121
121
|
}
|
|
122
122
|
});
|
|
123
123
|
}
|
|
@@ -186,7 +186,7 @@ class BackendLogin {
|
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
(document.querySelectorAll('.t3js-clearable') as NodeListOf<HTMLInputElement>).forEach(
|
|
189
|
-
(clearableField
|
|
189
|
+
(clearableField) => clearableField.clearable(),
|
|
190
190
|
);
|
|
191
191
|
|
|
192
192
|
const passwordField: HTMLInputElement = document.querySelector(this.options.passwordField);
|
package/backend/module/iframe.ts
CHANGED
|
@@ -122,4 +122,14 @@ declare global {
|
|
|
122
122
|
interface HTMLElementTagNameMap {
|
|
123
123
|
'typo3-iframe-module': IframeModuleElement;
|
|
124
124
|
}
|
|
125
|
+
|
|
126
|
+
interface HTMLElementEventMap {
|
|
127
|
+
'typo3-iframe-load': CustomEvent<ModuleState>;
|
|
128
|
+
'typo3-iframe-loaded': CustomEvent<ModuleState>;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
interface DocumentEventMap {
|
|
132
|
+
'typo3-iframe-load': CustomEvent<ModuleState>;
|
|
133
|
+
'typo3-iframe-loaded': CustomEvent<ModuleState>;
|
|
134
|
+
}
|
|
125
135
|
}
|
package/backend/module/router.ts
CHANGED
|
@@ -266,4 +266,14 @@ declare global {
|
|
|
266
266
|
interface HTMLElementTagNameMap {
|
|
267
267
|
'typo3-backend-module-router': ModuleRouter;
|
|
268
268
|
}
|
|
269
|
+
|
|
270
|
+
interface HTMLElementEventMap {
|
|
271
|
+
'typo3-module-load': CustomEvent<ModuleState>;
|
|
272
|
+
'typo3-module-loaded': CustomEvent<ModuleState>;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
interface DocumentEventMap {
|
|
276
|
+
'typo3-module-load': CustomEvent<ModuleState>;
|
|
277
|
+
'typo3-module-loaded': CustomEvent<ModuleState>;
|
|
278
|
+
}
|
|
269
279
|
}
|
package/backend/module-menu.ts
CHANGED
|
@@ -160,7 +160,7 @@ class ModuleMenu {
|
|
|
160
160
|
|
|
161
161
|
private static highlightModule(identifier: string): void {
|
|
162
162
|
const menu = document.querySelector(ModuleMenuSelector.menu);
|
|
163
|
-
menu.querySelectorAll(ModuleMenuSelector.item).forEach((element
|
|
163
|
+
menu.querySelectorAll(ModuleMenuSelector.item).forEach((element) => {
|
|
164
164
|
element.classList.remove('modulemenu-action-active');
|
|
165
165
|
element.removeAttribute('aria-current');
|
|
166
166
|
});
|
|
@@ -171,8 +171,8 @@ class ModuleMenu {
|
|
|
171
171
|
|
|
172
172
|
private static highlightModuleMenuItem(module: Module, current: boolean = true): void {
|
|
173
173
|
const menu = document.querySelector(ModuleMenuSelector.menu);
|
|
174
|
-
const menuElements = menu.querySelectorAll(ModuleMenuSelector.item + selector`[data-modulemenu-identifier="${module.name}"]`);
|
|
175
|
-
menuElements.forEach((element
|
|
174
|
+
const menuElements = menu.querySelectorAll<HTMLElement>(ModuleMenuSelector.item + selector`[data-modulemenu-identifier="${module.name}"]`);
|
|
175
|
+
menuElements.forEach((element) => {
|
|
176
176
|
element.classList.add('modulemenu-action-active');
|
|
177
177
|
if (current) {
|
|
178
178
|
element.setAttribute('aria-current', 'location');
|
|
@@ -33,7 +33,7 @@ export class MultiRecordSelectionAction {
|
|
|
33
33
|
{
|
|
34
34
|
// Evaluate all checked records and if valid, add their uid to the list
|
|
35
35
|
const entityIdentifiers: Array<string> = [];
|
|
36
|
-
eventDetails.checkboxes.forEach((checkbox
|
|
36
|
+
eventDetails.checkboxes.forEach((checkbox): void => {
|
|
37
37
|
const checkboxContainer: HTMLElement = checkbox.closest(MultiRecordSelectionSelectors.elementSelector);
|
|
38
38
|
if (checkboxContainer !== null && checkboxContainer.dataset[eventDetails.configuration.idField]) {
|
|
39
39
|
entityIdentifiers.push(checkboxContainer.dataset[eventDetails.configuration.idField]);
|
|
@@ -85,7 +85,7 @@ class MultiRecordSelectionDeleteAction {
|
|
|
85
85
|
try {
|
|
86
86
|
const result = await AjaxDataHandler.process({
|
|
87
87
|
cmd: {
|
|
88
|
-
[tableName]: Object.fromEntries(entityIdentifiers.map((identifier
|
|
88
|
+
[tableName]: Object.fromEntries(entityIdentifiers.map((identifier): [string, DatahandlerCommand] => [
|
|
89
89
|
identifier, { delete: 1 }
|
|
90
90
|
]))
|
|
91
91
|
}
|