Skip to content

Commit 4c4e4c6

Browse files
authored
Merge pull request #1032 from jcb91/tttoc
[toc2] use amd structure to avoid polluting the global namespace
2 parents 3b74c45 + 2eb8186 commit 4c4e4c6

File tree

3 files changed

+129
-119
lines changed

3 files changed

+129
-119
lines changed

src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js

Lines changed: 78 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,34 @@
22
// by minrk https://github.com/minrk/ipython_extensions
33
// See the history of contributions in README.md
44

5-
6-
//define(["require", "jquery", "base/js/namespace", 'services/config',
7-
// 'base/js/utils', "nbextensions/toc2/toc2"], function(require, $, IPython, configmod, utils, toc2) {
8-
9-
define(["require", "jquery", "base/js/namespace", 'services/config',
10-
'base/js/utils', 'notebook/js/codecell', "nbextensions/toc2/toc2"], function(require, $, IPython, configmod, utils, codecell, toc2 ) {
11-
12-
var Notebook = require('notebook/js/notebook').Notebook
13-
"use strict";
14-
5+
define([
6+
'require',
7+
'jquery',
8+
'base/js/namespace',
9+
'services/config',
10+
'base/js/utils',
11+
'notebook/js/codecell',
12+
'./toc2'
13+
], function(
14+
require,
15+
$,
16+
IPython,
17+
configmod,
18+
utils,
19+
codecell,
20+
toc2
21+
) {
22+
"use strict";
23+
24+
// imports
25+
var highlight_toc_item = toc2.highlight_toc_item;
26+
var table_of_contents = toc2.table_of_contents;
27+
var toggle_toc = toc2.toggle_toc;
1528

1629
// ...........Parameters configuration......................
17-
// define default values for config parameters if they were not present in general settings (notebook.json)
30+
// default values for system-wide configurable parameters
1831
var cfg={'threshold':4,
19-
'number_sections':true,
20-
'toc_cell':false,
21-
'toc_window_display':false,
22-
"toc_section_display": "block",
23-
'sideBar':true,
24-
'navigate_menu':true,
32+
'navigate_menu':true,
2533
'moveMenuLeft': true,
2634
'widenNotebook': false,
2735
'colors': {
@@ -34,75 +42,74 @@ define(["require", "jquery", "base/js/namespace", 'services/config',
3442
'navigate_num': '#000000',
3543
},
3644
collapse_to_match_collapsible_headings: false,
37-
skip_h1_title: false,
3845
}
46+
// default values for per-notebook configurable parameters
47+
var metadata_settings = {
48+
nav_menu: {},
49+
number_sections: true,
50+
sideBar: true,
51+
skip_h1_title: false,
52+
toc_cell: false,
53+
toc_position: {},
54+
toc_section_display: 'block',
55+
toc_window_display: false,
56+
};
57+
// add per-notebook settings into global config object
58+
$.extend(true, cfg, metadata_settings);
3959

4060
//.....................global variables....
41-
42-
var liveNotebook = !(typeof IPython == "undefined")
43-
4461
var st={}
4562
st.rendering_toc_cell = false;
46-
st.config_loaded = false;
47-
st.extension_initialized=false;
48-
49-
st.nbcontainer_marginleft = $('#notebook-container').css('margin-left')
50-
st.nbcontainer_marginright = $('#notebook-container').css('margin-right')
51-
st.nbcontainer_width = $('#notebook-container').css('width')
5263
st.oldTocHeight = undefined
53-
5464
st.cell_toc = undefined;
5565
st.toc_index=0;
5666

57-
58-
59-
function read_config(cfg, callback) { // read after nb is loaded
60-
// create config object to load parameters
61-
var base_url = utils.get_body_data("baseUrl");
62-
var initial_cfg = $.extend(true, {}, cfg);
63-
var config = new configmod.ConfigSection('notebook', { base_url: base_url });
64-
config.loaded.then(function(){
67+
var read_config = function (cfg, callback) {
68+
IPython.notebook.config.loaded.then(function () {
6569
// config may be specified at system level or at document level.
6670
// first, update defaults with config loaded from server
67-
cfg = $.extend(true, cfg, config.data.toc2);
71+
$.extend(true, cfg, IPython.notebook.config.data.toc2);
72+
// ensure notebook metadata has toc object, cache old values
73+
var md = IPython.notebook.metadata.toc || {};
74+
// reset notebook metadata to remove old values
75+
IPython.notebook.metadata.toc = {};
6876
// then update cfg with any found in current notebook metadata
6977
// and save in nb metadata (then can be modified per document)
70-
cfg = IPython.notebook.metadata.toc = $.extend(true, cfg,
71-
IPython.notebook.metadata.toc);
72-
// excepted colors that are taken globally (if defined)
73-
cfg.colors = $.extend(true, {}, initial_cfg.colors);
74-
try
75-
{cfg.colors = IPython.notebook.metadata.toc.colors = $.extend(true, cfg.colors, config.data.toc2.colors); }
76-
catch(e) {}
77-
// and moveMenuLeft, threshold, wideNotebook, collapse_to_match_collapsible_headings taken globally (if it exists, otherwise default)
78-
cfg.moveMenuLeft = IPython.notebook.metadata.toc.moveMenuLeft = initial_cfg.moveMenuLeft;
79-
cfg.threshold = IPython.notebook.metadata.toc.threshold = initial_cfg.threshold;
80-
cfg.widenNotebook = IPython.notebook.metadata.toc.widenNotebook = initial_cfg.widenNotebook;
81-
cfg.collapse_to_match_collapsible_headings = IPython.notebook.metadata.toc.collapse_to_match_collapsible_headings = initial_cfg.collapse_to_match_collapsible_headings
82-
if (config.data.toc2) {
83-
if (typeof config.data.toc2.moveMenuLeft !== "undefined") {
84-
cfg.moveMenuLeft = IPython.notebook.metadata.toc.moveMenuLeft = config.data.toc2.moveMenuLeft;
85-
}
86-
if (typeof config.data.toc2.threshold !== "undefined") {
87-
cfg.threshold = IPython.notebook.metadata.toc.threshold = config.data.toc2.threshold;
88-
}
89-
if (typeof config.data.toc2.widenNotebook !== "undefined") {
90-
cfg.widenNotebook = IPython.notebook.metadata.toc.widenNotebook = config.data.toc2.widenNotebook;
91-
}
92-
if (typeof config.data.toc2.collapse_to_match_collapsible_headings !== "undefined") {
93-
cfg.collapse_to_match_collapsible_headings = IPython.notebook.metadata.toc.collapse_to_match_collapsible_headings = config.data.toc2.collapse_to_match_collapsible_headings;
94-
}
95-
}
96-
// create highlights style section in document
97-
create_additional_css();
98-
// call callbacks
99-
callback && callback();
100-
st.config_loaded = true;
101-
})
102-
config.load();
78+
Object.keys(metadata_settings).forEach(function (key) {
79+
cfg[key] = IPython.notebook.metadata.toc[key] = (md.hasOwnProperty(key) ? md : cfg)[key];
80+
});
81+
// create highlights style section in document
82+
create_additional_css();
83+
// call callbacks
84+
callback && callback();
85+
});
10386
return cfg;
104-
}
87+
};
10588

89+
// extra download as html with toc menu (needs IPython kernel)
90+
function addSaveAsWithToc() {
91+
if (IPython.notebook.metadata.kernelspec.language == 'python') {
92+
if ($('#save_html_with_toc').length == 0) {
93+
$('#save_checkpoint').after("<li id='save_html_with_toc'/>")
94+
$('#save_html_with_toc')
95+
.append($('<a/>').text('Save as HTML (with toc)').attr("href", "#"))
96+
.on('click', function (evt) {
97+
if (IPython.notebook.metadata.kernelspec.language == 'python') {
98+
var code = "!jupyter nbconvert '" + IPython.notebook.notebook_name + "' --template toc2";
99+
console.log('[toc2] running:', code);
100+
IPython.notebook.kernel.execute(code);
101+
}
102+
else {
103+
alert('Sorry; this only works with a IPython kernel');
104+
$('#save_html_with_toc').remove();
105+
}
106+
});
107+
}
108+
}
109+
else {
110+
$('#save_html_with_toc').remove()
111+
}
112+
}
106113

107114

108115

src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js

Lines changed: 48 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,31 @@
1-
//---------------------------------------------------------------------
2-
3-
//......... utilitary functions............
4-
5-
var liveNotebook = !(typeof IPython == "undefined")
6-
var events;
7-
if (liveNotebook) {
8-
events = require('base/js/events');
9-
}
10-
else {
11-
// in non-live notebook, there's no event structure, so we make our own
12-
if (window.events === undefined) {
13-
var Events = function () {};
14-
window.events = $([new Events()]);
1+
(require.specified('base/js/namespace') ? define : function (deps, callback) {
2+
// if here, the Jupyter namespace hasn't been specified to be loaded.
3+
// This means that we're probably embedded in a page, so we need to make
4+
// our definition with a specific module name
5+
return define('nbextensions/toc2/toc2', deps, callback);
6+
})(['jquery', 'require'], function ($, require) {
7+
"use strict";
8+
9+
var IPython;
10+
var events;
11+
var liveNotebook = false;
12+
try {
13+
// this will work in a live notebook because nbextensions & custom.js
14+
// are loaded by/after notebook.js, which requires base/js/namespace
15+
IPython = require('base/js/namespace');
16+
events = require('base/js/events');
17+
liveNotebook = true;
18+
}
19+
catch (err) {
20+
// log the error, just in case we *are* in a live notebook
21+
console.log('[toc2] working in non-live notebook:', err);
22+
// in non-live notebook, there's no event structure, so we make our own
23+
if (window.events === undefined) {
24+
var Events = function () {};
25+
window.events = $([new Events()]);
26+
}
27+
events = window.events;
1528
}
16-
events = window.events;
17-
}
18-
1929

2030
function incr_lbl(ary, h_idx) { //increment heading label w/ h_idx (zero based)
2131
ary[h_idx]++;
@@ -100,34 +110,6 @@ function highlight_toc_item(evt, data) {
100110
}
101111
}
102112

103-
104-
// extra download as html with toc menu (needs IPython kernel)
105-
function addSaveAsWithToc() {
106-
var saveAsWithToc = $('#save_html_with_toc').length == 0
107-
var IPythonKernel = IPython.notebook.metadata.kernelspec.language == "python"
108-
if (IPythonKernel) {
109-
if ($('#save_html_with_toc').length == 0) {
110-
$('#save_checkpoint').after("<li id='save_html_with_toc'/>")
111-
$('#save_html_with_toc').append($('<a/>').text('Save as HTML (with toc)').attr("href", "#"))
112-
$('#save_html_with_toc').click(function() {
113-
var IPythonKernel = IPython.notebook.metadata.kernelspec.language == "python"
114-
if (IPythonKernel) {
115-
var code = "!jupyter nbconvert '" + IPython.notebook.notebook_name + "' --template toc2"
116-
console.log(code)
117-
IPython.notebook.kernel.execute(code)
118-
} else {
119-
alert("Sorry; this only works with a IPython kernel");
120-
$('#save_html_with_toc').remove();
121-
}
122-
})
123-
}
124-
} else {
125-
if ($('#save_html_with_toc').length > 0) $('#save_html_with_toc').remove()
126-
}
127-
}
128-
129-
130-
131113
var create_navigate_menu = function(callback) {
132114
$('#kernel_menu').parent().after('<li id="Navigate"/>')
133115
$('#Navigate').addClass('dropdown').append($('<a/>').attr('href', '#').attr('id', 'Navigate_sub'))
@@ -640,8 +622,9 @@ var table_of_contents = function (cfg,st) {
640622
}
641623

642624

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

697680
};
681+
682+
return {
683+
highlight_toc_item: highlight_toc_item,
684+
table_of_contents: table_of_contents,
685+
toggle_toc: toggle_toc,
686+
};
687+
});
688+
// export table_of_contents to global namespace for backwards compatibility
689+
// Do export synchronously, so that it's defined as soon as this file is loaded
690+
if (!require.specified('base/js/namespace')) {
691+
window.table_of_contents = function (cfg, st) {
692+
// use require to ensure the module is correctly loaded before the
693+
// actual call is made
694+
require(['nbextensions/toc2/toc2'], function (toc2) {
695+
toc2.table_of_contents(cfg, st);
696+
});
697+
};
698+
}

src/jupyter_contrib_nbextensions/templates/toc2.tpl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ $( document ).ready(function(){
5050
st.toc_index=0;
5151
5252
// fire the main function with these parameters
53-
table_of_contents(cfg,st);
53+
require(['nbextensions/toc2/toc2'], function (toc2) {
54+
toc2.table_of_contents(cfg, st);
55+
});
5456
});
5557
</script>
5658

0 commit comments

Comments
 (0)