plugin.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. 'use strict';
  4. import {
  5. NotebookWidget, NotebookModel, NBData, populateNotebookModel, buildOutputModel, Output
  6. } from 'jupyter-js-notebook';
  7. import {
  8. Container
  9. } from 'phosphor-di';
  10. import {
  11. IContentsModel, IContentsManager,
  12. NotebookSessionManager, INotebookSessionManager,
  13. INotebookSession, IKernelMessage
  14. } from 'jupyter-js-services';
  15. import {
  16. Panel
  17. } from 'phosphor-panel';
  18. import {
  19. IServicesProvider, IFileOpener, IFileHandler
  20. } from '../index';
  21. import {
  22. AbstractFileHandler
  23. } from 'jupyter-js-filebrowser';
  24. import {
  25. Widget
  26. } from 'phosphor-widget';
  27. import {
  28. CodeCellModel, ICellModel, isCodeCell, BaseCellModel
  29. } from 'jupyter-js-cells';
  30. import {
  31. WidgetManager
  32. } from './widgetmanager';
  33. import './plugin.css';
  34. /**
  35. * Register the plugin contributions.
  36. *
  37. * @param container - The di container for type registration.
  38. *
  39. * #### Notes
  40. * This is called automatically when the plugin is loaded.
  41. */
  42. export
  43. function resolve(container: Container): Promise<IFileHandler> {
  44. return container.resolve({
  45. requires: [IServicesProvider, IFileOpener],
  46. create: (services: IServicesProvider, opener: IFileOpener) => {
  47. let handler = new NotebookFileHandler(services.contentsManager, services.notebookSessionManager);
  48. opener.register(handler);
  49. return handler;
  50. }
  51. });
  52. }
  53. export
  54. class SessionStoreMapping {
  55. constructor(services: IServicesProvider) {
  56. this.services = services;
  57. }
  58. public services: IServicesProvider;
  59. }
  60. function messageToModel(msg: IKernelMessage) {
  61. let m: Output = msg.content;
  62. let type = msg.header.msg_type;
  63. if (type === 'execute_result') {
  64. m.output_type = 'display_data';
  65. } else {
  66. m.output_type = type;
  67. }
  68. return buildOutputModel(m);
  69. }
  70. function executeSelectedCell(model: NotebookModel, session: INotebookSession) {
  71. let cell = model.cells.get(model.selectedCellIndex);
  72. if (isCodeCell(cell)) {
  73. let exRequest = {
  74. code: cell.input.textEditor.text,
  75. silent: false,
  76. store_history: true,
  77. stop_on_error: true,
  78. allow_stdin: true
  79. };
  80. let output = cell.output;
  81. console.log(`executing`, exRequest)
  82. let ex = session.kernel.execute(exRequest);
  83. output.clear(false);
  84. ex.onIOPub = (msg => {
  85. let model = messageToModel(msg);
  86. console.log('iopub', msg);
  87. if (model !== void 0) {
  88. output.add(model)
  89. }
  90. });
  91. ex.onReply = (msg => {console.log('a', msg)});
  92. ex.onDone = (msg => {console.log('b', msg)});
  93. }
  94. }
  95. /**
  96. * An implementation of a file handler.
  97. */
  98. export
  99. class NotebookFileHandler extends AbstractFileHandler {
  100. constructor(contents: IContentsManager, session: INotebookSessionManager) {
  101. super(contents);
  102. this.session = session;
  103. }
  104. /**
  105. * Get the list of file extensions supported by the handler.
  106. */
  107. get fileExtensions(): string[] {
  108. return ['.ipynb']
  109. }
  110. /**
  111. * Get file contents given a path.
  112. */
  113. protected getContents(path: string): Promise<IContentsModel> {
  114. return this.manager.get(path, { type: 'notebook' });
  115. }
  116. /**
  117. * Create the widget from an `IContentsModel`.
  118. */
  119. protected createWidget(path: string): Widget {
  120. let model = new NotebookModel();
  121. let panel = new Panel();
  122. let button = new Widget();
  123. let b = document.createElement('button');
  124. b.appendChild(document.createTextNode('Execute Current Cell'))
  125. button.node.appendChild(b);
  126. let widgetarea = new Widget();
  127. let manager = new WidgetManager(widgetarea.node);
  128. this.session.startNew({notebookPath: path}).then(s => {
  129. b.addEventListener('click', ev=> {
  130. executeSelectedCell(model, s);
  131. })
  132. s.kernel.commOpened.connect((kernel, msg) => {
  133. let content = msg.content;
  134. if (content.target_name !== 'jupyter.widget') {
  135. return;
  136. }
  137. let comm = kernel.connectToComm('jupyter.widget', content.comm_id);
  138. console.log('comm message', msg);
  139. let modelPromise = manager.handle_comm_open(comm, msg);
  140. comm.onMsg = (msg) => {
  141. manager.handle_comm_open(comm, msg)
  142. // create the widget model and (if needed) the view
  143. console.log('comm widget message', msg);
  144. }
  145. comm.onClose = (msg) => {
  146. console.log('comm widget close', msg);
  147. }
  148. })
  149. })
  150. panel.addChild(button);
  151. panel.addChild(widgetarea)
  152. panel.addChild(new NotebookWidget(model));
  153. panel.title.text = path.split('/').pop();
  154. panel.addClass('jp-NotebookContainer')
  155. return panel;
  156. }
  157. /**
  158. * Populate the notebook widget with the contents of the notebook.
  159. */
  160. protected setState(widget: Widget, model: IContentsModel): Promise<void> {
  161. let nbData: NBData = makedata(model);
  162. let nbWidget: NotebookWidget = ((widget as Panel).childAt(2)) as NotebookWidget;
  163. populateNotebookModel(nbWidget.model, nbData);
  164. return Promise.resolve();
  165. }
  166. protected getState(widget: Widget): Promise<IContentsModel> {
  167. return Promise.resolve(void 0);
  168. }
  169. session: INotebookSessionManager;
  170. }
  171. function makedata(a: IContentsModel): NBData {
  172. return {
  173. content: a.content,
  174. name: a.name,
  175. path: a.path
  176. }
  177. }
  178. /**
  179. * Widgets:
  180. * - write my own manager that inserts the widget element in a widget in the output area
  181. * - maybe have a single widget panel at the top of the notebook for starters.
  182. * - register with the comm manager of the kernel
  183. * -
  184. */