Browse Source

Clean up use of ready promise

Steven Silvester 7 years ago
parent
commit
901c2cd678

+ 16 - 1
packages/cells/src/widget.ts

@@ -6,7 +6,7 @@ import {
 } from '@jupyterlab/services';
 } from '@jupyterlab/services';
 
 
 import {
 import {
-  JSONObject, JSONValue
+  JSONObject, JSONValue, PromiseDelegate
 } from '@phosphor/coreutils';
 } from '@phosphor/coreutils';
 
 
 import {
 import {
@@ -689,6 +689,13 @@ class MarkdownCell extends Cell {
    */
    */
   readonly model: IMarkdownCellModel;
   readonly model: IMarkdownCellModel;
 
 
+  /**
+   * A promise that resolves when the widget renders for the first time.
+   */
+  get ready(): Promise<void> {
+    return this._ready.promise;
+  }
+
   /**
   /**
    * Whether the cell is rendered.
    * Whether the cell is rendered.
    */
    */
@@ -765,6 +772,12 @@ class MarkdownCell extends Cell {
       let data: JSONObject = { 'text/markdown': text };
       let data: JSONObject = { 'text/markdown': text };
       let bundle = new MimeModel({ data, trusted });
       let bundle = new MimeModel({ data, trusted });
       let widget = this._rendermime.render(bundle);
       let widget = this._rendermime.render(bundle);
+      if (!this._isReady) {
+        widget.ready.then(() => {
+          this._isReady = true;
+          this._ready.resolve(undefined);
+        });
+      }
       this._renderedInput = widget || new Widget();
       this._renderedInput = widget || new Widget();
       this._renderedInput.addClass(MARKDOWN_OUTPUT_CLASS);
       this._renderedInput.addClass(MARKDOWN_OUTPUT_CLASS);
     }
     }
@@ -778,6 +791,8 @@ class MarkdownCell extends Cell {
   private _rendered = true;
   private _rendered = true;
   private _prevText = '';
   private _prevText = '';
   private _prevTrusted = false;
   private _prevTrusted = false;
+  private _ready = new PromiseDelegate<void>();
+  private _isReady = false;
 }
 }
 
 
 
 

+ 16 - 9
packages/markdownviewer/src/widget.ts

@@ -1,6 +1,10 @@
 // Copyright (c) Jupyter Development Team.
 // Copyright (c) Jupyter Development Team.
 // Distributed under the terms of the Modified BSD License.
 // Distributed under the terms of the Modified BSD License.
 
 
+import {
+  PromiseDelegate
+} from '@phosphor/coreutils';
+
 import {
 import {
   Message
   Message
 } from '@phosphor/messaging';
 } from '@phosphor/messaging';
@@ -60,15 +64,16 @@ class MarkdownViewer extends Widget implements DocumentRegistry.IWidget {
     context.pathChanged.connect(this._onPathChanged, this);
     context.pathChanged.connect(this._onPathChanged, this);
 
 
     this._context.ready.then(() => {
     this._context.ready.then(() => {
+      return this._render().ready;
+    }).then(() => {
+      this._ready.resolve(undefined);
+
       // Throttle the rendering rate of the widget.
       // Throttle the rendering rate of the widget.
       this._monitor = new ActivityMonitor({
       this._monitor = new ActivityMonitor({
         signal: context.model.contentChanged,
         signal: context.model.contentChanged,
         timeout: RENDER_TIMEOUT
         timeout: RENDER_TIMEOUT
       });
       });
       this._monitor.activityStopped.connect(this.update, this);
       this._monitor.activityStopped.connect(this.update, this);
-      if (this.isAttached) {
-        this.update();
-      }
     });
     });
   }
   }
 
 
