Skip to content

Commit

Permalink
Add trust button next to cell output
Browse files Browse the repository at this point in the history
  • Loading branch information
trungleduc committed Feb 18, 2022
1 parent ec014bb commit 5ca73e5
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 31 deletions.
32 changes: 30 additions & 2 deletions packages/cells/src/model.ts
Expand Up @@ -118,6 +118,10 @@ export interface ICodeCellModel extends ICellModel {
* Clear execution, outputs, and related metadata
*/
clearExecution(): void;

readonly displayModelRequested: ISignal<ICodeCellModel, void>

needTrustButton: boolean;
}

/**
Expand Down Expand Up @@ -693,11 +697,25 @@ export class CodeCellModel extends CellModel implements ICodeCellModel {
): void {
if (reinitialize) {
this.clearExecution();
sharedModel.getOutputs().forEach(output => this._outputs.add(output));
console.log('switchSharedModel', sharedModel.getOutputs());

sharedModel.getOutputs().forEach(output => {
if(output.output_type === 'display_data'){
this._needTrustButton = true
}
this._outputs.add(output)
});
}
super.switchSharedModel(sharedModel, reinitialize);
}

get needTrustButton(): boolean {
return this._needTrustButton
}

get displayModelRequested(): ISignal<ICodeCellModel, void>{
return this._displayModelRequested
}
/**
* The type of the cell.
*/
Expand Down Expand Up @@ -867,7 +885,15 @@ export class CodeCellModel extends CellModel implements ICodeCellModel {
globalModelDBMutex(() => {
if (change.outputsChange) {
this.clearExecution();
sender.getOutputs().forEach(output => this._outputs.add(output));
sender.getOutputs().forEach(output => {
if (
output.output_type === 'display_data'
){
console.log('_onSharedModelChanged');
this._displayModelRequested.emit()
}
this._outputs.add(output)
});
}

if (change.executionCountChange) {
Expand Down Expand Up @@ -905,6 +931,8 @@ export class CodeCellModel extends CellModel implements ICodeCellModel {
private _executedCode: string = '';
private _isDirty = false;
private _outputs: IOutputAreaModel;
private _displayModelRequested = new Signal<this, void>(this)
private _needTrustButton = false;
}

/**
Expand Down
82 changes: 55 additions & 27 deletions packages/cells/src/widget.ts
Expand Up @@ -5,20 +5,13 @@

import { marked } from 'marked';

import { AttachmentsResolver } from '@jupyterlab/attachments';

import { ISessionContext } from '@jupyterlab/apputils';

import { ActivityMonitor, IChangedArgs, URLExt } from '@jupyterlab/coreutils';

import { AttachmentsResolver } from '@jupyterlab/attachments';
import { CodeEditor, CodeEditorWrapper } from '@jupyterlab/codeeditor';

import { ActivityMonitor, IChangedArgs, URLExt } from '@jupyterlab/coreutils';
import { DirListing } from '@jupyterlab/filebrowser';

import * as nbformat from '@jupyterlab/nbformat';

import { IObservableJSON, IObservableMap } from '@jupyterlab/observables';

import {
IOutputPrompt,
IStdin,
Expand All @@ -27,60 +20,51 @@ import {
SimplifiedOutputArea,
Stdin
} from '@jupyterlab/outputarea';

import {
imageRendererFactory,
IRenderMime,
IRenderMimeRegistry,
MimeModel
} from '@jupyterlab/rendermime';

import { Kernel, KernelMessage } from '@jupyterlab/services';

import { ITranslator, nullTranslator } from '@jupyterlab/translation';

import {
addIcon,
notTrustedIcon,
ToolbarButton,
trustedIcon
} from '@jupyterlab/ui-components';
import { filter, some, toArray } from '@lumino/algorithm';
import {
JSONObject,
JSONValue,
PartialJSONValue,
PromiseDelegate,
UUID
} from '@lumino/coreutils';

import { filter, some, toArray } from '@lumino/algorithm';

import { IDragEvent } from '@lumino/dragdrop';

import { Message } from '@lumino/messaging';

import { Signal } from '@lumino/signaling';
import { Panel, PanelLayout, Widget } from '@lumino/widgets';

import { InputCollapser, OutputCollapser } from './collapser';

import {
CellFooter,
CellHeader,
ICellFooter,
ICellHeader
} from './headerfooter';

import { IInputPrompt, InputArea, InputPrompt } from './inputarea';

import {
IAttachmentsCellModel,
ICellModel,
ICodeCellModel,
IMarkdownCellModel,
IRawCellModel
} from './model';

import { InputPlaceholder, OutputPlaceholder } from './placeholder';

import { ResizeHandle } from './resizeHandle';

import { Signal } from '@lumino/signaling';
import { addIcon } from '@jupyterlab/ui-components';

/**
* The CSS class added to cell widgets.
*/
Expand Down Expand Up @@ -760,6 +744,7 @@ export class CodeCell extends Cell<ICodeCellModel> {
ariaLabel = trans.__('Code Cell Content');
}
output.outputLengthChanged.connect(this._outputLengthHandler, this);

outputWrapper.addWidget(outputCollapser);
outputWrapper.addWidget(output);
(this.layout as PanelLayout).insertWidget(2, new ResizeHandle(this.node));
Expand All @@ -774,6 +759,10 @@ export class CodeCell extends Cell<ICodeCellModel> {
});
}
model.stateChanged.connect(this.onStateChanged, this);
model.displayModelRequested.connect(this.addTrustButton, this);
if (model.needTrustButton) {
this.addTrustButton();
}
this.node.setAttribute('aria-label', ariaLabel);
}

Expand Down Expand Up @@ -1019,6 +1008,27 @@ export class CodeCell extends Cell<ICodeCellModel> {
}
}

