typo3-typescript-sources 13.4.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/sync-and-publish.yml +265 -0
- package/.last-synced-tag +1 -0
- package/LICENSE.txt +339 -0
- package/README-TYPO3.md +166 -0
- package/README.md +28 -0
- package/adminpanel/admin-panel.ts +375 -0
- package/adminpanel/modules/cache.ts +27 -0
- package/adminpanel/modules/preview.ts +75 -0
- package/backend/action-button/abstract-action.ts +22 -0
- package/backend/action-button/deferred-action.ts +41 -0
- package/backend/action-button/immediate-action.ts +31 -0
- package/backend/action-dispatcher.ts +104 -0
- package/backend/ajax-data-handler/message-interface.ts +18 -0
- package/backend/ajax-data-handler/response-interface.ts +20 -0
- package/backend/ajax-data-handler.ts +214 -0
- package/backend/backend-exception.ts +22 -0
- package/backend/broadcast-message.ts +50 -0
- package/backend/broadcast-service.ts +52 -0
- package/backend/browse-database.ts +38 -0
- package/backend/clear-cache.ts +88 -0
- package/backend/clipboard-panel.ts +240 -0
- package/backend/close-current-window.ts +2 -0
- package/backend/code-editor/autocomplete/completion-result.ts +105 -0
- package/backend/code-editor/autocomplete/ts-code-completion.ts +142 -0
- package/backend/code-editor/autocomplete/ts-parser.ts +485 -0
- package/backend/code-editor/autocomplete/ts-ref.ts +164 -0
- package/backend/code-editor/element/code-mirror-element.ts +282 -0
- package/backend/code-editor/language/typoscript.ts +181 -0
- package/backend/code-editor/stream-parser/typoscript.ts +1600 -0
- package/backend/color-picker.ts +158 -0
- package/backend/color-scheme-switch.ts +179 -0
- package/backend/column-selector-button.ts +302 -0
- package/backend/context-help.ts +68 -0
- package/backend/context-menu-actions.ts +322 -0
- package/backend/context-menu.ts +751 -0
- package/backend/copy-to-clipboard.ts +79 -0
- package/backend/date-time-picker.ts +270 -0
- package/backend/document-save-actions.ts +159 -0
- package/backend/drag-tooltip.ts +285 -0
- package/backend/drag-uploader.ts +914 -0
- package/backend/element/alert-element.ts +116 -0
- package/backend/element/dispatch-modal-button.ts +50 -0
- package/backend/element/draggable-resizable-element.ts +249 -0
- package/backend/element/editable-page-title.ts +306 -0
- package/backend/element/icon-element.ts +84 -0
- package/backend/element/immediate-action-element.ts +89 -0
- package/backend/element/pagination.ts +59 -0
- package/backend/element/progress-bar-element.ts +172 -0
- package/backend/element/progress-tracker-element.ts +119 -0
- package/backend/element/pseudo-button.ts +58 -0
- package/backend/element/spinner-element.ts +51 -0
- package/backend/element/thumbnail-element.ts +80 -0
- package/backend/element-browser.ts +182 -0
- package/backend/enum/data-transfer-types.ts +21 -0
- package/backend/enum/icon-types.ts +31 -0
- package/backend/enum/key-types.ts +27 -0
- package/backend/enum/severity.ts +20 -0
- package/backend/enum/viewport/scaffold-identifier.ts +24 -0
- package/backend/event/client-request.ts +25 -0
- package/backend/event/consumable.ts +18 -0
- package/backend/event/consumer-scope.ts +54 -0
- package/backend/event/event-dispatcher.ts +26 -0
- package/backend/event/interaction-request-assignment.ts +24 -0
- package/backend/event/interaction-request-map.ts +75 -0
- package/backend/event/interaction-request.ts +48 -0
- package/backend/event/trigger-request.ts +56 -0
- package/backend/form/submit-interceptor.ts +66 -0
- package/backend/form-engine/container/files-control-container.ts +716 -0
- package/backend/form-engine/container/flex-form-container-container.ts +166 -0
- package/backend/form-engine/container/flex-form-section-container.ts +210 -0
- package/backend/form-engine/container/inline-control-container.ts +1230 -0
- package/backend/form-engine/container/site-language-container.ts +616 -0
- package/backend/form-engine/element/abstract-sortable-select-items.ts +186 -0
- package/backend/form-engine/element/category-element.ts +160 -0
- package/backend/form-engine/element/color-element.ts +81 -0
- package/backend/form-engine/element/datetime-element.ts +66 -0
- package/backend/form-engine/element/extra/char-counter.ts +112 -0
- package/backend/form-engine/element/extra/select-box-filter.ts +85 -0
- package/backend/form-engine/element/folder-element.ts +66 -0
- package/backend/form-engine/element/group-element.ts +47 -0
- package/backend/form-engine/element/json-element.ts +52 -0
- package/backend/form-engine/element/link-element.ts +121 -0
- package/backend/form-engine/element/mfa-info-element.ts +169 -0
- package/backend/form-engine/element/modifier/resizable.ts +27 -0
- package/backend/form-engine/element/modifier/tabbable.ts +29 -0
- package/backend/form-engine/element/online-media-form-element.ts +65 -0
- package/backend/form-engine/element/password-element.ts +71 -0
- package/backend/form-engine/element/select-multiple-side-by-side-element.ts +83 -0
- package/backend/form-engine/element/select-single-element.ts +82 -0
- package/backend/form-engine/element/select-tree-element.ts +148 -0
- package/backend/form-engine/element/select-tree-toolbar.ts +118 -0
- package/backend/form-engine/element/select-tree.ts +210 -0
- package/backend/form-engine/element/slug-element.ts +243 -0
- package/backend/form-engine/element/suggest/result-container.ts +118 -0
- package/backend/form-engine/element/suggest/result-item.ts +90 -0
- package/backend/form-engine/element/table-permission-element.ts +101 -0
- package/backend/form-engine/element/table-wizard-element.ts +427 -0
- package/backend/form-engine/element/text-element.ts +52 -0
- package/backend/form-engine/element/text-table-element.ts +31 -0
- package/backend/form-engine/field-control/add-record.ts +40 -0
- package/backend/form-engine/field-control/edit-popup.ts +64 -0
- package/backend/form-engine/field-control/insert-clipboard.ts +50 -0
- package/backend/form-engine/field-control/link-popup.ts +53 -0
- package/backend/form-engine/field-control/list-module.ts +40 -0
- package/backend/form-engine/field-control/password-generator.ts +102 -0
- package/backend/form-engine/field-control/reset-selection.ts +48 -0
- package/backend/form-engine/field-wizard/localization-state-selector.ts +67 -0
- package/backend/form-engine/field-wizard/value-picker.ts +123 -0
- package/backend/form-engine/field-wizard/value-slider.ts +86 -0
- package/backend/form-engine/inline-relation/ajax-dispatcher.ts +124 -0
- package/backend/form-engine/inline-relation/inline-response-interface.ts +41 -0
- package/backend/form-engine-link-browser-adapter.ts +129 -0
- package/backend/form-engine-review.ts +155 -0
- package/backend/form-engine-suggest.ts +133 -0
- package/backend/form-engine-validation.ts +686 -0
- package/backend/form-engine.ts +1391 -0
- package/backend/global-event-handler.ts +252 -0
- package/backend/grid-editor.ts +1077 -0
- package/backend/hashing/md5.ts +252 -0
- package/backend/helper.ts +24 -0
- package/backend/hotkeys/hotkey-storage.ts +63 -0
- package/backend/hotkeys.ts +216 -0
- package/backend/icons.ts +236 -0
- package/backend/image-manipulation.ts +885 -0
- package/backend/info-window.ts +46 -0
- package/backend/input/clearable.ts +128 -0
- package/backend/input/index.d.ts +8 -0
- package/backend/java-script-module-import-event-handler.ts +19 -0
- package/backend/key-bindings.ts +42 -0
- package/backend/layout-module/drag-drop.ts +359 -0
- package/backend/layout-module/paste.ts +165 -0
- package/backend/link-browser.ts +89 -0
- package/backend/live-search/element/backend-search.ts +34 -0
- package/backend/live-search/element/hint.ts +33 -0
- package/backend/live-search/element/provider/default-result-item.ts +52 -0
- package/backend/live-search/element/provider/page-provider-result-item.ts +52 -0
- package/backend/live-search/element/result/item/action/action-container.ts +135 -0
- package/backend/live-search/element/result/item/action/action.ts +56 -0
- package/backend/live-search/element/result/item/item-container.ts +224 -0
- package/backend/live-search/element/result/item/item.ts +74 -0
- package/backend/live-search/element/result/result-container.ts +110 -0
- package/backend/live-search/element/result/result-detail-container.ts +50 -0
- package/backend/live-search/element/result/result-pagination.ts +122 -0
- package/backend/live-search/element/search-option-item.ts +70 -0
- package/backend/live-search/live-search-configurator.ts +54 -0
- package/backend/live-search/live-search-shortcut.ts +29 -0
- package/backend/live-search/result-types/backend-module-result-type.ts +8 -0
- package/backend/live-search/result-types/default-result-type.ts +21 -0
- package/backend/live-search/result-types/page-result-type.ts +23 -0
- package/backend/localization.ts +390 -0
- package/backend/login-refresh.ts +525 -0
- package/backend/login.ts +179 -0
- package/backend/mail-link-handler.ts +45 -0
- package/backend/modal-interface.ts +19 -0
- package/backend/modal.ts +685 -0
- package/backend/module/iframe.ts +125 -0
- package/backend/module/router.ts +275 -0
- package/backend/module-menu.ts +550 -0
- package/backend/module.ts +133 -0
- package/backend/multi-record-selection-action.ts +44 -0
- package/backend/multi-record-selection-delete-action.ts +108 -0
- package/backend/multi-record-selection-edit-action.ts +56 -0
- package/backend/multi-record-selection.ts +468 -0
- package/backend/multi-step-wizard.ts +568 -0
- package/backend/new-content-element-wizard-button.ts +51 -0
- package/backend/new-multiple-pages.ts +108 -0
- package/backend/new-record-wizard.ts +680 -0
- package/backend/notification.ts +366 -0
- package/backend/offset.ts +40 -0
- package/backend/online-media.ts +110 -0
- package/backend/page-actions.ts +91 -0
- package/backend/page-link-handler.ts +51 -0
- package/backend/pagetsconfig/pagetsconfig-includes.ts +77 -0
- package/backend/popover.ts +165 -0
- package/backend/record-download-button.ts +104 -0
- package/backend/record-link-handler.ts +31 -0
- package/backend/record-search.ts +44 -0
- package/backend/recordlist.ts +230 -0
- package/backend/resource/resource.ts +35 -0
- package/backend/security/element/csp-reports.ts +406 -0
- package/backend/security/element/sudo-mode.ts +249 -0
- package/backend/security/sudo-mode-interceptor.ts +19 -0
- package/backend/settings/editor/editable-setting.ts +231 -0
- package/backend/settings/editor.ts +451 -0
- package/backend/settings/enum/settings-mode.enum.ts +24 -0
- package/backend/settings/type/base.ts +200 -0
- package/backend/settings/type/bool.ts +56 -0
- package/backend/settings/type/color.ts +64 -0
- package/backend/settings/type/int.ts +85 -0
- package/backend/settings/type/number.ts +61 -0
- package/backend/settings/type/page.ts +100 -0
- package/backend/settings/type/string.ts +77 -0
- package/backend/settings/type/stringlist.ts +87 -0
- package/backend/severity.ts +88 -0
- package/backend/site-inline-actions.ts +32 -0
- package/backend/sortable-table.ts +208 -0
- package/backend/storage/abstract-client-storage.ts +76 -0
- package/backend/storage/browser-session.ts +28 -0
- package/backend/storage/client.ts +28 -0
- package/backend/storage/module-state-storage.ts +118 -0
- package/backend/storage/persistent.ts +204 -0
- package/backend/switch-user.ts +82 -0
- package/backend/tabs.ts +72 -0
- package/backend/telephone-link-handler.ts +40 -0
- package/backend/tests/backend/storage/browser-storage-test.ts +87 -0
- package/backend/tests/backend/storage/client-test.ts +87 -0
- package/backend/tests/backend/utility/dom-helper-test.ts +51 -0
- package/backend/tests/backend-exception-test.ts +28 -0
- package/backend/tests/element/immediate-action-element-test.ts +81 -0
- package/backend/tests/form-engine-validation-test.ts +304 -0
- package/backend/tests/grid-editor-test.ts +29 -0
- package/backend/tests/hashing/md5Test.ts +28 -0
- package/backend/tests/icons-test.ts +23 -0
- package/backend/tests/notification-test.ts +161 -0
- package/backend/tests/popover-test.ts +83 -0
- package/backend/toolbar/clear-cache-menu.ts +88 -0
- package/backend/toolbar/live-search.ts +284 -0
- package/backend/toolbar/shortcut-menu.ts +254 -0
- package/backend/toolbar/system-information-menu.ts +161 -0
- package/backend/toolbar.ts +41 -0
- package/backend/tree/file-storage-browser.ts +194 -0
- package/backend/tree/file-storage-tree-container.ts +465 -0
- package/backend/tree/file-storage-tree.ts +42 -0
- package/backend/tree/page-browser.ts +272 -0
- package/backend/tree/page-tree-element.ts +602 -0
- package/backend/tree/page-tree.ts +152 -0
- package/backend/tree/tree-module-state.ts +159 -0
- package/backend/tree/tree-node-toggle.ts +31 -0
- package/backend/tree/tree-node.ts +97 -0
- package/backend/tree/tree-toolbar.ts +117 -0
- package/backend/tree/tree.ts +1595 -0
- package/backend/url-link-handler.ts +36 -0
- package/backend/user-pass-login.ts +255 -0
- package/backend/user-settings-manager.ts +189 -0
- package/backend/utility/collapse-state-persister.ts +205 -0
- package/backend/utility/collapse-state-search.ts +183 -0
- package/backend/utility/dom-helper.ts +91 -0
- package/backend/utility/drag-drop-utility.ts +47 -0
- package/backend/utility/message-utility.ts +45 -0
- package/backend/utility/top-level-module-import.ts +32 -0
- package/backend/utility.ts +194 -0
- package/backend/viewport/abstract-container.ts +22 -0
- package/backend/viewport/content-container.ts +98 -0
- package/backend/viewport/loader.ts +28 -0
- package/backend/viewport/navigation-container.ts +119 -0
- package/backend/viewport/resizable-navigation.ts +176 -0
- package/backend/viewport/toolbar.ts +27 -0
- package/backend/viewport/topbar.ts +39 -0
- package/backend/viewport.ts +46 -0
- package/backend/window-manager.ts +84 -0
- package/backend/wizard/move-content-element.ts +107 -0
- package/backend/wizard/move-page.ts +74 -0
- package/backend/wizard.ts +331 -0
- package/belog/backend-log.ts +88 -0
- package/beuser/backend-user-listing.ts +40 -0
- package/beuser/permissions.ts +291 -0
- package/core/ajax/ajax-request-types.ts +15 -0
- package/core/ajax/ajax-request.ts +202 -0
- package/core/ajax/ajax-response.ts +57 -0
- package/core/ajax/input-transformer.ts +92 -0
- package/core/ajax/simple-response-interface.ts +5 -0
- package/core/authentication/mfa-provider/totp.ts +54 -0
- package/core/cache/dedupe-async-task.ts +95 -0
- package/core/directive/markdown.ts +82 -0
- package/core/directive/nl2br.ts +16 -0
- package/core/document-service.ts +35 -0
- package/core/event/debounce-event.ts +40 -0
- package/core/event/event-interface.ts +24 -0
- package/core/event/regular-event.ts +58 -0
- package/core/event/request-animation-frame-event.ts +42 -0
- package/core/event/throttle-event.ts +54 -0
- package/core/java-script-item-handler.ts +29 -0
- package/core/java-script-item-processor.ts +171 -0
- package/core/lit-helper.ts +126 -0
- package/core/literals.ts +17 -0
- package/core/referrer-refresh.ts +2 -0
- package/core/security-utility.ts +89 -0
- package/core/tests/ajax/ajax-request-test.ts +290 -0
- package/core/tests/ajax/input-transformer-test.ts +64 -0
- package/core/tests/cache/dedupe-async-task-test.ts +152 -0
- package/core/tests/event/throttle-event-test.ts +47 -0
- package/core/tests/literals-test.ts +24 -0
- package/core/tests/security-utility-test.ts +50 -0
- package/core/utility/types.ts +9 -0
- package/dashboard/chart-initializer.ts +136 -0
- package/dashboard/dashboard.ts +1487 -0
- package/extensionmanager/distribution-image.ts +55 -0
- package/extensionmanager/main.ts +291 -0
- package/extensionmanager/repository.ts +195 -0
- package/extensionmanager/update.ts +118 -0
- package/extensionmanager/upload-form.ts +42 -0
- package/filelist/browse-files.ts +148 -0
- package/filelist/browse-folders.ts +94 -0
- package/filelist/context-menu-actions.ts +335 -0
- package/filelist/create-folder.ts +69 -0
- package/filelist/file-delete.ts +69 -0
- package/filelist/file-list-actions.ts +132 -0
- package/filelist/file-list-dragdrop.ts +139 -0
- package/filelist/file-list-rename-handler.ts +128 -0
- package/filelist/file-list-transfer-handler.ts +138 -0
- package/filelist/file-list.ts +396 -0
- package/filelist/file-replace.ts +37 -0
- package/filelist/linkbrowser-file-handler.ts +94 -0
- package/filelist/linkbrowser-folder-handler.ts +74 -0
- package/filelist/rename-file.ts +109 -0
- package/form/backend/form-editor/component/property-grid-editor.ts +340 -0
- package/form/backend/form-editor/core.ts +2104 -0
- package/form/backend/form-editor/helper.ts +226 -0
- package/form/backend/form-editor/inspector-component.ts +2323 -0
- package/form/backend/form-editor/mediator.ts +941 -0
- package/form/backend/form-editor/modals-component.ts +433 -0
- package/form/backend/form-editor/stage-component.ts +908 -0
- package/form/backend/form-editor/tree-component.ts +548 -0
- package/form/backend/form-editor/view-model.ts +1343 -0
- package/form/backend/form-editor.ts +846 -0
- package/form/backend/form-manager/main.ts +39 -0
- package/form/backend/form-manager/view-model.ts +789 -0
- package/form/backend/form-manager.ts +180 -0
- package/form/backend/helper.ts +60 -0
- package/form/frontend/date-picker.ts +38 -0
- package/frontend/default_frontend.ts +82 -0
- package/impexp/context-menu-actions.ts +50 -0
- package/impexp/import-export.ts +62 -0
- package/indexed-search/pagination.ts +26 -0
- package/indexed-search/statistics.ts +50 -0
- package/info/translation-status.ts +48 -0
- package/install/ajax/ajax-queue.ts +83 -0
- package/install/init-install.ts +2 -0
- package/install/init-installer.ts +2 -0
- package/install/install.ts +25 -0
- package/install/installer.ts +458 -0
- package/install/message-interface.ts +18 -0
- package/install/module/abstract-inline-module.ts +27 -0
- package/install/module/abstract-interactable-module.ts +107 -0
- package/install/module/environment/environment-check.ts +92 -0
- package/install/module/environment/folder-structure.ts +145 -0
- package/install/module/environment/image-processing.ts +141 -0
- package/install/module/environment/mail-test.ts +127 -0
- package/install/module/environment/php-info.ts +50 -0
- package/install/module/environment/system-information.ts +50 -0
- package/install/module/maintenance/cache.ts +59 -0
- package/install/module/maintenance/clear-tables.ts +134 -0
- package/install/module/maintenance/clear-typo3temp-files.ts +137 -0
- package/install/module/maintenance/create-admin.ts +126 -0
- package/install/module/maintenance/database-analyzer.ts +266 -0
- package/install/module/maintenance/dump-autoload.ts +58 -0
- package/install/module/maintenance/language-packs.ts +338 -0
- package/install/module/maintenance/reset-backend-user-uc.ts +58 -0
- package/install/module/password-strength.ts +56 -0
- package/install/module/settings/change-install-tool-password.ts +101 -0
- package/install/module/settings/extension-configuration.ts +224 -0
- package/install/module/settings/features.ts +102 -0
- package/install/module/settings/local-configuration.ts +316 -0
- package/install/module/settings/presets.ts +147 -0
- package/install/module/settings/system-maintainer.ts +111 -0
- package/install/module/upgrade/core-update.ts +255 -0
- package/install/module/upgrade/extension-compat-tester.ts +195 -0
- package/install/module/upgrade/extension-scanner.ts +381 -0
- package/install/module/upgrade/tca-ext-tables-check.ts +93 -0
- package/install/module/upgrade/tca-migrations-check.ts +101 -0
- package/install/module/upgrade/upgrade-docs.ts +310 -0
- package/install/module/upgrade/upgrade-wizards.ts +612 -0
- package/install/renderable/clearable.ts +113 -0
- package/install/renderable/flash-message.ts +64 -0
- package/install/renderable/info-box.ts +66 -0
- package/install/renderable/language-packs.ts +304 -0
- package/install/renderable/offset-group.ts +38 -0
- package/install/renderable/severity.ts +49 -0
- package/install/renderable/wrap-group.ts +36 -0
- package/install/router.ts +468 -0
- package/linkvalidator/linkvalidator-modal.ts +45 -0
- package/linkvalidator/linkvalidator.ts +101 -0
- package/lowlevel/query-generator.ts +132 -0
- package/lowlevel/reference-index.ts +44 -0
- package/opendocs/toolbar/opendocs-menu.ts +117 -0
- package/package.json +34 -0
- package/recycler/recycler.ts +539 -0
- package/redirects/event-handler.ts +108 -0
- package/redirects/form-engine-evaluation.ts +34 -0
- package/redirects/redirects-module.ts +58 -0
- package/rte-ckeditor/ckeditor5.ts +402 -0
- package/rte-ckeditor/css-prefixer.ts +94 -0
- package/rte-ckeditor/legacy/ckeditor5-bundle.ts +17 -0
- package/rte-ckeditor/legacy/ckeditor5-inspector.ts +2 -0
- package/rte-ckeditor/plugin/typo3-link.ts +810 -0
- package/rte-ckeditor/plugin/whitespace.ts +114 -0
- package/rte-ckeditor/rte-link-browser.ts +112 -0
- package/rte-ckeditor/tests/css-prefixer-test.ts +314 -0
- package/scheduler/scheduler-add-group.ts +119 -0
- package/scheduler/scheduler-editable-group-name.ts +307 -0
- package/scheduler/scheduler-sortable-groups.ts +59 -0
- package/scheduler/scheduler.ts +466 -0
- package/setup/setup-module.ts +122 -0
- package/styleguide/checkbox-demo.ts +5 -0
- package/styleguide/element/theme-switcher-element.ts +101 -0
- package/styleguide/filter.ts +22 -0
- package/styleguide/find-icons.ts +78 -0
- package/styleguide/processing-indicator.ts +78 -0
- package/styleguide/render-notifications.ts +64 -0
- package/sys-note/element/delete-button.ts +78 -0
- package/tstemplate/constant-editor.ts +64 -0
- package/tstemplate/information-module.ts +31 -0
- package/tstemplate/template-analyzer.ts +77 -0
- package/viewpage/main.ts +253 -0
- package/workspaces/backend.ts +979 -0
- package/workspaces/preview.ts +232 -0
- package/workspaces/renderable/comment-view.ts +79 -0
- package/workspaces/renderable/diff-view.ts +58 -0
- package/workspaces/renderable/history-view.ts +97 -0
- package/workspaces/renderable/record-information.ts +118 -0
- package/workspaces/renderable/record-table.ts +355 -0
- package/workspaces/renderable/send-to-stage-form.ts +108 -0
- package/workspaces/toolbar/workspaces-menu.ts +190 -0
- package/workspaces/utility/icon-helper.ts +57 -0
- package/workspaces/workspaces.ts +136 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of the TYPO3 CMS project.
|
|
3
|
+
*
|
|
4
|
+
* It is free software; you can redistribute it and/or modify it under
|
|
5
|
+
* the terms of the GNU General Public License, either version 2
|
|
6
|
+
* of the License, or any later version.
|
|
7
|
+
*
|
|
8
|
+
* For the full copyright and license information, please read the
|
|
9
|
+
* LICENSE.txt file that was distributed with this source code.
|
|
10
|
+
*
|
|
11
|
+
* The TYPO3 project - inspiring people to share!
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { customElement, property, query } from 'lit/decorators';
|
|
15
|
+
import { css, html, LitElement, type TemplateResult } from 'lit';
|
|
16
|
+
import Alwan from 'alwan';
|
|
17
|
+
import RegularEvent from '@typo3/core/event/regular-event';
|
|
18
|
+
import DocumentService from '@typo3/core/document-service';
|
|
19
|
+
|
|
20
|
+
@customElement('typo3-backend-color-picker')
|
|
21
|
+
export class Typo3BackendColorPicker extends LitElement {
|
|
22
|
+
static override styles = css`
|
|
23
|
+
:host {
|
|
24
|
+
display: inline-block;
|
|
25
|
+
position: relative;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.color-picker-preview {
|
|
29
|
+
--typo3-colorpicker-preview-width: 1.25rem;
|
|
30
|
+
--typo3-colorpicker-preview-height: 1.25rem;
|
|
31
|
+
--typo3-bg-checkerboard-pattern-size: calc(var(--typo3-colorpicker-preview-width) / 2);
|
|
32
|
+
--typo3-bg-checkerboard-background-color: light-dark(var(--token-color-neutral-10), var(--token-color-neutral-85));
|
|
33
|
+
--typo3-bg-checkerboard-background-image-color: light-dark(var(--token-color-neutral-0), var(--token-color-neutral-90));
|
|
34
|
+
|
|
35
|
+
display: block;
|
|
36
|
+
position: absolute;
|
|
37
|
+
width: var(--typo3-colorpicker-preview-width);
|
|
38
|
+
height: var(--typo3-colorpicker-preview-height);
|
|
39
|
+
top: 50%;
|
|
40
|
+
inset-inline-start: var(--typo3-input-sm-padding-x);
|
|
41
|
+
z-index: 1;
|
|
42
|
+
transform: translate(0, -50%);
|
|
43
|
+
background: var(--typo3-bg-checkerboard-background-color);
|
|
44
|
+
background-image: linear-gradient(45deg, var(--typo3-bg-checkerboard-background-image-color) 25%, transparent 25%), linear-gradient(135deg, var(--typo3-bg-checkerboard-background-image-color) 25%, transparent 25%), linear-gradient(45deg, transparent 75%, var(--typo3-bg-checkerboard-background-image-color) 75%), linear-gradient(135deg, transparent 75%, var(--typo3-bg-checkerboard-background-image-color) 75%);
|
|
45
|
+
background-position: 0 0, calc(var(--typo3-bg-checkerboard-pattern-size) / 2) 0, calc(var(--typo3-bg-checkerboard-pattern-size) / 2) calc(var(--typo3-bg-checkerboard-pattern-size) / 2 * -1), 0 calc(var(--typo3-bg-checkerboard-pattern-size) / 2);
|
|
46
|
+
background-size: var(--typo3-bg-checkerboard-pattern-size) var(--typo3-bg-checkerboard-pattern-size);
|
|
47
|
+
background-clip: padding-box;
|
|
48
|
+
border-radius: var(--typo3-component-border-radius);
|
|
49
|
+
pointer-events: none;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.color-picker-preview-color {
|
|
53
|
+
position: absolute;
|
|
54
|
+
inset: 0;
|
|
55
|
+
border-radius: 2px;
|
|
56
|
+
background-color: var(--color, transparent);
|
|
57
|
+
}
|
|
58
|
+
`;
|
|
59
|
+
|
|
60
|
+
@property({ type: String }) color: string = '';
|
|
61
|
+
@property({ type: Boolean }) opacity: boolean = false;
|
|
62
|
+
@property({ type: String }) swatches: string = '';
|
|
63
|
+
|
|
64
|
+
// Use a reference to the input slot element
|
|
65
|
+
@query('slot') slotEl!: HTMLSlotElement;
|
|
66
|
+
|
|
67
|
+
protected override async firstUpdated(): Promise<void> {
|
|
68
|
+
await DocumentService.ready();
|
|
69
|
+
|
|
70
|
+
const inputElement = this.getInputElement();
|
|
71
|
+
if (inputElement) {
|
|
72
|
+
if (!inputElement.value && this.color) {
|
|
73
|
+
inputElement.value = this.color;
|
|
74
|
+
} else {
|
|
75
|
+
this.color = inputElement.value;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (inputElement.disabled || inputElement.readOnly) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const alwan = new Alwan(inputElement, {
|
|
83
|
+
position: 'bottom-start',
|
|
84
|
+
format: 'hex',
|
|
85
|
+
opacity: this.opacity,
|
|
86
|
+
swatches: this.swatches ? this.swatches.split(';') : [],
|
|
87
|
+
preset: false,
|
|
88
|
+
color: this.color,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
alwan.on('color', (e): void => {
|
|
92
|
+
this.color = e.hex;
|
|
93
|
+
inputElement.value = this.color;
|
|
94
|
+
inputElement.dispatchEvent(new Event('blur'));
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// input: react on user input
|
|
98
|
+
// change: react on indirect changes, e.g. a value picker
|
|
99
|
+
['input', 'change'].forEach((eventName: string): void => {
|
|
100
|
+
new RegularEvent(eventName, (e: Event): void => {
|
|
101
|
+
const input = (e.target as HTMLInputElement);
|
|
102
|
+
this.color = input.value;
|
|
103
|
+
alwan.setColor(this.color);
|
|
104
|
+
}).bindTo(inputElement);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
protected override render(): TemplateResult {
|
|
110
|
+
return html`
|
|
111
|
+
<slot></slot>
|
|
112
|
+
<span style="--color: ${this.color}" class="color-picker-preview"><span class="color-picker-preview-color"></span></span>
|
|
113
|
+
`;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private getInputElement(): HTMLInputElement | null {
|
|
117
|
+
const assignedNodes = this.slotEl.assignedNodes();
|
|
118
|
+
for (const node of assignedNodes) {
|
|
119
|
+
if (node instanceof HTMLInputElement) {
|
|
120
|
+
return node;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
console.warn('No input element found in the slot.');
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
interface LegacyColorPickerSettings {
|
|
129
|
+
swatches?: string[],
|
|
130
|
+
opacity?: boolean
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
class LegacyColorPicker {
|
|
135
|
+
/**
|
|
136
|
+
* Initialize the color picker for the given element
|
|
137
|
+
*/
|
|
138
|
+
public initialize(element: HTMLInputElement, options: LegacyColorPickerSettings = {}): void {
|
|
139
|
+
if (element.parentElement instanceof Typo3BackendColorPicker) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const colorPicker = document.createElement('typo3-backend-color-picker');
|
|
144
|
+
colorPicker.swatches = options.swatches?.join(';') ?? '';
|
|
145
|
+
colorPicker.opacity = options.opacity ?? false;
|
|
146
|
+
element.parentNode.insertBefore(colorPicker, element);
|
|
147
|
+
colorPicker.appendChild(element);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export default new LegacyColorPicker();
|
|
152
|
+
|
|
153
|
+
// Register the custom element
|
|
154
|
+
declare global {
|
|
155
|
+
interface HTMLElementTagNameMap {
|
|
156
|
+
'typo3-backend-color-picker': Typo3BackendColorPicker;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of the TYPO3 CMS project.
|
|
3
|
+
*
|
|
4
|
+
* It is free software; you can redistribute it and/or modify it under
|
|
5
|
+
* the terms of the GNU General Public License, either version 2
|
|
6
|
+
* of the License, or any later version.
|
|
7
|
+
*
|
|
8
|
+
* For the full copyright and license information, please read theÍ
|
|
9
|
+
* LICENSE.txt file that was distributed with this source code.
|
|
10
|
+
*
|
|
11
|
+
* The TYPO3 project - inspiring people to share!
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { html, LitElement, nothing, type TemplateResult } from 'lit';
|
|
15
|
+
import { customElement, property, state } from 'lit/decorators';
|
|
16
|
+
import AjaxRequest from '@typo3/core/ajax/ajax-request';
|
|
17
|
+
import '@typo3/backend/element/icon-element';
|
|
18
|
+
import type { ColorSchemeUpdateEventData, ColorScheme } from '@typo3/backend/user-settings-manager';
|
|
19
|
+
|
|
20
|
+
interface ColorSchemeOption {
|
|
21
|
+
label: string,
|
|
22
|
+
icon: string,
|
|
23
|
+
value: ColorScheme,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@customElement('typo3-backend-color-scheme-switch')
|
|
27
|
+
export class ColorSchemeSwitchElement extends LitElement {
|
|
28
|
+
@property({ type: String }) activeColorScheme: ColorScheme = null;
|
|
29
|
+
@property({ type: Array }) colorSchemes: ColorSchemeOption[] = null;
|
|
30
|
+
@property({ type: String }) toggleLabel: string;
|
|
31
|
+
@property({ type: String }) disabledLabel: string;
|
|
32
|
+
|
|
33
|
+
@state() advancedOptionsExpanded: boolean = false;
|
|
34
|
+
@state() autoDetect: ColorScheme|null = null;
|
|
35
|
+
@state() enabled: boolean|null = null;
|
|
36
|
+
|
|
37
|
+
private colorSchemeMql: MediaQueryList|null = null;
|
|
38
|
+
private forcedColorsMql: MediaQueryList|null = null;
|
|
39
|
+
|
|
40
|
+
public override connectedCallback(): void {
|
|
41
|
+
super.connectedCallback();
|
|
42
|
+
this.colorSchemeMql = window.matchMedia('(prefers-color-scheme: dark)');
|
|
43
|
+
this.forcedColorsMql = window.matchMedia('(forced-colors: active)');
|
|
44
|
+
this.colorSchemeMediaQueryListener(this.colorSchemeMql);
|
|
45
|
+
this.forcedColorsMediaQueryListener(this.forcedColorsMql);
|
|
46
|
+
this.colorSchemeMql.addEventListener('change', this.colorSchemeMediaQueryListener);
|
|
47
|
+
this.forcedColorsMql.addEventListener('change', this.forcedColorsMediaQueryListener);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public override disconnectedCallback(): void {
|
|
51
|
+
super.disconnectedCallback();
|
|
52
|
+
this.colorSchemeMql.removeEventListener('change', this.colorSchemeMediaQueryListener);
|
|
53
|
+
this.forcedColorsMql.removeEventListener('change', this.forcedColorsMediaQueryListener);
|
|
54
|
+
this.colorSchemeMql = null;
|
|
55
|
+
this.forcedColorsMql = null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
protected readonly colorSchemeMediaQueryListener = (mql: MediaQueryList|MediaQueryListEvent) => this.autoDetect = mql.matches ? 'dark' : 'light';
|
|
59
|
+
|
|
60
|
+
protected readonly forcedColorsMediaQueryListener = (mql: MediaQueryList|MediaQueryListEvent) => this.enabled = !mql.matches;
|
|
61
|
+
|
|
62
|
+
protected override createRenderRoot(): HTMLElement | ShadowRoot {
|
|
63
|
+
return this;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
protected getRealColorScheme(): ColorScheme {
|
|
67
|
+
if (this.activeColorScheme === 'auto') {
|
|
68
|
+
return this.autoDetect ?? 'light';
|
|
69
|
+
}
|
|
70
|
+
return this.activeColorScheme ?? 'light';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
protected override render(): TemplateResult | symbol {
|
|
74
|
+
return html`
|
|
75
|
+
<div class="btn-group">
|
|
76
|
+
<button
|
|
77
|
+
type="button"
|
|
78
|
+
class="btn btn-default"
|
|
79
|
+
title=${this.enabled ? this.toggleLabel : this.disabledLabel}
|
|
80
|
+
?disabled=${!this.enabled}
|
|
81
|
+
@click=${(e: Event) => this.toggle(e)}
|
|
82
|
+
>
|
|
83
|
+
<typo3-backend-icon identifier=${this.getIcon(this.activeColorScheme ?? 'auto')} size="small"></typo3-backend-icon>
|
|
84
|
+
${this.getLabel(this.getRealColorScheme())}
|
|
85
|
+
<typo3-backend-icon identifier="actions-exchange" size="small" style="margin-left: auto;"></typo3-backend-icon>
|
|
86
|
+
</button>
|
|
87
|
+
|
|
88
|
+
<button
|
|
89
|
+
type="button"
|
|
90
|
+
class="btn btn-default ${this.advancedOptionsExpanded ? 'active' : ''}"
|
|
91
|
+
aria-haspopup="true"
|
|
92
|
+
aria-expanded=${this.advancedOptionsExpanded ? 'true' : 'false'}
|
|
93
|
+
?disabled=${!this.enabled}
|
|
94
|
+
@click=${(e: Event) => { e.stopPropagation(); this.advancedOptionsExpanded = !this.advancedOptionsExpanded; }}
|
|
95
|
+
>
|
|
96
|
+
<span class="visually-hidden">Show more options</span>
|
|
97
|
+
<typo3-backend-icon identifier=${this.advancedOptionsExpanded ? 'actions-chevron-up' : 'actions-chevron-down'} size="small"></typo3-backend-icon>
|
|
98
|
+
</button>
|
|
99
|
+
</div>
|
|
100
|
+
${this.advancedOptionsExpanded === false ? nothing : html`
|
|
101
|
+
<ul class="dropdown-list">
|
|
102
|
+
${this.colorSchemes.map(item => this.renderItem(item))}
|
|
103
|
+
</ul>
|
|
104
|
+
`}
|
|
105
|
+
`;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
protected getIcon(colorScheme: ColorScheme): string {
|
|
109
|
+
return this.colorSchemes.find(cs => cs.value === colorScheme)?.icon ?? 'auto';
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
protected getLabel(colorScheme: ColorScheme): string {
|
|
113
|
+
return this.colorSchemes.find(cs => cs.value === colorScheme)?.label ?? '';
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
protected renderItem(colorScheme: ColorSchemeOption): TemplateResult | symbol {
|
|
117
|
+
return html`
|
|
118
|
+
<li>
|
|
119
|
+
<button class="dropdown-item" @click="${(e: Event) => this.handleClick(e, colorScheme.value)}" aria-current="${this.activeColorScheme === colorScheme.value ? 'true' : 'false'}">
|
|
120
|
+
<span class="dropdown-item-columns">
|
|
121
|
+
<span class="dropdown-item-column dropdown-item-column-icon" aria-hidden="true">
|
|
122
|
+
<typo3-backend-icon identifier="${colorScheme.icon}" size="small"></typo3-backend-icon>
|
|
123
|
+
</span>
|
|
124
|
+
<span class="dropdown-item-column dropdown-item-column-title">
|
|
125
|
+
${colorScheme.label}
|
|
126
|
+
${colorScheme.value === 'auto' ? html`<span class="dropdown-item-column-title-info">${this.getLabel(this.autoDetect)}</span>` : ''}
|
|
127
|
+
</span>
|
|
128
|
+
${this.activeColorScheme === colorScheme.value ? html`
|
|
129
|
+
<span class="text-primary">
|
|
130
|
+
<typo3-backend-icon identifier="actions-dot" size="small"></typo3-backend-icon>
|
|
131
|
+
</span>
|
|
132
|
+
` : html`
|
|
133
|
+
<typo3-backend-icon identifier="empty-empty" size="small"></typo3-backend-icon>
|
|
134
|
+
`}
|
|
135
|
+
</span>
|
|
136
|
+
</button>
|
|
137
|
+
</li>
|
|
138
|
+
`;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private async toggle(e: Event): Promise<void> {
|
|
142
|
+
e.preventDefault();
|
|
143
|
+
e.stopPropagation();
|
|
144
|
+
const currentColorScheme = this.getRealColorScheme();
|
|
145
|
+
let colorScheme: ColorScheme = currentColorScheme === 'dark' ? 'light' : 'dark';
|
|
146
|
+
if (colorScheme === this.autoDetect) {
|
|
147
|
+
// Set to auto if the user toggled to the
|
|
148
|
+
// OS default, that basically means user wants the color
|
|
149
|
+
// scheme to match the current system theme
|
|
150
|
+
colorScheme = 'auto';
|
|
151
|
+
}
|
|
152
|
+
this.triggerSchemeUpdate(colorScheme);
|
|
153
|
+
await this.persistSchemeUpdate(colorScheme);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
private async handleClick(e: Event, value: ColorScheme): Promise<void> {
|
|
157
|
+
e.preventDefault();
|
|
158
|
+
e.stopPropagation();
|
|
159
|
+
this.triggerSchemeUpdate(value);
|
|
160
|
+
await this.persistSchemeUpdate(value);
|
|
161
|
+
this.advancedOptionsExpanded = false;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
private async persistSchemeUpdate(colorScheme: ColorScheme) {
|
|
165
|
+
const url = new URL(TYPO3.settings.ajaxUrls.color_scheme_update, window.location.origin);
|
|
166
|
+
|
|
167
|
+
return await new AjaxRequest(url).post({ colorScheme });
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private triggerSchemeUpdate(colorScheme: ColorScheme): void {
|
|
171
|
+
document.dispatchEvent(new CustomEvent<ColorSchemeUpdateEventData>('typo3:color-scheme:update', { detail: { colorScheme } }));
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
declare global {
|
|
176
|
+
interface HTMLElementTagNameMap {
|
|
177
|
+
'typo3-backend-color-scheme-switch': ColorSchemeSwitchElement;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of the TYPO3 CMS project.
|
|
3
|
+
*
|
|
4
|
+
* It is free software; you can redistribute it and/or modify it under
|
|
5
|
+
* the terms of the GNU General Public License, either version 2
|
|
6
|
+
* of the License, or any later version.
|
|
7
|
+
*
|
|
8
|
+
* For the full copyright and license information, please read the
|
|
9
|
+
* LICENSE.txt file that was distributed with this source code.
|
|
10
|
+
*
|
|
11
|
+
* The TYPO3 project - inspiring people to share!
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { customElement, property } from 'lit/decorators';
|
|
15
|
+
import { PseudoButtonLitElement } from '@typo3/backend/element/pseudo-button';
|
|
16
|
+
import { SeverityEnum } from '@typo3/backend/enum/severity';
|
|
17
|
+
import { default as Modal, type ModalElement } from '@typo3/backend/modal';
|
|
18
|
+
import { lll } from '@typo3/core/lit-helper';
|
|
19
|
+
import AjaxRequest from '@typo3/core/ajax/ajax-request';
|
|
20
|
+
import type { AjaxResponse } from '@typo3/core/ajax/ajax-response';
|
|
21
|
+
import Notification from '@typo3/backend/notification';
|
|
22
|
+
|
|
23
|
+
enum Selectors {
|
|
24
|
+
columnsSelector = '.t3js-column-selector',
|
|
25
|
+
columnsContainerSelector = '.t3js-column-selector-container',
|
|
26
|
+
columnsFilterSelector = 'input[name="columns-filter"]',
|
|
27
|
+
columnsSelectorActionsSelector = '.t3js-column-selector-actions'
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
enum SelectorActions {
|
|
31
|
+
toggle = 'select-toggle',
|
|
32
|
+
all = 'select-all',
|
|
33
|
+
none = 'select-none'
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Module: @typo3/backend/column-selector-button
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* <typo3-backend-column-selector-button
|
|
41
|
+
* class="btn btn-default"
|
|
42
|
+
* data-url="/url/to/column/selector/form"
|
|
43
|
+
* data-target="/url/to/go/after/column/selection"
|
|
44
|
+
* data-title="Show columns"
|
|
45
|
+
* data-button-ok="Update"
|
|
46
|
+
* data-button-close="Cancel"
|
|
47
|
+
* data-error-message="Error"
|
|
48
|
+
* >
|
|
49
|
+
* Show columns
|
|
50
|
+
* </typo3-backend-column-selector-button>
|
|
51
|
+
*/
|
|
52
|
+
@customElement('typo3-backend-column-selector-button')
|
|
53
|
+
export class ColumnSelectorButton extends PseudoButtonLitElement {
|
|
54
|
+
@property({ type: String, attribute: 'data-url' }) modalUrl: string;
|
|
55
|
+
@property({ type: String, attribute: 'data-target' }) modalTarget: string;
|
|
56
|
+
@property({ type: String, attribute: 'data-title' }) modalTitle: string = 'Show columns';
|
|
57
|
+
@property({ type: String, attribute: 'data-button-ok' }) buttonOk: string = lll('button.ok') || 'Update';
|
|
58
|
+
@property({ type: String, attribute: 'data-button-close' }) buttonClose: string = lll('button.close') || 'Close';
|
|
59
|
+
@property({ type: String, attribute: 'data-error-message' }) errorMessage: string = 'Could not update columns';
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Toggle selector actions state (enabled or disabled) depending
|
|
63
|
+
* on the columns state (checked, unchecked, displayed or hidden)
|
|
64
|
+
*
|
|
65
|
+
* @param columns The columns
|
|
66
|
+
* @param selectAll The "select all" action button
|
|
67
|
+
* @param selectNone The "select none" action button
|
|
68
|
+
* @param initialize Whether this is the initialize call - don't check hidden
|
|
69
|
+
* state as all columns are displayed on initialization
|
|
70
|
+
* @private
|
|
71
|
+
*/
|
|
72
|
+
private static toggleSelectorActions(
|
|
73
|
+
columns: NodeListOf<HTMLInputElement>,
|
|
74
|
+
selectAll: HTMLButtonElement,
|
|
75
|
+
selectNone: HTMLButtonElement,
|
|
76
|
+
initialize: boolean = false
|
|
77
|
+
) {
|
|
78
|
+
selectAll.classList.add('disabled');
|
|
79
|
+
for (let i = 0; i < columns.length; i++) {
|
|
80
|
+
if (!columns[i].disabled
|
|
81
|
+
&& !columns[i].checked
|
|
82
|
+
&& (initialize || !ColumnSelectorButton.isColumnHidden(columns[i]))
|
|
83
|
+
) {
|
|
84
|
+
selectAll.classList.remove('disabled');
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
selectNone.classList.add('disabled');
|
|
89
|
+
for (let i = 0; i < columns.length; i++) {
|
|
90
|
+
if (!columns[i].disabled
|
|
91
|
+
&& columns[i].checked
|
|
92
|
+
&& (initialize || !ColumnSelectorButton.isColumnHidden(columns[i]))
|
|
93
|
+
) {
|
|
94
|
+
selectNone.classList.remove('disabled');
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Check if the given column is hidden by looking at it's container element
|
|
102
|
+
*
|
|
103
|
+
* @param column The column to check for
|
|
104
|
+
* @private
|
|
105
|
+
*/
|
|
106
|
+
private static isColumnHidden(column: HTMLInputElement): boolean {
|
|
107
|
+
return column.closest(Selectors.columnsContainerSelector)?.classList.contains('hidden');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Check each column if it matches the current search term.
|
|
112
|
+
* If not, hide its outer container to not break the grid.
|
|
113
|
+
*
|
|
114
|
+
* @param columnsFilter The columns filter
|
|
115
|
+
* @param columns The columns to check
|
|
116
|
+
* @private
|
|
117
|
+
*/
|
|
118
|
+
private static filterColumns(columnsFilter: HTMLInputElement, columns: NodeListOf<HTMLInputElement>): void {
|
|
119
|
+
columns.forEach((column: HTMLInputElement) => {
|
|
120
|
+
const columnContainer: HTMLDivElement = column.closest(Selectors.columnsContainerSelector);
|
|
121
|
+
if (!column.disabled && columnContainer !== null) {
|
|
122
|
+
const filterValue: string = columnContainer.querySelector('.form-check-label')?.textContent;
|
|
123
|
+
if (filterValue && filterValue.length) {
|
|
124
|
+
columnContainer.classList.toggle(
|
|
125
|
+
'hidden',
|
|
126
|
+
columnsFilter.value !== '' && !RegExp(columnsFilter.value, 'i').test(
|
|
127
|
+
filterValue.trim().replace(/\[\]/g, '').replace(/\s+/g, ' ')
|
|
128
|
+
)
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
protected override buttonActivated(): void {
|
|
136
|
+
this.showColumnSelectorModal();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private showColumnSelectorModal(): void {
|
|
140
|
+
if (!this.modalUrl || !this.modalTarget) {
|
|
141
|
+
// Don't render modal in case no url or target is given
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const modal = Modal.advanced({
|
|
146
|
+
content: this.modalUrl,
|
|
147
|
+
title: this.modalTitle,
|
|
148
|
+
severity: SeverityEnum.notice,
|
|
149
|
+
size: Modal.sizes.medium,
|
|
150
|
+
type: Modal.types.ajax,
|
|
151
|
+
buttons: [
|
|
152
|
+
{
|
|
153
|
+
text: this.buttonClose,
|
|
154
|
+
active: true,
|
|
155
|
+
btnClass: 'btn-default',
|
|
156
|
+
name: 'cancel',
|
|
157
|
+
trigger: (e: Event, modal: ModalElement): void => modal.hideModal()
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
text: this.buttonOk,
|
|
161
|
+
btnClass: 'btn-primary',
|
|
162
|
+
name: 'update',
|
|
163
|
+
trigger: (e: Event, modal: ModalElement): void => this.processSelection(modal)
|
|
164
|
+
}
|
|
165
|
+
],
|
|
166
|
+
ajaxCallback: (): void => this.handleModalContentLoaded(modal)
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private processSelection(currentModal: HTMLElement): void {
|
|
171
|
+
const form: HTMLFormElement = currentModal.querySelector('form') as HTMLFormElement;
|
|
172
|
+
if (form === null) {
|
|
173
|
+
this.abortSelection();
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
(new AjaxRequest(TYPO3.settings.ajaxUrls.show_columns))
|
|
177
|
+
.post(new FormData(form))
|
|
178
|
+
.then(async (response: AjaxResponse): Promise<void> => {
|
|
179
|
+
const data = await response.resolve();
|
|
180
|
+
if (data.success === true) {
|
|
181
|
+
// @todo This does not jump to the anchor (#t3-table-some_table) after the reload!!!
|
|
182
|
+
this.ownerDocument.location.href = this.modalTarget;
|
|
183
|
+
this.ownerDocument.location.reload();
|
|
184
|
+
} else {
|
|
185
|
+
Notification.error(data.message || 'No update was performed');
|
|
186
|
+
}
|
|
187
|
+
Modal.dismiss();
|
|
188
|
+
})
|
|
189
|
+
.catch(() => {
|
|
190
|
+
this.abortSelection();
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
private handleModalContentLoaded(currentModal: HTMLElement): void {
|
|
195
|
+
const form: HTMLFormElement = currentModal.querySelector('form') as HTMLFormElement;
|
|
196
|
+
if (form === null) {
|
|
197
|
+
// Early return if modal content does not include a form
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
// Prevent the form from being submitted as the form data will be send via an ajax request
|
|
201
|
+
form.addEventListener('submit', (e: Event): void => { e.preventDefault(); });
|
|
202
|
+
|
|
203
|
+
const columns: NodeListOf<HTMLInputElement> = currentModal.querySelectorAll(Selectors.columnsSelector);
|
|
204
|
+
const columnsFilter: HTMLInputElement = currentModal.querySelector(Selectors.columnsFilterSelector);
|
|
205
|
+
const columnsSelectorActions: HTMLDivElement = currentModal.querySelector(Selectors.columnsSelectorActionsSelector);
|
|
206
|
+
const selectAll: HTMLButtonElement = columnsSelectorActions.querySelector('button[data-action="' + SelectorActions.all + '"]');
|
|
207
|
+
const selectNone: HTMLButtonElement = columnsSelectorActions.querySelector('button[data-action="' + SelectorActions.none + '"]');
|
|
208
|
+
|
|
209
|
+
if (!columns.length || columnsFilter === null || selectAll === null || selectNone === null) {
|
|
210
|
+
// Return in case required elements do not exist in the modal content
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// First initialize select-all / select-none buttons
|
|
215
|
+
ColumnSelectorButton.toggleSelectorActions(columns, selectAll, selectNone, true);
|
|
216
|
+
|
|
217
|
+
// Add event listener for each column to toggle the selector actions after change
|
|
218
|
+
columns.forEach((column: HTMLInputElement) => {
|
|
219
|
+
column.addEventListener('change', (): void => {
|
|
220
|
+
ColumnSelectorButton.toggleSelectorActions(columns, selectAll, selectNone);
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// Add event listener for keydown event for the columns filter, so we
|
|
225
|
+
// can catch the "Escape" key, which would otherwise close the modal.
|
|
226
|
+
columnsFilter.addEventListener('keydown', (e: KeyboardEvent): void => {
|
|
227
|
+
const target = e.target as HTMLInputElement;
|
|
228
|
+
if (e.code === 'Escape') {
|
|
229
|
+
e.stopImmediatePropagation();
|
|
230
|
+
target.value = '';
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// Add event listener for keydown event for the columns filter, allowing the "live filtering"
|
|
235
|
+
columnsFilter.addEventListener('keyup', (e: KeyboardEvent): void => {
|
|
236
|
+
ColumnSelectorButton.filterColumns(e.target as HTMLInputElement, columns);
|
|
237
|
+
ColumnSelectorButton.toggleSelectorActions(columns, selectAll, selectNone);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
// Catch browser specific "search" event, triggered on clicking the "clear" button
|
|
241
|
+
columnsFilter.addEventListener('search', (e: Event): void => {
|
|
242
|
+
ColumnSelectorButton.filterColumns(e.target as HTMLInputElement, columns);
|
|
243
|
+
ColumnSelectorButton.toggleSelectorActions(columns, selectAll, selectNone);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
// Add event listener for all columns select actions. querySelectorAll will return
|
|
247
|
+
// at least two actions (selectAll and selectNone) which we checked above already
|
|
248
|
+
columnsSelectorActions.querySelectorAll('button[data-action]').forEach((action: HTMLButtonElement) => {
|
|
249
|
+
action.addEventListener('click', (e: Event): void => {
|
|
250
|
+
e.preventDefault();
|
|
251
|
+
|
|
252
|
+
const target: HTMLButtonElement = e.currentTarget as HTMLButtonElement;
|
|
253
|
+
if (!target.dataset.action) {
|
|
254
|
+
// Return if we don't deal with a valid action (No action defined)
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Perform requested action
|
|
259
|
+
switch (target.dataset.action) {
|
|
260
|
+
case SelectorActions.toggle:
|
|
261
|
+
columns.forEach((column: HTMLInputElement) => {
|
|
262
|
+
if (!column.disabled && !ColumnSelectorButton.isColumnHidden(column)) {
|
|
263
|
+
column.checked = !column.checked;
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
break;
|
|
267
|
+
case SelectorActions.all:
|
|
268
|
+
columns.forEach((column: HTMLInputElement) => {
|
|
269
|
+
if (!column.disabled && !ColumnSelectorButton.isColumnHidden(column)) {
|
|
270
|
+
column.checked = true;
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
break;
|
|
274
|
+
case SelectorActions.none:
|
|
275
|
+
columns.forEach((column: HTMLInputElement) => {
|
|
276
|
+
if (!column.disabled && !ColumnSelectorButton.isColumnHidden(column)) {
|
|
277
|
+
column.checked = false;
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
break;
|
|
281
|
+
default:
|
|
282
|
+
// Unknown action
|
|
283
|
+
Notification.warning('Unknown selector action');
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// After performing the action always toggle selector actions
|
|
287
|
+
ColumnSelectorButton.toggleSelectorActions(columns, selectAll, selectNone);
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
private abortSelection(): void {
|
|
293
|
+
Notification.error(this.errorMessage);
|
|
294
|
+
Modal.dismiss();
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
declare global {
|
|
299
|
+
interface HTMLElementTagNameMap {
|
|
300
|
+
'typo3-backend-column-selector-button': ColumnSelectorButton;
|
|
301
|
+
}
|
|
302
|
+
}
|