From 591585b328e9b9e19a0d444721cab8395a945942 Mon Sep 17 00:00:00 2001 From: Josh Barnes Date: Sat, 22 Jul 2017 23:13:23 +0100 Subject: [PATCH 01/15] [toc2] allow collapsing toc items in the sidebar also remove redundant css for hovering over items so they don't flicker :/ --- .../nbextensions/toc2/main.css | 8 +++++++- .../nbextensions/toc2/main.js | 2 +- .../nbextensions/toc2/toc2.js | 10 ++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.css b/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.css index 5eda4e554..7508791ea 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.css +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.css @@ -4,7 +4,9 @@ /*background color for links when you mouse over it This style is used on export, but can be overwritted in the livenotebook by selecting a color in the nbextension-configurator*/ -#toc-level0 li > a:hover { display: block; background-color: #DAA520} +#toc-wrapper li > a:hover { + background-color: #DAA520; +} #toc-level0 a { /*color: #333333;*/ /* now specified in js */ @@ -175,3 +177,7 @@ and updated using the nbextension-configurator .lev6 {margin-left: 180px} .lev7 {margin-left: 200px} .lev8 {margin-left: 220px} + +.toc-item .fa-fw:first-child { + cursor: pointer; +} diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js b/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js index ec9827fbc..5c4eeb268 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js @@ -137,7 +137,7 @@ define(["require", "jquery", "base/js/namespace", 'services/config', function create_additional_css() { var sheet = document.createElement('style') - sheet.innerHTML = "#toc-level0 li > a:hover { display: block; background-color: " + cfg.colors.hover_highlight + " }\n" + + sheet.innerHTML = "#toc-level0 li > a:hover { background-color: " + cfg.colors.hover_highlight + " }\n" + ".toc-item-highlight-select {background-color: " + cfg.colors.selected_highlight + "}\n" + ".toc-item-highlight-execute {background-color: " + cfg.colors.running_highlight + "}\n" + ".toc-item-highlight-execute.toc-item-highlight-select {background-color: " + cfg.colors.selected_highlight + "}" diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js b/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js index ef476b9ae..75e8b407b 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js @@ -529,6 +529,12 @@ var table_of_contents = function (cfg,st) { process_cell_toc(cfg,st); } //process_cell_toc(); + + var callback_collapser = function (evt) { + var clicked_i = $(evt.currentTarget).toggleClass('fa-caret-right fa-caret-down'); + var show = clicked_i.hasClass('fa-caret-down'); + clicked_i.siblings('ul')[show ? 'slideDown' : 'slideUp']('fast'); + }; var cell_toc_text = "# Table of Contents\n

