Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Partial merge of ModelDB proposal. #2039

Merged
merged 16 commits into from
Apr 19, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 61 additions & 42 deletions packages/cells/src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
} from '@jupyterlab/coreutils';

import {
IObservableJSON, ObservableJSON
IObservableJSON, IModelDB, IObservableValue
} from '@jupyterlab/coreutils';

import {
Expand Down Expand Up @@ -121,14 +121,32 @@ class CellModel extends CodeEditor.Model implements ICellModel {
* Construct a cell model from optional cell content.
*/
constructor(options: CellModel.IOptions) {
super();
super({modelDB: options.modelDB});

this.value.changed.connect(this.onGenericChange, this);

let cellType = this.modelDB.createValue('type');
cellType.set(this.type);

let observableMetadata = this.modelDB.createJSON('metadata');
observableMetadata.changed.connect(this.onGenericChange, this);

let cell = options.cell;
let trusted = this.modelDB.createValue('trusted');
if (!cell) {
trusted.set(false);
return;
}
this._trusted = !!cell.metadata['trusted'];
trusted.set(!!cell.metadata['trusted']);
delete cell.metadata['trusted'];
trusted.changed.connect((value, args) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a general pattern we don't connect signals to anonymous functions, because they won't be cleared by Signal.clearData(this).

this.onTrustedChanged(args.newValue as boolean);
this.stateChanged.emit({
name: 'trusted',
oldValue: args.oldValue,
newValue: args.newValue
});
});

if (Array.isArray(cell.source)) {
this.value.text = (cell.source as string[]).join('\n');
Expand All @@ -143,10 +161,10 @@ class CellModel extends CodeEditor.Model implements ICellModel {
delete metadata['collapsed'];
delete metadata['scrolled'];
}

for (let key in metadata) {
this._metadata.set(key, metadata[key]);
observableMetadata.set(key, metadata[key]);
}
this._metadata.changed.connect(this.onGenericChange, this);
}

/**
Expand All @@ -168,35 +186,25 @@ class CellModel extends CodeEditor.Model implements ICellModel {
* The metadata associated with the cell.
*/
get metadata(): IObservableJSON {
return this._metadata;
return this.modelDB.get('metadata') as IObservableJSON;
}

/**
* Get the trusted state of the model.
*/
get trusted(): boolean {
return this._trusted;
return (this.modelDB.get('trusted') as IObservableValue).get() as boolean;
}

/**
* Set the trusted state of the model.
*/
set trusted(newValue: boolean) {
if (this._trusted === newValue) {
let oldValue = this.trusted;
if (oldValue === newValue) {
return;
}
let oldValue = this._trusted;
this._trusted = newValue;
this.onTrustedChanged(newValue);
this.stateChanged.emit({ name: 'trusted', oldValue, newValue });
}

/**
* Dispose of the resources held by the model.
*/
dispose(): void {
this._metadata.dispose();
super.dispose();
(this.modelDB.get('trusted') as IObservableValue).set(newValue);
}

/**
Expand Down Expand Up @@ -231,9 +239,6 @@ class CellModel extends CodeEditor.Model implements ICellModel {
protected onGenericChange(): void {
this.contentChanged.emit(void 0);
}

private _metadata = new ObservableJSON();
private _trusted = false;
}


Expand All @@ -250,6 +255,16 @@ namespace CellModel {
* The source cell data.
*/
cell?: nbformat.IBaseCell;

/**
* An IModelDB in which to store cell data.
*/
modelDB?: IModelDB;

/**
* A unique identifier for this cell.
*/
uuid?: string;
}
}

Expand Down Expand Up @@ -307,13 +322,27 @@ class CodeCellModel extends CellModel implements ICodeCellModel {
let trusted = this.trusted;
let cell = options.cell as nbformat.ICodeCell;
let outputs: nbformat.IOutput[] = [];
if (cell && cell.cell_type === 'code') {
this.executionCount = cell.execution_count;
outputs = cell.outputs;
let executionCount = this.modelDB.createValue('executionCount');
if (!executionCount.get()) {
if (cell && cell.cell_type === 'code') {
executionCount.set(cell.execution_count || null);
outputs = cell.outputs;
} else {
executionCount.set(null);
}
}
executionCount.changed.connect((value, args) => {
this.contentChanged.emit(void 0);
this.stateChanged.emit({
name: 'executionCount',
oldValue: args.oldValue,
newValue: args.newValue });
});

this._outputs = factory.createOutputArea({
trusted,
values: outputs
values: outputs,
modelDB: this.modelDB
});
this._outputs.stateChanged.connect(this.onGenericChange, this);
}
Expand All @@ -329,16 +358,14 @@ class CodeCellModel extends CellModel implements ICodeCellModel {
* The execution count of the cell.
*/
get executionCount(): nbformat.ExecutionCount {
return this._executionCount || null;
return (this.modelDB.get('executionCount') as IObservableValue).get() as number || null;
}
set executionCount(newValue: nbformat.ExecutionCount) {
if (newValue === this._executionCount) {
let oldValue = this.executionCount;
if (newValue === oldValue) {
return;
}
let oldValue = this.executionCount;
this._executionCount = newValue || null;
this.contentChanged.emit(void 0);
this.stateChanged.emit({ name: 'executionCount', oldValue, newValue });
(this.modelDB.get('executionCount') as IObservableValue).set(newValue || null);
}

/**
Expand Down Expand Up @@ -372,15 +399,12 @@ class CodeCellModel extends CellModel implements ICodeCellModel {

/**
* Handle a change to the trusted state.
*
* The default implementation is a no-op.
*/
onTrustedChanged(value: boolean): void {
this._outputs.trusted = value;
}

private _outputs: IOutputAreaModel = null;
private _executionCount: nbformat.ExecutionCount = null;
}


Expand All @@ -392,12 +416,7 @@ namespace CodeCellModel {
/**
* The options used to initialize a `CodeCellModel`.
*/
export interface IOptions {
/**
* The source cell data.
*/
cell?: nbformat.IBaseCell;

export interface IOptions extends CellModel.IOptions {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be a new line after export

/**
* The factory for output area model creation.
*/
Expand Down
66 changes: 37 additions & 29 deletions packages/codeeditor/src/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,8 @@ import {
} from '@phosphor/signaling';

import {
IChangedArgs
} from '@jupyterlab/coreutils';

import {
IObservableString, ObservableString
} from '@jupyterlab/coreutils';

import {
IObservableMap, ObservableMap
IModelDB, ModelDB, IObservableValue,
IObservableMap, IObservableString, IChangedArgs
} from '@jupyterlab/coreutils';


Expand All @@ -40,7 +33,7 @@ namespace CodeEditor {
* A zero-based position in the editor.
*/
export
interface IPosition {
interface IPosition extends JSONObject {
/**
* The cursor line number.
*/
Expand Down Expand Up @@ -78,7 +71,7 @@ namespace CodeEditor {
* A range.
*/
export
interface IRange {
interface IRange extends JSONObject {
/**
* The position of the first character in the current range.
*
Expand All @@ -102,7 +95,7 @@ namespace CodeEditor {
* A selection style.
*/
export
interface ISelectionStyle {
interface ISelectionStyle extends JSONObject {
/**
* A class name added to a selection.
*/
Expand Down Expand Up @@ -186,8 +179,26 @@ namespace CodeEditor {
*/
constructor(options?: Model.IOptions) {
options = options || {};
this._value = new ObservableString(options.value);
this._mimetype = options.mimeType || 'text/plain';

if(options.modelDB) {
this.modelDB = options.modelDB;
} else {
this.modelDB = new ModelDB();
}

let value = this.modelDB.createString('value');
value.text = value.text || options.value || '';
let mimeType = this.modelDB.createValue('mimeType');
mimeType.set(options.mimeType || 'text/plain');
this.modelDB.createMap<ITextSelection[]>('selections');

mimeType.changed.connect((val, args)=>{
this._mimeTypeChanged.emit({
name: 'mimeType',
oldValue: args.oldValue as string,
newValue: args.newValue as string
});
});
}

/**
Expand All @@ -201,33 +212,28 @@ namespace CodeEditor {
* Get the value of the model.
*/
get value(): IObservableString {
return this._value;
return this.modelDB.get('value') as IObservableString;
}

/**
* Get the selections for the model.
*/
get selections(): IObservableMap<ITextSelection[]> {
return this._selections;
return this.modelDB.get('selections') as IObservableMap<ITextSelection[]>;
}

/**
* A mime type of the model.
*/
get mimeType(): string {
return this._mimetype;
return (this.modelDB.get('mimeType') as IObservableValue).get() as string;
}
set mimeType(newValue: string) {
const oldValue = this._mimetype;
const oldValue = this.mimeType;
if (oldValue === newValue) {
return;
}
this._mimetype = newValue;
this._mimeTypeChanged.emit({
name: 'mimeType',
oldValue,
newValue
});
(this.modelDB.get('mimeType') as IObservableValue).set(newValue);
Copy link
Contributor

@blink1073 blink1073 Apr 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about adding db.setValue('mimeType', foo) and db.getValue('foo') to avoid this verbose pattern?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, that works. It would also be possible to just keep a reference to the IObservableValue and call set on that.

}

/**
Expand All @@ -246,13 +252,10 @@ namespace CodeEditor {
}
this._isDisposed = true;
Signal.clearData(this);
this._selections.dispose();
this._value.dispose();
}

private _value: ObservableString;
private _selections = new ObservableMap<ITextSelection[]>();
private _mimetype: string;

protected modelDB: IModelDB = null;
private _isDisposed = false;
private _mimeTypeChanged = new Signal<this, IChangedArgs<string>>(this);
}
Expand Down Expand Up @@ -567,6 +570,11 @@ namespace CodeEditor {
* The mimetype of the model.
*/
mimeType?: string;

/**
* An optional modelDB for storing model state.
*/
modelDB?: IModelDB;
}
}
}
1 change: 1 addition & 0 deletions packages/coreutils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ export * from './undoablevector';
export * from './url';
export * from './uuid';
export * from './vector';
export * from './modeldb';
Loading