Skip to content

Commit b3930b0

Browse files
authored
Merge pull request atom#22943 from ericcornelissen/prevent-destroy-pane-item
Add prevent option to ::onWillDestroyPaneItem
2 parents eb33066 + 3652d2f commit b3930b0

File tree

3 files changed

+80
-13
lines changed

3 files changed

+80
-13
lines changed

spec/pane-container-spec.js

+31-8
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ describe('PaneContainer', () => {
391391
});
392392
});
393393

394-
describe('::onWillDestroyPaneItem() and ::onDidDestroyPaneItem', () => {
394+
describe('::onWillDestroyPaneItem() and ::onDidDestroyPaneItem()', () => {
395395
it('invokes the given callbacks when an item will be destroyed on any pane', async () => {
396396
const container = new PaneContainer(params);
397397
const pane1 = container.getRoot();
@@ -409,14 +409,37 @@ describe('PaneContainer', () => {
409409
await pane2.destroyItem(item3);
410410
await pane2.destroyItem(item2);
411411

412-
expect(events).toEqual([
413-
['will', { item: item1, pane: pane1, index: 0 }],
414-
['did', { item: item1, pane: pane1, index: 0 }],
415-
['will', { item: item3, pane: pane2, index: 1 }],
416-
['did', { item: item3, pane: pane2, index: 1 }],
417-
['will', { item: item2, pane: pane2, index: 0 }],
418-
['did', { item: item2, pane: pane2, index: 0 }]
412+
expect(events.length).toBe(6);
413+
expect(events[1]).toEqual([
414+
'did',
415+
{ item: item1, pane: pane1, index: 0 }
416+
]);
417+
expect(events[3]).toEqual([
418+
'did',
419+
{ item: item3, pane: pane2, index: 1 }
419420
]);
421+
expect(events[5]).toEqual([
422+
'did',
423+
{ item: item2, pane: pane2, index: 0 }
424+
]);
425+
426+
expect(events[0][0]).toEqual('will');
427+
expect(events[0][1].item).toEqual(item1);
428+
expect(events[0][1].pane).toEqual(pane1);
429+
expect(events[0][1].index).toEqual(0);
430+
expect(typeof events[0][1].prevent).toEqual('function');
431+
432+
expect(events[2][0]).toEqual('will');
433+
expect(events[2][1].item).toEqual(item3);
434+
expect(events[2][1].pane).toEqual(pane2);
435+
expect(events[2][1].index).toEqual(1);
436+
expect(typeof events[2][1].prevent).toEqual('function');
437+
438+
expect(events[4][0]).toEqual('will');
439+
expect(events[4][1].item).toEqual(item2);
440+
expect(events[4][1].pane).toEqual(pane2);
441+
expect(events[4][1].index).toEqual(0);
442+
expect(typeof events[4][1].prevent).toEqual('function');
420443
});
421444
});
422445

spec/pane-spec.js

+36-4
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,32 @@ describe('Pane', () => {
568568
expect(pane.getActiveItem()).toBeUndefined();
569569
});
570570

571+
it('does nothing if prevented', () => {
572+
const container = new PaneContainer({
573+
config: atom.config,
574+
deserializerManager: atom.deserializers,
575+
applicationDelegate: atom.applicationDelegate
576+
});
577+
578+
pane.setContainer(container);
579+
container.onWillDestroyPaneItem(e => e.prevent());
580+
pane.itemStack = [item2, item3, item1];
581+
582+
pane.activateItem(item1);
583+
expect(pane.getActiveItem()).toBe(item1);
584+
pane.destroyItem(item3);
585+
expect(pane.itemStack).toEqual([item2, item3, item1]);
586+
expect(pane.getActiveItem()).toBe(item1);
587+
588+
pane.destroyItem(item1);
589+
expect(pane.itemStack).toEqual([item2, item3, item1]);
590+
expect(pane.getActiveItem()).toBe(item1);
591+
592+
pane.destroyItem(item2);
593+
expect(pane.itemStack).toEqual([item2, item3, item1]);
594+
expect(pane.getActiveItem()).toBe(item1);
595+
});
596+
571597
it('invokes ::onWillDestroyItem() and PaneContainer::onWillDestroyPaneItem observers before destroying the item', async () => {
572598
jasmine.useRealClock();
573599
pane.container = new PaneContainer({ config: atom.config, confirm });
@@ -589,10 +615,16 @@ describe('Pane', () => {
589615

590616
await pane.destroyItem(item2);
591617
expect(item2.isDestroyed()).toBe(true);
592-
expect(events).toEqual([
593-
['will-destroy-item', { item: item2, index: 1 }],
594-
['will-destroy-pane-item', { item: item2, index: 1, pane }]
595-
]);
618+
619+
expect(events[0][0]).toEqual('will-destroy-item');
620+
expect(events[0][1].item).toEqual(item2);
621+
expect(events[0][1].index).toEqual(1);
622+
623+
expect(events[1][0]).toEqual('will-destroy-pane-item');
624+
expect(events[1][1].item).toEqual(item2);
625+
expect(events[1][1].index).toEqual(1);
626+
expect(typeof events[1][1].prevent).toEqual('function');
627+
expect(events[1][1].pane).toEqual(pane);
596628
});
597629

598630
it('invokes ::onWillRemoveItem() observers', () => {

src/pane.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,9 @@ module.exports = class Pane {
814814
// last item, the pane will be destroyed if the `core.destroyEmptyPanes` config
815815
// setting is `true`.
816816
//
817+
// This action can be prevented by onWillDestroyPaneItem callbacks in which
818+
// case nothing happens.
819+
//
817820
// * `item` Item to destroy
818821
// * `force` (optional) {Boolean} Destroy the item without prompting to save
819822
// it, even if the item's `isPermanentDockItem` method returns true.
@@ -844,7 +847,16 @@ module.exports = class Pane {
844847
'will-destroy-pane-item'
845848
) > 0
846849
) {
847-
await this.container.willDestroyPaneItem({ item, index, pane: this });
850+
let preventClosing = false;
851+
await this.container.willDestroyPaneItem({
852+
item,
853+
index,
854+
pane: this,
855+
prevent: () => {
856+
preventClosing = true;
857+
}
858+
});
859+
if (preventClosing) return false;
848860
}
849861

850862
if (

0 commit comments

Comments
 (0)