mirror of
https://github.com/mathuo/dockview
synced 2025-10-11 18:38:05 +00:00
Merge pull request #937 from mathuo/936-handle-browser-blocked-popups
936 handle browser blocked popups
This commit is contained in:
commit
588fe9b28c
@ -5852,6 +5852,54 @@ describe('dockviewComponent', () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('when browsers block popups', () => {
|
||||||
|
let container: HTMLDivElement;
|
||||||
|
let dockview: DockviewComponent;
|
||||||
|
let panel: DockviewPanel;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.spyOn(window, 'open').mockReturnValue(null);
|
||||||
|
|
||||||
|
container = document.createElement('div');
|
||||||
|
|
||||||
|
dockview = new DockviewComponent(container, {
|
||||||
|
createComponent(options) {
|
||||||
|
switch (options.name) {
|
||||||
|
case 'default':
|
||||||
|
return new PanelContentPartTest(
|
||||||
|
options.id,
|
||||||
|
options.name
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
throw new Error(`unsupported`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
dockview.layout(1000, 500);
|
||||||
|
|
||||||
|
panel = dockview.addPanel({
|
||||||
|
id: 'panel_1',
|
||||||
|
component: 'default',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('onDidOpenPoputWindowFail event is emitted', async () => {
|
||||||
|
const onDidBlockPopoutHandler = jest.fn();
|
||||||
|
dockview.onDidOpenPopoutWindowFail(onDidBlockPopoutHandler);
|
||||||
|
|
||||||
|
await dockview.addPopoutGroup(panel.group);
|
||||||
|
|
||||||
|
expect(onDidBlockPopoutHandler).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('popout group is restored to its original position', async () => {
|
||||||
|
await dockview.addPopoutGroup(panel.group);
|
||||||
|
|
||||||
|
expect(panel.group.api.location.type).toBe('grid');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test('dispose of dockview instance when popup is open', async () => {
|
test('dispose of dockview instance when popup is open', async () => {
|
||||||
const container = document.createElement('div');
|
const container = document.createElement('div');
|
||||||
|
|
||||||
|
@ -749,6 +749,10 @@ export class DockviewApi implements CommonApi<SerializedDockview> {
|
|||||||
return this.component.onDidPopoutGroupPositionChange;
|
return this.component.onDidPopoutGroupPositionChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get onDidOpenPopoutWindowFail(): Event<void> {
|
||||||
|
return this.component.onDidOpenPopoutWindowFail;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All panel objects.
|
* All panel objects.
|
||||||
*/
|
*/
|
||||||
|
@ -227,6 +227,7 @@ export interface IDockviewComponent extends IBaseGrid<DockviewGroupPanel> {
|
|||||||
readonly onDidMaximizedGroupChange: Event<DockviewMaximizedGroupChanged>;
|
readonly onDidMaximizedGroupChange: Event<DockviewMaximizedGroupChanged>;
|
||||||
readonly onDidPopoutGroupSizeChange: Event<PopoutGroupChangeSizeEvent>;
|
readonly onDidPopoutGroupSizeChange: Event<PopoutGroupChangeSizeEvent>;
|
||||||
readonly onDidPopoutGroupPositionChange: Event<PopoutGroupChangePositionEvent>;
|
readonly onDidPopoutGroupPositionChange: Event<PopoutGroupChangePositionEvent>;
|
||||||
|
readonly onDidOpenPopoutWindowFail: Event<void>;
|
||||||
readonly options: DockviewComponentOptions;
|
readonly options: DockviewComponentOptions;
|
||||||
updateOptions(options: DockviewOptions): void;
|
updateOptions(options: DockviewOptions): void;
|
||||||
moveGroupOrPanel(options: MoveGroupOrPanelOptions): void;
|
moveGroupOrPanel(options: MoveGroupOrPanelOptions): void;
|
||||||
@ -320,6 +321,10 @@ export class DockviewComponent
|
|||||||
readonly onDidPopoutGroupPositionChange: Event<PopoutGroupChangePositionEvent> =
|
readonly onDidPopoutGroupPositionChange: Event<PopoutGroupChangePositionEvent> =
|
||||||
this._onDidPopoutGroupPositionChange.event;
|
this._onDidPopoutGroupPositionChange.event;
|
||||||
|
|
||||||
|
private readonly _onDidOpenPopoutWindowFail = new Emitter<void>();
|
||||||
|
readonly onDidOpenPopoutWindowFail: Event<void> =
|
||||||
|
this._onDidOpenPopoutWindowFail.event;
|
||||||
|
|
||||||
private readonly _onDidLayoutFromJSON = new Emitter<void>();
|
private readonly _onDidLayoutFromJSON = new Emitter<void>();
|
||||||
readonly onDidLayoutFromJSON: Event<void> = this._onDidLayoutFromJSON.event;
|
readonly onDidLayoutFromJSON: Event<void> = this._onDidLayoutFromJSON.event;
|
||||||
|
|
||||||
@ -506,6 +511,7 @@ export class DockviewComponent
|
|||||||
this._onDidOptionsChange,
|
this._onDidOptionsChange,
|
||||||
this._onDidPopoutGroupSizeChange,
|
this._onDidPopoutGroupSizeChange,
|
||||||
this._onDidPopoutGroupPositionChange,
|
this._onDidPopoutGroupPositionChange,
|
||||||
|
this._onDidOpenPopoutWindowFail,
|
||||||
this.onDidViewVisibilityChangeMicroTaskQueue(() => {
|
this.onDidViewVisibilityChangeMicroTaskQueue(() => {
|
||||||
this.updateWatermark();
|
this.updateWatermark();
|
||||||
}),
|
}),
|
||||||
@ -714,19 +720,6 @@ export class DockviewComponent
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (popoutContainer === null) {
|
|
||||||
popoutWindowDisposable.dispose();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const gready = document.createElement('div');
|
|
||||||
gready.className = 'dv-overlay-render-container';
|
|
||||||
|
|
||||||
const overlayRenderContainer = new OverlayRenderContainer(
|
|
||||||
gready,
|
|
||||||
this
|
|
||||||
);
|
|
||||||
|
|
||||||
const referenceGroup = options?.referenceGroup
|
const referenceGroup = options?.referenceGroup
|
||||||
? options.referenceGroup
|
? options.referenceGroup
|
||||||
: itemToPopout instanceof DockviewPanel
|
: itemToPopout instanceof DockviewPanel
|
||||||
@ -736,7 +729,7 @@ export class DockviewComponent
|
|||||||
const referenceLocation = itemToPopout.api.location.type;
|
const referenceLocation = itemToPopout.api.location.type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The group that is being added doesn't already exist within the DOM, the most likely occurance
|
* The group that is being added doesn't already exist within the DOM, the most likely occurrence
|
||||||
* of this case is when being called from the `fromJSON(...)` method
|
* of this case is when being called from the `fromJSON(...)` method
|
||||||
*/
|
*/
|
||||||
const isGroupAddedToDom =
|
const isGroupAddedToDom =
|
||||||
@ -750,9 +743,44 @@ export class DockviewComponent
|
|||||||
group = options.overridePopoutGroup;
|
group = options.overridePopoutGroup;
|
||||||
} else {
|
} else {
|
||||||
group = this.createGroup({ id: groupId });
|
group = this.createGroup({ id: groupId });
|
||||||
this._onDidAddGroup.fire(group);
|
|
||||||
|
if (popoutContainer) {
|
||||||
|
this._onDidAddGroup.fire(group);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (popoutContainer === null) {
|
||||||
|
console.error(
|
||||||
|
'dockview: failed to create popout. perhaps you need to allow pop-ups for this website'
|
||||||
|
);
|
||||||
|
|
||||||
|
popoutWindowDisposable.dispose();
|
||||||
|
this._onDidOpenPopoutWindowFail.fire();
|
||||||
|
|
||||||
|
// if the popout window was blocked, we need to move the group back to the reference group
|
||||||
|
// and set it to visible
|
||||||
|
this.movingLock(() =>
|
||||||
|
moveGroupWithoutDestroying({
|
||||||
|
from: group,
|
||||||
|
to: referenceGroup,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!referenceGroup.api.isVisible) {
|
||||||
|
referenceGroup.api.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const gready = document.createElement('div');
|
||||||
|
gready.className = 'dv-overlay-render-container';
|
||||||
|
|
||||||
|
const overlayRenderContainer = new OverlayRenderContainer(
|
||||||
|
gready,
|
||||||
|
this
|
||||||
|
);
|
||||||
|
|
||||||
group.model.renderContainer = overlayRenderContainer;
|
group.model.renderContainer = overlayRenderContainer;
|
||||||
group.layout(
|
group.layout(
|
||||||
_window.window!.innerWidth,
|
_window.window!.innerWidth,
|
||||||
@ -968,7 +996,7 @@ export class DockviewComponent
|
|||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error('dockview: failed to create popout window', err);
|
console.error('dockview: failed to create popout.', err);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -143,6 +143,9 @@ export const App = (props: { theme?: string }) => {
|
|||||||
|
|
||||||
const load = (api: DockviewApi) => {
|
const load = (api: DockviewApi) => {
|
||||||
api.clear();
|
api.clear();
|
||||||
|
api.onDidOpenPopoutWindowFail(() => {
|
||||||
|
console.log('Popout blocked');
|
||||||
|
});
|
||||||
if (layout) {
|
if (layout) {
|
||||||
try {
|
try {
|
||||||
api.fromJSON(layout);
|
api.fromJSON(layout);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user