@jupyterlab/rendermime
Version:
JupyterLab - RenderMime
398 lines • 11.9 kB
JavaScript
import { nullTranslator } from '@jupyterlab/translation';
import { Widget } from '@lumino/widgets';
import * as renderers from './renderers';
/**
* A common base class for mime renderers.
*/
export class RenderedCommon extends Widget {
/**
* Construct a new rendered common widget.
*
* @param options - The options for initializing the widget.
*/
constructor(options) {
var _a, _b;
super();
this.mimeType = options.mimeType;
this.sanitizer = options.sanitizer;
this.resolver = options.resolver;
this.linkHandler = options.linkHandler;
this.translator = (_a = options.translator) !== null && _a !== void 0 ? _a : nullTranslator;
this.latexTypesetter = options.latexTypesetter;
this.markdownParser = (_b = options.markdownParser) !== null && _b !== void 0 ? _b : null;
this.node.dataset['mimeType'] = this.mimeType;
}
/**
* Render a mime model.
*
* @param model - The mime model to render.
*
* @param keepExisting - Whether to keep the existing rendering.
*
* @returns A promise which resolves when rendering is complete.
*
* #### Notes
* By default, if the DOM node for this widget already has content, it
* is emptied before rendering. Subclasses that do not want this behavior
* (if, for instance, they are using DOM diffing), should override this
* method or call `super.renderModel(model, true)`.
*/
async renderModel(model, keepExisting) {
// TODO compare model against old model for early bail?
// Empty any existing content in the node from previous renders
if (!keepExisting) {
while (this.node.firstChild) {
this.node.removeChild(this.node.firstChild);
}
}
// Toggle the trusted class on the widget.
this.toggleClass('jp-mod-trusted', model.trusted);
// Render the actual content.
await this.render(model);
// Handle the fragment identifier if given.
const { fragment } = model.metadata;
if (fragment) {
this.setFragment(fragment);
}
}
/**
* Set the URI fragment identifier.
*
* @param fragment - The URI fragment identifier.
*/
setFragment(fragment) {
/* no-op */
}
}
/**
* A common base class for HTML mime renderers.
*/
export class RenderedHTMLCommon extends RenderedCommon {
/**
* Construct a new rendered HTML common widget.
*
* @param options - The options for initializing the widget.
*/
constructor(options) {
super(options);
this.addClass('jp-RenderedHTMLCommon');
}
setFragment(fragment) {
let el;
try {
el = this.node.querySelector(fragment.startsWith('#')
? `#${CSS.escape(fragment.slice(1))}`
: fragment);
}
catch (error) {
console.warn('Unable to set URI fragment identifier.', error);
}
if (el) {
el.scrollIntoView();
}
}
}
/**
* A mime renderer for displaying HTML and math.
*/
export class RenderedHTML extends RenderedHTMLCommon {
/**
* Construct a new rendered HTML widget.
*
* @param options - The options for initializing the widget.
*/
constructor(options) {
super(options);
// A promise which resolves when most recent rendering is complete.
this._rendered = Promise.resolve();
this.addClass('jp-RenderedHTML');
}
/**
* Render a mime model.
*
* @param model - The mime model to render.
*
* @returns A promise which resolves when rendering is complete.
*/
render(model) {
return (this._rendered = renderers.renderHTML({
host: this.node,
source: String(model.data[this.mimeType]),
trusted: model.trusted,
resolver: this.resolver,
sanitizer: this.sanitizer,
linkHandler: this.linkHandler,
shouldTypeset: this.isAttached,
latexTypesetter: this.latexTypesetter,
translator: this.translator
}));
}
/**
* A message handler invoked on an `'after-attach'` message.
*/
onAfterAttach(msg) {
this._rendered
.then(() => {
if (this.latexTypesetter) {
this.latexTypesetter.typeset(this.node);
}
})
.catch(console.warn);
}
}
/**
* A mime renderer for displaying LaTeX output.
*/
export class RenderedLatex extends RenderedCommon {
/**
* Construct a new rendered LaTeX widget.
*
* @param options - The options for initializing the widget.
*/
constructor(options) {
super(options);
// A promise which resolves when most recent rendering is complete.
this._rendered = Promise.resolve();
this.addClass('jp-RenderedLatex');
}
/**
* Render a mime model.
*
* @param model - The mime model to render.
*
* @returns A promise which resolves when rendering is complete.
*/
render(model) {
return (this._rendered = renderers.renderLatex({
host: this.node,
source: String(model.data[this.mimeType]),
shouldTypeset: this.isAttached,
latexTypesetter: this.latexTypesetter
}));
}
/**
* A message handler invoked on an `'after-attach'` message.
*/
onAfterAttach(msg) {
this._rendered
.then(() => {
if (this.latexTypesetter) {
this.latexTypesetter.typeset(this.node);
}
})
.catch(console.warn);
}
}
/**
* A mime renderer for displaying images.
*/
export class RenderedImage extends RenderedCommon {
/**
* Construct a new rendered image widget.
*
* @param options - The options for initializing the widget.
*/
constructor(options) {
super(options);
this.addClass('jp-RenderedImage');
}
/**
* Render a mime model.
*
* @param model - The mime model to render.
*
* @returns A promise which resolves when rendering is complete.
*/
render(model) {
const metadata = model.metadata[this.mimeType];
return renderers.renderImage({
host: this.node,
mimeType: this.mimeType,
source: String(model.data[this.mimeType]),
width: metadata && metadata.width,
height: metadata && metadata.height,
needsBackground: model.metadata['needs_background'],
unconfined: metadata && metadata.unconfined
});
}
}
/**
* A mime renderer for displaying Markdown with embedded latex.
*/
export class RenderedMarkdown extends RenderedHTMLCommon {
/**
* Construct a new rendered markdown widget.
*
* @param options - The options for initializing the widget.
*/
constructor(options) {
super(options);
// A promise which resolves when most recent rendering is complete.
this._rendered = Promise.resolve();
this.addClass('jp-RenderedMarkdown');
}
/**
* Render a mime model.
*
* @param model - The mime model to render.
*
* @returns A promise which resolves when rendering is complete.
*/
render(model) {
return (this._rendered = renderers.renderMarkdown({
host: this.node,
source: String(model.data[this.mimeType]),
trusted: model.trusted,
resolver: this.resolver,
sanitizer: this.sanitizer,
linkHandler: this.linkHandler,
shouldTypeset: this.isAttached,
latexTypesetter: this.latexTypesetter,
markdownParser: this.markdownParser,
translator: this.translator
}));
}
/**
* Render a mime model.
*
* @param model - The mime model to render.
*
* @returns A promise which resolves when rendering is complete.
*/
async renderModel(model) {
await super.renderModel(model, true);
}
/**
* A message handler invoked on an `'after-attach'` message.
*/
onAfterAttach(msg) {
this._rendered
.then(() => {
if (this.latexTypesetter) {
this.latexTypesetter.typeset(this.node);
}
})
.catch(console.warn);
}
}
/**
* A widget for displaying SVG content.
*/
export class RenderedSVG extends RenderedCommon {
/**
* Construct a new rendered SVG widget.
*
* @param options - The options for initializing the widget.
*/
constructor(options) {
super(options);
// A promise which resolves when most recent rendering is complete.
this._rendered = Promise.resolve();
this.addClass('jp-RenderedSVG');
}
/**
* Render a mime model.
*
* @param model - The mime model to render.
*
* @returns A promise which resolves when rendering is complete.
*/
render(model) {
const metadata = model.metadata[this.mimeType];
return (this._rendered = renderers.renderSVG({
host: this.node,
source: String(model.data[this.mimeType]),
trusted: model.trusted,
unconfined: metadata && metadata.unconfined,
translator: this.translator
}));
}
/**
* A message handler invoked on an `'after-attach'` message.
*/
onAfterAttach(msg) {
this._rendered
.then(() => {
if (this.latexTypesetter) {
this.latexTypesetter.typeset(this.node);
}
})
.catch(console.warn);
}
}
/**
* A widget for displaying plain text and console text.
*/
export class RenderedText extends RenderedCommon {
/**
* Construct a new rendered text widget.
*
* @param options - The options for initializing the widget.
*/
constructor(options) {
super(options);
this.addClass('jp-RenderedText');
}
/**
* Render a mime model.
*
* @param model - The mime model to render.
*
* @returns A promise which resolves when rendering is complete.
*/
render(model) {
return renderers.renderText({
host: this.node,
sanitizer: this.sanitizer,
source: String(model.data[this.mimeType]),
translator: this.translator
});
}
}
export class RenderedError extends RenderedCommon {
constructor(options) {
super(options);
this.addClass('jp-RenderedText');
}
render(model) {
return renderers.renderError({
host: this.node,
sanitizer: this.sanitizer,
source: String(model.data[this.mimeType]),
linkHandler: this.linkHandler,
resolver: this.resolver,
translator: this.translator
});
}
}
/**
* A widget for displaying JavaScript output.
*/
export class RenderedJavaScript extends RenderedCommon {
/**
* Construct a new rendered text widget.
*
* @param options - The options for initializing the widget.
*/
constructor(options) {
super(options);
this.addClass('jp-RenderedJavaScript');
}
/**
* Render a mime model.
*
* @param model - The mime model to render.
*
* @returns A promise which resolves when rendering is complete.
*/
render(model) {
const trans = this.translator.load('jupyterlab');
return renderers.renderText({
host: this.node,
sanitizer: this.sanitizer,
source: trans.__('JavaScript output is disabled in JupyterLab'),
translator: this.translator
});
}
}
//# sourceMappingURL=widgets.js.map