/ src / workspace-center.js
workspace-center.js
  1  'use strict';
  2  
  3  const TextEditor = require('./text-editor');
  4  const PaneContainer = require('./pane-container');
  5  
  6  // Essential: Represents the workspace at the center of the entire window.
  7  module.exports = class WorkspaceCenter {
  8    constructor(params) {
  9      params.location = 'center';
 10      this.paneContainer = new PaneContainer(params);
 11      this.didActivate = params.didActivate;
 12      this.paneContainer.onDidActivatePane(() => this.didActivate(this));
 13      this.paneContainer.onDidChangeActivePane(pane => {
 14        params.didChangeActivePane(this, pane);
 15      });
 16      this.paneContainer.onDidChangeActivePaneItem(item => {
 17        params.didChangeActivePaneItem(this, item);
 18      });
 19      this.paneContainer.onDidDestroyPaneItem(item =>
 20        params.didDestroyPaneItem(item)
 21      );
 22    }
 23  
 24    destroy() {
 25      this.paneContainer.destroy();
 26    }
 27  
 28    serialize() {
 29      return this.paneContainer.serialize();
 30    }
 31  
 32    deserialize(state, deserializerManager) {
 33      this.paneContainer.deserialize(state, deserializerManager);
 34    }
 35  
 36    activate() {
 37      this.getActivePane().activate();
 38    }
 39  
 40    getLocation() {
 41      return 'center';
 42    }
 43  
 44    setDraggingItem() {
 45      // No-op
 46    }
 47  
 48    /*
 49    Section: Event Subscription
 50    */
 51  
 52    // Essential: Invoke the given callback with all current and future text
 53    // editors in the workspace center.
 54    //
 55    // * `callback` {Function} to be called with current and future text editors.
 56    //   * `editor` An {TextEditor} that is present in {::getTextEditors} at the time
 57    //     of subscription or that is added at some later time.
 58    //
 59    // Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
 60    observeTextEditors(callback) {
 61      for (let textEditor of this.getTextEditors()) {
 62        callback(textEditor);
 63      }
 64      return this.onDidAddTextEditor(({ textEditor }) => callback(textEditor));
 65    }
 66  
 67    // Essential: Invoke the given callback with all current and future panes items
 68    // in the workspace center.
 69    //
 70    // * `callback` {Function} to be called with current and future pane items.
 71    //   * `item` An item that is present in {::getPaneItems} at the time of
 72    //      subscription or that is added at some later time.
 73    //
 74    // Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
 75    observePaneItems(callback) {
 76      return this.paneContainer.observePaneItems(callback);
 77    }
 78  
 79    // Essential: Invoke the given callback when the active pane item changes.
 80    //
 81    // Because observers are invoked synchronously, it's important not to perform
 82    // any expensive operations via this method. Consider
 83    // {::onDidStopChangingActivePaneItem} to delay operations until after changes
 84    // stop occurring.
 85    //
 86    // * `callback` {Function} to be called when the active pane item changes.
 87    //   * `item` The active pane item.
 88    //
 89    // Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
 90    onDidChangeActivePaneItem(callback) {
 91      return this.paneContainer.onDidChangeActivePaneItem(callback);
 92    }
 93  
 94    // Essential: Invoke the given callback when the active pane item stops
 95    // changing.
 96    //
 97    // Observers are called asynchronously 100ms after the last active pane item
 98    // change. Handling changes here rather than in the synchronous
 99    // {::onDidChangeActivePaneItem} prevents unneeded work if the user is quickly
100    // changing or closing tabs and ensures critical UI feedback, like changing the
101    // highlighted tab, gets priority over work that can be done asynchronously.
102    //
103    // * `callback` {Function} to be called when the active pane item stopts
104    //   changing.
105    //   * `item` The active pane item.
106    //
107    // Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
108    onDidStopChangingActivePaneItem(callback) {
109      return this.paneContainer.onDidStopChangingActivePaneItem(callback);
110    }
111  
112    // Essential: Invoke the given callback with the current active pane item and
113    // with all future active pane items in the workspace center.
114    //
115    // * `callback` {Function} to be called when the active pane item changes.
116    //   * `item` The current active pane item.
117    //
118    // Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
119    observeActivePaneItem(callback) {
120      return this.paneContainer.observeActivePaneItem(callback);
121    }
122  
123    // Extended: Invoke the given callback when a pane is added to the workspace
124    // center.
125    //
126    // * `callback` {Function} to be called panes are added.
127    //   * `event` {Object} with the following keys:
128    //     * `pane` The added pane.
129    //
130    // Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
131    onDidAddPane(callback) {
132      return this.paneContainer.onDidAddPane(callback);
133    }
134  
135    // Extended: Invoke the given callback before a pane is destroyed in the
136    // workspace center.
137    //
138    // * `callback` {Function} to be called before panes are destroyed.
139    //   * `event` {Object} with the following keys:
140    //     * `pane` The pane to be destroyed.
141    //
142    // Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
143    onWillDestroyPane(callback) {
144      return this.paneContainer.onWillDestroyPane(callback);
145    }
146  
147    // Extended: Invoke the given callback when a pane is destroyed in the
148    // workspace center.
149    //
150    // * `callback` {Function} to be called panes are destroyed.
151    //   * `event` {Object} with the following keys:
152    //     * `pane` The destroyed pane.
153    //
154    // Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
155    onDidDestroyPane(callback) {
156      return this.paneContainer.onDidDestroyPane(callback);
157    }
158  
159    // Extended: Invoke the given callback with all current and future panes in the
160    // workspace center.
161    //
162    // * `callback` {Function} to be called with current and future panes.
163    //   * `pane` A {Pane} that is present in {::getPanes} at the time of
164    //      subscription or that is added at some later time.
165    //
166    // Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
167    observePanes(callback) {
168      return this.paneContainer.observePanes(callback);
169    }
170  
171    // Extended: Invoke the given callback when the active pane changes.
172    //
173    // * `callback` {Function} to be called when the active pane changes.
174    //   * `pane` A {Pane} that is the current return value of {::getActivePane}.
175    //
176    // Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
177    onDidChangeActivePane(callback) {
178      return this.paneContainer.onDidChangeActivePane(callback);
179    }
180  
181    // Extended: Invoke the given callback with the current active pane and when
182    // the active pane changes.
183    //
184    // * `callback` {Function} to be called with the current and future active#
185    //   panes.
186    //   * `pane` A {Pane} that is the current return value of {::getActivePane}.
187    //
188    // Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
189    observeActivePane(callback) {
190      return this.paneContainer.observeActivePane(callback);
191    }
192  
193    // Extended: Invoke the given callback when a pane item is added to the
194    // workspace center.
195    //
196    // * `callback` {Function} to be called when pane items are added.
197    //   * `event` {Object} with the following keys:
198    //     * `item` The added pane item.
199    //     * `pane` {Pane} containing the added item.
200    //     * `index` {Number} indicating the index of the added item in its pane.
201    //
202    // Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
203    onDidAddPaneItem(callback) {
204      return this.paneContainer.onDidAddPaneItem(callback);
205    }
206  
207    // Extended: Invoke the given callback when a pane item is about to be
208    // destroyed, before the user is prompted to save it.
209    //
210    // * `callback` {Function} to be called before pane items are destroyed.
211    //   * `event` {Object} with the following keys:
212    //     * `item` The item to be destroyed.
213    //     * `pane` {Pane} containing the item to be destroyed.
214    //     * `index` {Number} indicating the index of the item to be destroyed in
215    //       its pane.
216    //
217    // Returns a {Disposable} on which `.dispose` can be called to unsubscribe.
218    onWillDestroyPaneItem(callback) {
219      return this.paneContainer.onWillDestroyPaneItem(callback);
220    }
221  
222    // Extended: Invoke the given callback when a pane item is destroyed.
223    //
224    // * `callback` {Function} to be called when pane items are destroyed.
225    //   * `event` {Object} with the following keys:
226    //     * `item` The destroyed item.
227    //     * `pane` {Pane} containing the destroyed item.
228    //     * `index` {Number} indicating the index of the destroyed item in its
229    //       pane.
230    //
231    // Returns a {Disposable} on which `.dispose` can be called to unsubscribe.
232    onDidDestroyPaneItem(callback) {
233      return this.paneContainer.onDidDestroyPaneItem(callback);
234    }
235  
236    // Extended: Invoke the given callback when a text editor is added to the
237    // workspace center.
238    //
239    // * `callback` {Function} to be called when panes are added.
240    //   * `event` {Object} with the following keys:
241    //     * `textEditor` {TextEditor} that was added.
242    //     * `pane` {Pane} containing the added text editor.
243    //     * `index` {Number} indicating the index of the added text editor in its
244    //        pane.
245    //
246    // Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
247    onDidAddTextEditor(callback) {
248      return this.onDidAddPaneItem(({ item, pane, index }) => {
249        if (item instanceof TextEditor) {
250          callback({ textEditor: item, pane, index });
251        }
252      });
253    }
254  
255    /*
256    Section: Pane Items
257    */
258  
259    // Essential: Get all pane items in the workspace center.
260    //
261    // Returns an {Array} of items.
262    getPaneItems() {
263      return this.paneContainer.getPaneItems();
264    }
265  
266    // Essential: Get the active {Pane}'s active item.
267    //
268    // Returns an pane item {Object}.
269    getActivePaneItem() {
270      return this.paneContainer.getActivePaneItem();
271    }
272  
273    // Essential: Get all text editors in the workspace center.
274    //
275    // Returns an {Array} of {TextEditor}s.
276    getTextEditors() {
277      return this.getPaneItems().filter(item => item instanceof TextEditor);
278    }
279  
280    // Essential: Get the active item if it is an {TextEditor}.
281    //
282    // Returns an {TextEditor} or `undefined` if the current active item is not an
283    // {TextEditor}.
284    getActiveTextEditor() {
285      const activeItem = this.getActivePaneItem();
286      if (activeItem instanceof TextEditor) {
287        return activeItem;
288      }
289    }
290  
291    // Save all pane items.
292    saveAll() {
293      this.paneContainer.saveAll();
294    }
295  
296    confirmClose(options) {
297      return this.paneContainer.confirmClose(options);
298    }
299  
300    /*
301    Section: Panes
302    */
303  
304    // Extended: Get all panes in the workspace center.
305    //
306    // Returns an {Array} of {Pane}s.
307    getPanes() {
308      return this.paneContainer.getPanes();
309    }
310  
311    // Extended: Get the active {Pane}.
312    //
313    // Returns a {Pane}.
314    getActivePane() {
315      return this.paneContainer.getActivePane();
316    }
317  
318    // Extended: Make the next pane active.
319    activateNextPane() {
320      return this.paneContainer.activateNextPane();
321    }
322  
323    // Extended: Make the previous pane active.
324    activatePreviousPane() {
325      return this.paneContainer.activatePreviousPane();
326    }
327  
328    paneForURI(uri) {
329      return this.paneContainer.paneForURI(uri);
330    }
331  
332    paneForItem(item) {
333      return this.paneContainer.paneForItem(item);
334    }
335  
336    // Destroy (close) the active pane.
337    destroyActivePane() {
338      const activePane = this.getActivePane();
339      if (activePane != null) {
340        activePane.destroy();
341      }
342    }
343  };