typo3-typescript-sources 14.2.0 → 14.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/.github/workflows/sync-and-publish.yml +6 -6
  2. package/.last-synced-tag +1 -1
  3. package/README.md +1 -1
  4. package/backend/clear-cache.ts +7 -7
  5. package/backend/clipboard-panel.ts +20 -17
  6. package/backend/color-picker.ts +44 -36
  7. package/backend/context-menu-actions.ts +7 -7
  8. package/backend/date-time-picker.ts +38 -16
  9. package/backend/element/contextual-record-edit-trigger.ts +4 -2
  10. package/backend/element/editable-page-title.ts +17 -14
  11. package/backend/form-engine/container/inline-control-container.ts +2 -1
  12. package/backend/form-engine/element/datetime-element.ts +1 -1
  13. package/{styleguide/filter.ts → backend/layout-module/page-layout-event.ts} +8 -8
  14. package/backend/layout-module/page-layout.ts +102 -0
  15. package/backend/layout-module/toggle-hidden-element.ts +126 -0
  16. package/backend/layout-module/velocity-scroll.ts +123 -0
  17. package/backend/live-search/live-search.ts +2 -2
  18. package/backend/modal.ts +79 -4
  19. package/backend/page-wizard/helper/wizard-helper.ts +5 -2
  20. package/backend/security/element/csp-reports.ts +1 -6
  21. package/backend/settings/editor/editable-setting.ts +3 -8
  22. package/backend/settings/type/base.ts +1 -1
  23. package/{setup → backend}/setup-module.ts +3 -3
  24. package/backend/toolbar/clear-cache-menu.ts +11 -4
  25. package/backend/tree/page-position-select.ts +52 -41
  26. package/backend/tree/tree.ts +27 -6
  27. package/dashboard/dashboard.ts +0 -3
  28. package/form/backend/form-editor/inspector-component.ts +1 -1
  29. package/form/backend/form-editor/stage-component.ts +3 -3
  30. package/form/backend/form-manager/view-model.ts +15 -13
  31. package/linkvalidator/linkvalidator.ts +13 -46
  32. package/package.json +2 -2
  33. package/workspaces/renderable/record-table.ts +1 -1
  34. package/backend/page-actions.ts +0 -91
@@ -87,6 +87,24 @@ export class TreeNodeMap<T extends TreeNodeInterface = TreeNodeInterface> {
87
87
  }
88
88
  }
89
89
 
90
+ export class TreeFilterAppliedEvent extends CustomEvent<{searchTerm: string, resultCount: number}> {
91
+ static readonly eventName = 'typo3:tree:filter-applied';
92
+ constructor(searchTerm: string, resultCount: number) {
93
+ super(TreeFilterAppliedEvent.eventName, {
94
+ detail: { searchTerm, resultCount },
95
+ bubbles: true,
96
+ composed: true,
97
+ });
98
+ }
99
+ }
100
+
101
+ export class TreeFilterResetEvent extends Event {
102
+ static readonly eventName = 'typo3:tree:filter-reset';
103
+ constructor() {
104
+ super(TreeFilterResetEvent.eventName, { bubbles: true, composed: true });
105
+ }
106
+ }
107
+
90
108
  export class Tree extends LitElement {
91
109
  @property({ type: Object }) setup?: {[keys: string]: any} = null;
92
110
  @state() settings: TreeSettings = {
@@ -474,22 +492,25 @@ export class Tree extends LitElement {
474
492
  }).then(() => {
475
493
  this.loading = false;
476
494
  this.currentFilterRequest = null;
495
+ this.dispatchEvent(new TreeFilterAppliedEvent(this.searchTerm, this.searchResults));
477
496
  });
478
497
  } else {
479
498
  // restore original state without filters
480
- this.resetFilter();
481
- this.loading = false;
499
+ this.resetFilter().then(() => {
500
+ this.loading = false;
501
+ this.dispatchEvent(new TreeFilterResetEvent());
502
+ });
482
503
  }
483
504
  }
484
505
 
485
- public resetFilter(): void
506
+ public async resetFilter(): Promise<void>
486
507
  {
487
508
  this.searchTerm = '';
488
509
  this.searchResults = 0;
489
510
  if (this.unfilteredNodes.length > 0) {
490
511
  const currentlySelected = this.getSelectedNodes()[0];
491
512
  if (typeof currentlySelected === 'undefined') {
492
- this.loadData();
513
+ await this.loadData();
493
514
  return;
494
515
  }
495
516
  this.nodeMap = new TreeNodeMap(this.enhanceNodes(JSON.parse(this.unfilteredNodes)));
@@ -499,10 +520,10 @@ export class Tree extends LitElement {
499
520
  if (currentlySelectedNode) {
500
521
  this.selectNode(currentlySelectedNode, false);
501
522
  } else {
502
- this.loadData();
523
+ await this.loadData();
503
524
  }
504
525
  } else {
505
- this.loadData();
526
+ await this.loadData();
506
527
  }
507
528
  }
508
529
 
@@ -1578,7 +1578,4 @@ declare global {
1578
1578
 
1579
1579
  [newRecordWizardEventName]: CustomEvent<NewRecordWizardItemSelectedEventInterface>;
1580
1580
  }
1581
- interface FocusOptions {
1582
- focusVisible: boolean;
1583
- }
1584
1581
  }
