Fix broken new collection dialog opened from context menu of a group (#5592)

Fix new collection dialog appearing broken when
opened via "New Collection" option of context menu
on "My Library" or a group in collection tree.

On macOS, the popup of collections would never leave
and on windows, subcollection would never appear.

This is a followup to zotero#5409
that fixes this issue for all collections. The reason
why it didn't work for groups is that the command event
would fire not on a menuitem but on the <command> node itself,
which is not what the workaround expects.

Now, if we get such an event, we'll try to use the
original 'command' event dispatched on the <menuitem>
from event.sourceEvent to locate the <menupopup>
and as a blueprint for redispatching the event.
This commit is contained in:
abaevbog 2025-11-10 11:14:47 -08:00 • committed by GitHub
parent 544e9d11a3
commit c45ed42af7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -120,7 +120,16 @@ Services.scriptloader.loadSubScript('chrome://zotero/content/elements/itemTreeMe
// stops propagation of those events, and then dispatches a copy of
// that event after a delay. This gives the popup enough time to close.
document.addEventListener("command", (event) => {
let originalEvent = event;
let originalTarget = event.target;
// When a 'command' event fires on a <command> node, it will have the original 'command'
// event with <menuitem> as target in event.sourceEvent.
// This is the event we want to work with, since we do not expect events with .sourceEvent
// and <command> has no menupopup ancestor.
if (originalTarget.localName === "command" && event.sourceEvent?.type === "command") {
event = event.sourceEvent;
originalTarget = event.target;
}
// Find the topmost menupopup containing the element that triggered the command
let menupopup = originalTarget.closest("menupopup:not(menupopup *)");
@ -137,8 +146,8 @@ Services.scriptloader.loadSubScript('chrome://zotero/content/elements/itemTreeMe
// Hide the popup and don't let anything else happen
menupopup.hidePopup(true);
event.stopPropagation();
event.preventDefault();
originalEvent.stopPropagation();
originalEvent.preventDefault();
// Create a copy of the 'command' event and re-dispatch it after a delay
let delayedEvent = document.createEvent("XULCommandEvent");