Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[toc2] use amd structure to avoid polluting the global namespace #1032

Merged
merged 5 commits into from
Aug 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 78 additions & 71 deletions src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,34 @@
// by minrk https://github.com/minrk/ipython_extensions
// See the history of contributions in README.md


//define(["require", "jquery", "base/js/namespace", 'services/config',
// 'base/js/utils', "nbextensions/toc2/toc2"], function(require, $, IPython, configmod, utils, toc2) {

define(["require", "jquery", "base/js/namespace", 'services/config',
'base/js/utils', 'notebook/js/codecell', "nbextensions/toc2/toc2"], function(require, $, IPython, configmod, utils, codecell, toc2 ) {

var Notebook = require('notebook/js/notebook').Notebook
"use strict";

define([
'require',
'jquery',
'base/js/namespace',
'services/config',
'base/js/utils',
'notebook/js/codecell',
'./toc2'
], function(
require,
$,
IPython,
configmod,
utils,
codecell,
toc2
) {
"use strict";

// imports
var highlight_toc_item = toc2.highlight_toc_item;
var table_of_contents = toc2.table_of_contents;
var toggle_toc = toc2.toggle_toc;

// ...........Parameters configuration......................
// define default values for config parameters if they were not present in general settings (notebook.json)
// default values for system-wide configurable parameters
var cfg={'threshold':4,
'number_sections':true,
'toc_cell':false,
'toc_window_display':false,
"toc_section_display": "block",
'sideBar':true,
'navigate_menu':true,
'navigate_menu':true,
'moveMenuLeft': true,
'widenNotebook': false,
'colors': {
Expand All @@ -34,75 +42,74 @@ define(["require", "jquery", "base/js/namespace", 'services/config',
'navigate_num': '#000000',
},
collapse_to_match_collapsible_headings: false,
skip_h1_title: false,
}
// default values for per-notebook configurable parameters
var metadata_settings = {
nav_menu: {},
number_sections: true,
sideBar: true,
skip_h1_title: false,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that skip_1_title is a system-wide parameter.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me, it's per-notebook, as whether it makes sense depends on the notebook content?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but we have nothing to change the behavior per notebook, except directly editing the metadata.

toc_cell: false,
toc_position: {},
toc_section_display: 'block',
toc_window_display: false,
};
// add per-notebook settings into global config object
$.extend(true, cfg, metadata_settings);

//.....................global variables....

var liveNotebook = !(typeof IPython == "undefined")

var st={}
st.rendering_toc_cell = false;
st.config_loaded = false;
st.extension_initialized=false;

st.nbcontainer_marginleft = $('#notebook-container').css('margin-left')
st.nbcontainer_marginright = $('#notebook-container').css('margin-right')
st.nbcontainer_width = $('#notebook-container').css('width')
st.oldTocHeight = undefined

st.cell_toc = undefined;
st.toc_index=0;



function read_config(cfg, callback) { // read after nb is loaded
// create config object to load parameters
var base_url = utils.get_body_data("baseUrl");
var initial_cfg = $.extend(true, {}, cfg);
var config = new configmod.ConfigSection('notebook', { base_url: base_url });
config.loaded.then(function(){
var read_config = function (cfg, callback) {
IPython.notebook.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.toc2);
$.extend(true, cfg, IPython.notebook.config.data.toc2);
// ensure notebook metadata has toc object, cache old values
var md = IPython.notebook.metadata.toc || {};
// reset notebook metadata to remove old values
IPython.notebook.metadata.toc = {};
// then update cfg with any found in current notebook metadata
// and save in nb metadata (then can be modified per document)
cfg = IPython.notebook.metadata.toc = $.extend(true, cfg,
IPython.notebook.metadata.toc);
// excepted colors that are taken globally (if defined)
cfg.colors = $.extend(true, {}, initial_cfg.colors);
try
{cfg.colors = IPython.notebook.metadata.toc.colors = $.extend(true, cfg.colors, config.data.toc2.colors); }
catch(e) {}
// and moveMenuLeft, threshold, wideNotebook, collapse_to_match_collapsible_headings taken globally (if it exists, otherwise default)
cfg.moveMenuLeft = IPython.notebook.metadata.toc.moveMenuLeft = initial_cfg.moveMenuLeft;
cfg.threshold = IPython.notebook.metadata.toc.threshold = initial_cfg.threshold;
cfg.widenNotebook = IPython.notebook.metadata.toc.widenNotebook = initial_cfg.widenNotebook;
cfg.collapse_to_match_collapsible_headings = IPython.notebook.metadata.toc.collapse_to_match_collapsible_headings = initial_cfg.collapse_to_match_collapsible_headings
if (config.data.toc2) {
if (typeof config.data.toc2.moveMenuLeft !== "undefined") {
cfg.moveMenuLeft = IPython.notebook.metadata.toc.moveMenuLeft = config.data.toc2.moveMenuLeft;
}
if (typeof config.data.toc2.threshold !== "undefined") {
cfg.threshold = IPython.notebook.metadata.toc.threshold = config.data.toc2.threshold;
}
if (typeof config.data.toc2.widenNotebook !== "undefined") {
cfg.widenNotebook = IPython.notebook.metadata.toc.widenNotebook = config.data.toc2.widenNotebook;
}
if (typeof config.data.toc2.collapse_to_match_collapsible_headings !== "undefined") {
cfg.collapse_to_match_collapsible_headings = IPython.notebook.metadata.toc.collapse_to_match_collapsible_headings = config.data.toc2.collapse_to_match_collapsible_headings;
}
}
// create highlights style section in document
create_additional_css();
// call callbacks
callback && callback();
st.config_loaded = true;
})
config.load();
Object.keys(metadata_settings).forEach(function (key) {
cfg[key] = IPython.notebook.metadata.toc[key] = (md.hasOwnProperty(key) ? md : cfg)[key];
});
// create highlights style section in document
create_additional_css();
// call callbacks
callback && callback();
});
return cfg;
}
};

// extra download as html with toc menu (needs IPython kernel)
function addSaveAsWithToc() {
if (IPython.notebook.metadata.kernelspec.language == 'python') {
if ($('#save_html_with_toc').length == 0) {
$('#save_checkpoint').after("<li id='save_html_with_toc'/>")
$('#save_html_with_toc')
.append($('<a/>').text('Save as HTML (with toc)').attr("href", "#"))
.on('click', function (evt) {
if (IPython.notebook.metadata.kernelspec.language == 'python') {
var code = "!jupyter nbconvert '" + IPython.notebook.notebook_name + "' --template toc2";
console.log('[toc2] running:', code);
IPython.notebook.kernel.execute(code);
}
else {
alert('Sorry; this only works with a IPython kernel');
$('#save_html_with_toc').remove();
}
});
}
}
else {
$('#save_html_with_toc').remove()
}
}



Expand Down
95 changes: 48 additions & 47 deletions src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
//---------------------------------------------------------------------

//......... utilitary functions............

var liveNotebook = !(typeof IPython == "undefined")
var events;
if (liveNotebook) {
events = require('base/js/events');
}
else {
// in non-live notebook, there's no event structure, so we make our own
if (window.events === undefined) {
var Events = function () {};
window.events = $([new Events()]);
(require.specified('base/js/namespace') ? define : function (deps, callback) {
// if here, the Jupyter namespace hasn't been specified to be loaded.
// This means that we're probably embedded in a page, so we need to make
// our definition with a specific module name
return define('nbextensions/toc2/toc2', deps, callback);
})(['jquery', 'require'], function ($, require) {
"use strict";

var IPython;
var events;
var liveNotebook = false;
try {
// this will work in a live notebook because nbextensions & custom.js
// are loaded by/after notebook.js, which requires base/js/namespace
IPython = require('base/js/namespace');
events = require('base/js/events');
liveNotebook = true;
}
catch (err) {
// log the error, just in case we *are* in a live notebook
console.log('[toc2] working in non-live notebook:', err);
// in non-live notebook, there's no event structure, so we make our own
if (window.events === undefined) {
var Events = function () {};
window.events = $([new Events()]);
}
events = window.events;
}
events = window.events;
}


function incr_lbl(ary, h_idx) { //increment heading label w/ h_idx (zero based)
ary[h_idx]++;
Expand Down Expand Up @@ -100,34 +110,6 @@ function highlight_toc_item(evt, data) {
}
}


// extra download as html with toc menu (needs IPython kernel)
function addSaveAsWithToc() {
var saveAsWithToc = $('#save_html_with_toc').length == 0
var IPythonKernel = IPython.notebook.metadata.kernelspec.language == "python"
if (IPythonKernel) {
if ($('#save_html_with_toc').length == 0) {
$('#save_checkpoint').after("<li id='save_html_with_toc'/>")
$('#save_html_with_toc').append($('<a/>').text('Save as HTML (with toc)').attr("href", "#"))
$('#save_html_with_toc').click(function() {
var IPythonKernel = IPython.notebook.metadata.kernelspec.language == "python"
if (IPythonKernel) {
var code = "!jupyter nbconvert '" + IPython.notebook.notebook_name + "' --template toc2"
console.log(code)
IPython.notebook.kernel.execute(code)
} else {
alert("Sorry; this only works with a IPython kernel");
$('#save_html_with_toc').remove();
}
})
}
} else {
if ($('#save_html_with_toc').length > 0) $('#save_html_with_toc').remove()
}
}



var create_navigate_menu = function(callback) {
$('#kernel_menu').parent().after('<li id="Navigate"/>')
$('#Navigate').addClass('dropdown').append($('<a/>').attr('href', '#').attr('id', 'Navigate_sub'))
Expand Down Expand Up @@ -640,8 +622,9 @@ var table_of_contents = function (cfg,st) {
}



if (cfg.toc_cell) {
// check for st.cell_toc because we may have a non-live notebook where
// metadata says to use cell_toc, but the actual cell's been removed
if (cfg.toc_cell && st.cell_toc) {
st.rendering_toc_cell = true;
st.cell_toc.set_text(
cell_toc_text +
Expand Down Expand Up @@ -695,3 +678,21 @@ var table_of_contents = function (cfg,st) {
});

};

return {
highlight_toc_item: highlight_toc_item,
table_of_contents: table_of_contents,
toggle_toc: toggle_toc,
};
});
// export table_of_contents to global namespace for backwards compatibility
// Do export synchronously, so that it's defined as soon as this file is loaded
if (!require.specified('base/js/namespace')) {
window.table_of_contents = function (cfg, st) {
// use require to ensure the module is correctly loaded before the
// actual call is made
require(['nbextensions/toc2/toc2'], function (toc2) {
toc2.table_of_contents(cfg, st);
});
};
}
4 changes: 3 additions & 1 deletion src/jupyter_contrib_nbextensions/templates/toc2.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ $( document ).ready(function(){
st.toc_index=0;

// fire the main function with these parameters
table_of_contents(cfg,st);
require(['nbextensions/toc2/toc2'], function (toc2) {
toc2.table_of_contents(cfg, st);
});
});
</script>

Expand Down