From 1552854f3b3e55c9ea243cedb37f13dfe8882a2f Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 3 Apr 2017 16:54:22 -0700 Subject: [PATCH] Allow workspace item objects to be passed to Workspace.open --- spec/workspace-spec.js | 48 ++++++++++++++++++++++++++++++++++++++++-- src/workspace.js | 20 ++++++++++++------ 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/spec/workspace-spec.js b/spec/workspace-spec.js index 5c02b8852..4ab183886 100644 --- a/spec/workspace-spec.js +++ b/spec/workspace-spec.js @@ -1,4 +1,4 @@ -'use strict' +/** @babel */ /* global advanceClock, HTMLElement, waits */ @@ -12,6 +12,7 @@ const _ = require('underscore-plus') const fstream = require('fstream') const fs = require('fs-plus') const AtomEnvironment = require('../src/atom-environment') +const {it, fit, ffit, fffit, beforeEach, afterEach} = require('./async-spec-helpers') describe('Workspace', () => { let workspace @@ -187,7 +188,7 @@ describe('Workspace', () => { }) describe("when the 'searchAllPanes' option is false (default)", () => { - describe('when called without a uri', () => { + describe('when called without a uri or item', () => { it('adds and activates an empty editor on the active pane', () => { let editor1 let editor2 @@ -406,6 +407,49 @@ describe('Workspace', () => { }) }) + describe('when called with an item rather than a URI', () => { + it('adds the item itself to the workspace', async () => { + const item = document.createElement('div') + await atom.workspace.open(item) + expect(atom.workspace.getActivePaneItem()).toBe(item) + }) + + describe('when the active pane already contains the item', () => { + it('activates the item', async () => { + const item = document.createElement('div') + + await atom.workspace.open(item) + await atom.workspace.open() + expect(atom.workspace.getActivePaneItem()).not.toBe(item) + expect(atom.workspace.getActivePane().getItems().length).toBe(2) + + await atom.workspace.open(item) + expect(atom.workspace.getActivePaneItem()).toBe(item) + expect(atom.workspace.getActivePane().getItems().length).toBe(2) + }) + }) + + describe('when the item already exists in another pane', () => { + it('rejects the promise', async () => { + const item = document.createElement('div') + + await atom.workspace.open(item) + await atom.workspace.open(null, {split: 'right'}) + expect(atom.workspace.getActivePaneItem()).not.toBe(item) + expect(atom.workspace.getActivePane().getItems().length).toBe(1) + + let rejection + try { + await atom.workspace.open(item) + } catch (error) { + rejection = error + } + + expect(rejection.message).toMatch(/The workspace can only contain one instance of item/) + }) + }) + }) + describe("when the 'split' option is set", () => { describe("when the 'split' option is 'left'", () => { it('opens the editor in the leftmost pane of the current pane axis', () => { diff --git a/src/workspace.js b/src/workspace.js index 894d67b62..7bc7b3244 100644 --- a/src/workspace.js +++ b/src/workspace.js @@ -628,8 +628,14 @@ module.exports = class Workspace extends Model { // should almost always be omitted to honor user preference. // // Returns a {Promise} that resolves to the {TextEditor} for the file URI. - async open (uri_, options = {}) { - const uri = this.project.resolvePath(uri_) + async open (itemOrURI, options = {}) { + let uri, item + if (typeof itemOrURI === 'string') { + uri = this.project.resolvePath(itemOrURI) + } else if (itemOrURI) { + item = itemOrURI + if (typeof item.getURI === 'function') uri = item.getURI() + } if (!atom.config.get('core.allowPendingPaneItems')) { options.pending = false @@ -641,14 +647,14 @@ module.exports = class Workspace extends Model { this.applicationDelegate.addRecentDocument(uri) } - let container, pane, item + let container, pane - // Try to find an existing item with the given URI. - if (uri) { + // Try to find an existing item in the workspace. + if (item || uri) { if (options.pane) { pane = options.pane } else if (options.searchAllPanes) { - pane = this.paneForURI(uri) + pane = item ? this.paneForItem(item) : this.paneForURI(uri) } else { // The `split` option affects where we search for the item. pane = this.getActivePane() @@ -668,7 +674,7 @@ module.exports = class Workspace extends Model { } } - if (pane) item = pane.itemForURI(uri) + if (pane && !item) item = pane.itemForURI(uri) } // If an item is already present, yield the event loop to ensure this method