Skip to content

Commit

Permalink
Render an empty widget if we don’t have a renderer for the mimebundle…
Browse files Browse the repository at this point in the history
… types.

Fixes jupyterlab#6216

This does render a div for outputs corresponding to things we can’t render, since we need the list of widgets to correspond to the output messages.
  • Loading branch information
jasongrout committed Jun 12, 2019
1 parent 2e9885a commit 55e6979
Showing 1 changed file with 48 additions and 43 deletions.
91 changes: 48 additions & 43 deletions packages/outputarea/src/widget.ts
Expand Up @@ -343,77 +343,80 @@ export class OutputArea extends Widget {
*/
private _insertOutput(index: number, model: IOutputModel): void {
let output = this.createOutputItem(model);
output.toggleClass(EXECUTE_CLASS, model.executionCount !== null);
if (output) {
output.toggleClass(EXECUTE_CLASS, model.executionCount !== null);
} else {
output = new Widget();
}
let layout = this.layout as PanelLayout;
layout.insertWidget(index, output);
}

/**
* Create an output item with a prompt and actual output
*/
protected createOutputItem(model: IOutputModel): Widget {
protected createOutputItem(model: IOutputModel): Widget | null {
let output = this.createRenderedMimetype(model);

if (!output) {
return null;
}

let panel = new Panel();

panel.addClass(OUTPUT_AREA_ITEM_CLASS);

let prompt = this.contentFactory.createOutputPrompt();
prompt.executionCount = model.executionCount;
prompt.addClass(OUTPUT_AREA_PROMPT_CLASS);
panel.addWidget(prompt);

let output = this.createRenderedMimetype(model);
output.addClass(OUTPUT_AREA_OUTPUT_CLASS);
panel.addWidget(output);

return panel;
}

/**
* Render a mimetype
*/
protected createRenderedMimetype(model: IOutputModel): Widget {
let widget: Widget;
protected createRenderedMimetype(model: IOutputModel): Widget | null {
let mimeType = this.rendermime.preferredMimeType(
model.data,
model.trusted ? 'any' : 'ensure'
);
if (mimeType) {
let metadata = model.metadata;
let mimeMd = metadata[mimeType] as ReadonlyJSONObject;
let isolated = false;
// mime-specific higher priority
if (mimeMd && mimeMd['isolated'] !== undefined) {
isolated = mimeMd['isolated'] as boolean;
} else {
// fallback on global
isolated = metadata['isolated'] as boolean;
}

let output = this.rendermime.createRenderer(mimeType);
if (isolated === true) {
output = new Private.IsolatedRenderer(output);
}
output.renderModel(model).catch(error => {
// Manually append error message to output
const pre = document.createElement('pre');
pre.textContent = `Javascript Error: ${error.message}`;
output.node.appendChild(pre);

// Remove mime-type-specific CSS classes
output.node.className = 'p-Widget jp-RenderedText';
output.node.setAttribute(
'data-mime-type',
'application/vnd.jupyter.stderr'
);
});
widget = output;
if (!mimeType) {
return null;
}
let metadata = model.metadata;
let mimeMd = metadata[mimeType] as ReadonlyJSONObject;
let isolated = false;
// mime-specific higher priority
if (mimeMd && mimeMd['isolated'] !== undefined) {
isolated = mimeMd['isolated'] as boolean;
} else {
widget = new Widget();
widget.node.innerHTML =
`No ${model.trusted ? '' : '(safe) '}renderer could be ` +
'found for output. It has the following MIME types: ' +
Object.keys(model.data).join(', ');
// fallback on global
isolated = metadata['isolated'] as boolean;
}

let output = this.rendermime.createRenderer(mimeType);
if (isolated === true) {
output = new Private.IsolatedRenderer(output);
}
return widget;
output.renderModel(model).catch(error => {
// Manually append error message to output
const pre = document.createElement('pre');
pre.textContent = `Javascript Error: ${error.message}`;
output.node.appendChild(pre);

// Remove mime-type-specific CSS classes
output.node.className = 'p-Widget jp-RenderedText';
output.node.setAttribute(
'data-mime-type',
'application/vnd.jupyter.stderr'
);
});
return output;
}

/**
Expand Down Expand Up @@ -511,9 +514,11 @@ export class SimplifiedOutputArea extends OutputArea {
/**
* Create an output item without a prompt, just the output widgets
*/
protected createOutputItem(model: IOutputModel): Widget {
protected createOutputItem(model: IOutputModel): Widget | null {
let output = this.createRenderedMimetype(model);
output.addClass(OUTPUT_AREA_OUTPUT_CLASS);
if (output) {
output.addClass(OUTPUT_AREA_OUTPUT_CLASS);
}
return output;
}
}
Expand Down

0 comments on commit 55e6979

Please sign in to comment.