utils.ts 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. import json2html = require('json-to-html');
  4. import {
  5. simulate
  6. } from 'simulate-event';
  7. import {
  8. createServiceManager, utils, IServiceManager
  9. } from 'jupyter-js-services';
  10. import {
  11. Widget
  12. } from 'phosphor/lib/ui/widget';
  13. import {
  14. TextModelFactory, IDocumentModel
  15. } from '../../lib/docregistry';
  16. import {
  17. Context
  18. } from '../../lib/docmanager/context';
  19. import {
  20. INotebookModel
  21. } from '../../lib/notebook/notebook/model';
  22. import {
  23. NotebookModelFactory
  24. } from '../../lib/notebook/notebook/modelfactory';
  25. import {
  26. LatexRenderer, PDFRenderer, JavascriptRenderer,
  27. SVGRenderer, MarkdownRenderer, TextRenderer, HTMLRenderer, ImageRenderer
  28. } from '../../lib/renderers';
  29. import {
  30. RenderMime
  31. } from '../../lib/rendermime';
  32. import {
  33. defaultSanitizer
  34. } from '../../lib/sanitizer';
  35. /**
  36. * Get a copy of the default rendermime instance.
  37. */
  38. export
  39. function defaultRenderMime(): RenderMime {
  40. return Private.rendermime.clone();
  41. }
  42. /**
  43. * Create a context for a file.
  44. */
  45. export
  46. function createFileContext(path?: string): Promise<Context<IDocumentModel>> {
  47. return Private.servicePromise.then(manager => {
  48. let factory = Private.textFactory;
  49. path = path || utils.uuid() + '.txt';
  50. return new Context({ manager, factory, path });
  51. });
  52. }
  53. /**
  54. * Create a context for a notebook.
  55. */
  56. export
  57. function createNotebookContext(path?: string): Promise<Context<INotebookModel>> {
  58. return Private.servicePromise.then(manager => {
  59. let factory = Private.notebookFactory;
  60. path = path || utils.uuid() + '.ipynb';
  61. return new Context({ manager, factory, path });
  62. });
  63. }
  64. /**
  65. * Wait for a dialog to be attached to an element.
  66. */
  67. export
  68. function waitForDialog(host: HTMLElement = document.body): Promise<void> {
  69. return new Promise<void>((resolve, reject) => {
  70. let refresh = () => {
  71. let node = host.getElementsByClassName('jp-Dialog')[0];
  72. if (node) {
  73. resolve(void 0);
  74. return;
  75. }
  76. setTimeout(refresh, 10);
  77. };
  78. refresh();
  79. });
  80. }
  81. /**
  82. * Accept a dialog after it is attached if it has an OK button.
  83. */
  84. export
  85. function acceptDialog(host: HTMLElement = document.body): Promise<void> {
  86. return waitForDialog(host).then(() => {
  87. let node = host.getElementsByClassName('jp-Dialog-okButton')[0];
  88. if (node) {
  89. (node as HTMLElement).click();
  90. }
  91. });
  92. }
  93. /**
  94. * Dismiss a dialog after it is attached.
  95. */
  96. export
  97. function dismissDialog(host: HTMLElement = document.body): Promise<void> {
  98. return waitForDialog(host).then(() => {
  99. let node = host.getElementsByClassName('jp-Dialog')[0];
  100. if (node) {
  101. simulate(node as HTMLElement, 'keydown', { keyCode: 27 });
  102. }
  103. });
  104. }
  105. /**
  106. * A namespace for private data.
  107. */
  108. namespace Private {
  109. export
  110. const servicePromise: Promise<IServiceManager> = createServiceManager();
  111. export
  112. const textFactory = new TextModelFactory();
  113. export
  114. const notebookFactory = new NotebookModelFactory();
  115. class JSONRenderer extends HTMLRenderer {
  116. /**
  117. * The mimetypes this renderer accepts.
  118. */
  119. mimetypes = ['application/json'];
  120. /**
  121. * Render the transformed mime bundle.
  122. */
  123. render(options: RenderMime.IRendererOptions<string>): Widget {
  124. options.source = json2html(options.source);
  125. return super.render(options);
  126. }
  127. }
  128. class InjectionRenderer extends TextRenderer {
  129. /**
  130. * The mimetypes this renderer accepts.
  131. */
  132. mimetypes = ['foo/bar'];
  133. /**
  134. * Render the transformed mime bundle.
  135. */
  136. render(options: RenderMime.IRendererOptions<string>): Widget {
  137. if (options.injector) {
  138. options.injector('text/plain', 'foo');
  139. options.injector('application/json', { 'foo': 1 } );
  140. }
  141. return super.render(options);
  142. }
  143. }
  144. const TRANSFORMERS = [
  145. new JavascriptRenderer(),
  146. new JSONRenderer(),
  147. new MarkdownRenderer(),
  148. new HTMLRenderer(),
  149. new PDFRenderer(),
  150. new ImageRenderer(),
  151. new SVGRenderer(),
  152. new LatexRenderer(),
  153. new InjectionRenderer(),
  154. new TextRenderer()
  155. ];
  156. let renderers: RenderMime.MimeMap<RenderMime.IRenderer> = {};
  157. let order: string[] = [];
  158. for (let t of TRANSFORMERS) {
  159. for (let m of t.mimetypes) {
  160. renderers[m] = t;
  161. order.push(m);
  162. }
  163. }
  164. let sanitizer = defaultSanitizer;
  165. export
  166. const rendermime = new RenderMime({ renderers, order, sanitizer });
  167. }