/*! Deck JS - deck.toc Copyright (c) 2011 Remi BARRAQUAND Dual licensed under the MIT license and GPL license. https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt https://github.com/imakewebthings/deck.js/blob/master/GPL-license.txt */ /* This module provides a support for TOC to the deck. */ (function($, deck, undefined) { var $d = $(document); var $toc; /* Extends defaults/options. options.classes.toc This class is added to the deck container when showing the slide toc. options.keys.toc The numeric keycode used to toggle between showing and hiding the slide toc. options.selectors.toc The element matching this selector displays the toc. options.selectors.tocTitle The element matching this selector displays the current title of the slide i.e the current h1. options.selectors.tocSection The element matching this selector displays the current section of the slide i.e the current h2. options.selectors.tocSubSection The element matching this selector displays the current subsection of the slide i.e the current h3. options.selectors.tocSubSubSection The element matching this selector displays the current subsubsection of the slide i.e the current h4. */ $.extend(true, $[deck].defaults, { classes: { toc: 'deck-toc-frame' }, keys: { toc: 84 // t }, selectors: { toc: '.deck-toc', tocTitle: '.deck-toc-h1', tocSection: '.deck-toc-h2', tocSubSection: '.deck-toc-h3', tocSubSubSection: '.deck-toc-h4', tocStatus: '.deck-toc-status' } }); /* jQuery.deck('showToc') Shows the slide toc by adding the class specified by the toc class option to the deck container. */ $[deck]('extend', 'showToc', function() { $[deck]('getContainer').addClass($[deck]('getOptions').classes.toc); }); /* jQuery.deck('hideToc') Hides the slide toc by removing the class specified by the toc class option from the deck container. */ $[deck]('extend', 'hideToc', function() { $[deck]('getContainer').removeClass($[deck]('getOptions').classes.toc); }); /* jQuery.deck('toggleToc') Toggles between showing and hiding the TOC. */ $[deck]('extend', 'toggleToc', function() { $[deck]('getContainer').hasClass($[deck]('getOptions').classes.toc) ? $[deck]('hideToc') : $[deck]('showToc'); }); /* jQuery.deck('Init') */ $d.bind('deck.init', function() { var opts = $[deck]('getOptions'); var container = $[deck]('getContainer'); /* Bind key events */ $d.unbind('keydown.decktoc').bind('keydown.decktoc', function(e) { if (e.which === opts.keys.toc || $.inArray(e.which, opts.keys.toc) > -1) { $[deck]('toggleToc'); e.preventDefault(); } }); /* Hide TOC panel when user click on container */ container.click(function(e){ $[deck]('hideToc'); }); /* Init TOC and append it to the document */ $toc = new TOC(); $($[deck]('getOptions').selectors.toc).append($toc.root); /* Go through all slides */ $.each($[deck]('getSlides'), function(i, $el) { var slide = $[deck]('getSlide',i); //var tocElementFound = false; /* If there is a toc item, push it in the TOC */ for(var level=1; level<6; level++) { if( slide.find("h"+level).length > 0) { var tocTitle = ""; var $tocElement = slide.find("h"+level+":first"); if( $tocElement.attr("title") != undefined && $tocElement.attr("title") != "") { tocTitle = $tocElement.attr("title"); } else { tocTitle = $tocElement.text(); } $toc.push(level, tocTitle, slide); $toc.tag(slide); //tocElementFound = true; } } /* Tag the slide with the current TOC level */ $toc.tag(slide); }); }) /* Update current slide number with each change event */ .bind('deck.change', function(e, from, to) { var opts = $[deck]('getOptions'); var slideTo = $[deck]('getSlide', to); var container = $[deck]('getContainer'); if (container.hasClass($[deck]('getOptions').classes.toc)) { container.scrollTop(slideTo.offset().top); } /* update toc status */ if( slideTo.data("toc") ) { // reset $(opts.selectors.tocTitle).text(""); $(opts.selectors.tocSection).text(""); $(opts.selectors.tocSubSection).text(""); $(opts.selectors.tocSubSubSection).text(""); if( slideTo.hasClass('hide-toc-status') ) { $(opts.selectors.tocStatus).hide(); } else { $(opts.selectors.tocStatus).show(); // update according to the current context var $context = $toc.context(slideTo.data('toc')) for(var level=1; level<=$context.length; level++) { switch(level) { case 1: $(opts.selectors.tocTitle).text($context[level-1]); break; case 2: $(opts.selectors.tocSection).text($context[level-1]); break; case 3: $(opts.selectors.tocSubSection).text($context[level-1]); break; case 4: $(opts.selectors.tocSubSubSection).text($context[level-1]); break; } } } } }); /* Simple TOC manager (must be improved) */ var TOC = function() { this.root = $("