widgets.ts 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. /*-----------------------------------------------------------------------------
  2. | Copyright (c) Jupyter Development Team.
  3. | Distributed under the terms of the Modified BSD License.
  4. |----------------------------------------------------------------------------*/
  5. import {
  6. IRenderMime
  7. } from '@jupyterlab/rendermime-interfaces';
  8. import {
  9. ReadonlyJSONObject
  10. } from '@phosphor/coreutils';
  11. import {
  12. Message
  13. } from '@phosphor/messaging';
  14. import {
  15. Widget
  16. } from '@phosphor/widgets';
  17. import {
  18. typeset
  19. } from './latex';
  20. import * as renderers
  21. from './renderers';
  22. /**
  23. * A common base class for mime renderers.
  24. */
  25. export
  26. abstract class RenderedCommon extends Widget implements IRenderMime.IRenderer {
  27. /**
  28. * Construct a new rendered common widget.
  29. *
  30. * @param options - The options for initializing the widget.
  31. */
  32. constructor(options: IRenderMime.IRendererOptions) {
  33. super();
  34. this.mimeType = options.mimeType;
  35. this.sanitizer = options.sanitizer;
  36. this.resolver = options.resolver;
  37. this.linkHandler = options.linkHandler;
  38. this.node.dataset['mimeType'] = this.mimeType;
  39. }
  40. /**
  41. * The mimetype being rendered.
  42. */
  43. readonly mimeType: string;
  44. /**
  45. * The sanitizer used to sanitize untrusted html inputs.
  46. */
  47. readonly sanitizer: IRenderMime.ISanitizer;
  48. /**
  49. * The resolver object.
  50. */
  51. readonly resolver: IRenderMime.IResolver | null;
  52. /**
  53. * The link handler.
  54. */
  55. readonly linkHandler: IRenderMime.ILinkHandler | null;
  56. /**
  57. * Render a mime model.
  58. *
  59. * @param model - The mime model to render.
  60. *
  61. * @returns A promise which resolves when rendering is complete.
  62. */
  63. renderModel(model: IRenderMime.IMimeModel): Promise<void> {
  64. // TODO compare model against old model for early bail?
  65. // Toggle the trusted class on the widget.
  66. this.toggleClass('jp-mod-trusted', model.trusted);
  67. // Render the actual content.
  68. return this.render(model);
  69. }
  70. /**
  71. * Render the mime model.
  72. *
  73. * @param model - The mime model to render.
  74. *
  75. * @returns A promise which resolves when rendering is complete.
  76. */
  77. abstract render(model: IRenderMime.IMimeModel): Promise<void>;
  78. }
  79. /**
  80. * A common base class for HTML mime renderers.
  81. */
  82. export
  83. abstract class RenderedHTMLCommon extends RenderedCommon {
  84. /**
  85. * Construct a new rendered HTML common widget.
  86. *
  87. * @param options - The options for initializing the widget.
  88. */
  89. constructor(options: IRenderMime.IRendererOptions) {
  90. super(options);
  91. this.addClass('jp-RenderedHTMLCommon');
  92. }
  93. }
  94. /**
  95. * A mime renderer for displaying HTML and math.
  96. */
  97. export
  98. class RenderedHTML extends RenderedHTMLCommon {
  99. /**
  100. * Construct a new rendered HTML widget.
  101. *
  102. * @param options - The options for initializing the widget.
  103. */
  104. constructor(options: IRenderMime.IRendererOptions) {
  105. super(options);
  106. this.addClass('jp-RenderedHTML');
  107. }
  108. /**
  109. * Render a mime model.
  110. *
  111. * @param model - The mime model to render.
  112. *
  113. * @returns A promise which resolves when rendering is complete.
  114. */
  115. render(model: IRenderMime.IMimeModel): Promise<void> {
  116. return renderers.renderHTML({
  117. host: this.node,
  118. source: String(model.data[this.mimeType]),
  119. trusted: model.trusted,
  120. resolver: this.resolver,
  121. sanitizer: this.sanitizer,
  122. linkHandler: this.linkHandler,
  123. shouldTypeset: this.isAttached
  124. });
  125. }
  126. /**
  127. * A message handler invoked on an `'after-attach'` message.
  128. */
  129. onAfterAttach(msg: Message): void {
  130. typeset(this.node);
  131. }
  132. }
  133. /**
  134. * A mime renderer for displaying LaTeX output.
  135. */
  136. export
  137. class RenderedLatex extends RenderedCommon {
  138. /**
  139. * Construct a new rendered Latex widget.
  140. *
  141. * @param options - The options for initializing the widget.
  142. */
  143. constructor(options: IRenderMime.IRendererOptions) {
  144. super(options);
  145. this.addClass('jp-RenderedLatex');
  146. }
  147. /**
  148. * Render a mime model.
  149. *
  150. * @param model - The mime model to render.
  151. *
  152. * @returns A promise which resolves when rendering is complete.
  153. */
  154. render(model: IRenderMime.IMimeModel): Promise<void> {
  155. return renderers.renderLatex({
  156. host: this.node,
  157. source: String(model.data[this.mimeType]),
  158. shouldTypeset: this.isAttached
  159. });
  160. }
  161. /**
  162. * A message handler invoked on an `'after-attach'` message.
  163. */
  164. onAfterAttach(msg: Message): void {
  165. typeset(this.node);
  166. }
  167. }
  168. /**
  169. * A mime renderer for displaying images.
  170. */
  171. export
  172. class RenderedImage extends RenderedCommon {
  173. /**
  174. * Construct a new rendered image widget.
  175. *
  176. * @param options - The options for initializing the widget.
  177. */
  178. constructor(options: IRenderMime.IRendererOptions) {
  179. super(options);
  180. this.addClass('jp-RenderedImage');
  181. }
  182. /**
  183. * Render a mime model.
  184. *
  185. * @param model - The mime model to render.
  186. *
  187. * @returns A promise which resolves when rendering is complete.
  188. */
  189. render(model: IRenderMime.IMimeModel): Promise<void> {
  190. let metadata = model.metadata[this.mimeType] as ReadonlyJSONObject;
  191. return renderers.renderImage({
  192. host: this.node,
  193. mimeType: this.mimeType,
  194. source: String(model.data[this.mimeType]),
  195. width: metadata && metadata.width as number | undefined,
  196. height: metadata && metadata.height as number | undefined
  197. });
  198. }
  199. }
  200. /**
  201. * A mime renderer for displaying Markdown with embeded latex.
  202. */
  203. export
  204. class RenderedMarkdown extends RenderedHTMLCommon {
  205. /**
  206. * Construct a new rendered markdown widget.
  207. *
  208. * @param options - The options for initializing the widget.
  209. */
  210. constructor(options: IRenderMime.IRendererOptions) {
  211. super(options);
  212. this.addClass('jp-RenderedMarkdown');
  213. }
  214. /**
  215. * Render a mime model.
  216. *
  217. * @param model - The mime model to render.
  218. *
  219. * @returns A promise which resolves when rendering is complete.
  220. */
  221. render(model: IRenderMime.IMimeModel): Promise<void> {
  222. return renderers.renderMarkdown({
  223. host: this.node,
  224. source: String(model.data[this.mimeType]),
  225. trusted: model.trusted,
  226. resolver: this.resolver,
  227. sanitizer: this.sanitizer,
  228. linkHandler: this.linkHandler,
  229. shouldTypeset: this.isAttached
  230. });
  231. }
  232. /**
  233. * A message handler invoked on an `'after-attach'` message.
  234. */
  235. onAfterAttach(msg: Message): void {
  236. typeset(this.node);
  237. }
  238. }
  239. /**
  240. * A widget for displaying rendered PDF content.
  241. */
  242. export
  243. class RenderedPDF extends RenderedCommon {
  244. /**
  245. * Construct a new rendered PDF widget.
  246. *
  247. * @param options - The options for initializing the widget.
  248. */
  249. constructor(options: IRenderMime.IRendererOptions) {
  250. super(options);
  251. this.addClass('jp-RenderedPDF');
  252. }
  253. /**
  254. * Render a mime model.
  255. */
  256. render(model: IRenderMime.IMimeModel): Promise<void> {
  257. return renderers.renderPDF({
  258. host: this.node,
  259. source: String(model.data[this.mimeType]),
  260. trusted: model.trusted
  261. });
  262. }
  263. }
  264. /**
  265. * A widget for displaying SVG content.
  266. */
  267. export
  268. class RenderedSVG extends RenderedCommon {
  269. /**
  270. * Construct a new rendered SVG widget.
  271. *
  272. * @param options - The options for initializing the widget.
  273. */
  274. constructor(options: IRenderMime.IRendererOptions) {
  275. super(options);
  276. this.addClass('jp-RenderedSVG');
  277. }
  278. /**
  279. * Render a mime model.
  280. *
  281. * @param model - The mime model to render.
  282. *
  283. * @returns A promise which resolves when rendering is complete.
  284. */
  285. render(model: IRenderMime.IMimeModel): Promise<void> {
  286. return renderers.renderSVG({
  287. host: this.node,
  288. source: String(model.data[this.mimeType]),
  289. trusted: model.trusted,
  290. resolver: this.resolver,
  291. linkHandler: this.linkHandler,
  292. shouldTypeset: this.isAttached
  293. });
  294. }
  295. /**
  296. * A message handler invoked on an `'after-attach'` message.
  297. */
  298. onAfterAttach(msg: Message): void {
  299. typeset(this.node);
  300. }
  301. }
  302. /**
  303. * A widget for displaying plain text and console text.
  304. */
  305. export
  306. class RenderedText extends RenderedCommon {
  307. /**
  308. * Construct a new rendered text widget.
  309. *
  310. * @param options - The options for initializing the widget.
  311. */
  312. constructor(options: IRenderMime.IRendererOptions) {
  313. super(options);
  314. this.addClass('jp-RenderedText');
  315. }
  316. /**
  317. * Render a mime model.
  318. *
  319. * @param model - The mime model to render.
  320. *
  321. * @returns A promise which resolves when rendering is complete.
  322. */
  323. render(model: IRenderMime.IMimeModel): Promise<void> {
  324. return renderers.renderText({
  325. host: this.node,
  326. source: String(model.data[this.mimeType])
  327. });
  328. }
  329. }