@@ -1821,10 +1821,10 @@ export function renderRequiredValidatorEditor(
1821
1821
  getCurrentlySelectedFormElement().set(propertyPath, propertyValue);
1822
1822
  }
1823
1823
  } else {
1824
- getPublisherSubscriber().publish('view/inspector/removeCollectionElement/perform', [validatorIdentifier, 'validators']);
1825
1824
  if (getUtility().isNonEmptyString(propertyPath)) {
1826
1825
  getCurrentlySelectedFormElement().unset(propertyPath);
1827
1826
  }
1827
+ getPublisherSubscriber().publish('view/inspector/removeCollectionElement/perform', [validatorIdentifier, 'validators']);
1828
1828
  propertyData = getCurrentlySelectedFormElement().get(validationErrorMessagePropertyPath);
1829
1829
  if (getUtility().isUndefinedOrNull(propertyData)) { propertyData = []; }
1830
1830
  getCurrentlySelectedFormElement().set(validationErrorMessagePropertyPath, renewValidationErrorMessages(
@@ -583,7 +583,7 @@ function wireAbstractViewFormElementToolbarEventListeners(toolbar: HTMLElement,
583
583
  }
584
584
 
585
585
  qs('abstractViewToolbarRemoveElement')?.addEventListener('click', function() {
586
- getViewModel().showRemoveFormElementModal();
586
+ getViewModel().showRemoveFormElementModal(formElement);
587
587
  });
588
588
  }
589
589
 
@@ -631,7 +631,7 @@ export function createAndAddAbstractViewFormElementToolbar(
631
631
  });
632
632
 
633
633
  toolbar.addEventListener('toolbar-remove-element', () => {
634
- getViewModel().showRemoveFormElementModal();
634
+ getViewModel().showRemoveFormElementModal(formElement);
635
635
  });
636
636
  }
637
637
 
@@ -908,7 +908,7 @@ export function renderFormElementStageItem(formElement: FormElement, template: H
908
908
  });
909
909
 
910
910
  stageItem.addEventListener('toolbar-remove-element', () => {
911
- getViewModel().showRemoveFormElementModal();
911
+ getViewModel().showRemoveFormElementModal(formElement);
912
912
  });
913
913
 
914
914
  template.replaceChildren(stageItem);
@@ -39,19 +39,21 @@ enum Identifiers {
39
39
  }
40
40
 
