feat: provide means to obtain popoutWindow document

This commit is contained in:
mathuo 2024-01-27 14:11:47 +00:00
parent b901f4de0c
commit a24dd21ca2
No known key found for this signature in database
GPG Key ID: C6EEDEFD6CA07281
16 changed files with 288 additions and 200 deletions

View File

@ -11,7 +11,7 @@ describe('groupDragHandler', () => {
const groupMock = jest.fn<DockviewGroupPanel, []>(() => {
const partial: Partial<DockviewGroupPanel> = {
id: 'test_group_id',
api: { location: 'grid' } as any,
api: { location: { type: 'grid' } } as any,
};
return partial as DockviewGroupPanel;
});
@ -53,7 +53,7 @@ describe('groupDragHandler', () => {
const groupMock = jest.fn<DockviewGroupPanel, []>(() => {
const partial: Partial<DockviewGroupPanel> = {
api: { location: 'floating' } as any,
api: { location: { type: 'floating' } } as any,
};
return partial as DockviewGroupPanel;
});
@ -85,7 +85,7 @@ describe('groupDragHandler', () => {
const groupMock = jest.fn<DockviewGroupPanel, []>(() => {
const partial: Partial<DockviewGroupPanel> = {
api: { location: 'grid' } as any,
api: { location: { type: 'grid' } } as any,
};
return partial as DockviewGroupPanel;
});

View File

@ -9,6 +9,7 @@ import { DockviewGroupPanelModel } from '../../../../dockview/dockviewGroupPanel
import { fireEvent } from '@testing-library/dom';
import { TestPanel } from '../../dockviewGroupPanelModel.spec';
import { IDockviewPanel } from '../../../../dockview/dockviewPanel';
import { fromPartial } from '@total-typescript/shoehorn';
describe('tabsContainer', () => {
test('that an external event does not render a drop target and calls through to the group mode', () => {
@ -478,7 +479,7 @@ describe('tabsContainer', () => {
const groupPanelMock = jest.fn<DockviewGroupPanel, []>(() => {
return (<Partial<DockviewGroupPanel>>{
api: { location: 'grid' } as any,
api: { location: { type: 'grid' } } as any,
}) as DockviewGroupPanel;
});
@ -538,7 +539,7 @@ describe('tabsContainer', () => {
const groupPanelMock = jest.fn<DockviewGroupPanel, []>(() => {
return (<Partial<DockviewGroupPanel>>{
api: { location: 'floating' } as any,
api: { location: { type: 'floating' } } as any,
}) as DockviewGroupPanel;
});
@ -591,7 +592,7 @@ describe('tabsContainer', () => {
const groupPanelMock = jest.fn<DockviewGroupPanel, []>(() => {
return (<Partial<DockviewGroupPanel>>{
api: { location: 'floating' } as any,
api: { location: { type: 'floating' } } as any,
model: {} as any,
}) as DockviewGroupPanel;
});
@ -601,23 +602,20 @@ describe('tabsContainer', () => {
const cut = new TabsContainer(accessor, groupPanel);
const panelMock = jest.fn<IDockviewPanel, [string]>((id: string) => {
const partial: Partial<IDockviewPanel> = {
const createPanel = (id: string) =>
fromPartial<IDockviewPanel>({
id,
view: {
tab: {
element: document.createElement('div'),
} as any,
},
content: {
element: document.createElement('div'),
} as any,
} as any,
};
return partial as IDockviewPanel;
},
},
});
const panel = new panelMock('test_id');
const panel = createPanel('test_id');
cut.openPanel(panel);
const el = cut.element.querySelector('.tab')!;
@ -628,15 +626,15 @@ describe('tabsContainer', () => {
fireEvent(el, event);
// a floating group with a single tab shouldn't be eligible
expect(preventDefaultSpy).toBeCalledTimes(0);
expect(accessor.addFloatingGroup).toBeCalledTimes(0);
expect(preventDefaultSpy).toHaveBeenCalledTimes(0);
expect(accessor.addFloatingGroup).toHaveBeenCalledTimes(0);
const panel2 = new panelMock('test_id_2');
const panel2 = createPanel('test_id_2');
cut.openPanel(panel2);
fireEvent(el, event);
expect(preventDefaultSpy).toBeCalledTimes(1);
expect(accessor.addFloatingGroup).toBeCalledTimes(1);
expect(preventDefaultSpy).toHaveBeenCalledTimes(1);
expect(accessor.addFloatingGroup).toHaveBeenCalledTimes(1);
});
test('pre header actions', () => {
@ -653,7 +651,7 @@ describe('tabsContainer', () => {
const groupPanelMock = jest.fn<DockviewGroupPanel, []>(() => {
return (<Partial<DockviewGroupPanel>>{
api: { location: 'grid' } as any,
api: { location: { type: 'grid' } } as any,
model: {} as any,
}) as DockviewGroupPanel;
});
@ -723,7 +721,7 @@ describe('tabsContainer', () => {
const groupPanelMock = jest.fn<DockviewGroupPanel, []>(() => {
return (<Partial<DockviewGroupPanel>>{
api: { location: 'grid' } as any,
api: { location: { type: 'grid' } } as any,
model: {} as any,
}) as DockviewGroupPanel;
});
@ -793,7 +791,7 @@ describe('tabsContainer', () => {
const groupPanelMock = jest.fn<DockviewGroupPanel, []>(() => {
return (<Partial<DockviewGroupPanel>>{
api: { location: 'grid' } as any,
api: { location: { type: 'grid' } } as any,
model: {} as any,
}) as DockviewGroupPanel;
});

View File

@ -3452,8 +3452,8 @@ describe('dockviewComponent', () => {
floating: true,
});
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(2);
@ -3464,8 +3464,8 @@ describe('dockviewComponent', () => {
'right'
);
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('grid');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('grid');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(2);
});
@ -3497,8 +3497,8 @@ describe('dockviewComponent', () => {
floating: true,
});
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(2);
@ -3509,8 +3509,8 @@ describe('dockviewComponent', () => {
'center'
);
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('grid');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('grid');
expect(dockview.groups.length).toBe(1);
expect(dockview.panels.length).toBe(2);
});
@ -3548,9 +3548,9 @@ describe('dockviewComponent', () => {
floating: true,
});
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('floating');
expect(panel3.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('floating');
expect(panel3.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(3);
expect(dockview.panels.length).toBe(3);
@ -3561,9 +3561,9 @@ describe('dockviewComponent', () => {
'center'
);
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('floating');
expect(panel3.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('floating');
expect(panel3.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(3);
});
@ -3601,9 +3601,9 @@ describe('dockviewComponent', () => {
position: { referencePanel: panel2 },
});
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('floating');
expect(panel3.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('floating');
expect(panel3.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(3);
@ -3614,9 +3614,9 @@ describe('dockviewComponent', () => {
'right'
);
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('grid');
expect(panel3.group.api.location).toBe('grid');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('grid');
expect(panel3.group.api.location.type).toBe('grid');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(3);
});
@ -3654,9 +3654,9 @@ describe('dockviewComponent', () => {
position: { referencePanel: panel2 },
});
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('floating');
expect(panel3.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('floating');
expect(panel3.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(3);
@ -3667,9 +3667,9 @@ describe('dockviewComponent', () => {
'center'
);
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('grid');
expect(panel3.group.api.location).toBe('grid');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('grid');
expect(panel3.group.api.location.type).toBe('grid');
expect(dockview.groups.length).toBe(1);
expect(dockview.panels.length).toBe(3);
});
@ -3713,10 +3713,10 @@ describe('dockviewComponent', () => {
floating: true,
});
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('floating');
expect(panel3.group.api.location).toBe('floating');
expect(panel4.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('floating');
expect(panel3.group.api.location.type).toBe('floating');
expect(panel4.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(3);
expect(dockview.panels.length).toBe(4);
@ -3727,10 +3727,10 @@ describe('dockviewComponent', () => {
'center'
);
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('floating');
expect(panel3.group.api.location).toBe('floating');
expect(panel4.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('floating');
expect(panel3.group.api.location.type).toBe('floating');
expect(panel4.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(4);
});
@ -3762,8 +3762,8 @@ describe('dockviewComponent', () => {
floating: true,
});
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(2);
@ -3774,8 +3774,8 @@ describe('dockviewComponent', () => {
'right'
);
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('grid');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('grid');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(2);
});
@ -3807,8 +3807,8 @@ describe('dockviewComponent', () => {
floating: true,
});
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(2);
@ -3819,8 +3819,8 @@ describe('dockviewComponent', () => {
'center'
);
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('grid');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('grid');
expect(dockview.groups.length).toBe(1);
expect(dockview.panels.length).toBe(2);
});
@ -3858,9 +3858,9 @@ describe('dockviewComponent', () => {
floating: true,
});
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('floating');
expect(panel3.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('floating');
expect(panel3.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(3);
expect(dockview.panels.length).toBe(3);
@ -3871,9 +3871,9 @@ describe('dockviewComponent', () => {
'center'
);
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('floating');
expect(panel3.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('floating');
expect(panel3.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(3);
});
@ -3911,9 +3911,9 @@ describe('dockviewComponent', () => {
position: { referencePanel: panel2 },
});
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('floating');
expect(panel3.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('floating');
expect(panel3.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(3);
@ -3924,9 +3924,9 @@ describe('dockviewComponent', () => {
'right'
);
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('grid');
expect(panel3.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('grid');
expect(panel3.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(3);
expect(dockview.panels.length).toBe(3);
});
@ -3964,9 +3964,9 @@ describe('dockviewComponent', () => {
position: { referencePanel: panel2 },
});
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('floating');
expect(panel3.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('floating');
expect(panel3.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(3);
@ -3977,9 +3977,9 @@ describe('dockviewComponent', () => {
'center'
);
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('grid');
expect(panel3.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('grid');
expect(panel3.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(3);
});
@ -4023,10 +4023,10 @@ describe('dockviewComponent', () => {
floating: true,
});
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('floating');
expect(panel3.group.api.location).toBe('floating');
expect(panel4.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('floating');
expect(panel3.group.api.location.type).toBe('floating');
expect(panel4.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(3);
expect(dockview.panels.length).toBe(4);
@ -4037,10 +4037,10 @@ describe('dockviewComponent', () => {
'center'
);
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('floating');
expect(panel3.group.api.location).toBe('floating');
expect(panel4.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('floating');
expect(panel3.group.api.location.type).toBe('floating');
expect(panel4.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(3);
expect(dockview.panels.length).toBe(4);
});
@ -4078,9 +4078,9 @@ describe('dockviewComponent', () => {
floating: true,
});
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('grid');
expect(panel3.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('grid');
expect(panel3.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(3);
expect(dockview.panels.length).toBe(3);
@ -4091,9 +4091,9 @@ describe('dockviewComponent', () => {
'center'
);
expect(panel1.group.api.location).toBe('floating');
expect(panel2.group.api.location).toBe('grid');
expect(panel3.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('floating');
expect(panel2.group.api.location.type).toBe('grid');
expect(panel3.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(3);
});
@ -4130,9 +4130,9 @@ describe('dockviewComponent', () => {
floating: true,
});
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('grid');
expect(panel3.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('grid');
expect(panel3.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(3);
@ -4143,9 +4143,9 @@ describe('dockviewComponent', () => {
'center'
);
expect(panel1.group.api.location).toBe('floating');
expect(panel2.group.api.location).toBe('grid');
expect(panel3.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('floating');
expect(panel2.group.api.location.type).toBe('grid');
expect(panel3.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(3);
});
@ -4183,9 +4183,9 @@ describe('dockviewComponent', () => {
floating: true,
});
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('grid');
expect(panel3.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('grid');
expect(panel3.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(3);
expect(dockview.panels.length).toBe(3);
@ -4196,9 +4196,9 @@ describe('dockviewComponent', () => {
'center'
);
expect(panel1.group.api.location).toBe('floating');
expect(panel2.group.api.location).toBe('grid');
expect(panel3.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('floating');
expect(panel2.group.api.location.type).toBe('grid');
expect(panel3.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(3);
});
@ -4235,9 +4235,9 @@ describe('dockviewComponent', () => {
floating: true,
});
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('grid');
expect(panel3.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('grid');
expect(panel3.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(3);
@ -4248,9 +4248,9 @@ describe('dockviewComponent', () => {
'center'
);
expect(panel1.group.api.location).toBe('floating');
expect(panel2.group.api.location).toBe('floating');
expect(panel3.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('floating');
expect(panel2.group.api.location.type).toBe('floating');
expect(panel3.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(1);
expect(dockview.panels.length).toBe(3);
});
@ -4282,15 +4282,15 @@ describe('dockviewComponent', () => {
position: { direction: 'right' },
});
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('grid');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('grid');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(2);
dockview.addFloatingGroup(panel2);
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(2);
});
@ -4321,15 +4321,15 @@ describe('dockviewComponent', () => {
component: 'default',
});
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('grid');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('grid');
expect(dockview.groups.length).toBe(1);
expect(dockview.panels.length).toBe(2);
dockview.addFloatingGroup(panel2);
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(2);
});
@ -4361,15 +4361,15 @@ describe('dockviewComponent', () => {
position: { direction: 'right' },
});
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('grid');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('grid');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(2);
dockview.addFloatingGroup(panel2.group);
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(2);
});
@ -4400,15 +4400,15 @@ describe('dockviewComponent', () => {
component: 'default',
});
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('grid');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('grid');
expect(dockview.groups.length).toBe(1);
expect(dockview.panels.length).toBe(2);
dockview.addFloatingGroup(panel2.group);
expect(panel1.group.api.location).toBe('floating');
expect(panel2.group.api.location).toBe('floating');
expect(panel1.group.api.location.type).toBe('floating');
expect(panel2.group.api.location.type).toBe('floating');
expect(dockview.groups.length).toBe(1);
expect(dockview.panels.length).toBe(2);
});
@ -4440,7 +4440,7 @@ describe('dockviewComponent', () => {
expect(dockview.panels.length).toBe(1);
expect(dockview.groups.length).toBe(1);
expect(panel1.api.group.api.location).toBe('popout');
expect(panel1.api.group.api.location.type).toBe('popout');
dockview.removePanel(panel1);
@ -4474,15 +4474,15 @@ describe('dockviewComponent', () => {
component: 'default',
});
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('grid');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('grid');
expect(dockview.groups.length).toBe(1);
expect(dockview.panels.length).toBe(2);
dockview.addPopoutGroup(panel2.group);
expect(panel1.group.api.location).toBe('popout');
expect(panel2.group.api.location).toBe('popout');
expect(panel1.group.api.location.type).toBe('popout');
expect(panel2.group.api.location.type).toBe('popout');
expect(dockview.groups.length).toBe(1);
expect(dockview.panels.length).toBe(2);
});
@ -4521,17 +4521,17 @@ describe('dockviewComponent', () => {
},
});
expect(panel1.group.api.location).toBe('grid');
expect(panel2.group.api.location).toBe('grid');
expect(panel3.group.api.location).toBe('grid');
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('grid');
expect(panel3.group.api.location.type).toBe('grid');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(3);
dockview.addPopoutGroup(panel2.group);
expect(panel1.group.api.location).toBe('popout');
expect(panel2.group.api.location).toBe('popout');
expect(panel3.group.api.location).toBe('grid');
expect(panel1.group.api.location.type).toBe('popout');
expect(panel2.group.api.location.type).toBe('popout');
expect(panel3.group.api.location.type).toBe('grid');
expect(dockview.groups.length).toBe(2);
expect(dockview.panels.length).toBe(3);
@ -4542,9 +4542,9 @@ describe('dockviewComponent', () => {
'right'
);
expect(panel1.group.api.location).toBe('popout');
expect(panel2.group.api.location).toBe('grid');
expect(panel3.group.api.location).toBe('grid');
expect(panel1.group.api.location.type).toBe('popout');
expect(panel2.group.api.location.type).toBe('grid');
expect(panel3.group.api.location.type).toBe('grid');
expect(dockview.groups.length).toBe(3);
expect(dockview.panels.length).toBe(3);
});

View File

@ -41,7 +41,7 @@ describe('overlayRenderContainer', () => {
},
group: {
api: {
location: 'grid',
location: { type: 'grid' },
},
},
});
@ -77,7 +77,7 @@ describe('overlayRenderContainer', () => {
},
group: {
api: {
location: 'grid',
location: { type: 'grid' },
},
},
});

View File

@ -8,6 +8,13 @@ import { GridviewPanelApi, GridviewPanelApiImpl } from './gridviewPanelApi';
export interface DockviewGroupPanelApi extends GridviewPanelApi {
readonly onDidLocationChange: Event<DockviewGroupPanelFloatingChangeEvent>;
readonly location: DockviewGroupLocation;
/**
*
* If you require the documents Window object you can call `document.defaultView`.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/Document/defaultView
*/
getDocument(): Document;
moveTo(options: { group?: DockviewGroupPanel; position?: Position }): void;
maximize(): void;
isMaximized(): boolean;
@ -42,6 +49,12 @@ export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
this.addDisposables(this._onDidLocationChange);
}
getDocument(): Document {
return this.location.type === 'popout'
? this.location.getWindow().document
: window.document;
}
moveTo(options: { group?: DockviewGroupPanel; position?: Position }): void {
if (!this._group) {
throw new Error(NOT_INITIALIZED_MESSAGE);
@ -66,7 +79,7 @@ export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
throw new Error(NOT_INITIALIZED_MESSAGE);
}
if (this.location !== 'grid') {
if (this.location.type !== 'grid') {
// only grid groups can be maximized
return;
}

View File

@ -1,11 +1,13 @@
import { Emitter, Event } from '../events';
import { GridviewPanelApiImpl, GridviewPanelApi } from './gridviewPanelApi';
import { DockviewGroupPanel } from '../dockview/dockviewGroupPanel';
import { MutableDisposable } from '../lifecycle';
import { CompositeDisposable, MutableDisposable } from '../lifecycle';
import { DockviewPanel } from '../dockview/dockviewPanel';
import { DockviewComponent } from '../dockview/dockviewComponent';
import { Position } from '../dnd/droptarget';
import { DockviewPanelRenderer } from '../overlayRenderContainer';
import { DockviewGroupPanelFloatingChangeEvent } from './dockviewGroupPanelApi';
import { DockviewGroupLocation } from '../dockview/dockviewGroupPanelModel';
export interface TitleEvent {
readonly title: string;
@ -28,6 +30,8 @@ export interface DockviewPanelApi
readonly onDidActiveGroupChange: Event<void>;
readonly onDidGroupChange: Event<void>;
readonly onDidRendererChange: Event<RendererChangedEvent>;
readonly location: DockviewGroupLocation;
readonly onDidLocationChange: Event<DockviewGroupPanelFloatingChangeEvent>;
close(): void;
setTitle(title: string): void;
setRenderer(renderer: DockviewPanelRenderer): void;
@ -39,6 +43,13 @@ export interface DockviewPanelApi
maximize(): void;
isMaximized(): boolean;
exitMaximized(): void;
/**
*
* If you require the documents Window object you can call `document.defaultView`.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/Document/defaultView
*/
getDocument(): Document;
}
export class DockviewPanelApiImpl
@ -59,7 +70,16 @@ export class DockviewPanelApiImpl
readonly _onDidRendererChange = new Emitter<RendererChangedEvent>();
readonly onDidRendererChange = this._onDidRendererChange.event;
private readonly disposable = new MutableDisposable();
private readonly _onDidLocationChange =
new Emitter<DockviewGroupPanelFloatingChangeEvent>();
readonly onDidLocationChange: Event<DockviewGroupPanelFloatingChangeEvent> =
this._onDidLocationChange.event;
private readonly groupEventsDisposable = new MutableDisposable();
get location(): DockviewGroupLocation {
return this.group.api.location;
}
get title(): string | undefined {
return this.panel.title;
@ -81,13 +101,22 @@ export class DockviewPanelApiImpl
this._onDidGroupChange.fire();
if (this._group) {
this.disposable.value = this._group.api.onDidActiveChange(() => {
this.groupEventsDisposable.value = new CompositeDisposable(
this.group.api.onDidLocationChange((event) => {
this._onDidLocationChange.fire(event);
}),
this.group.api.onDidActiveChange(() => {
this._onDidActiveGroupChange.fire();
});
})
);
if (this.isGroupActive !== isOldGroupActive) {
this._onDidActiveGroupChange.fire();
}
this._onDidLocationChange.fire({
location: this.group.api.location,
});
}
}
@ -107,14 +136,19 @@ export class DockviewPanelApiImpl
this._group = group;
this.addDisposables(
this.disposable,
this.groupEventsDisposable,
this._onDidRendererChange,
this._onDidTitleChange,
this._onDidGroupChange,
this._onDidActiveGroupChange
this._onDidActiveGroupChange,
this._onDidLocationChange
);
}
getDocument(): Document {
return this.group.api.getDocument();
}
moveTo(options: {
group: DockviewGroupPanel;
position?: Position;

View File

@ -38,7 +38,7 @@ export class GroupDragHandler extends DragHandler {
}
override isCancelled(_event: DragEvent): boolean {
if (this.group.api.location === 'floating' && !_event.shiftKey) {
if (this.group.api.location.type === 'floating' && !_event.shiftKey) {
return true;
}
return false;

View File

@ -71,7 +71,7 @@ export class ContentContainer
if (
!data &&
event.shiftKey &&
this.group.location !== 'floating'
this.group.location.type !== 'floating'
) {
return false;
}

View File

@ -247,7 +247,7 @@ export class TabsContainer
if (
isFloatingGroupsEnabled &&
event.shiftKey &&
this.group.api.location !== 'floating'
this.group.api.location.type !== 'floating'
) {
event.preventDefault();
@ -350,7 +350,7 @@ export class TabsContainer
!this.accessor.options.disableFloatingGroups;
const isFloatingWithOnePanel =
this.group.api.location === 'floating' && this.size === 1;
this.group.api.location.type === 'floating' && this.size === 1;
if (
isFloatingGroupsEnabled &&

View File

@ -67,6 +67,7 @@ import {
DockviewPanelRenderer,
OverlayRenderContainer,
} from '../overlayRenderContainer';
import { PopoutWindow } from '../popoutWindow';
const DEFAULT_ROOT_OVERLAY_MODEL: DroptargetOverlayModel = {
activationSize: { type: 'pixels', value: 10 },
@ -608,7 +609,7 @@ export class DockviewComponent
}
}
group.model.location = 'floating';
group.model.location = { type: 'floating' };
const overlayLeft =
typeof coord?.x === 'number'
@ -683,7 +684,7 @@ export class DockviewComponent
dispose: () => {
disposable.dispose();
group.model.location = 'grid';
group.model.location = { type: 'grid' };
remove(this._floatingGroups, floatingGroupPanel);
this.updateWatermark();
},
@ -1173,7 +1174,7 @@ export class DockviewComponent
group.model.openPanel(panel);
this.doSetGroupAndPanelActive(group);
} else if (
referenceGroup.api.location === 'floating' ||
referenceGroup.api.location.type === 'floating' ||
target === 'center'
) {
panel = this.createPanel(options, referenceGroup);
@ -1259,7 +1260,10 @@ export class DockviewComponent
}
private updateWatermark(): void {
if (this.groups.filter((x) => x.api.location === 'grid').length === 0) {
if (
this.groups.filter((x) => x.api.location.type === 'grid').length ===
0
) {
if (!this.watermark) {
this.watermark = this.createWatermarkComponent();
@ -1377,7 +1381,7 @@ export class DockviewComponent
}
| undefined
): DockviewGroupPanel {
if (group.api.location === 'floating') {
if (group.api.location.type === 'floating') {
const floatingGroup = this._floatingGroups.find(
(_) => _.group === group
);
@ -1406,7 +1410,7 @@ export class DockviewComponent
throw new Error('failed to find floating group');
}
if (group.api.location === 'popout') {
if (group.api.location.type === 'popout') {
const selectedGroup = this._popoutGroups.find(
(_) => _.group === group
);
@ -1486,7 +1490,7 @@ export class DockviewComponent
if (sourceGroup && sourceGroup.size < 2) {
const [targetParentLocation, to] = tail(targetLocation);
if (sourceGroup.api.location === 'grid') {
if (sourceGroup.api.location.type === 'grid') {
const sourceLocation = getGridLocation(sourceGroup.element);
const [sourceParentLocation, from] = tail(sourceLocation);
@ -1562,7 +1566,7 @@ export class DockviewComponent
});
}
} else {
switch (sourceGroup.api.location) {
switch (sourceGroup.api.location.type) {
case 'grid':
this.gridview.removeView(
getGridLocation(sourceGroup.element)

View File

@ -130,7 +130,10 @@ export interface IDockviewGroupPanelModel extends IPanel {
): boolean;
}
export type DockviewGroupLocation = 'grid' | 'floating' | 'popout';
export type DockviewGroupLocation =
| { type: 'grid' }
| { type: 'floating' }
| { type: 'popout'; getWindow: () => Window };
export class DockviewGroupPanelModel
extends CompositeDisposable
@ -146,7 +149,7 @@ export class DockviewGroupPanelModel
private _leftHeaderActions: IHeaderActionsRenderer | undefined;
private _prefixHeaderActions: IHeaderActionsRenderer | undefined;
private _location: DockviewGroupLocation = 'grid';
private _location: DockviewGroupLocation = { type: 'grid' };
private mostRecentlyUsed: IDockviewPanel[] = [];
@ -253,7 +256,7 @@ export class DockviewGroupPanelModel
toggleClass(this.container, 'dv-groupview-floating', false);
toggleClass(this.container, 'dv-groupview-popout', false);
switch (value) {
switch (value.type) {
case 'grid':
this.contentContainer.dropTarget.setTargetZones([
'top',

View File

@ -25,13 +25,16 @@ export class DockviewPopoutGroupPanel extends CompositeDisposable {
height: this.options.box.height,
});
group.model.location = 'popout';
group.model.location = {
type: 'popout',
getWindow: () => this.window.window!,
};
this.addDisposables(
this.window,
{
dispose: () => {
group.model.location = 'grid';
group.model.location = { type: 'grid' };
},
},
this.window.onDidClose(() => {

View File

@ -11,6 +11,8 @@ export {
CompositeDisposable as DockviewCompositeDisposable,
} from './lifecycle';
export { PopoutWindow } from './popoutWindow';
export * from './panel/types';
export * from './panel/componentFactory';

View File

@ -93,7 +93,7 @@ export class OverlayRenderContainer extends CompositeDisposable {
toggleClass(
focusContainer,
'dv-render-overlay-float',
panel.group.api.location === 'floating'
panel.group.api.location.type === 'floating'
);
};

View File

@ -8,19 +8,26 @@ export type PopoutWindowOptions = {
} & Box;
export class PopoutWindow extends CompositeDisposable {
private readonly _onWillClose = new Emitter<void>();
readonly onWillClose = this._onWillClose.event;
private readonly _onDidClose = new Emitter<void>();
readonly onDidClose = this._onDidClose.event;
private _window: { value: Window; disposable: IDisposable } | null = null;
get window(): Window | null {
return this._window?.value ?? null;
}
constructor(
private readonly id: string,
private readonly target: string,
private readonly className: string,
private readonly options: PopoutWindowOptions
) {
super();
this.addDisposables(this._onDidClose, {
this.addDisposables(this._onWillClose, this._onDidClose, {
dispose: () => {
this.close();
},
@ -42,9 +49,13 @@ export class PopoutWindow extends CompositeDisposable {
close(): void {
if (this._window) {
this._onWillClose.fire();
this._window.disposable.dispose();
this._window.value.close();
this._window = null;
this._onDidClose.fire();
}
}
@ -64,8 +75,10 @@ export class PopoutWindow extends CompositeDisposable {
.map(([key, value]) => `${key}=${value}`)
.join(',');
// https://developer.mozilla.org/en-US/docs/Web/API/Window/open
const externalWindow = window.open(url, this.id, features);
/**
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window/open
*/
const externalWindow = window.open(url, this.target, features);
if (!externalWindow) {
return;
@ -75,44 +88,55 @@ export class PopoutWindow extends CompositeDisposable {
this._window = { value: externalWindow, disposable };
const cleanUp = () => {
this._onDidClose.fire();
this._window = null;
};
// prevent any default content from loading
// externalWindow.document.body.replaceWith(document.createElement('div'));
disposable.addDisposables(
addDisposableWindowListener(window, 'beforeunload', () => {
cleanUp();
/**
* before the main window closes we should close this popup too
* to be good citizens
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
*/
this.close();
})
);
externalWindow.addEventListener('load', () => {
/**
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
*/
const externalDocument = externalWindow.document;
externalDocument.title = document.title;
const div = document.createElement('div');
div.classList.add('dv-popout-window');
div.style.position = 'absolute';
div.style.width = '100%';
div.style.height = '100%';
div.style.top = '0px';
div.style.left = '0px';
div.classList.add(this.className);
div.appendChild(content);
const container = this.createPopoutWindowContainer();
container.classList.add(this.className);
container.appendChild(content);
externalDocument.body.replaceChildren(div);
// externalDocument.body.replaceChildren(container);
externalDocument.body.appendChild(container);
externalDocument.body.classList.add(this.className);
addStyles(externalDocument, window.document.styleSheets);
externalWindow.addEventListener('beforeunload', () => {
// TODO: indicate external window is closing
cleanUp();
/**
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
*/
this.close();
});
});
}
private createPopoutWindowContainer(): HTMLElement {
const el = document.createElement('div');
el.classList.add('dv-popout-window');
el.id = 'dv-popout-window';
el.style.position = 'absolute';
el.style.width = '100%';
el.style.height = '100%';
el.style.top = '0px';
el.style.left = '0px';
return el;
}
}

View File

@ -13882,6 +13882,13 @@ react-json-view-lite@^1.2.0:
resolved "https://registry.yarnpkg.com/react-json-view-lite/-/react-json-view-lite-1.2.1.tgz#c59a0bea4ede394db331d482ee02e293d38f8218"
integrity sha512-Itc0g86fytOmKZoIoJyGgvNqohWSbh3NXIKNgH6W6FT9PC1ck4xas1tT3Rr/b3UlFXyA9Jjaw9QSXdZy2JwGMQ==
react-laag@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/react-laag/-/react-laag-2.0.5.tgz#549f1035b761b9ba09ac98fd128ccad63464c877"
integrity sha512-RCvublJhdcgGRHU1wMYJ8kRtnYsKUgYusLvVhMuftg65POnnOB4+fwXvnETm6adc0cMnc1spujlrK6bGIz6aug==
dependencies:
tiny-warning "^1.0.3"
react-loadable-ssr-addon-v5-slorber@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz#2cdc91e8a744ffdf9e3556caabeb6e4278689883"
@ -15678,7 +15685,7 @@ tiny-invariant@^1.0.2:
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642"
integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==
tiny-warning@^1.0.0:
tiny-warning@^1.0.0, tiny-warning@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==