فهرست منبع

Add an option to dispose of widgets on detach

Steven Silvester 7 سال پیش
والد
کامیت
dbb81a8627
1فایلهای تغییر یافته به همراه34 افزوده شده و 1 حذف شده
  1. 34 1
      packages/apputils/src/instancetracker.ts

+ 34 - 1
packages/apputils/src/instancetracker.ts

@@ -21,6 +21,10 @@ import {
   IDisposable
 } from '@phosphor/disposable';
 
+import {
+  IMessageHandler, Message, MessageLoop
+} from '@phosphor/messaging';
+
 import {
   AttachedProperty
 } from '@phosphor/properties';
@@ -122,6 +126,7 @@ class InstanceTracker<T extends Widget> implements IInstanceTracker<T>, IDisposa
    */
   constructor(options: InstanceTracker.IOptions) {
     this.namespace = options.namespace;
+    this._disposeOnDetach = options.disposeOnDetach === true;
     this._tracker.currentChanged.connect(this._onCurrentChanged, this);
   }
 
@@ -194,6 +199,11 @@ class InstanceTracker<T extends Widget> implements IInstanceTracker<T>, IDisposa
       return promise;
     }
 
+    // Handle closing the widget.
+    if (this._disposeOnDetach) {
+      MessageLoop.installMessageHook(widget, this);
+    }
+
     widget.disposed.connect(this._onWidgetDisposed, this);
 
     // Handle widget state restoration.
@@ -359,6 +369,23 @@ class InstanceTracker<T extends Widget> implements IInstanceTracker<T>, IDisposa
     }
   }
 
+  /**
+   * Intercept a message sent to a message handler.
+   *
+   * @param handler - The target handler of the message.
+   *
+   * @param msg - The message to be sent to the handler.
+   *
+   * @returns `true` if the message should continue to be processed
+   *   as normal, or `false` if processing should cease immediately.
+   */
+  messageHook(handler: IMessageHandler, msg: Message): boolean {
+    if (msg.type === 'after-detach') {
+      (handler as Widget).dispose();
+    }
+    return true;
+  }
+
   /**
    * Handle the current change event.
    *
@@ -381,7 +408,7 @@ class InstanceTracker<T extends Widget> implements IInstanceTracker<T>, IDisposa
   }
 
   /**
-   * Clean up after disposed widgets.
+   * Handle a widget disposal.
    */
   private _onWidgetDisposed(widget: T): void {
     let injected = Private.injectedProperty.get(widget);
@@ -424,6 +451,7 @@ class InstanceTracker<T extends Widget> implements IInstanceTracker<T>, IDisposa
   private _widgets: T[] = [];
   private _currentWidget: T | null = null;
   private _isDisposed = false;
+  private _disposeOnDetach = false;
 }
 
 
@@ -442,6 +470,11 @@ namespace InstanceTracker {
      * A namespace for all tracked widgets, (e.g., `notebook`).
      */
     namespace: string;
+
+    /**
+     * Whether to dispose of widgets when they are detached.
+     */
+    disposeOnDetach?: boolean;
   }
 
   /**