From 678621e164b6b3b47aa1f9a4138a856bd0c57246 Mon Sep 17 00:00:00 2001 From: Ayke Halder <mail@ayke-halder.de> Date: Sun, 14 Apr 2024 13:04:54 +0200 Subject: [PATCH] [BUGFIX] Hide hidden content elements in page module There is a checkbox in page module to show hidden content elements. If this checkbox is not selected the hidden content elements must be hidden. Additionally hidden elements must not be accessible/focusable by keyboard. Resolves: #103626 Releases: main, 12.4 Change-Id: Id8f4b98938ae27e3bd3d3e7903c3f50588d554b8 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/83781 Tested-by: core-ci <typo3@b13.com> Reviewed-by: Willi Wehmeier <wwwehmeier@gmail.com> Tested-by: Oliver Bartsch <bo@cedev.de> Reviewed-by: Oliver Bartsch <bo@cedev.de> Tested-by: Willi Wehmeier <wwwehmeier@gmail.com> --- .../TypeScript/backend/page-actions.ts | 31 +++++++++++++------ .../Private/Partials/PageLayout/Record.html | 2 +- .../Public/JavaScript/page-actions.js | 2 +- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/Build/Sources/TypeScript/backend/page-actions.ts b/Build/Sources/TypeScript/backend/page-actions.ts index d2556a7f6d3f..552f1447e1ec 100644 --- a/Build/Sources/TypeScript/backend/page-actions.ts +++ b/Build/Sources/TypeScript/backend/page-actions.ts @@ -42,21 +42,27 @@ class PageActions { me.disabled = true; for (const hiddenElement of hiddenElements) { - hiddenElement.style.display = 'block'; + hiddenElement.style.display = 'flow-root'; const scrollHeight = hiddenElement.scrollHeight; - hiddenElement.style.display = ''; + + // Always set `overflow: clip` after storing scrollHeight + // * For hidden state `height: 0px` is already set. + // * For visible state setting `overflow: clip` is fine anyway. + hiddenElement.style.overflow = 'clip'; if (!me.checked) { - // Spacing between content elements is kept uniform by collapsed margins, - // hidden elements have a height of 0 and the margins of the surrounding elements - // cannot collapse, causing a visual gap. We therefore remove the element - // from the flow to prevent this. + // * Invisible elements must not be accessible/focusable by keyboard. + // * Spacing between content elements is kept uniform by collapsed margins, + // hidden elements have a height of 0 and the margins of the surrounding elements + // cannot collapse, causing a visual gap. + // Therefore do not display the element at all by setting `display: none`. hiddenElement.addEventListener('transitionend', (): void => { - hiddenElement.style.position = 'absolute'; + hiddenElement.style.display = 'none'; + hiddenElement.style.overflow = ''; }, { once: true }); - // We use requestAnimationFrame() as we have to set the container's height at first before resizing to 0px - // results in a smooth animation. + // We use requestAnimationFrame() as we have to set the container's height at first before resizing to + // collapsed-element-height. This results in a smooth animation. requestAnimationFrame(function() { hiddenElement.style.height = scrollHeight + 'px'; requestAnimationFrame(function() { @@ -64,7 +70,12 @@ class PageActions { }); }); } else { - hiddenElement.style.position = ''; + hiddenElement.addEventListener('transitionend', (): void => { + hiddenElement.style.display = ''; + hiddenElement.style.overflow = ''; + hiddenElement.style.height = ''; + }, { once: true }); + hiddenElement.style.height = scrollHeight + 'px'; } } diff --git a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record.html b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record.html index 2d1304484f53..ea41eabc1961 100644 --- a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record.html +++ b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record.html @@ -1,4 +1,4 @@ -{f:if(condition: '{item.disabled} && {item.context.drawingConfiguration.showHidden} == 0', then: 'height: 0; position: absolute;') -> f:variable(name: 'style')} +{f:if(condition: '{item.disabled} && {item.context.drawingConfiguration.showHidden} == 0', then: 'height: 0; display: none;') -> f:variable(name: 'style')} <div class="t3-page-ce {item.wrapperClassName} t3js-page-ce t3js-page-ce-sortable" id="element-tt_content-{item.record.uid}" data-table="tt_content" data-uid="{item.record.uid}" data-language-uid="{item.record.sys_language_uid}" style="{style}"> <div class="t3-page-ce-element t3-page-ce-dragitem"> <f:render partial="PageLayout/Record/{item.record.CType}/Header" arguments="{_all}" optional="1"> diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/page-actions.js b/typo3/sysext/backend/Resources/Public/JavaScript/page-actions.js index a16ba5b5c15c..bbc9b5358694 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/page-actions.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/page-actions.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import DocumentService from"@typo3/core/document-service.js";import RegularEvent from"@typo3/core/event/regular-event.js";import PersistentStorage from"@typo3/backend/storage/persistent.js";var IdentifierEnum;!function(e){e.hiddenElements=".t3js-hidden-record"}(IdentifierEnum||(IdentifierEnum={}));class PageActions{constructor(){DocumentService.ready().then((()=>{const e=document.getElementById("checkShowHidden");null!==e&&new RegularEvent("change",this.toggleContentElementVisibility).bindTo(e)}))}toggleContentElementVisibility(e){const t=e.target,n=document.querySelectorAll(IdentifierEnum.hiddenElements);t.disabled=!0;for(const e of n){e.style.display="block";const n=e.scrollHeight;e.style.display="",t.checked?(e.style.position="",e.style.height=n+"px"):(e.addEventListener("transitionend",(()=>{e.style.position="absolute"}),{once:!0}),requestAnimationFrame((function(){e.style.height=n+"px",requestAnimationFrame((function(){e.style.height="0px"}))})))}PersistentStorage.set("moduleData.web_layout.showHidden",t.checked?"1":"0").then((()=>{t.disabled=!1}))}}export default new PageActions; \ No newline at end of file +import DocumentService from"@typo3/core/document-service.js";import RegularEvent from"@typo3/core/event/regular-event.js";import PersistentStorage from"@typo3/backend/storage/persistent.js";var IdentifierEnum;!function(e){e.hiddenElements=".t3js-hidden-record"}(IdentifierEnum||(IdentifierEnum={}));class PageActions{constructor(){DocumentService.ready().then((()=>{const e=document.getElementById("checkShowHidden");null!==e&&new RegularEvent("change",this.toggleContentElementVisibility).bindTo(e)}))}toggleContentElementVisibility(e){const t=e.target,n=document.querySelectorAll(IdentifierEnum.hiddenElements);t.disabled=!0;for(const e of n){e.style.display="flow-root";const n=e.scrollHeight;e.style.overflow="clip",t.checked?(e.addEventListener("transitionend",(()=>{e.style.display="",e.style.overflow="",e.style.height=""}),{once:!0}),e.style.height=n+"px"):(e.addEventListener("transitionend",(()=>{e.style.display="none",e.style.overflow=""}),{once:!0}),requestAnimationFrame((function(){e.style.height=n+"px",requestAnimationFrame((function(){e.style.height="0px"}))})))}PersistentStorage.set("moduleData.web_layout.showHidden",t.checked?"1":"0").then((()=>{t.disabled=!1}))}}export default new PageActions; \ No newline at end of file -- GitLab