Add prevent option to ::onWillDestroyPaneItem

This commit is contained in:
Eric Cornelissen 2021-09-03 23:59:58 +02:00
parent 93d85e0aaf
commit 3652d2ff28
3 changed files with 80 additions and 13 deletions

View File

@ -391,7 +391,7 @@ describe('PaneContainer', () => {
});
});
describe('::onWillDestroyPaneItem() and ::onDidDestroyPaneItem', () => {
describe('::onWillDestroyPaneItem() and ::onDidDestroyPaneItem()', () => {
it('invokes the given callbacks when an item will be destroyed on any pane', async () => {
const container = new PaneContainer(params);
const pane1 = container.getRoot();
@ -409,14 +409,37 @@ describe('PaneContainer', () => {
await pane2.destroyItem(item3);
await pane2.destroyItem(item2);
expect(events).toEqual([
['will', { item: item1, pane: pane1, index: 0 }],
['did', { item: item1, pane: pane1, index: 0 }],
['will', { item: item3, pane: pane2, index: 1 }],
['did', { item: item3, pane: pane2, index: 1 }],
['will', { item: item2, pane: pane2, index: 0 }],
['did', { item: item2, pane: pane2, index: 0 }]
expect(events.length).toBe(6);
expect(events[1]).toEqual([
'did',
{ item: item1, pane: pane1, index: 0 }
]);
expect(events[3]).toEqual([
'did',
{ item: item3, pane: pane2, index: 1 }
]);
expect(events[5]).toEqual([
'did',
{ item: item2, pane: pane2, index: 0 }
]);
expect(events[0][0]).toEqual('will');
expect(events[0][1].item).toEqual(item1);
expect(events[0][1].pane).toEqual(pane1);
expect(events[0][1].index).toEqual(0);
expect(typeof events[0][1].prevent).toEqual('function');
expect(events[2][0]).toEqual('will');
expect(events[2][1].item).toEqual(item3);
expect(events[2][1].pane).toEqual(pane2);
expect(events[2][1].index).toEqual(1);
expect(typeof events[2][1].prevent).toEqual('function');
expect(events[4][0]).toEqual('will');
expect(events[4][1].item).toEqual(item2);
expect(events[4][1].pane).toEqual(pane2);
expect(events[4][1].index).toEqual(0);
expect(typeof events[4][1].prevent).toEqual('function');
});
});

View File

@ -568,6 +568,32 @@ describe('Pane', () => {
expect(pane.getActiveItem()).toBeUndefined();
});
it('does nothing if prevented', () => {
const container = new PaneContainer({
config: atom.config,
deserializerManager: atom.deserializers,
applicationDelegate: atom.applicationDelegate
});
pane.setContainer(container);
container.onWillDestroyPaneItem(e => e.prevent());
pane.itemStack = [item2, item3, item1];
pane.activateItem(item1);
expect(pane.getActiveItem()).toBe(item1);
pane.destroyItem(item3);
expect(pane.itemStack).toEqual([item2, item3, item1]);
expect(pane.getActiveItem()).toBe(item1);
pane.destroyItem(item1);
expect(pane.itemStack).toEqual([item2, item3, item1]);
expect(pane.getActiveItem()).toBe(item1);
pane.destroyItem(item2);
expect(pane.itemStack).toEqual([item2, item3, item1]);
expect(pane.getActiveItem()).toBe(item1);
});
it('invokes ::onWillDestroyItem() and PaneContainer::onWillDestroyPaneItem observers before destroying the item', async () => {
jasmine.useRealClock();
pane.container = new PaneContainer({ config: atom.config, confirm });
@ -589,10 +615,16 @@ describe('Pane', () => {
await pane.destroyItem(item2);
expect(item2.isDestroyed()).toBe(true);
expect(events).toEqual([
['will-destroy-item', { item: item2, index: 1 }],
['will-destroy-pane-item', { item: item2, index: 1, pane }]
]);
expect(events[0][0]).toEqual('will-destroy-item');
expect(events[0][1].item).toEqual(item2);
expect(events[0][1].index).toEqual(1);
expect(events[1][0]).toEqual('will-destroy-pane-item');
expect(events[1][1].item).toEqual(item2);
expect(events[1][1].index).toEqual(1);
expect(typeof events[1][1].prevent).toEqual('function');
expect(events[1][1].pane).toEqual(pane);
});
it('invokes ::onWillRemoveItem() observers', () => {

View File

@ -814,6 +814,9 @@ module.exports = class Pane {
// last item, the pane will be destroyed if the `core.destroyEmptyPanes` config
// setting is `true`.
//
// This action can be prevented by onWillDestroyPaneItem callbacks in which
// case nothing happens.
//
// * `item` Item to destroy
// * `force` (optional) {Boolean} Destroy the item without prompting to save
// it, even if the item's `isPermanentDockItem` method returns true.
@ -844,7 +847,16 @@ module.exports = class Pane {
'will-destroy-pane-item'
) > 0
) {
await this.container.willDestroyPaneItem({ item, index, pane: this });
let preventClosing = false;
await this.container.willDestroyPaneItem({
item,
index,
pane: this,
prevent: () => {
preventClosing = true;
}
});
if (preventClosing) return false;
}
if (