@@ -112,8 +112,10 @@ type OpenerStandardListItem = StandardListItem & { associatedItem: MenuItem };
112
112
113
113
/**
114
114
* Fired when an item is being clicked.
115
+ * <b>Note:</b> Since 1.17.0 the event is preventable, allowing the menu to remain open after an item is pressed.
115
116
*
116
117
* @event sap.ui.webc.main.Menu#item-click
118
+ * @allowPreventDefault
117
119
* @param { HTMLElement } item The currently clicked menu item.
118
120
* @param { string } text The text of the currently clicked menu item.
119
121
* @public
@@ -367,7 +369,8 @@ class Menu extends UI5Element {
367
369
const menuItem = item . item ;
368
370
if ( subMenu && subMenu . busy ) {
369
371
subMenu . innerHTML = "" ;
370
- this . _cloneItems ( menuItem , subMenu ) ;
372
+ const fragment = this . _clonedItemsFragment ( menuItem ) ;
373
+ subMenu . appendChild ( fragment ) ;
371
374
}
372
375
373
376
if ( subMenu ) {
@@ -471,16 +474,21 @@ class Menu extends UI5Element {
471
474
subMenu . _parentMenuItem = item ;
472
475
subMenu . busy = item . busy ;
473
476
subMenu . busyDelay = item . busyDelay ;
474
- this . _cloneItems ( item , subMenu ) ;
477
+ const fragment = this . _clonedItemsFragment ( item ) ;
478
+ subMenu . appendChild ( fragment ) ;
475
479
this . staticAreaItem ! . shadowRoot ! . querySelector ( ".ui5-menu-submenus" ) ! . appendChild ( subMenu ) ;
476
480
item . _subMenu = subMenu ;
477
481
}
478
482
479
- _cloneItems ( item : MenuItem , menu : Menu ) {
483
+ _clonedItemsFragment ( item : MenuItem ) {
484
+ const fragment = document . createDocumentFragment ( ) ;
485
+
480
486
for ( let i = 0 ; i < item . items . length ; ++ i ) {
481
487
const clonedItem = item . items [ i ] . cloneNode ( true ) ;
482
- menu . appendChild ( clonedItem ) ;
488
+ fragment . appendChild ( clonedItem ) ;
483
489
}
490
+
491
+ return fragment ;
484
492
}
485
493
486
494
_openItemSubMenu ( item : MenuItem , opener : HTMLElement , actionId : string ) {
@@ -637,15 +645,33 @@ class Menu extends UI5Element {
637
645
this . _parentMenuItem = undefined ;
638
646
}
639
647
// fire event if the click is on top-level menu item
640
- this . fireEvent < MenuItemClickEventDetail > ( "item-click" , {
648
+ const prevented = ! this . fireEvent < MenuItemClickEventDetail > ( "item-click" , {
641
649
"item" : item ,
642
650
"text" : item . text ,
643
- } ) ;
644
- this . _popover ! . close ( ) ;
651
+ } , true , false ) ;
652
+
653
+ if ( ! prevented ) {
654
+ this . _popover ! . close ( ) ;
655
+ }
645
656
} else {
646
- // find top-level menu and redirect event to it
647
657
const mainMenu = this . _findMainMenu ( item ) ;
648
- mainMenu . _itemClick ( e ) ;
658
+ const prevented = ! mainMenu . fireEvent < MenuItemClickEventDetail > ( "item-click" , {
659
+ "item" : item ,
660
+ "text" : item . text ,
661
+ } , true , false ) ;
662
+
663
+ if ( ! prevented ) {
664
+ let openerMenuItem = item ;
665
+ let parentMenu = openerMenuItem . parentElement as Menu ;
666
+ do {
667
+ openerMenuItem . _preventSubMenuClose = false ;
668
+ this . _closeItemSubMenu ( openerMenuItem ) ;
669
+ parentMenu = openerMenuItem . parentElement as Menu ;
670
+ openerMenuItem = parentMenu . _parentMenuItem as MenuItem ;
671
+ } while ( parentMenu . _parentMenuItem ) ;
672
+
673
+ mainMenu . _popover ! . close ( ) ;
674
+ }
649
675
}
650
676
} else if ( isPhone ( ) ) {
651
677
// prepares and opens sub-menu on phone
@@ -659,8 +685,6 @@ class Menu extends UI5Element {
659
685
_findMainMenu ( item : MenuItem ) {
660
686
let parentMenu = item . parentElement as Menu ;
661
687
while ( parentMenu . _parentMenuItem ) {
662
- parentMenu . _parentMenuItem . _preventSubMenuClose = false ;
663
- this . _closeItemSubMenu ( parentMenu . _parentMenuItem ) ;
664
688
parentMenu = parentMenu . _parentMenuItem . parentElement as Menu ;
665
689
}
666
690
0 commit comments