typo3-typescript-sources 13.4.32 → 13.4.34

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 CHANGED
@@ -1 +1 @@
1
- v13.4.32
1
+ v13.4.34
package/README.md CHANGED
@@ -16,7 +16,7 @@ npm install typo3-typescript-sources
16
16
 
17
17
  - **Original Repository:** [TYPO3/typo3](https://github.com/TYPO3/typo3)
18
18
  - **Source Path:** `Build/Sources/TypeScript/`
19
- - **Current TYPO3 Version:** `v13.4.32`
19
+ - **Current TYPO3 Version:** `v13.4.34`
20
20
 
21
21
  ## 🌿 Branches
22
22
 
@@ -88,7 +88,7 @@ class SlugElement {
88
88
  }
89
89
 
90
90
  private registerEvents(): void {
91
- const fieldsToListenOnList = Object.values(this.getAvailableFieldsForProposalGeneration()).map((field: HTMLElement) => `[id="${field.id}"]`);
91
+ const fieldsToListenOnList = Object.values(this.getAvailableFieldsForProposalGeneration()).map((field: HTMLElement) => field.dataset.slugSelector);
92
92
  const recreateButton: HTMLButtonElement = this.fullElement.querySelector(Selectors.recreateButton);
93
93
 
94
94
  // Listen on 'listenerFieldNames' for new pages. This is typically the 'title' field
@@ -217,12 +217,20 @@ class SlugElement {
217
217
  private getAvailableFieldsForProposalGeneration(): { [key: string]: HTMLElement } {
218
218
  const availableFields: { [key: string]: HTMLElement } = {};
219
219
  for (const [fieldName, selector] of Object.entries(this.fieldsToListenOn)) {
220
- let field = document.querySelector('[data-formengine-input-name="' + selector + '"]') as HTMLElement;
221
- if (field === null) {
220
+ const selectorCandidates = [
221
+ '[data-formengine-input-name="' + selector + '"]',
222
222
  // Also check for fields, which do not point to a hidden input field (e.g. "input type=hidden", readOnly, or select fields)
223
- field = document.querySelector('[name="' + selector + '"]') as HTMLElement;
224
- }
223
+ '[name="' + selector + '"]'
224
+ ];
225
+ let field: HTMLElement;
226
+ let usedSelector = '';
227
+ selectorCandidates.some((testSelector: string) => {
228
+ field = document.querySelector(testSelector) as HTMLElement;
229
+ usedSelector = testSelector;
230
+ return field !== null;
231
+ });
225
232
  if (field !== null) {
233
+ field.dataset.slugSelector = usedSelector;
226
234
  availableFields[fieldName] = field;
227
235
  }
228
236
  }
@@ -66,6 +66,13 @@ export class StringlistTypeElement extends BaseElement<string[]> {
66
66
 
67
67
  protected override render(): TemplateResult {
68
68
  const value = this.value || [];
69
+ if (value.length === 0) {
70
+ return html`
71
+ <button id=${this.formid} class="btn btn-default" type="button" ?disabled=${this.readonly} @click=${() => this.addValue(0)}>
72
+ <typo3-backend-icon identifier="actions-plus" size="small"></typo3-backend-icon>
73
+ </button>
74
+ `;
75
+ }
69
76
  return html`
70
77
  <div class="form-control-wrap">
71
78
  <div class="table-fit">
@@ -0,0 +1,90 @@
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 { StringlistTypeElement } from '@typo3/backend/settings/type/stringlist.js';
15
+ import { expect } from '@open-wc/testing';
16
+ import type { } from 'mocha';
17
+
18
+ describe('@typo3/backend/settings/type/stringlist', () => {
19
+ let root: HTMLElement;
20
+
21
+ beforeEach((): void => {
22
+ root = document.createElement('div');
23
+ document.body.appendChild(root);
24
+ });
25
+
26
+ afterEach((): void => {
27
+ root.remove();
28
+ root = null;
29
+ });
30
+
31
+ it('renders one button when the value list is empty', async () => {
32
+ const element = new StringlistTypeElement;
33
+ element.formid = 'setting-test';
34
+ element.value = [];
35
+ root.appendChild(element);
36
+ await new Promise((resolve) => setTimeout(resolve, 100));
37
+
38
+ const inputs = element.querySelectorAll<HTMLInputElement>('input[type="text"]');
39
+ expect(inputs).to.have.lengthOf(0);
40
+
41
+ const buttons = element.querySelectorAll<HTMLButtonElement>('button');
42
+ expect(buttons).to.have.lengthOf(1);
43
+ });
44
+
45
+ it('renders one empty input when the value list is a single empty string', async () => {
46
+ const element = new StringlistTypeElement;
47
+ element.formid = 'setting-test';
48
+ element.value = [''];
49
+ root.appendChild(element);
50
+ await new Promise((resolve) => setTimeout(resolve, 100));
51
+
52
+ const inputs = element.querySelectorAll<HTMLInputElement>('input[type="text"]');
53
+ expect(inputs).to.have.lengthOf(1);
54
+ expect(inputs[0].id).to.equal('setting-test');
55
+ });
56
+
57
+ it('hides the remove button when only one row is shown', async () => {
58
+ const element = new StringlistTypeElement;
59
+ element.value = [];
60
+ root.appendChild(element);
61
+ await new Promise((resolve) => setTimeout(resolve, 100));
62
+
63
+ expect(element.querySelectorAll('button')).to.have.lengthOf(1);
64
+ });
65
+
66
+ it('adds a row when the add button is clicked on an empty list', async () => {
67
+ const element = new StringlistTypeElement;
68
+ element.value = [];
69
+ root.appendChild(element);
70
+ await new Promise((resolve) => setTimeout(resolve, 100));
71
+
72
+ const addButton = element.querySelectorAll<HTMLButtonElement>('button:not([disabled])')[0];
73
+ addButton.click();
74
+ await new Promise((resolve) => setTimeout(resolve, 100));
75
+
76
+ expect(element.value).to.deep.equal(['']);
77
+ expect(element.querySelectorAll('input[type="text"]')).to.have.lengthOf(1);
78
+ });
79
+
80
+ it('renders per-row controls for each entry when value has multiple entries', async () => {
81
+ const element = new StringlistTypeElement;
82
+ element.value = ['/typo3', '/fileadmin'];
83
+ root.appendChild(element);
84
+ await new Promise((resolve) => setTimeout(resolve, 100));
85
+
86
+ expect(element.querySelectorAll('input[type="text"]')).to.have.lengthOf(2);
87
+ // Two rows, each with + and - buttons.
88
+ expect(element.querySelectorAll('button')).to.have.lengthOf(4);
89
+ });
90
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typo3-typescript-sources",
3
- "version": "13.4.32",
3
+ "version": "13.4.34",
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": "v13.4.32",
31
+ "sourceTag": "v13.4.34",
32
32
  "sourcePath": "Build/Sources/TypeScript"
33
33
  }
34
34
  }
@@ -86,9 +86,9 @@ class EventHandler {
86
86
  }
87
87
 
88
88
  private revert(correlationIds: string[]): Promise<AjaxResponse> {
89
- const request = new AjaxRequest(TYPO3.settings.ajaxUrls.redirects_revert_correlation).withQueryArguments({
90
- correlation_ids: correlationIds
91
- }).get();
89
+ const request = new AjaxRequest(TYPO3.settings.ajaxUrls.redirects_revert_correlation).post({
90
+ correlation_ids: correlationIds,
91
+ });
92
92
 
93
93
  request.then(async (response: AjaxResponse): Promise<void> => {
94
94
  const json = await response.resolve();