Browse Source

wip refactoring

Steven Silvester 9 years ago
parent
commit
cbde1c2a8a

+ 131 - 63
src/notebook/notebook/model.ts

@@ -104,10 +104,6 @@ interface INotebookModel extends IDocumentModel {
    *
    *
    * @returns A new code cell. If a source cell is provided, the
    * @returns A new code cell. If a source cell is provided, the
    *   new cell will be intialized with the data from the source.
    *   new cell will be intialized with the data from the source.
-   *
-   * #### Notes
-   * If the source argument does not give an input mimetype, the code cell
-   * defaults to the notebook [[defaultMimetype]].
    */
    */
   createCodeCell(source?: nbformat.IBaseCell): CodeCellModel;
   createCodeCell(source?: nbformat.IBaseCell): CodeCellModel;
 
 
@@ -141,21 +137,30 @@ class NotebookModel extends DocumentModel implements INotebookModel {
   /**
   /**
    * Construct a new notebook model.
    * Construct a new notebook model.
    */
    */
-  constructor(languagePreference?: string) {
-    super(languagePreference);
+  constructor(options: NotebookModel.IOptions = {}) {
+    super(options.languagePreference);
+    this._codeFactory = options.codeCellFactory || Private.createCodeCell;
+    this._mdFactory = options.markdownCellFactory || Private.createMarkdownCell;
+    this._rawFactory = options.rawCellFactory || Private.createRawCell;
+    let codeFactory = this._codeFactory;
     this._cells = new ObservableUndoableList<ICellModel>((data: nbformat.IBaseCell) => {
     this._cells = new ObservableUndoableList<ICellModel>((data: nbformat.IBaseCell) => {
       switch (data.cell_type) {
       switch (data.cell_type) {
         case 'code':
         case 'code':
-          return this.createCodeCell(data);
+          return codeFactory(data);
         case 'markdown':
         case 'markdown':
-          return this.createMarkdownCell(data);
+          let markdownFactory = this._mdFactory;
+          return markdownFactory(data);
         default:
         default:
-          return this.createRawCell(data);
+          let rawFactory = this._rawFactory;
+          return rawFactory(data);
       }
       }
     });
     });
-    this._cells.changed.connect(this.onCellsChanged, this);
-    if (languagePreference) {
-      this._metadata['language_info'] = { name: languagePreference };
+    // Add an initial code cell by default.
+    let cell = codeFactory();
+    this._cells.add(cell);
+    this._cells.changed.connect(this._onCellsChanged, this);
+    if (options.languagePreference) {
+      this._metadata['language_info'] = { name: options.languagePreference };
     }
     }
   }
   }
 
 
@@ -322,7 +327,7 @@ class NotebookModel extends DocumentModel implements INotebookModel {
         continue;
         continue;
       }
       }
       if (!(key in metadata)) {
       if (!(key in metadata)) {
-        this.setCursorData(key, null);
+        this._setCursorData(key, null);
         delete this._metadata[key];
         delete this._metadata[key];
         if (this._cursors[key]) {
         if (this._cursors[key]) {
           this._cursors[key].dispose();
           this._cursors[key].dispose();
@@ -331,7 +336,7 @@ class NotebookModel extends DocumentModel implements INotebookModel {
       }
       }
     }
     }
     for (let key in metadata) {
     for (let key in metadata) {
-      this.setCursorData(key, (metadata as any)[key]);
+      this._setCursorData(key, (metadata as any)[key]);
     }
     }
     this.dirty = true;
     this.dirty = true;
   }
   }
@@ -344,6 +349,38 @@ class NotebookModel extends DocumentModel implements INotebookModel {
     this.dirty = false;
     this.dirty = false;
   }
   }
 
 
+  /**
+   * Get a metadata cursor for the notebook.
+   *
+   * #### Notes
+   * Metadata associated with the nbformat spec are set directly
+   * on the model.  This method is used to interact with a namespaced
+   * set of metadata on the notebook.
+   */
+  getMetadata(name: string): IMetadataCursor {
+    if (name in this._cursors) {
+      return this._cursors[name];
+    }
+    let cursor = new MetadataCursor(
+      name,
+      () => {
+        return this._metadata[name];
+      },
+      (value: string) => {
+        this._setCursorData(name, value);
+      }
+    );
+    this._cursors[name] = cursor;
+    return cursor;
+  }
+
+  /**
+   * List the metadata namespace keys for the notebook.
+   */
+  listMetadata(): string[] {
+    return Object.keys(this._metadata);
+  }
+
   /**
   /**
    * A factory for creating a new code cell.
    * A factory for creating a new code cell.
    *
    *
@@ -353,7 +390,8 @@ class NotebookModel extends DocumentModel implements INotebookModel {
    *   new cell will be intialized with the data from the source.
    *   new cell will be intialized with the data from the source.
    */
    */
   createCodeCell(source?: nbformat.IBaseCell): CodeCellModel {
   createCodeCell(source?: nbformat.IBaseCell): CodeCellModel {
-    return new CodeCellModel(source);
+    let factory = this._codeFactory;
+    return factory(source);
   }
   }
 
 
   /**
   /**
@@ -365,7 +403,8 @@ class NotebookModel extends DocumentModel implements INotebookModel {
    *   new cell will be intialized with the data from the source.
    *   new cell will be intialized with the data from the source.
    */
    */
   createMarkdownCell(source?: nbformat.IBaseCell): MarkdownCellModel {
   createMarkdownCell(source?: nbformat.IBaseCell): MarkdownCellModel {
-    return new MarkdownCellModel(source);
+    let factory = this._mdFactory;
+    return factory(source);
   }
   }
 
 
   /**
   /**
@@ -377,50 +416,33 @@ class NotebookModel extends DocumentModel implements INotebookModel {
    *   new cell will be intialized with the data from the source.
    *   new cell will be intialized with the data from the source.
    */
    */
   createRawCell(source?: nbformat.IBaseCell): RawCellModel {
   createRawCell(source?: nbformat.IBaseCell): RawCellModel {
-    return new RawCellModel(source);
+    let factory = this._rawFactory;
+    return factory(source);
   }
   }
 
 
   /**
   /**
-   * Get a metadata cursor for the notebook.
-   *
-   * #### Notes
-   * Metadata associated with the nbformat spec are set directly
-   * on the model.  This method is used to interact with a namespaced
-   * set of metadata on the notebook.
+   * Set the cursor data for a given field.
    */
    */
