|
@@ -55,6 +55,35 @@ interface IInstanceTracker<T extends Widget> {
|
|
|
* The current widget is the most recently focused widget.
|
|
|
*/
|
|
|
currentWidget: T;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * The number of widgets held by the tracker.
|
|
|
+ */
|
|
|
+ size: number;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Iterate through each widget in the tracker.
|
|
|
+ *
|
|
|
+ * @param fn - The function to call on each widget.
|
|
|
+ */
|
|
|
+ forEach(fn: (widget: T) => void): void;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Inject a foreign widget into the instance tracker.
|
|
|
+ *
|
|
|
+ * @param widget - The widget to inject into the tracker.
|
|
|
+ *
|
|
|
+ * #### Notes
|
|
|
+ * Any widgets injected into an instance tracker will not have their state
|
|
|
+ * or layout saved by the tracker. The primary use case for widget injection
|
|
|
+ * is for a plugin that offers a sub-class of an extant plugin to have its
|
|
|
+ * instances share the same commands as the parent plugin (since most relevant
|
|
|
+ * commands will use the `currentWidget` of the parent plugin's instance
|
|
|
+ * tracker). In this situation, the sub-class plugin may well have its own
|
|
|
+ * instance tracker for layout and state restoration in addition to injecting
|
|
|
+ * its widgets into the parent plugin's instance tracker.
|
|
|
+ */
|
|
|
+ inject(widget: T): void;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -74,6 +103,8 @@ export
|
|
|
class InstanceTracker<T extends Widget> implements IInstanceTracker<T>, IDisposable {
|
|
|
/**
|
|
|
* Create a new instance tracker.
|
|
|
+ *
|
|
|
+ * @param options - The instance tracker configuration options.
|
|
|
*/
|
|
|
constructor(options: InstanceTracker.IOptions<T> = {}) {
|
|
|
this._restore = options.restore;
|
|
@@ -124,12 +155,21 @@ class InstanceTracker<T extends Widget> implements IInstanceTracker<T>, IDisposa
|
|
|
return this._widgets === null;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * The number of widgets held by the tracker.
|
|
|
+ */
|
|
|
+ get size(): number {
|
|
|
+ return this._widgets.size;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Add a new widget to the tracker.
|
|
|
+ *
|
|
|
+ * @param widget - The widget being added.
|
|
|
*/
|
|
|
add(widget: T): void {
|
|
|
if (this._widgets.has(widget)) {
|
|
|
- console.warn(`${widget.id} has already been added to the tracker.`);
|
|
|
+ console.warn(`${widget.id} already exists in the tracker.`);
|
|
|
return;
|
|
|
}
|
|
|
this._widgets.add(widget);
|
|
@@ -186,7 +226,7 @@ class InstanceTracker<T extends Widget> implements IInstanceTracker<T>, IDisposa
|
|
|
/**
|
|
|
* Find the first widget in the tracker that satisfies a filter function.
|
|
|
*
|
|
|
- * @param fn The filter function to call on each widget.
|
|
|
+ * @param - fn The filter function to call on each widget.
|
|
|
*/
|
|
|
find(fn: (widget: T) => boolean): T {
|
|
|
let result: T = null;
|
|
@@ -205,14 +245,35 @@ class InstanceTracker<T extends Widget> implements IInstanceTracker<T>, IDisposa
|
|
|
/**
|
|
|
* Iterate through each widget in the tracker.
|
|
|
*
|
|
|
- * @param fn The function to call on each widget.
|
|
|
+ * @param fn - The function to call on each widget.
|
|
|
*/
|
|
|
forEach(fn: (widget: T) => void): void {
|
|
|
this._widgets.forEach(widget => { fn(widget); });
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Inject a foreign widget into the instance tracker.
|
|
|
+ *
|
|
|
+ * @param widget - The widget to inject into the tracker.
|
|
|
+ *
|
|
|
+ * #### Notes
|
|
|
+ * Any widgets injected into an instance tracker will not have their state
|
|
|
+ * or layout saved by the tracker. The primary use case for widget injection
|
|
|
+ * is for a plugin that offers a sub-class of an extant plugin to have its
|
|
|
+ * instances share the same commands as the parent plugin (since most relevant
|
|
|
+ * commands will use the `currentWidget` of the parent plugin's instance
|
|
|
+ * tracker). In this situation, the sub-class plugin may well have its own
|
|
|
+ * instance tracker for layout and state restoration in addition to injecting
|
|
|
+ * its widgets into the parent plugin's instance tracker.
|
|
|
+ */
|
|
|
+ inject(widget: T): void {
|
|
|
+ /* This method has not been implemented yet */
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Check if this tracker has the specified widget.
|
|
|
+ *
|
|
|
+ * @param widget - The widget whose existence is being checked.
|
|
|
*/
|
|
|
has(widget: Widget): boolean {
|
|
|
return this._widgets.has(widget as any);
|
|
@@ -220,6 +281,8 @@ class InstanceTracker<T extends Widget> implements IInstanceTracker<T>, IDisposa
|
|
|
|
|
|
/**
|
|
|
* Save the restore data for a given widget.
|
|
|
+ *
|
|
|
+ * @param widget - The widget being saved.
|
|
|
*/
|
|
|
save(widget: T): void {
|
|
|
if (!this._restore || !this.has(widget)) {
|
|
@@ -368,6 +431,14 @@ namespace InstanceTracker {
|
|
|
* A namespace for private data.
|
|
|
*/
|
|
|
namespace Private {
|
|
|
+ /**
|
|
|
+ * An attached property to indicate whether a widget has been injected.
|
|
|
+ */
|
|
|
+ export
|
|
|
+ const injectedProperty = new AttachedProperty<Widget, boolean>({
|
|
|
+ name: 'injected'
|
|
|
+ });
|
|
|
+
|
|
|
/**
|
|
|
* An attached property for a widget's ID in the state database.
|
|
|
*/
|