Skip to content
Snippets Groups Projects
Commit 2d21c593 authored by Oliver Hader's avatar Oliver Hader Committed by Benjamin Franzke
Browse files

[BUGFIX] Resolve DOM elements in NavigationContainer on usage

There have been reports that DOM elements that were assigned in the
constructor of NavigationContainer actually were not available/ready
in the corresponding DOM.

Resolves: #96618
Releases: main, 11.5
Change-Id: Ic4e8aa4e960e46052e645be2380c015e42d3f86c
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/73133


Tested-by: default avatarcore-ci <typo3@b13.com>
Tested-by: default avatarBenjamin Franzke <bfr@qbus.de>
Reviewed-by: default avatarBenjamin Franzke <bfr@qbus.de>
parent 0fe332e0
Branches
Tags
No related merge requests found
......@@ -17,17 +17,26 @@ import TriggerRequest = require('../Event/TriggerRequest');
import InteractionRequest = require('../Event/InteractionRequest');
class NavigationContainer extends AbstractContainer {
private readonly parent: HTMLElement;
private readonly container: HTMLElement;
private readonly switcher: HTMLElement = null;
private activeComponentId: string = '';
private get parent(): HTMLElement
{
return document.querySelector(ScaffoldIdentifierEnum.scaffold);
}
private get container(): HTMLElement
{
return document.querySelector(ScaffoldIdentifierEnum.contentNavigation);
}
private get switcher(): HTMLElement|null
{
return document.querySelector(ScaffoldIdentifierEnum.contentNavigationSwitcher);
}
public constructor(consumerScope: any)
{
super(consumerScope);
this.parent = document.querySelector(ScaffoldIdentifierEnum.scaffold);
this.container = document.querySelector(ScaffoldIdentifierEnum.contentNavigation);
this.switcher = <HTMLElement>document.querySelector(ScaffoldIdentifierEnum.contentNavigationSwitcher);
}
/**
......@@ -36,13 +45,14 @@ class NavigationContainer extends AbstractContainer {
* @param {string} navigationComponentId
*/
public showComponent(navigationComponentId: string): void {
const container = this.container;
this.show(navigationComponentId);
// Component is already loaded and active, nothing to do
if (navigationComponentId === this.activeComponentId) {
return;
}
if (this.activeComponentId !== '') {
let activeComponentElement = this.container.querySelector('#navigationComponent-' + this.activeComponentId.replace(/[/]/g, '_')) as HTMLElement;
let activeComponentElement = container.querySelector('#navigationComponent-' + this.activeComponentId.replace(/[/]/g, '_')) as HTMLElement;
if (activeComponentElement) {
activeComponentElement.style.display = 'none';
}
......@@ -52,7 +62,7 @@ class NavigationContainer extends AbstractContainer {
const navigationComponentElement = 'navigationComponent-' + componentCssName;
// The component was already set up, so requiring the module again can be excluded.
if (this.container.querySelectorAll('[data-component="' + navigationComponentId + '"]').length === 1) {
if (container.querySelectorAll('[data-component="' + navigationComponentId + '"]').length === 1) {
this.show(navigationComponentId);
this.activeComponentId = navigationComponentId;
return;
......@@ -65,10 +75,10 @@ class NavigationContainer extends AbstractContainer {
element.setAttribute('id', navigationComponentElement);
element.classList.add('scaffold-content-navigation-component');
element.dataset.component = navigationComponentId;
this.container.append(element);
container.append(element);
} else {
// Because the component does not exist, let's create the div as wrapper
this.container.insertAdjacentHTML(
container.insertAdjacentHTML(
'beforeend',
'<div class="scaffold-content-navigation-component" data-component="' + navigationComponentId + '" id="' + navigationComponentElement + '"></div>'
);
......@@ -85,27 +95,32 @@ class NavigationContainer extends AbstractContainer {
}
public hide(hideSwitcher: boolean): void {
this.parent.classList.remove('scaffold-content-navigation-expanded');
this.parent.classList.remove('scaffold-content-navigation-available');
if (hideSwitcher && this.switcher) {
this.switcher.style.display = 'none';
const parent = this.parent;
const switcher = this.switcher;
parent.classList.remove('scaffold-content-navigation-expanded');
parent.classList.remove('scaffold-content-navigation-available');
if (hideSwitcher && switcher) {
switcher.style.display = 'none';
}
}
public show(component: string): void {
this.container.querySelectorAll(ScaffoldIdentifierEnum.contentNavigationDataComponent).forEach((el: HTMLElement) => el.style.display = 'none');
const parent = this.parent;
const container = this.container;
const switcher = this.switcher;
container.querySelectorAll(ScaffoldIdentifierEnum.contentNavigationDataComponent).forEach((el: HTMLElement) => el.style.display = 'none');
if (typeof component !== undefined) {
this.parent.classList.add('scaffold-content-navigation-expanded');
this.parent.classList.add('scaffold-content-navigation-available');
const selectedElement = this.container.querySelector('[data-component="' + component + '"]') as HTMLElement;
parent.classList.add('scaffold-content-navigation-expanded');
parent.classList.add('scaffold-content-navigation-available');
const selectedElement = container.querySelector('[data-component="' + component + '"]') as HTMLElement;
if (selectedElement) {
// Re-set to the display setting from CSS
selectedElement.style.display = null;
}
}
if (this.switcher) {
if (switcher) {
// Re-set to the display setting from CSS
this.switcher.style.display = null;
switcher.style.display = null;
}
}
......
......@@ -10,4 +10,4 @@
*
* The TYPO3 project - inspiring people to share!
*/
define(["require","exports","../Enum/Viewport/ScaffoldIdentifier","./AbstractContainer","../Event/TriggerRequest"],(function(t,e,n,i,o){"use strict";class a extends i.AbstractContainer{constructor(t){super(t),this.switcher=null,this.activeComponentId="",this.parent=document.querySelector(n.ScaffoldIdentifierEnum.scaffold),this.container=document.querySelector(n.ScaffoldIdentifierEnum.contentNavigation),this.switcher=document.querySelector(n.ScaffoldIdentifierEnum.contentNavigationSwitcher)}showComponent(e){if(this.show(e),e===this.activeComponentId)return;if(""!==this.activeComponentId){let t=this.container.querySelector("#navigationComponent-"+this.activeComponentId.replace(/[/]/g,"_"));t&&(t.style.display="none")}const n="navigationComponent-"+e.replace(/[/]/g,"_");if(1===this.container.querySelectorAll('[data-component="'+e+'"]').length)return this.show(e),void(this.activeComponentId=e);t([e],t=>{if("string"==typeof t.navigationComponentName){const i=t.navigationComponentName,o=document.createElement(i);o.setAttribute("id",n),o.classList.add("scaffold-content-navigation-component"),o.dataset.component=e,this.container.append(o)}else{this.container.insertAdjacentHTML("beforeend",'<div class="scaffold-content-navigation-component" data-component="'+e+'" id="'+n+'"></div>');Object.values(t)[0].initialize("#"+n)}this.show(e),this.activeComponentId=e})}hide(t){this.parent.classList.remove("scaffold-content-navigation-expanded"),this.parent.classList.remove("scaffold-content-navigation-available"),t&&this.switcher&&(this.switcher.style.display="none")}show(t){if(this.container.querySelectorAll(n.ScaffoldIdentifierEnum.contentNavigationDataComponent).forEach(t=>t.style.display="none"),void 0!==typeof t){this.parent.classList.add("scaffold-content-navigation-expanded"),this.parent.classList.add("scaffold-content-navigation-available");const e=this.container.querySelector('[data-component="'+t+'"]');e&&(e.style.display=null)}this.switcher&&(this.switcher.style.display=null)}setUrl(t,e){const n=this.consumerScope.invoke(new o("typo3.setUrl",e));return n.then(()=>{this.parent.classList.add("scaffold-content-navigation-expanded");const e=this.getIFrameElement();e&&e.setAttribute("src",t)}),n}getUrl(){const t=this.getIFrameElement();return t?t.getAttribute("src"):""}refresh(){const t=this.getIFrameElement();if(t)return t.contentWindow.location.reload()}getIFrameElement(){return this.container.querySelector(n.ScaffoldIdentifierEnum.contentNavigationIframe)}}return a}));
\ No newline at end of file
define(["require","exports","../Enum/Viewport/ScaffoldIdentifier","./AbstractContainer","../Event/TriggerRequest"],(function(t,e,n,o,i){"use strict";class a extends o.AbstractContainer{constructor(t){super(t),this.activeComponentId=""}get parent(){return document.querySelector(n.ScaffoldIdentifierEnum.scaffold)}get container(){return document.querySelector(n.ScaffoldIdentifierEnum.contentNavigation)}get switcher(){return document.querySelector(n.ScaffoldIdentifierEnum.contentNavigationSwitcher)}showComponent(e){const n=this.container;if(this.show(e),e===this.activeComponentId)return;if(""!==this.activeComponentId){let t=n.querySelector("#navigationComponent-"+this.activeComponentId.replace(/[/]/g,"_"));t&&(t.style.display="none")}const o="navigationComponent-"+e.replace(/[/]/g,"_");if(1===n.querySelectorAll('[data-component="'+e+'"]').length)return this.show(e),void(this.activeComponentId=e);t([e],t=>{if("string"==typeof t.navigationComponentName){const i=t.navigationComponentName,a=document.createElement(i);a.setAttribute("id",o),a.classList.add("scaffold-content-navigation-component"),a.dataset.component=e,n.append(a)}else{n.insertAdjacentHTML("beforeend",'<div class="scaffold-content-navigation-component" data-component="'+e+'" id="'+o+'"></div>');Object.values(t)[0].initialize("#"+o)}this.show(e),this.activeComponentId=e})}hide(t){const e=this.parent,n=this.switcher;e.classList.remove("scaffold-content-navigation-expanded"),e.classList.remove("scaffold-content-navigation-available"),t&&n&&(n.style.display="none")}show(t){const e=this.parent,o=this.container,i=this.switcher;if(o.querySelectorAll(n.ScaffoldIdentifierEnum.contentNavigationDataComponent).forEach(t=>t.style.display="none"),void 0!==typeof t){e.classList.add("scaffold-content-navigation-expanded"),e.classList.add("scaffold-content-navigation-available");const n=o.querySelector('[data-component="'+t+'"]');n&&(n.style.display=null)}i&&(i.style.display=null)}setUrl(t,e){const n=this.consumerScope.invoke(new i("typo3.setUrl",e));return n.then(()=>{this.parent.classList.add("scaffold-content-navigation-expanded");const e=this.getIFrameElement();e&&e.setAttribute("src",t)}),n}getUrl(){const t=this.getIFrameElement();return t?t.getAttribute("src"):""}refresh(){const t=this.getIFrameElement();if(t)return t.contentWindow.location.reload()}getIFrameElement(){return this.container.querySelector(n.ScaffoldIdentifierEnum.contentNavigationIframe)}}return a}));
\ No newline at end of file
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment