mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-07 19:22:14 +09:00
fix(app): keep popouts in the window they were opened in (#2561)
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
// @vitest-environment happy-dom
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {scopePortalHostToDocument} from '@app/features/ui/overlay/PortalHostContext';
|
||||
import {describe, expect, it} from 'vitest';
|
||||
|
||||
describe('scopePortalHostToDocument', () => {
|
||||
it('keeps a host that belongs to the scoped document', () => {
|
||||
const host = document.createElement('div');
|
||||
expect(scopePortalHostToDocument(host, document)).toBe(host);
|
||||
});
|
||||
|
||||
it('drops a host owned by another document', () => {
|
||||
const popoutDocument = document.implementation.createHTMLDocument('popout');
|
||||
const popoutHost = popoutDocument.createElement('div');
|
||||
expect(scopePortalHostToDocument(popoutHost, document)).toBeNull();
|
||||
expect(scopePortalHostToDocument(popoutHost, popoutDocument)).toBe(popoutHost);
|
||||
});
|
||||
|
||||
it('passes a missing host through', () => {
|
||||
expect(scopePortalHostToDocument(null, document)).toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -39,3 +39,8 @@ export function usePortalHost(): PortalHostElement {
|
||||
export function resolvePortalHost(host: PortalHostElement): HTMLElement {
|
||||
return host ?? document.body;
|
||||
}
|
||||
|
||||
export function scopePortalHostToDocument(host: PortalHostElement, scopeDocument: Document): PortalHostElement {
|
||||
if (host == null) return null;
|
||||
return host.ownerDocument === scopeDocument ? host : null;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import Accessibility from '@app/features/accessibility/state/Accessibility';
|
||||
import {useAntiShiftFloating} from '@app/features/app/hooks/useAntiShiftFloating';
|
||||
import {shouldDisableAutofocusOnMobile} from '@app/features/platform/utils/AutofocusUtils';
|
||||
import * as PopoutCommands from '@app/features/ui/commands/PopoutCommands';
|
||||
import {usePortalHost} from '@app/features/ui/overlay/PortalHostContext';
|
||||
import {scopePortalHostToDocument, usePortalHost} from '@app/features/ui/overlay/PortalHostContext';
|
||||
import {type Popout, PopoutKeyContext, type PopoutReferenceRect} from '@app/features/ui/popover';
|
||||
import {PopoutResizePositionContext} from '@app/features/ui/popover/PopoutResizePositionContext';
|
||||
import {getPopoutFocusManagerInsideElements} from '@app/features/ui/popover/PopoverFocusManagerUtils';
|
||||
@@ -426,10 +426,11 @@ interface PopoutsProps {
|
||||
|
||||
export const Popouts: React.FC<PopoutsProps> = observer(({ownerDocument}) => {
|
||||
const prevPopoutKeysRef = useRef<Set<string>>(new Set());
|
||||
const portalHost = usePortalHost();
|
||||
const activePortalHost = usePortalHost();
|
||||
let scopeDocument = document;
|
||||
if (portalHost != null) scopeDocument = portalHost.ownerDocument;
|
||||
if (activePortalHost != null) scopeDocument = activePortalHost.ownerDocument;
|
||||
if (ownerDocument != null) scopeDocument = ownerDocument;
|
||||
const portalHost = scopePortalHostToDocument(activePortalHost, scopeDocument);
|
||||
const popouts = PopoutState.getPopouts(scopeDocument);
|
||||
const topPopout = popouts.length ? popouts[popouts.length - 1] : null;
|
||||
const needsBackdrop = Boolean(topPopout && !topPopout.disableBackdrop);
|
||||
|
||||
Reference in New Issue
Block a user