move overview to new module

edit
Hakim El Hattab 2020-03-09 20:57:12 +01:00
parent 75ef44ca69
commit cd78bbd48d
4 changed files with 351 additions and 304 deletions

2
dist/reveal.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,9 @@
import { extend, toArray } from '../utils/util.js' import { extend, toArray } from '../utils/util.js'
/** /**
* * Handles sorting and navigation of slide fragments.
* Fragments are elements within a slide that are
* revealed/animated incrementally.
*/ */
export default class Fragments { export default class Fragments {

View File

@ -0,0 +1,249 @@
import { SLIDES_SELECTOR } from '../utils/constants.js'
import { extend, toArray, transformElement } from '../utils/util.js'
/**
* Handles all logic related to the overview mode
* (birds-eye view of all slides).
*/
export default class Overview {
constructor( Reveal ) {
this.Reveal = Reveal;
this.active = false;
this.onSlideClicked = this.onSlideClicked.bind( this );
}
/**
* Displays the overview of slides (quick nav) by scaling
* down and arranging all slide elements.
*/
activate() {
// Only proceed if enabled in config
if( this.Reveal.getConfig().overview && !this.isActive() ) {
this.active = true;
this.Reveal.getRevealElement().classList.add( 'overview' );
// Don't auto-slide while in overview mode
this.Reveal.cancelAutoSlide();
// Move the backgrounds element into the slide container to
// that the same scaling is applied
this.Reveal.getSlidesElement().appendChild( this.Reveal.getBackgroundsElement() );
// Clicking on an overview slide navigates to it
toArray( this.Reveal.getRevealElement().querySelectorAll( SLIDES_SELECTOR ) ).forEach( slide => {
if( !slide.classList.contains( 'stack' ) ) {
slide.addEventListener( 'click', this.onSlideClicked, true );
}
} );
// Calculate slide sizes
const margin = 70;
const slideSize = this.Reveal.getComputedSlideSize();
this.overviewSlideWidth = slideSize.width + margin;
this.overviewSlideHeight = slideSize.height + margin;
// Reverse in RTL mode
if( this.Reveal.getConfig().rtl ) {
this.overviewSlideWidth = -this.overviewSlideWidth;
}
this.Reveal.updateSlidesVisibility();
this.layout();
this.update();
this.Reveal.layout();
const indices = this.Reveal.getIndices();
// Notify observers of the overview showing
this.Reveal.dispatchEvent( 'overviewshown', {
'indexh': indices.h,
'indexv': indices.v,
'currentSlide': this.Reveal.getCurrentSlide()
} );
}
}
/**
* Uses CSS transforms to position all slides in a grid for
* display inside of the overview mode.
*/
layout() {
// Layout slides
this.Reveal.getHorizontalSlides().forEach( ( hslide, h ) => {
hslide.setAttribute( 'data-index-h', h );
transformElement( hslide, 'translate3d(' + ( h * this.overviewSlideWidth ) + 'px, 0, 0)' );
if( hslide.classList.contains( 'stack' ) ) {
toArray( hslide.querySelectorAll( 'section' ) ).forEach( ( vslide, v ) => {
vslide.setAttribute( 'data-index-h', h );
vslide.setAttribute( 'data-index-v', v );
transformElement( vslide, 'translate3d(0, ' + ( v * this.overviewSlideHeight ) + 'px, 0)' );
} );
}
} );
// Layout slide backgrounds
toArray( this.Reveal.getBackgroundsElement().childNodes ).forEach( ( hbackground, h ) => {
transformElement( hbackground, 'translate3d(' + ( h * this.overviewSlideWidth ) + 'px, 0, 0)' );
toArray( hbackground.querySelectorAll( '.slide-background' ) ).forEach( ( vbackground, v ) => {
transformElement( vbackground, 'translate3d(0, ' + ( v * this.overviewSlideHeight ) + 'px, 0)' );
} );
} );
}
/**
* Moves the overview viewport to the current slides.
* Called each time the current slide changes.
*/
update() {
const vmin = Math.min( window.innerWidth, window.innerHeight );
const scale = Math.max( vmin / 5, 150 ) / vmin;
const indices = this.Reveal.getIndices();
this.Reveal.transformSlides( {
overview: [
'scale('+ scale +')',
'translateX('+ ( -indices.h * this.overviewSlideWidth ) +'px)',
'translateY('+ ( -indices.v * this.overviewSlideHeight ) +'px)'
].join( ' ' )
} );
}
/**
* Exits the slide overview and enters the currently
* active slide.
*/
deactivate() {
// Only proceed if enabled in config
if( this.Reveal.getConfig().overview ) {
this.active = false;
this.Reveal.getRevealElement().classList.remove( 'overview' );
// Temporarily add a class so that transitions can do different things
// depending on whether they are exiting/entering overview, or just
// moving from slide to slide
this.Reveal.getRevealElement().classList.add( 'overview-deactivating' );
setTimeout( () => {
this.Reveal.getRevealElement().classList.remove( 'overview-deactivating' );
}, 1 );
// Move the background element back out
this.Reveal.getRevealElement().appendChild( this.Reveal.getBackgroundsElement() );
// Clean up changes made to slides
toArray( this.Reveal.getRevealElement().querySelectorAll( SLIDES_SELECTOR ) ).forEach( slide => {
transformElement( slide, '' );
slide.removeEventListener( 'click', this.onSlideClicked, true );
} );
// Clean up changes made to backgrounds
toArray( this.Reveal.getBackgroundsElement().querySelectorAll( '.slide-background' ) ).forEach( background => {
transformElement( background, '' );
} );
this.Reveal.transformSlides( { overview: '' } );
const indices = this.Reveal.getIndices();
this.Reveal.slide( indices.h, indices.v );
this.Reveal.layout();
this.Reveal.cueAutoSlide();
// Notify observers of the overview hiding
this.Reveal.dispatchEvent( 'overviewhidden', {
'indexh': indices.h,
'indexv': indices.v,
'currentSlide': this.Reveal.getCurrentSlide()
} );
}
}
/**
* Toggles the slide overview mode on and off.
*
* @param {Boolean} [override] Flag which overrides the
* toggle logic and forcibly sets the desired state. True means
* overview is open, false means it's closed.
*/
toggle( override ) {
if( typeof override === 'boolean' ) {
override ? this.activate() : this.deactivate();
}
else {
this.isActive() ? this.deactivate() : this.activate();
}
}
/**
* Checks if the overview is currently active.
*
* @return {Boolean} true if the overview is active,
* false otherwise
*/
isActive() {
return this.active;
}
/**
* Invoked when a slide is and we're in the overview.
*
* @param {object} event
*/
onSlideClicked( event ) {
if( this.isActive() ) {
event.preventDefault();
let element = event.target;
while( element && !element.nodeName.match( /section/gi ) ) {
element = element.parentNode;
}
if( element && !element.classList.contains( 'disabled' ) ) {
this.deactivate();
if( element.nodeName.match( /section/gi ) ) {
let h = parseInt( element.getAttribute( 'data-index-h' ), 10 ),
v = parseInt( element.getAttribute( 'data-index-v' ), 10 );
this.Reveal.slide( h, v );
}
}
}
}
}

View File

@ -1,6 +1,7 @@
import SlideContent from './controllers/slidecontent.js' import SlideContent from './controllers/slidecontent.js'
import AutoAnimate from './controllers/autoanimate.js' import AutoAnimate from './controllers/autoanimate.js'
import Fragments from './controllers/fragments.js' import Fragments from './controllers/fragments.js'
import Overview from './controllers/overview.js'
import Plugins from './controllers/plugins.js' import Plugins from './controllers/plugins.js'
import Playback from './components/playback.js' import Playback from './components/playback.js'
import defaultConfig from './config.js' import defaultConfig from './config.js'
@ -37,21 +38,12 @@ export default function( revealElement, options ) {
// The reveal.js version // The reveal.js version
const VERSION = '4.0.0-dev'; const VERSION = '4.0.0-dev';
const UA = navigator.userAgent;
// Configuration defaults, can be overridden at initialization time // Configuration defaults, can be overridden at initialization time
let config, let config,
// Flags if reveal.js is loaded (has dispatched the 'ready' event) // Flags if reveal.js is loaded (has dispatched the 'ready' event)
ready = false, ready = false,
// Flags if the overview mode is currently active
overview = false,
// Holds the dimensions of our overview slides, including margins
overviewSlideWidth = null,
overviewSlideHeight = null,
// The horizontal and vertical index of the currently active slide // The horizontal and vertical index of the currently active slide
indexh, indexh,
indexv, indexv,
@ -93,6 +85,8 @@ export default function( revealElement, options ) {
// Controls navigation between slide fragments // Controls navigation between slide fragments
fragments = new Fragments( Reveal ), fragments = new Fragments( Reveal ),
overview = new Overview( Reveal ),
// List of asynchronously loaded reveal.js dependencies // List of asynchronously loaded reveal.js dependencies
asyncDependencies = [], asyncDependencies = [],
@ -1489,8 +1483,8 @@ export default function( revealElement, options ) {
updateProgress(); updateProgress();
updateParallax(); updateParallax();
if( isOverview() ) { if( overview.isActive() ) {
updateOverview(); overview.update();
} }
} }
@ -1606,199 +1600,6 @@ export default function( revealElement, options ) {
} }
/**
* Displays the overview of slides (quick nav) by scaling
* down and arranging all slide elements.
*/
function activateOverview() {
// Only proceed if enabled in config
if( config.overview && !isOverview() ) {
overview = true;
dom.wrapper.classList.add( 'overview' );
// Don't auto-slide while in overview mode
cancelAutoSlide();
// Move the backgrounds element into the slide container to
// that the same scaling is applied
dom.slides.appendChild( dom.background );
// Clicking on an overview slide navigates to it
toArray( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) ).forEach( slide => {
if( !slide.classList.contains( 'stack' ) ) {
slide.addEventListener( 'click', onOverviewSlideClicked, true );
}
} );
// Calculate slide sizes
const margin = 70;
const slideSize = getComputedSlideSize();
overviewSlideWidth = slideSize.width + margin;
overviewSlideHeight = slideSize.height + margin;
// Reverse in RTL mode
if( config.rtl ) {
overviewSlideWidth = -overviewSlideWidth;
}
updateSlidesVisibility();
layoutOverview();
updateOverview();
layout();
// Notify observers of the overview showing
dispatchEvent( 'overviewshown', {
'indexh': indexh,
'indexv': indexv,
'currentSlide': currentSlide
} );
}
}
/**
* Uses CSS transforms to position all slides in a grid for
* display inside of the overview mode.
*/
function layoutOverview() {
// Layout slides
toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ).forEach( ( hslide, h ) => {
hslide.setAttribute( 'data-index-h', h );
transformElement( hslide, 'translate3d(' + ( h * overviewSlideWidth ) + 'px, 0, 0)' );
if( hslide.classList.contains( 'stack' ) ) {
toArray( hslide.querySelectorAll( 'section' ) ).forEach( ( vslide, v ) => {
vslide.setAttribute( 'data-index-h', h );
vslide.setAttribute( 'data-index-v', v );
transformElement( vslide, 'translate3d(0, ' + ( v * overviewSlideHeight ) + 'px, 0)' );
} );
}
} );
// Layout slide backgrounds
toArray( dom.background.childNodes ).forEach( ( hbackground, h ) => {
transformElement( hbackground, 'translate3d(' + ( h * overviewSlideWidth ) + 'px, 0, 0)' );
toArray( hbackground.querySelectorAll( '.slide-background' ) ).forEach( ( vbackground, v ) => {
transformElement( vbackground, 'translate3d(0, ' + ( v * overviewSlideHeight ) + 'px, 0)' );
} );
} );
}
/**
* Moves the overview viewport to the current slides.
* Called each time the current slide changes.
*/
function updateOverview() {
const vmin = Math.min( window.innerWidth, window.innerHeight );
const scale = Math.max( vmin / 5, 150 ) / vmin;
transformSlides( {
overview: [
'scale('+ scale +')',
'translateX('+ ( -indexh * overviewSlideWidth ) +'px)',
'translateY('+ ( -indexv * overviewSlideHeight ) +'px)'
].join( ' ' )
} );
}
/**
* Exits the slide overview and enters the currently
* active slide.
*/
function deactivateOverview() {
// Only proceed if enabled in config
if( config.overview ) {
overview = false;
dom.wrapper.classList.remove( 'overview' );
// Temporarily add a class so that transitions can do different things
// depending on whether they are exiting/entering overview, or just
// moving from slide to slide
dom.wrapper.classList.add( 'overview-deactivating' );
setTimeout( () => {
dom.wrapper.classList.remove( 'overview-deactivating' );
}, 1 );
// Move the background element back out
dom.wrapper.appendChild( dom.background );
// Clean up changes made to slides
toArray( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) ).forEach( slide => {
transformElement( slide, '' );
slide.removeEventListener( 'click', onOverviewSlideClicked, true );
} );
// Clean up changes made to backgrounds
toArray( dom.background.querySelectorAll( '.slide-background' ) ).forEach( background => {
transformElement( background, '' );
} );
transformSlides( { overview: '' } );
slide( indexh, indexv );
layout();
cueAutoSlide();
// Notify observers of the overview hiding
dispatchEvent( 'overviewhidden', {
'indexh': indexh,
'indexv': indexv,
'currentSlide': currentSlide
} );
}
}
/**
* Toggles the slide overview mode on and off.
*
* @param {Boolean} [override] Flag which overrides the
* toggle logic and forcibly sets the desired state. True means
* overview is open, false means it's closed.
*/
function toggleOverview( override ) {
if( typeof override === 'boolean' ) {
override ? activateOverview() : deactivateOverview();
}
else {
isOverview() ? deactivateOverview() : activateOverview();
}
}
/**
* Checks if the overview is currently active.
*
* @return {Boolean} true if the overview is active,
* false otherwise
*/
function isOverview() {
return overview;
}
/** /**
* Return a hash URL that will resolve to the given slide location. * Return a hash URL that will resolve to the given slide location.
* *
@ -1851,6 +1652,55 @@ export default function( revealElement, options ) {
} }
/**
* Returns true if we're on the last slide in the current
* vertical stack.
*/
function isLastVerticalSlide() {
if( currentSlide && isVerticalSlide( currentSlide ) ) {
// Does this slide have a next sibling?
if( currentSlide.nextElementSibling ) return false;
return true;
}
return false;
}
/**
* Returns true if we're currently on the first slide in
* the presentation.
*/
function isFirstSlide() {
return indexh === 0 && indexv === 0;
}
/**
* Returns true if we're currently on the last slide in
* the presenation. If the last slide is a stack, we only
* consider this the last slide if it's at the end of the
* stack.
*/
function isLastSlide() {
if( currentSlide ) {
// Does this slide have a next sibling?
if( currentSlide.nextElementSibling ) return false;
// If it's vertical, does its parent have a next sibling?
if( isVerticalSlide( currentSlide ) && currentSlide.parentNode.nextElementSibling ) return false;
return true;
}
return false;
}
/** /**
* Shows the mouse pointer after it has been hidden with * Shows the mouse pointer after it has been hidden with
* #hideCursor. * #hideCursor.
@ -1991,7 +1841,7 @@ export default function( revealElement, options ) {
// If no vertical index is specified and the upcoming slide is a // If no vertical index is specified and the upcoming slide is a
// stack, resume at its previous vertical index // stack, resume at its previous vertical index
if( v === undefined && !isOverview() ) { if( v === undefined && !overview.isActive() ) {
v = getPreviousVerticalIndex( horizontalSlides[ h ] ); v = getPreviousVerticalIndex( horizontalSlides[ h ] );
} }
@ -2020,8 +1870,8 @@ export default function( revealElement, options ) {
layout(); layout();
// Update the overview if it's currently active // Update the overview if it's currently active
if( isOverview() ) { if( overview.isActive() ) {
updateOverview(); overview.update();
} }
// Find the current horizontal slide and any possible vertical slides // Find the current horizontal slide and any possible vertical slides
@ -2052,7 +1902,7 @@ export default function( revealElement, options ) {
previousSlide.setAttribute( 'aria-hidden', 'true' ); previousSlide.setAttribute( 'aria-hidden', 'true' );
// Reset all slides upon navigate to home // Reset all slides upon navigate to home
if( Reveal.isFirstSlide() ) { if( isFirstSlide() ) {
// Launch async task // Launch async task
setTimeout( () => { setTimeout( () => {
getVerticalStacks().forEach( slide => { getVerticalStacks().forEach( slide => {
@ -2118,7 +1968,7 @@ export default function( revealElement, options ) {
cueAutoSlide(); cueAutoSlide();
// Auto-animation // Auto-animation
if( slideChanged && previousSlide && currentSlide && !isOverview() ) { if( slideChanged && previousSlide && currentSlide && !overview.isActive() ) {
// Skip the slide transition between our two slides // Skip the slide transition between our two slides
// when auto-animating individual elements // when auto-animating individual elements
@ -2185,8 +2035,8 @@ export default function( revealElement, options ) {
slideContent.startEmbeddedContent( currentSlide ); slideContent.startEmbeddedContent( currentSlide );
} }
if( isOverview() ) { if( overview.isActive() ) {
layoutOverview(); overview.layout();
} }
} }
@ -2388,12 +2238,12 @@ export default function( revealElement, options ) {
// The number of steps away from the present slide that will // The number of steps away from the present slide that will
// be visible // be visible
let viewDistance = isOverview() ? 10 : config.viewDistance; let viewDistance = overview.isActive() ? 10 : config.viewDistance;
// Shorten the view distance on devices that typically have // Shorten the view distance on devices that typically have
// less resources // less resources
if( isMobile ) { if( isMobile ) {
viewDistance = isOverview() ? 6 : config.mobileViewDistance; viewDistance = overview.isActive() ? 6 : config.mobileViewDistance;
} }
// All slides need to be visible when exporting to PDF // All slides need to be visible when exporting to PDF
@ -3313,7 +3163,7 @@ export default function( revealElement, options ) {
indexv: indices.v, indexv: indices.v,
indexf: indices.f, indexf: indices.f,
paused: isPaused(), paused: isPaused(),
overview: isOverview() overview: overview.isActive()
}; };
} }
@ -3336,8 +3186,8 @@ export default function( revealElement, options ) {
togglePause( pausedFlag ); togglePause( pausedFlag );
} }
if( typeof overviewFlag === 'boolean' && overviewFlag !== isOverview() ) { if( typeof overviewFlag === 'boolean' && overviewFlag !== overview.isActive() ) {
toggleOverview( overviewFlag ); overview.toggle( overviewFlag );
} }
} }
@ -3401,7 +3251,7 @@ export default function( revealElement, options ) {
// - The presentation isn't paused // - The presentation isn't paused
// - The overview isn't active // - The overview isn't active
// - The presentation isn't over // - The presentation isn't over
if( autoSlide && !autoSlidePaused && !isPaused() && !isOverview() && ( !Reveal.isLastSlide() || fragments.availableRoutes().next || config.loop === true ) ) { if( autoSlide && !autoSlidePaused && !isPaused() && !overview.isActive() && ( !isLastSlide() || fragments.availableRoutes().next || config.loop === true ) ) {
autoSlideTimeout = setTimeout( () => { autoSlideTimeout = setTimeout( () => {
if( typeof config.autoSlideMethod === 'function' ) { if( typeof config.autoSlideMethod === 'function' ) {
config.autoSlideMethod() config.autoSlideMethod()
@ -3462,12 +3312,12 @@ export default function( revealElement, options ) {
// Reverse for RTL // Reverse for RTL
if( config.rtl ) { if( config.rtl ) {
if( ( isOverview() || fragments.next() === false ) && availableRoutes().left ) { if( ( overview.isActive() || fragments.next() === false ) && availableRoutes().left ) {
slide( indexh + 1, config.navigationMode === 'grid' ? indexv : undefined ); slide( indexh + 1, config.navigationMode === 'grid' ? indexv : undefined );
} }
} }
// Normal navigation // Normal navigation
else if( ( isOverview() || fragments.prev() === false ) && availableRoutes().left ) { else if( ( overview.isActive() || fragments.prev() === false ) && availableRoutes().left ) {
slide( indexh - 1, config.navigationMode === 'grid' ? indexv : undefined ); slide( indexh - 1, config.navigationMode === 'grid' ? indexv : undefined );
} }
@ -3479,12 +3329,12 @@ export default function( revealElement, options ) {
// Reverse for RTL // Reverse for RTL
if( config.rtl ) { if( config.rtl ) {
if( ( isOverview() || fragments.prev() === false ) && availableRoutes().right ) { if( ( overview.isActive() || fragments.prev() === false ) && availableRoutes().right ) {
slide( indexh - 1, config.navigationMode === 'grid' ? indexv : undefined ); slide( indexh - 1, config.navigationMode === 'grid' ? indexv : undefined );
} }
} }
// Normal navigation // Normal navigation
else if( ( isOverview() || fragments.next() === false ) && availableRoutes().right ) { else if( ( overview.isActive() || fragments.next() === false ) && availableRoutes().right ) {
slide( indexh + 1, config.navigationMode === 'grid' ? indexv : undefined ); slide( indexh + 1, config.navigationMode === 'grid' ? indexv : undefined );
} }
@ -3493,7 +3343,7 @@ export default function( revealElement, options ) {
function navigateUp() { function navigateUp() {
// Prioritize hiding fragments // Prioritize hiding fragments
if( ( isOverview() || fragments.prev() === false ) && availableRoutes().up ) { if( ( overview.isActive() || fragments.prev() === false ) && availableRoutes().up ) {
slide( indexh, indexv - 1 ); slide( indexh, indexv - 1 );
} }
@ -3504,7 +3354,7 @@ export default function( revealElement, options ) {
hasNavigatedVertically = true; hasNavigatedVertically = true;
// Prioritize revealing fragments // Prioritize revealing fragments
if( ( isOverview() || fragments.next() === false ) && availableRoutes().down ) { if( ( overview.isActive() || fragments.next() === false ) && availableRoutes().down ) {
slide( indexh, indexv + 1 ); slide( indexh, indexv + 1 );
} }
@ -3560,7 +3410,7 @@ export default function( revealElement, options ) {
// When looping is enabled `routes.down` is always available // When looping is enabled `routes.down` is always available
// so we need a separate check for when we've reached the // so we need a separate check for when we've reached the
// end of a stack and should move horizontally // end of a stack and should move horizontally
if( routes.down && routes.right && config.loop && Reveal.isLastVerticalSlide( currentSlide ) ) { if( routes.down && routes.right && config.loop && isLastVerticalSlide( currentSlide ) ) {
routes.down = false; routes.down = false;
} }
@ -3773,7 +3623,7 @@ export default function( revealElement, options ) {
if( firstSlideShortcut ) { if( firstSlideShortcut ) {
slide( 0 ); slide( 0 );
} }
else if( !isOverview() && useLinearMode ) { else if( !overview.isActive() && useLinearMode ) {
navigatePrev(); navigatePrev();
} }
else { else {
@ -3785,7 +3635,7 @@ export default function( revealElement, options ) {
if( lastSlideShortcut ) { if( lastSlideShortcut ) {
slide( Number.MAX_VALUE ); slide( Number.MAX_VALUE );
} }
else if( !isOverview() && useLinearMode ) { else if( !overview.isActive() && useLinearMode ) {
navigateNext(); navigateNext();
} }
else { else {
@ -3794,7 +3644,7 @@ export default function( revealElement, options ) {
} }
// K, UP // K, UP
else if( keyCode === 75 || keyCode === 38 ) { else if( keyCode === 75 || keyCode === 38 ) {
if( !isOverview() && useLinearMode ) { if( !overview.isActive() && useLinearMode ) {
navigatePrev(); navigatePrev();
} }
else { else {
@ -3803,7 +3653,7 @@ export default function( revealElement, options ) {
} }
// J, DOWN // J, DOWN
else if( keyCode === 74 || keyCode === 40 ) { else if( keyCode === 74 || keyCode === 40 ) {
if( !isOverview() && useLinearMode ) { if( !overview.isActive() && useLinearMode ) {
navigateNext(); navigateNext();
} }
else { else {
@ -3820,8 +3670,8 @@ export default function( revealElement, options ) {
} }
// SPACE // SPACE
else if( keyCode === 32 ) { else if( keyCode === 32 ) {
if( isOverview() ) { if( overview.isActive() ) {
deactivateOverview(); overview.deactivate();
} }
if( event.shiftKey ) { if( event.shiftKey ) {
navigatePrev(); navigatePrev();
@ -3861,7 +3711,7 @@ export default function( revealElement, options ) {
closeOverlay(); closeOverlay();
} }
else { else {
toggleOverview(); overview.toggle();
} }
event.preventDefault && event.preventDefault(); event.preventDefault && event.preventDefault();
@ -4134,40 +3984,6 @@ export default function( revealElement, options ) {
} }
/**
* Invoked when a slide is and we're in the overview.
*
* @param {object} event
*/
function onOverviewSlideClicked( event ) {
// TODO There's a bug here where the event listeners are not
// removed after deactivating the overview.
if( eventsAreBound && isOverview() ) {
event.preventDefault();
let 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 ) ) {
let h = parseInt( element.getAttribute( 'data-index-h' ), 10 ),
v = parseInt( element.getAttribute( 'data-index-v' ), 10 );
slide( h, v );
}
}
}
}
/** /**
* Handles clicks on links that are set to preview in the * Handles clicks on links that are set to preview in the
* iframe overlay. * iframe overlay.
@ -4194,7 +4010,7 @@ export default function( revealElement, options ) {
function onAutoSlidePlayerClick( event ) { function onAutoSlidePlayerClick( event ) {
// Replay // Replay
if( Reveal.isLastSlide() && config.loop === false ) { if( isLastSlide() && config.loop === false ) {
slide( 0, 0 ); slide( 0, 0 );
resumeAutoSlide(); resumeAutoSlide();
} }
@ -4264,7 +4080,7 @@ export default function( revealElement, options ) {
toggleHelp, toggleHelp,
// Toggles the overview mode on/off // Toggles the overview mode on/off
toggleOverview, toggleOverview: () => overview.toggle,
// Toggles the "black screen" mode on/off // Toggles the "black screen" mode on/off
togglePause, togglePause,
@ -4272,8 +4088,13 @@ export default function( revealElement, options ) {
// Toggles the auto slide mode on/off // Toggles the auto slide mode on/off
toggleAutoSlide, toggleAutoSlide,
// Slide navigation checks
isFirstSlide,
isLastSlide,
isLastVerticalSlide,
// State checks // State checks
isOverview, isOverview: () => overview.isActive,
isPaused, isPaused,
isAutoSliding, isAutoSliding,
isSpeakerNotes, isSpeakerNotes,
@ -4393,52 +4214,27 @@ export default function( revealElement, options ) {
// Returns the top-level DOM element // Returns the top-level DOM element
getRevealElement: () => dom.wrapper || document.querySelector( '.reveal' ), getRevealElement: () => dom.wrapper || document.querySelector( '.reveal' ),
getSlidesElement: () => dom.slides, getSlidesElement: () => dom.slides,
getBackgroundsElement: () => dom.background,
// Returns true if we're currently on the first slide
isFirstSlide: () => indexh === 0 && indexv === 0,
// Returns true if we're currently on the last slide
isLastSlide: () => {
if( currentSlide ) {
// Does this slide have a next sibling?
if( currentSlide.nextElementSibling ) return false;
// If it's vertical, does its parent have a next sibling?
if( isVerticalSlide( currentSlide ) && currentSlide.parentNode.nextElementSibling ) return false;
return true;
}
return false;
},
// Returns true if we're on the last slide in the current
// vertical stack
isLastVerticalSlide: () => {
if( currentSlide && isVerticalSlide( currentSlide ) ) {
// Does this slide have a next sibling?
if( currentSlide.nextElementSibling ) return false;
return true;
}
return false;
},
// Checks if reveal.js has been loaded and is ready for use // Checks if reveal.js has been loaded and is ready for use
isReady: () => ready, isReady: () => ready,
// The following API methods are primarily intended for use
// by reveal.js controllers
// Methods for announcing content to screen readers // Methods for announcing content to screen readers
announceStatus, announceStatus,
getStatusText, getStatusText,
// Expose direct access to controllers via the API
slideContent, slideContent,
updateControls, updateControls,
updateProgress, updateProgress,
writeURL updateSlidesVisibility,
writeURL,
transformSlides,
cueAutoSlide,
cancelAutoSlide
} ); } );