diff --git a/packages/cells/src/model.ts b/packages/cells/src/model.ts index 70ee4fb8dd46..148085591910 100644 --- a/packages/cells/src/model.ts +++ b/packages/cells/src/model.ts @@ -469,11 +469,7 @@ export class CodeCellModel extends CellModel implements ICodeCellModel { } executionCount.changed.connect(this._onExecutionCountChanged, this); - this._outputs = factory.createOutputArea({ - trusted, - values: outputs, - modelDB: this.modelDB - }); + this._outputs = factory.createOutputArea({ trusted, values: outputs }); this._outputs.changed.connect(this.onGenericChange, this); // We keep `collapsed` and `jupyter.outputs_hidden` metadata in sync, since diff --git a/packages/outputarea/src/model.ts b/packages/outputarea/src/model.ts index 3bb4518e8de0..cd2d8c4fb853 100644 --- a/packages/outputarea/src/model.ts +++ b/packages/outputarea/src/model.ts @@ -9,13 +9,7 @@ import { ISignal, Signal } from '@phosphor/signaling'; import { nbformat } from '@jupyterlab/coreutils'; -import { - IObservableList, - ObservableList, - IObservableValue, - ObservableValue, - IModelDB -} from '@jupyterlab/observables'; +import { IObservableList, ObservableList } from '@jupyterlab/observables'; import { IOutputModel, OutputModel } from '@jupyterlab/rendermime'; @@ -112,11 +106,6 @@ export namespace IOutputAreaModel { * If not given, a default factory will be used. */ contentFactory?: IContentFactory; - - /** - * An optional IModelDB to store the output area model. - */ - modelDB?: IModelDB; } /** @@ -153,19 +142,6 @@ export class OutputAreaModel implements IOutputAreaModel { }); } this.list.changed.connect(this._onListChanged, this); - - // If we are given a IModelDB, keep an up-to-date - // serialized copy of the OutputAreaModel in it. - if (options.modelDB) { - this._modelDB = options.modelDB; - this._serialized = this._modelDB.createValue('outputs'); - if (this._serialized.get()) { - this.fromJSON(this._serialized.get() as nbformat.IOutput[]); - } else { - this._serialized.set(this.toJSON()); - } - this._serialized.changed.connect(this._onSerializedChanged, this); - } } /** @@ -252,7 +228,7 @@ export class OutputAreaModel implements IOutputAreaModel { */ set(index: number, value: nbformat.IOutput): void { // Normalize stream data. - this._normalize(value); + Private.normalize(value); let item = this._createItem({ value, trusted: this._trusted }); this.list.set(index, item); } @@ -318,7 +294,7 @@ export class OutputAreaModel implements IOutputAreaModel { let trusted = this._trusted; // Normalize the value. - this._normalize(value); + Private.normalize(value); // Consolidate outputs if they are stream outputs of the same kind. if ( @@ -330,8 +306,8 @@ export class OutputAreaModel implements IOutputAreaModel { // text to the current item and replace the previous item. // This also replaces the metadata of the last item. this._lastStream += value.text as string; + this._lastStream = Private.removeOverwrittenChars(this._lastStream); value.text = this._lastStream; - this._removeOverwrittenChars(value); let item = this._createItem({ value, trusted }); let index = this.length - 1; let prev = this.list.get(index); @@ -341,7 +317,7 @@ export class OutputAreaModel implements IOutputAreaModel { } if (nbformat.isStream(value)) { - this._removeOverwrittenChars(value); + value.text = Private.removeOverwrittenChars(value.text as string); } // Create the new item. @@ -360,53 +336,15 @@ export class OutputAreaModel implements IOutputAreaModel { } /** - * Normalize an output. - */ - private _normalize(value: nbformat.IOutput): void { - if (nbformat.isStream(value)) { - if (Array.isArray(value.text)) { - value.text = (value.text as string[]).join('\n'); - } - } - } - - /** - * Remove characters that are overridden by backspace characters. + * A flag that is set when we want to clear the output area + * *after* the next addition to it. */ - private _fixBackspace(txt: string): string { - let tmp = txt; - do { - txt = tmp; - // Cancel out anything-but-newline followed by backspace - tmp = txt.replace(/[^\n]\x08/gm, ''); - } while (tmp.length < txt.length); - return txt; - } + protected clearNext = false; /** - * Remove chunks that should be overridden by the effect of - * carriage return characters. - */ - private _fixCarriageReturn(txt: string): string { - txt = txt.replace(/\r+\n/gm, '\n'); // \r followed by \n --> newline - while (txt.search(/\r[^$]/g) > -1) { - const base = txt.match(/^(.*)\r+/m)[1]; - let insert = txt.match(/\r+(.*)$/m)[1]; - insert = insert + base.slice(insert.length, base.length); - txt = txt.replace(/\r+.*$/m, '\r').replace(/^.*\r/m, insert); - } - return txt; - } - - /* - * Remove characters overridden by backspaces and carriage returns + * An observable list containing the output models + * for this output area. */ - private _removeOverwrittenChars(value: nbformat.IOutput): void { - let tmp = value.text as string; - value.text = this._fixCarriageReturn(this._fixBackspace(tmp)); - } - - protected clearNext = false; protected list: IObservableList = null; /** @@ -426,29 +364,9 @@ export class OutputAreaModel implements IOutputAreaModel { sender: IObservableList, args: IObservableList.IChangedArgs ) { - if (this._serialized && !this._changeGuard) { - this._changeGuard = true; - this._serialized.set(this.toJSON()); - this._changeGuard = false; - } this._changed.emit(args); } - /** - * If the serialized version of the outputs have changed due to a remote - * action, then update the model accordingly. - */ - private _onSerializedChanged( - sender: IObservableValue, - args: ObservableValue.IChangedArgs - ) { - if (!this._changeGuard) { - this._changeGuard = true; - this.fromJSON(args.newValue as nbformat.IOutput[]); - this._changeGuard = false; - } - } - /** * Handle a change to an item. */ @@ -462,9 +380,6 @@ export class OutputAreaModel implements IOutputAreaModel { private _isDisposed = false; private _stateChanged = new Signal(this); private _changed = new Signal(this); - private _modelDB: IModelDB = null; - private _serialized: IObservableValue = null; - private _changeGuard = false; } /** @@ -488,3 +403,54 @@ export namespace OutputAreaModel { */ export const defaultContentFactory = new ContentFactory(); } + +/** + * A namespace for module-private functionality. + */ +namespace Private { + /** + * Normalize an output. + */ + export function normalize(value: nbformat.IOutput): void { + if (nbformat.isStream(value)) { + if (Array.isArray(value.text)) { + value.text = (value.text as string[]).join('\n'); + } + } + } + + /** + * Remove characters that are overridden by backspace characters. + */ + function fixBackspace(txt: string): string { + let tmp = txt; + do { + txt = tmp; + // Cancel out anything-but-newline followed by backspace + tmp = txt.replace(/[^\n]\x08/gm, ''); + } while (tmp.length < txt.length); + return txt; + } + + /** + * Remove chunks that should be overridden by the effect of + * carriage return characters. + */ + function fixCarriageReturn(txt: string): string { + txt = txt.replace(/\r+\n/gm, '\n'); // \r followed by \n --> newline + while (txt.search(/\r[^$]/g) > -1) { + const base = txt.match(/^(.*)\r+/m)[1]; + let insert = txt.match(/\r+(.*)$/m)[1]; + insert = insert + base.slice(insert.length, base.length); + txt = txt.replace(/\r+.*$/m, '\r').replace(/^.*\r/m, insert); + } + return txt; + } + + /* + * Remove characters overridden by backspaces and carriage returns + */ + export function removeOverwrittenChars(text: string): string { + return fixCarriageReturn(fixBackspace(text)); + } +}