From bbf6cbd8fb81336718e15d7ea3253fddac36cba1 Mon Sep 17 00:00:00 2001 From: Raj <44002319+rajmusuku@users.noreply.github.com> Date: Thu, 8 Nov 2018 14:12:59 -0800 Subject: [PATCH] Hookup trusted flag to both code cell and markdown preview (#3166) * 1133: Notebook file registration changes * File registration stuff * Yarn files * Outputview Changes * Misc changes * Changes to code component name space * Output view changes * notebook output view changes * Latest changes * Output view changes * Code review changes on output view * CSS file and misc changes * Hookup trusted mode to code cell and markdown * Return default sanitizer * Misc changes - code review comments --- .../notebook/cellViews/output.component.ts | 70 +++++++++---------- .../cellViews/outputArea.component.html | 2 +- .../notebook/cellViews/textCell.component.ts | 23 +++++- 3 files changed, 57 insertions(+), 38 deletions(-) diff --git a/src/sql/parts/notebook/cellViews/output.component.ts b/src/sql/parts/notebook/cellViews/output.component.ts index c3f8e9d4fe..b57a58e9d9 100644 --- a/src/sql/parts/notebook/cellViews/output.component.ts +++ b/src/sql/parts/notebook/cellViews/output.component.ts @@ -17,61 +17,61 @@ export const OUTPUT_SELECTOR: string = 'output-component'; @Component({ selector: OUTPUT_SELECTOR, - templateUrl: decodeURI(require.toUrl('./output.component.html')) + templateUrl: decodeURI(require.toUrl('./output.component.html')) }) export class OutputComponent extends AngularDisposable implements OnInit { @ViewChild('output', { read: ElementRef }) private outputElement: ElementRef; - @Input() cellOutput: nb.ICellOutput; + @Input() cellOutput: nb.ICellOutput; + @Input() trustedMode: boolean; private readonly _minimumHeight = 30; registry: RenderMimeRegistry; - trusted: boolean = false; constructor( @Inject(INotebookService) private _notebookService: INotebookService ) { super(); - this.registry = _notebookService.getMimeRegistry(); + this.registry = _notebookService.getMimeRegistry(); } ngOnInit() { let node = this.outputElement.nativeElement; - let output = this.cellOutput; - let options = outputProcessor.getBundleOptions({ value: output, trusted: this.trusted }); - // TODO handle safe/unsafe mapping - this.createRenderedMimetype(options, node); - } + let output = this.cellOutput; + let options = outputProcessor.getBundleOptions({ value: output, trusted: this.trustedMode }); + // TODO handle safe/unsafe mapping + this.createRenderedMimetype(options, node); + } public layout(): void { } protected createRenderedMimetype(options: MimeModel.IOptions, node: HTMLElement): void { - let mimeType = this.registry.preferredMimeType( - options.data, - options.trusted ? 'any' : 'ensure' - ); - if (mimeType) { + let mimeType = this.registry.preferredMimeType( + options.data, + options.trusted ? 'any' : 'ensure' + ); + if (mimeType) { let output = this.registry.createRenderer(mimeType); - output.node = node; - let model = new MimeModel(options); - output.renderModel(model).catch(error => { - // Manually append error message to output - output.node.innerHTML = `
Javascript Error: ${error.message}
`; - // Remove mime-type-specific CSS classes - output.node.className = 'p-Widget jp-RenderedText'; - output.node.setAttribute( - 'data-mime-type', - 'application/vnd.jupyter.stderr' - ); - }); + output.node = node; + let model = new MimeModel(options); + output.renderModel(model).catch(error => { + // Manually append error message to output + output.node.innerHTML = `
Javascript Error: ${error.message}
`; + // Remove mime-type-specific CSS classes + output.node.className = 'p-Widget jp-RenderedText'; + output.node.setAttribute( + 'data-mime-type', + 'application/vnd.jupyter.stderr' + ); + }); //this.setState({ node: node }); - } else { - // TODO Localize - node.innerHTML = - `No ${options.trusted ? '' : '(safe) '}renderer could be ` + - 'found for output. It has the following MIME types: ' + - Object.keys(options.data).join(', '); - //this.setState({ node: node }); - } - } + } else { + // TODO Localize + node.innerHTML = + `No ${options.trusted ? '' : '(safe) '}renderer could be ` + + 'found for output. It has the following MIME types: ' + + Object.keys(options.data).join(', '); + //this.setState({ node: node }); + } + } } diff --git a/src/sql/parts/notebook/cellViews/outputArea.component.html b/src/sql/parts/notebook/cellViews/outputArea.component.html index 15c0fe1f71..02f6d576b5 100644 --- a/src/sql/parts/notebook/cellViews/outputArea.component.html +++ b/src/sql/parts/notebook/cellViews/outputArea.component.html @@ -6,7 +6,7 @@ -->
- +
\ No newline at end of file diff --git a/src/sql/parts/notebook/cellViews/textCell.component.ts b/src/sql/parts/notebook/cellViews/textCell.component.ts index 829ec38fc3..b436bf1f81 100644 --- a/src/sql/parts/notebook/cellViews/textCell.component.ts +++ b/src/sql/parts/notebook/cellViews/textCell.component.ts @@ -13,6 +13,7 @@ import { IColorTheme, IWorkbenchThemeService } from 'vs/workbench/services/theme import * as themeColors from 'vs/workbench/common/theme'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { ICellModel } from 'sql/parts/notebook/models/modelInterfaces'; +import { ISanitizer, defaultSanitizer } from 'sql/parts/notebook/outputs/sanitizer'; export const TEXT_SELECTOR: string = 'text-cell-component'; @@ -25,6 +26,8 @@ export class TextCellComponent extends CellView implements OnInit { @Input() cellModel: ICellModel; private _content: string; private isEditMode: boolean; + private _sanitizer: ISanitizer; + constructor( @Inject(forwardRef(() => CommonServiceInterface)) private _bootstrapService: CommonServiceInterface, @Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef, @@ -39,9 +42,17 @@ export class TextCellComponent extends CellView implements OnInit { this.updatePreview(); } + //Gets sanitizer from ISanitizer interface + private get sanitizer(): ISanitizer { + if (this._sanitizer) { + return this._sanitizer; + } + return this._sanitizer = defaultSanitizer; + } + private updatePreview() { - if (this._content !== this.cellModel.source) { - this._content = this.cellModel.source; + if (this.cellModel.source && this._content !== this.cellModel.source) { + this._content = this.sanitizeContent(this.cellModel.source); // todo: pass in the notebook filename instead of undefined value this._commandService.executeCommand('notebook.showPreview', undefined, this._content).then((htmlcontent) => { let outputElement = this.output.nativeElement; @@ -50,6 +61,14 @@ export class TextCellComponent extends CellView implements OnInit { } } + //Sanitizes the content based on trusted mode of Cell Model + private sanitizeContent(content: string): string { + if (this.cellModel && !this.cellModel.trustedMode) { + content = this.sanitizer.sanitize(content); + } + return content; + } + ngOnInit() { this._register(this.themeService.onDidColorThemeChange(this.updateTheme, this)); this.updateTheme(this.themeService.getColorTheme());