From 25a726729bcab1ee3e5fd172638c5e881fa3a79b Mon Sep 17 00:00:00 2001 From: Andreas Fernandez <a.fernandez@scripting-base.de> Date: Tue, 11 Apr 2023 11:26:10 +0200 Subject: [PATCH] [BUGFIX] Render only one toggle per node in trees In non-SVG trees, there are currently two icons representing the node's expansion state rendered that get toggled via CSS rules based on hard-coded aria attributes and icon identifiers, which is a bad practice. To solve this, a new web component `typo3-backend-tree-node-toggle` is added whose only responsibility is to render the correct icon based on its `aria-expanded` attribute Resolves: #100549 Releases: main, 12.4 Change-Id: I1a955731fc21da01a914b1ef721d7eb2d1e18ed5 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/79826 Tested-by: core-ci <typo3@b13.com> Reviewed-by: Benni Mack <benni@typo3.org> Tested-by: Benni Mack <benni@typo3.org> --- Build/Sources/Sass/component/_treelist.scss | 8 ----- .../backend/tree/tree-node-toggle.ts | 31 +++++++++++++++++++ .../Templates/PageTsConfig/Active.html | 11 +++---- .../Templates/PageTsConfig/Includes.html | 11 +++---- .../backend/Resources/Public/Css/backend.css | 2 -- .../JavaScript/tree/tree-node-toggle.js | 13 ++++++++ .../Application/Template/TemplateCest.php | 4 +-- .../Controller/ConfigurationController.php | 11 ++++--- .../Private/Templates/Configuration.html | 2 +- .../Private/Partials/ActiveTree.html | 9 ++---- .../Private/Partials/AnalyzerTree.html | 11 +++---- .../Private/Templates/ActiveMain.html | 2 +- 12 files changed, 70 insertions(+), 45 deletions(-) create mode 100644 Build/Sources/TypeScript/backend/tree/tree-node-toggle.ts create mode 100644 typo3/sysext/backend/Resources/Public/JavaScript/tree/tree-node-toggle.js diff --git a/Build/Sources/Sass/component/_treelist.scss b/Build/Sources/Sass/component/_treelist.scss index d986bcb2bdd5..941f2b8b9373 100644 --- a/Build/Sources/Sass/component/_treelist.scss +++ b/Build/Sources/Sass/component/_treelist.scss @@ -205,14 +205,6 @@ typo3-backend-icon { --icon-color-primary: var(--treelist-color); } - - &[aria-expanded="true"] typo3-backend-icon[identifier="actions-chevron-right"] { - display: none; - } - - &[aria-expanded="false"] typo3-backend-icon[identifier="actions-chevron-down"] { - display: none; - } } .treelist-root { diff --git a/Build/Sources/TypeScript/backend/tree/tree-node-toggle.ts b/Build/Sources/TypeScript/backend/tree/tree-node-toggle.ts new file mode 100644 index 000000000000..45a4cebca6d3 --- /dev/null +++ b/Build/Sources/TypeScript/backend/tree/tree-node-toggle.ts @@ -0,0 +1,31 @@ +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +import { customElement, property } from 'lit/decorators'; +import { html, LitElement, TemplateResult } from 'lit'; +import '@typo3/backend/element/icon-element'; + +@customElement('typo3-backend-tree-node-toggle') +export default class TreeNodeToggle extends LitElement { + @property({ type: String, reflect: true, attribute: 'aria-expanded' }) expanded: string = 'false'; + + public render(): TemplateResult | symbol { + return html`<typo3-backend-icon size="small" identifier="${this.expanded === 'true' ? 'actions-chevron-down' : 'actions-chevron-right'}"></typo3-backend-icon>`; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'typo3-backend-tree-node-toggle': TreeNodeToggle; + } +} diff --git a/typo3/sysext/backend/Resources/Private/Templates/PageTsConfig/Active.html b/typo3/sysext/backend/Resources/Private/Templates/PageTsConfig/Active.html index 1d6f1ecb5a45..944911236ff7 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/PageTsConfig/Active.html +++ b/typo3/sysext/backend/Resources/Private/Templates/PageTsConfig/Active.html @@ -12,7 +12,7 @@ includeJavaScriptModules="{ 0: '@typo3/backend/context-menu.js', 1: '@typo3/backend/element/immediate-action-element.js', - 2: '@typo3/backend/element/icon-element.js', + 2: '@typo3/backend/tree/tree-node-toggle.js', 3: '@typo3/backend/utility/collapse-state-persister.js', 4: '@typo3/backend/utility/collapse-state-search.js' }" @@ -361,15 +361,12 @@ </f:if> <li> <f:if condition="{child.children}"> - <a + <typo3-backend-tree-node-toggle class="treelist-control collapsed" data-bs-toggle="collapse" data-bs-target="#collapse-list-{child.identifier}" - aria-expanded="false" - > - <typo3-backend-icon size="small" identifier="actions-chevron-right"></typo3-backend-icon> - <typo3-backend-icon size="small" identifier="actions-chevron-down"></typo3-backend-icon> - </a> + aria-expanded="false"> + </typo3-backend-tree-node-toggle> </f:if> <span class="treelist-group treelist-group-monospace"> <span class="treelist-label">{child.name}</span> diff --git a/typo3/sysext/backend/Resources/Private/Templates/PageTsConfig/Includes.html b/typo3/sysext/backend/Resources/Private/Templates/PageTsConfig/Includes.html index 70823655f610..733809b9bc5a 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/PageTsConfig/Includes.html +++ b/typo3/sysext/backend/Resources/Private/Templates/PageTsConfig/Includes.html @@ -12,7 +12,7 @@ includeJavaScriptModules="{ 0: '@typo3/backend/context-menu.js', 1: '@typo3/backend/element/immediate-action-element.js', - 2: '@typo3/backend/element/icon-element.js', + 2: '@typo3/backend/tree/tree-node-toggle.js', 3: '@typo3/backend/utility/collapse-state-persister.js', 4: '@typo3/backend/pagetsconfig/pagetsconfig-includes.js' }" @@ -113,15 +113,12 @@ <f:for each="{tree.nextChild}" as="child"> <li> <f:if condition="{child.children}"> - <a + <typo3-backend-tree-node-toggle class="treelist-control treelist-control-collapsed" data-bs-toggle="collapse" data-bs-target="#collapse-list-{child.identifier}" - aria-expanded="false" - > - <typo3-backend-icon size="small" identifier="actions-chevron-down"></typo3-backend-icon> - <typo3-backend-icon size="small" identifier="actions-chevron-right"></typo3-backend-icon> - </a> + aria-expanded="false"> + </typo3-backend-tree-node-toggle> </f:if> <div class="row justify-content-between"> <div class="col"> diff --git a/typo3/sysext/backend/Resources/Public/Css/backend.css b/typo3/sysext/backend/Resources/Public/Css/backend.css index 916fbf18b131..9ad4f9ae91b5 100644 --- a/typo3/sysext/backend/Resources/Public/Css/backend.css +++ b/typo3/sysext/backend/Resources/Public/Css/backend.css @@ -3840,8 +3840,6 @@ typo3-backend-live-search-result-item-action>* .livesearch-result-item-title .sm .treelist-control:before,.treelist-control:target:before{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:var(--treelist-control-size);height:var(--treelist-control-size);background-color:var(--treelist-bg)} .treelist-control:active,.treelist-control:focus,.treelist-control:hover{cursor:pointer;outline:0;text-decoration:none} .treelist-control typo3-backend-icon{--icon-color-primary:var(--treelist-color)} -.treelist-control[aria-expanded=true] typo3-backend-icon[identifier=actions-chevron-right]{display:none} -.treelist-control[aria-expanded=false] typo3-backend-icon[identifier=actions-chevron-down]{display:none} .treelist-root{padding-left:0} .treelist-root:before{display:none} .treelist-root>li{padding-left:var(--treelist-control-size)} diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/tree/tree-node-toggle.js b/typo3/sysext/backend/Resources/Public/JavaScript/tree/tree-node-toggle.js new file mode 100644 index 000000000000..d486a2925111 --- /dev/null +++ b/typo3/sysext/backend/Resources/Public/JavaScript/tree/tree-node-toggle.js @@ -0,0 +1,13 @@ +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ +var __decorate=function(e,t,o,r){var n,c=arguments.length,d=c<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,o):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)d=Reflect.decorate(e,t,o,r);else for(var l=e.length-1;l>=0;l--)(n=e[l])&&(d=(c<3?n(d):c>3?n(t,o,d):n(t,o))||d);return c>3&&d&&Object.defineProperty(t,o,d),d};import{customElement,property}from"lit/decorators.js";import{html,LitElement}from"lit";import"@typo3/backend/element/icon-element.js";let TreeNodeToggle=class extends LitElement{constructor(){super(...arguments),this.expanded="false"}render(){return html`<typo3-backend-icon size="small" identifier="${"true"===this.expanded?"actions-chevron-down":"actions-chevron-right"}"></typo3-backend-icon>`}};__decorate([property({type:String,reflect:!0,attribute:"aria-expanded"})],TreeNodeToggle.prototype,"expanded",void 0),TreeNodeToggle=__decorate([customElement("typo3-backend-tree-node-toggle")],TreeNodeToggle);export default TreeNodeToggle; \ No newline at end of file diff --git a/typo3/sysext/core/Tests/Acceptance/Application/Template/TemplateCest.php b/typo3/sysext/core/Tests/Acceptance/Application/Template/TemplateCest.php index ca0210bf89d9..72958ccd2fd1 100644 --- a/typo3/sysext/core/Tests/Acceptance/Application/Template/TemplateCest.php +++ b/typo3/sysext/core/Tests/Acceptance/Application/Template/TemplateCest.php @@ -108,10 +108,10 @@ final class TemplateCest $I->waitForText('Setup'); // find and open page in tree $I->waitForText('page = PAGE'); - $I->click('//span[@class="treelist-label"]/a[text()=\'page\']/../../../a'); + $I->click('//span[@class="treelist-label"]/a[text()=\'page\']/../../../typo3-backend-tree-node-toggle'); // find and open page.10 in tree $I->waitForText('10 = TEXT'); - $I->click('//span[@class="treelist-label"]/a[text()=\'page\']/../../../div/ul//span[@class="treelist-label"]/a[text()=\'10\']/../../../a'); + $I->click('//span[@class="treelist-label"]/a[text()=\'page\']/../../../div/ul//span[@class="treelist-label"]/a[text()=\'10\']/../../../typo3-backend-tree-node-toggle'); // find and edit page.10.value in tree $I->waitForText('value = Hello Acceptance Test!'); $I->click('//span[@class="treelist-label"]/a[text()=\'10\']/../../../div/ul//span[@class="treelist-label"]/a[text()=\'value\']'); diff --git a/typo3/sysext/lowlevel/Classes/Controller/ConfigurationController.php b/typo3/sysext/lowlevel/Classes/Controller/ConfigurationController.php index 7c73156fcfec..cf95cd8c79ea 100644 --- a/typo3/sysext/lowlevel/Classes/Controller/ConfigurationController.php +++ b/typo3/sysext/lowlevel/Classes/Controller/ConfigurationController.php @@ -101,10 +101,13 @@ final class ConfigurationController $newIdentifier = ''; if ($isValueIterable && !empty($value)) { $newIdentifier = hash('xxh3', $incomingIdentifier . $key); - $html .= '<a class="treelist-control collapsed" data-bs-toggle="collapse" data-bs-target="#collapse-list-' . $newIdentifier . '" aria-expanded="false">' . - '<typo3-backend-icon size="small" identifier="actions-chevron-right"></typo3-backend-icon>' . - '<typo3-backend-icon size="small" identifier="actions-chevron-down"></typo3-backend-icon>' . - '</a>'; + $html .= ' + <typo3-backend-tree-node-toggle + class="treelist-control collapsed" + data-bs-toggle="collapse" + data-bs-target="#collapse-list-' . $newIdentifier . '" + aria-expanded="false"> + </typo3-backend-tree-node-toggle>'; } $html .= '<span class="treelist-group treelist-group-monospace">'; $html .= '<span class="treelist-label">' . htmlspecialchars((string)$key) . '</span>'; diff --git a/typo3/sysext/lowlevel/Resources/Private/Templates/Configuration.html b/typo3/sysext/lowlevel/Resources/Private/Templates/Configuration.html index dac60a5038bc..6c347010ba56 100644 --- a/typo3/sysext/lowlevel/Resources/Private/Templates/Configuration.html +++ b/typo3/sysext/lowlevel/Resources/Private/Templates/Configuration.html @@ -10,7 +10,7 @@ <f:be.pageRenderer includeJavaScriptModules="{ - 0: '@typo3/backend/element/icon-element.js', + 0: '@typo3/backend/tree/tree-node-toggle.js', 1: '@typo3/backend/utility/collapse-state-persister.js', 2: '@typo3/backend/utility/collapse-state-search.js' }" diff --git a/typo3/sysext/tstemplate/Resources/Private/Partials/ActiveTree.html b/typo3/sysext/tstemplate/Resources/Private/Partials/ActiveTree.html index 0f63168a1454..d9d3faa0658f 100644 --- a/typo3/sysext/tstemplate/Resources/Private/Partials/ActiveTree.html +++ b/typo3/sysext/tstemplate/Resources/Private/Partials/ActiveTree.html @@ -31,15 +31,12 @@ </f:if> <li> <f:if condition="{child.children}"> - <a + <typo3-backend-tree-node-toggle class="treelist-control collapsed" data-bs-toggle="collapse" data-bs-target="#collapse-list-{child.identifier}" - aria-expanded="false" - > - <typo3-backend-icon size="small" identifier="actions-chevron-right"></typo3-backend-icon> - <typo3-backend-icon size="small"identifier="actions-chevron-down"></typo3-backend-icon> - </a> + aria-expanded="false"> + </typo3-backend-tree-node-toggle> </f:if> <span class="treelist-group treelist-group-monospace"> diff --git a/typo3/sysext/tstemplate/Resources/Private/Partials/AnalyzerTree.html b/typo3/sysext/tstemplate/Resources/Private/Partials/AnalyzerTree.html index 5618f9ab7e92..0737c03e0e06 100644 --- a/typo3/sysext/tstemplate/Resources/Private/Partials/AnalyzerTree.html +++ b/typo3/sysext/tstemplate/Resources/Private/Partials/AnalyzerTree.html @@ -7,7 +7,7 @@ <f:be.pageRenderer includeJavaScriptModules="{ - 0: '@typo3/backend/element/icon-element.js', + 0: '@typo3/backend/tree/tree-node-toggle.js', 1: '@typo3/backend/utility/collapse-state-persister.js' }" /> @@ -18,15 +18,12 @@ <f:for each="{tree.nextChild}" as="child"> <li> <f:if condition="{child.children}"> - <a + <typo3-backend-tree-node-toggle class="treelist-control treelist-control-collapsed" data-bs-toggle="collapse" data-bs-target="#collapse-list-{child.identifier}" - aria-expanded="false" - > - <typo3-backend-icon size="small" identifier="actions-chevron-down"></typo3-backend-icon> - <typo3-backend-icon size="small" identifier="actions-chevron-right"></typo3-backend-icon> - </a> + aria-expanded="false"> + </typo3-backend-tree-node-toggle> </f:if> <div class="row justify-content-between"> <div class="col"> diff --git a/typo3/sysext/tstemplate/Resources/Private/Templates/ActiveMain.html b/typo3/sysext/tstemplate/Resources/Private/Templates/ActiveMain.html index 92ad7746e884..6110a25bcb7c 100644 --- a/typo3/sysext/tstemplate/Resources/Private/Templates/ActiveMain.html +++ b/typo3/sysext/tstemplate/Resources/Private/Templates/ActiveMain.html @@ -10,7 +10,7 @@ includeJavaScriptModules="{ 0: '@typo3/backend/context-menu.js', 1: '@typo3/backend/element/immediate-action-element.js', - 3: '@typo3/backend/element/icon-element.js', + 3: '@typo3/backend/tree/tree-node-toggle.js', 4: '@typo3/backend/utility/collapse-state-persister.js', 5: '@typo3/backend/utility/collapse-state-search.js' }" -- GitLab