1/*! 2Deck JS - deck.menu 3Copyright (c) 2011 Caleb Troughton 4Dual licensed under the MIT license and GPL license. 5https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt 6https://github.com/imakewebthings/deck.js/blob/master/GPL-license.txt 7*/ 8 9/* 10This module adds the methods and key binding to show and hide a menu of all 11slides in the deck. The deck menu state is indicated by the presence of a class 12on the deck container. 13*/ 14(function($, deck, undefined) { 15 var $d = $(document), 16 rootSlides; // Array of top level slides 17 18 /* 19 Extends defaults/options. 20 21 options.classes.menu 22 This class is added to the deck container when showing the slide menu. 23 24 options.keys.menu 25 The numeric keycode used to toggle between showing and hiding the slide 26 menu. 27 28 options.touch.doubletapWindow 29 Two consecutive touch events within this number of milliseconds will 30 be considered a double tap, and will toggle the menu on touch devices. 31 */ 32 $.extend(true, $[deck].defaults, { 33 classes: { 34 menu: 'deck-menu' 35 }, 36 37 keys: { 38 menu: 77 // m 39 }, 40 41 touch: { 42 doubletapWindow: 400 43 } 44 }); 45 46 /* 47 jQuery.deck('showMenu') 48 49 Shows the slide menu by adding the class specified by the menu class option 50 to the deck container. 51 */ 52 $[deck]('extend', 'showMenu', function() { 53 var $c = $[deck]('getContainer'), 54 opts = $[deck]('getOptions'); 55 56 if ($c.hasClass(opts.classes.menu)) return; 57 58 // Hide through loading class to short-circuit transitions (perf) 59 $c.addClass([opts.classes.loading, opts.classes.menu].join(' ')); 60 61 /* Forced to do this in JS until CSS learns second-grade math. Save old 62 style value for restoration when menu is hidden. */ 63 if (Modernizr.csstransforms) { 64 $.each(rootSlides, function(i, $slide) { 65 $slide.data('oldStyle', $slide.attr('style')); 66 $slide.css({ 67 'position': 'absolute', 68 'left': ((i % 4) * 25) + '%', 69 'top': (Math.floor(i / 4) * 25) + '%' 70 }); 71 }); 72 } 73 74 // Need to ensure the loading class renders first, then remove 75 window.setTimeout(function() { 76 $c.removeClass(opts.classes.loading) 77 .scrollTop($[deck]('getSlide').offset().top); 78 }, 0); 79 }); 80 81 /* 82 jQuery.deck('hideMenu') 83 84 Hides the slide menu by removing the class specified by the menu class 85 option from the deck container. 86 */ 87 $[deck]('extend', 'hideMenu', function() { 88 var $c = $[deck]('getContainer'), 89 opts = $[deck]('getOptions'); 90 91 if (!$c.hasClass(opts.classes.menu)) return; 92 93 $c.removeClass(opts.classes.menu); 94 $c.addClass(opts.classes.loading); 95 96 /* Restore old style value */ 97 if (Modernizr.csstransforms) { 98 $.each(rootSlides, function(i, $slide) { 99 var oldStyle = $slide.data('oldStyle'); 100 101 $slide.attr('style', oldStyle ? oldStyle : ''); 102 }); 103 } 104 105 window.setTimeout(function() { 106 $c.removeClass(opts.classes.loading).scrollTop(0); 107 }, 0); 108 }); 109 110 /* 111 jQuery.deck('toggleMenu') 112 113 Toggles between showing and hiding the slide menu. 114 */ 115 $[deck]('extend', 'toggleMenu', function() { 116 $[deck]('getContainer').hasClass($[deck]('getOptions').classes.menu) ? 117 $[deck]('hideMenu') : $[deck]('showMenu'); 118 }); 119 120 $d.bind('deck.init', function() { 121 var opts = $[deck]('getOptions'), 122 touchEndTime = 0, 123 currentSlide, 124 slideTest = $.map([ 125 opts.classes.before, 126 opts.classes.previous, 127 opts.classes.current, 128 opts.classes.next, 129 opts.classes.after 130 ], function(el, i) { 131 return '.' + el; 132 }).join(', '); 133 134 // Build top level slides array 135 rootSlides = []; 136 $.each($[deck]('getSlides'), function(i, $el) { 137 if (!$el.parentsUntil(opts.selectors.container, slideTest).length) { 138 rootSlides.push($el); 139 } 140 }); 141 142 // Bind key events 143 $d.unbind('keydown.deckmenu').bind('keydown.deckmenu', function(e) { 144 if (e.which === opts.keys.menu || $.inArray(e.which, opts.keys.menu) > -1) { 145 $[deck]('toggleMenu'); 146 e.preventDefault(); 147 } 148 }); 149 150 // Double tap to toggle slide menu for touch devices 151 $[deck]('getContainer').unbind('touchstart.deckmenu').bind('touchstart.deckmenu', function(e) { 152 currentSlide = $[deck]('getSlide'); 153 }) 154 .unbind('touchend.deckmenu').bind('touchend.deckmenu', function(e) { 155 var now = Date.now(); 156
157 // Ignore this touch event if it caused a nav change (swipe) 158 if (currentSlide !== $[deck]('getSlide')) return; 159 160 if (now - touchEndTime < opts.touch.doubletapWindow) { 161 $[deck]('toggleMenu'); 162 e.preventDefault(); 163 } 164 touchEndTime = now; 165 }); 166 167 // Selecting slides from the menu 168 $.each($[deck]('getSlides'), function(i, $s) { 169 $s.unbind('click.deckmenu').bind('click.deckmenu', function(e) { 170 if (!$[deck]('getContainer').hasClass(opts.classes.menu)) return; 171 172 $[deck]('go', i); 173 $[deck]('hideMenu'); 174 e.stopPropagation(); 175 e.preventDefault(); 176 }); 177 }); 178 }) 179 .bind('deck.change', function(e, from, to) { 180 var container = $[deck]('getContainer'); 181 182 if (container.hasClass($[deck]('getOptions').classes.menu)) { 183 container.scrollTop($[deck]('getSlide', to).offset().top); 184 } 185 }); 186})(jQuery, 'deck'); 187
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.