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 = ' \
| X | Name | Type | Size | ' + shape_str + 'Value |
|---|
| \
|
';
varList.forEach(listVar => {
var shape_col_str = '';
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) +
' |
';
});
var full_table = beg_table + '
';
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
};
});