Newer
Older

Hakim El Hattab
committed
* @return {Object} { h: <int>, v: <int>, f: <int> }

Hakim El Hattab
committed
*/
function getIndices( slide ) {

Hakim El Hattab
committed
// By default, return the current indices
var h = indexh,

Hakim El Hattab
committed
v = indexv,
f;

Hakim El Hattab
committed
// If a slide is specified, return the indices of that slide
if( slide ) {
var isVertical = isVerticalSlide( slide );

Hakim El Hattab
committed
var slideh = isVertical ? slide.parentNode : slide;
// Select all horizontal slides

Hakim El Hattab
committed
var horizontalSlides = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );

Hakim El Hattab
committed
// Now that we know which the horizontal slide is, get its index
h = Math.max( horizontalSlides.indexOf( slideh ), 0 );
v = undefined;

Hakim El Hattab
committed
// If this is a vertical slide, grab the vertical index
if( isVertical ) {
v = Math.max( toArray( slide.parentNode.querySelectorAll( 'section' ) ).indexOf( slide ), 0 );

Hakim El Hattab
committed
}
}

Hakim El Hattab
committed
if( !slide && currentSlide ) {
var hasFragments = currentSlide.querySelectorAll( '.fragment' ).length > 0;
if( hasFragments ) {
var currentFragment = currentSlide.querySelector( '.current-fragment' );
if( currentFragment && currentFragment.hasAttribute( 'data-fragment-index' ) ) {
f = parseInt( currentFragment.getAttribute( 'data-fragment-index' ), 10 );
}
else {
f = currentSlide.querySelectorAll( '.fragment.visible' ).length - 1;
}

Hakim El Hattab
committed
}
}
return { h: h, v: v, f: f };

Hakim El Hattab
committed
}
/**
* Retrieves the total number of slides in this presentation.
*/
function getTotalSlides() {

Hakim El Hattab
committed
return dom.wrapper.querySelectorAll( SLIDES_SELECTOR + ':not(.stack)' ).length;

Hakim El Hattab
committed
/**
* Returns the slide element matching the specified index.
*/

Hakim El Hattab
committed
var horizontalSlide = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR )[ x ];
var verticalSlides = horizontalSlide && horizontalSlide.querySelectorAll( 'section' );

