Newer
Older
return false;
}

Hakim El Hattab
committed
/**
* Cues a new automated slide if enabled in the config.
*/

Hakim El Hattab
committed
function cueAutoSlide() {
clearTimeout( autoSlideTimeout );
// Cue the next auto-slide if enabled
if( autoSlide ) {
autoSlideTimeout = setTimeout( navigateNext, autoSlide );

Hakim El Hattab
committed
}
}
// Prioritize hiding fragments
if( availableRoutes().left && ( isOverviewActive() || previousFragment() === false ) ) {
slide( indexh - 1, 0 );
// Prioritize revealing fragments
if( availableRoutes().right && ( isOverviewActive() || nextFragment() === false ) ) {
slide( indexh + 1, 0 );
// Prioritize hiding fragments
if( availableRoutes().up && ( isOverviewActive() || previousFragment() === false ) ) {
slide( indexh, indexv - 1 );
// Prioritize revealing fragments
if( availableRoutes().down && ( isOverviewActive() || nextFragment() === false ) ) {
slide( indexh, indexv + 1 );
/**
* Navigates backwards, prioritized in the following order:
* 1) Previous fragment
* 2) Previous vertical slide
* 3) Previous horizontal slide
*/
function navigatePrev() {
// Prioritize revealing fragments
if( previousFragment() === false ) {
if( availableRoutes().up ) {
navigateUp();
}
else {
// Fetch the previous horizontal slide, if there is one
var previousSlide = document.querySelector( '.reveal .slides>section.past:nth-child(' + indexh + ')' );
if( previousSlide ) {
indexv = ( previousSlide.querySelectorAll( 'section' ).length + 1 ) || 0;
indexh --;
slide();
}
}
}
}
/**
* Same as #navigatePrev() but navigates forwards.
*/
function navigateNext() {
// Prioritize revealing fragments
if( nextFragment() === false ) {
availableRoutes().down ? navigateDown() : navigateRight();
}

Hakim El Hattab
committed
// If auto-sliding is enabled we need to cue up

Hakim El Hattab
committed
// another timeout
cueAutoSlide();

Hakim El Hattab
committed
// --------------------------------------------------------------------//
// ----------------------------- EVENTS -------------------------------//
// --------------------------------------------------------------------//
/**
* Handler for the document level 'keydown' event.

Hakim El Hattab
committed
* @param {Object} event
*/
function onDocumentKeyDown( event ) {
// Check if there's a focused element that could be using
// the keyboard
var activeElement = document.activeElement;
var hasFocus = !!( document.activeElement && ( document.activeElement.type || document.activeElement.href || document.activeElement.contentEditable !== 'inherit' ) );
// Disregard the event if there's a focused element or a
// keyboard modifier key is present
if ( hasFocus || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return;

Hakim El Hattab
committed
var triggered = true;
switch( event.keyCode ) {
// p, page up
case 80: case 33: navigatePrev(); break;

Hakim El Hattab
committed
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
// n, page down
case 78: case 34: navigateNext(); break;
// h, left
case 72: case 37: navigateLeft(); break;
// l, right
case 76: case 39: navigateRight(); break;
// k, up
case 75: case 38: navigateUp(); break;
// j, down
case 74: case 40: navigateDown(); break;
// home
case 36: slide( 0 ); break;
// end
case 35: slide( Number.MAX_VALUE ); break;
// space
case 32: isOverviewActive() ? deactivateOverview() : navigateNext(); break;
// return
case 13: isOverviewActive() ? deactivateOverview() : triggered = false; break;
// b, period
case 66: case 190: togglePause(); break;
// f
case 70: enterFullscreen(); break;
default:
triggered = false;
}
// If the input resulted in a triggered action we should prevent

Hakim El Hattab
committed
// the browsers default behavior
if( triggered ) {
event.preventDefault();
}
else if ( event.keyCode === 27 && supports3DTransforms ) {
toggleOverview();

Hakim El Hattab
committed
event.preventDefault();
}
// If auto-sliding is enabled we need to cue up

Hakim El Hattab
committed
// another timeout
cueAutoSlide();
}
/**
* Handler for the document level 'touchstart' event,
* enables support for swipe and pinch gestures.
*/
function onDocumentTouchStart( event ) {
touch.startX = event.touches[0].clientX;
touch.startY = event.touches[0].clientY;
touch.startCount = event.touches.length;
// If there's two touches we need to memorize the distance

Hakim El Hattab
committed
// between those two points to detect pinching
if( event.touches.length === 2 && config.overview ) {
touch.startSpan = distanceBetween( {
x: event.touches[1].clientX,
y: event.touches[1].clientY
}, {
x: touch.startX,
y: touch.startY
} );
}
}

Hakim El Hattab
committed
/**
* Handler for the document level 'touchmove' event.
*/
function onDocumentTouchMove( event ) {
// Each touch should only trigger one action
if( !touch.handled ) {
var currentX = event.touches[0].clientX;
var currentY = event.touches[0].clientY;
// If the touch started off with two points and still has

Hakim El Hattab
committed
// two active touches; test for the pinch gesture
if( event.touches.length === 2 && touch.startCount === 2 && config.overview ) {
// The current distance in pixels between the two touch points
var currentSpan = distanceBetween( {
x: event.touches[1].clientX,
y: event.touches[1].clientY
}, {
x: touch.startX,
y: touch.startY
} );
// If the span is larger than the desire amount we've got

Hakim El Hattab
committed
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
// ourselves a pinch
if( Math.abs( touch.startSpan - currentSpan ) > touch.threshold ) {
touch.handled = true;
if( currentSpan < touch.startSpan ) {
activateOverview();
}
else {
deactivateOverview();
}
}
event.preventDefault();
}
// There was only one touch point, look for a swipe
else if( event.touches.length === 1 && touch.startCount !== 2 ) {
var deltaX = currentX - touch.startX,
deltaY = currentY - touch.startY;
if( deltaX > touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
touch.handled = true;
navigateLeft();

Hakim El Hattab
committed
else if( deltaX < -touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
touch.handled = true;
navigateRight();

Hakim El Hattab
committed
else if( deltaY > touch.threshold ) {
touch.handled = true;
navigateUp();

Hakim El Hattab
committed
else if( deltaY < -touch.threshold ) {
touch.handled = true;
navigateDown();
}
event.preventDefault();
}
}
// There's a bug with swiping on some Android devices unless

Hakim El Hattab
committed
// the default action is always prevented
else if( navigator.userAgent.match( /android/gi ) ) {
event.preventDefault();
}
}
/**
* Handler for the document level 'touchend' event.
*/
function onDocumentTouchEnd( event ) {
touch.handled = false;
}
/**
* Handles mouse wheel scrolling, throttled to avoid skipping
* multiple slides.

Hakim El Hattab
committed
*/
function onDocumentMouseScroll( event ){
clearTimeout( mouseWheelTimeout );
mouseWheelTimeout = setTimeout( function() {
var delta = event.detail || -event.wheelDelta;
if( delta > 0 ) {
navigateNext();
}
else {
navigatePrev();
}
}, 100 );
}
* Clicking on the progress bar results in a navigation to the
* closest approximate horizontal slide using this equation:
*
* ( clickX / presentationWidth ) * numberOfSlides
*/
function onProgressClick( event ) {
var slidesTotal = Array.prototype.slice.call( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ).length;
var slideIndex = Math.floor( ( event.clientX / dom.wrapper.offsetWidth ) * slidesTotal );
slide( slideIndex );
}

Hakim El Hattab
committed
/**
* Handler for the window level 'hashchange' event.

Hakim El Hattab
committed
* @param {Object} event
*/
function onWindowHashChange( event ) {
readURL();
}
/**
* Invoked when a slide is and we're in the overview.
*/
function onOverviewSlideClicked( event ) {
// TODO There's a bug here where the event listeners are not

Hakim El Hattab
committed
// removed after deactivating the overview.
if( isOverviewActive() ) {
event.preventDefault();
deactivateOverview();
indexh = this.getAttribute( 'data-index-h' );
indexv = this.getAttribute( 'data-index-v' );
slide();
}
}

Hakim El Hattab
committed
// --------------------------------------------------------------------//
// ------------------------------- API --------------------------------//
// --------------------------------------------------------------------//
initialize: initialize,

Hakim El Hattab
committed
// Navigation methods
slide: slide,
left: navigateLeft,
right: navigateRight,
up: navigateUp,
down: navigateDown,
prev: navigatePrev,
next: navigateNext,
prevFragment: previousFragment,
nextFragment: nextFragment,

Hakim El Hattab
committed
// Deprecated aliases
navigateTo: slide,
navigateLeft: navigateLeft,
navigateRight: navigateRight,
navigateUp: navigateUp,

Hakim El Hattab
committed
navigateDown: navigateDown,
navigatePrev: navigatePrev,
navigateNext: navigateNext,

Hakim El Hattab
committed
// Toggles the overview mode on/off
toggleOverview: toggleOverview,

Hakim El Hattab
committed

Hakim El Hattab
committed
// Adds or removes all internal event listeners (such as keyboard)
addEventListeners: addEventListeners,
removeEventListeners: removeEventListeners,
// Returns the indices of the current, or specified, slide

Hakim El Hattab
committed
getIndices: getIndices,

Hakim El Hattab
committed
// Returns the previous slide element, may be null
getPreviousSlide: function() {
return previousSlide;

Hakim El Hattab
committed
},
// Returns the current slide element
getCurrentSlide: function() {
return currentSlide;

Hakim El Hattab
committed
},
// Helper method, retrieves query string as a key/value hash
getQueryHash: function() {
var query = {};
location.search.replace( /[A-Z0-9]+?=(\w*)/gi, function(a) {
query[ a.split( '=' ).shift() ] = a.split( '=' ).pop();
} );
return query;
},

Hakim El Hattab
committed
// Forward event binding to the reveal DOM element
addEventListener: function( type, listener, useCapture ) {
if( 'addEventListener' in window ) {
( dom.wrapper || document.querySelector( '.reveal' ) ).addEventListener( type, listener, useCapture );
}

Hakim El Hattab
committed
},
removeEventListener: function( type, listener, useCapture ) {
if( 'addEventListener' in window ) {
( dom.wrapper || document.querySelector( '.reveal' ) ).removeEventListener( type, listener, useCapture );
}

Hakim El Hattab
committed
}