"; var depth = 1; //var depth = ol_depth(ol); @@ -585,6 +591,10 @@ var table_of_contents = function (cfg,st) { // Create toc entry, append

  • tag to the current
      . Prepend numbered-labels to headings. li=$("
    1. ").append( make_link( $(h), num_lbl)); + $('') + .addClass('fa fa-fw fa-caret-down') + .on('click', callback_collapser) + .prependTo(li); ul.append(li); $(h).prepend(num_lbl); From 76f78df5b191b154fbd0a1866d6077ffd17efb93 Mon Sep 17 00:00:00 2001 From: Josh Barnes Date: Sun, 23 Jul 2017 01:40:16 +0100 Subject: [PATCH 02/15] [toc2] simplify toc link generation, allowing collapsing toc cell links also: * rework toc link highlighting to work with new-form ids * remove collapsible_headings' now-redundant toc click handler, since toc's own handler selects the cell, which is enough to get ch to reveal it --- .../nbextensions/collapsible_headings/main.js | 29 --- .../nbextensions/toc2/main.css | 26 ++- .../nbextensions/toc2/toc2.js | 174 ++++++++---------- 3 files changed, 85 insertions(+), 144 deletions(-) diff --git a/src/jupyter_contrib_nbextensions/nbextensions/collapsible_headings/main.js b/src/jupyter_contrib_nbextensions/nbextensions/collapsible_headings/main.js index d7b459e9a..cb40d71f1 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/collapsible_headings/main.js +++ b/src/jupyter_contrib_nbextensions/nbextensions/collapsible_headings/main.js @@ -748,31 +748,6 @@ define(['jquery', 'require'], function ($, require) { Jupyter.notebook.edit_mode(); } - function toc2_callback (evt) { - // evt.target is what was clicked, not what the handler was attached to - var toc_link = $(evt.target).closest('a'); - var href = toc_link.attr('href'); - href = href.slice(href.indexOf('#') + 1); // remove # - // for toc2's cell-toc links, we use the data-toc-modified-id attr - var toc_mod_href = toc_link.attr('data-toc-modified-id'); - - // jquery doesn't cope with $(href) or $('a[href=' + href + ']') - // if href contains periods or other unusual characters - var $anchor = $(document.getElementById(toc_mod_href)); - if ($anchor.length < 1) { - // we didn't find the toc-modified id, so use the regular id - $anchor = $(document.getElementById(href)); - } - if ($anchor.length < 1) { - return; - } - var cell_index = $anchor.closest('.cell').index(); - - reveal_cell_by_index(cell_index); - // scroll link into view once animation is complete - setTimeout(function () { imitate_hash_click($anchor); }, 400); - } - function refresh_all_headings () { var cells = _get_cells(); for (var ii=0; ii < cells.length; ii++) { @@ -930,10 +905,6 @@ define(['jquery', 'require'], function ($, require) { }) .appendTo('head'); - // register toc2 callback - see - // https://github.com/ipython-contrib/jupyter_contrib_nbextensions/issues/609 - $(document).on('click', '.toc-item a', toc2_callback); - // ensure Jupyter module is defined before proceeding further new Promise(function (resolve, reject) { require(['base/js/namespace'], function (Jupyter_mod) { diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.css b/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.css index 7508791ea..433b13105 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.css +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.css @@ -67,7 +67,7 @@ padding-left: 20px; display: block; } -#toc ul.toc-item { +.toc ul.toc-item { list-style-type: none; padding: 0; margin: 0; @@ -144,18 +144,19 @@ padding-left: 20px; /* don't waste so much screen space... */ -#toc-wrapper .toc-item{ - padding-left: 20px; -} -#toc-wrapper .toc-item .toc-item{ - padding-left: 10px; +.toc .toc-item .toc-item { + padding-left: 1em; } .toc-item-num { font-style: normal; } +.toc-item-num:after { + content: "\00a0\00a0"; +} + #toc-wrapper .toc-item-num { font-style: normal; font-family: Georgia, Times New Roman, Times, serif; @@ -169,15 +170,10 @@ and updated using the nbextension-configurator .toc-item-highlight-execute {background-color: red} .toc-item-highlight-execute.toc-item-highlight-select {background-color: Gold} */ -.lev1 {margin-left: 80px} -.lev2 {margin-left: 100px} -.lev3 {margin-left: 120px} -.lev4 {margin-left: 140px} -.lev5 {margin-left: 160px} -.lev6 {margin-left: 180px} -.lev7 {margin-left: 200px} -.lev8 {margin-left: 220px} - .toc-item .fa-fw:first-child { cursor: pointer; } + +.text_cell .toc { + margin-top: 1em; +} \ No newline at end of file diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js b/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js index 75e8b407b..0ea464fbc 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js @@ -11,6 +11,7 @@ function incr_lbl(ary, h_idx) { //increment heading label w/ h_idx (zero based) } function removeMathJaxPreview(elt) { + elt.children('.anchor-link, .toc-mod-link').remove(); elt.find("script[type='math/tex']").each( function(i, e) { $(e).replaceWith('$' + $(e).text() + '$') @@ -20,48 +21,36 @@ function removeMathJaxPreview(elt) { return elt } + var callback_toc_link_click = function (evt) { + // workaround for https://github.com/jupyter/notebook/issues/699 + setTimeout(function() { $.ajax() }, 100); + evt.preventDefault(); + var trg_id = $(evt.currentTarget).attr('data-toc-modified-id'); + // use browser's native click method with semi-unique id + $('').attr('href', '#' + trg_id)[0].click(); + if (liveNotebook) { + // use native document method as jquery won't cope with characters + // like . in an id + var cell = $(document.getElementById(trg_id)).closest('.cell').data('cell'); + Jupyter.notebook.select(Jupyter.notebook.find_cell_index(cell)); + highlight_toc_item("toc_link_click", {cell: cell}); + } + }; -var make_link = function(h, num_lbl) { - var a = $(""); - a.attr("href", '#' + h.attr('id')); +var make_link = function (h, toc_mod_id) { + var a = $('') + .attr({ + 'href': h.find('.anchor-link').attr('href'), + 'data-toc-modified-id': toc_mod_id, + }); // get the text *excluding* the link text, whatever it may be var hclone = h.clone(); hclone = removeMathJaxPreview(hclone); - if (num_lbl) { hclone.prepend(num_lbl); } - hclone.children().last().remove(); // remove the last child (that is the automatic anchor) - hclone.find("a[name]").remove(); //remove all named anchors a.html(hclone.html()); - a.on('click', function() { - setTimeout(function() { $.ajax() }, 100); //workaround for https://github.com/jupyter/notebook/issues/699 - if (liveNotebook) { - IPython.notebook.get_selected_cell().unselect(); //unselect current cell - var new_selected_cell = $("[id='" + h.attr('id') + "']").parents('.unselected').switchClass('unselected', 'selected') - new_selected_cell.data('cell').selected = true; - var cell = new_selected_cell.data('cell') // IPython.notebook.get_selected_cell() - highlight_toc_item("toc_link_click", {cell: cell}) - } - }) + a.on('click', callback_toc_link_click); return a; }; - - var make_link_originalid = function(h, num_lbl) { - var a = $(""); - a.attr("href", '#' + h.attr('saveid')); - // add a data attribute so that other code (e.g. collapsible_headings) can use it - a.attr('data-toc-modified-id', h.attr('id')); - // get the text *excluding* the link text, whatever it may be - var hclone = h.clone(); - hclone = removeMathJaxPreview(hclone); - if (num_lbl) { hclone.prepend(num_lbl); } - hclone.children().last().remove(); // remove the last child (that is the automatic anchor) - hclone.find("a[name]").remove(); //remove all named anchors - a.html(hclone.html()); - a.on('click', function() { setTimeout(function() { $.ajax() }, 100) }) //workaround for https://github.com/jupyter/notebook/issues/699 - return a; - } - - var ol_depth = function (element) { // get depth of nested ol var d = 0; @@ -72,29 +61,29 @@ var make_link = function(h, num_lbl) { return d; }; - - function highlight_toc_item(evt, data) { - var c = data.cell.element; // - if (c) { - var ll = $(c).find(':header') - if (ll.length == 0) { - var ll = $(c).prevAll().find(':header') - } - var elt = ll[ll.length - 1] - if (elt) { - var highlighted_item = $(toc).find('a[href="#' + elt.id + '"]') - if (evt.type == "execute") { - // remove the selected class and add execute class - // il the cell is selected again, it will be highligted as selected+running - highlighted_item.removeClass('toc-item-highlight-select').addClass('toc-item-highlight-execute') - //console.log("->>> highlighted_item class",highlighted_item.attr('class')) - } else { - $(toc).find('.toc-item-highlight-select').removeClass('toc-item-highlight-select') - highlighted_item.addClass('toc-item-highlight-select') - } - } - } - } +function highlight_toc_item(evt, data) { + var c = $(data.cell.element); + if (c.length < 1) { + return; + } + var trg_id = c.find('.toc-mod-link').attr('id') || + c.prevAll().find('.toc-mod-link').eq(-1).attr('id'); + var highlighted_item = $(); + if (trg_id !== undefined) { + highlighted_item = $('.toc a').filter(function (idx, elt) { + return $(elt).attr('data-toc-modified-id') === trg_id; + }); + } + if (evt.type === 'execute') { + // remove the selected class and add execute class + // if the cell is selected again, it will be highligted as selected+running + highlighted_item.removeClass('toc-item-highlight-select').addClass('toc-item-highlight-execute'); + } + else { + $('.toc .toc-item-highlight-select').removeClass('toc-item-highlight-select'); + highlighted_item.addClass('toc-item-highlight-select'); + } +} // extra download as html with toc menu (needs IPython kernel) @@ -535,8 +524,7 @@ var table_of_contents = function (cfg,st) { var show = clicked_i.hasClass('fa-caret-down'); clicked_i.siblings('ul')[show ? 'slideDown' : 'slideUp']('fast'); }; - - var cell_toc_text = "# Table of Contents\n

      "; + var depth = 1; //var depth = ol_depth(ol); var li= ul;//yes, initialize li with ul! var all_headers= $("#notebook").find(":header"); @@ -553,11 +541,17 @@ var table_of_contents = function (cfg,st) { if (!h.id){ return; } // skip toc cell if present if (h.id=="Table-of-Contents"){ return; } - //If h had already a number, remove it - $(h).find(".toc-item-num").remove(); - var num_str= incr_lbl(lbl_ary,level-1).join('.');// numbered heading labels - var num_lbl= $("").addClass("toc-item-num") - .text(num_str).append(' ').append(' '); + + h = $(h); + h.children('.toc-item-num').remove(); // remove pre-existing number + // numbered heading labels + var num_str = incr_lbl(lbl_ary, level - 1).join('.'); + if (cfg.number_sections) { + $('') + .text(num_str) + .addClass('toc-item-num') + .prependTo(h); + } // walk down levels for(var elm=li; depth < level; depth++) { @@ -571,46 +565,23 @@ var table_of_contents = function (cfg,st) { ul= ul.parent(); while(!ul.is('ul')){ ul= ul.parent(); } } - // Change link id -- append current num_str so as to get a kind of unique anchor - // A drawback of this approach is that anchors are subject to change and thus external links can fail if toc changes - // Anyway, one can always add a in the heading and refer to that anchor, eg [link](#myanchor) - // This anchor is automatically removed when building toc links. The original id is also preserved and an anchor is created - // using it. - // Finally a heading line can be linked to by [link](#initialID), or [link](#initialID-num_str) or [link](#myanchor) - h.id = h.id.replace(/\$/g,'').replace('\\','') - if (!$(h).attr("saveid")) {$(h).attr("saveid", h.id)} //save original id - h.id=$(h).attr("saveid")+'-'+num_str.replace(/\./g,''); - // change the id to be "unique" and toc links to it - // (and replace '.' with '' in num_str since it poses some pb with jquery) - var saveid = $(h).attr('saveid') - //escape special chars: http://stackoverflow.com/questions/3115150/ - var saveid_search=saveid.replace(/[-[\]{}():\/!;&@=$£%§<>%"'*+?.,~\\^$|#\s]/g, "\\$&"); - if ($(h).find("a[name="+saveid_search+"]").length==0){ //add an anchor with original id (if it doesnt't already exists) - $(h).prepend($("").attr("name",saveid)); } + var toc_mod_id = h.attr('id') + '-' + num_str; + h.attr('data-toc-modified-id', toc_mod_id); + // add an anchor with modified id (if it doesn't already exist) + h.children('.toc-mod-link').remove(); + $('').addClass('toc-mod-link').attr('id', toc_mod_id).prependTo(h); - // Create toc entry, append

    2. tag to the current
        . Prepend numbered-labels to headings. - li=$("
      1. ").append( make_link( $(h), num_lbl)); + // Create toc entry, append
      2. tag to the current
          . + li = $('
        1. ').append(make_link(h, toc_mod_id)); $('') .addClass('fa fa-fw fa-caret-down') .on('click', callback_collapser) .prependTo(li); ul.append(li); - $(h).prepend(num_lbl); - - - //toc_cell: - if(cfg.toc_cell) { - var leves = '
          '; - var lnk=make_link_originalid($(h)) - cell_toc_text += leves + $('

          ').append(lnk).html()+'

          '; - //workaround for https://github.com/jupyter/notebook/issues/699 as suggested by @jhamrick - lnk.on('click',function(){setTimeout(function(){$.ajax()}, 100) }) - } - }); - + }); // update navigation menu if (cfg.navigate_menu) { @@ -631,14 +602,17 @@ var table_of_contents = function (cfg,st) { if(cfg.toc_cell) { st.rendering_toc_cell = true; - //IPython.notebook.to_markdown(toc_index); - st.cell_toc.set_text(cell_toc_text); + st.cell_toc.set_text( + '# Table of Contents\n\n
          ' + + $('#toc').html() + + '
          ' + ); st.cell_toc.render(); + var lis = st.cell_toc.element.find('.toc-item li'); + lis.find('a').on('click', callback_toc_link_click); + lis.find('i').on('click', callback_collapser); }; - // Show section numbers if enabled - cfg.number_sections ? $('.toc-item-num').show() : $('.toc-item-num').hide() - $(window).resize(function(){ $('#toc').css({maxHeight: $(window).height() - 30}); $('#toc-wrapper').css({maxHeight: $(window).height() - 10}); From c7551b6c5ca03e4d654e07ea9c5c0cc6d611bcc2 Mon Sep 17 00:00:00 2001 From: Josh Barnes Date: Sun, 23 Jul 2017 23:45:30 +0100 Subject: [PATCH 03/15] [toc2] adjust styling to suit saving as html * add collapse controls after writing toc cell html, so they don't show up as useless in html saveas page * explicitly write spacing for number labels, so the html doesn't need css file to add it as a :before pseudoelement * write toc cell heading margin as a per-element css rule, so html doesn't need css file * fix removal of execute highlight class --- .../nbextensions/toc2/main.css | 8 -------- .../nbextensions/toc2/main.js | 2 +- .../nbextensions/toc2/toc2.js | 19 ++++++++++--------- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.css b/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.css index 433b13105..c6bae45bb 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.css +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.css @@ -153,10 +153,6 @@ padding-left: 20px; font-style: normal; } -.toc-item-num:after { - content: "\00a0\00a0"; -} - #toc-wrapper .toc-item-num { font-style: normal; font-family: Georgia, Times New Roman, Times, serif; @@ -173,7 +169,3 @@ and updated using the nbextension-configurator .toc-item .fa-fw:first-child { cursor: pointer; } - -.text_cell .toc { - margin-top: 1em; -} \ No newline at end of file diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js b/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js index 5c4eeb268..da0cf8f05 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js @@ -167,7 +167,7 @@ define(["require", "jquery", "base/js/namespace", 'services/config', callbacks.shell.reply = function(msg) { if (msg.msg_type === 'execute_reply') { setTimeout(function(){ - $(toc).find('.toc-item-highlight-execute').removeClass('toc-item-highlight-execute') + $('.toc .toc-item-highlight-execute').removeClass('toc-item-highlight-execute'); rehighlight_running_cells() // re-highlight running cells }, 100); var c = IPython.notebook.get_selected_cell(); diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js b/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js index 0ea464fbc..12cbe0b93 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js @@ -548,7 +548,7 @@ var table_of_contents = function (cfg,st) { var num_str = incr_lbl(lbl_ary, level - 1).join('.'); if (cfg.number_sections) { $('') - .text(num_str) + .text(num_str + '\u00a0\u00a0') .addClass('toc-item-num') .prependTo(h); } @@ -574,13 +574,7 @@ var table_of_contents = function (cfg,st) { // Create toc entry, append
        2. tag to the current
            . li = $('
          1. ').append(make_link(h, toc_mod_id)); - $('') - .addClass('fa fa-fw fa-caret-down') - .on('click', callback_collapser) - .prependTo(li); - ul.append(li); - }); // update navigation menu @@ -600,10 +594,11 @@ var table_of_contents = function (cfg,st) { - if(cfg.toc_cell) { + if (cfg.toc_cell) { st.rendering_toc_cell = true; st.cell_toc.set_text( - '# Table of Contents\n\n
            ' + + '# Table of Contents\n' + + '
            ' + $('#toc').html() + '
            ' ); @@ -613,6 +608,12 @@ var table_of_contents = function (cfg,st) { lis.find('i').on('click', callback_collapser); }; + // add collapse controls + $('') + .addClass('fa fa-fw fa-caret-down') + .on('click', callback_collapser) + .prependTo('.toc li'); + $(window).resize(function(){ $('#toc').css({maxHeight: $(window).height() - 30}); $('#toc-wrapper').css({maxHeight: $(window).height() - 10}); From a4aa82ff0d8b97f59e4aecb0b2064bf050d4de77 Mon Sep 17 00:00:00 2001 From: Josh Barnes Date: Mon, 24 Jul 2017 00:11:31 +0100 Subject: [PATCH 04/15] [toc2] adjust section collapser callback to keep cell & sidebar in sync --- .../nbextensions/toc2/toc2.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js b/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js index 12cbe0b93..c3300fe13 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js @@ -520,9 +520,16 @@ var table_of_contents = function (cfg,st) { //process_cell_toc(); var callback_collapser = function (evt) { - var clicked_i = $(evt.currentTarget).toggleClass('fa-caret-right fa-caret-down'); - var show = clicked_i.hasClass('fa-caret-down'); - clicked_i.siblings('ul')[show ? 'slideDown' : 'slideUp']('fast'); + var clicked_i = $(evt.currentTarget); + var trg_id = clicked_i.siblings('a').attr('data-toc-modified-id'); + var anchors = $('.toc .toc-item > li > a').filter(function (idx, elt) { + return $(elt).attr('data-toc-modified-id') === trg_id; + }); + var show = clicked_i.hasClass('fa-caret-right'); + anchors.siblings('i') + .toggleClass('fa-caret-right', !show) + .toggleClass('fa-caret-down', show); + anchors.siblings('ul')[show ? 'slideDown' : 'slideUp']('fast'); }; var depth = 1; //var depth = ol_depth(ol); @@ -603,9 +610,7 @@ var table_of_contents = function (cfg,st) { '
            ' ); st.cell_toc.render(); - var lis = st.cell_toc.element.find('.toc-item li'); - lis.find('a').on('click', callback_toc_link_click); - lis.find('i').on('click', callback_collapser); + st.cell_toc.element.find('.toc-item li a').on('click', callback_toc_link_click); }; // add collapse controls From 599e92c9afe9d4bd20e4cab1bc8a0e0aa002c3e2 Mon Sep 17 00:00:00 2001 From: Josh Barnes Date: Mon, 24 Jul 2017 02:22:51 +0100 Subject: [PATCH 05/15] [toc2] remove redundant css classes from toc2.tpl --- src/jupyter_contrib_nbextensions/templates/toc2.tpl | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/jupyter_contrib_nbextensions/templates/toc2.tpl b/src/jupyter_contrib_nbextensions/templates/toc2.tpl index 85ac4f53a..a9eedc674 100644 --- a/src/jupyter_contrib_nbextensions/templates/toc2.tpl +++ b/src/jupyter_contrib_nbextensions/templates/toc2.tpl @@ -9,15 +9,6 @@ - - From 3d5c84f77ee33ca60c89e08e47b3bbad37f73067 Mon Sep 17 00:00:00 2001 From: Josh Barnes Date: Thu, 27 Jul 2017 14:44:00 +0100 Subject: [PATCH 06/15] [toc2, collapsible_headings] optional sync of collapsed sections we pass new events, either through Jupyter's events object, or in a non-live notebook, through an ojbect at `window.events`, which we create if necessary. --- .../collapsible_headings.yaml | 8 ++++ .../nbextensions/collapsible_headings/main.js | 31 ++++++++++++++- .../collapsible_headings/readme.md | 1 + .../nbextensions/toc2/README.md | 1 + .../nbextensions/toc2/main.js | 4 +- .../nbextensions/toc2/toc2.js | 38 +++++++++++++++++++ .../nbextensions/toc2/toc2.yaml | 9 +++++ 7 files changed, 89 insertions(+), 3 deletions(-) diff --git a/src/jupyter_contrib_nbextensions/nbextensions/collapsible_headings/collapsible_headings.yaml b/src/jupyter_contrib_nbextensions/nbextensions/collapsible_headings/collapsible_headings.yaml index 74bcd76e2..b793a6f0f 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/collapsible_headings/collapsible_headings.yaml +++ b/src/jupyter_contrib_nbextensions/nbextensions/collapsible_headings/collapsible_headings.yaml @@ -78,3 +78,11 @@ Parameters: description: "By default, selecting a whole section also expands the section to reveal its last cell. Set this option to false to disable the expansion." input_type: checkbox default: true + +- name: collapsible_headings.collapse_to_match_toc + description: | + Collapse/uncollapse notebook sections when the ToC2 nbextension is used to + collapse/uncollapse sections in the table of contents. For the inverse + behaviour, see ToC2's configuration + input_type: checkbox + default: false diff --git a/src/jupyter_contrib_nbextensions/nbextensions/collapsible_headings/main.js b/src/jupyter_contrib_nbextensions/nbextensions/collapsible_headings/main.js index cb40d71f1..1eb943dae 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/collapsible_headings/main.js +++ b/src/jupyter_contrib_nbextensions/nbextensions/collapsible_headings/main.js @@ -33,7 +33,8 @@ define(['jquery', 'require'], function ($, require) { show_section_brackets : false, section_bracket_width : 10, show_ellipsis : true, - select_reveals : true + select_reveals : true, + collapse_to_match_toc: false, }; // ------------------------------------------------------------------------ @@ -42,6 +43,21 @@ define(['jquery', 'require'], function ($, require) { // It is declared here to allow us to keep logic for live/nonlive functions // together. var Jupyter; + // similarly, in a live notebook, events is the Jupyter global events + // object, but in a non-live notebook, we must construct our own version + var events; + try { + events = require('base/js/events'); + } + catch (err) { + // in non-live notebook, there's no events structure, so we make our own + if (window.events === undefined) { + var Events = function () {}; + window.events = $([new Events()]); + } + events = window.events; + } + // global flag denoting whether we're in a live notebook or exported html. // In a live notebook we operate on Cell instances, in exported html we // operate on jQuery collections of '.cell' elements @@ -473,7 +489,7 @@ define(['jquery', 'require'], function ($, require) { * * @param {Object} cell Cell instance or jQuery collection of '.cell' elements */ - function toggle_heading (cell, set_collapsed) { + function toggle_heading (cell, set_collapsed, trigger_event) { if (is_heading(cell)) { if (set_collapsed === undefined) { set_collapsed = !_is_collapsed(cell); @@ -482,6 +498,9 @@ define(['jquery', 'require'], function ($, require) { update_heading_cell_status(cell); update_collapsed_headings(params.show_section_brackets ? undefined : cell); console.log(log_prefix, set_collapsed ? 'collapsed' : 'expanded', 'cell', _find_cell_index(cell)); + if (trigger_event !== false) { + events.trigger((set_collapsed ? '' : 'un') + 'collapse.CollapsibleHeading', {cell: cell}); + } } } @@ -759,6 +778,9 @@ define(['jquery', 'require'], function ($, require) { function set_collapsible_headings_options (options) { // options may be undefined here, but it's still handled ok by $.extend $.extend(true, params, options); + // bind/unbind toc-collapse handler + events[params.collapse_to_match_toc ? 'on' : 'off']('collapse.Toc uncollapse.Toc', callback_toc_collapse); + return params; } function add_buttons_and_shortcuts () { @@ -801,6 +823,11 @@ define(['jquery', 'require'], function ($, require) { } } + var callback_toc_collapse = function (evt, data) { + // use trigger_event false to avoid re-triggering toc2 + toggle_heading(data.cell, evt.type.indexOf('un') < 0, false); + } + /** * Return a promise which resolves once event handlers have been bound * diff --git a/src/jupyter_contrib_nbextensions/nbextensions/collapsible_headings/readme.md b/src/jupyter_contrib_nbextensions/nbextensions/collapsible_headings/readme.md index 835546222..8804050ad 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/collapsible_headings/readme.md +++ b/src/jupyter_contrib_nbextensions/nbextensions/collapsible_headings/readme.md @@ -38,6 +38,7 @@ the nbextensions config page: indicating hidden content (disabled by default) * A toolbar button to collapse the nearest heading to the curently selected cell (disabled by default) +* Collapse/uncollapse sections when ToC2 sections are collapsed/uncollapsed css diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/README.md b/src/jupyter_contrib_nbextensions/nbextensions/toc2/README.md index f65acf1a4..e65b16967 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/README.md +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/README.md @@ -31,6 +31,7 @@ The initial configuration can be given using the IPython-contrib nbextensions fa - Moving header title and menus on the left (default: true) - Customization of highlighting the title of currently selected/running sections. - Customization of background, fonts, border and highlighting colors in the toc window and navigation menus (as third demo). +- Collapse/uncollapse ToC2 sections when collapsible_headings is used to collapse/uncollapse notebook sections (default: false). The differents states and position of the floating window have reasonable defaults and can be modfied per notebook). diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js b/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js index da0cf8f05..ab4d2d5b3 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js @@ -32,7 +32,8 @@ define(["require", "jquery", "base/js/namespace", 'services/config', 'sidebar_border': '#EEEEEE', 'navigate_text': '#333333', 'navigate_num': '#000000', - } + }, + collapse_to_match_collapsible_headings: false, } //.....................global variables.... @@ -209,6 +210,7 @@ define(["require", "jquery", "base/js/namespace", 'services/config', $([IPython.events]).on("kernel_ready.Kernel", function() { addSaveAsWithToc(); }) + // add a save as HTML with toc included addSaveAsWithToc(); // diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js b/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js index c3300fe13..f5fd06d65 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js @@ -3,6 +3,19 @@ //......... 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()]); + } + events = window.events; +} + function incr_lbl(ary, h_idx) { //increment heading label w/ h_idx (zero based) ary[h_idx]++; @@ -490,6 +503,15 @@ function highlight_toc_item(evt, data) { } } //end function process_cell_toc -------------------------- + var callback_toc2_collapsible_headings = function (evt, data) { + var trg_id = data.cell.element.find(':header').filter(function (idx, elt) { + return Boolean($(elt).attr('data-toc-modified-id')); + }).attr('data-toc-modified-id'); + var show = evt.type.indexOf('un') >= 0; + // use trigger_event false to avoid re-triggering collapsible_headings + collapse_by_id(trg_id, show, false); + }; + // Table of Contents ================================================================= var table_of_contents = function (cfg,st) { @@ -526,10 +548,22 @@ var table_of_contents = function (cfg,st) { return $(elt).attr('data-toc-modified-id') === trg_id; }); var show = clicked_i.hasClass('fa-caret-right'); + collapse_by_id(trg_id, show); + }; + + var collapse_by_id = function (trg_id, show, trigger_event) { + var anchors = $('.toc .toc-item > li > a').filter(function (idx, elt) { + return $(elt).attr('data-toc-modified-id') === trg_id; + }); anchors.siblings('i') .toggleClass('fa-caret-right', !show) .toggleClass('fa-caret-down', show); anchors.siblings('ul')[show ? 'slideDown' : 'slideUp']('fast'); + if (trigger_event !== false) { + // fire event for collapsible_heading to catch + var cell = $(document.getElementById(trg_id)).closest('.cell').data('cell'); + events.trigger((show ? 'un' : '') + 'collapse.Toc', {cell: cell}); + } }; var depth = 1; //var depth = ol_depth(ol); @@ -619,6 +653,10 @@ var table_of_contents = function (cfg,st) { .on('click', callback_collapser) .prependTo('.toc li'); + events[cfg.collapse_to_match_collapsible_headings ? 'on' : 'off']( + 'collapse.CollapsibleHeading uncollapse.CollapsibleHeading', callback_toc2_collapsible_headings); + + $(window).resize(function(){ $('#toc').css({maxHeight: $(window).height() - 30}); $('#toc-wrapper').css({maxHeight: $(window).height() - 10}); diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.yaml b/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.yaml index 84432dd0e..fe5d3ae31 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.yaml +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.yaml @@ -40,6 +40,15 @@ Parameters: description: Move notebook's title and menu on the left instead of being centered -- This provides a better look when the toc/sidebar is present input_type: checkbox default: true + +- name: toc2.collapse_to_match_collapsible_headings + input_type: checkbox + default: false + description: | + Collapse/uncollapse ToC sections when the collapsible_headings nbextension + is used to collapse/uncollapse sections in the notebook. For the inverse + behaviour, see collapsible_headings' configuration + - name: toc2.colors.hover_highlight input_type: color description: Hover color in toc From 5fe9cb24b20a7ace2f09e2047d496fa707ecd54d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Bercher?= Date: Mon, 7 Aug 2017 12:22:15 +0200 Subject: [PATCH 07/15] [toc2] Only add collapse controls to items with descendants --- src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js b/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js index f5fd06d65..ec7d680e8 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js @@ -650,8 +650,9 @@ var table_of_contents = function (cfg,st) { // add collapse controls $('') .addClass('fa fa-fw fa-caret-down') - .on('click', callback_collapser) - .prependTo('.toc li'); + .on('click', callback_collapser) // callback + .prependTo('.toc li:has(ul)'); // only if li has descendants + $('').addClass('fa fa-fw ').prependTo('.toc li:not(:has(ul))'); // otherwise still add to keep things aligned events[cfg.collapse_to_match_collapsible_headings ? 'on' : 'off']( 'collapse.CollapsibleHeading uncollapse.CollapsibleHeading', callback_toc2_collapsible_headings); From 1b6d917cd343d55f4b15fd47539e495990806612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Bercher?= Date: Mon, 7 Aug 2017 12:24:22 +0200 Subject: [PATCH 08/15] [toc2] un-nest collapse_by_id & callback_collapser function definitions The former is needed for collapse_by_id to be defined in callback_toc2_collapsible_headings, the latter just for consistency/neatness --- .../nbextensions/toc2/toc2.js | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js b/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js index ec7d680e8..2642a2cb5 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js @@ -503,6 +503,21 @@ function highlight_toc_item(evt, data) { } } //end function process_cell_toc -------------------------- + var collapse_by_id = function (trg_id, show, trigger_event) { + var anchors = $('.toc .toc-item > li > span > a').filter(function (idx, elt) { + return $(elt).attr('data-toc-modified-id') === trg_id; + }); + anchors.siblings('i') + .toggleClass('fa-caret-right', !show) + .toggleClass('fa-caret-down', show); + anchors.parent().siblings('ul')[show ? 'slideDown' : 'slideUp']('fast'); + if (trigger_event !== false) { + // fire event for collapsible_heading to catch + var cell = $(document.getElementById(trg_id)).closest('.cell').data('cell'); + events.trigger((show ? 'un' : '') + 'collapse.Toc', {cell: cell}); + } + }; + var callback_toc2_collapsible_headings = function (evt, data) { var trg_id = data.cell.element.find(':header').filter(function (idx, elt) { return Boolean($(elt).attr('data-toc-modified-id')); @@ -512,6 +527,16 @@ function highlight_toc_item(evt, data) { collapse_by_id(trg_id, show, false); }; + var callback_collapser = function (evt) { + var clicked_i = $(evt.currentTarget); + var trg_id = clicked_i.siblings('a').attr('data-toc-modified-id'); + var anchors = $('.toc .toc-item > li > a').filter(function (idx, elt) { + return $(elt).attr('data-toc-modified-id') === trg_id; + }); + var show = clicked_i.hasClass('fa-caret-right'); + collapse_by_id(trg_id, show); + }; + // Table of Contents ================================================================= var table_of_contents = function (cfg,st) { @@ -541,31 +566,6 @@ var table_of_contents = function (cfg,st) { } //process_cell_toc(); - var callback_collapser = function (evt) { - var clicked_i = $(evt.currentTarget); - var trg_id = clicked_i.siblings('a').attr('data-toc-modified-id'); - var anchors = $('.toc .toc-item > li > a').filter(function (idx, elt) { - return $(elt).attr('data-toc-modified-id') === trg_id; - }); - var show = clicked_i.hasClass('fa-caret-right'); - collapse_by_id(trg_id, show); - }; - - var collapse_by_id = function (trg_id, show, trigger_event) { - var anchors = $('.toc .toc-item > li > a').filter(function (idx, elt) { - return $(elt).attr('data-toc-modified-id') === trg_id; - }); - anchors.siblings('i') - .toggleClass('fa-caret-right', !show) - .toggleClass('fa-caret-down', show); - anchors.siblings('ul')[show ? 'slideDown' : 'slideUp']('fast'); - if (trigger_event !== false) { - // fire event for collapsible_heading to catch - var cell = $(document.getElementById(trg_id)).closest('.cell').data('cell'); - events.trigger((show ? 'un' : '') + 'collapse.Toc', {cell: cell}); - } - }; - var depth = 1; //var depth = ol_depth(ol); var li= ul;//yes, initialize li with ul! var all_headers= $("#notebook").find(":header"); From ba2678f7fea5a5c1e319f2ad23785e5bc9924a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Bercher?= Date: Mon, 7 Aug 2017 12:27:12 +0200 Subject: [PATCH 09/15] [toc2] Take collapse_to_match_collapsible_headings parameter from system, not from notebook metadata --- src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js b/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js index ab4d2d5b3..9c5eeba19 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js @@ -73,10 +73,11 @@ define(["require", "jquery", "base/js/namespace", 'services/config', try {cfg.colors = IPython.notebook.metadata.toc.colors = $.extend(true, cfg.colors, config.data.toc2.colors); } catch(e) {} - // and moveMenuLeft, threshold, wideNotebook taken globally (if it exists, otherwise default) + // 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; @@ -87,6 +88,9 @@ define(["require", "jquery", "base/js/namespace", 'services/config', 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(); From 79d4d03a6860aea7922349fcb6fea6aa49b74c57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Bercher?= Date: Mon, 7 Aug 2017 12:31:56 +0200 Subject: [PATCH 10/15] [toc2] Enable full highlight of heading line instead of solely the link --- .../nbextensions/toc2/main.css | 4 ++-- .../nbextensions/toc2/main.js | 2 +- .../nbextensions/toc2/toc2.js | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.css b/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.css index c6bae45bb..ffcb38f51 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.css +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.css @@ -4,7 +4,7 @@ /*background color for links when you mouse over it This style is used on export, but can be overwritted in the livenotebook by selecting a color in the nbextension-configurator*/ -#toc-wrapper li > a:hover { +#toc-wrapper li > span:hover { background-color: #DAA520; } @@ -12,7 +12,7 @@ by selecting a color in the nbextension-configurator*/ /*color: #333333;*/ /* now specified in js */ text-decoration: none; } -#navigate_menu li a:hover {background-color: #f1f1f1} +#navigate_menu li > span:hover {background-color: #f1f1f1} /* Move menus and tooolbar to the left, following @Kevin-McIsaac suggestion diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js b/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js index 9c5eeba19..5131e0bcc 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js @@ -142,7 +142,7 @@ define(["require", "jquery", "base/js/namespace", 'services/config', function create_additional_css() { var sheet = document.createElement('style') - sheet.innerHTML = "#toc-level0 li > a:hover { background-color: " + cfg.colors.hover_highlight + " }\n" + + sheet.innerHTML = "#toc-level0 li > span:hover { background-color: " + cfg.colors.hover_highlight + " }\n" + ".toc-item-highlight-select {background-color: " + cfg.colors.selected_highlight + "}\n" + ".toc-item-highlight-execute {background-color: " + cfg.colors.running_highlight + "}\n" + ".toc-item-highlight-execute.toc-item-highlight-select {background-color: " + cfg.colors.selected_highlight + "}" diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js b/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js index 2642a2cb5..7929a6868 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js @@ -530,7 +530,7 @@ function highlight_toc_item(evt, data) { var callback_collapser = function (evt) { var clicked_i = $(evt.currentTarget); var trg_id = clicked_i.siblings('a').attr('data-toc-modified-id'); - var anchors = $('.toc .toc-item > li > a').filter(function (idx, elt) { + var anchors = $('.toc .toc-item > li > span > a').filter(function (idx, elt) { return $(elt).attr('data-toc-modified-id') === trg_id; }); var show = clicked_i.hasClass('fa-caret-right'); @@ -614,7 +614,7 @@ var table_of_contents = function (cfg,st) { $('
            ').addClass('toc-mod-link').attr('id', toc_mod_id).prependTo(h); // Create toc entry, append
          2. tag to the current
              . - li = $('
            1. ').append(make_link(h, toc_mod_id)); + li = $('
            2. ').append($('').append(make_link(h, toc_mod_id))); ul.append(li); }); @@ -651,8 +651,8 @@ var table_of_contents = function (cfg,st) { $('') .addClass('fa fa-fw fa-caret-down') .on('click', callback_collapser) // callback - .prependTo('.toc li:has(ul)'); // only if li has descendants - $('').addClass('fa fa-fw ').prependTo('.toc li:not(:has(ul))'); // otherwise still add to keep things aligned + .prependTo('.toc li:has(ul) > span'); // only if li has descendants + $('').addClass('fa fa-fw ').prependTo('.toc li:not(:has(ul)) > span'); // otherwise still add to keep things aligned events[cfg.collapse_to_match_collapsible_headings ? 'on' : 'off']( 'collapse.CollapsibleHeading uncollapse.CollapsibleHeading', callback_toc2_collapsible_headings); From 1bd906bf8aa23767bedfec2c985a8bc8026c1f60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Bercher?= Date: Wed, 16 Aug 2017 14:57:30 +0200 Subject: [PATCH 11/15] [toc2] Change .click() to scollIntoView for follwing links to target ids (issue with Firefox) --- .../nbextensions/toc2/toc2.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js b/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js index 9647ae234..f5fe0d36c 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js @@ -39,8 +39,10 @@ function removeMathJaxPreview(elt) { setTimeout(function() { $.ajax() }, 100); evt.preventDefault(); var trg_id = $(evt.currentTarget).attr('data-toc-modified-id'); - // use browser's native click method with semi-unique id - $('').attr('href', '#' + trg_id)[0].click(); + // use native scrollIntoView method with semi-unique id + // ! browser native click does't follow links on all browsers + // $('').attr('href', window.location.href.split('#')[0] + '#' + trg_id)[0].click(); + document.getElementById(trg_id).scrollIntoView(true) if (liveNotebook) { // use native document method as jquery won't cope with characters // like . in an id @@ -53,7 +55,7 @@ function removeMathJaxPreview(elt) { var make_link = function (h, toc_mod_id) { var a = $('') .attr({ - 'href': h.find('.anchor-link').attr('href'), + 'href': window.location.href.split('#')[0] + h.find('.anchor-link').attr('href'), 'data-toc-modified-id': toc_mod_id, }); // get the text *excluding* the link text, whatever it may be From cb63154378e05ef3075cb95477d81ccad89341e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Bercher?= Date: Wed, 16 Aug 2017 14:58:09 +0200 Subject: [PATCH 12/15] [toc2] Updated README with last contributions --- src/jupyter_contrib_nbextensions/nbextensions/toc2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/README.md b/src/jupyter_contrib_nbextensions/nbextensions/toc2/README.md index 7ce21e51f..33a0ac8bc 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/README.md +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/README.md @@ -117,3 +117,4 @@ This option requires the IPython kernel and is not present with other kernels. - Support customization of background, fonts, border and highlighting colors in the toc window and navigation menus with PR [#969](https://github.com/ipython-contrib/jupyter_contrib_nbextensions/pull/969) - @jfbercher, @louisabraham, @jcb91 July 2017. Add support for skipping h1 headings, enabling their use as unnumbered notebook titles +- @jcb91 with minor contributions by @jfbercher. August 2017. Make toc entries collapsible #1031 with optional synchronization with `collapsible_headings` + some small other tweaks. From 84bf6f9937d0050c49feff5b1960e9599c1cdeff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Bercher?= Date: Wed, 16 Aug 2017 18:14:57 +0200 Subject: [PATCH 13/15] [toc2] Updated template to include font-awesome (firefox issue) --- src/jupyter_contrib_nbextensions/templates/toc2.tpl | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/jupyter_contrib_nbextensions/templates/toc2.tpl b/src/jupyter_contrib_nbextensions/templates/toc2.tpl index a9eedc674..ca5b751e7 100644 --- a/src/jupyter_contrib_nbextensions/templates/toc2.tpl +++ b/src/jupyter_contrib_nbextensions/templates/toc2.tpl @@ -11,6 +11,19 @@ + +