typo3-typescript-sources 14.3.9 → 14.3.10
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/.last-synced-tag +1 -1
- package/README.md +1 -1
- package/backend/bookmark/bookmark-manager.ts +2 -1
- package/backend/bookmark/bookmark-store.ts +8 -12
- package/backend/clipboard-panel.ts +9 -3
- package/backend/context-menu-actions.ts +14 -12
- package/backend/context-menu.ts +2 -1
- package/backend/contextual-record-edit.ts +2 -1
- package/backend/date-time-picker.ts +2 -1
- package/backend/drag-uploader.ts +2 -1
- package/backend/element/contextual-record-edit-trigger.ts +7 -6
- package/backend/element/datetime-element.ts +2 -1
- package/backend/element/editable-page-title.ts +2 -1
- package/backend/element/pseudo-button.ts +29 -5
- package/backend/element/qrcode-modal-button.ts +2 -2
- package/backend/element/sidebar-toggle-element.ts +1 -15
- package/backend/element-browser.ts +4 -3
- package/backend/event/event-dispatcher.ts +4 -2
- package/backend/form-engine/element/extra/char-counter.ts +1 -1
- package/backend/form-engine.ts +4 -3
- package/backend/hotkeys.ts +2 -1
- package/backend/image-manipulation.ts +2 -1
- package/backend/info-window.ts +4 -3
- package/backend/layout-module/drag-drop.ts +2 -1
- package/backend/live-search/live-search-configurator.ts +4 -3
- package/backend/live-search/live-search-shortcut.ts +2 -1
- package/backend/live-search/live-search.ts +4 -3
- package/backend/live-search/result-types/default-result-type.ts +2 -1
- package/backend/localization/label-provider.ts +2 -1
- package/backend/login-refresh.ts +4 -24
- package/backend/login.ts +3 -2
- package/backend/modal.ts +9 -15
- package/backend/module-menu.ts +4 -3
- package/backend/multi-record-selection-edit-action.ts +3 -2
- package/backend/new-record-wizard.ts +2 -1
- package/backend/notification.ts +3 -19
- package/backend/recordlist.ts +6 -4
- package/backend/security/element/sudo-mode.ts +6 -7
- package/backend/settings/type/page.ts +3 -2
- package/backend/severity.ts +2 -22
- package/backend/storage/module-state-storage.ts +3 -1
- package/backend/storage/persistent.ts +15 -3
- package/backend/switch-user.ts +3 -2
- package/backend/tests/element/pseudo-button-test.ts +95 -0
- package/backend/tests/notification-test.ts +1 -1
- package/backend/tree/file-storage-browser.ts +5 -3
- package/backend/tree/file-storage-tree-container.ts +8 -6
- package/backend/tree/page-browser.ts +2 -1
- package/backend/tree/page-position-select.ts +2 -1
- package/backend/tree/page-tree-element.ts +5 -4
- package/backend/tree/tree.ts +2 -1
- package/backend/user-settings-manager.ts +2 -1
- package/backend/utility/drag-drop-utility.ts +2 -1
- package/backend/utility/top-level-module-import.ts +3 -1
- package/backend/viewport/content-container.ts +2 -1
- package/backend/viewport/content-navigation-toggle.ts +3 -10
- package/backend/viewport.ts +5 -4
- package/backend/window-manager.ts +5 -4
- package/backend/wizard/finisher/noop-finisher.ts +3 -2
- package/backend/wizard/finisher/redirect-finisher.ts +4 -3
- package/backend/wizard/finisher/reload-finisher.ts +3 -2
- package/backend/wizard/move-page.ts +2 -1
- package/core/java-script-item-processor.ts +3 -1
- package/core/lit-helper.ts +5 -2
- package/core/tests/utility/top-window-test.ts +121 -0
- package/core/utility/top-window.ts +99 -0
- package/dashboard/dashboard.ts +2 -1
- package/extensionmanager/dependency-check.ts +2 -1
- package/extensionmanager/extension-toggle-button.ts +2 -1
- package/extensionmanager/repository.ts +2 -1
- package/filelist/context-menu-actions.ts +20 -19
- package/filelist/file-delete.ts +4 -3
- package/filelist/file-list-dragdrop.ts +3 -2
- package/filelist/file-list-rename-handler.ts +2 -1
- package/filelist/file-list-replace-handler.ts +2 -1
- package/filelist/file-list-transfer-handler.ts +5 -4
- package/filelist/file-list.ts +7 -6
- package/impexp/context-menu-actions.ts +5 -3
- package/install/installer.ts +2 -1
- package/install/module/abstract-interactable-module.ts +2 -2
- package/install/module/maintenance/language-packs.ts +2 -1
- package/install/module/settings/extension-configuration.ts +3 -4
- package/install/renderable/flash-message.ts +2 -2
- package/install/renderable/info-box.ts +2 -2
- package/opendocs/open-document-store.ts +5 -4
- package/package.json +2 -2
- package/recycler/recycler.ts +2 -1
- package/redirects/event-handler.ts +2 -1
- package/scheduler/scheduler-add-group.ts +2 -1
- package/workspaces/backend.ts +8 -6
- package/workspaces/preview.ts +3 -2
- package/workspaces/workspace-state.ts +5 -4
package/.last-synced-tag
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
v14.3.
|
|
1
|
+
v14.3.10
|
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ npm install github:maikschneider/typo3-typescript-sources#main
|
|
|
23
23
|
|
|
24
24
|
- **Original Repository:** [TYPO3/typo3](https://github.com/TYPO3/typo3)
|
|
25
25
|
- **Source Path:** `Build/Sources/TypeScript/`
|
|
26
|
-
- **Current TYPO3 Version:** `v14.3.
|
|
26
|
+
- **Current TYPO3 Version:** `v14.3.10`
|
|
27
27
|
|
|
28
28
|
## 🌿 Branches
|
|
29
29
|
|
|
@@ -21,6 +21,7 @@ import Modal from '../modal';
|
|
|
21
21
|
import Notification from '../notification';
|
|
22
22
|
import { SeverityEnum } from '../enum/severity';
|
|
23
23
|
import { PseudoButtonLitElement } from '@typo3/backend/element/pseudo-button';
|
|
24
|
+
import { topDocument } from '@typo3/core/utility/top-window';
|
|
24
25
|
import '@typo3/backend/element/spinner-element';
|
|
25
26
|
import '@typo3/backend/element/icon-element';
|
|
26
27
|
import labels from '~labels/core.bookmarks';
|
|
@@ -1208,7 +1209,7 @@ export class BookmarkManagerButtonElement extends PseudoButtonLitElement {
|
|
|
1208
1209
|
|
|
1209
1210
|
protected override buttonActivated(): void {
|
|
1210
1211
|
// Create element in top frame to avoid adoptedStyleSheets cross-document issues
|
|
1211
|
-
const targetDocument =
|
|
1212
|
+
const targetDocument = topDocument;
|
|
1212
1213
|
const managerElement = targetDocument.createElement('typo3-backend-bookmark-manager-content') as BookmarkManagerContentElement;
|
|
1213
1214
|
if (this.editId !== undefined) {
|
|
1214
1215
|
managerElement.editId = this.editId;
|
|
@@ -20,6 +20,7 @@ import Notification from '../notification';
|
|
|
20
20
|
import { SeverityEnum } from '../enum/severity';
|
|
21
21
|
import { BroadcastMessage, type BroadcastEvent } from '@typo3/backend/broadcast-message';
|
|
22
22
|
import BroadcastService from '@typo3/backend/broadcast-service';
|
|
23
|
+
import { topWindow } from '@typo3/core/utility/top-window';
|
|
23
24
|
|
|
24
25
|
export const BookmarkStoreChangedEvent = 'typo3:bookmark-store:changed';
|
|
25
26
|
|
|
@@ -683,19 +684,14 @@ class BookmarkStore {
|
|
|
683
684
|
* Returns singleton instance from top frame, creating it if needed.
|
|
684
685
|
*/
|
|
685
686
|
function getOrCreateInstance(): BookmarkStore {
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
top.TYPO3.BookmarkStore = instance;
|
|
693
|
-
}
|
|
694
|
-
return instance;
|
|
695
|
-
} catch {
|
|
696
|
-
// Cross-origin access denied, create local instance
|
|
697
|
-
return new BookmarkStore();
|
|
687
|
+
if (topWindow.TYPO3?.BookmarkStore) {
|
|
688
|
+
return topWindow.TYPO3.BookmarkStore;
|
|
689
|
+
}
|
|
690
|
+
const instance = new BookmarkStore();
|
|
691
|
+
if (topWindow.TYPO3) {
|
|
692
|
+
topWindow.TYPO3.BookmarkStore = instance;
|
|
698
693
|
}
|
|
694
|
+
return instance;
|
|
699
695
|
}
|
|
700
696
|
|
|
701
697
|
export default getOrCreateInstance();
|
|
@@ -21,6 +21,7 @@ import type { AjaxResponse } from '@typo3/core/ajax/ajax-response';
|
|
|
21
21
|
import Notification from '@typo3/backend/notification';
|
|
22
22
|
import '@typo3/backend/element/spinner-element';
|
|
23
23
|
import '@typo3/backend/element/icon-element';
|
|
24
|
+
import { topWindow } from '@typo3/core/utility/top-window';
|
|
24
25
|
|
|
25
26
|
enum CopyMode {
|
|
26
27
|
cut = 'cut',
|
|
@@ -60,11 +61,12 @@ interface DispatchArgs {
|
|
|
60
61
|
* Module: @typo3/backend/clipboard-panel
|
|
61
62
|
*
|
|
62
63
|
* @example
|
|
63
|
-
* <typo3-backend-clipboard-panel return-url="/typo3/module" table="_FILE"></typo3-backend-clipboard-panel>
|
|
64
|
+
* <typo3-backend-clipboard-panel return-url="/typo3/module" module-url="/typo3/clipboard/process" table="_FILE"></typo3-backend-clipboard-panel>
|
|
64
65
|
*/
|
|
65
66
|
@customElement('typo3-backend-clipboard-panel')
|
|
66
67
|
export class ClipboardPanel extends LitElement {
|
|
67
68
|
@property({ type: String, attribute: 'return-url' }) returnUrl: string = '';
|
|
69
|
+
@property({ type: String, attribute: 'module-url' }) moduleUrl: string = '';
|
|
68
70
|
@property({ type: String }) table: string = '';
|
|
69
71
|
|
|
70
72
|
private static renderLoader(): TemplateResult {
|
|
@@ -89,8 +91,12 @@ export class ClipboardPanel extends LitElement {
|
|
|
89
91
|
`;
|
|
90
92
|
}
|
|
91
93
|
|
|
94
|
+
private getModuleUrl(): string {
|
|
95
|
+
return this.moduleUrl || topWindow.TYPO3.settings.Clipboard.moduleUrl;
|
|
96
|
+
}
|
|
97
|
+
|
|
92
98
|
private renderPanel(): Promise<TemplateResult> {
|
|
93
|
-
return (new AjaxRequest(
|
|
99
|
+
return (new AjaxRequest(this.getModuleUrl()))
|
|
94
100
|
.withQueryArguments({ action: 'getClipboardData' })
|
|
95
101
|
.post({ table: this.table })
|
|
96
102
|
.then(async (response: AjaxResponse): Promise<TemplateResult> => {
|
|
@@ -202,7 +208,7 @@ export class ClipboardPanel extends LitElement {
|
|
|
202
208
|
private updateClipboard(event: PointerEvent, payload: object): void {
|
|
203
209
|
event.preventDefault();
|
|
204
210
|
const target: HTMLElement = event.currentTarget as HTMLElement;
|
|
205
|
-
(new AjaxRequest(
|
|
211
|
+
(new AjaxRequest(this.getModuleUrl()))
|
|
206
212
|
.post(payload)
|
|
207
213
|
.then(async (response: AjaxResponse): Promise<void> => {
|
|
208
214
|
const resolvedBody = await response.resolve();
|
|
@@ -23,6 +23,7 @@ import Viewport from './viewport';
|
|
|
23
23
|
import '@typo3/backend/new-record-wizard';
|
|
24
24
|
import Utility from '@typo3/backend/utility';
|
|
25
25
|
import { topLevelModuleImport } from '@typo3/backend/utility/top-level-module-import';
|
|
26
|
+
import { topWindow, topDocument } from '@typo3/core/utility/top-window';
|
|
26
27
|
import { html } from 'lit';
|
|
27
28
|
import coreCommonLabels from '~labels/core.common';
|
|
28
29
|
import cacheLabels from '~labels/core.cache';
|
|
@@ -38,7 +39,8 @@ class ContextMenuActions {
|
|
|
38
39
|
* @returns {string}
|
|
39
40
|
*/
|
|
40
41
|
public static getReturnUrl(): string {
|
|
41
|
-
|
|
42
|
+
const location = topWindow.list_frame.document.location;
|
|
43
|
+
return encodeURIComponent(location.pathname + location.search);
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
public static editRecord(table: string, uid: number, dataset: DOMStringMap): void {
|
|
@@ -51,10 +53,10 @@ class ContextMenuActions {
|
|
|
51
53
|
}
|
|
52
54
|
|
|
53
55
|
Viewport.ContentContainer.setUrl(
|
|
54
|
-
|
|
56
|
+
topWindow.TYPO3.settings.FormEngine.moduleUrl
|
|
55
57
|
+ '&edit[' + table + '][' + uid + ']=edit'
|
|
56
58
|
+ overrideVals
|
|
57
|
-
+ '&module=' + encodeURIComponent(
|
|
59
|
+
+ '&module=' + encodeURIComponent(topWindow.TYPO3.ModuleMenu.App.getCurrentModule())
|
|
58
60
|
+ '&returnUrl=' + ContextMenuActions.getReturnUrl(),
|
|
59
61
|
);
|
|
60
62
|
}
|
|
@@ -112,7 +114,7 @@ class ContextMenuActions {
|
|
|
112
114
|
pageId: uid
|
|
113
115
|
},
|
|
114
116
|
});
|
|
115
|
-
|
|
117
|
+
topDocument.dispatchEvent(event);
|
|
116
118
|
}
|
|
117
119
|
}
|
|
118
120
|
|
|
@@ -152,13 +154,13 @@ class ContextMenuActions {
|
|
|
152
154
|
}
|
|
153
155
|
|
|
154
156
|
Viewport.ContentContainer.setUrl(
|
|
155
|
-
|
|
157
|
+
topWindow.TYPO3.settings.FormEngine.moduleUrl + '&edit[' + table + '][' + (table !== 'pages' ? '-' : '') + uid + ']=new&returnUrl=' + ContextMenuActions.getReturnUrl(),
|
|
156
158
|
);
|
|
157
159
|
}
|
|
158
160
|
|
|
159
161
|
public static openHistoryPopUp(table: string, uid: number): void {
|
|
160
162
|
Viewport.ContentContainer.setUrl(
|
|
161
|
-
|
|
163
|
+
topWindow.TYPO3.settings.RecordHistory.moduleUrl + '&element=' + table + ':' + uid + '&returnUrl=' + ContextMenuActions.getReturnUrl(),
|
|
162
164
|
);
|
|
163
165
|
}
|
|
164
166
|
|
|
@@ -198,7 +200,7 @@ class ContextMenuActions {
|
|
|
198
200
|
public static disableRecord(table: string, uid: number, dataset: DOMStringMap): void {
|
|
199
201
|
const disableFieldName = dataset.disableField || 'hidden';
|
|
200
202
|
Viewport.ContentContainer.setUrl(
|
|
201
|
-
|
|
203
|
+
topWindow.TYPO3.settings.RecordCommit.moduleUrl
|
|
202
204
|
+ '&data[' + table + '][' + uid + '][' + disableFieldName + ']=1'
|
|
203
205
|
+ '&redirect=' + ContextMenuActions.getReturnUrl(),
|
|
204
206
|
);
|
|
@@ -207,7 +209,7 @@ class ContextMenuActions {
|
|
|
207
209
|
public static enableRecord(table: string, uid: number, dataset: DOMStringMap): void {
|
|
208
210
|
const disableFieldName = dataset.disableField || 'hidden';
|
|
209
211
|
Viewport.ContentContainer.setUrl(
|
|
210
|
-
|
|
212
|
+
topWindow.TYPO3.settings.RecordCommit.moduleUrl
|
|
211
213
|
+ '&data[' + table + '][' + uid + '][' + disableFieldName + ']=0'
|
|
212
214
|
+ '&redirect=' + ContextMenuActions.getReturnUrl(),
|
|
213
215
|
);
|
|
@@ -215,7 +217,7 @@ class ContextMenuActions {
|
|
|
215
217
|
|
|
216
218
|
public static showInMenus(table: string, uid: number): void {
|
|
217
219
|
Viewport.ContentContainer.setUrl(
|
|
218
|
-
|
|
220
|
+
topWindow.TYPO3.settings.RecordCommit.moduleUrl
|
|
219
221
|
+ '&data[' + table + '][' + uid + '][nav_hide]=0'
|
|
220
222
|
+ '&redirect=' + ContextMenuActions.getReturnUrl(),
|
|
221
223
|
);
|
|
@@ -223,7 +225,7 @@ class ContextMenuActions {
|
|
|
223
225
|
|
|
224
226
|
public static hideInMenus(table: string, uid: number): void {
|
|
225
227
|
Viewport.ContentContainer.setUrl(
|
|
226
|
-
|
|
228
|
+
topWindow.TYPO3.settings.RecordCommit.moduleUrl
|
|
227
229
|
+ '&data[' + table + '][' + uid + '][nav_hide]=1'
|
|
228
230
|
+ '&redirect=' + ContextMenuActions.getReturnUrl(),
|
|
229
231
|
);
|
|
@@ -350,7 +352,7 @@ class ContextMenuActions {
|
|
|
350
352
|
+ '&redirect=' + ContextMenuActions.getReturnUrl();
|
|
351
353
|
|
|
352
354
|
Viewport.ContentContainer.setUrl(
|
|
353
|
-
|
|
355
|
+
topWindow.TYPO3.settings.RecordCommit.moduleUrl + url,
|
|
354
356
|
);
|
|
355
357
|
};
|
|
356
358
|
if (!dataset.title) {
|
|
@@ -384,7 +386,7 @@ class ContextMenuActions {
|
|
|
384
386
|
}
|
|
385
387
|
|
|
386
388
|
private static refreshPageTree(): void {
|
|
387
|
-
|
|
389
|
+
topDocument.dispatchEvent(new CustomEvent('typo3:pagetree:refresh'));
|
|
388
390
|
}
|
|
389
391
|
}
|
|
390
392
|
|
package/backend/context-menu.ts
CHANGED
|
@@ -18,6 +18,7 @@ import '@typo3/backend/element/spinner-element';
|
|
|
18
18
|
import { customElement, queryAll, state } from 'lit/decorators.js';
|
|
19
19
|
import { html, LitElement, nothing, type TemplateResult } from 'lit';
|
|
20
20
|
import { delay } from '@typo3/core/lit-helper';
|
|
21
|
+
import { topDocument } from '@typo3/core/utility/top-window';
|
|
21
22
|
import { styleMap } from 'lit/directives/style-map.js';
|
|
22
23
|
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
|
23
24
|
import { Task, initialState } from '@lit/task';
|
|
@@ -99,7 +100,7 @@ class ContextMenu {
|
|
|
99
100
|
bubbles: true,
|
|
100
101
|
composed: true
|
|
101
102
|
});
|
|
102
|
-
|
|
103
|
+
topDocument.dispatchEvent(contextMenuEvent);
|
|
103
104
|
}
|
|
104
105
|
|
|
105
106
|
private handleTriggerEvent(event: PointerEvent): void {
|
|
@@ -15,6 +15,7 @@ import FormEngine from '@typo3/backend/form-engine';
|
|
|
15
15
|
import Modal from '@typo3/backend/modal';
|
|
16
16
|
import Severity from '@typo3/backend/severity';
|
|
17
17
|
import DocumentService from '@typo3/core/document-service';
|
|
18
|
+
import { topWindow } from '@typo3/core/utility/top-window';
|
|
18
19
|
import '@typo3/backend/element/icon-element';
|
|
19
20
|
import labels from '~labels/backend.alt_doc';
|
|
20
21
|
|
|
@@ -78,7 +79,7 @@ class ContextualRecordEdit {
|
|
|
78
79
|
document.querySelectorAll('.has-change').forEach((el) => el.classList.remove('has-change'));
|
|
79
80
|
// Navigate the content frame directly (same-origin access) — using
|
|
80
81
|
// postMessage for this failed silently in Firefox.
|
|
81
|
-
|
|
82
|
+
topWindow.TYPO3?.Backend?.ContentContainer?.setUrl(this.fullscreenButton.href);
|
|
82
83
|
// Tell the parent to close the modal
|
|
83
84
|
window.parent.postMessage(
|
|
84
85
|
{ actionName: 'typo3:editform:navigate' },
|
|
@@ -21,6 +21,7 @@ import type { PostValidationEvent } from '@typo3/backend/form-engine-validation'
|
|
|
21
21
|
import type { DateConfiguration } from '@typo3/backend/type/date-configuration';
|
|
22
22
|
import '@typo3/backend/input/clearable';
|
|
23
23
|
import coreLabels from '~labels/core.core';
|
|
24
|
+
import { openerTopWindow, topWindow } from '@typo3/core/utility/top-window';
|
|
24
25
|
|
|
25
26
|
const ISO8601_LOCALTIME = 'ISO8601_LOCALTIME';
|
|
26
27
|
|
|
@@ -33,7 +34,7 @@ interface FlatpickrInputElement extends HTMLInputElement {
|
|
|
33
34
|
* contains all logic for the date time picker used in FormEngine, EXT:belog and EXT:scheduler
|
|
34
35
|
*/
|
|
35
36
|
class DateTimePicker {
|
|
36
|
-
private readonly format: DateConfiguration = (
|
|
37
|
+
private readonly format: DateConfiguration = (openerTopWindow() ?? topWindow).TYPO3.settings.DateConfiguration;
|
|
37
38
|
|
|
38
39
|
/**
|
|
39
40
|
* initialize date fields to add a datepicker to each field
|
package/backend/drag-uploader.ts
CHANGED
|
@@ -27,6 +27,7 @@ import { KeyTypesEnum } from '@typo3/backend/enum/key-types';
|
|
|
27
27
|
import '@typo3/backend/element/progress-bar-element';
|
|
28
28
|
import type { ProgressBarElement } from '@typo3/backend/element/progress-bar-element';
|
|
29
29
|
import { topLevelModuleImport } from '@typo3/backend/utility/top-level-module-import';
|
|
30
|
+
import { topWindow } from '@typo3/core/utility/top-window';
|
|
30
31
|
import { FormatUtility } from '@typo3/backend/utility/format-utility';
|
|
31
32
|
import coreLabels from '~labels/core.core';
|
|
32
33
|
import commonLabels from '~labels/core.common';
|
|
@@ -490,7 +491,7 @@ export default class DragUploader {
|
|
|
490
491
|
{
|
|
491
492
|
label: coreLabels.get('file_upload.reload.filelist.actions.reload'),
|
|
492
493
|
action: new ImmediateAction((): void => {
|
|
493
|
-
|
|
494
|
+
topWindow.list_frame.document.location.href = this.reloadUrl;
|
|
494
495
|
})
|
|
495
496
|
}
|
|
496
497
|
]
|
|
@@ -17,6 +17,7 @@ import Modal, { Types, Sizes, Positions, type ModalElement } from '@typo3/backen
|
|
|
17
17
|
import Notification from '@typo3/backend/notification';
|
|
18
18
|
import Persistent from '@typo3/backend/storage/persistent';
|
|
19
19
|
import labels from '~labels/backend.alt_doc';
|
|
20
|
+
import { topWindow, topDocument } from '@typo3/core/utility/top-window';
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* Module: @typo3/backend/element/contextual-record-edit-trigger
|
|
@@ -49,8 +50,8 @@ export class ContextualRecordEditTriggerElement extends PseudoButtonLitElement {
|
|
|
49
50
|
|
|
50
51
|
protected override async buttonActivated(): Promise<void> {
|
|
51
52
|
if (Persistent.isset('contextualRecordEdit') && Persistent.get('contextualRecordEdit') == 0) {
|
|
52
|
-
if (
|
|
53
|
-
|
|
53
|
+
if (topWindow.TYPO3?.Backend?.ContentContainer) {
|
|
54
|
+
topWindow.TYPO3.Backend.ContentContainer.setUrl(this.editUrl);
|
|
54
55
|
}
|
|
55
56
|
return;
|
|
56
57
|
}
|
|
@@ -67,7 +68,7 @@ export class ContextualRecordEditTriggerElement extends PseudoButtonLitElement {
|
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
private setupMessageHandling(modal: ModalElement): void {
|
|
70
|
-
const messageTarget =
|
|
71
|
+
const messageTarget = topWindow;
|
|
71
72
|
let savedRecordTitle = '';
|
|
72
73
|
let hasSaved = false;
|
|
73
74
|
let closeConfirmed = false;
|
|
@@ -105,9 +106,9 @@ export class ContextualRecordEditTriggerElement extends PseudoButtonLitElement {
|
|
|
105
106
|
modal.addEventListener('typo3-modal-hidden', () => {
|
|
106
107
|
messageTarget.removeEventListener('message', messageHandler);
|
|
107
108
|
if (hasSaved) {
|
|
108
|
-
|
|
109
|
-
if (
|
|
110
|
-
|
|
109
|
+
topDocument.dispatchEvent(new CustomEvent('typo3:pagetree:refresh'));
|
|
110
|
+
if (topWindow.TYPO3?.Backend?.ContentContainer) {
|
|
111
|
+
topWindow.TYPO3.Backend.ContentContainer.refresh();
|
|
111
112
|
}
|
|
112
113
|
Notification.success(
|
|
113
114
|
labels.get('notification.record_updated.title'),
|
|
@@ -15,6 +15,7 @@ import { html, LitElement, nothing, type TemplateResult, type PropertyValues } f
|
|
|
15
15
|
import { customElement, property, state } from 'lit/decorators.js';
|
|
16
16
|
import { DateTime, type DurationUnit, type DurationUnits } from 'luxon';
|
|
17
17
|
import type { DateConfiguration } from '@typo3/backend/type/date-configuration';
|
|
18
|
+
import { openerTopWindow, topWindow } from '@typo3/core/utility/top-window';
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* Display mode for the time element
|
|
@@ -267,7 +268,7 @@ export class DateTimeElement extends LitElement {
|
|
|
267
268
|
|
|
268
269
|
private getConfiguredDateFormats(): DateConfiguration | null {
|
|
269
270
|
try {
|
|
270
|
-
const root = (
|
|
271
|
+
const root = openerTopWindow() ?? topWindow;
|
|
271
272
|
return root.TYPO3.settings.DateConfiguration;
|
|
272
273
|
} catch {
|
|
273
274
|
return null;
|
|
@@ -17,6 +17,7 @@ import '@typo3/backend/element/icon-element';
|
|
|
17
17
|
import AjaxDataHandler from '../ajax-data-handler';
|
|
18
18
|
import commonLabels from '~labels/core.common';
|
|
19
19
|
import layoutLabels from '~labels/backend.layout';
|
|
20
|
+
import { topDocument } from '@typo3/core/utility/top-window';
|
|
20
21
|
|
|
21
22
|
@customElement('typo3-backend-editable-page-title')
|
|
22
23
|
export class EditablePageTitle extends LitElement {
|
|
@@ -251,7 +252,7 @@ export class EditablePageTitle extends LitElement {
|
|
|
251
252
|
|
|
252
253
|
AjaxDataHandler.process(parameters).then((): void => {
|
|
253
254
|
this.pageTitle = newPageTitle;
|
|
254
|
-
|
|
255
|
+
topDocument.dispatchEvent(new CustomEvent('typo3:pagetree:refresh'));
|
|
255
256
|
}).finally((): void => {
|
|
256
257
|
this.endEditing();
|
|
257
258
|
this._isSubmitting = false;
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import { property } from 'lit/decorators.js';
|
|
15
|
-
import { html, css, LitElement, type TemplateResult } from 'lit';
|
|
15
|
+
import { html, css, LitElement, type PropertyValues, type TemplateResult } from 'lit';
|
|
16
16
|
import { KeyTypesEnum } from '@typo3/backend/enum/key-types';
|
|
17
17
|
|
|
18
18
|
/**
|
|
@@ -20,18 +20,24 @@ import { KeyTypesEnum } from '@typo3/backend/enum/key-types';
|
|
|
20
20
|
*/
|
|
21
21
|
export abstract class PseudoButtonLitElement extends LitElement {
|
|
22
22
|
static override styles = [
|
|
23
|
-
css`:host { cursor: pointer; appearance: button; }
|
|
23
|
+
css`:host { cursor: pointer; appearance: button; }`,
|
|
24
|
+
css`:host([disabled]) { cursor: default; }`
|
|
24
25
|
];
|
|
25
26
|
|
|
26
27
|
// eslint-disable-next-line lit/no-native-attributes
|
|
27
28
|
@property({ type: String, reflect: true }) override role: string = 'button';
|
|
28
29
|
@property({ type: String, reflect: true }) override tabIndex: number = 0;
|
|
30
|
+
/** As a disabled <button>: not activated, not in the tab order, announced as disabled */
|
|
31
|
+
@property({ type: Boolean, reflect: true }) disabled: boolean = false;
|
|
32
|
+
|
|
33
|
+
/** Of the markup or the element, back once the button is enabled again */
|
|
34
|
+
private enabledTabIndex: number = 0;
|
|
29
35
|
|
|
30
36
|
public constructor() {
|
|
31
37
|
super();
|
|
32
38
|
this.addEventListener('click', (e: Event): void => {
|
|
33
39
|
e.preventDefault();
|
|
34
|
-
this.
|
|
40
|
+
this.activate(e);
|
|
35
41
|
});
|
|
36
42
|
this.addEventListener('keydown', (e: KeyboardEvent): void => {
|
|
37
43
|
if (e.key === KeyTypesEnum.SPACE) {
|
|
@@ -39,20 +45,38 @@ export abstract class PseudoButtonLitElement extends LitElement {
|
|
|
39
45
|
}
|
|
40
46
|
if (e.key === KeyTypesEnum.ENTER) {
|
|
41
47
|
e.preventDefault();
|
|
42
|
-
this.
|
|
48
|
+
this.activate(e);
|
|
43
49
|
}
|
|
44
50
|
});
|
|
45
51
|
this.addEventListener('keyup', (e: KeyboardEvent): void => {
|
|
46
52
|
if (e.key === KeyTypesEnum.SPACE) {
|
|
47
53
|
e.preventDefault();
|
|
48
|
-
this.
|
|
54
|
+
this.activate(e);
|
|
49
55
|
}
|
|
50
56
|
});
|
|
51
57
|
}
|
|
52
58
|
|
|
59
|
+
protected override willUpdate(changed: PropertyValues<this>): void {
|
|
60
|
+
super.willUpdate(changed);
|
|
61
|
+
// Only a change of the state: a button enabled from the start keeps its tab index
|
|
62
|
+
if (changed.has('disabled') && this.disabled !== Boolean(changed.get('disabled'))) {
|
|
63
|
+
if (this.disabled) {
|
|
64
|
+
this.enabledTabIndex = this.tabIndex;
|
|
65
|
+
}
|
|
66
|
+
this.ariaDisabled = this.disabled ? 'true' : null;
|
|
67
|
+
this.tabIndex = this.disabled ? -1 : this.enabledTabIndex;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
53
71
|
protected override render(): TemplateResult {
|
|
54
72
|
return html`<slot></slot>`;
|
|
55
73
|
}
|
|
56
74
|
|
|
75
|
+
private activate(e: Event): void {
|
|
76
|
+
if (!this.disabled) {
|
|
77
|
+
this.buttonActivated(e);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
57
81
|
protected abstract buttonActivated(e: Event): void | Promise<void>;
|
|
58
82
|
}
|
|
@@ -16,6 +16,7 @@ import { PseudoButtonLitElement } from '@typo3/backend/element/pseudo-button';
|
|
|
16
16
|
import Modal from '@typo3/backend/modal';
|
|
17
17
|
import { html } from 'lit';
|
|
18
18
|
import { topLevelModuleImport } from '@typo3/backend/utility/top-level-module-import';
|
|
19
|
+
import { topWindow } from '@typo3/core/utility/top-window';
|
|
19
20
|
import listLabels from '~labels/core.mod_web_list';
|
|
20
21
|
|
|
21
22
|
/**
|
|
@@ -36,8 +37,7 @@ export class QrCodeModalButton extends PseudoButtonLitElement {
|
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
protected async loadModuleFrameAgnostic(module: string): Promise<any> {
|
|
39
|
-
|
|
40
|
-
if (isInIframe) {
|
|
40
|
+
if (topWindow !== window) {
|
|
41
41
|
await topLevelModuleImport(module);
|
|
42
42
|
} else {
|
|
43
43
|
await import(module);
|
|
@@ -49,7 +49,6 @@ export class SidebarToggleElement extends PseudoButtonLitElement {
|
|
|
49
49
|
|
|
50
50
|
@property({ type: String, attribute: 'label-collapse' }) labelCollapse: string = 'Collapse sidebar';
|
|
51
51
|
@property({ type: String, attribute: 'label-expand' }) labelExpand: string = 'Expand sidebar';
|
|
52
|
-
@property({ type: Boolean, reflect: true }) disabled: boolean = false;
|
|
53
52
|
|
|
54
53
|
@state() private expanded: boolean = false;
|
|
55
54
|
|
|
@@ -67,7 +66,6 @@ export class SidebarToggleElement extends PseudoButtonLitElement {
|
|
|
67
66
|
|
|
68
67
|
protected override updated(): void {
|
|
69
68
|
this.updateLabels();
|
|
70
|
-
this.updateDisabledState();
|
|
71
69
|
}
|
|
72
70
|
|
|
73
71
|
protected override render(): TemplateResult {
|
|
@@ -77,9 +75,7 @@ export class SidebarToggleElement extends PseudoButtonLitElement {
|
|
|
77
75
|
}
|
|
78
76
|
|
|
79
77
|
protected override buttonActivated(): void {
|
|
80
|
-
|
|
81
|
-
ScaffoldState.toggleSidebar();
|
|
82
|
-
}
|
|
78
|
+
ScaffoldState.toggleSidebar();
|
|
83
79
|
}
|
|
84
80
|
|
|
85
81
|
private readonly handleSidebarToggle = (event: ScaffoldSidebarToggleEvent): void => {
|
|
@@ -91,16 +87,6 @@ export class SidebarToggleElement extends PseudoButtonLitElement {
|
|
|
91
87
|
this.title = label;
|
|
92
88
|
this.setAttribute('aria-label', label);
|
|
93
89
|
}
|
|
94
|
-
|
|
95
|
-
private updateDisabledState(): void {
|
|
96
|
-
if (this.disabled) {
|
|
97
|
-
this.setAttribute('aria-disabled', 'true');
|
|
98
|
-
this.tabIndex = -1;
|
|
99
|
-
} else {
|
|
100
|
-
this.removeAttribute('aria-disabled');
|
|
101
|
-
this.tabIndex = 0;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
90
|
}
|
|
105
91
|
|
|
106
92
|
declare global {
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import { MessageUtility } from '@typo3/backend/utility/message-utility';
|
|
15
15
|
import DocumentService from '@typo3/core/document-service';
|
|
16
16
|
import Modal from '@typo3/backend/modal';
|
|
17
|
+
import { topWindow } from '@typo3/core/utility/top-window';
|
|
17
18
|
|
|
18
19
|
interface RTESettings {
|
|
19
20
|
parameters: string;
|
|
@@ -79,7 +80,7 @@ class ElementBrowser {
|
|
|
79
80
|
const isInModalFrame = typeof window.frames !== 'undefined'
|
|
80
81
|
&& typeof window.frames.frameElement !== 'undefined'
|
|
81
82
|
&& window.frames.frameElement.classList.contains('t3js-modal-iframe');
|
|
82
|
-
const otherModalFrames = Array.from(
|
|
83
|
+
const otherModalFrames = Array.from(topWindow.frames || []).filter((item) => {
|
|
83
84
|
try {
|
|
84
85
|
return typeof item.frameElement !== 'undefined'
|
|
85
86
|
&& item.frameElement.classList.contains('t3js-modal-iframe')
|
|
@@ -185,9 +186,9 @@ class ElementBrowser {
|
|
|
185
186
|
|
|
186
187
|
private findEditFormWindow(): Window | null {
|
|
187
188
|
try {
|
|
188
|
-
for (let i = 0; i <
|
|
189
|
+
for (let i = 0; i < topWindow.frames.length; i++) {
|
|
189
190
|
try {
|
|
190
|
-
const frame =
|
|
191
|
+
const frame = topWindow.frames[i];
|
|
191
192
|
if (frame !== window && this.windowHasEditForm(frame)) {
|
|
192
193
|
return frame;
|
|
193
194
|
}
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
* The TYPO3 project - inspiring people to share!
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
+
import { topDocument } from '@typo3/core/utility/top-window';
|
|
15
|
+
|
|
14
16
|
/**
|
|
15
17
|
* Module: @typo3/backend/event/event-dispatcher
|
|
16
18
|
*/
|
|
@@ -19,8 +21,8 @@ export class EventDispatcher {
|
|
|
19
21
|
const event = new CustomEvent(name, { detail: detail });
|
|
20
22
|
if (!useTop) {
|
|
21
23
|
document.dispatchEvent(event);
|
|
22
|
-
} else
|
|
23
|
-
|
|
24
|
+
} else {
|
|
25
|
+
topDocument.dispatchEvent(event);
|
|
24
26
|
}
|
|
25
27
|
}
|
|
26
28
|
}
|
|
@@ -49,7 +49,7 @@ export class CharCounter extends LitElement {
|
|
|
49
49
|
|
|
50
50
|
protected override render(): TemplateResult {
|
|
51
51
|
return html`
|
|
52
|
-
<span class="form-hint form-hint--${this.determineCounterClass()}">
|
|
52
|
+
<span class="form-hint form-hint--${this.determineCounterClass()}" role="status" aria-live="polite" aria-atomic="true">
|
|
53
53
|
${labels.get('labels.remainingCharacters', { '0': this.remainingCharacters.toString(10) })}
|
|
54
54
|
</span>
|
|
55
55
|
`;
|
package/backend/form-engine.ts
CHANGED
|
@@ -39,6 +39,7 @@ import RegularEvent from '@typo3/core/event/regular-event';
|
|
|
39
39
|
import backendAltDocLabels from '~labels/backend.alt_doc';
|
|
40
40
|
import coreCoreLabels from '~labels/core.core';
|
|
41
41
|
import type { ElementBrowserMessage, ElementBrowserElementAddedMessage } from '@typo3/backend/element-browser';
|
|
42
|
+
import { topWindow } from '@typo3/core/utility/top-window';
|
|
42
43
|
|
|
43
44
|
export interface OnFieldChangeItem {
|
|
44
45
|
name: string;
|
|
@@ -531,12 +532,12 @@ export default (function() {
|
|
|
531
532
|
* Initialize events for all form engine relevant tasks.
|
|
532
533
|
*/
|
|
533
534
|
FormEngine.initializeEvents = function() {
|
|
534
|
-
if (
|
|
535
|
+
if (topWindow.TYPO3 && typeof topWindow.TYPO3.Backend !== 'undefined') {
|
|
535
536
|
// @todo: The consumer scope attachment is actually not needed
|
|
536
537
|
// in page wizard and context panel (which currently uses it own handling).
|
|
537
538
|
// This needs to be streamlined.
|
|
538
|
-
|
|
539
|
-
window.addEventListener('pagehide', () =>
|
|
539
|
+
topWindow.TYPO3.Backend.consumerScope.attach(FormEngine);
|
|
540
|
+
window.addEventListener('pagehide', () => topWindow.TYPO3.Backend.consumerScope.detach(FormEngine), { once: true });
|
|
540
541
|
}
|
|
541
542
|
|
|
542
543
|
FormEngine.formElement.addEventListener('submit', function(e: SubmitEvent) {
|
package/backend/hotkeys.ts
CHANGED
|
@@ -15,6 +15,7 @@ import HotkeyStorage, { type ScopedHotkeyMap, type Options, type HotkeySetup } f
|
|
|
15
15
|
import RegularEvent from '@typo3/core/event/regular-event';
|
|
16
16
|
import { HotkeyStruct } from '@typo3/backend/hotkeys/hotkey-struct';
|
|
17
17
|
import { HotkeyDispatchedEvent, HotkeyRequestedEvent } from '@typo3/backend/hotkeys/events';
|
|
18
|
+
import { topDocument } from '@typo3/core/utility/top-window';
|
|
18
19
|
|
|
19
20
|
export enum ModifierKeys {
|
|
20
21
|
META = 'meta',
|
|
@@ -101,7 +102,7 @@ class Hotkeys {
|
|
|
101
102
|
new RegularEvent('keydown', (e: KeyboardEvent): void => {
|
|
102
103
|
const hotkeyStruct = HotkeyStruct.fromEvent(e);
|
|
103
104
|
if (hotkeyStruct.hasAnyModifier()) {
|
|
104
|
-
|
|
105
|
+
topDocument.dispatchEvent(new HotkeyRequestedEvent(e));
|
|
105
106
|
}
|
|
106
107
|
}).bindTo(document);
|
|
107
108
|
|
|
@@ -23,6 +23,7 @@ import { default as Modal, type ModalElement } from './modal';
|
|
|
23
23
|
import '@typo3/backend/element/spinner-element';
|
|
24
24
|
import { renderNodes } from '@typo3/core/lit-helper';
|
|
25
25
|
import { topLevelModuleImport } from '@typo3/backend/utility/top-level-module-import';
|
|
26
|
+
import { topDocument } from '@typo3/core/utility/top-window';
|
|
26
27
|
import { Offset } from '@typo3/backend/offset';
|
|
27
28
|
import type { DraggableResizableEvent, PointerEventNames, DraggableResizableElement } from '@typo3/backend/element/draggable-resizable-element';
|
|
28
29
|
import type { EventInterface } from '@typo3/core/event/event-interface';
|
|
@@ -608,7 +609,7 @@ class ImageManipulation {
|
|
|
608
609
|
private initFocusArea(container: HTMLElement): DraggableResizableElement {
|
|
609
610
|
topLevelModuleImport('@typo3/backend/element/draggable-resizable-element.js');
|
|
610
611
|
|
|
611
|
-
const focusAreaEl =
|
|
612
|
+
const focusAreaEl = topDocument.createElement('typo3-backend-draggable-resizable');
|
|
612
613
|
// assign area declaration (as persisted in the database)
|
|
613
614
|
focusAreaEl.setAttribute('offset', JSON.stringify(this.convertAreaToOffset(this.currentCropVariant.focusArea, container)));
|
|
614
615
|
// use the same events as cropper.js does
|
package/backend/info-window.ts
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
import { SeverityEnum } from './enum/severity';
|
|
15
15
|
import Modal from './modal';
|
|
16
|
+
import { topWindow } from '@typo3/core/utility/top-window';
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* Module: @typo3/backend/info-window
|
|
@@ -29,7 +30,7 @@ class InfoWindow {
|
|
|
29
30
|
Modal.advanced({
|
|
30
31
|
type: Modal.types.iframe,
|
|
31
32
|
size: Modal.sizes.large,
|
|
32
|
-
content:
|
|
33
|
+
content: topWindow.TYPO3.settings.ShowItem.moduleUrl
|
|
33
34
|
+ '&table=' + encodeURIComponent(table)
|
|
34
35
|
+ '&uid=' + (typeof uid === 'number' ? uid : encodeURIComponent(uid)),
|
|
35
36
|
severity: SeverityEnum.notice,
|
|
@@ -37,8 +38,8 @@ class InfoWindow {
|
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
if (!
|
|
41
|
-
|
|
41
|
+
if (!topWindow.TYPO3.InfoWindow) {
|
|
42
|
+
topWindow.TYPO3.InfoWindow = InfoWindow;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
// expose as global object
|