@@ -83,7 +88,7 @@ class MarkdownViewer extends Widget implements DocumentRegistry.IWidget {
    * A promise that resolves when the markdown viewer is ready.
    * A promise that resolves when the markdown viewer is ready.
    */
    */
   get ready(): Promise<void> {
   get ready(): Promise<void> {
-    return this._context.ready;
+    return this._ready.promise;
   }
   }
 
 
   /**
   /**
@@ -106,16 +111,16 @@ class MarkdownViewer extends Widget implements DocumentRegistry.IWidget {
   }
   }
 
 
   /**
   /**
-   * Handle an `after-attach` message to the widget.
+   * Handle an `update-request` message to the widget.
    */
    */
-  protected onAfterAttach(msg: Message): void {
-    this.update();
+  protected onUpdateRequest(msg: Message): void {
+    this._render();
   }
   }
 
 
   /**
   /**
-   * Handle an `update-request` message to the widget.
+   * Render the markdown content.
    */
    */
-  protected onUpdateRequest(msg: Message): void {
+  private _render(): RenderMime.IWidget {
     let context = this._context;
     let context = this._context;
     let model = context.model;
     let model = context.model;
     let layout = this.layout as PanelLayout;
     let layout = this.layout as PanelLayout;
@@ -127,6 +132,7 @@ class MarkdownViewer extends Widget implements DocumentRegistry.IWidget {
       layout.widgets[1].dispose();
       layout.widgets[1].dispose();
     }
     }
     layout.addWidget(widget);
     layout.addWidget(widget);
+    return widget;
   }
   }
 
 
   /**
   /**
@@ -139,6 +145,7 @@ class MarkdownViewer extends Widget implements DocumentRegistry.IWidget {
   private _context: DocumentRegistry.Context = null;
   private _context: DocumentRegistry.Context = null;
   private _monitor: ActivityMonitor<any, any> = null;
   private _monitor: ActivityMonitor<any, any> = null;
   private _rendermime: RenderMime = null;
   private _rendermime: RenderMime = null;
+  private _ready = new PromiseDelegate<void>();
 }
 }
 
 
 
 

+ 13 - 1
packages/notebook/src/panel.ts

@@ -30,6 +30,10 @@ import {
   IClientSession, Toolbar
   IClientSession, Toolbar
 } from '@jupyterlab/apputils';
 } from '@jupyterlab/apputils';
 
 
+import {
+  MarkdownCell
+} from '@jupyterlab/cells';
+
 import {
 import {
   IEditorMimeTypeService
   IEditorMimeTypeService
 } from '@jupyterlab/codeeditor';
 } from '@jupyterlab/codeeditor';
@@ -135,7 +139,15 @@ class NotebookPanel extends Widget implements DocumentRegistry.IWidget {
    * A promise that resolves when the notebook panel is ready.
    * A promise that resolves when the notebook panel is ready.
    */
    */
   get ready(): Promise<void> {
   get ready(): Promise<void> {
-    return this._context.ready;
+    return this._context.ready.then(() => {
+      let promises: Promise<void>[] = [];
+      each(this.notebook.widgets, widget => {
+        if (widget instanceof MarkdownCell) {
+          promises.push(widget.ready);
+        }
+      });
+      return Promise.all(promises).then(() => undefined);
+    });
   }
   }
 
 
   /**
   /**

+ 2 - 2
packages/rendermime/src/rendermime.ts

@@ -106,7 +106,7 @@ class RenderMime {
    * Renders the model using the preferred mime type.  See
    * Renders the model using the preferred mime type.  See
    * [[preferredMimeType]].
    * [[preferredMimeType]].
    */
    */
-  render(model: RenderMime.IMimeModel): Widget {
+  render(model: RenderMime.IMimeModel): RenderMime.IWidget {
     let mimeType = this.preferredMimeType(model);
     let mimeType = this.preferredMimeType(model);
     if (!mimeType) {
     if (!mimeType) {
       return this._handleError(model);
       return this._handleError(model);
@@ -215,7 +215,7 @@ class RenderMime {
   /**
   /**
    * Return a widget for an error.
    * Return a widget for an error.
    */
    */
-  private _handleError(model: RenderMime.IMimeModel): Widget {
+  private _handleError(model: RenderMime.IMimeModel): RenderMime.IWidget {
    let errModel = new MimeModel({
    let errModel = new MimeModel({
       data: {
       data: {
         'application/vnd.jupyter.stderr': 'Unable to render data'
         'application/vnd.jupyter.stderr': 'Unable to render data'