浏览代码

Finish initial implementation

Steven Silvester 8 年之前
父节点
当前提交
6cd8b7406b

+ 30 - 1
packages/coreutils/src/nbformat.ts

@@ -342,7 +342,7 @@ namespace nbformat {
    * The valid output types.
    */
   export
-  type OutputType = 'execute_result' | 'display_data' | 'stream' | 'error';
+  type OutputType = 'execute_result' | 'display_data' | 'stream' | 'error' | 'update_display_data';
 
   /**
    * The base output type.
@@ -402,6 +402,27 @@ namespace nbformat {
     metadata: OutputMetadata;
   }
 
+  /**
+   * Data displayed as an update to existing display data.
+   */
+  export
+  interface IDisplayUpdate extends IBaseOutput {
+    /**
+     * Type of cell output.
+     */
+    output_type: 'update_display_data';
+
+    /**
+     * A mime-type keyed dictionary of data.
+     */
+    data: IMimeBundle;
+
+    /**
+     * Cell output metadata.
+     */
+    metadata: OutputMetadata;
+  }
+
   /**
    * Stream output from a code cell.
    */
@@ -477,6 +498,14 @@ namespace nbformat {
     return output.output_type === 'display_data';
   }
 
+  /**
+   * Test whether an output is from updated display data.
+   */
+  export
+  function isDisplayUpdate(output: IOutput): output is IDisplayUpdate {
+    return output.output_type === 'update_display_data';
+  }
+
   /**
    * Test whether an output is from a stream.
    */

+ 29 - 1
packages/outputarea/src/widget.ts

@@ -1,6 +1,10 @@
 // Copyright (c) Jupyter Development Team.
 // Distributed under the terms of the Modified BSD License.
 
+import {
+  JSONObject
+} from '@phosphor/coreutils';
+
 import {
   Message
 } from '@phosphor/messaging';
@@ -255,6 +259,9 @@ class OutputArea extends Widget {
       widget.dispose();
     }
 
+    // Clear the display id map.
+    this._displayIdMap.clear();
+
     // When an output area is cleared and then quickly replaced with new
     // content (as happens with @interact in widgets, for example), the
     // quickly changing height can make the page jitter.
@@ -279,12 +286,17 @@ class OutputArea extends Widget {
   private _onIOPub(msg: KernelMessage.IIOPubMessage): void {
     let model = this.model;
     let msgType = msg.header.msg_type;
+    let output: nbformat.IOutput;
+    let transient = (msg.content.transient || {}) as JSONObject;
+    let displayId = transient['display_id'] as string;
+    let targets: number[];
+
     switch (msgType) {
     case 'execute_result':
     case 'display_data':
     case 'stream':
     case 'error':
-      let output = msg.content as nbformat.IOutput;
+      output = msg.content as nbformat.IOutput;
       output.output_type = msgType as nbformat.OutputType;
       model.add(output);
       break;
@@ -292,9 +304,24 @@ class OutputArea extends Widget {
       let wait = (msg as KernelMessage.IClearOutputMsg).content.wait;
       model.clear(wait);
       break;
+    case 'update_display_data':
+      output = msg.content as nbformat.IOutput;
+      output.output_type = msgType as nbformat.OutputType;
+      targets = this._displayIdMap.get(displayId);
+      if (targets) {
+        for (let index of targets) {
+          model.set(index, output);
+        }
+      }
+      break;
     default:
       break;
     }
+    if (displayId && msgType === 'display_data') {
+       targets = this._displayIdMap.get(displayId) || [];
+       targets.push(model.length - 1);
+       this._displayIdMap.set(displayId, targets);
+    }
   }
 
   /**
@@ -395,6 +422,7 @@ class OutputArea extends Widget {
 
   private _minHeightTimeout: number = null;
   private _future: Kernel.IFuture = null;
+  private _displayIdMap = new Map<string, number[]>();
 }
 
 

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

@@ -114,6 +114,7 @@ class OutputModel extends MimeModel implements IOutputModel {
     switch (this.type) {
     case 'display_data':
     case 'execute_result':
+    case 'update_display_data':
       output['data'] = this.data.toJSON();
       output['metadata'] = this.metadata.toJSON();
       break;
@@ -170,7 +171,7 @@ namespace OutputModel {
   export
   function getData(output: nbformat.IOutput): JSONObject {
     let bundle: nbformat.IMimeBundle = {};
-    if (nbformat.isExecuteResult(output) || nbformat.isDisplayData(output)) {
+    if (nbformat.isExecuteResult(output) || nbformat.isDisplayData(output) || nbformat.isDisplayUpdate(output)) {
       bundle = (output as nbformat.IExecuteResult).data;
     } else if (nbformat.isStream(output)) {
       if (output.name === 'stderr') {

+ 1 - 1
packages/services/src/kernel/default.ts

@@ -776,7 +776,7 @@ class DefaultKernel implements Kernel.IKernel {
       parentIds.map((parentId) => {
         let future = this._futures && this._futures.get(parentId);
         if (future) {
-          future.handleMsg(msg);
+          future.handleMsg(updateMsg);
         }
       });
     }