Take care that click events can still bubble up the dom when a menu is closed again. Otherwise the project search will not close when any other global menu is opened. Further the event

handler for mobile was removed as the element did not match anyways and it thus does not seem to be needed any more.
pull/10830/head
Henriette Darge 2 years ago
parent 13f8712a98
commit b3b634a7a9
  1. 74
      frontend/src/app/core/setup/globals/global-listeners/top-menu.ts
  2. 18
      frontend/src/app/shared/components/autocompleter/project-menu-autocomplete/project-menu-autocomplete.template.html

@ -41,7 +41,7 @@ export class TopMenu {
this.skipContentClickListener(); this.skipContentClickListener();
} }
skipContentClickListener() { skipContentClickListener():void {
// Skip menu on content // Skip menu on content
jQuery('#skip-navigation--content').on('click', () => { jQuery('#skip-navigation--content').on('click', () => {
// Skip to the breadcrumb or the first link in the toolbar or the first link in the content (homescreen) // Skip to the breadcrumb or the first link in the toolbar or the first link in the content (homescreen)
@ -56,11 +56,11 @@ export class TopMenu {
}); });
} }
accessibility() { accessibility():void {
jQuery('.op-app-menu--dropdown').attr('aria-expanded', 'false'); jQuery('.op-app-menu--dropdown').attr('aria-expanded', 'false');
} }
toggleClick(dropdown:JQuery) { toggleClick(dropdown:JQuery):void {
if (this.menuIsOpen) { if (this.menuIsOpen) {
if (this.isOpen(dropdown)) { if (this.isOpen(dropdown)) {
this.closing(); this.closing();
@ -74,37 +74,37 @@ export class TopMenu {
} }
// somebody opens the menu via click, hover possible afterwards // somebody opens the menu via click, hover possible afterwards
opening() { opening():void {
this.startHover(); this.startHover();
this.menuIsOpen = true; this.menuIsOpen = true;
this.menuContainer.trigger('openedMenu', this.menuContainer); this.menuContainer.trigger('openedMenu', this.menuContainer);
} }
// the entire menu gets closed, no hover possible afterwards // the entire menu gets closed, no hover possible afterwards
closing() { closing():void {
this.stopHover(); this.stopHover();
this.closeAllItems(); this.closeAllItems();
this.menuIsOpen = false; this.menuIsOpen = false;
this.menuContainer.trigger('closedMenu', this.menuContainer); this.menuContainer.trigger('closedMenu', this.menuContainer);
} }
stopHover() { stopHover():void {
this.hover = false; this.hover = false;
this.menuContainer.removeClass('hover'); this.menuContainer.removeClass('hover');
} }
startHover() { startHover():void {
this.hover = true; this.hover = true;
this.menuContainer.addClass('hover'); this.menuContainer.addClass('hover');
} }
closeAllItems() { closeAllItems():void {
this.openDropdowns().each((ix, item) => { this.openDropdowns().each((ix, item) => {
this.close(jQuery(item)); this.close(jQuery(item));
}); });
} }
closeOnBodyClick() { closeOnBodyClick():void {
const wrapper = document.getElementById('wrapper'); const wrapper = document.getElementById('wrapper');
if (!wrapper) { if (!wrapper) {
return; return;
@ -125,7 +125,7 @@ export class TopMenu {
return this.menuContainer.find('.op-app-menu--item_has-dropdown'); return this.menuContainer.find('.op-app-menu--item_has-dropdown');
} }
withHeadingFoldOutAtBorder() { withHeadingFoldOutAtBorder():void {
let menuStartPosition; let menuStartPosition;
const next = this.menuContainer.next(); const next = this.menuContainer.next();
const wikiHeading = this.menuContainer.next().children().next().first(); const wikiHeading = this.menuContainer.next().children().next().first();
@ -139,35 +139,24 @@ export class TopMenu {
} }
} }
setupDropdownClick() { setupDropdownClick():void {
this.dropdowns().each((ix, it) => { this.dropdowns().each((ix, it) => {
jQuery(it).find('.op-app-menu--item-action').click(() => { jQuery(it).find('.op-app-menu--item-action').click((e) => {
this.toggleClick(jQuery(it)); this.toggleClick(jQuery(it));
return false;
});
jQuery(it).find('op-app-menu--item-action').on('touchstart', (e) => {
// This shall avoid the hover event is fired,
// which would otherwise lead to menu being closed directly after its opened.
// Ignore clicks from within the dropdown
if (jQuery(e.target).closest('.op-app-menu--body').length) {
return true;
}
e.preventDefault(); e.preventDefault();
jQuery(it).click();
return false;
}); });
}); });
} }
isOpen(dropdown:JQuery) { isOpen(dropdown:JQuery):boolean {
return dropdown.filter('.op-app-menu--item_dropdown-open').length === 1; return dropdown.filter('.op-app-menu--item_dropdown-open').length === 1;
} }
isClosed(dropdown:JQuery) { isClosed(dropdown:JQuery):boolean {
return !this.isOpen(dropdown); return !this.isOpen(dropdown);
} }
open(dropdown:JQuery) { open(dropdown:JQuery):void {
this.dontCloseWhenUsing(dropdown); this.dontCloseWhenUsing(dropdown);
this.closeOtherItems(dropdown); this.closeOtherItems(dropdown);
this.slideAndFocus(dropdown, () => { this.slideAndFocus(dropdown, () => {
@ -175,12 +164,13 @@ export class TopMenu {
}); });
} }
close(dropdown:JQuery, immediate?:any) { close(dropdown:JQuery, immediate?:boolean):void {
this.slideUp(dropdown, immediate); this.slideUp(dropdown, !!immediate);
dropdown.trigger('closed', dropdown); dropdown.trigger('closed', dropdown);
this.removeStoppingOfEventPropagation(dropdown);
} }
closeOtherItems(dropdown:JQuery) { closeOtherItems(dropdown:JQuery):void {
this.openDropdowns().each((ix, it) => { this.openDropdowns().each((ix, it) => {
if (jQuery(it) !== jQuery(dropdown)) { if (jQuery(it) !== jQuery(dropdown)) {
this.close(jQuery(it), true); this.close(jQuery(it), true);
@ -188,13 +178,21 @@ export class TopMenu {
}); });
} }
dontCloseWhenUsing(dropdown:JQuery) { dontCloseWhenUsing(dropdown:JQuery):void {
jQuery(dropdown).find('li').click((event) => { setTimeout(() => {
event.stopPropagation(); jQuery(dropdown).find('li').click((event) => {
}); event.stopPropagation();
jQuery(dropdown).bind('mousedown mouseup click', (event) => { });
event.stopPropagation();
}); jQuery(dropdown).bind('mousedown mouseup click', (event) => {
event.stopPropagation();
});
}, 0);
}
removeStoppingOfEventPropagation(dropdown:JQuery):void {
jQuery(dropdown).find('li').unbind('click');
jQuery(dropdown).unbind('mousedown mouseup click');
} }
slideAndFocus(dropdown:JQuery, callback:any) { slideAndFocus(dropdown:JQuery, callback:any) {
@ -208,7 +206,7 @@ export class TopMenu {
toDrop.slideDown(ANIMATION_RATE_MS, callback).attr('aria-expanded', 'true'); toDrop.slideDown(ANIMATION_RATE_MS, callback).attr('aria-expanded', 'true');
} }
slideUp(dropdown:JQuery, immediate:any) { slideUp(dropdown:JQuery, immediate:boolean):void {
const toDrop = jQuery(dropdown).find('.op-app-menu--dropdown'); const toDrop = jQuery(dropdown).find('.op-app-menu--dropdown');
dropdown.removeClass('op-app-menu--item_dropdown-open'); dropdown.removeClass('op-app-menu--item_dropdown-open');
@ -238,7 +236,7 @@ export class TopMenu {
}, 10); }, 10);
} }
registerEventHandlers() { registerEventHandlers():void {
const toggler = jQuery('#main-menu-toggle'); const toggler = jQuery('#main-menu-toggle');
this.menuContainer.on('closeDropDown', (event:Event) => { this.menuContainer.on('closeDropDown', (event:Event) => {

@ -4,19 +4,21 @@
alignment="bottom-left" alignment="bottom-left"
class="op-project-list-modal" class="op-project-list-modal"
> >
<a id="projects-menu" <button
accesskey="5" id="projects-menu"
aria-haspopup="true" accesskey="5"
class="op-app-menu--item-action" aria-haspopup="true"
href="#" class="op-app-menu--item-action"
slot="trigger" type="button"
(click)="toggleDropModal()"> slot="trigger"
(click)="toggleDropModal()"
>
<span <span
class="op-app-menu--item-title ellipsis" class="op-app-menu--item-title ellipsis"
[textContent]="currentProjectName()" [textContent]="currentProjectName()"
></span> ></span>
<i class="op-app-menu--item-dropdown-indicator button--dropdown-indicator"></i> <i class="op-app-menu--item-dropdown-indicator button--dropdown-indicator"></i>
</a> </button>
<ng-container slot="body"> <ng-container slot="body">
<div class="op-project-list-modal--header"> <div class="op-project-list-modal--header">

Loading…
Cancel
Save