UNPKG

@jupyterlab/lsp

Version:
174 lines 5.22 kB
// Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. import { DocumentWidget } from '@jupyterlab/docregistry'; import { Signal } from '@lumino/signaling'; /** * A class that keeps track of widget adapter instances. * * @typeparam T - The type of widget being tracked. Defaults to `WidgetLSPAdapter`. */ export class WidgetLSPAdapterTracker { /** * Create a new widget tracker. * * @param options - The instantiation options for a widget tracker. */ constructor(options) { this._isDisposed = false; this._current = null; this._adapters = new Set(); this._adapterAdded = new Signal(this); this._adapterUpdated = new Signal(this); this._currentChanged = new Signal(this); const shell = (this._shell = options.shell); shell.currentChanged.connect((_, args) => { let newValue = args.newValue; if (!newValue || !(newValue instanceof DocumentWidget)) { return; } const adapter = this.find(value => value.widget === newValue); if (!adapter) { return; } this._current = adapter; this._currentChanged.emit(adapter); }); } /** * A signal emitted when the current adapter changes. */ get currentChanged() { return this._currentChanged; } /** * The current adapter is the most recently focused or added adapter. * * #### Notes * It is the most recently focused adapter, or the most recently added * adapter if no adapter has taken focus. */ get currentAdapter() { return this._current; } /** * The number of adapter held by the tracker. */ get size() { return this._adapters.size; } /** * A signal emitted when an adapter is added. */ get adapterAdded() { return this._adapterAdded; } /** * A signal emitted when an adapter is updated. */ get adapterUpdated() { return this._adapterUpdated; } /** * Add a new adapter to the tracker. * * @param adapter - The adapter being added. * * #### Notes. * The newly added adapter becomes the current adapter unless the shell * already had a DocumentWidget as the activeWidget. */ add(adapter) { if (adapter.isDisposed) { const warning = 'A disposed object cannot be added.'; console.warn(warning, adapter); throw new Error(warning); } if (this._adapters.has(adapter)) { const warning = 'This object already exists in the pool.'; console.warn(warning, adapter); throw new Error(warning); } this._adapters.add(adapter); this._adapterAdded.emit(adapter); adapter.disposed.connect(() => { this._adapters.delete(adapter); if (adapter === this._current) { this._current = null; this._currentChanged.emit(this._current); } }, this); // Only update the current adapter, when there is no shell.activeWidget // or the active widget is not a DocumentWidget // We will be able to use other panels while keeping the current adapter. const active = this._shell.activeWidget; if (!active || !(active instanceof DocumentWidget)) { this._current = adapter; this._currentChanged.emit(adapter); } } /** * Test whether the tracker is disposed. */ get isDisposed() { return this._isDisposed; } /** * Dispose of the resources held by the tracker. */ dispose() { if (this.isDisposed) { return; } this._isDisposed = true; this._adapters.clear(); Signal.clearData(this); } /** * Find the first adapter in the tracker that satisfies a filter function. * * @param fn The filter function to call on each adapter. * * #### Notes * If no adapter is found, the value returned is `undefined`. */ find(fn) { const values = this._adapters.values(); for (const value of values) { if (fn(value)) { return value; } } return undefined; } /** * Iterate through each adapter in the tracker. * * @param fn - The function to call on each adapter. */ forEach(fn) { this._adapters.forEach(fn); } /** * Filter the adapter in the tracker based on a predicate. * * @param fn - The function by which to filter. */ filter(fn) { const filtered = []; this.forEach(value => { if (fn(value)) { filtered.push(value); } }); return filtered; } /** * Check if this tracker has the specified adapter. * * @param adapter - The adapter whose existence is being checked. */ has(adapter) { return this._adapters.has(adapter); } } //# sourceMappingURL=tracker.js.map