123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420 |
- // Copyright (c) Jupyter Development Team.
- // Distributed under the terms of the Modified BSD License.
- 'use strict';
- import * as utils
- from 'jupyter-js-utils';
- import {
- IDisposable
- } from 'phosphor-disposable';
- import {
- ISignal, Signal, clearSignalData
- } from 'phosphor-signaling';
- import {
- CellType, IBaseCell, ICodeCell
- } from '../notebook/nbformat';
- import {
- ObservableOutputs
- } from '../output-area';
- /**
- * The definition of a model object for a cell.
- */
- export
- interface ICellModel extends IDisposable {
- /**
- * The type of cell.
- */
- type: CellType;
- /**
- * A signal emitted when the content of the model changes.
- */
- contentChanged: ISignal<ICellModel, string>;
- /**
- * The input content of the cell.
- */
- source: string;
- /**
- * Serialize the model to JSON.
- */
- toJSON(): any;
- /**
- * Get a metadata cursor for the cell.
- *
- * #### 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 cell.
- */
- getMetadata(name: string): IMetadataCursor;
- /**
- * List the metadata namespace keys for the notebook.
- *
- * #### Notes
- * Metadata associated with the nbformat are not included.
- */
- listMetadata(): string[];
- }
- /**
- * The definition of a code cell.
- */
- export
- interface ICodeCellModel extends ICellModel {
- /**
- * The code cell's prompt number. Will be null if the cell has not been run.
- */
- executionCount: number;
- /**
- * The cell outputs.
- */
- outputs: ObservableOutputs;
- }
- /**
- * An implementation of the cell model.
- */
- export
- class CellModel implements ICellModel {
- /**
- * Construct a cell model from optional cell content.
- */
- constructor(cell?: IBaseCell) {
- if (!cell) {
- return;
- }
- this.source = cell.source;
- let metadata = utils.copy(cell.metadata);
- if (this.type !== 'raw') {
- delete metadata['format'];
- }
- if (this.type !== 'code') {
- delete metadata['collapsed'];
- delete metadata['scrolled'];
- }
- this._metadata = metadata;
- }
- /**
- * A signal emitted when the state of the model changes.
- */
- get contentChanged(): ISignal<ICellModel, string> {
- return Private.contentChangedSignal.bind(this);
- }
- /**
- * The input content of the cell.
- */
- get source(): string {
- return this._source;
- }
- set source(value: string) {
- if (this._source === value) {
- return;
- }
- this._source = value;
- this.contentChanged.emit('source');
- }
- /**
- * Get whether the model is disposed.
- *
- * #### Notes
- * This is a read-only property.
- */
- get isDisposed(): boolean {
- return this._metadata === null;
- }
- /**
- * Dispose of the resources held by the model.
- */
- dispose(): void {
- // Do nothing if already disposed.
- if (this.isDisposed) {
- return;
- }
- clearSignalData(this);
- for (let cursor of this._cursors) {
- cursor.dispose();
- }
- this._cursors = null;
- this._metadata = null;
- }
- /**
- * Serialize the model to JSON.
- */
- toJSON(): IBaseCell {
- return {
- cell_type: this.type,
- source: this.source,
- metadata: utils.copy(this._metadata)
- };
- }
- /**
- * Get a metadata cursor for the cell.
- *
- * #### 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 cell.
- */
- getMetadata(name: string): IMetadataCursor {
- let cursor = new MetadataCursor(
- name,
- () => {
- return this._metadata[name];
- },
- (value: string) => {
- this.setCursorData(name, value);
- }
- );
- this._cursors.push(cursor);
- return cursor;
- }
- /**
- * List the metadata namespace keys for the notebook.
- *
- * #### Notes
- * Metadata associated with the nbformat are not included.
- */
- listMetadata(): string[] {
- return Object.keys(this._metadata);
- }
- /**
- * Set the cursor data for a given field.
- */
- protected setCursorData(name: string, value: string): void {
- if (this._metadata[name] === value) {
- return;
- }
- this._metadata[name] = value;
- this.contentChanged.emit(`metadata.${name}`);
- }
- /**
- * The type of cell.
- */
- type: CellType;
- private _metadata: { [key: string]: string } = Object.create(null);
- private _cursors: MetadataCursor[] = [];
- private _source = '';
- }
- /**
- * An implementation of a raw cell model.
- */
- export
- class RawCellModel extends CellModel {
- type: CellType = 'code';
- }
- /**
- * An implementation of a markdown cell model.
- */
- export
- class MarkdownCellModel extends CellModel {
- type: CellType = 'markdown';
- }
- /**
- * An implementation of a code cell Model.
- */
- export
- class CodeCellModel extends CellModel implements ICodeCellModel {
- /**
- * Construct a new code cell with optional original cell content.
- */
- constructor(cell?: IBaseCell) {
- super(cell);
- this._outputs = new ObservableOutputs();
- if (cell && cell.cell_type === 'code') {
- this.executionCount = (cell as ICodeCell).execution_count;
- this._outputs.assign((cell as ICodeCell).outputs);
- }
- this._outputs.changed.connect(() => {
- this.contentChanged.emit('outputs');
- });
- }
- /**
- * The execution count of the cell.
- */
- get executionCount(): number {
- return this._executionCount;
- }
- set executionCount(value: number) {
- if (value === this._executionCount) {
- return;
- }
- this._executionCount = value;
- this.contentChanged.emit('executionCount');
- }
- /**
- * The cell outputs.
- *
- * #### Notes
- * This is a read-only property.
- */
- get outputs(): ObservableOutputs {
- return this._outputs;
- }
- /**
- * Dispose of the resources held by the model.
- */
- dispose(): void {
- if (this.isDisposed) {
- return;
- }
- this._outputs.clear(false);
- this._outputs = null;
- super.dispose();
- }
- /**
- * Serialize the model to JSON.
- */
- toJSON(): ICodeCell {
- let cell = super.toJSON() as ICodeCell;
- cell.execution_count = this.executionCount;
- let outputs = this.outputs;
- cell.outputs = [];
- for (let i = 0; i < outputs.length; i++) {
- cell.outputs.push(outputs.get(i));
- }
- return cell;
- }
- type: CellType = 'code';
- private _outputs: ObservableOutputs = null;
- private _executionCount: number = null;
- }
- /**
- * A class used to interact with user level metadata.
- */
- export
- interface IMetadataCursor extends IDisposable {
- /**
- * The metadata namespace.
- */
- name: string;
- /**
- * Get the value of the metadata.
- */
- getValue(): any;
- /**
- * Set the value of the metdata.
- */
- setValue(value: any): void;
- }
- /**
- * An implementation of a metadata cursor.
- */
- export
- class MetadataCursor implements IMetadataCursor {
- /**
- * Construct a new metadata cursor.
- *
- * @param name - the metadata namespace key.
- *
- * @param value - this initial value of the namespace.
- *
- * @param cb - a change callback.
- */
- constructor(name: string, read: () => string, write: (value: string) => void) {
- this._name = name;
- this._read = read;
- this._write = write;
- }
- /**
- * Get the namespace key of the metadata.
- *
- * #### Notes
- * This is a read-only property.
- */
- get name(): string {
- return this._name;
- }
- /**
- * Get whether the cursor is disposed.
- */
- get isDisposed(): boolean {
- return this._read === null;
- }
- /**
- * Dispose of the resources used by the cursor.
- */
- dispose(): void {
- if (this.isDisposed) {
- return;
- }
- this._read = null;
- this._write = null;
- }
- /**
- * Get the value of the namespace data.
- */
- getValue(): any {
- let value = this._read.call(void 0);
- return JSON.parse(value || 'null');
- }
- /**
- * Set the value of the namespace data.
- */
- setValue(value: any): any {
- this._write.call(void 0, JSON.stringify(value));
- }
- private _name = '';
- private _read: () => string = null;
- private _write: (value: string) => void = null;
- }
- /**
- * A namespace for cell private data.
- */
- namespace Private {
- /**
- * A signal emitted when the state of the model changes.
- */
- export
- const contentChangedSignal = new Signal<ICellModel, string>();
- }
|