-  getMetadata(name: string): IMetadataCursor {
-    if (name in this._cursors) {
-      return this._cursors[name];
+  private _setCursorData(name: string, newValue: any): void {
+    let oldValue = this._metadata[name];
+    if (deepEqual(oldValue, newValue)) {
+      return;
     }
     }
-    let cursor = new MetadataCursor(
-      name,
-      () => {
-        return this._metadata[name];
-      },
-      (value: string) => {
-        this.setCursorData(name, value);
-      }
-    );
-    this._cursors[name] = cursor;
-    return cursor;
-  }
-
-  /**
-   * List the metadata namespace keys for the notebook.
-   */
-  listMetadata(): string[] {
-    return Object.keys(this._metadata);
+    this._metadata[name] = newValue;
+    this.dirty = true;
+    this.contentChanged.emit(void 0);
+    this.metadataChanged.emit({ name, oldValue, newValue });
   }
   }
 
 
   /**
   /**
    * Handle a change in the cells list.
    * Handle a change in the cells list.
    */
    */
-  protected onCellsChanged(list: IObservableList<ICellModel>, change: IListChangedArgs<ICellModel>): void {
+  private _onCellsChanged(list: IObservableList<ICellModel>, change: IListChangedArgs<ICellModel>): void {
     let cell: ICellModel;
     let cell: ICellModel;
     switch (change.type) {
     switch (change.type) {
     case ListChangeType.Add:
     case ListChangeType.Add:
       cell = change.newValue as ICellModel;
       cell = change.newValue as ICellModel;
-      cell.contentChanged.connect(this.onCellChanged, this);
+      cell.contentChanged.connect(this._onCellChanged, this);
       break;
       break;
     case ListChangeType.Remove:
     case ListChangeType.Remove:
       (change.oldValue as ICellModel).dispose();
       (change.oldValue as ICellModel).dispose();
@@ -428,7 +450,7 @@ class NotebookModel extends DocumentModel implements INotebookModel {
     case ListChangeType.Replace:
     case ListChangeType.Replace:
       let newValues = change.newValue as ICellModel[];
       let newValues = change.newValue as ICellModel[];
       for (cell of newValues) {
       for (cell of newValues) {
-        cell.contentChanged.connect(this.onCellChanged, this);
+        cell.contentChanged.connect(this._onCellChanged, this);
       }
       }
       let oldValues = change.oldValue as ICellModel[];
       let oldValues = change.oldValue as ICellModel[];
       for (cell of oldValues) {
       for (cell of oldValues) {
@@ -437,7 +459,7 @@ class NotebookModel extends DocumentModel implements INotebookModel {
       break;
       break;
     case ListChangeType.Set:
     case ListChangeType.Set:
       cell = change.newValue as ICellModel;
       cell = change.newValue as ICellModel;
-      cell.contentChanged.connect(this.onCellChanged, this);
+      cell.contentChanged.connect(this._onCellChanged, this);
       if (change.oldValue) {
       if (change.oldValue) {
         (change.oldValue as ICellModel).dispose();
         (change.oldValue as ICellModel).dispose();
       }
       }
@@ -452,30 +474,52 @@ class NotebookModel extends DocumentModel implements INotebookModel {
   /**
   /**
    * Handle a change to a cell state.
    * Handle a change to a cell state.
    */
    */
-  protected onCellChanged(cell: ICellModel, change: any): void {
+  private _onCellChanged(cell: ICellModel, change: any): void {
     this.dirty = true;
     this.dirty = true;
     this.contentChanged.emit(void 0);
     this.contentChanged.emit(void 0);
   }
   }
 
 
-  /**
-   * Set the cursor data for a given field.
-   */
-  protected setCursorData(name: string, newValue: any): void {
-    let oldValue = this._metadata[name];
-    if (deepEqual(oldValue, newValue)) {
-      return;
-    }
-    this._metadata[name] = newValue;
-    this.dirty = true;
-    this.contentChanged.emit(void 0);
-    this.metadataChanged.emit({ name, oldValue, newValue });
-  }
-
   private _cells: ObservableUndoableList<ICellModel> = null;
   private _cells: ObservableUndoableList<ICellModel> = null;
   private _metadata: { [key: string]: any } = Private.createMetadata();
   private _metadata: { [key: string]: any } = Private.createMetadata();
   private _cursors: { [key: string]: MetadataCursor } = Object.create(null);
   private _cursors: { [key: string]: MetadataCursor } = Object.create(null);
   private _nbformat = nbformat.MAJOR_VERSION;
   private _nbformat = nbformat.MAJOR_VERSION;
   private _nbformatMinor = nbformat.MINOR_VERSION;
   private _nbformatMinor = nbformat.MINOR_VERSION;
+  private _codeFactory: (source?: nbformat.IBaseCell) => CodeCellModel = null;
+  private _rawFactory: (source?: nbformat.IBaseCell) => RawCellModel = null;
+  private _mdFactory: (source?: nbformat.IBaseCell) => MarkdownCellModel = null;
+}
+
+
+/**
+ * The namespace for the `NotebookModel` class statics.
+ */
+export
+namespace NotebookModel {
+  /**
+   * An options object for initializing a notebook model.
+   */
+  export
+  interface IOptions {
+    /**
+     * The language preference for the model.
+     */
+    languagePreference?: string;
+
+    /**
+     * A factory for creating code cell models.
+     */
+    codeCellFactory?: (source?: nbformat.IBaseCell) => CodeCellModel;
+
+    /**
+     * A factory for creating markdown cell models.
+     */
+    markdownCellFactory?: (source?: nbformat.IBaseCell) => MarkdownCellModel;
+
+    /**
+     * A factory for creating raw cell models.
+     */
+    rawCellFactory?: (source?: nbformat.IBaseCell) => RawCellModel;
+  }
 }
 }
 
 
 
 
@@ -489,6 +533,30 @@ namespace Private {
   export
   export
   const metadataChangedSignal = new Signal<IDocumentModel, IChangedArgs<any>>();
   const metadataChangedSignal = new Signal<IDocumentModel, IChangedArgs<any>>();
 
 
+  /**
+   * A factory for creating a new code cell.
+   */
+  export
+  function createCodeCell(source?: nbformat.IBaseCell): CodeCellModel {
+    return new CodeCellModel(source);
+  }
+
+  /**
+   * A factory for creating a new Markdown cell.
+   */
+  export
+  function createMarkdownCell(source?: nbformat.IBaseCell): MarkdownCellModel {
+    return new MarkdownCellModel(source);
+  }
+
+  /**
+   * A factory for creating a new raw cell.
+   */
+  export
+  function createRawCell(source?: nbformat.IBaseCell): RawCellModel {
+    return new RawCellModel(source);
+  }
+
   /**
   /**
    * Create the default metadata for the notebook.
    * Create the default metadata for the notebook.
    */
    */

+ 113 - 65
src/notebook/notebook/widget.ts

@@ -36,7 +36,7 @@ import {
 import {
 import {
   ICellModel, BaseCellWidget, MarkdownCellModel,
   ICellModel, BaseCellWidget, MarkdownCellModel,
   CodeCellWidget, MarkdownCellWidget,
   CodeCellWidget, MarkdownCellWidget,
-  CodeCellModel, RawCellWidget
+  CodeCellModel, RawCellWidget, RawCellModel
 } from '../cells';
 } from '../cells';
 
 
 import {
 import {
@@ -103,31 +103,18 @@ type NotebookMode = 'command' | 'edit';
  */
  */
 export
 export
 class StaticNotebook extends Widget {
 class StaticNotebook extends Widget {
-  /**
-   * Create a new cell widget given a cell model.
-   */
-  static createCell(cell: ICellModel, rendermime: RenderMime<Widget>): BaseCellWidget {
-    switch (cell.type) {
-    case 'code':
-      return new CodeCellWidget(cell as CodeCellModel, rendermime);
-    case 'markdown':
-      return new MarkdownCellWidget(cell, rendermime);
-    // If there are any issues, just return a raw
-    // widget so the lists stay in sync.
-    default:
-      return new RawCellWidget(cell);
-    }
-  }
-
   /**
   /**
    * Construct a notebook widget.
    * Construct a notebook widget.
    */
    */
-  constructor(rendermime: RenderMime<Widget>) {
+  constructor(rendermime: RenderMime<Widget>, options: StaticNotebook.IOptions = {}) {
     super();
     super();
     this.node.tabIndex = -1;  // Allow the widget to take focus.
     this.node.tabIndex = -1;  // Allow the widget to take focus.
     this.addClass(NB_CLASS);
     this.addClass(NB_CLASS);
     this._rendermime = rendermime;
     this._rendermime = rendermime;
     this.layout = new PanelLayout();
     this.layout = new PanelLayout();
+    this._codeFactory = options.codeCellFactory || Private.createCodeCell;
+    this._mdFactory = options.markdownCellFactory || Private.createMarkdownCell;
+    this._rawFactory = options.rawCellFactory || Private.createRawCell;
   }
   }
 
 
   /**
   /**
@@ -138,16 +125,11 @@ class StaticNotebook extends Widget {
   }
   }
 
 
   /**
   /**
-   * Get the model for the widget.
+   * The model for the widget.
    */
    */
   get model(): INotebookModel {
   get model(): INotebookModel {
     return this._model;
     return this._model;
   }
   }
-
-  /**
-   * Set the model for the widget.
-   *
-   */
   set model(newValue: INotebookModel) {
   set model(newValue: INotebookModel) {
     newValue = newValue || null;
     newValue = newValue || null;
     if (this._model === newValue) {
     if (this._model === newValue) {
@@ -155,7 +137,7 @@ class StaticNotebook extends Widget {
     }
     }
     let oldValue = this._model;
     let oldValue = this._model;
     this._model = newValue;
     this._model = newValue;
-    this.changeModel(oldValue, newValue);
+    this._changeModel(oldValue, newValue);
     this.modelChanged.emit(newValue);
     this.modelChanged.emit(newValue);
   }
   }
 
 
@@ -198,14 +180,27 @@ class StaticNotebook extends Widget {
     super.dispose();
     super.dispose();
   }
   }
 
 
+
+  /**
+   * Handle a `child-added` message.
+   */
+  protected onChildAdded(msg: ChildMessage): void {
+    msg.child.addClass(NB_CLASS);
+    this.update();
+  }
+
+  /**
+   * Handle a `child-removed` message.
+   */
+  protected onChildRemoved(msg: ChildMessage): void {
+    msg.child.dispose();
+    this.update();
+  }
+
   /**
   /**
    * Handle a new model on the widget.
    * Handle a new model on the widget.
-   *
-   * #### Notes
-   * Creates child widgets for each of the cells in the model.
-   * If there are no cells, adds a single code cell.
    */
    */
-  protected changeModel(oldValue: INotebookModel, newValue: INotebookModel): void {
+  private _changeModel(oldValue: INotebookModel, newValue: INotebookModel): void {
     let layout = this.layout as PanelLayout;
     let layout = this.layout as PanelLayout;
     if (oldValue) {
     if (oldValue) {
       oldValue.cells.changed.disconnect(this._onCellsChanged, this);
       oldValue.cells.changed.disconnect(this._onCellsChanged, this);
@@ -215,39 +210,36 @@ class StaticNotebook extends Widget {
         layout.removeChild(layout.childAt(0));
         layout.removeChild(layout.childAt(0));
       }
       }
     }
     }
-    let rendermime = this.rendermime;
     let cells = newValue.cells;
     let cells = newValue.cells;
-    let constructor = this.constructor as typeof StaticNotebook;
-    let factory = constructor.createCell;
     for (let i = 0; i < cells.length; i++) {
     for (let i = 0; i < cells.length; i++) {
-      let widget = factory(cells.get(i), rendermime);
-      layout.addChild(widget);
+      layout.addChild(this._createWidget(cells.get(i)));
     }
     }
-    this.setChildMimetypes();
+    this._setChildMimetypes();
     cells.changed.connect(this._onCellsChanged, this);
     cells.changed.connect(this._onCellsChanged, this);
     newValue.metadataChanged.connect(this._onMetadataChanged, this);
     newValue.metadataChanged.connect(this._onMetadataChanged, this);
   }
   }
 
 
   /**
   /**
-   * Handle a `child-added` message.
+   * Create a widget from a model using the appropriate factory.
    */
    */
-  protected onChildAdded(msg: ChildMessage): void {
-    msg.child.addClass(NB_CLASS);
-    this.update();
-  }
-
-  /**
-   * Handle a `child-removed` message.
-   */
-  protected onChildRemoved(msg: ChildMessage): void {
-    msg.child.dispose();
-    this.update();
+  private _createWidget(model: ICellModel): BaseCellWidget {
+    switch (model.type) {
+    case 'code':
+      let codeFactory = this._codeFactory;
+      return codeFactory(model as CodeCellModel, this._rendermime);
+    case 'markdown':
+      let mdFactory = this._mdFactory;
+      return mdFactory(model as MarkdownCellModel, this._rendermime);
+    default:
+      let rawFactory = this._rawFactory;
+      return rawFactory(model as RawCellModel);
+    }
   }
   }
 
 
   /**
   /**
    * Set the mimetype of the child code widgets.
    * Set the mimetype of the child code widgets.
    */
    */
-  protected setChildMimetypes(): void {
+  private _setChildMimetypes(): void {
     let cursor = this.model.getMetadata('language_info');
     let cursor = this.model.getMetadata('language_info');
     let info = cursor.getValue() as nbformat.ILanguageInfoMetadata;
     let info = cursor.getValue() as nbformat.ILanguageInfoMetadata;
     let mimetype = mimetypeForLanguage(info as IKernelLanguageInfo);
     let mimetype = mimetypeForLanguage(info as IKernelLanguageInfo);
@@ -266,7 +258,7 @@ class StaticNotebook extends Widget {
   private _onMetadataChanged(model: INotebookModel, args: IChangedArgs<any>): void {
   private _onMetadataChanged(model: INotebookModel, args: IChangedArgs<any>): void {
     switch (args.name) {
     switch (args.name) {
     case 'language_info':
     case 'language_info':
-      this.setChildMimetypes();
+      this._setChildMimetypes();
       break;
       break;
     default:
     default:
       break;
       break;
@@ -278,38 +270,33 @@ class StaticNotebook extends Widget {
    */
    */
   private _onCellsChanged(sender: IObservableList<ICellModel>, args: IListChangedArgs<ICellModel>) {
   private _onCellsChanged(sender: IObservableList<ICellModel>, args: IListChangedArgs<ICellModel>) {
     let layout = this.layout as PanelLayout;
     let layout = this.layout as PanelLayout;
-    let constructor = this.constructor as typeof StaticNotebook;
-    let factory = constructor.createCell;
-    let widget: BaseCellWidget;
+    let model: ICellModel;
     switch (args.type) {
     switch (args.type) {
     case ListChangeType.Add:
     case ListChangeType.Add:
-      widget = factory(args.newValue as ICellModel, this._rendermime);
-      layout.insertChild(args.newIndex, widget);
+      model = args.newValue as ICellModel;
+      layout.insertChild(args.newIndex, this._createWidget(model));
       break;
       break;
     case ListChangeType.Move:
     case ListChangeType.Move:
       layout.insertChild(args.newIndex, layout.childAt(args.oldIndex));
       layout.insertChild(args.newIndex, layout.childAt(args.oldIndex));
       break;
       break;
     case ListChangeType.Remove:
     case ListChangeType.Remove:
-      widget = layout.childAt(args.oldIndex) as BaseCellWidget;
-      layout.removeChild(widget);
+      layout.removeChild(layout.childAt(args.oldIndex));
       break;
       break;
     case ListChangeType.Replace:
     case ListChangeType.Replace:
       let oldValues = args.oldValue as ICellModel[];
       let oldValues = args.oldValue as ICellModel[];
       for (let i = 0; i < oldValues.length; i++) {
       for (let i = 0; i < oldValues.length; i++) {
-        widget = layout.childAt(args.oldIndex) as BaseCellWidget;
-        layout.removeChild(widget);
+        layout.removeChild(layout.childAt(args.oldIndex));
       }
       }
       let newValues = args.newValue as ICellModel[];
       let newValues = args.newValue as ICellModel[];
       for (let i = newValues.length; i > 0; i--) {
       for (let i = newValues.length; i > 0; i--) {
-        widget = factory(newValues[i - 1], this._rendermime);
-        layout.insertChild(args.newIndex, widget);
+        model = newValues[i - 1];
+        layout.insertChild(args.newIndex, this._createWidget(model));
       }
       }
       break;
       break;
     case ListChangeType.Set:
     case ListChangeType.Set:
-      widget = layout.childAt(args.newIndex) as BaseCellWidget;
-      layout.removeChild(widget);
-      widget = factory(args.newValue as ICellModel, this._rendermime);
-      layout.insertChild(args.newIndex, widget);
+      layout.removeChild(layout.childAt(args.newIndex));
+      model = args.newValue as ICellModel;
+      layout.insertChild(args.newIndex, this._createWidget(model));
       break;
       break;
     default:
     default:
       return;
       return;
@@ -318,6 +305,43 @@ class StaticNotebook extends Widget {
 
 
   private _model: INotebookModel = null;
   private _model: INotebookModel = null;
   private _rendermime: RenderMime<Widget> = null;
   private _rendermime: RenderMime<Widget> = null;
+  private _codeFactory: (model: CodeCellModel, rendermime: RenderMime<Widget>) => CodeCellWidget = null;
+  private _mdFactory: (model: MarkdownCellModel, rendermime: RenderMime<Widget>) => MarkdownCellWidget = null;
+  private _rawFactory: (model: RawCellModel) => RawCellWidget = null;
+}
+
+
+
+/**
+ * The namespace for the `StaticNotebook` class statics.
+ */
+export
+namespace StaticNotebook {
+  /**
+   * An options object for initializing a static notebook.
+   */
+  export
+  interface IOptions {
+    /**
+     * The language preference for the model.
+     */
+    languagePreference?: string;
+
+    /**
+     * A factory for creating code cell models.
+     */
+    codeCellFactory?: (model: CodeCellModel, rendermime: RenderMime<Widget>) => CodeCellWidget;
+
+    /**
+     * A factory for creating markdown cell models.
+     */
+    markdownCellFactory?: (model: MarkdownCellModel, rendermime: RenderMime<Widget>) => MarkdownCellWidget;
+
+    /**
+     * A factory for creating raw cell models.
+     */
+    rawCellFactory?: (model: RawCellModel) => RawCellWidget;
+  }
 }
 }
 
 
 
 
@@ -627,6 +651,30 @@ namespace Private {
   export
   export
   const stateChangedSignal = new Signal<Notebook, IChangedArgs<any>>();
   const stateChangedSignal = new Signal<Notebook, IChangedArgs<any>>();
 
 
+  /**
+   * A factory for creating a new code cell widget.
+   */
+  export
+  function createCodeCell(model: CodeCellModel, rendermime: RenderMime<Widget>): CodeCellWidget {
+    return new CodeCellWidget(model, rendermime);
+  }
+
+  /**
+   * A factory for creating a new markdown cell widget.
+   */
+  export
+  function createMarkdownCell(model: MarkdownCellModel, rendermime: RenderMime<Widget>): MarkdownCellWidget {
+    return new MarkdownCellWidget(model, rendermime);
+  }
+
+  /**
+   * A factory for creating a new raw cell widget.
+   */
+  export
+  function createRawCell(model: RawCellModel): RawCellWidget {
+    return new RawCellWidget(model);
+  }
+
  /**
  /**
   * Scroll an element into view if needed.
   * Scroll an element into view if needed.
   *
   *

+ 77 - 112
test/src/notebook/notebook/model.spec.ts

@@ -27,29 +27,6 @@ import {
 const DEFAULT_CONTENT: nbformat.INotebookContent = require('../../../../examples/notebook/test.ipynb') as nbformat.INotebookContent;
 const DEFAULT_CONTENT: nbformat.INotebookContent = require('../../../../examples/notebook/test.ipynb') as nbformat.INotebookContent;
 
 
 
 
-/**
- * A notebook model which tests protected methods.
- */
-class LogNotebookModel extends NotebookModel {
-  methods: string[] = [];
-
-  protected onCellChanged(cell: ICellModel, change: any): void {
-    super.onCellChanged(cell, change);
-    this.methods.push('onCellChanged');
-  }
-
-  protected onCellsChanged(list: ObservableList<ICellModel>, change: IListChangedArgs<ICellModel>): void {
-    super.onCellsChanged(list, change);
-    this.methods.push('onCellsChanged');
-  }
-
-  protected setCursorData(name: string, newValue: any): void {
-    super.setCursorData(name, newValue);
-    this.methods.push('setCursorData');
-  }
-}
-
-
 describe('notebook/notebook', () => {
 describe('notebook/notebook', () => {
 
 
   describe('NotebookModel', () => {
   describe('NotebookModel', () => {
@@ -62,7 +39,7 @@ describe('notebook/notebook', () => {
       });
       });
 
 
       it('should accept an optional language preference', () => {
       it('should accept an optional language preference', () => {
-        let model = new NotebookModel('python');
+        let model = new NotebookModel({ languagePreference: 'python' });
         let cursor = model.getMetadata('language_info');
         let cursor = model.getMetadata('language_info');
         let lang = cursor.getValue() as nbformat.ILanguageInfoMetadata;
         let lang = cursor.getValue() as nbformat.ILanguageInfoMetadata;
         expect(lang.name).to.be('python');
         expect(lang.name).to.be('python');
@@ -137,6 +114,65 @@ describe('notebook/notebook', () => {
         expect(() => { model.cells = null; }).to.throwError();
         expect(() => { model.cells = null; }).to.throwError();
       });
       });
 
 
+      context('cells `changed` signal', () => {
+
+        it('should emit a `contentChanged` signal', () => {
+          let model = new NotebookModel();
+          let cell = model.createCodeCell();
+          let called = false;
+          model.contentChanged.connect(() => { called = true; });
+          model.cells.add(cell);
+          expect(called).to.be(true);
+        });
+
+        it('should set the dirty flag', () => {
+          let model = new NotebookModel();
+          let cell = model.createCodeCell();
+          model.cells.add(cell);
+          expect(model.dirty).to.be(true);
+        });
+
+        it('should dispose of old cells', () => {
+          let model = new NotebookModel();
+          let cell = model.createCodeCell();
+          model.cells.add(cell);
+          model.cells.clear();
+          expect(cell.isDisposed).to.be(true);
+        });
+
+      });
+
+      describe('cell `changed` signal', () => {
+
+        it('should be called when a cell content changes', () => {
+          let model = new NotebookModel();
+          let cell = model.createCodeCell();
+          model.cells.add(cell);
+          cell.source = 'foo';
+        });
+
+        it('should emit the `contentChanged` signal', () => {
+          let model = new NotebookModel();
+          let cell = model.createCodeCell();
+          model.cells.add(cell);
+          let called = false;
+          model.contentChanged.connect(() => { called = true; });
+          let cursor = cell.getMetadata('foo');
+          cursor.setValue('bar');
+          expect(called).to.be(true);
+        });
+
+        it('should set the dirty flag', () => {
+          let model = new NotebookModel();
+          let cell = model.createCodeCell();
+          model.cells.add(cell);
+          model.dirty = false;
+          cell.source = 'foo';
+          expect(model.dirty).to.be(true);
+        });
+
+      });
+
     });
     });
 
 
     describe('#nbformat', () => {
     describe('#nbformat', () => {
@@ -401,108 +437,24 @@ describe('notebook/notebook', () => {
         expect(cursor1.getValue()).to.be(1);
         expect(cursor1.getValue()).to.be(1);
       });
       });
 
 
-    });
-
-    describe('#listMetadata()', () => {
-
-      it('should list the metadata namespace keys for the notebook', () => {
+      it('should set the dirty flag', () => {
         let model = new NotebookModel();
         let model = new NotebookModel();
-        let keys = ['kernelspec', 'language_info', 'orig_nbformat'];
-        expect(model.listMetadata()).to.eql(keys);
         let cursor = model.getMetadata('foo');
         let cursor = model.getMetadata('foo');
-        expect(model.listMetadata()).to.eql(keys);
-        cursor.setValue(1);
-        keys.push('foo');
-        expect(model.listMetadata()).to.eql(keys);
-      });
-
-    });
-
-    describe('#onCellsChanged()', () => {
-
-      it('should emit a `contentChanged` signal', () => {
-        let model = new LogNotebookModel();
-        let cell = model.createCodeCell();
-        let called = false;
-        model.contentChanged.connect(() => { called = true; });
-        model.cells.add(cell);
-        expect(model.methods.indexOf('onCellsChanged')).to.not.be(-1);
-        expect(called).to.be(true);
-      });
-
-      it('should set the dirty flag', () => {
-        let model = new LogNotebookModel();
-        let cell = model.createCodeCell();
-        model.cells.add(cell);
-        expect(model.methods.indexOf('onCellsChanged')).to.not.be(-1);
-        expect(model.dirty).to.be(true);
-      });
-
-      it('should dispose of old cells', () => {
-        let model = new LogNotebookModel();
-        let cell = model.createCodeCell();
-        model.cells.add(cell);
-        model.cells.clear();
-        expect(cell.isDisposed).to.be(true);
-      });
-
-    });
-
-    describe('#onCellChanged()', () => {
-
-      it('should be called when a cell content changes', () => {
-        let model = new LogNotebookModel();
-        let cell = model.createCodeCell();
-        model.cells.add(cell);
-        cell.source = 'foo';
-        expect(model.methods.indexOf('onCellChanged')).to.not.be(-1);
-      });
-
-      it('should emit the `contentChanged` signal', () => {
-        let model = new LogNotebookModel();
-        let cell = model.createCodeCell();
-        model.cells.add(cell);
-        let called = false;
-        model.contentChanged.connect(() => { called = true; });
-        let cursor = cell.getMetadata('foo');
         cursor.setValue('bar');
         cursor.setValue('bar');
-        expect(model.methods.indexOf('onCellChanged')).to.not.be(-1);
-        expect(called).to.be(true);
-      });
-
-      it('should set the dirty flag', () => {
-        let model = new LogNotebookModel();
-        let cell = model.createCodeCell();
-        model.cells.add(cell);
-        model.dirty = false;
-        cell.source = 'foo';
-        expect(model.methods.indexOf('onCellChanged')).to.not.be(-1);
         expect(model.dirty).to.be(true);
         expect(model.dirty).to.be(true);
       });
       });
 
 
-    });
-
-    describe('#setCursorData()', () => {
-
-      it('should set the dirty flag', () => {
-        let model = new LogNotebookModel();
-        let cursor = model.getMetadata('foo');
-        cursor.setValue('bar');
-        expect(model.methods.indexOf('setCursorData')).to.not.be(-1);
-      });
-
       it('should emit the `contentChanged` signal', () => {
       it('should emit the `contentChanged` signal', () => {
-        let model = new LogNotebookModel();
+        let model = new NotebookModel();
         let cursor = model.getMetadata('foo');
         let cursor = model.getMetadata('foo');
         let called = false;
         let called = false;
         model.contentChanged.connect(() => { called = true; });
         model.contentChanged.connect(() => { called = true; });
         cursor.setValue('bar');
         cursor.setValue('bar');
-        expect(model.methods.indexOf('setCursorData')).to.not.be(-1);
         expect(called).to.be(true);
         expect(called).to.be(true);
       });
       });
 
 
       it('should emit the `metadataChanged` signal', () => {
       it('should emit the `metadataChanged` signal', () => {
-        let model = new LogNotebookModel();
+        let model = new NotebookModel();
         let cursor = model.getMetadata('foo');
         let cursor = model.getMetadata('foo');
         let called = false;
         let called = false;
         model.metadataChanged.connect((sender, args) => {
         model.metadataChanged.connect((sender, args) => {
@@ -513,9 +465,22 @@ describe('notebook/notebook', () => {
           called = true;
           called = true;
         });
         });
         cursor.setValue('bar');
         cursor.setValue('bar');
-        expect(model.methods.indexOf('setCursorData')).to.not.be(-1);
         expect(called).to.be(true);
         expect(called).to.be(true);
       });
       });
+    });
+
+    describe('#listMetadata()', () => {
+
+      it('should list the metadata namespace keys for the notebook', () => {
+        let model = new NotebookModel();
+        let keys = ['kernelspec', 'language_info', 'orig_nbformat'];
+        expect(model.listMetadata()).to.eql(keys);
+        let cursor = model.getMetadata('foo');
+        expect(model.listMetadata()).to.eql(keys);
+        cursor.setValue(1);
+        keys.push('foo');
+        expect(model.listMetadata()).to.eql(keys);
+      });
 
 
     });
     });
 
 

+ 83 - 80
test/src/notebook/notebook/widget.spec.ts

@@ -16,7 +16,7 @@ import {
 } from 'phosphor-properties';
 } from 'phosphor-properties';
 
 
 import {
 import {
-  Widget
+  ChildMessage, Widget
 } from 'phosphor-widget';
 } from 'phosphor-widget';
 
 
 import {
 import {
@@ -36,7 +36,7 @@ import {
 } from '../../../../lib/notebook/notebook/model';
 } from '../../../../lib/notebook/notebook/model';
 
 
 import {
 import {
-  ActiveNotebook, NotebookRenderer
+  Notebook, StaticNotebook
 } from '../../../../lib/notebook/notebook/widget';
 } from '../../../../lib/notebook/notebook/widget';
 
 
 import {
 import {
@@ -51,16 +51,16 @@ import {
 const DEFAULT_CONTENT: nbformat.INotebookContent = require('../../../../examples/notebook/test.ipynb') as nbformat.INotebookContent;
 const DEFAULT_CONTENT: nbformat.INotebookContent = require('../../../../examples/notebook/test.ipynb') as nbformat.INotebookContent;
 
 
 
 
-function createWidget(): LogNotebookRenderer {
+function createWidget(): LogStaticNotebook {
   let model = new NotebookModel();
   let model = new NotebookModel();
   let rendermime = defaultRenderMime();
   let rendermime = defaultRenderMime();
-  let widget = new LogNotebookRenderer(rendermime);
+  let widget = new LogStaticNotebook(rendermime);
   widget.model = model;
   widget.model = model;
   return widget;
   return widget;
 }
 }
 
 
 
 
-class LogNotebookRenderer extends NotebookRenderer {
+class LogStaticNotebook extends StaticNotebook {
 
 
   methods: string[] = [];
   methods: string[] = [];
 
 
@@ -69,34 +69,29 @@ class LogNotebookRenderer extends NotebookRenderer {
     this.methods.push('onUpdateRequest');
     this.methods.push('onUpdateRequest');
   }
   }
 
 
-  protected onMetadataChanged(model: INotebookModel, args: IChangedArgs<any>): void {
-    super.onMetadataChanged(model, args);
-    this.methods.push('onMetadataChanged');
+  protected onChildAdded(msg: ChildMessage): void {
+    super.onChildAdded(msg);
+    this.methods.push('onChildAdded');
   }
   }
 
 
-  protected onCellsChanged(sender: IObservableList<ICellModel>, args: IListChangedArgs<ICellModel>) {
-    super.onCellsChanged(sender, args);
-    this.methods.push('onCellsChanged');
+  protected onChildRemoved(msg: ChildMessage): void {
+    super.onChildRemoved(msg);
+    this.methods.push('onChildRemoved');
   }
   }
 
 
-  protected initialize(model: INotebookModel): void {
-    super.initialize(model);
-    this.methods.push('initialize');
+  protected changeModel(oldValue: INotebookModel, newValue: INotebookModel): void {
+    super.changeModel(oldValue, newValue);
+    this.methods.push('changeModel');
   }
   }
 
 
-  protected initializeCellWidget(widget: BaseCellWidget): void {
-    super.initializeCellWidget(widget);
-    this.methods.push('initializeCellWidget');
-  }
-
-  protected updateMimetypes(): void {
-    this.methods.push('updateMimetypes');
-    return super.updateMimetypes();
+  protected setChildMimetypes(): void {
+    this.methods.push('setChildMimetypes');
+    return super.setChildMimetypes();
   }
   }
 }
 }
 
 
 
 
-class LogActiveNotebook extends ActiveNotebook {
+class LogNotebook extends Notebook {
 
 
   events: string[] = [];
   events: string[] = [];
 
 
@@ -122,22 +117,17 @@ class LogActiveNotebook extends ActiveNotebook {
     this.methods.push('onUpdateRequest');
     this.methods.push('onUpdateRequest');
   }
   }
 
 
-  protected initializeCellWidget(widget: BaseCellWidget): void {
-    super.initializeCellWidget(widget);
-    this.methods.push('initializeCellWidget');
-  }
-
-  protected onEdgeRequest(widget: Widget, location: EdgeLocation): void {
-    super.onEdgeRequest(widget, location);
-    this.methods.push('onEdgeRequest');
+  protected onChildAdded(msg: ChildMessage): void {
+    super.onChildAdded(msg);
+    this.methods.push('onChildAdded');
   }
   }
 }
 }
 
 
 
 
-function createActiveWidget(): LogActiveNotebook {
+function createActiveWidget(): LogNotebook {
   let model = new NotebookModel();
   let model = new NotebookModel();
   let rendermime = defaultRenderMime();
   let rendermime = defaultRenderMime();
-  let widget = new LogActiveNotebook(rendermime);
+  let widget = new LogNotebook(rendermime);
   widget.model = model;
   widget.model = model;
   return widget;
   return widget;
 }
 }
@@ -145,7 +135,7 @@ function createActiveWidget(): LogActiveNotebook {
 
 
 describe('notebook/notebook/widget', () => {
 describe('notebook/notebook/widget', () => {
 
 
-  describe('NotebookRenderer', () => {
+  describe('StaticNotebook', () => {
 
 
     describe('.createCell()', () => {
     describe('.createCell()', () => {
 
 
@@ -153,7 +143,7 @@ describe('notebook/notebook/widget', () => {
         let model = new NotebookModel();
         let model = new NotebookModel();
         let rendermime = defaultRenderMime();
         let rendermime = defaultRenderMime();
         let cell = model.createCodeCell();
         let cell = model.createCodeCell();
-        let widget = NotebookRenderer.createCell(cell, rendermime);
+        let widget = StaticNotebook.createCell(cell, rendermime);
         expect(widget).to.be.a(CodeCellWidget);
         expect(widget).to.be.a(CodeCellWidget);
       });
       });
 
 
@@ -161,7 +151,7 @@ describe('notebook/notebook/widget', () => {
         let model = new NotebookModel();
         let model = new NotebookModel();
         let rendermime = defaultRenderMime();
         let rendermime = defaultRenderMime();
         let cell = model.createRawCell();
         let cell = model.createRawCell();
-        let widget = NotebookRenderer.createCell(cell, rendermime);
+        let widget = StaticNotebook.createCell(cell, rendermime);
         expect(widget).to.be.a(RawCellWidget);
         expect(widget).to.be.a(RawCellWidget);
       });
       });
 
 
@@ -169,7 +159,7 @@ describe('notebook/notebook/widget', () => {
         let model = new NotebookModel();
         let model = new NotebookModel();
         let rendermime = defaultRenderMime();
         let rendermime = defaultRenderMime();
         let cell = model.createMarkdownCell();
         let cell = model.createMarkdownCell();
-        let widget = NotebookRenderer.createCell(cell, rendermime);
+        let widget = StaticNotebook.createCell(cell, rendermime);
         expect(widget).to.be.a(MarkdownCellWidget);
         expect(widget).to.be.a(MarkdownCellWidget);
       });
       });
 
 
@@ -179,58 +169,82 @@ describe('notebook/notebook/widget', () => {
 
 
       it('should create a notebook widget', () => {
       it('should create a notebook widget', () => {
         let rendermime = defaultRenderMime();
         let rendermime = defaultRenderMime();
-        let widget = new NotebookRenderer(rendermime);
-        expect(widget).to.be.a(NotebookRenderer);
+        let widget = new StaticNotebook(rendermime);
+        expect(widget).to.be.a(StaticNotebook);
       });
       });
 
 
       it('should add the `jp-Notebook` class', () => {
       it('should add the `jp-Notebook` class', () => {
         let rendermime = defaultRenderMime();
         let rendermime = defaultRenderMime();
-        let widget = new NotebookRenderer(rendermime);
+        let widget = new StaticNotebook(rendermime);
         expect(widget.hasClass('jp-Notebook')).to.be(true);
         expect(widget.hasClass('jp-Notebook')).to.be(true);
       });
       });
 
 
     });
     });
 
 
+    describe('#modelChanged', () => {
+
+      it('should be emitted when the model changes', () => {
+        let widget = new StaticNotebook(defaultRenderMime());
+        let model = new NotebookModel();
+        let called = false;
+        widget.modelChanged.connect((sender, args) => {
+          expect(sender).to.be(widget);
+          expect(args).to.be(model);
+          called = true;
+        });
+        widget.model = model;
+        expect(called).to.be(true);
+      });
+
+    });
+
     describe('#model', () => {
     describe('#model', () => {
 
 
       it('should get the model for the widget', () => {
       it('should get the model for the widget', () => {
-        let widget = new NotebookRenderer(defaultRenderMime());
+        let widget = new StaticNotebook(defaultRenderMime());
         expect(widget.model).to.be(null);
         expect(widget.model).to.be(null);
       });
       });
 
 
       it('should set the model for the widget', () => {
       it('should set the model for the widget', () => {
-        let widget = new NotebookRenderer(defaultRenderMime());
+        let widget = new StaticNotebook(defaultRenderMime());
         let model = new NotebookModel();
         let model = new NotebookModel();
         widget.model = model;
         widget.model = model;
         expect(widget.model).to.be(model);
         expect(widget.model).to.be(model);
       });
       });
 
 
-      it('should call `initialize()` on the widget', () => {
-        let widget = new LogNotebookRenderer(defaultRenderMime());
+      it('should emit the `modelChanged` signal', () => {
+        let widget = new StaticNotebook(defaultRenderMime());
         let model = new NotebookModel();
         let model = new NotebookModel();
         widget.model = model;
         widget.model = model;
-        expect(widget.methods.indexOf('initialize')).to.not.be(-1);
+        let called = false;
+        widget.modelChanged.connect(() => { called = true; });
+        widget.model = new NotebookModel();
+        expect(called).to.be(true);
       });
       });
 
 
-      it('should throw an error when changing to a different value', () => {
-        let widget = new LogNotebookRenderer(defaultRenderMime());
+      it('should be a no-op if the value does not change', () => {
+        let widget = new StaticNotebook(defaultRenderMime());
         let model = new NotebookModel();
         let model = new NotebookModel();
         widget.model = model;
         widget.model = model;
-        expect(() => { widget.model = new NotebookModel(); }).to.throwError();
-      });
-
-      it('should throw an error if set to `null`', () => {
-        let widget = new LogNotebookRenderer(defaultRenderMime());
-        widget.model = new NotebookModel();
-        expect(() => { widget.model = null; }).to.throwError();
+        let called = false;
+        widget.modelChanged.connect(() => { called = true; });
+        widget.model = model;
+        expect(called).to.be(false);
       });
       });
 
 
-      it('should be a no-op if the value does not change', () => {
-        let widget = new NotebookRenderer(defaultRenderMime());
+      it('should call `changeModel`', () => {
+        let widget = new LogStaticNotebook(defaultRenderMime());
         let model = new NotebookModel();
         let model = new NotebookModel();
         widget.model = model;
         widget.model = model;
-        widget.model = model;
-        expect(widget.model).to.be(model);
+        expect(widget.methods.indexOf('changeModel')).to.not.be(-1);
+      });
+
+      context('`cells.changed` signal', () => {
+
+      });
+
+      context('`metadataChanged` signal', () => {
+
       });
       });
 
 
     });
     });
@@ -239,7 +253,7 @@ describe('notebook/notebook/widget', () => {
 
 
       it('should be the rendermime instance used by the widget', () => {
       it('should be the rendermime instance used by the widget', () => {
         let rendermime = defaultRenderMime();
         let rendermime = defaultRenderMime();
-        let widget = new NotebookRenderer(rendermime);
+        let widget = new StaticNotebook(rendermime);
         expect(widget.rendermime).to.be(rendermime);
         expect(widget.rendermime).to.be(rendermime);
       });
       });
 
 
@@ -297,31 +311,20 @@ describe('notebook/notebook/widget', () => {
 
 
     });
     });
 
 
-    describe('#initialize()', () => {
+    describe('#changeModel()', () => {
 
 
-      it('should add the cells to the initial layout', () => {
-        let widget = new LogNotebookRenderer(defaultRenderMime());
+      it('should add the model cells to the layout', () => {
+        let widget = new LogStaticNotebook(defaultRenderMime());
         let model = new NotebookModel();
         let model = new NotebookModel();
         model.fromJSON(DEFAULT_CONTENT);
         model.fromJSON(DEFAULT_CONTENT);
-        expect(widget.methods.indexOf('initialize')).to.be(-1);
+        expect(widget.methods.indexOf('changeModel')).to.be(-1);
         widget.model = model;
         widget.model = model;
         expect(widget.childCount()).to.be(6);
         expect(widget.childCount()).to.be(6);
-        expect(widget.methods.indexOf('initialize')).to.not.be(-1);
-      });
-
-      it('should add a code cell if there are no cells', () => {
-        let widget = new LogNotebookRenderer(defaultRenderMime());
-        let model = new NotebookModel();
-        expect(widget.methods.indexOf('initialize')).to.be(-1);
-        widget.model = model;
-        expect(widget.childCount()).to.be(1);
-        expect(widget.methods.indexOf('initialize')).to.not.be(-1);
-        let cell = widget.childAt(0);
-        expect(cell).to.be.a(CodeCellWidget);
+        expect(widget.methods.indexOf('changeModel')).to.not.be(-1);
       });
       });
 
 
       it('should set the mime types of the cell widgets', () => {
       it('should set the mime types of the cell widgets', () => {
-        let widget = new LogNotebookRenderer(defaultRenderMime());
+        let widget = new LogStaticNotebook(defaultRenderMime());
         let model = new NotebookModel();
         let model = new NotebookModel();
         let cursor = model.getMetadata('language_info');
         let cursor = model.getMetadata('language_info');
         cursor.setValue({ name: 'python', codemirror_mode: 'python' });
         cursor.setValue({ name: 'python', codemirror_mode: 'python' });
@@ -364,7 +367,7 @@ describe('notebook/notebook/widget', () => {
 
 
     describe('#onCellsChanged()', () => {
     describe('#onCellsChanged()', () => {
 
 
-      let widget: LogNotebookRenderer;
+      let widget: LogStaticNotebook;
 
 
       beforeEach(() => {
       beforeEach(() => {
         widget = createWidget();
         widget = createWidget();
@@ -446,7 +449,7 @@ describe('notebook/notebook/widget', () => {
 
 
   });
   });
 
 
-  describe('ActiveNotebook', () => {
+  describe('Notebook', () => {
 
 
     describe('#stateChanged', () => {
     describe('#stateChanged', () => {
 
 
@@ -664,7 +667,7 @@ describe('notebook/notebook/widget', () => {
 
 
     describe('#handleEvent()', () => {
     describe('#handleEvent()', () => {
 
 
-      let widget: LogActiveNotebook;
+      let widget: LogNotebook;
 
 
       beforeEach((done) => {
       beforeEach((done) => {
         widget = createActiveWidget();
         widget = createActiveWidget();
@@ -811,7 +814,7 @@ describe('notebook/notebook/widget', () => {
 
 
     describe('#onUpdateRequest()', () => {
     describe('#onUpdateRequest()', () => {
 
 
-      let widget: LogActiveNotebook;
+      let widget: LogNotebook;
 
 
       beforeEach((done) => {
       beforeEach((done) => {
         widget = createActiveWidget();
         widget = createActiveWidget();