Quellcode durchsuchen

Merge pull request #37 from blink1073/readonly-notebook

Allow readonly notebooks and fix default mimetype
Dave Willmer vor 9 Jahren
Ursprung
Commit
89627009ab
3 geänderte Dateien mit 61 neuen und 27 gelöschten Zeilen
  1. 46 11
      src/notebook/notebook/model.ts
  2. 9 15
      src/notebook/notebook/serialize.ts
  3. 6 1
      src/notebook/notebook/widget.ts

+ 46 - 11
src/notebook/notebook/model.ts

@@ -53,17 +53,8 @@ import {
  * The interactivity modes for a notebook.
  */
 export
-enum NotebookMode {
-  /**
-   * Command mode is used for navigation and manipulation.
-   */
-  Command,
+type NotebookMode = "command" | "edit";
 
-  /**
-   * Edit mode is used for text and code editing.
-   */
-  Edit
-}
 
 /**
  * The definition of a model object for a notebook widget.
@@ -88,6 +79,11 @@ interface INotebookModel {
    */
   dirty: boolean;
 
+  /**
+   * Whether the notebook is read-only.
+   */
+  readOnly: boolean;
+
   /**
    * Whether the notebook can be trusted.
    *
@@ -236,6 +232,25 @@ class NotebookModel implements INotebookModel {
     NotebookModelPrivate.modeProperty.set(this, value);
   }
 
+  /**
+   * Get the read-only status of the notebook.
+   */
+  get readOnly(): boolean {
+    return NotebookModelPrivate.readOnlyProperty.get(this);
+  }
+
+  /**
+   * Set the read-only status of the notebook.
+   */
+  set readOnly(value: boolean) {
+    NotebookModelPrivate.readOnlyProperty.set(this, value);
+    let cells = this._cells;
+    for (let i = 0; i < cells.length; i++) {
+      let cell = cells.get(i);
+      cell.input.textEditor.readOnly = value;
+    }
+  }
+
   /**
    * Get the session for the notebook.
    */
@@ -325,11 +340,15 @@ class NotebookModel implements INotebookModel {
    */
   createCodeCell(source?: ICellModel): ICodeCellModel {
     let input = new InputAreaModel();
-    input.textEditor = new EditorModel({ lineNumbers: false });
+    input.textEditor = new EditorModel({
+      lineNumbers: false,
+      mimetype: this.defaultMimetype
+    });
     let cell = new CodeCellModel();
     cell.input = input;
     let outputArea = new OutputAreaModel();
     cell.output = outputArea;
+    cell.input.textEditor.readOnly = this.readOnly;
     return cell;
   }
 
@@ -341,6 +360,7 @@ class NotebookModel implements INotebookModel {
     input.textEditor = new EditorModel({ lineNumbers: false });
     let cell  = new MarkdownCellModel();
     cell.input = input;
+    cell.input.textEditor.readOnly = this.readOnly;
     return cell;
   }
 
@@ -348,6 +368,9 @@ class NotebookModel implements INotebookModel {
    * Run the selected cell, taking the appropriate action.
    */
   runSelectedCell(): void {
+    if (this.readOnly) {
+      return;
+    }
     let cell = this.cells.get(this.selectedCellIndex);
     if (!cell) {
       return;
@@ -368,6 +391,9 @@ class NotebookModel implements INotebookModel {
    * Execute the given cell. 
    */
   protected executeCell(cell: CodeCellModel): void {
+    if (this.readOnly) {
+      return;
+    }
     let session = this.session;
     if (!session) {
       return;
@@ -442,6 +468,15 @@ namespace NotebookModelPrivate {
     notify: stateChangedSignal,
   });
 
+  /**
+  * A property descriptor which holds the read only status of the notebook.
+  */
+  export
+  const readOnlyProperty = new Property<NotebookModel, boolean>({
+    name: 'readOnly',
+    notify: stateChangedSignal,
+  });
+
  /**
   * A property descriptor which holds the session of the notebook.
   */

+ 9 - 15
src/notebook/notebook/serialize.ts

@@ -47,31 +47,25 @@ import {
 export
 function populateNotebookModel(nb: INotebookModel, data: NotebookContent): void {
   nb.cells.clear();
+  nb.defaultMimetype = 'text/x-python';
 
-  // iterate through the cell data, creating cell models
+  // Iterate through the cell data, creating cell models.
   data.cells.forEach((c) => {
-    let input = new InputAreaModel();
-    input.textEditor = new EditorModel({ lineNumbers: false });
-    input.textEditor.text = c.source;
-
     if (isMarkdownCell(c)) {
-      let cell = new MarkdownCellModel();
-      cell.input = input;
+      let cell = nb.createMarkdownCell();
+      cell.input.textEditor.text = c.source;
       cell.rendered = true;
       nb.cells.add(cell);
     } else if (isCodeCell(c)) {
-      let cell = new CodeCellModel();
-      cell.input = input;
-      let outputArea = new OutputAreaModel();
-      cell.output = outputArea;
-      for (let i=0; i<c.outputs.length; i++) {
-        outputArea.add(buildOutputModel(c.outputs[i]));
+      let cell = nb.createCodeCell();
+      cell.input.textEditor.text = c.source;
+      for (let i = 0; i < c.outputs.length; i++) {
+        cell.output.add(buildOutputModel(c.outputs[i]));
       }
       nb.cells.add(cell);
     }
   });
-
-  nb.defaultMimetype = 'text/x-python';
+  
   if (nb.cells.length) {
     nb.selectedCellIndex = 0;
   }

+ 6 - 1
src/notebook/notebook/widget.ts

@@ -89,9 +89,14 @@ class NotebookWidget extends Panel {
     // bind events that can select the cell
     // see https://github.com/jupyter/notebook/blob/203ccd3d4496cc22e6a1c5e6ece9f5a7d791472a/notebook/static/notebook/js/cell.js#L178
     this.node.addEventListener('click', (ev: MouseEvent) => {
-      this._model.selectedCellIndex = this.findCell(ev.target as HTMLElement);
+      if (!this._model.readOnly) {
+        this._model.selectedCellIndex = this.findCell(ev.target as HTMLElement);
+      }
     })
     this.node.addEventListener('dblclick', (ev: MouseEvent) => {
+      if (this._model.readOnly) {
+        return;
+      }
       let i = this.findCell(ev.target as HTMLElement);
       if (i === void 0) {
         return;