41
41
  function newFormSetup(formManagerApp: FormManager): void {
42
- const newFormModalTrigger: HTMLElement = document.querySelector<HTMLElement>(Identifiers.newFormModalTrigger);
43
- newFormModalTrigger.addEventListener('click', async (): Promise<void> => {
44
- await topLevelModuleImport('@typo3/form/backend/form-wizard/form-wizard.js');
45
- const content = html`<typo3-backend-form-wizard .formManager="${formManagerApp}"
46
- ></typo3-backend-form-wizard>`;
47
-
48
- Modal.advanced({
49
- title: formManagerLabels.get('formManager.newFormWizard.step1.title'),
50
- content: content,
51
- severity: SeverityEnum.notice,
52
- size: Modal.sizes.medium,
53
- staticBackdrop: true,
54
- buttons: []
42
+ document.querySelectorAll<HTMLElement>(Identifiers.newFormModalTrigger).forEach((element: HTMLElement): void => {
43
+ element.addEventListener('click', async (e: Event): Promise<void> => {
44
+ e.preventDefault();
45
+ await topLevelModuleImport('@typo3/form/backend/form-wizard/form-wizard.js');
46
+ const content = html`<typo3-backend-form-wizard .formManager="${formManagerApp}"
47
+ ></typo3-backend-form-wizard>`;
48
+
49
+ Modal.advanced({
50
+ title: formManagerLabels.get('formManager.newFormWizard.step1.title'),
51
+ content: content,
52
+ severity: SeverityEnum.notice,
53
+ size: Modal.sizes.medium,
54
+ staticBackdrop: true,
55
+ buttons: []
56
+ });
55
57
  });
56
58
  });
57
59
  }
@@ -13,22 +13,17 @@
13
13
 
14
14
  import DocumentService from '@typo3/core/document-service';
15
15
  import Notification from '@typo3/backend/notification';
16
+ import { ProgressBarElement } from '@typo3/backend/element/progress-bar-element';
16
17
  import RegularEvent from '@typo3/core/event/regular-event';
17
18
  import SortableTable from '@typo3/backend/sortable-table';
18
19
 
19
20
  enum Selectors {
20
- // Check
21
- linktypesSelectorCheck = '.t3js-linkvalidator-settings input[type="checkbox"].options-by-type-check',
22
21
  actionButtonSelectorCheck = '.t3js-linkvalidator-action-button-check',
23
-
24
- // Report
25
- toggleAllLinktypesSelectorReport = '.t3js-linkvalidator-settings input[type="checkbox"].options-by-type-toggle-all-report',
26
- linktypesSelectorReport = '.t3js-linkvalidator-settings input[type="checkbox"].options-by-type-report',
27
- actionButtonSelectorReport = '.t3js-linkvalidator-action-button-report'
22
+ actionButtonSelectorReport = '.t3js-linkvalidator-action-button-report',
23
+ reportTable = '.t3js-linkvalidator-report-table',
28
24
  }
29
25
 
30
26
  enum Identifier {
31
- toggleAllLinktypesIdReport = 'options-by-type-toggle-all-report',
32
27
  brokenLinksTableIdReport = 'typo3-broken-links-table'
33
28
  }
34
29
 
@@ -36,6 +31,8 @@ enum Identifier {
36
31
  * Module: @typo3/linkvalidator/linkvalidator
37
32
  */
38
33
  class Linkvalidator {
34
+ private progressBar: ProgressBarElement | null = null;
35
+
39
36
  constructor() {
40
37
  DocumentService.ready().then((): void => {
41
38
  const linkList = document.getElementById(Identifier.brokenLinksTableIdReport);
@@ -49,51 +46,21 @@ class Linkvalidator {
49
46
  this.initializeEvents();
50
47
  }
51
48
 
52
- private static allCheckBoxesAreChecked(checkBoxes: NodeListOf<HTMLInputElement>): boolean {
53
- const checkboxArray = Array.from(checkBoxes);
54
- return checkBoxes.length === checkboxArray.filter((checkBox: HTMLInputElement) => checkBox.checked).length;
55
- }
56
-
57
- private toggleActionButtonReport(): void {
58
- document.querySelector(Selectors.actionButtonSelectorReport)?.toggleAttribute(
59
- 'disabled',
60
- !document.querySelectorAll('input[type="checkbox"]:checked').length
61
- );
62
- }
63
-
64
- /**
65
- * Enables the "Toggle all" checkbox on document load if all child checkboxes are checked
66
- */
67
- private toggleTriggerCheckBoxReport(): void {
68
- const checkBoxes: NodeListOf<HTMLInputElement> = document.querySelectorAll(Selectors.linktypesSelectorReport);
69
- (document.getElementById(Identifier.toggleAllLinktypesIdReport) as HTMLInputElement).checked = Linkvalidator.allCheckBoxesAreChecked(checkBoxes);
49
+ private getProgress(): ProgressBarElement {
50
+ if (!this.progressBar || !this.progressBar.isConnected) {
51
+ this.progressBar = document.createElement('typo3-backend-progress-bar');
52
+ document.querySelector(Selectors.reportTable).prepend(this.progressBar);
53
+ }
54
+ return this.progressBar;
70
55
  }
71
56
 
72
57
  private initializeEvents(): void {
73
- // toggleAll (checkboxes): on change
74
- new RegularEvent('change', (e: Event, currentTarget: HTMLInputElement): void => {
75
- const checkBoxes: NodeListOf<HTMLInputElement> = document.querySelectorAll(Selectors.linktypesSelectorReport);
76
- const checkIt = !Linkvalidator.allCheckBoxesAreChecked(checkBoxes);
77
-
78
- checkBoxes.forEach((checkBox: HTMLInputElement): void => {
79
- checkBox.checked = checkIt;
80
- });
81
- currentTarget.checked = checkIt;
82
- this.toggleActionButtonReport();
83
- }).delegateTo(document, Selectors.toggleAllLinktypesSelectorReport);
84
-
85
- // toggle (checkbox): on change
86
- new RegularEvent('change', (): void => {
87
- this.toggleTriggerCheckBoxReport();
88
- this.toggleActionButtonReport();
89
- }).delegateTo(document, Selectors.linktypesSelectorReport);
90
-
91
58
  new RegularEvent('click', (e: PointerEvent, actionButton: HTMLInputElement): void => {
92
59
  Notification.success(actionButton.dataset.notificationMessage || 'Event triggered', '', 2);
93
60
  }).delegateTo(document, Selectors.actionButtonSelectorCheck);
94
61
 
95
- new RegularEvent('click', (e: PointerEvent, actionButton: HTMLInputElement): void => {
96
- Notification.success(actionButton.dataset.notificationMessage || 'Event triggered', '', 2);
62
+ new RegularEvent('click', (): void => {
63
+ this.getProgress().start();
97
64
  }).delegateTo(document, Selectors.actionButtonSelectorReport);
98
65
  }
99
66
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typo3-typescript-sources",
3
- "version": "14.2.0",
3
+ "version": "14.3.1",
4
4
  "description": "TYPO3 Core TypeScript Sources - Extracted from TYPO3/typo3 repository",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -28,7 +28,7 @@
28
28
  },
29
29
  "typo3": {
30
30
  "sourceRepository": "https://github.com/TYPO3/typo3",
31
- "sourceTag": "v14.2.0",
31
+ "sourceTag": "v14.3.1",
32
32
  "sourcePath": "Build/Sources/TypeScript"
33
33
  }
34
34
  }
@@ -89,7 +89,7 @@ export class RecordTableElement extends LitElement {
89
89
  <thead>
90
90
  <tr>
91
91
  <th>
92
- <div class="btn-group dropdown">
92
+ <div class="dropdown">
93
93
  <button type="button" class="dropdown-toggle dropdown-toggle-link t3js-multi-record-selection-check-actions-toggle" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false" aria-label="${coreLabels.get('labels.openSelectionOptions')}">
94
94
  <typo3-backend-icon identifier="actions-selection" size="small"></typo3-backend-icon>
95
95
  </button>
@@ -1,91 +0,0 @@
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 DocumentService from '@typo3/core/document-service';
15
- import RegularEvent from '@typo3/core/event/regular-event';
16
- import PersistentStorage from './storage/persistent';
17
-
18
- enum IdentifierEnum {
19
- hiddenElements = '.t3js-hidden-record',
20
- }
21
-
22
- /**
23
- * Module: @typo3/backend/page-actions
24
- * JavaScript implementations for page actions
25
- */
26
- class PageActions {
27
- constructor() {
28
- DocumentService.ready().then((): void => {
29
- const pageLayoutToggleShowHidden = document.getElementById('pageLayoutToggleShowHidden') as HTMLButtonElement|null;
30
- if (pageLayoutToggleShowHidden !== null) {
31
- new RegularEvent('click', this.toggleContentElementVisibility).bindTo(pageLayoutToggleShowHidden);
32
- }
33
- });
34
- }
35
-
36
- /**
37
- * Toggles the "Show hidden content elements"
38
- */
39
- private toggleContentElementVisibility(e: Event): void {
40
- const me = e.target as HTMLButtonElement;
41
- const hiddenElements = document.querySelectorAll(IdentifierEnum.hiddenElements) as NodeListOf<HTMLElement>;
42
- const show = me.dataset.dropdowntoggleStatus !== 'active';
43
- me.disabled = true;
44
-
45
- for (const hiddenElement of hiddenElements) {
46
- hiddenElement.style.display = 'flow-root';
47
- const scrollHeight = hiddenElement.scrollHeight;
48
-
49
- // Always set `overflow: clip` after storing scrollHeight
50
- // * For hidden state `height: 0px` is already set.
51
- // * For visible state setting `overflow: clip` is fine anyway.
52
- hiddenElement.style.overflow = 'clip';
53
-
54
- if (!show) {
55
- // * Invisible elements must not be accessible/focusable by keyboard.
56
- // * Spacing between content elements is kept uniform by collapsed margins,
57
- // hidden elements have a height of 0 and the margins of the surrounding elements
58
- // cannot collapse, causing a visual gap.
59
- // Therefore do not display the element at all by setting `display: none`.
60
- hiddenElement.addEventListener('transitionend', (): void => {
61
- hiddenElement.style.display = 'none';
62
- hiddenElement.style.overflow = '';
63
- }, { once: true });
64
-
65
- // We use requestAnimationFrame() as we have to set the container's height at first before resizing to
66
- // collapsed-element-height. This results in a smooth animation.
67
- requestAnimationFrame(function() {
68
- hiddenElement.style.height = scrollHeight + 'px';
69
- requestAnimationFrame(function() {
70
- hiddenElement.style.height = 0 + 'px';
71
- });
72
- });
73
- } else {
74
- hiddenElement.addEventListener('transitionend', (): void => {
75
- hiddenElement.style.display = '';
76
- hiddenElement.style.overflow = '';
77
- hiddenElement.style.height = '';
78
- }, { once: true });
79
-
80
- hiddenElement.style.height = scrollHeight + 'px';
81
- }
82
- }
83
-
84
- me.dataset.dropdowntoggleStatus = show ? 'active' : 'inactive';
85
- PersistentStorage.set('moduleData.web_layout.showHidden', show ? '1' : '0').then((): void => {
86
- me.disabled = false;
87
- });
88
- }
89
- }
90
-
91
- export default new PageActions();