mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
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
This commit is contained in:
@@ -17,61 +17,61 @@ export const OUTPUT_SELECTOR: string = 'output-component';
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: OUTPUT_SELECTOR,
|
selector: OUTPUT_SELECTOR,
|
||||||
templateUrl: decodeURI(require.toUrl('./output.component.html'))
|
templateUrl: decodeURI(require.toUrl('./output.component.html'))
|
||||||
})
|
})
|
||||||
export class OutputComponent extends AngularDisposable implements OnInit {
|
export class OutputComponent extends AngularDisposable implements OnInit {
|
||||||
@ViewChild('output', { read: ElementRef }) private outputElement: ElementRef;
|
@ViewChild('output', { read: ElementRef }) private outputElement: ElementRef;
|
||||||
@Input() cellOutput: nb.ICellOutput;
|
@Input() cellOutput: nb.ICellOutput;
|
||||||
|
@Input() trustedMode: boolean;
|
||||||
private readonly _minimumHeight = 30;
|
private readonly _minimumHeight = 30;
|
||||||
registry: RenderMimeRegistry;
|
registry: RenderMimeRegistry;
|
||||||
trusted: boolean = false;
|
|
||||||
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(INotebookService) private _notebookService: INotebookService
|
@Inject(INotebookService) private _notebookService: INotebookService
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this.registry = _notebookService.getMimeRegistry();
|
this.registry = _notebookService.getMimeRegistry();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
let node = this.outputElement.nativeElement;
|
let node = this.outputElement.nativeElement;
|
||||||
let output = this.cellOutput;
|
let output = this.cellOutput;
|
||||||
let options = outputProcessor.getBundleOptions({ value: output, trusted: this.trusted });
|
let options = outputProcessor.getBundleOptions({ value: output, trusted: this.trustedMode });
|
||||||
// TODO handle safe/unsafe mapping
|
// TODO handle safe/unsafe mapping
|
||||||
this.createRenderedMimetype(options, node);
|
this.createRenderedMimetype(options, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
public layout(): void {
|
public layout(): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected createRenderedMimetype(options: MimeModel.IOptions, node: HTMLElement): void {
|
protected createRenderedMimetype(options: MimeModel.IOptions, node: HTMLElement): void {
|
||||||
let mimeType = this.registry.preferredMimeType(
|
let mimeType = this.registry.preferredMimeType(
|
||||||
options.data,
|
options.data,
|
||||||
options.trusted ? 'any' : 'ensure'
|
options.trusted ? 'any' : 'ensure'
|
||||||
);
|
);
|
||||||
if (mimeType) {
|
if (mimeType) {
|
||||||
let output = this.registry.createRenderer(mimeType);
|
let output = this.registry.createRenderer(mimeType);
|
||||||
output.node = node;
|
output.node = node;
|
||||||
let model = new MimeModel(options);
|
let model = new MimeModel(options);
|
||||||
output.renderModel(model).catch(error => {
|
output.renderModel(model).catch(error => {
|
||||||
// Manually append error message to output
|
// Manually append error message to output
|
||||||
output.node.innerHTML = `<pre>Javascript Error: ${error.message}</pre>`;
|
output.node.innerHTML = `<pre>Javascript Error: ${error.message}</pre>`;
|
||||||
// Remove mime-type-specific CSS classes
|
// Remove mime-type-specific CSS classes
|
||||||
output.node.className = 'p-Widget jp-RenderedText';
|
output.node.className = 'p-Widget jp-RenderedText';
|
||||||
output.node.setAttribute(
|
output.node.setAttribute(
|
||||||
'data-mime-type',
|
'data-mime-type',
|
||||||
'application/vnd.jupyter.stderr'
|
'application/vnd.jupyter.stderr'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
//this.setState({ node: node });
|
//this.setState({ node: node });
|
||||||
} else {
|
} else {
|
||||||
// TODO Localize
|
// TODO Localize
|
||||||
node.innerHTML =
|
node.innerHTML =
|
||||||
`No ${options.trusted ? '' : '(safe) '}renderer could be ` +
|
`No ${options.trusted ? '' : '(safe) '}renderer could be ` +
|
||||||
'found for output. It has the following MIME types: ' +
|
'found for output. It has the following MIME types: ' +
|
||||||
Object.keys(options.data).join(', ');
|
Object.keys(options.data).join(', ');
|
||||||
//this.setState({ node: node });
|
//this.setState({ node: node });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
-->
|
-->
|
||||||
<div style="overflow: hidden; width: 100%; height: 100%; display: flex; flex-flow: column">
|
<div style="overflow: hidden; width: 100%; height: 100%; display: flex; flex-flow: column">
|
||||||
<div class="notebook-output" style="flex: 0 0 auto;">
|
<div class="notebook-output" style="flex: 0 0 auto;">
|
||||||
<output-component *ngFor="let output of cellModel.outputs" [cellOutput]="output">
|
<output-component *ngFor="let output of cellModel.outputs" [cellOutput]="output" [trustedMode] = "cellModel.trustedMode" >
|
||||||
</output-component>
|
</output-component>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -13,6 +13,7 @@ import { IColorTheme, IWorkbenchThemeService } from 'vs/workbench/services/theme
|
|||||||
import * as themeColors from 'vs/workbench/common/theme';
|
import * as themeColors from 'vs/workbench/common/theme';
|
||||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||||
import { ICellModel } from 'sql/parts/notebook/models/modelInterfaces';
|
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';
|
export const TEXT_SELECTOR: string = 'text-cell-component';
|
||||||
|
|
||||||
@@ -25,6 +26,8 @@ export class TextCellComponent extends CellView implements OnInit {
|
|||||||
@Input() cellModel: ICellModel;
|
@Input() cellModel: ICellModel;
|
||||||
private _content: string;
|
private _content: string;
|
||||||
private isEditMode: boolean;
|
private isEditMode: boolean;
|
||||||
|
private _sanitizer: ISanitizer;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => CommonServiceInterface)) private _bootstrapService: CommonServiceInterface,
|
@Inject(forwardRef(() => CommonServiceInterface)) private _bootstrapService: CommonServiceInterface,
|
||||||
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
|
@Inject(forwardRef(() => ChangeDetectorRef)) private _changeRef: ChangeDetectorRef,
|
||||||
@@ -39,9 +42,17 @@ export class TextCellComponent extends CellView implements OnInit {
|
|||||||
this.updatePreview();
|
this.updatePreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Gets sanitizer from ISanitizer interface
|
||||||
|
private get sanitizer(): ISanitizer {
|
||||||
|
if (this._sanitizer) {
|
||||||
|
return this._sanitizer;
|
||||||
|
}
|
||||||
|
return this._sanitizer = defaultSanitizer;
|
||||||
|
}
|
||||||
|
|
||||||
private updatePreview() {
|
private updatePreview() {
|
||||||
if (this._content !== this.cellModel.source) {
|
if (this.cellModel.source && this._content !== 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
|
// todo: pass in the notebook filename instead of undefined value
|
||||||
this._commandService.executeCommand<string>('notebook.showPreview', undefined, this._content).then((htmlcontent) => {
|
this._commandService.executeCommand<string>('notebook.showPreview', undefined, this._content).then((htmlcontent) => {
|
||||||
let outputElement = <HTMLElement>this.output.nativeElement;
|
let outputElement = <HTMLElement>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() {
|
ngOnInit() {
|
||||||
this._register(this.themeService.onDidColorThemeChange(this.updateTheme, this));
|
this._register(this.themeService.onDidColorThemeChange(this.updateTheme, this));
|
||||||
this.updateTheme(this.themeService.getColorTheme());
|
this.updateTheme(this.themeService.getColorTheme());
|
||||||
|
|||||||
Reference in New Issue
Block a user