typo3-typescript-sources 14.3.9 → 14.3.11
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/adminpanel/admin-panel.ts +2 -2
- package/backend/bookmark/bookmark-manager.ts +4 -3
- package/backend/bookmark/bookmark-store.ts +8 -12
- package/backend/clipboard-panel.ts +22 -10
- package/backend/code-editor/language/typoscript.ts +1 -1
- package/backend/column-selector-button.ts +2 -2
- package/backend/context-menu-actions.ts +36 -16
- package/backend/context-menu.ts +35 -3
- package/backend/contextual-record-edit.ts +115 -33
- package/backend/date-time-picker.ts +3 -2
- package/backend/drag-uploader.ts +51 -21
- package/backend/element/breadcrumb.ts +6 -6
- package/backend/element/combobox-element.ts +2 -2
- package/backend/element/contextual-record-edit-trigger.ts +100 -65
- 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/enum/viewport/scaffold-identifier.ts +1 -1
- package/backend/event/event-dispatcher.ts +4 -2
- package/backend/form-engine/container/flex-form-container-container.ts +1 -1
- package/backend/form-engine/container/flex-form-section-container.ts +3 -3
- package/backend/form-engine/container/inline-control-container.ts +29 -29
- package/backend/form-engine/element/abstract-sortable-select-items.ts +1 -1
- package/backend/form-engine/element/category-element.ts +5 -5
- package/backend/form-engine/element/extra/char-counter.ts +1 -1
- package/backend/form-engine/element/group-element.ts +1 -1
- package/backend/form-engine/element/select-tree-element.ts +4 -4
- package/backend/form-engine/element/select-tree.ts +1 -1
- package/backend/form-engine/element/slug-element.ts +9 -7
- package/backend/form-engine/element/suggest/result-container.ts +1 -1
- package/backend/form-engine/element/suggest/result-item.ts +1 -1
- package/backend/form-engine/element/table-permission-element.ts +4 -4
- package/backend/form-engine/field-control/add-record.ts +1 -1
- package/backend/form-engine/field-control/edit-popup.ts +2 -2
- package/backend/form-engine/field-control/insert-clipboard.ts +1 -1
- package/backend/form-engine/field-control/link-popup.ts +1 -1
- package/backend/form-engine/field-control/list-module.ts +1 -1
- package/backend/form-engine/field-control/password-generator.ts +4 -4
- package/backend/form-engine/field-control/reset-selection.ts +2 -2
- package/backend/form-engine/field-wizard/localization-state-selector.ts +2 -2
- package/backend/form-engine/field-wizard/value-picker.ts +1 -1
- package/backend/form-engine/field-wizard/value-slider.ts +2 -2
- package/backend/form-engine-review.ts +1 -1
- package/backend/form-engine-suggest.ts +2 -2
- package/backend/form-engine-validation.ts +55 -10
- package/backend/form-engine.ts +16 -14
- package/backend/global-event-handler.ts +1 -1
- package/backend/grid-editor.ts +83 -8
- package/backend/hotkeys.ts +2 -1
- package/backend/image-manipulation.ts +4 -3
- package/backend/info-window.ts +4 -3
- package/backend/layout-module/drag-drop.ts +17 -16
- package/backend/layout-module/page-layout.ts +7 -2
- package/backend/layout-module/paste.ts +3 -3
- package/backend/layout-module/toggle-hidden-element.ts +1 -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 +10 -9
- package/backend/live-search/result-types/default-result-type.ts +2 -1
- package/backend/localization/finisher/localization-submission-service.ts +1 -0
- package/backend/localization/label-provider.ts +2 -1
- package/backend/localization/localization-button.ts +3 -0
- package/backend/localization/localization-wizard.ts +3 -0
- package/backend/localization/steps/source-language-step.ts +1 -0
- package/backend/login/capslock-warning.ts +84 -0
- package/backend/login-refresh.ts +6 -26
- package/backend/login.ts +6 -4
- package/backend/mail-link-handler.ts +2 -2
- package/backend/modal.ts +36 -18
- package/backend/module-menu.ts +21 -11
- package/backend/module.ts +1 -1
- package/backend/multi-record-selection-edit-action.ts +3 -2
- package/backend/multi-record-selection.ts +3 -3
- package/backend/multi-step-wizard.ts +2 -2
- package/backend/new-record-wizard.ts +3 -2
- package/backend/notification.ts +4 -20
- package/backend/page-wizard/steps/form-engine-step.ts +2 -2
- package/backend/popover.ts +1 -1
- package/backend/recordlist.ts +13 -11
- package/backend/security/element/csp-reports.ts +2 -2
- package/backend/security/element/sudo-mode.ts +6 -7
- package/backend/settings/editor.ts +9 -9
- package/backend/settings/type/page.ts +5 -4
- package/backend/severity.ts +2 -22
- package/backend/sortable-table.ts +3 -3
- 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/tab.ts +3 -3
- package/backend/telephone-link-handler.ts +1 -1
- package/backend/tests/drag-uploader-test.ts +287 -0
- package/backend/tests/element/pseudo-button-test.ts +95 -0
- package/backend/tests/form-engine/element/select-tree-test.ts +1 -1
- package/backend/tests/form-engine-validation-test.ts +75 -0
- package/backend/tests/grid-editor-test.ts +29 -0
- package/backend/tests/login/capslock-warning-test.ts +78 -0
- package/backend/tests/modal-test.ts +73 -0
- package/backend/tests/notification-test.ts +16 -16
- package/backend/tests/tree/tree-test.ts +68 -0
- package/backend/tests/utility/drag-drop-utility-test.ts +82 -0
- package/backend/toolbar/system-information-menu.ts +2 -2
- package/backend/tree/file-storage-browser.ts +7 -5
- package/backend/tree/file-storage-tree-container.ts +8 -6
- package/backend/tree/page-browser.ts +4 -3
- package/backend/tree/page-position-select.ts +4 -3
- package/backend/tree/page-tree-element.ts +8 -6
- package/backend/tree/tree-module-state.ts +12 -0
- package/backend/tree/tree-toolbar.ts +1 -1
- package/backend/tree/tree.ts +26 -18
- package/backend/url-link-handler.ts +1 -1
- package/backend/user-pass-login.ts +0 -103
- package/backend/user-settings-manager.ts +2 -1
- package/backend/utility/collapse-state-search.ts +2 -2
- package/backend/utility/drag-drop-utility.ts +7 -10
- package/backend/utility/top-level-module-import.ts +3 -1
- package/backend/viewport/content-container.ts +3 -2
- package/backend/viewport/content-navigation-toggle.ts +5 -12
- package/backend/viewport/content-navigation.ts +3 -3
- package/backend/viewport/navigation-container.ts +2 -2
- 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-content-element.ts +7 -7
- package/backend/wizard/move-page.ts +5 -4
- package/backend/wizard/steps/finisher-step.ts +1 -1
- package/belog/backend-log.ts +2 -2
- package/beuser/permissions.ts +4 -4
- package/core/java-script-item-handler.ts +12 -2
- package/core/java-script-item-processor.ts +55 -7
- package/core/lit-helper.ts +5 -2
- package/core/tests/java-script-item-processor-test.ts +83 -0
- package/core/tests/utility/top-window-test.ts +121 -0
- package/core/utility/top-window.ts +99 -0
- package/dashboard/dashboard.ts +3 -7
- package/extensionmanager/dependency-check.ts +2 -1
- package/extensionmanager/extension-toggle-button.ts +2 -1
- package/extensionmanager/main.ts +1 -1
- package/extensionmanager/repository.ts +2 -1
- package/extensionmanager/update.ts +1 -1
- package/extensionmanager/upload-form.ts +1 -1
- package/filelist/browse-files.ts +2 -2
- package/filelist/browse-folders.ts +1 -1
- package/filelist/context-menu-actions.ts +20 -19
- package/filelist/file-delete.ts +4 -3
- package/filelist/file-list-actions.ts +1 -1
- package/filelist/file-list-dragdrop.ts +7 -6
- 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 +12 -11
- package/filelist/linkbrowser-file-handler.ts +1 -1
- package/filelist/rename-file.ts +3 -3
- package/filelist/resource-creation.ts +1 -1
- package/form/backend/form-editor/core.ts +1 -1
- package/form/backend/form-editor/inspector-component.ts +4 -4
- package/form/backend/form-editor/stage-component.ts +10 -11
- package/form/backend/form-editor/view-model.ts +1 -1
- package/impexp/context-menu-actions.ts +5 -3
- package/info/translation-status.ts +2 -2
- package/install/installer.ts +8 -7
- package/install/module/abstract-interactable-module.ts +2 -2
- package/install/module/environment/folder-structure.ts +1 -1
- package/install/module/maintenance/clear-tables.ts +1 -1
- package/install/module/maintenance/clear-typo3temp-files.ts +1 -1
- package/install/module/maintenance/database-analyzer.ts +2 -2
- package/install/module/maintenance/language-packs.ts +2 -1
- package/install/module/settings/extension-configuration.ts +3 -4
- package/install/module/settings/local-configuration.ts +8 -8
- package/install/module/upgrade/upgrade-docs.ts +1 -1
- package/install/module/upgrade/upgrade-wizards.ts +8 -8
- package/install/renderable/flash-message.ts +2 -2
- package/install/renderable/info-box.ts +2 -2
- package/install/router.ts +3 -3
- package/lowlevel/query-generator.ts +4 -4
- package/opendocs/open-document-store.ts +5 -4
- package/package.json +2 -2
- package/recycler/recycler.ts +19 -18
- package/redirects/event-handler.ts +66 -20
- package/redirects/short-url-generator.ts +2 -2
- package/redirects/tests/event-handler-test.ts +121 -0
- package/rte-ckeditor/ckeditor5.ts +2 -2
- package/rte-ckeditor/tests/ckeditor5-test.ts +1 -1
- package/scheduler/form-engine/element/timing-options-element.ts +2 -2
- package/scheduler/scheduler-add-group.ts +5 -4
- package/scheduler/scheduler-sortable-groups.ts +2 -2
- package/scheduler/scheduler.ts +1 -1
- package/styleguide/find-icons.ts +1 -1
- package/viewpage/main.ts +7 -7
- package/workspaces/backend.ts +33 -31
- package/workspaces/preview.ts +11 -10
- package/workspaces/workspace-state.ts +6 -5
package/.last-synced-tag
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
v14.3.
|
|
1
|
+
v14.3.11
|
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.11`
|
|
27
27
|
|
|
28
28
|
## 🌿 Branches
|
|
29
29
|
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
private readonly trigger: HTMLElement;
|
|
37
37
|
|
|
38
38
|
constructor() {
|
|
39
|
-
this.adminPanel = document.querySelector(AdminPanelSelectors.adminPanelRole)
|
|
39
|
+
this.adminPanel = document.querySelector<HTMLFormElement>(AdminPanelSelectors.adminPanelRole);
|
|
40
40
|
this.modules = this.querySelectorAll(AdminPanelSelectors.moduleTriggerRole).map(
|
|
41
41
|
(moduleTrigger) => {
|
|
42
42
|
const moduleParent = moduleTrigger.closest(AdminPanelSelectors.moduleParentClass);
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
new AdminPanelContentSetting(contentSettingElement, contentSettingTrigger);
|
|
61
61
|
},
|
|
62
62
|
);
|
|
63
|
-
this.trigger = document.querySelector(AdminPanelSelectors.triggerRole)
|
|
63
|
+
this.trigger = document.querySelector<HTMLElement>(AdminPanelSelectors.triggerRole);
|
|
64
64
|
|
|
65
65
|
this.initializeEvents();
|
|
66
66
|
this.addBackdropListener();
|
|
@@ -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';
|
|
@@ -1119,7 +1120,7 @@ export class BookmarkManagerContentElement extends LitElement {
|
|
|
1119
1120
|
|
|
1120
1121
|
private async handleDropBookmark(draggedBookmark: Bookmark, target: Bookmark | BookmarkGroup | BookmarkGroupId, dropPosition?: 'before' | 'after'): Promise<void> {
|
|
1121
1122
|
if (typeof target === 'object' && 'route' in target) {
|
|
1122
|
-
const targetBookmark = target
|
|
1123
|
+
const targetBookmark = target;
|
|
1123
1124
|
if (draggedBookmark.id === targetBookmark.id) {
|
|
1124
1125
|
return;
|
|
1125
1126
|
}
|
|
@@ -1208,8 +1209,8 @@ 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 managerElement = targetDocument.createElement('typo3-backend-bookmark-manager-content')
|
|
1212
|
+
const targetDocument = topDocument;
|
|
1213
|
+
const managerElement = targetDocument.createElement('typo3-backend-bookmark-manager-content');
|
|
1213
1214
|
if (this.editId !== undefined) {
|
|
1214
1215
|
managerElement.editId = this.editId;
|
|
1215
1216
|
}
|
|
@@ -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> => {
|
|
@@ -99,11 +105,17 @@ export class ClipboardPanel extends LitElement {
|
|
|
99
105
|
const clipboardData: ClipboardData = resolvedBody.data;
|
|
100
106
|
return html`
|
|
101
107
|
<div class="panel panel-default" data-clipboard-panel>
|
|
102
|
-
<div class="panel-heading">
|
|
108
|
+
<div class="panel-heading" id="clipboard-panel-heading">
|
|
103
109
|
${clipboardData.labels.clipboard}
|
|
104
110
|
</div>
|
|
105
111
|
<div class="table-fit">
|
|
106
|
-
<table class="table">
|
|
112
|
+
<table class="table" aria-labelledby="clipboard-panel-heading">
|
|
113
|
+
<thead>
|
|
114
|
+
<tr>
|
|
115
|
+
<th scope="col" colspan="2" class="p-0 border-0"><span class="visually-hidden">${clipboardData.labels.element}</span></th>
|
|
116
|
+
<th scope="col" class="p-0 border-0"><span class="visually-hidden">${clipboardData.labels.control}</span></th>
|
|
117
|
+
</tr>
|
|
118
|
+
</thead>
|
|
107
119
|
<tbody>
|
|
108
120
|
${clipboardData.tabs.map((tab): TemplateResult => this.renderTab(tab, clipboardData))}
|
|
109
121
|
</tbody>
|
|
@@ -127,8 +139,8 @@ export class ClipboardPanel extends LitElement {
|
|
|
127
139
|
private renderTab(tab: ClipboardTab, clipboardData: ClipboardData): TemplateResult {
|
|
128
140
|
return html`
|
|
129
141
|
<tr>
|
|
130
|
-
<
|
|
131
|
-
<button type="button" class="btn btn-link" aria-
|
|
142
|
+
<th scope="row" colspan="2" class="nowrap fw-normal">
|
|
143
|
+
<button type="button" class="btn btn-link" aria-current="${clipboardData.current === tab.identifier ? 'true' : nothing}" title="${tab.description}" data-action="setP" @click="${(event: PointerEvent) => this.updateClipboard(event, { CB: { 'setP': tab.identifier } })}">
|
|
132
144
|
${clipboardData.current === tab.identifier ? html`
|
|
133
145
|
<typo3-backend-icon identifier="actions-check-circle-alt" size="small"></typo3-backend-icon>
|
|
134
146
|
${tab.title}
|
|
@@ -140,7 +152,7 @@ export class ClipboardPanel extends LitElement {
|
|
|
140
152
|
</span>
|
|
141
153
|
`}
|
|
142
154
|
</button>
|
|
143
|
-
</
|
|
155
|
+
</th>
|
|
144
156
|
<td class="col-control nowrap">
|
|
145
157
|
${clipboardData.current !== tab.identifier ? nothing : html`
|
|
146
158
|
<div class="btn-toolbar btn-toolbar-nowrap">
|
|
@@ -176,11 +188,11 @@ export class ClipboardPanel extends LitElement {
|
|
|
176
188
|
<td class="col-icon nowrap ${classMap({ 'ps-4': !tabItem.identifier })}">
|
|
177
189
|
${unsafeHTML(tabItem.icon)}
|
|
178
190
|
</td>
|
|
179
|
-
<
|
|
191
|
+
<th scope="row" class="col-title col-responsive nowrap fw-normal">
|
|
180
192
|
${unsafeHTML(tabItem.title)}
|
|
181
193
|
${tabIdentifier === 'normal' ? html`<strong>(${clipboardData.copyMode === CopyMode.copy ? html`${clipboardData.labels.copy}` : html`${clipboardData.labels.cut}`})</strong>` : nothing}
|
|
182
194
|
${tabItem.thumb ? html`<div class="d-block">${unsafeHTML(tabItem.thumb)}</div>` : nothing}
|
|
183
|
-
</
|
|
195
|
+
</th>
|
|
184
196
|
<td class="col-control nowrap">
|
|
185
197
|
<div class="btn-group">
|
|
186
198
|
${!tabItem.infoDataDispatch ? nothing : html`
|
|
@@ -202,7 +214,7 @@ export class ClipboardPanel extends LitElement {
|
|
|
202
214
|
private updateClipboard(event: PointerEvent, payload: object): void {
|
|
203
215
|
event.preventDefault();
|
|
204
216
|
const target: HTMLElement = event.currentTarget as HTMLElement;
|
|
205
|
-
(new AjaxRequest(
|
|
217
|
+
(new AjaxRequest(this.getModuleUrl()))
|
|
206
218
|
.post(payload)
|
|
207
219
|
.then(async (response: AjaxResponse): Promise<void> => {
|
|
208
220
|
const resolvedBody = await response.resolve();
|
|
@@ -47,7 +47,7 @@ export function typoscript() {
|
|
|
47
47
|
|
|
48
48
|
const tsCodeCompletionInitializer = (async (): Promise<TsCodeCompletion> => {
|
|
49
49
|
await DocumentService.ready();
|
|
50
|
-
const effectivePid = parseInt((document.querySelector('input[name="effectivePid"]')
|
|
50
|
+
const effectivePid = parseInt((document.querySelector<HTMLInputElement>('input[name="effectivePid"]'))?.value, 10);
|
|
51
51
|
return new TsCodeCompletion(effectivePid);
|
|
52
52
|
})();
|
|
53
53
|
|
|
@@ -168,7 +168,7 @@ export class ColumnSelectorButton extends PseudoButtonLitElement {
|
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
private processSelection(currentModal: HTMLElement): void {
|
|
171
|
-
const form
|
|
171
|
+
const form = currentModal.querySelector('form');
|
|
172
172
|
if (form === null) {
|
|
173
173
|
this.abortSelection();
|
|
174
174
|
return;
|
|
@@ -192,7 +192,7 @@ export class ColumnSelectorButton extends PseudoButtonLitElement {
|
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
private handleModalContentLoaded(currentModal: HTMLElement): void {
|
|
195
|
-
const form
|
|
195
|
+
const form = currentModal.querySelector('form');
|
|
196
196
|
if (form === null) {
|
|
197
197
|
// Early return if modal content does not include a form
|
|
198
198
|
return;
|
|
@@ -15,6 +15,8 @@ import type { AjaxResponse } from '@typo3/core/ajax/ajax-response';
|
|
|
15
15
|
import { SeverityEnum } from './enum/severity';
|
|
16
16
|
import AjaxDataHandler from './ajax-data-handler';
|
|
17
17
|
import AjaxRequest from '@typo3/core/ajax/ajax-request';
|
|
18
|
+
import ClientRequest from './event/client-request';
|
|
19
|
+
import { isContextualRecordEditOpen, openContextualRecordEdit } from './element/contextual-record-edit-trigger';
|
|
18
20
|
import InfoWindow from './info-window';
|
|
19
21
|
import Modal, { type ModalElement } from './modal';
|
|
20
22
|
import ModuleMenu from './module-menu';
|
|
@@ -23,6 +25,7 @@ import Viewport from './viewport';
|
|
|
23
25
|
import '@typo3/backend/new-record-wizard';
|
|
24
26
|
import Utility from '@typo3/backend/utility';
|
|
25
27
|
import { topLevelModuleImport } from '@typo3/backend/utility/top-level-module-import';
|
|
28
|
+
import { topWindow, topDocument } from '@typo3/core/utility/top-window';
|
|
26
29
|
import { html } from 'lit';
|
|
27
30
|
import coreCommonLabels from '~labels/core.common';
|
|
28
31
|
import cacheLabels from '~labels/core.cache';
|
|
@@ -38,7 +41,8 @@ class ContextMenuActions {
|
|
|
38
41
|
* @returns {string}
|
|
39
42
|
*/
|
|
40
43
|
public static getReturnUrl(): string {
|
|
41
|
-
|
|
44
|
+
const location = topWindow.list_frame.document.location;
|
|
45
|
+
return encodeURIComponent(location.pathname + location.search);
|
|
42
46
|
}
|
|
43
47
|
|
|
44
48
|
public static editRecord(table: string, uid: number, dataset: DOMStringMap): void {
|
|
@@ -50,13 +54,17 @@ class ContextMenuActions {
|
|
|
50
54
|
overrideVals = '&overrideVals[pages][sys_language_uid]=' + pageLanguageId;
|
|
51
55
|
}
|
|
52
56
|
|
|
53
|
-
|
|
54
|
-
top.TYPO3.settings.FormEngine.moduleUrl
|
|
55
|
-
+ '&edit[' + table + '][' + uid + ']=edit'
|
|
57
|
+
const editParameters = '&edit[' + table + '][' + uid + ']=edit'
|
|
56
58
|
+ overrideVals
|
|
57
|
-
+ '&module=' + encodeURIComponent(
|
|
58
|
-
+ '&returnUrl=' + ContextMenuActions.getReturnUrl()
|
|
59
|
-
|
|
59
|
+
+ '&module=' + encodeURIComponent(topWindow.TYPO3.ModuleMenu.App.getCurrentModule())
|
|
60
|
+
+ '&returnUrl=' + ContextMenuActions.getReturnUrl();
|
|
61
|
+
|
|
62
|
+
if (isContextualRecordEditOpen()) {
|
|
63
|
+
openContextualRecordEdit(topWindow.TYPO3.settings.FormEngine.contextualUrl + editParameters, table);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
Viewport.ContentContainer.setUrl(topWindow.TYPO3.settings.FormEngine.moduleUrl + editParameters);
|
|
60
68
|
}
|
|
61
69
|
|
|
62
70
|
public static viewRecord(table: string, uid: number, dataset: DOMStringMap): void {
|
|
@@ -112,7 +120,7 @@ class ContextMenuActions {
|
|
|
112
120
|
pageId: uid
|
|
113
121
|
},
|
|
114
122
|
});
|
|
115
|
-
|
|
123
|
+
topDocument.dispatchEvent(event);
|
|
116
124
|
}
|
|
117
125
|
}
|
|
118
126
|
|
|
@@ -152,13 +160,13 @@ class ContextMenuActions {
|
|
|
152
160
|
}
|
|
153
161
|
|
|
154
162
|
Viewport.ContentContainer.setUrl(
|
|
155
|
-
|
|
163
|
+
topWindow.TYPO3.settings.FormEngine.moduleUrl + '&edit[' + table + '][' + (table !== 'pages' ? '-' : '') + uid + ']=new&returnUrl=' + ContextMenuActions.getReturnUrl(),
|
|
156
164
|
);
|
|
157
165
|
}
|
|
158
166
|
|
|
159
167
|
public static openHistoryPopUp(table: string, uid: number): void {
|
|
160
168
|
Viewport.ContentContainer.setUrl(
|
|
161
|
-
|
|
169
|
+
topWindow.TYPO3.settings.RecordHistory.moduleUrl + '&element=' + table + ':' + uid + '&returnUrl=' + ContextMenuActions.getReturnUrl(),
|
|
162
170
|
);
|
|
163
171
|
}
|
|
164
172
|
|
|
@@ -195,37 +203,49 @@ class ContextMenuActions {
|
|
|
195
203
|
}
|
|
196
204
|
}
|
|
197
205
|
|
|
206
|
+
/**
|
|
207
|
+
* Marks a navigation that commits a record and returns to the current
|
|
208
|
+
* module, so it is not handled as leaving the current view.
|
|
209
|
+
*/
|
|
210
|
+
public static createRecordCommitRequest(): ClientRequest {
|
|
211
|
+
return new ClientRequest('typo3.recordCommit');
|
|
212
|
+
}
|
|
213
|
+
|
|
198
214
|
public static disableRecord(table: string, uid: number, dataset: DOMStringMap): void {
|
|
199
215
|
const disableFieldName = dataset.disableField || 'hidden';
|
|
200
216
|
Viewport.ContentContainer.setUrl(
|
|
201
|
-
|
|
217
|
+
topWindow.TYPO3.settings.RecordCommit.moduleUrl
|
|
202
218
|
+ '&data[' + table + '][' + uid + '][' + disableFieldName + ']=1'
|
|
203
219
|
+ '&redirect=' + ContextMenuActions.getReturnUrl(),
|
|
220
|
+
ContextMenuActions.createRecordCommitRequest(),
|
|
204
221
|
);
|
|
205
222
|
}
|
|
206
223
|
|
|
207
224
|
public static enableRecord(table: string, uid: number, dataset: DOMStringMap): void {
|
|
208
225
|
const disableFieldName = dataset.disableField || 'hidden';
|
|
209
226
|
Viewport.ContentContainer.setUrl(
|
|
210
|
-
|
|
227
|
+
topWindow.TYPO3.settings.RecordCommit.moduleUrl
|
|
211
228
|
+ '&data[' + table + '][' + uid + '][' + disableFieldName + ']=0'
|
|
212
229
|
+ '&redirect=' + ContextMenuActions.getReturnUrl(),
|
|
230
|
+
ContextMenuActions.createRecordCommitRequest(),
|
|
213
231
|
);
|
|
214
232
|
}
|
|
215
233
|
|
|
216
234
|
public static showInMenus(table: string, uid: number): void {
|
|
217
235
|
Viewport.ContentContainer.setUrl(
|
|
218
|
-
|
|
236
|
+
topWindow.TYPO3.settings.RecordCommit.moduleUrl
|
|
219
237
|
+ '&data[' + table + '][' + uid + '][nav_hide]=0'
|
|
220
238
|
+ '&redirect=' + ContextMenuActions.getReturnUrl(),
|
|
239
|
+
ContextMenuActions.createRecordCommitRequest(),
|
|
221
240
|
);
|
|
222
241
|
}
|
|
223
242
|
|
|
224
243
|
public static hideInMenus(table: string, uid: number): void {
|
|
225
244
|
Viewport.ContentContainer.setUrl(
|
|
226
|
-
|
|
245
|
+
topWindow.TYPO3.settings.RecordCommit.moduleUrl
|
|
227
246
|
+ '&data[' + table + '][' + uid + '][nav_hide]=1'
|
|
228
247
|
+ '&redirect=' + ContextMenuActions.getReturnUrl(),
|
|
248
|
+
ContextMenuActions.createRecordCommitRequest(),
|
|
229
249
|
);
|
|
230
250
|
}
|
|
231
251
|
|
|
@@ -350,7 +370,7 @@ class ContextMenuActions {
|
|
|
350
370
|
+ '&redirect=' + ContextMenuActions.getReturnUrl();
|
|
351
371
|
|
|
352
372
|
Viewport.ContentContainer.setUrl(
|
|
353
|
-
|
|
373
|
+
topWindow.TYPO3.settings.RecordCommit.moduleUrl + url,
|
|
354
374
|
);
|
|
355
375
|
};
|
|
356
376
|
if (!dataset.title) {
|
|
@@ -384,7 +404,7 @@ class ContextMenuActions {
|
|
|
384
404
|
}
|
|
385
405
|
|
|
386
406
|
private static refreshPageTree(): void {
|
|
387
|
-
|
|
407
|
+
topDocument.dispatchEvent(new CustomEvent('typo3:pagetree:refresh'));
|
|
388
408
|
}
|
|
389
409
|
}
|
|
390
410
|
|
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 {
|
|
@@ -154,6 +155,9 @@ export class ContextMenuElement extends LitElement {
|
|
|
154
155
|
@queryAll('.context-menu') contextMenuElements: HTMLDivElement[];
|
|
155
156
|
@queryAll('.context-menu-item') contextMenuItemElements: HTMLButtonElement[];
|
|
156
157
|
private readonly rootIdentifier: string = 'root';
|
|
158
|
+
// A modal <dialog> makes everything outside of it inert, so the menu is rendered
|
|
159
|
+
// into a popover that is mounted into the topmost open dialog while it is shown.
|
|
160
|
+
private readonly popoverHost: HTMLDivElement = document.createElement('div');
|
|
157
161
|
|
|
158
162
|
private focusFirstElement: boolean = false;
|
|
159
163
|
|
|
@@ -210,6 +214,8 @@ export class ContextMenuElement extends LitElement {
|
|
|
210
214
|
window.addEventListener('resize', this.hide);
|
|
211
215
|
document.addEventListener(ContextMenuEvent.open, this.show);
|
|
212
216
|
document.addEventListener(ContextMenuEvent.close, this.hide);
|
|
217
|
+
document.addEventListener('typo3-modal-show', this.hide);
|
|
218
|
+
document.addEventListener('typo3-modal-hide', this.hide);
|
|
213
219
|
}
|
|
214
220
|
|
|
215
221
|
public override disconnectedCallback(): void {
|
|
@@ -217,6 +223,8 @@ export class ContextMenuElement extends LitElement {
|
|
|
217
223
|
window.removeEventListener('resize', this.hide);
|
|
218
224
|
document.removeEventListener(ContextMenuEvent.open, this.show);
|
|
219
225
|
document.removeEventListener(ContextMenuEvent.close, this.hide);
|
|
226
|
+
document.removeEventListener('typo3-modal-show', this.hide);
|
|
227
|
+
document.removeEventListener('typo3-modal-hide', this.hide);
|
|
220
228
|
}
|
|
221
229
|
|
|
222
230
|
protected override updated(): void {
|
|
@@ -231,7 +239,10 @@ export class ContextMenuElement extends LitElement {
|
|
|
231
239
|
}
|
|
232
240
|
|
|
233
241
|
protected override createRenderRoot(): HTMLElement | ShadowRoot {
|
|
234
|
-
|
|
242
|
+
this.popoverHost.classList.add('context-menu-host');
|
|
243
|
+
this.popoverHost.setAttribute('popover', 'manual');
|
|
244
|
+
this.append(this.popoverHost);
|
|
245
|
+
return this.popoverHost;
|
|
235
246
|
}
|
|
236
247
|
|
|
237
248
|
protected override render() {
|
|
@@ -264,6 +275,7 @@ export class ContextMenuElement extends LitElement {
|
|
|
264
275
|
this.uid = detail.uid;
|
|
265
276
|
this.context = detail.context;
|
|
266
277
|
this.eventSource = detail.eventSource;
|
|
278
|
+
this.mountPopoverHost();
|
|
267
279
|
|
|
268
280
|
if (detail.originalEvent !== null) {
|
|
269
281
|
const offset = this.calculateIframeOffset(detail.originalEvent.view, window);
|
|
@@ -294,11 +306,31 @@ export class ContextMenuElement extends LitElement {
|
|
|
294
306
|
return;
|
|
295
307
|
}
|
|
296
308
|
this.open = false;
|
|
309
|
+
this.unmountPopoverHost();
|
|
297
310
|
this.fetchTask.run();
|
|
298
311
|
await this.updateComplete;
|
|
299
312
|
this.eventSource?.focus();
|
|
300
313
|
};
|
|
301
314
|
|
|
315
|
+
private mountPopoverHost(): void {
|
|
316
|
+
const openDialogs = document.querySelectorAll<HTMLDialogElement>('typo3-backend-modal > dialog[open]');
|
|
317
|
+
const target: HTMLElement = openDialogs.item(openDialogs.length - 1) ?? this;
|
|
318
|
+
if (this.popoverHost.matches(':popover-open')) {
|
|
319
|
+
this.popoverHost.hidePopover();
|
|
320
|
+
}
|
|
321
|
+
if (this.popoverHost.parentElement !== target) {
|
|
322
|
+
target.append(this.popoverHost);
|
|
323
|
+
}
|
|
324
|
+
this.popoverHost.showPopover();
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
private unmountPopoverHost(): void {
|
|
328
|
+
if (this.popoverHost.matches(':popover-open')) {
|
|
329
|
+
this.popoverHost.hidePopover();
|
|
330
|
+
}
|
|
331
|
+
this.append(this.popoverHost);
|
|
332
|
+
}
|
|
333
|
+
|
|
302
334
|
private renderOverlay(): TemplateResult {
|
|
303
335
|
return html`
|
|
304
336
|
<div
|
|
@@ -593,7 +625,7 @@ export class ContextMenuElement extends LitElement {
|
|
|
593
625
|
}
|
|
594
626
|
|
|
595
627
|
private getElementFromNode(node: MenuItemInterface): HTMLElement | null {
|
|
596
|
-
return this.querySelector('[data-contextmenu-id="' + this.getNodeIdentifier(node) + '"]');
|
|
628
|
+
return this.renderRoot.querySelector<HTMLElement>('[data-contextmenu-id="' + this.getNodeIdentifier(node) + '"]');
|
|
597
629
|
}
|
|
598
630
|
|
|
599
631
|
private enhanceNodes(parentIdentifier: string, nodes: RawMenuItemInterface[]): MenuItemInterface[] {
|