addTrustButton(): void {
console.log('model');
if (!this._trustButton && !this.model.trusted) {
const onClick = () => {
this.model.trusted = !this.model.trusted;
};
this._trustButton = new ToolbarButton({
onClick,
icon: this.model.trusted ? trustedIcon : notTrustedIcon
}); //new Widget({ node });

this._trustButton.addClass('jp-Cell-trustButton');
this._outputWrapper.addWidget(this._trustButton);
}
// else if(args === 0 && this._trustButton){
// this._outputWrapper.layout?.removeWidget(this._trustButton)
// this._trustButton = undefined

// }
}

/**
* Handle changes in the metadata.
*/
Expand Down Expand Up @@ -1051,6 +1061,23 @@ export class CodeCell extends Cell<ICodeCellModel> {
* Handle changes in the number of outputs in the output area.
*/
private _outputLengthHandler(sender: OutputArea, args: number) {
console.log('outpuit leng change', args, this._trustButton);
// if (args > 0 && !this._trustButton && !this.model.trusted) {
// const node = document.createElement('button');
// node.style.position = 'absolute';
// node.style.left = '35px';
// node.style.top = '6px';
// node.innerText = 'trust';
// node.onclick = () => {this.model.trusted = true}
// this._trustButton = new Widget({ node });
// this._outputWrapper.addWidget(this._trustButton);
// } else
if (args === 0 && this._trustButton) {
if (this._outputWrapper.layout) {
this._outputWrapper.layout.removeWidget(this._trustButton);
}
this._trustButton = undefined;
}
const force = args === 0 ? true : false;
this.toggleClass(NO_OUTPUTS_CLASS, force);
const trans = this.translator.load('jupyterlab');
Expand All @@ -1063,11 +1090,12 @@ export class CodeCell extends Cell<ICodeCellModel> {
private _rendermime: IRenderMimeRegistry;
private _outputHidden = false;
private _outputsScrolled: boolean;
private _outputWrapper: Widget;
private _outputWrapper: Panel;
private _outputPlaceholder: OutputPlaceholder;
private _output: OutputArea;
private _syncScrolled = false;
private _savingMetadata = false;
private _trustButton?: Widget;
}

/**
Expand Down
16 changes: 16 additions & 0 deletions packages/cells/style/widget.css
Expand Up @@ -23,6 +23,22 @@
background: transparent;
}

.jp-Cell-trustButton {
position: absolute;
left: calc(
0.5 * var(--jp-cell-collapser-width) + 0.5 * var(--jp-cell-prompt-width)
);
top: calc(50% - 7px);
}

.jp-Cell-trustButton > button {
height: 14px;
}
.jp-Cell-trustButton > button svg {
width: 14px;
height: 14px;
}

/*-----------------------------------------------------------------------------
| Common input/output
|----------------------------------------------------------------------------*/
Expand Down
4 changes: 2 additions & 2 deletions packages/outputarea/src/model.ts
Expand Up @@ -296,7 +296,7 @@ export class OutputAreaModel implements IOutputAreaModel {
/**
* Add a copy of the item to the list.
*/
private _add(value: nbformat.IOutput): number {
private _add(value: nbformat.IOutput): number {
const trusted = this._trusted;
value = JSONExt.deepCopy(value);

Expand Down Expand Up @@ -387,7 +387,7 @@ export class OutputAreaModel implements IOutputAreaModel {
private _onListChanged(
sender: IObservableList<IOutputModel>,
args: IObservableList.IChangedArgs<IOutputModel>
) {
) {
this._changed.emit(args);
}

Expand Down

0 comments on commit 5ca73e5

Please sign in to comment.