define([ 'require', 'jquery', 'base/js/namespace', 'base/js/events', 'notebook/js/codecell' ], function( requirejs, $, Jupyter, events, codecell ) { "use strict"; var mod_name = "mickaSearch"; var log_prefix = '[' + mod_name + '] '; // ...........Parameters configuration...................... // define default values for config parameters if they were not present in general settings (notebook.json) var cfg = { 'window_display': false, 'csw_url': 'https://hub.lesprojekt.cz/micka/micka2/csw/', 'cols': { 'lenName': 16, 'lenType': 16, 'lenVar': 40 }, } //.....................global variables.... var st = {} st.config_loaded = false; st.extension_initialized = false; st.code_init = ""; function read_config(cfg, callback) { // read after nb is loaded var config = Jupyter.notebook.config; config.loaded.then(function() { // config may be specified at system level or at document level. // first, update defaults with config loaded from server cfg = $.extend(true, cfg, config.data.mickaSearch); // then update cfg with some vars found in current notebook metadata // and save in nb metadata (then can be modified per document) if (Jupyter.notebook.metadata.mickaSearch) { if (Jupyter.notebook.metadata.mickaSearch.window_display) cfg.window_display = Jupyter.notebook.metadata.mickaSearch.window_display; if (Jupyter.notebook.metadata.mickaSearch.csw_url) cfg.csw_url = Jupyter.notebook.metadata.mickaSearch.csw_url; } cfg = Jupyter.notebook.metadata.mickaSearch = $.extend(true, cfg, Jupyter.notebook.metadata.mickaSearch); // call callbacks callback && callback(); st.config_loaded = true; }) return cfg; } var sortable; function togglemickaSearch() { toggle_mickaSearch(cfg, st) } var mickaSearch_button = function() { if (!Jupyter.toolbar) { events.on("app_initialized.NotebookApp", mickaSearch_button); return; } if ($("#mickaSearch_button").length === 0) { $(Jupyter.toolbar.add_buttons_group([ Jupyter.keyboard_manager.actions.register ({ 'help' : 'MIcKA Search', 'icon' : 'fa-search', 'handler': togglemickaSearch, }, 'toggle-micka-search', 'mickaSearch') ])).find('.btn').attr('id', 'mickaSearch_button'); } }; var load_css = function() { var link = document.createElement("link"); link.type = "text/css"; link.rel = "stylesheet"; link.href = requirejs.toUrl("./main.css"); document.getElementsByTagName("head")[0].appendChild(link); }; function html_table(jsonVars) { function _trunc(x, L) { x = String(x) if (x.length < L) return x else return x.substring(0, L - 3) + '...' } var kernelLanguage = Jupyter.notebook.metadata.kernelspec.language.toLowerCase() var kernel_config = cfg.kernels_config[kernelLanguage]; var varList = JSON.parse(String(jsonVars)) var shape_str = ''; var has_shape = false; if (varList.some(listVar => "varShape" in listVar && listVar.varShape !== '')) { //if any of them have a shape shape_str = 'Shape'; has_shape = true; } var beg_table = '
\ ' + shape_str + ''; varList.forEach(listVar => { var shape_col_str = '' + ''; }); var full_table = beg_table + '
XNameTypeSizeValue
\
'; if (has_shape) { shape_col_str = '' + listVar.varShape + ''; } beg_table += '
x' + _trunc(listVar.varName, cfg.cols.lenName) + '' + _trunc(listVar.varType, cfg.cols.lenType) + '' + listVar.varSize + shape_col_str + _trunc(listVar.varContent, cfg.cols.lenVar) + '
'; return full_table; } function code_exec_callback(msg) { var jsonVars = msg.content['text']; var notWellDefined = false; if (msg.content.evalue) notWellDefined = msg.content.evalue == "name 'var_dic_list' is not defined" || msg.content.evalue.substr(0,28) == "Error in cat(var_dic_list())" //means that var_dic_list was cleared ==> need to retart the extension if (notWellDefined) mickaSearch_init() else $('#mickaSearch').html(html_table(jsonVars)) requirejs(['nbextensions/mickaSearch/jquery.tablesorter.min'], function() { setTimeout(function() { if ($('#mickaSearch').length>0) $('#mickaSearch table').tablesorter()}, 50) }); } function tableSort() { requirejs(['nbextensions/mickaSearch/jquery.tablesorter.min']) $('#mickaSearch table').tablesorter() } var varRefresh = function() { var kernelLanguage = Jupyter.notebook.metadata.kernelspec.language.toLowerCase() var kernel_config = cfg.kernels_config[kernelLanguage]; requirejs(['nbextensions/mickaSearch/jquery.tablesorter.min'], function() { Jupyter.notebook.kernel.execute( kernel_config.varRefreshCmd, { iopub: { output: code_exec_callback } }, { silent: false } ); }); } var mickaSearch_init = function() { // Define code_init // read and execute code_init function read_code_init(lib) { /*var libName = Jupyter.notebook.base_url + "nbextensions/mickaSearch/" + lib; $.get(libName).done(function(data) { st.code_init = data; st.code_init = st.code_init.replace('lenName', cfg.cols.lenName).replace('lenType', cfg.cols.lenType) .replace('lenVar', cfg.cols.lenVar) //.replace('types_to_exclude', JSON.stringify(cfg.types_to_exclude).replace(/\"/g, "'")) requirejs( [ 'nbextensions/mickaSearch/jquery.tablesorter.min' //'nbextensions/mickaSearch/colResizable-1.6.min' ], function() { Jupyter.notebook.kernel.execute(st.code_init, { iopub: { output: code_exec_callback } }, { silent: false }); })*/ micka_search(cfg, st); // create window if not already present /*console.log(log_prefix + 'loaded library'); }).fail(function() { console.log(log_prefix + 'failed to load ' + lib + ' library') });*/ } // read configuration cfg = read_config(cfg, function() { // Called when config is available if ($("#mickaSearch_button").length > 0) { // extension was present $("#mickaSearch_button").remove(); $('#mickaSearch-wrapper').remove(); } mickaSearch_button(); read_code_init(kernel_config.library); /* if (typeof Jupyter.notebook.kernel !== "undefined" && Jupyter.notebook.kernel !== null) { var kernelLanguage = Jupyter.notebook.metadata.kernelspec.language.toLowerCase() var kernel_config = cfg.kernels_config[kernelLanguage]; if (kernel_config === undefined) { // Kernel is not supported console.warn(log_prefix + " Sorry, can't use kernel language " + kernelLanguage + ".\n" + "Configurations are currently only defined for the following languages:\n" + Object.keys(cfg.kernels_config).join(', ') + "\n" + "See readme for more details."); if ($("#mickaSearch_button").length > 0) { // extension was present $("#mickaSearch_button").remove(); $('#mickaSearch-wrapper').remove(); // turn off events events.off('execute.CodeCell', varRefresh); events.off('varRefresh', varRefresh); } return } mickaSearch_button(); // In case button was removed // read and execute code_init (if kernel is supported) read_code_init(kernel_config.library); // console.log("code_init-->", st.code_init) } else { console.warn(log_prefix + "Kernel not available?"); }*/ }); // called after config is stable // event: on cell execution, update the list of variables /*events.on('execute.CodeCell', varRefresh); events.on('varRefresh', varRefresh);*/ } var create_mickaSearch_div = function(cfg, st) { function save_position(){ Jupyter.notebook.metadata.mickaSearch.position = { 'left': $('#mickaSearch-wrapper').css('left'), 'top': $('#mickaSearch-wrapper').css('top'), 'width': $('#mickaSearch-wrapper').css('width'), 'height': $('#mickaSearch-wrapper').css('height'), 'right': $('#mickaSearch-wrapper').css('right') }; } var mickaSearch_wrapper = $('
') .append( $('
') .addClass("header") .text("MIcKA Search ") .append( $("") .attr("href", "#") .text("[x]") .addClass("kill-btn") .attr('title', 'Close window') .click(function() { togglemickaSearch(); return false; }) ) .append( $("") .attr("href", "#") .addClass("hide-btn") .attr('title', 'Hide MIcKA Search') .text("[-]") .click(function() { $('#mickaSearch-wrapper').css('position', 'fixed'); $('#mickaSearch').slideToggle({ start: function(event, ui) { // $(this).width($(this).width()); }, 'complete': function() { Jupyter.notebook.metadata.mickaSearch['mickaSearch_section_display'] = $('#mickaSearch').css('display'); save_position(); Jupyter.notebook.set_dirty(); } }); $('#mickaSearch-wrapper').toggleClass('closed'); if ($('#mickaSearch-wrapper').hasClass('closed')) { cfg.oldHeight = $('#mickaSearch-wrapper').height(); //.css('height'); $('#mickaSearch-wrapper').css({ height: 40 }); $('#mickaSearch-wrapper .hide-btn') .text('[+]') .attr('title', 'Show MIcKA Search'); } else { $('#mickaSearch-wrapper').height(cfg.oldHeight); //css({ height: cfg.oldHeight }); $('#mickaSearch').height(cfg.oldHeight - $('#mickaSearch-header').height() - 30 ) $('#mickaSearch-wrapper .hide-btn') .text('[-]') .attr('title', 'Hide MIcKA Search'); } return false; }) ).append( $("") .attr("href", "#") .text(" \u21BB") .addClass("reload-btn") .attr('title', 'Reload MIcKA Search') .click(function() { //micka_search(cfg,st); varRefresh(); return false; }) ).append( $("") .html("  ") ).append( $("") .html("  ") ) ).append( $("
").attr("id", "mickaSearch").addClass('mickaSearch') ) $("body").append(mickaSearch_wrapper); // Ensure position is fixed $('#mickaSearch-wrapper').css('position', 'fixed'); // enable dragging and save position on stop moving $('#mickaSearch-wrapper').draggable({ drag: function(event, ui) {}, //end of drag function start: function(event, ui) { $(this).width($(this).width()); }, stop: function(event, ui) { // on save, store window position save_position(); Jupyter.notebook.set_dirty(); // Ensure position is fixed (again) $('#mickaSearch-wrapper').css('position', 'fixed'); }, }); $('#mickaSearch-wrapper').resizable({ resize: function(event, ui) { $('#mickaSearch').height($('#mickaSearch-wrapper').height() - $('#mickaSearch-header').height()); }, start: function(event, ui) { //$(this).width($(this).width()); $(this).css('position', 'fixed'); }, stop: function(event, ui) { // on save, store window position save_position(); $('#mickaSearch').height($('#mickaSearch-wrapper').height() - $('#mickaSearch-header').height()) Jupyter.notebook.set_dirty(); // Ensure position is fixed (again) //$(this).css('position', 'fixed'); } }) // restore window position at startup if (Jupyter.notebook.metadata.mickaSearch.position !== undefined) { $('#mickaSearch-wrapper').css(Jupyter.notebook.metadata.mickaSearch.position); } // Ensure position is fixed $('#mickaSearch-wrapper').css('position', 'fixed'); // Restore window display if (Jupyter.notebook.metadata.mickaSearch !== undefined) { if (Jupyter.notebook.metadata.mickaSearch['mickaSearch_section_display'] !== undefined) { $('#mickaSearch').css('display', Jupyter.notebook.metadata.mickaSearch['mickaSearch_section_display']) //$('#mickaSearch').css('height', $('#mickaSearch-wrapper').height() - $('#mickaSearch-header').height()) if (Jupyter.notebook.metadata.mickaSearch['mickaSearch_section_display'] == 'none') { $('#mickaSearch-wrapper').addClass('closed'); $('#mickaSearch-wrapper').css({ height: 40 }); $('#mickaSearch-wrapper .hide-btn') .text('[+]') .attr('title', 'Show MIcKA Search'); } } if (Jupyter.notebook.metadata.mickaSearch['window_display'] !== undefined) { console.log(log_prefix + "Restoring MIcKA Search window"); $('#mickaSearch-wrapper').css('display', Jupyter.notebook.metadata.mickaSearch['window_display'] ? 'block' : 'none'); if ($('#mickaSearch-wrapper').hasClass('closed')){ $('#mickaSearch').height(cfg.oldHeight - $('#mickaSearch-header').height()) }else{ $('#mickaSearch').height($('#mickaSearch-wrapper').height() - $('#mickaSearch-header').height()-30) } } } // if mickaSearch-wrapper is undefined (first run(?), then hide it) if ($('#mickaSearch-wrapper').css('display') == undefined) $('#mickaSearch-wrapper').css('display', "none") //block mickaSearch_wrapper.addClass('mickaSearch-float-wrapper'); } var micka_search = function(cfg, st) { var mickaSearch_wrapper = $("#mickaSearch-wrapper"); if (mickaSearch_wrapper.length === 0) { create_mickaSearch_div(cfg, st); } $(window).resize(function() { $('#mickaSearch').css({ maxHeight: $(window).height() - 30 }); $('#mickaSearch-wrapper').css({ maxHeight: $(window).height() - 10 }); }); $(window).trigger('resize'); varRefresh(); }; var toggle_mickaSearch = function(cfg, st) { // toggle draw (first because of first-click behavior) $("#mickaSearch-wrapper").toggle({ 'progress': function() {}, 'complete': function() { Jupyter.notebook.metadata.mickaSearch['window_display'] = $('#mickaSearch-wrapper').css('display') == 'block'; Jupyter.notebook.set_dirty(); // recompute: micka_search(cfg, st); } }); }; var load_jupyter_extension = function() { load_css(); //console.log("Loading css") mickaSearch_button(); //console.log("Adding mickaSearch_button") // If a kernel is available, if (typeof Jupyter.notebook.kernel !== "undefined" && Jupyter.notebook.kernel !== null) { console.log(log_prefix + "Kernel is available -- mickaSearch initializing ") mickaSearch_init(); } // if a kernel wasn't available, we still wait for one. Anyway, we will run this for new kernel // (test if is is a Python kernel and initialize) // on kernel_ready.Kernel, a new kernel has been started and we shall initialize the extension events.on("kernel_ready.Kernel", function(evt, data) { console.log(log_prefix + "Kernel is available -- reading configuration"); mickaSearch_init(); }); }; return { load_ipython_extension: load_jupyter_extension, //varRefresh: varRefresh }; });