main.js.orig.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. define([
  2. 'require',
  3. 'jquery',
  4. 'base/js/namespace',
  5. 'base/js/events',
  6. 'notebook/js/codecell'
  7. ], function(
  8. requirejs,
  9. $,
  10. Jupyter,
  11. events,
  12. codecell
  13. ) {
  14. "use strict";
  15. var mod_name = "mickaSearch";
  16. var log_prefix = '[' + mod_name + '] ';
  17. // ...........Parameters configuration......................
  18. // define default values for config parameters if they were not present in general settings (notebook.json)
  19. var cfg = {
  20. 'window_display': false,
  21. 'csw_url': 'https://hub.lesprojekt.cz/micka/micka2/csw/',
  22. 'cols': {
  23. 'lenName': 16,
  24. 'lenType': 16,
  25. 'lenVar': 40
  26. },
  27. }
  28. //.....................global variables....
  29. var st = {}
  30. st.config_loaded = false;
  31. st.extension_initialized = false;
  32. st.code_init = "";
  33. function read_config(cfg, callback) { // read after nb is loaded
  34. var config = Jupyter.notebook.config;
  35. config.loaded.then(function() {
  36. // config may be specified at system level or at document level.
  37. // first, update defaults with config loaded from server
  38. cfg = $.extend(true, cfg, config.data.mickaSearch);
  39. // then update cfg with some vars found in current notebook metadata
  40. // and save in nb metadata (then can be modified per document)
  41. if (Jupyter.notebook.metadata.mickaSearch) {
  42. if (Jupyter.notebook.metadata.mickaSearch.window_display)
  43. cfg.window_display = Jupyter.notebook.metadata.mickaSearch.window_display;
  44. if (Jupyter.notebook.metadata.mickaSearch.csw_url)
  45. cfg.csw_url = Jupyter.notebook.metadata.mickaSearch.csw_url;
  46. }
  47. cfg = Jupyter.notebook.metadata.mickaSearch = $.extend(true,
  48. cfg, Jupyter.notebook.metadata.mickaSearch);
  49. // call callbacks
  50. callback && callback();
  51. st.config_loaded = true;
  52. })
  53. return cfg;
  54. }
  55. var sortable;
  56. function togglemickaSearch() {
  57. toggle_mickaSearch(cfg, st)
  58. }
  59. var mickaSearch_button = function() {
  60. if (!Jupyter.toolbar) {
  61. events.on("app_initialized.NotebookApp", mickaSearch_button);
  62. return;
  63. }
  64. if ($("#mickaSearch_button").length === 0) {
  65. $(Jupyter.toolbar.add_buttons_group([
  66. Jupyter.keyboard_manager.actions.register ({
  67. 'help' : 'MIcKA Search',
  68. 'icon' : 'fa-search',
  69. 'handler': togglemickaSearch,
  70. }, 'toggle-micka-search', 'mickaSearch')
  71. ])).find('.btn').attr('id', 'mickaSearch_button');
  72. }
  73. };
  74. var load_css = function() {
  75. var link = document.createElement("link");
  76. link.type = "text/css";
  77. link.rel = "stylesheet";
  78. link.href = requirejs.toUrl("./main.css");
  79. document.getElementsByTagName("head")[0].appendChild(link);
  80. };
  81. function html_table(jsonVars) {
  82. function _trunc(x, L) {
  83. x = String(x)
  84. if (x.length < L) return x
  85. else return x.substring(0, L - 3) + '...'
  86. }
  87. var kernelLanguage = Jupyter.notebook.metadata.kernelspec.language.toLowerCase()
  88. var kernel_config = cfg.kernels_config[kernelLanguage];
  89. var varList = JSON.parse(String(jsonVars))
  90. var shape_str = '';
  91. var has_shape = false;
  92. if (varList.some(listVar => "varShape" in listVar && listVar.varShape !== '')) { //if any of them have a shape
  93. shape_str = '<th >Shape</th>';
  94. has_shape = true;
  95. }
  96. var beg_table = '<div class=\"inspector\"><table class=\"table fixed table-condensed table-nonfluid \"><col /> \
  97. <col /><col /><thead><tr><th >X</th><th >Name</th><th >Type</th><th >Size</th>' + shape_str + '<th >Value</th></tr></thead><tr><td> \
  98. </td></tr>';
  99. varList.forEach(listVar => {
  100. var shape_col_str = '</td><td>';
  101. if (has_shape) {
  102. shape_col_str = '</td><td>' + listVar.varShape + '</td><td>';
  103. }
  104. beg_table +=
  105. '<tr><td><a href=\"#\" onClick=\"Jupyter.notebook.kernel.execute(\'' +
  106. kernel_config.delete_cmd_prefix + listVar.varName + kernel_config.delete_cmd_postfix + '\'' + '); ' +
  107. 'Jupyter.notebook.events.trigger(\'varRefresh\'); \">x</a></td>' +
  108. '<td>' + _trunc(listVar.varName, cfg.cols.lenName) + '</td><td>' + _trunc(listVar.varType, cfg.cols.lenType) +
  109. '</td><td>' + listVar.varSize + shape_col_str + _trunc(listVar.varContent, cfg.cols.lenVar) +
  110. '</td></tr>';
  111. });
  112. var full_table = beg_table + '</table></div>';
  113. return full_table;
  114. }
  115. function code_exec_callback(msg) {
  116. var jsonVars = msg.content['text'];
  117. var notWellDefined = false;
  118. if (msg.content.evalue)
  119. notWellDefined = msg.content.evalue == "name 'var_dic_list' is not defined" ||
  120. msg.content.evalue.substr(0,28) == "Error in cat(var_dic_list())"
  121. //means that var_dic_list was cleared ==> need to retart the extension
  122. if (notWellDefined) mickaSearch_init()
  123. else $('#mickaSearch').html(html_table(jsonVars))
  124. requirejs(['nbextensions/mickaSearch/jquery.tablesorter.min'],
  125. function() {
  126. setTimeout(function() { if ($('#mickaSearch').length>0)
  127. $('#mickaSearch table').tablesorter()}, 50)
  128. });
  129. }
  130. function tableSort() {
  131. requirejs(['nbextensions/mickaSearch/jquery.tablesorter.min'])
  132. $('#mickaSearch table').tablesorter()
  133. }
  134. var varRefresh = function() {
  135. var kernelLanguage = Jupyter.notebook.metadata.kernelspec.language.toLowerCase()
  136. var kernel_config = cfg.kernels_config[kernelLanguage];
  137. requirejs(['nbextensions/mickaSearch/jquery.tablesorter.min'],
  138. function() {
  139. Jupyter.notebook.kernel.execute(
  140. kernel_config.varRefreshCmd, { iopub: { output: code_exec_callback } }, { silent: false }
  141. );
  142. });
  143. }
  144. var mickaSearch_init = function() {
  145. // Define code_init
  146. // read and execute code_init
  147. function read_code_init(lib) {
  148. /*var libName = Jupyter.notebook.base_url + "nbextensions/mickaSearch/" + lib;
  149. $.get(libName).done(function(data) {
  150. st.code_init = data;
  151. st.code_init = st.code_init.replace('lenName', cfg.cols.lenName).replace('lenType', cfg.cols.lenType)
  152. .replace('lenVar', cfg.cols.lenVar)
  153. //.replace('types_to_exclude', JSON.stringify(cfg.types_to_exclude).replace(/\"/g, "'"))
  154. requirejs(
  155. [
  156. 'nbextensions/mickaSearch/jquery.tablesorter.min'
  157. //'nbextensions/mickaSearch/colResizable-1.6.min'
  158. ],
  159. function() {
  160. Jupyter.notebook.kernel.execute(st.code_init, { iopub: { output: code_exec_callback } }, { silent: false });
  161. })*/
  162. micka_search(cfg, st); // create window if not already present
  163. /*console.log(log_prefix + 'loaded library');
  164. }).fail(function() {
  165. console.log(log_prefix + 'failed to load ' + lib + ' library')
  166. });*/
  167. }
  168. // read configuration
  169. cfg = read_config(cfg, function() {
  170. // Called when config is available
  171. if ($("#mickaSearch_button").length > 0) { // extension was present
  172. $("#mickaSearch_button").remove();
  173. $('#mickaSearch-wrapper').remove();
  174. }
  175. mickaSearch_button();
  176. read_code_init(kernel_config.library);
  177. /* if (typeof Jupyter.notebook.kernel !== "undefined" && Jupyter.notebook.kernel !== null) {
  178. var kernelLanguage = Jupyter.notebook.metadata.kernelspec.language.toLowerCase()
  179. var kernel_config = cfg.kernels_config[kernelLanguage];
  180. if (kernel_config === undefined) { // Kernel is not supported
  181. console.warn(log_prefix + " Sorry, can't use kernel language " + kernelLanguage + ".\n" +
  182. "Configurations are currently only defined for the following languages:\n" +
  183. Object.keys(cfg.kernels_config).join(', ') + "\n" +
  184. "See readme for more details.");
  185. if ($("#mickaSearch_button").length > 0) { // extension was present
  186. $("#mickaSearch_button").remove();
  187. $('#mickaSearch-wrapper').remove();
  188. // turn off events
  189. events.off('execute.CodeCell', varRefresh);
  190. events.off('varRefresh', varRefresh);
  191. }
  192. return
  193. }
  194. mickaSearch_button(); // In case button was removed
  195. // read and execute code_init (if kernel is supported)
  196. read_code_init(kernel_config.library);
  197. // console.log("code_init-->", st.code_init)
  198. } else {
  199. console.warn(log_prefix + "Kernel not available?");
  200. }*/
  201. }); // called after config is stable
  202. // event: on cell execution, update the list of variables
  203. /*events.on('execute.CodeCell', varRefresh);
  204. events.on('varRefresh', varRefresh);*/
  205. }
  206. var create_mickaSearch_div = function(cfg, st) {
  207. function save_position(){
  208. Jupyter.notebook.metadata.mickaSearch.position = {
  209. 'left': $('#mickaSearch-wrapper').css('left'),
  210. 'top': $('#mickaSearch-wrapper').css('top'),
  211. 'width': $('#mickaSearch-wrapper').css('width'),
  212. 'height': $('#mickaSearch-wrapper').css('height'),
  213. 'right': $('#mickaSearch-wrapper').css('right')
  214. };
  215. }
  216. var mickaSearch_wrapper = $('<div id="mickaSearch-wrapper"/>')
  217. .append(
  218. $('<div id="mickaSearch-header"/>')
  219. .addClass("header")
  220. .text("MIcKA Search ")
  221. .append(
  222. $("<a/>")
  223. .attr("href", "#")
  224. .text("[x]")
  225. .addClass("kill-btn")
  226. .attr('title', 'Close window')
  227. .click(function() {
  228. togglemickaSearch();
  229. return false;
  230. })
  231. )
  232. .append(
  233. $("<a/>")
  234. .attr("href", "#")
  235. .addClass("hide-btn")
  236. .attr('title', 'Hide MIcKA Search')
  237. .text("[-]")
  238. .click(function() {
  239. $('#mickaSearch-wrapper').css('position', 'fixed');
  240. $('#mickaSearch').slideToggle({
  241. start: function(event, ui) {
  242. // $(this).width($(this).width());
  243. },
  244. 'complete': function() {
  245. Jupyter.notebook.metadata.mickaSearch['mickaSearch_section_display'] = $('#mickaSearch').css('display');
  246. save_position();
  247. Jupyter.notebook.set_dirty();
  248. }
  249. });
  250. $('#mickaSearch-wrapper').toggleClass('closed');
  251. if ($('#mickaSearch-wrapper').hasClass('closed')) {
  252. cfg.oldHeight = $('#mickaSearch-wrapper').height(); //.css('height');
  253. $('#mickaSearch-wrapper').css({ height: 40 });
  254. $('#mickaSearch-wrapper .hide-btn')
  255. .text('[+]')
  256. .attr('title', 'Show MIcKA Search');
  257. } else {
  258. $('#mickaSearch-wrapper').height(cfg.oldHeight); //css({ height: cfg.oldHeight });
  259. $('#mickaSearch').height(cfg.oldHeight - $('#mickaSearch-header').height() - 30 )
  260. $('#mickaSearch-wrapper .hide-btn')
  261. .text('[-]')
  262. .attr('title', 'Hide MIcKA Search');
  263. }
  264. return false;
  265. })
  266. ).append(
  267. $("<a/>")
  268. .attr("href", "#")
  269. .text(" \u21BB")
  270. .addClass("reload-btn")
  271. .attr('title', 'Reload MIcKA Search')
  272. .click(function() {
  273. //micka_search(cfg,st);
  274. varRefresh();
  275. return false;
  276. })
  277. ).append(
  278. $("<span/>")
  279. .html("&nbsp;&nbsp")
  280. ).append(
  281. $("<span/>")
  282. .html("&nbsp;&nbsp;")
  283. )
  284. ).append(
  285. $("<div/>").attr("id", "mickaSearch").addClass('mickaSearch')
  286. )
  287. $("body").append(mickaSearch_wrapper);
  288. // Ensure position is fixed
  289. $('#mickaSearch-wrapper').css('position', 'fixed');
  290. // enable dragging and save position on stop moving
  291. $('#mickaSearch-wrapper').draggable({
  292. drag: function(event, ui) {}, //end of drag function
  293. start: function(event, ui) {
  294. $(this).width($(this).width());
  295. },
  296. stop: function(event, ui) { // on save, store window position
  297. save_position();
  298. Jupyter.notebook.set_dirty();
  299. // Ensure position is fixed (again)
  300. $('#mickaSearch-wrapper').css('position', 'fixed');
  301. },
  302. });
  303. $('#mickaSearch-wrapper').resizable({
  304. resize: function(event, ui) {
  305. $('#mickaSearch').height($('#mickaSearch-wrapper').height() - $('#mickaSearch-header').height());
  306. },
  307. start: function(event, ui) {
  308. //$(this).width($(this).width());
  309. $(this).css('position', 'fixed');
  310. },
  311. stop: function(event, ui) { // on save, store window position
  312. save_position();
  313. $('#mickaSearch').height($('#mickaSearch-wrapper').height() - $('#mickaSearch-header').height())
  314. Jupyter.notebook.set_dirty();
  315. // Ensure position is fixed (again)
  316. //$(this).css('position', 'fixed');
  317. }
  318. })
  319. // restore window position at startup
  320. if (Jupyter.notebook.metadata.mickaSearch.position !== undefined) {
  321. $('#mickaSearch-wrapper').css(Jupyter.notebook.metadata.mickaSearch.position);
  322. }
  323. // Ensure position is fixed
  324. $('#mickaSearch-wrapper').css('position', 'fixed');
  325. // Restore window display
  326. if (Jupyter.notebook.metadata.mickaSearch !== undefined) {
  327. if (Jupyter.notebook.metadata.mickaSearch['mickaSearch_section_display'] !== undefined) {
  328. $('#mickaSearch').css('display', Jupyter.notebook.metadata.mickaSearch['mickaSearch_section_display'])
  329. //$('#mickaSearch').css('height', $('#mickaSearch-wrapper').height() - $('#mickaSearch-header').height())
  330. if (Jupyter.notebook.metadata.mickaSearch['mickaSearch_section_display'] == 'none') {
  331. $('#mickaSearch-wrapper').addClass('closed');
  332. $('#mickaSearch-wrapper').css({ height: 40 });
  333. $('#mickaSearch-wrapper .hide-btn')
  334. .text('[+]')
  335. .attr('title', 'Show MIcKA Search');
  336. }
  337. }
  338. if (Jupyter.notebook.metadata.mickaSearch['window_display'] !== undefined) {
  339. console.log(log_prefix + "Restoring MIcKA Search window");
  340. $('#mickaSearch-wrapper').css('display', Jupyter.notebook.metadata.mickaSearch['window_display'] ? 'block' : 'none');
  341. if ($('#mickaSearch-wrapper').hasClass('closed')){
  342. $('#mickaSearch').height(cfg.oldHeight - $('#mickaSearch-header').height())
  343. }else{
  344. $('#mickaSearch').height($('#mickaSearch-wrapper').height() - $('#mickaSearch-header').height()-30)
  345. }
  346. }
  347. }
  348. // if mickaSearch-wrapper is undefined (first run(?), then hide it)
  349. if ($('#mickaSearch-wrapper').css('display') == undefined) $('#mickaSearch-wrapper').css('display', "none") //block
  350. mickaSearch_wrapper.addClass('mickaSearch-float-wrapper');
  351. }
  352. var micka_search = function(cfg, st) {
  353. var mickaSearch_wrapper = $("#mickaSearch-wrapper");
  354. if (mickaSearch_wrapper.length === 0) {
  355. create_mickaSearch_div(cfg, st);
  356. }
  357. $(window).resize(function() {
  358. $('#mickaSearch').css({ maxHeight: $(window).height() - 30 });
  359. $('#mickaSearch-wrapper').css({ maxHeight: $(window).height() - 10 });
  360. });
  361. $(window).trigger('resize');
  362. varRefresh();
  363. };
  364. var toggle_mickaSearch = function(cfg, st) {
  365. // toggle draw (first because of first-click behavior)
  366. $("#mickaSearch-wrapper").toggle({
  367. 'progress': function() {},
  368. 'complete': function() {
  369. Jupyter.notebook.metadata.mickaSearch['window_display'] = $('#mickaSearch-wrapper').css('display') == 'block';
  370. Jupyter.notebook.set_dirty();
  371. // recompute:
  372. micka_search(cfg, st);
  373. }
  374. });
  375. };
  376. var load_jupyter_extension = function() {
  377. load_css(); //console.log("Loading css")
  378. mickaSearch_button(); //console.log("Adding mickaSearch_button")
  379. // If a kernel is available,
  380. if (typeof Jupyter.notebook.kernel !== "undefined" && Jupyter.notebook.kernel !== null) {
  381. console.log(log_prefix + "Kernel is available -- mickaSearch initializing ")
  382. mickaSearch_init();
  383. }
  384. // if a kernel wasn't available, we still wait for one. Anyway, we will run this for new kernel
  385. // (test if is is a Python kernel and initialize)
  386. // on kernel_ready.Kernel, a new kernel has been started and we shall initialize the extension
  387. events.on("kernel_ready.Kernel", function(evt, data) {
  388. console.log(log_prefix + "Kernel is available -- reading configuration");
  389. mickaSearch_init();
  390. });
  391. };
  392. return {
  393. load_ipython_extension: load_jupyter_extension,
  394. //varRefresh: varRefresh
  395. };
  396. });