Hakim El Hattab
committed
if( verticalSlides && verticalSlides.length && typeof y === 'number' ) {
return verticalSlides ? verticalSlides[ y ] : undefined;
}
return horizontalSlide;
}
/**
* Returns the background element for the given slide.
* All slides, even the ones with no background properties
* defined, have a background element so as long as the
* index is valid an element will be returned.
*/
function getSlideBackground( x, y ) {
// When printing to PDF the slide backgrounds are nested
// inside of the slides
if( isPrintingPDF() ) {
var slide = getSlide( x, y );
if( slide ) {
var background = slide.querySelector( '.slide-background' );
if( background && background.parentNode === slide ) {
return background;
}
}
return undefined;

Hakim El Hattab
committed
var horizontalBackground = dom.wrapper.querySelectorAll( '.backgrounds>.slide-background' )[ x ];
var verticalBackgrounds = horizontalBackground && horizontalBackground.querySelectorAll( '.slide-background' );

Hakim El Hattab
committed
if( verticalBackgrounds && verticalBackgrounds.length && typeof y === 'number' ) {
return verticalBackgrounds ? verticalBackgrounds[ y ] : undefined;
}
return horizontalBackground;
}
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
/**
* Retrieves the current state of the presentation as
* an object. This state can then be restored at any
* time.
*/
function getState() {
var indices = getIndices();
return {
indexh: indices.h,
indexv: indices.v,
indexf: indices.f,
paused: isPaused(),
overview: isOverview()
};
}
/**
* Restores the presentation to the given state.
*
* @param {Object} state As generated by getState()
*/
function setState( state ) {
if( typeof state === 'object' ) {
slide( deserialize( state.indexh ), deserialize( state.indexv ), deserialize( state.indexf ) );
var pausedFlag = deserialize( state.paused ),
overviewFlag = deserialize( state.overview );
if( typeof pausedFlag === 'boolean' && pausedFlag !== isPaused() ) {
togglePause( pausedFlag );
}
if( typeof overviewFlag === 'boolean' && overviewFlag !== isOverview() ) {
toggleOverview( overviewFlag );
}
}
}
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
/**
* Return a sorted fragments list, ordered by an increasing
* "data-fragment-index" attribute.
*
* Fragments will be revealed in the order that they are returned by
* this function, so you can use the index attributes to control the
* order of fragment appearance.
*
* To maintain a sensible default fragment order, fragments are presumed
* to be passed in document order. This function adds a "fragment-index"
* attribute to each node if such an attribute is not already present,
* and sets that attribute to an integer value which is the position of
* the fragment within the fragments list.
*/
function sortFragments( fragments ) {
fragments = toArray( fragments );
var ordered = [],
unordered = [],
sorted = [];
// Group ordered and unordered elements
fragments.forEach( function( fragment, i ) {
if( fragment.hasAttribute( 'data-fragment-index' ) ) {
var index = parseInt( fragment.getAttribute( 'data-fragment-index' ), 10 );
if( !ordered[index] ) {
ordered[index] = [];
}
ordered[index].push( fragment );
}
else {
unordered.push( [ fragment ] );
}
} );
// Append fragments without explicit indices in their
// DOM order
ordered = ordered.concat( unordered );
// Manually count the index up per group to ensure there
// are no gaps
var index = 0;
// Push all fragments in their sorted order to an array,
// this flattens the groups
ordered.forEach( function( group ) {
group.forEach( function( fragment ) {
sorted.push( fragment );
fragment.setAttribute( 'data-fragment-index', index );
} );
index ++;
} );
return sorted;
}
* @param {Number} index The index of the fragment that
* should be shown, -1 means all are invisible
* @param {Number} offset Integer offset to apply to the
* fragment index
*
* @return {Boolean} true if a change was made in any
* fragments visibility as part of this call
function navigateFragment( index, offset ) {
if( currentSlide && config.fragments ) {

Hakim El Hattab
committed
var fragments = sortFragments( currentSlide.querySelectorAll( '.fragment' ) );
if( fragments.length ) {
// If no index is specified, find the current
if( typeof index !== 'number' ) {
var lastVisibleFragment = sortFragments( currentSlide.querySelectorAll( '.fragment.visible' ) ).pop();
if( lastVisibleFragment ) {
index = parseInt( lastVisibleFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );
// If an offset is specified, apply it to the index
if( typeof offset === 'number' ) {
index += offset;
}
var fragmentsShown = [],
fragmentsHidden = [];
toArray( fragments ).forEach( function( element, i ) {
if( element.hasAttribute( 'data-fragment-index' ) ) {
i = parseInt( element.getAttribute( 'data-fragment-index' ), 10 );
if( i <= index ) {
if( !element.classList.contains( 'visible' ) ) fragmentsShown.push( element );
element.classList.add( 'visible' );
element.classList.remove( 'current-fragment' );
// Announce the fragments one by one to the Screen Reader
dom.statusDiv.textContent = element.textContent;
if( i === index ) {
element.classList.add( 'current-fragment' );
}
}
// Hidden fragments
else {
if( element.classList.contains( 'visible' ) ) fragmentsHidden.push( element );
element.classList.remove( 'visible' );
element.classList.remove( 'current-fragment' );
}
dispatchEvent( 'fragmenthidden', { fragment: fragmentsHidden[0], fragments: fragmentsHidden } );
}
dispatchEvent( 'fragmentshown', { fragment: fragmentsShown[0], fragments: fragmentsShown } );
}
updateControls();
return !!( fragmentsShown.length || fragmentsHidden.length );
}
return false;
}
/**
* @return {Boolean} true if there was a next fragment,
* false otherwise
*/
/**
* Navigate to the previous slide fragment.
*
* @return {Boolean} true if there was a previous fragment,
* false otherwise
*/
function previousFragment() {

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

Hakim El Hattab
committed
function cueAutoSlide() {
cancelAutoSlide();
if( currentSlide ) {

Hakim El Hattab
committed
var currentFragment = currentSlide.querySelector( '.current-fragment' );
var fragmentAutoSlide = currentFragment ? currentFragment.getAttribute( 'data-autoslide' ) : null;
var parentAutoSlide = currentSlide.parentNode ? currentSlide.parentNode.getAttribute( 'data-autoslide' ) : null;
var slideAutoSlide = currentSlide.getAttribute( 'data-autoslide' );
// 1. Current fragment's data-autoslide
// 2. Current slide's data-autoslide
// 3. Parent slide's data-autoslide
// 4. Global autoSlide setting
if( fragmentAutoSlide ) {
autoSlide = parseInt( fragmentAutoSlide, 10 );
}
else if( slideAutoSlide ) {
autoSlide = parseInt( slideAutoSlide, 10 );
}
else if( parentAutoSlide ) {
autoSlide = parseInt( parentAutoSlide, 10 );
}
else {
autoSlide = config.autoSlide;
}

Hakim El Hattab
committed
// If there are media elements with data-autoplay,
// automatically set the autoSlide duration to the
// length of that media
toArray( currentSlide.querySelectorAll( 'video, audio' ) ).forEach( function( el ) {
if( el.hasAttribute( 'data-autoplay' ) ) {
if( autoSlide && el.duration * 1000 > autoSlide ) {
autoSlide = ( el.duration * 1000 ) + 1000;
}
}
} );
// Cue the next auto-slide if:
// - There is an autoSlide value
// - Auto-sliding isn't paused by the user
// - The presentation isn't paused
// - The overview isn't active
// - The presentation isn't over
if( autoSlide && !autoSlidePaused && !isPaused() && !isOverview() && ( !Reveal.isLastSlide() || availableFragments().next || config.loop === true ) ) {
autoSlideTimeout = setTimeout( navigateNext, autoSlide );
autoSlideStartTime = Date.now();
}
if( autoSlidePlayer ) {
autoSlidePlayer.setPlaying( autoSlideTimeout !== -1 );
}

Hakim El Hattab
committed
}
/**
* Cancels any ongoing request to auto-slide.
*/
function cancelAutoSlide() {
clearTimeout( autoSlideTimeout );
autoSlideTimeout = -1;
function pauseAutoSlide() {
if( autoSlide && !autoSlidePaused ) {
autoSlidePaused = true;
dispatchEvent( 'autoslidepaused' );
clearTimeout( autoSlideTimeout );
if( autoSlidePlayer ) {
autoSlidePlayer.setPlaying( false );
}
}
}
function resumeAutoSlide() {
if( autoSlide && autoSlidePaused ) {
autoSlidePaused = false;
dispatchEvent( 'autoslideresumed' );
cueAutoSlide();
}
// Reverse for RTL
if( config.rtl ) {
if( ( isOverview() || nextFragment() === false ) && availableRoutes().left ) {
slide( indexh + 1 );
}
}
// Normal navigation
else if( ( isOverview() || previousFragment() === false ) && availableRoutes().left ) {
slide( indexh - 1 );
// Reverse for RTL
if( config.rtl ) {
if( ( isOverview() || previousFragment() === false ) && availableRoutes().right ) {
slide( indexh - 1 );
}
}
// Normal navigation
else if( ( isOverview() || nextFragment() === false ) && availableRoutes().right ) {
slide( indexh + 1 );
// Prioritize hiding fragments
if( ( isOverview() || previousFragment() === false ) && availableRoutes().up ) {
slide( indexh, indexv - 1 );
// Prioritize revealing fragments
if( ( isOverview() || nextFragment() === false ) && availableRoutes().down ) {
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;
previousSlide = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR + '.future' ) ).pop();
}
else {
previousSlide = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR + '.past' ) ).pop();
}
if( previousSlide ) {
var v = ( previousSlide.querySelectorAll( 'section' ).length - 1 ) || undefined;
var h = indexh - 1;
slide( h, v );
}
}
}
}
/**
*/
function navigateNext() {
// Prioritize revealing fragments
if( nextFragment() === false ) {
if( availableRoutes().down ) {
navigateDown();
}
else if( config.rtl ) {
navigateLeft();
}
else {
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 -------------------------------//
// --------------------------------------------------------------------//

Hakim El Hattab
committed
/**
* Called by all event handlers that are based on user
* input.
*/
function onUserInput( event ) {
if( config.autoSlideStoppable ) {

Hakim El Hattab
committed
}
}

Hakim El Hattab
committed
/**
* Handler for the document level 'keypress' event.
*/
function onDocumentKeyPress( event ) {
// Check if the pressed key is question mark
if( event.shiftKey && event.charCode === 63 ) {
if( dom.overlay ) {
closeOverlay();
}
else {
showHelp( true );
}

Hakim El Hattab
committed
/**
* Handler for the document level 'keydown' event.
*/
function onDocumentKeyDown( event ) {
// If there's a condition specified and it returns false,
// ignore this event
if( typeof config.keyboardCondition === 'function' && config.keyboardCondition() === false ) {
return true;
}
// Remember if auto-sliding was paused so we can toggle it
var autoSlideWasPaused = autoSlidePaused;
onUserInput( event );
// Check if there's a focused element that could be using
var activeElementIsCE = document.activeElement && document.activeElement.contentEditable !== 'inherit';
var activeElementIsInput = document.activeElement && document.activeElement.tagName && /input|textarea/i.test( document.activeElement.tagName );
// Disregard the event if there's a focused element or a
// keyboard modifier key is present
if( activeElementIsCE || activeElementIsInput || (event.shiftKey && event.keyCode !== 32) || event.altKey || event.ctrlKey || event.metaKey ) return;

Hakim El Hattab
committed
// While paused only allow "unpausing" keyboard events (b and .)
if( isPaused() && [66,190,191].indexOf( event.keyCode ) === -1 ) {
return false;
}
var triggered = false;
// 1. User defined key bindings
if( typeof config.keyboard === 'object' ) {
for( var key in config.keyboard ) {
// Check if this binding matches the pressed key
if( parseInt( key, 10 ) === event.keyCode ) {
var value = config.keyboard[ key ];
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
if( typeof value === 'function' ) {
value.apply( null, [ event ] );
}
// String shortcuts to reveal.js API
else if( typeof value === 'string' && typeof Reveal[ value ] === 'function' ) {
Reveal[ value ].call();
}
triggered = true;
}
}
}
// 2. System defined key bindings
if( triggered === false ) {
// Assume true and try to prove false
triggered = true;
switch( event.keyCode ) {
// p, page up
case 80: case 33: navigatePrev(); break;
// 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: isOverview() ? deactivateOverview() : event.shiftKey ? navigatePrev() : navigateNext(); break;
// return
case 13: isOverview() ? deactivateOverview() : triggered = false; break;
// two-spot, semicolon, b, period, Logitech presenter tools "black screen" button
case 58: case 59: case 66: case 190: case 191: togglePause(); break;
// f
case 70: enterFullscreen(); break;
case 65: if ( config.autoSlideStoppable ) toggleAutoSlide( autoSlideWasPaused ); break;
default:
triggered = false;
}

Hakim El Hattab
committed
}
// If the input resulted in a triggered action we should prevent

Hakim El Hattab
committed
// the browsers default behavior
if( triggered ) {
event.preventDefault && event.preventDefault();

Hakim El Hattab
committed
}

Hakim El Hattab
committed
else if ( ( event.keyCode === 27 || event.keyCode === 79 ) && features.transforms3d ) {
if( dom.overlay ) {
closeOverlay();
}
else {
toggleOverview();
}
event.preventDefault && event.preventDefault();

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

Hakim El Hattab
committed
// another timeout
cueAutoSlide();
}
/**
* Handler for the 'touchstart' event, enables support for
* swipe and pinch gestures.

Hakim El Hattab
committed
*/
function onTouchStart( event ) {

Hakim El Hattab
committed
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
}

Hakim El Hattab
committed
/**
* Handler for the 'touchmove' event.

Hakim El Hattab
committed
*/
function onTouchMove( event ) {

Hakim El Hattab
committed
// Each touch should only trigger one action
onUserInput( event );

Hakim El Hattab
committed
var currentX = event.touches[0].clientX;
var currentY = event.touches[0].clientY;
// If the touch started 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
// ourselves a pinch
if( Math.abs( touch.startSpan - currentSpan ) > touch.threshold ) {

Hakim El Hattab
committed
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 ) ) {

Hakim El Hattab
committed
navigateLeft();

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

Hakim El Hattab
committed
navigateRight();

Hakim El Hattab
committed
else if( deltaY > touch.threshold ) {

Hakim El Hattab
committed
navigateUp();

Hakim El Hattab
committed
else if( deltaY < -touch.threshold ) {

Hakim El Hattab
committed
navigateDown();
}
// If we're embedded, only block touch events if they have
// triggered an action
if( config.embedded ) {
if( touch.captured || isVerticalSlide( currentSlide ) ) {
event.preventDefault();
}
}
// Not embedded? Block them all to avoid needless tossing
// around of the viewport in iOS
else {
event.preventDefault();
}

Hakim El Hattab
committed
}
}
// 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();
}

Hakim El Hattab
committed
}
/**
* Handler for the 'touchend' event.

Hakim El Hattab
committed
*/
function onTouchEnd( event ) {

Hakim El Hattab
committed
}
/**
* Convert pointer down to touch start.
*/
function onPointerDown( event ) {
if( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === "touch" ) {
event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
}
}
/**
* Convert pointer move to touch move.
*/
function onPointerMove( event ) {
if( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === "touch" ) {
event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
}
}
/**
* Convert pointer up to touch end.
*/
function onPointerUp( event ) {
if( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === "touch" ) {
event.touches = [{ clientX: event.clientX, clientY: event.clientY }];

Hakim El Hattab
committed
/**
* Handles mouse wheel scrolling, throttled to avoid skipping
* multiple slides.

Hakim El Hattab
committed
*/
function onDocumentMouseScroll( event ) {
if( Date.now() - lastMouseWheelStep > 600 ) {
lastMouseWheelStep = Date.now();

Hakim El Hattab
committed
var delta = event.detail || -event.wheelDelta;
if( delta > 0 ) {
navigateNext();
}
else {
navigatePrev();
}

Hakim El Hattab
committed
}
* Clicking on the progress bar results in a navigation to the
* closest approximate horizontal slide using this equation:
*
* ( clickX / presentationWidth ) * numberOfSlides
*/

Hakim El Hattab
committed
function onProgressClicked( event ) {
onUserInput( event );

Hakim El Hattab
committed
event.preventDefault();

Hakim El Hattab
committed
var slidesTotal = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ).length;
var slideIndex = Math.floor( ( event.clientX / dom.wrapper.offsetWidth ) * slidesTotal );
slide( slideIndex );

Hakim El Hattab
committed
/**
* Event handler for navigation control buttons.

Hakim El Hattab
committed
*/
function onNavigateLeftClicked( event ) { event.preventDefault(); onUserInput(); navigateLeft(); }
function onNavigateRightClicked( event ) { event.preventDefault(); onUserInput(); navigateRight(); }
function onNavigateUpClicked( event ) { event.preventDefault(); onUserInput(); navigateUp(); }
function onNavigateDownClicked( event ) { event.preventDefault(); onUserInput(); navigateDown(); }
function onNavigatePrevClicked( event ) { event.preventDefault(); onUserInput(); navigatePrev(); }
function onNavigateNextClicked( event ) { event.preventDefault(); onUserInput(); navigateNext(); }

Hakim El Hattab
committed

Hakim El Hattab
committed
/**
* Handler for the window level 'hashchange' event.
*/
function onWindowHashChange( event ) {

Hakim El Hattab
committed
readURL();

Hakim El Hattab
committed
}
/**
* Handler for the window level 'resize' event.
*/
function onWindowResize( event ) {

Espen Hovlandsdal
committed
/**
* Handle for the window level 'visibilitychange' event.
*/
function onPageVisibilityChange( event ) {
var isHidden = document.webkitHidden ||
document.msHidden ||
document.hidden;
// If, after clicking a link or similar and we're coming back,
// focus the document.body to ensure we can use keyboard shortcuts
if( isHidden === false && document.activeElement !== document.body ) {
document.activeElement.blur();
document.body.focus();
}
}

Hakim El Hattab
committed
/**
* 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( eventsAreBound && isOverview() ) {

Hakim El Hattab
committed
event.preventDefault();
var element = event.target;
while( element && !element.nodeName.match( /section/gi ) ) {
element = element.parentNode;
}
if( element && !element.classList.contains( 'disabled' ) ) {
deactivateOverview();
if( element.nodeName.match( /section/gi ) ) {
var h = parseInt( element.getAttribute( 'data-index-h' ), 10 ),
v = parseInt( element.getAttribute( 'data-index-v' ), 10 );
slide( h, v );
}

Hakim El Hattab
committed
}

Hakim El Hattab
committed
}

Hakim El Hattab
committed
/**
* Handles clicks on links that are set to preview in the
* iframe overlay.
*/
function onPreviewLinkClicked( event ) {
if( event.currentTarget && event.currentTarget.hasAttribute( 'href' ) ) {
var url = event.currentTarget.getAttribute( 'href' );
if( url ) {
showPreview( url );
event.preventDefault();
}

Hakim El Hattab
committed
}
}
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
/**
* Handles click on the auto-sliding controls element.
*/
function onAutoSlidePlayerClick( event ) {
// Replay
if( Reveal.isLastSlide() && config.loop === false ) {
slide( 0, 0 );
resumeAutoSlide();
}
// Resume
else if( autoSlidePaused ) {
resumeAutoSlide();
}
// Pause
else {
pauseAutoSlide();
}
}
// --------------------------------------------------------------------//
// ------------------------ PLAYBACK COMPONENT ------------------------//
// --------------------------------------------------------------------//
/**
* Constructor for the playback component, which displays
* play/pause/progress controls.
*