Skip to content

Commit 14add07

Browse files
authoredJun 10, 2020
fix(ui5-popover): fix closing order of popovers (#1676)
1 parent 3a0c7d5 commit 14add07

File tree

4 files changed

+83
-46
lines changed

4 files changed

+83
-46
lines changed
 

‎packages/main/src/Popover.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ class Popover extends Popup {
278278
* Closes the popover.
279279
* @public
280280
*/
281-
close(escPressed = false, preventRegitryUpdate = false, preventFocusRestore = false) {
281+
close(escPressed = false, preventRegistryUpdate = false, preventFocusRestore = false) {
282282
if (!this.opened) {
283283
return;
284284
}
@@ -296,7 +296,7 @@ class Popover extends Popup {
296296

297297
this.opened = false;
298298

299-
if (!preventRegitryUpdate) {
299+
if (!preventRegistryUpdate) {
300300
removeOpenedPopover(this);
301301
}
302302

‎packages/main/src/popup-utils/OpenedPopupsRegistry.js

+14-13
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,37 @@
11
import { isEscape } from "@ui5/webcomponents-base/dist/Keys.js";
22

3-
let registry = [];
4-
5-
const addOpenedPopup = instance => {
6-
if (!registry.includes(instance)) {
7-
registry.push(instance);
3+
let openedRegistry = [];
4+
5+
const addOpenedPopup = (instance, parentPopovers = []) => {
6+
if (!openedRegistry.includes(instance)) {
7+
openedRegistry.push({
8+
instance,
9+
parentPopovers,
10+
});
811
}
912

10-
if (registry.length === 1) {
13+
if (openedRegistry.length === 1) {
1114
attachGlobalListener();
1215
}
1316
};
1417

1518
const removeOpenedPopup = instance => {
16-
registry = registry.filter(el => {
17-
return el !== instance;
19+
openedRegistry = openedRegistry.filter(el => {
20+
return el !== instance.instance;
1821
});
1922

20-
if (!registry.length) {
23+
if (!openedRegistry.length) {
2124
detachGlobalListener();
2225
}
2326
};
2427

2528
const getOpenedPopups = () => {
26-
return [...registry];
29+
return [...openedRegistry];
2730
};
2831

2932
const _keydownListener = event => {
3033
if (isEscape(event)) {
31-
const topPopup = registry[registry.length - 1];
32-
33-
topPopup && topPopup.close(true);
34+
openedRegistry.pop().instance.close(true);
3435
}
3536
};
3637

‎packages/main/src/popup-utils/PopoverRegistry.js

+50-14
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { isClickInRect } from "./PopupUtils.js";
22
import { getOpenedPopups, addOpenedPopup, removeOpenedPopup } from "./OpenedPopupsRegistry.js";
33

4+
45
let updateInterval = null;
56
const intervalTimeout = 300;
67
const openedRegistry = [];
78

89
const repositionPopovers = event => {
910
openedRegistry.forEach(popover => {
10-
popover.reposition();
11+
popover.instance.reposition();
1112
});
1213
};
1314

@@ -39,15 +40,15 @@ const detachGlobalClickHandler = () => {
3940

4041
const clickHandler = event => {
4142
const openedPopups = getOpenedPopups();
42-
const isTopPopupPopover = openedPopups[openedPopups.length - 1].openBy;
43+
const isTopPopupPopover = openedPopups[openedPopups.length - 1].instance.openBy;
4344

4445
if (openedPopups.length === 0 || !isTopPopupPopover) {
4546
return;
4647
}
4748

4849
// loop all open popovers
4950
for (let i = (openedPopups.length - 1); i !== -1; i--) {
50-
const popup = openedPopups[i];
51+
const popup = openedPopups[i].instance;
5152

5253
// if popup is modal, opener is clicked, popup is dialog skip closing
5354
if (popup.isModal || popup.isOpenerClicked(event)) {
@@ -71,8 +72,13 @@ const detachScrollHandler = popover => {
7172
};
7273

7374
const addOpenedPopover = instance => {
74-
addOpenedPopup(instance);
75-
openedRegistry.push(instance);
75+
const parentPopovers = getParentPopoversIfNested(instance);
76+
77+
addOpenedPopup(instance, parentPopovers);
78+
openedRegistry.push({
79+
instance,
80+
parentPopovers,
81+
});
7682

7783
attachScrollHandler(instance);
7884

@@ -84,18 +90,31 @@ const addOpenedPopover = instance => {
8490
};
8591

8692
const removeOpenedPopover = instance => {
87-
let count = 0;
88-
93+
const popoversToClose = [instance];
8994

90-
for (let i = openedRegistry.indexOf(instance); i < openedRegistry.length; i++) {
91-
openedRegistry[i].close(false, true);
92-
removeOpenedPopup(openedRegistry[i]);
93-
detachScrollHandler(openedRegistry[i]);
94-
count++;
95+
for (let i = 0; i < openedRegistry.length; i++) {
96+
const indexOfCurrentInstance = openedRegistry[i].parentPopovers.indexOf(instance);
97+
if (openedRegistry[i].parentPopovers.length > 0 && indexOfCurrentInstance > -1) {
98+
popoversToClose.push(openedRegistry[i].instance);
99+
}
95100
}
96101

97-
// remove top popovers from registry
98-
Array(count).fill().forEach(() => { openedRegistry.pop(); });
102+
for (let i = popoversToClose.length - 1; i >= 0; i--) {
103+
for (let j = 0; j < openedRegistry.length; j++) {
104+
let indexOfItemToRemove;
105+
if (popoversToClose[i] === openedRegistry[j].instance) {
106+
indexOfItemToRemove = j;
107+
}
108+
109+
110+
if (indexOfItemToRemove >= 0) {
111+
removeOpenedPopup(openedRegistry[indexOfItemToRemove].instance);
112+
detachScrollHandler(openedRegistry[indexOfItemToRemove].instance);
113+
const itemToClose = openedRegistry.splice(indexOfItemToRemove, 1);
114+
itemToClose[0].instance.close(false, true);
115+
}
116+
}
117+
}
99118

100119
if (!openedRegistry.length) {
101120
detachGlobalScrollHandler();
@@ -108,4 +127,21 @@ const getRegistry = () => {
108127
return openedRegistry;
109128
};
110129

130+
const getParentPopoversIfNested = instance => {
131+
let currentElement = instance.parentNode;
132+
const parentPopovers = [];
133+
134+
while (currentElement.parentNode) {
135+
for (let i = 0; i < openedRegistry.length; i++) {
136+
if (currentElement && currentElement === openedRegistry[i].instance) {
137+
parentPopovers.push(currentElement);
138+
}
139+
}
140+
141+
currentElement = currentElement.parentNode;
142+
}
143+
144+
return parentPopovers;
145+
};
146+
111147
export { addOpenedPopover, removeOpenedPopover, getRegistry };

‎packages/main/test/pages/Popover.html

+17-17
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,9 @@
7474
<br>
7575
<br>
7676

77-
<ui5-button id='popbtn'>Open Popover</ui5-button>
77+
<ui5-button id="popbtn">Open Popover</ui5-button>
7878

79-
<ui5-popover placement-type="Bottom" no-arrow id='danger'>
79+
<ui5-popover placement-type="Bottom" no-arrow id="danger">
8080

8181

8282
<ui5-list>
@@ -88,9 +88,9 @@
8888
<br>
8989
<br>
9090

91-
<ui5-button id='bigDanger'>Super Danger !</ui5-button>
91+
<ui5-button id="bigDanger">Super Danger !</ui5-button>
9292

93-
<ui5-popover id='bigDangerPop'>
93+
<ui5-popover id="bigDangerPop">
9494
<ui5-list>
9595
<ui5-li>Hello</ui5-li>
9696
<ui5-li>World</ui5-li>
@@ -293,27 +293,27 @@
293293
</ui5-popover>
294294

295295
<script>
296-
btn.addEventListener('click', function (event) {
296+
btn.addEventListener("click", function (event) {
297297
pop.openBy(btn);
298298
});
299299

300-
popbtn.addEventListener('click', function (event) {
300+
popbtn.addEventListener("click", function (event) {
301301
danger.openBy(popbtn);
302302
});
303303

304-
bigDanger.addEventListener('click', function (event) {
304+
bigDanger.addEventListener("click", function (event) {
305305
bigDangerPop.openBy(bigDanger);
306306
});
307307

308-
btnPopModal.addEventListener('click', function (event) {
308+
btnPopModal.addEventListener("click", function (event) {
309309
modalPopover.openBy(btnPopModal);
310310
});
311311

312-
modalPopoverClose.addEventListener('click', function (event) {
312+
modalPopoverClose.addEventListener("click", function (event) {
313313
modalPopover.close();
314314
});
315315

316-
btnPopFocus.addEventListener('click', function (event) {
316+
btnPopFocus.addEventListener("click", function (event) {
317317
popFocus.openBy(btnPopFocus);
318318
});
319319

@@ -329,30 +329,30 @@
329329
document.getElementById("big-popover").openBy(event.target);
330330
});
331331

332-
btnFullWidth.addEventListener('click', function (event) {
332+
btnFullWidth.addEventListener("click", function (event) {
333333
popFullWidth.openBy(btnFullWidth);
334334
});
335335

336-
btnFullWidthTargetOverlap.addEventListener('click', function (event) {
336+
btnFullWidthTargetOverlap.addEventListener("click", function (event) {
337337
popFullWidthTargetOverlap.openBy(btnFullWidthTargetOverlap);
338338
});
339339

340-
btnFullWidthLeft.addEventListener('click', function (event) {
340+
btnFullWidthLeft.addEventListener("click", function (event) {
341341
popFullWidthLeft.openBy(btnFullWidthLeft);
342342
});
343343

344-
btnFullWidthLeftTargetOverlap.addEventListener('click', function (event) {
344+
btnFullWidthLeftTargetOverlap.addEventListener("click", function (event) {
345345
popFullWidthLeftTargetOverlap.openBy(btnFullWidthLeftTargetOverlap);
346346
});
347347

348-
btnFullWidthTop.addEventListener('click', function (event) {
348+
btnFullWidthTop.addEventListener("click", function (event) {
349349
popFullWidthTop.openBy(btnFullWidthTop);
350350
});
351351

352-
btnFullWidthBottom.addEventListener('click', function (event) {
352+
btnFullWidthBottom.addEventListener("click", function (event) {
353353
popFullWidthBottom.openBy(btnFullWidthBottom);
354354
});
355355
</script>
356356
</body>
357357

358-
</html>
358+
</html>

0 commit comments

Comments
 (0)
Please sign in to comment.