Steven Silvester 9 лет назад
Родитель
Сommit
97be3cb47d
2 измененных файлов с 108 добавлено и 30 удалено
  1. 69 0
      src/notebook/notebook/actions.ts
  2. 39 30
      src/notebook/notebook/widget.ts

+ 69 - 0
src/notebook/notebook/actions.ts

@@ -43,6 +43,9 @@ namespace NotebookActions {
    */
   export
   function splitCell(widget: Notebook): void {
+    if (!widget.model) {
+      return;
+    }
     Private.deselectCells(widget);
     let nbModel = widget.model;
     let index = widget.activeCellIndex;
@@ -69,6 +72,9 @@ namespace NotebookActions {
    */
   export
   function mergeCells(widget: Notebook): void {
+    if (!widget.model) {
+      return;
+    }
     let toMerge: string[] = [];
     let toDelete: ICellModel[] = [];
     let model = widget.model;
@@ -131,6 +137,9 @@ namespace NotebookActions {
    */
   export
   function deleteCells(widget: Notebook): void {
+    if (!widget.model) {
+      return;
+    }
     let model = widget.model;
     let cells = model.cells;
     // Delete the cells as one undo event.
@@ -155,6 +164,9 @@ namespace NotebookActions {
    */
   export
   function insertAbove(widget: Notebook): void {
+    if (!widget.model) {
+      return;
+    }
     let cell = widget.model.factory.createCodeCell();
     widget.model.cells.insert(widget.activeCellIndex, cell);
     Private.deselectCells(widget);
@@ -165,6 +177,9 @@ namespace NotebookActions {
    */
   export
   function insertBelow(widget: Notebook): void {
+    if (!widget.model) {
+      return;
+    }
     let cell = widget.model.factory.createCodeCell();
     widget.model.cells.insert(widget.activeCellIndex + 1, cell);
     Private.deselectCells(widget);
@@ -175,6 +190,9 @@ namespace NotebookActions {
    */
   export
   function changeCellType(widget: Notebook, value: string): void {
+    if (!widget.model) {
+      return;
+    }
     let model = widget.model;
     model.cells.beginCompoundOperation();
     for (let i = 0; i < widget.childCount(); i++) {
@@ -212,6 +230,9 @@ namespace NotebookActions {
    */
   export
   function run(widget: Notebook, kernel?: IKernel): void {
+    if (!widget.model) {
+      return;
+    }
     let selected: BaseCellWidget[] = [];
     for (let i = 0; i < widget.childCount(); i++) {
       let child = widget.childAt(i);
@@ -239,6 +260,9 @@ namespace NotebookActions {
    */
   export
   function runAndAdvance(widget: Notebook, kernel?: IKernel): void {
+    if (!widget.model) {
+      return;
+    }
     run(widget, kernel);
     let model = widget.model;
     if (widget.activeCellIndex === widget.childCount() - 1) {
@@ -257,6 +281,9 @@ namespace NotebookActions {
    */
   export
   function runAndInsert(widget: Notebook, kernel?: IKernel): void {
+    if (!widget.model) {
+      return;
+    }
     run(widget, kernel);
     let model = widget.model;
     let cell = model.factory.createCodeCell();
@@ -271,6 +298,9 @@ namespace NotebookActions {
    */
   export
   function runAll(widget: Notebook, kernel?: IKernel): void {
+    if (!widget.model) {
+      return;
+    }
     for (let i = 0; i < widget.childCount(); i++) {
       Private.runCell(widget.childAt(i), kernel);
     }
@@ -283,6 +313,9 @@ namespace NotebookActions {
    */
   export
   function selectBelow(widget: Notebook): void {
+    if (!widget.model) {
+      return;
+    }
     if (widget.activeCellIndex === widget.childCount() - 1) {
       return;
     }
@@ -296,6 +329,9 @@ namespace NotebookActions {
    */
   export
   function selectAbove(widget: Notebook): void {
+    if (!widget.model) {
+      return;
+    }
     if (widget.activeCellIndex === 0) {
       return;
     }
@@ -309,6 +345,9 @@ namespace NotebookActions {
    */
   export
   function extendSelectionAbove(widget: Notebook): void {
+    if (!widget.model) {
+      return;
+    }
     // Do not wrap around.
     if (widget.activeCellIndex === 0) {
       return;
@@ -337,6 +376,9 @@ namespace NotebookActions {
    */
   export
   function extendSelectionBelow(widget: Notebook): void {
+    if (!widget.model) {
+      return;
+    }
     // Do not wrap around.
     if (widget.activeCellIndex === widget.childCount() - 1) {
       return;
@@ -365,6 +407,9 @@ namespace NotebookActions {
    */
   export
   function copy(widget: Notebook, clipboard: IClipboard): void {
+    if (!widget.model) {
+      return;
+    }
     clipboard.clear();
     let data: nbformat.IBaseCell[] = [];
     for (let i = 0; i < widget.childCount(); i++) {
@@ -382,6 +427,9 @@ namespace NotebookActions {
    */
   export
   function cut(widget: Notebook, clipboard: IClipboard): void {
+    if (!widget.model) {
+      return;
+    }
     clipboard.clear();
     let data: nbformat.IBaseCell[] = [];
     let model = widget.model;
@@ -409,6 +457,9 @@ namespace NotebookActions {
    */
   export
   function paste(widget: Notebook, clipboard: IClipboard): void {
+    if (!widget.model) {
+      return;
+    }
     if (!clipboard.hasData(JUPYTER_CELL_MIME)) {
       return;
     }
@@ -438,6 +489,9 @@ namespace NotebookActions {
    */
   export
   function undo(widget: Notebook): void {
+    if (!widget.model) {
+      return;
+    }
     widget.mode = 'command';
     widget.model.cells.undo();
   }
@@ -447,6 +501,9 @@ namespace NotebookActions {
    */
   export
   function redo(widget: Notebook): void {
+    if (!widget.model) {
+      return;
+    }
     widget.mode = 'command';
     widget.model.cells.redo();
   }
@@ -456,6 +513,9 @@ namespace NotebookActions {
    */
   export
   function toggleLineNumbers(widget: Notebook): void {
+    if (!widget.model) {
+      return;
+    }
     let cell = widget.childAt(widget.activeCellIndex);
     let editor = cell.editor.editor;
     let lineNumbers = editor.getOption('lineNumbers');
@@ -473,6 +533,9 @@ namespace NotebookActions {
    */
   export
   function toggleAllLineNumbers(widget: Notebook): void {
+    if (!widget.model) {
+      return;
+    }
     let cell = widget.childAt(widget.activeCellIndex);
     let editor = cell.editor.editor;
     let lineNumbers = editor.getOption('lineNumbers');
@@ -488,6 +551,9 @@ namespace NotebookActions {
    */
   export
   function clearOutputs(widget: Notebook): void {
+    if (!widget.model) {
+      return;
+    }
     let cells = widget.model.cells;
     for (let i = 0; i < cells.length; i++) {
       let cell = cells.get(i) as CodeCellModel;
@@ -504,6 +570,9 @@ namespace NotebookActions {
    */
   export
   function clearAllOutputs(widget: Notebook): void {
+    if (!widget.model) {
+      return;
+    }
     let cells = widget.model.cells;
     for (let i = 0; i < cells.length; i++) {
       let cell = cells.get(i) as CodeCellModel;

+ 39 - 30
src/notebook/notebook/widget.ts

@@ -113,7 +113,7 @@ class StaticNotebook extends Widget {
     this.addClass(NB_CLASS);
     this._rendermime = options.rendermime;
     this.layout = new PanelLayout();
-    this._factory = options.factory || StaticNotebook.defaultFactory;
+    this._renderer = options.renderer || StaticNotebook.defaultRenderer;
   }
 
   /**
@@ -188,7 +188,7 @@ class StaticNotebook extends Widget {
     }
     this._model = null;
     this._rendermime = null;
-    this._factory = null;
+    this._renderer = null;
     super.dispose();
   }
 
@@ -199,7 +199,7 @@ class StaticNotebook extends Widget {
    * The default implementation is a no-op.
    */
   protected onModelChanged(oldValue: INotebookModel, newValue: INotebookModel): void {
-
+    // No-op.
   }
 
   /**
@@ -208,7 +208,7 @@ class StaticNotebook extends Widget {
   protected onMetadataChanged(model: INotebookModel, args: IChangedArgs<any>): void {
     switch (args.name) {
     case 'language_info':
-      this._mimetype = this.getMimetype();
+      this._mimetype = this._renderer.getCodeMimetype(model);
       this._updateChildren();
       break;
     default:
@@ -216,18 +216,6 @@ class StaticNotebook extends Widget {
     }
   }
 
-  /**
-   * Update a child widget.
-   */
-  private _updateChild(index: number): void {
-    let layout = this.layout as PanelLayout;
-    let child = layout.childAt(index);
-    if (child instanceof CodeCellWidget) {
-      child.mimetype = this._mimetype;
-    }
-    this._factory.updateChild(child);
-  }
-
   /**
    * Handle a new model on the widget.
    */
@@ -241,7 +229,11 @@ class StaticNotebook extends Widget {
         this._removeChild(0);
       }
     }
-    this._mimetype = this.getMimetype();
+    if (!newValue) {
+      this._mimetype = 'text/plain';
+      return;
+    }
+    this._mimetype = this._renderer.getCodeMimetype(newValue);
     let cells = newValue.cells;
     for (let i = 0; i < cells.length; i++) {
       this._insertChild(i, cells.get(i));
@@ -257,15 +249,15 @@ class StaticNotebook extends Widget {
     let widget: BaseCellWidget;
     switch (cell.type) {
     case 'code':
-      let codeFactory = this._factory.createCodeCell;
+      let codeFactory = this._renderer.createCodeCell;
       widget = codeFactory(cell as CodeCellModel, this._rendermime);
       break;
     case 'markdown':
-      let mdFactory = this._factory.createMarkdownCell;
+      let mdFactory = this._renderer.createMarkdownCell;
       widget = mdFactory(cell as MarkdownCellModel, this._rendermime);
       break;
     default:
-      widget = this._factory.createRawCell(cell as RawCellModel);
+      widget = this._renderer.createRawCell(cell as RawCellModel);
     }
     widget.addClass(NB_CELL_CLASS);
     let layout = this.layout as PanelLayout;
@@ -283,6 +275,18 @@ class StaticNotebook extends Widget {
     }
   }
 
+  /**
+   * Update a child widget.
+   */
+  private _updateChild(index: number): void {
+    let layout = this.layout as PanelLayout;
+    let child = layout.childAt(index) as BaseCellWidget;
+    if (child instanceof CodeCellWidget) {
+      child.mimetype = this._mimetype;
+    }
+    this._renderer.updateCell(child);
+  }
+
   /**
    * Remove a child widget.
    */
@@ -330,7 +334,7 @@ class StaticNotebook extends Widget {
   private _mimetype = 'text/plain';
   private _model: INotebookModel = null;
   private _rendermime: RenderMime<Widget> = null;
-  private _factory: StaticNotebook.ICellWidgetFactory = null;
+  private _renderer: StaticNotebook.IRenderer = null;
 }
 
 
@@ -355,11 +359,11 @@ namespace StaticNotebook {
     languagePreference?: string;
 
     /**
-     * A factory for creating code cell widgets.
+     * A renderer for a notebook.
      *
-     * The default is a shared factory instance.
+     * The default is a shared renderer instance.
      */
-    factory?: ICellWidgetFactory;
+    renderer?: IRenderer;
   }
 
   /**
@@ -389,8 +393,11 @@ namespace StaticNotebook {
 
     /**
      * Get the preferred mime type for code cells in the notebook.
+     *
+     * #### Notes
+     * The model is guaranteed to be non-null.
      */
-    getMimetype(model: INotebookModel): string;
+    getCodeMimetype(model: INotebookModel): string;
   }
 
   /**
@@ -422,15 +429,17 @@ namespace StaticNotebook {
     /**
      * Update a cell widget.
      */
-    updateCell(cell: BaseCellWidget): void { }
+    updateCell(cell: BaseCellWidget): void {
+      // No-op.
+    }
 
     /**
      * Get the preferred mime type for code cells in the notebook.
+     *
+     * #### Notes
+     * The model is guaranteed to be non-null.
      */
-    getMimetype(model: INotebookModel): string {
-      if (!model) {
-        return 'text/plain';
-      }
+    getCodeMimetype(model: INotebookModel): string {
       let cursor = model.getMetadata('language_info');
       let info = cursor.getValue() as nbformat.ILanguageInfoMetadata;
       return mimetypeForLanguage(info as IKernelLanguageInfo);