utils.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. // tslint:disable-next-line
  4. /// <reference path="./typings/json-to-html/json-to-html.d.ts"/>
  5. import json2html = require('json-to-html');
  6. import { simulate } from 'simulate-event';
  7. import { ServiceManager } from '@jupyterlab/services';
  8. import { ClientSession } from '@jupyterlab/apputils';
  9. import { nbformat } from '@jupyterlab/coreutils';
  10. import { UUID } from '@phosphor/coreutils';
  11. import {
  12. TextModelFactory,
  13. DocumentRegistry,
  14. Context
  15. } from '@jupyterlab/docregistry';
  16. import { INotebookModel, NotebookModelFactory } from '@jupyterlab/notebook';
  17. import {
  18. IRenderMime,
  19. RenderMimeRegistry,
  20. RenderedHTML,
  21. standardRendererFactories
  22. } from '@jupyterlab/rendermime';
  23. /**
  24. * Return a promise that resolves in the given milliseconds with the given value.
  25. */
  26. export function sleep<T>(milliseconds: number = 0, value?: T): Promise<T> {
  27. return new Promise((resolve, reject) => {
  28. setTimeout(() => {
  29. resolve(value);
  30. }, milliseconds);
  31. });
  32. }
  33. export function moment<T>(value?: T): Promise<T> {
  34. return new Promise((resolve, reject) => {
  35. requestAnimationFrame(() => {
  36. resolve(value);
  37. });
  38. });
  39. }
  40. /**
  41. * Get a copy of the default rendermime instance.
  42. */
  43. export function defaultRenderMime(): RenderMimeRegistry {
  44. return Private.rendermime.clone();
  45. }
  46. /**
  47. * Create a client session object.
  48. */
  49. export function createClientSession(
  50. options: Partial<ClientSession.IOptions> = {}
  51. ): Promise<ClientSession> {
  52. let manager = options.manager || Private.manager.sessions;
  53. return manager.ready.then(() => {
  54. return new ClientSession({
  55. manager,
  56. path: options.path || UUID.uuid4(),
  57. name: options.name,
  58. type: options.type,
  59. kernelPreference: options.kernelPreference || {
  60. shouldStart: true,
  61. canStart: true,
  62. name: manager.specs.default
  63. }
  64. });
  65. });
  66. }
  67. /**
  68. * Create a context for a file.
  69. */
  70. export function createFileContext(
  71. path?: string,
  72. manager?: ServiceManager.IManager
  73. ): Context<DocumentRegistry.IModel> {
  74. manager = manager || Private.manager;
  75. let factory = Private.textFactory;
  76. path = path || UUID.uuid4() + '.txt';
  77. return new Context({ manager, factory, path });
  78. }
  79. /**
  80. * Create a context for a notebook.
  81. */
  82. export async function createNotebookContext(
  83. path?: string,
  84. manager?: ServiceManager.IManager
  85. ): Promise<Context<INotebookModel>> {
  86. manager = manager || Private.manager;
  87. await manager.ready;
  88. const factory = Private.notebookFactory;
  89. path = path || UUID.uuid4() + '.ipynb';
  90. return new Context({
  91. manager,
  92. factory,
  93. path,
  94. kernelPreference: { name: manager.specs.default }
  95. });
  96. }
  97. /**
  98. * Wait for a dialog to be attached to an element.
  99. */
  100. export function waitForDialog(
  101. host: HTMLElement = document.body
  102. ): Promise<void> {
  103. return new Promise<void>((resolve, reject) => {
  104. let refresh = () => {
  105. let node = host.getElementsByClassName('jp-Dialog')[0];
  106. if (node) {
  107. resolve(void 0);
  108. return;
  109. }
  110. setTimeout(refresh, 10);
  111. };
  112. refresh();
  113. });
  114. }
  115. /**
  116. * Accept a dialog after it is attached by accepting the default button.
  117. */
  118. export function acceptDialog(host: HTMLElement = document.body): Promise<void> {
  119. return waitForDialog(host).then(() => {
  120. let node = host.getElementsByClassName('jp-Dialog')[0];
  121. if (node) {
  122. simulate(node as HTMLElement, 'keydown', { keyCode: 13 });
  123. }
  124. });
  125. }
  126. /**
  127. * Dismiss a dialog after it is attached.
  128. */
  129. export function dismissDialog(
  130. host: HTMLElement = document.body
  131. ): Promise<void> {
  132. return waitForDialog(host).then(() => {
  133. let node = host.getElementsByClassName('jp-Dialog')[0];
  134. if (node) {
  135. simulate(node as HTMLElement, 'keydown', { keyCode: 27 });
  136. }
  137. });
  138. }
  139. /**
  140. * A namespace for private data.
  141. */
  142. namespace Private {
  143. export const manager = new ServiceManager();
  144. export const textFactory = new TextModelFactory();
  145. export const notebookFactory = new NotebookModelFactory({});
  146. class JSONRenderer extends RenderedHTML {
  147. mimeType = 'text/html';
  148. renderModel(model: IRenderMime.IMimeModel): Promise<void> {
  149. let source = model.data['application/json'];
  150. model.setData({ data: { 'text/html': json2html(source) } });
  151. return super.renderModel(model);
  152. }
  153. }
  154. const jsonRendererFactory = {
  155. mimeTypes: ['application/json'],
  156. safe: true,
  157. createRenderer(
  158. options: IRenderMime.IRendererOptions
  159. ): IRenderMime.IRenderer {
  160. return new JSONRenderer(options);
  161. }
  162. };
  163. export const rendermime = new RenderMimeRegistry({
  164. initialFactories: standardRendererFactories
  165. });
  166. rendermime.addFactory(jsonRendererFactory, 10);
  167. }
  168. /**
  169. * The default outputs used for testing.
  170. */
  171. export const DEFAULT_OUTPUTS: nbformat.IOutput[] = [
  172. {
  173. name: 'stdout',
  174. output_type: 'stream',
  175. text: ['hello world\n', '0\n', '1\n', '2\n']
  176. },
  177. {
  178. name: 'stderr',
  179. output_type: 'stream',
  180. text: ['output to stderr\n']
  181. },
  182. {
  183. name: 'stderr',
  184. output_type: 'stream',
  185. text: ['output to stderr2\n']
  186. },
  187. {
  188. output_type: 'execute_result',
  189. execution_count: 1,
  190. data: { 'text/plain': 'foo' },
  191. metadata: {}
  192. },
  193. {
  194. output_type: 'display_data',
  195. data: { 'text/plain': 'hello, world' },
  196. metadata: {}
  197. },
  198. {
  199. output_type: 'error',
  200. ename: 'foo',
  201. evalue: 'bar',
  202. traceback: ['fizz', 'buzz']
  203. }
  204. ];