You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

187 lines
6.5 KiB

4 years ago
  1. define([
  2. 'jquery',
  3. 'base/js/namespace',
  4. 'base/js/dialog',
  5. 'base/js/events',
  6. 'base/js/utils',
  7. 'require',
  8. ], function(
  9. $,
  10. Jupyter,
  11. dialog,
  12. events,
  13. utils,
  14. require
  15. ) {
  16. "use strict";
  17. //==========================================================================
  18. var appmode_unload_handler = function (e) {
  19. var nb = Jupyter.notebook;
  20. var url_parts = [nb.base_url, 'apps', nb.notebook_path];
  21. var url = utils.url_path_join.apply(null, url_parts);
  22. // tell server to clean up session, kernel, and tmp notebook file.
  23. utils.ajax(url, {cache: false, type: "DELETE", async: false});
  24. };
  25. //==========================================================================
  26. var kernel_busy_handler = function (e) {
  27. $('#appmode-busy').css('visibility', 'visible');
  28. }
  29. //==========================================================================
  30. var kernel_idle_handler = function (e) {
  31. $('#appmode-busy').css('visibility', 'hidden');
  32. }
  33. //==========================================================================
  34. function goto_app_mode() {
  35. // kill Jupyter session
  36. Jupyter.notebook.session.delete();
  37. // build new URL
  38. var base_url = Jupyter.notebook.base_url;
  39. var prefix = base_url+"notebooks/"
  40. var path = window.location.pathname.substring(prefix.length);
  41. var search = window.location.search;
  42. var scroll = "appmode_scroll=" + $('#site').scrollTop();
  43. if (search.search(/appmode_scroll=\d+/) != -1){
  44. search = search.replace(/appmode_scroll=\d+/g, scroll);
  45. }else if (search.length == 0) {
  46. search = "?" + scroll;
  47. } else {
  48. search += "&" + scroll;
  49. }
  50. // goto new URL
  51. window.location.href = base_url + "apps/" + path + search;
  52. }
  53. //==========================================================================
  54. function goto_normal_mode() {
  55. // build new URL
  56. var base_url = Jupyter.notebook.base_url;
  57. var prefix = base_url+"apps/"
  58. var path = window.location.pathname.substring(prefix.length);
  59. var new_url = base_url + "notebooks/" + path + window.location.search;
  60. // goto new URL
  61. // Not using location.pathname as it might urlencode the path again
  62. window.location.href = new_url;
  63. }
  64. //==========================================================================
  65. function kernel_inject_url(kernel) {
  66. kernel.execute("jupyter_notebook_url = '" + window.location + "'");
  67. }
  68. //==========================================================================
  69. function initialize_step1() {
  70. if (Jupyter.notebook && Jupyter.notebook._fully_loaded) {
  71. initialize_step2();
  72. }else{
  73. events.one('notebook_loaded.Notebook', initialize_step2);
  74. }
  75. }
  76. //==========================================================================
  77. function initialize_step2() {
  78. // scroll to last position if in normal mode
  79. var base_url = Jupyter.notebook.base_url;
  80. if(window.location.pathname.startsWith(base_url+"notebooks/")){
  81. var url = window.location.href;
  82. var m = url.match(/appmode_scroll=(\d+)/);
  83. if(m)
  84. $('#site').scrollTop(m[1]);
  85. }
  86. var nb = Jupyter.notebook;
  87. if(nb.kernel && nb.kernel.info_reply.status) {
  88. initialize_step3();
  89. }else{
  90. events.one('kernel_ready.Kernel', initialize_step3);
  91. }
  92. }
  93. //==========================================================================
  94. function initialize_step3() {
  95. kernel_inject_url(Jupyter.notebook.kernel);
  96. // run kernel_inject_url() again when a new kernel is created
  97. events.on('kernel_created.Kernel kernel_created.Session', function(event, data) {
  98. kernel_inject_url(data.kernel);
  99. });
  100. var base_url = Jupyter.notebook.base_url;
  101. if(window.location.pathname.startsWith(base_url+"apps/")){
  102. // appmode is active -> continue intializtion
  103. initialize_step4();
  104. }
  105. }
  106. //==========================================================================
  107. function initialize_step4() {
  108. // install unload-handler
  109. window.onbeforeunload = appmode_unload_handler;
  110. // disable autosave
  111. Jupyter.notebook.set_autosave_interval(0);
  112. // disable keyboard shortcuts
  113. Jupyter.keyboard_manager.command_shortcuts.clear_shortcuts();
  114. Jupyter.keyboard_manager.edit_shortcuts.clear_shortcuts();
  115. // disable editing of text cells
  116. $('.text_cell').off("dblclick");
  117. // disable editing of raw cells
  118. $('.CodeMirror').each(function() {
  119. this.CodeMirror.setOption('readOnly', "nocursor");
  120. });
  121. // register kernel events
  122. events.on('kernel_idle.Kernel', kernel_idle_handler);
  123. events.on('kernel_busy.Kernel', kernel_busy_handler);
  124. // register on_click handler
  125. $('#appmode-leave').click(goto_normal_mode);
  126. // clear all cell outputs persisted in the initial notebook
  127. Jupyter.notebook.clear_all_output();
  128. // try to load the jupyter-js-widgets extension to see if it's installed
  129. utils.load_extension('jupyter-js-widgets/extension').then(function(module) {
  130. // force the extension to initialize if it exists, even if it's a repeat
  131. // operation, to avoid a race condition with executing cells that contain
  132. // widgets
  133. module.load_ipython_extension().then(initialize_step5);
  134. }).catch(initialize_step5);
  135. }
  136. //==========================================================================
  137. function initialize_step5() {
  138. // hide loading screen
  139. $('#appmode-loader').slideUp();
  140. // execute all cells
  141. Jupyter.notebook.execute_all_cells();
  142. console.log("Appmode: initialization finished");
  143. };
  144. //==========================================================================
  145. var load_ipython_extension = function() {
  146. // add button to toolbar in case appmode is not enabled
  147. Jupyter.toolbar.add_buttons_group([{
  148. id : 'toggle_codecells',
  149. label : 'Appmode',
  150. icon : 'fa-arrows-alt',
  151. callback : goto_app_mode
  152. }]);
  153. initialize_step1();
  154. };
  155. //==========================================================================
  156. return {
  157. load_ipython_extension : load_ipython_extension
  158. };
  159. });