new controls module for navigation arrows
This commit is contained in:
parent
2a06e0d1e5
commit
c50ec00419
2
dist/reveal.min.js
vendored
2
dist/reveal.min.js
vendored
File diff suppressed because one or more lines are too long
250
js/controllers/controls.js
vendored
Normal file
250
js/controllers/controls.js
vendored
Normal file
@ -0,0 +1,250 @@
|
||||
import { toArray } from '../utils/util.js'
|
||||
import { isMobile, isAndroid } from '../utils/device.js'
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export default class Controls {
|
||||
|
||||
constructor( Reveal ) {
|
||||
|
||||
this.Reveal = Reveal;
|
||||
|
||||
this.onNavigateLeftClicked = this.onNavigateLeftClicked.bind( this );
|
||||
this.onNavigateRightClicked = this.onNavigateRightClicked.bind( this );
|
||||
this.onNavigateUpClicked = this.onNavigateUpClicked.bind( this );
|
||||
this.onNavigateDownClicked = this.onNavigateDownClicked.bind( this );
|
||||
this.onNavigatePrevClicked = this.onNavigatePrevClicked.bind( this );
|
||||
this.onNavigateNextClicked = this.onNavigateNextClicked.bind( this );
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const rtl = this.Reveal.getConfig().rtl;
|
||||
const revealElement = this.Reveal.getRevealElement();
|
||||
|
||||
this.element = document.createElement( 'aside' );
|
||||
this.element.className = 'controls';
|
||||
this.element.innerHTML =
|
||||
`<button class="navigate-left" aria-label="${ rtl ? 'next slide' : 'previous slide' }"><div class="controls-arrow"></div></button>
|
||||
<button class="navigate-right" aria-label="${ rtl ? 'previous slide' : 'next slide' }"><div class="controls-arrow"></div></button>
|
||||
<button class="navigate-up" aria-label="above slide"><div class="controls-arrow"></div></button>
|
||||
<button class="navigate-down" aria-label="below slide"><div class="controls-arrow"></div></button>`;
|
||||
|
||||
this.Reveal.getRevealElement().appendChild( this.element );
|
||||
|
||||
// There can be multiple instances of controls throughout the page
|
||||
this.controlsLeft = toArray( revealElement.querySelectorAll( '.navigate-left' ) );
|
||||
this.controlsRight = toArray( revealElement.querySelectorAll( '.navigate-right' ) );
|
||||
this.controlsUp = toArray( revealElement.querySelectorAll( '.navigate-up' ) );
|
||||
this.controlsDown = toArray( revealElement.querySelectorAll( '.navigate-down' ) );
|
||||
this.controlsPrev = toArray( revealElement.querySelectorAll( '.navigate-prev' ) );
|
||||
this.controlsNext = toArray( revealElement.querySelectorAll( '.navigate-next' ) );
|
||||
|
||||
// The left, right and down arrows in the standard reveal.js controls
|
||||
this.controlsRightArrow = this.element.querySelector( '.navigate-right' );
|
||||
this.controlsLeftArrow = this.element.querySelector( '.navigate-left' );
|
||||
this.controlsDownArrow = this.element.querySelector( '.navigate-down' );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the reveal.js config is updated.
|
||||
*/
|
||||
configure( config, oldConfig ) {
|
||||
|
||||
this.element.style.display = config.controls ? 'block' : 'none';
|
||||
|
||||
this.element.setAttribute( 'data-controls-layout', config.controlsLayout );
|
||||
this.element.setAttribute( 'data-controls-back-arrows', config.controlsBackArrows );
|
||||
|
||||
}
|
||||
|
||||
bind() {
|
||||
|
||||
// Listen to both touch and click events, in case the device
|
||||
// supports both
|
||||
let pointerEvents = [ 'touchstart', 'click' ];
|
||||
|
||||
// Only support touch for Android, fixes double navigations in
|
||||
// stock browser
|
||||
if( isAndroid ) {
|
||||
pointerEvents = [ 'touchstart' ];
|
||||
}
|
||||
|
||||
pointerEvents.forEach( eventName => {
|
||||
this.controlsLeft.forEach( el => el.addEventListener( eventName, this.onNavigateLeftClicked, false ) );
|
||||
this.controlsRight.forEach( el => el.addEventListener( eventName, this.onNavigateRightClicked, false ) );
|
||||
this.controlsUp.forEach( el => el.addEventListener( eventName, this.onNavigateUpClicked, false ) );
|
||||
this.controlsDown.forEach( el => el.addEventListener( eventName, this.onNavigateDownClicked, false ) );
|
||||
this.controlsPrev.forEach( el => el.addEventListener( eventName, this.onNavigatePrevClicked, false ) );
|
||||
this.controlsNext.forEach( el => el.addEventListener( eventName, this.onNavigateNextClicked, false ) );
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
unbind() {
|
||||
|
||||
[ 'touchstart', 'click' ].forEach( eventName => {
|
||||
this.controlsLeft.forEach( el => el.removeEventListener( eventName, this.onNavigateLeftClicked, false ) );
|
||||
this.controlsRight.forEach( el => el.removeEventListener( eventName, this.onNavigateRightClicked, false ) );
|
||||
this.controlsUp.forEach( el => el.removeEventListener( eventName, this.onNavigateUpClicked, false ) );
|
||||
this.controlsDown.forEach( el => el.removeEventListener( eventName, this.onNavigateDownClicked, false ) );
|
||||
this.controlsPrev.forEach( el => el.removeEventListener( eventName, this.onNavigatePrevClicked, false ) );
|
||||
this.controlsNext.forEach( el => el.removeEventListener( eventName, this.onNavigateNextClicked, false ) );
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the state of all control/navigation arrows.
|
||||
*/
|
||||
update() {
|
||||
|
||||
let routes = this.Reveal.availableRoutes();
|
||||
|
||||
// Remove the 'enabled' class from all directions
|
||||
[...this.controlsLeft, ...this.controlsRight, ...this.controlsUp, ...this.controlsDown, ...this.controlsPrev, ...this.controlsNext].forEach( node => {
|
||||
node.classList.remove( 'enabled', 'fragmented' );
|
||||
|
||||
// Set 'disabled' attribute on all directions
|
||||
node.setAttribute( 'disabled', 'disabled' );
|
||||
} );
|
||||
|
||||
// Add the 'enabled' class to the available routes; remove 'disabled' attribute to enable buttons
|
||||
if( routes.left ) this.controlsLeft.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
if( routes.right ) this.controlsRight.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
if( routes.up ) this.controlsUp.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
if( routes.down ) this.controlsDown.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
|
||||
// Prev/next buttons
|
||||
if( routes.left || routes.up ) this.controlsPrev.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
if( routes.right || routes.down ) this.controlsNext.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
|
||||
// Highlight fragment directions
|
||||
let currentSlide = this.Reveal.getCurrentSlide();
|
||||
if( currentSlide ) {
|
||||
|
||||
let fragmentsRoutes = this.Reveal.fragments.availableRoutes();
|
||||
|
||||
// Always apply fragment decorator to prev/next buttons
|
||||
if( fragmentsRoutes.prev ) this.controlsPrev.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
if( fragmentsRoutes.next ) this.controlsNext.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
|
||||
// Apply fragment decorators to directional buttons based on
|
||||
// what slide axis they are in
|
||||
if( this.Reveal.isVerticalSlide( currentSlide ) ) {
|
||||
if( fragmentsRoutes.prev ) this.controlsUp.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
if( fragmentsRoutes.next ) this.controlsDown.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
}
|
||||
else {
|
||||
if( fragmentsRoutes.prev ) this.controlsLeft.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
if( fragmentsRoutes.next ) this.controlsRight.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( this.Reveal.getConfig().controlsTutorial ) {
|
||||
|
||||
let indices = this.Reveal.getIndices();
|
||||
|
||||
// Highlight control arrows with an animation to ensure
|
||||
// that the viewer knows how to navigate
|
||||
if( !this.Reveal.hasNavigatedVertically() && routes.down ) {
|
||||
this.controlsDownArrow.classList.add( 'highlight' );
|
||||
}
|
||||
else {
|
||||
this.controlsDownArrow.classList.remove( 'highlight' );
|
||||
|
||||
if( this.Reveal.getConfig().rtl ) {
|
||||
|
||||
if( !this.Reveal.hasNavigatedHorizontally() && routes.left && indices.v === 0 ) {
|
||||
this.controlsLeftArrow.classList.add( 'highlight' );
|
||||
}
|
||||
else {
|
||||
this.controlsLeftArrow.classList.remove( 'highlight' );
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if( !this.Reveal.hasNavigatedHorizontally() && routes.right && indices.v === 0 ) {
|
||||
this.controlsRightArrow.classList.add( 'highlight' );
|
||||
}
|
||||
else {
|
||||
this.controlsRightArrow.classList.remove( 'highlight' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handlers for navigation control buttons.
|
||||
*/
|
||||
onNavigateLeftClicked( event ) {
|
||||
|
||||
event.preventDefault();
|
||||
this.Reveal.onUserInput();
|
||||
|
||||
if( this.Reveal.getConfig().navigationMode === 'linear' ) {
|
||||
this.Reveal.prev();
|
||||
}
|
||||
else {
|
||||
this.Reveal.left();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onNavigateRightClicked( event ) {
|
||||
|
||||
event.preventDefault();
|
||||
this.Reveal.onUserInput();
|
||||
|
||||
if( this.Reveal.getConfig().navigationMode === 'linear' ) {
|
||||
this.Reveal.next();
|
||||
}
|
||||
else {
|
||||
this.Reveal.right();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onNavigateUpClicked( event ) {
|
||||
|
||||
event.preventDefault();
|
||||
this.Reveal.onUserInput();
|
||||
|
||||
this.Reveal.up();
|
||||
|
||||
}
|
||||
|
||||
onNavigateDownClicked( event ) {
|
||||
|
||||
event.preventDefault();
|
||||
this.Reveal.onUserInput();
|
||||
|
||||
this.Reveal.down();
|
||||
|
||||
}
|
||||
|
||||
onNavigatePrevClicked( event ) {
|
||||
|
||||
event.preventDefault();
|
||||
this.Reveal.onUserInput();
|
||||
|
||||
this.Reveal.prev();
|
||||
|
||||
}
|
||||
|
||||
onNavigateNextClicked( event ) {
|
||||
|
||||
event.preventDefault();
|
||||
this.Reveal.onUserInput();
|
||||
|
||||
this.Reveal.next();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -14,7 +14,7 @@ export default class Fragments {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called whenever the reveal.js config is updated.
|
||||
* Called when the reveal.js config is updated.
|
||||
*/
|
||||
configure( config, oldConfig ) {
|
||||
|
||||
@ -331,7 +331,8 @@ export default class Fragments {
|
||||
});
|
||||
}
|
||||
|
||||
this.Reveal.updateControls();
|
||||
this.Reveal.controls.update();
|
||||
|
||||
this.Reveal.updateProgress();
|
||||
|
||||
if( this.Reveal.getConfig().fragmentInURL ) {
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { extend, toArray } from '../utils/util.js'
|
||||
|
||||
/**
|
||||
*
|
||||
* Handles the showing and
|
||||
*/
|
||||
export default class Notes {
|
||||
|
||||
@ -81,7 +79,7 @@ export default class Notes {
|
||||
*
|
||||
* @return {boolean}
|
||||
*/
|
||||
isSpeakerNotes() {
|
||||
isSpeakerNotesWindow() {
|
||||
|
||||
return !!window.location.search.match( /receiver/gi );
|
||||
|
||||
|
190
js/reveal.js
190
js/reveal.js
@ -6,13 +6,14 @@ import Fragments from './controllers/fragments.js'
|
||||
import Overview from './controllers/overview.js'
|
||||
import Keyboard from './controllers/keyboard.js'
|
||||
import Location from './controllers/location.js'
|
||||
import Controls from './controllers/controls.js'
|
||||
import Plugins from './controllers/plugins.js'
|
||||
import Print from './controllers/print.js'
|
||||
import Touch from './controllers/touch.js'
|
||||
import Notes from './controllers/notes.js'
|
||||
import Playback from './components/playback.js'
|
||||
import defaultConfig from './config.js'
|
||||
import { isMobile, isChrome, isAndroid, supportsZoom } from './utils/device.js'
|
||||
import { isMobile, isChrome, supportsZoom } from './utils/device.js'
|
||||
import {
|
||||
SLIDES_SELECTOR,
|
||||
HORIZONTAL_SLIDES_SELECTOR,
|
||||
@ -58,10 +59,12 @@ export default function( revealElement, options ) {
|
||||
currentSlide,
|
||||
|
||||
// Remember which directions that the user has navigated towards
|
||||
hasNavigatedHorizontally = false,
|
||||
hasNavigatedVertically = false,
|
||||
navigationHistory = {
|
||||
hasNavigatedHorizontally: false,
|
||||
hasNavigatedVertically: false
|
||||
},
|
||||
|
||||
// Slides may hold a data-state attribute which we pick up and apply
|
||||
// Slides may have a data-state attribute which we pick up and apply
|
||||
// as a class to the body. This list contains the combined state of
|
||||
// all current slides.
|
||||
state = [],
|
||||
@ -80,6 +83,7 @@ export default function( revealElement, options ) {
|
||||
overview = new Overview( Reveal ),
|
||||
keyboard = new Keyboard( Reveal ),
|
||||
location = new Location( Reveal ),
|
||||
controls = new Controls( Reveal ),
|
||||
plugins = new Plugins( Reveal ),
|
||||
print = new Print( Reveal ),
|
||||
touch = new Touch( Reveal ),
|
||||
@ -223,45 +227,22 @@ export default function( revealElement, options ) {
|
||||
dom.wrapper.classList.remove( 'no-hover' );
|
||||
}
|
||||
|
||||
// Slide backgrounds
|
||||
backgrounds.render();
|
||||
|
||||
// Progress bar
|
||||
dom.progress = createSingletonNode( dom.wrapper, 'div', 'progress', '<span></span>' );
|
||||
dom.progressbar = dom.progress.querySelector( 'span' );
|
||||
|
||||
// Arrow controls
|
||||
dom.controls = createSingletonNode( dom.wrapper, 'aside', 'controls',
|
||||
`<button class="navigate-left" aria-label="${ config.rtl ? 'next slide' : 'previous slide' }"><div class="controls-arrow"></div></button>
|
||||
<button class="navigate-right" aria-label="${ config.rtl ? 'previous slide' : 'next slide' }"><div class="controls-arrow"></div></button>
|
||||
<button class="navigate-up" aria-label="above slide"><div class="controls-arrow"></div></button>
|
||||
<button class="navigate-down" aria-label="below slide"><div class="controls-arrow"></div></button>` );
|
||||
|
||||
// Slide number
|
||||
backgrounds.render();
|
||||
slideNumber.render();
|
||||
|
||||
// Slide notes
|
||||
controls.render();
|
||||
notes.render();
|
||||
|
||||
// Overlay graphic which is displayed during the paused mode
|
||||
dom.pauseOverlay = createSingletonNode( dom.wrapper, 'div', 'pause-overlay', config.controls ? '<button class="resume-button">Resume presentation</button>' : null );
|
||||
|
||||
dom.wrapper.setAttribute( 'role', 'application' );
|
||||
|
||||
// There can be multiple instances of controls throughout the page
|
||||
dom.controlsLeft = toArray( dom.wrapper.querySelectorAll( '.navigate-left' ) );
|
||||
dom.controlsRight = toArray( dom.wrapper.querySelectorAll( '.navigate-right' ) );
|
||||
dom.controlsUp = toArray( dom.wrapper.querySelectorAll( '.navigate-up' ) );
|
||||
dom.controlsDown = toArray( dom.wrapper.querySelectorAll( '.navigate-down' ) );
|
||||
dom.controlsPrev = toArray( dom.wrapper.querySelectorAll( '.navigate-prev' ) );
|
||||
dom.controlsNext = toArray( dom.wrapper.querySelectorAll( '.navigate-next' ) );
|
||||
|
||||
// The left, right and down arrows in the standard reveal.js controls
|
||||
dom.controlsRightArrow = dom.controls.querySelector( '.navigate-right' );
|
||||
dom.controlsLeftArrow = dom.controls.querySelector( '.navigate-left' );
|
||||
dom.controlsDownArrow = dom.controls.querySelector( '.navigate-down' );
|
||||
|
||||
dom.statusElement = createStatusElement();
|
||||
|
||||
dom.wrapper.setAttribute( 'role', 'application' );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -423,12 +404,8 @@ export default function( revealElement, options ) {
|
||||
dom.wrapper.setAttribute( 'data-transition-speed', config.transitionSpeed );
|
||||
dom.wrapper.setAttribute( 'data-background-transition', config.backgroundTransition );
|
||||
|
||||
dom.controls.style.display = config.controls ? 'block' : 'none';
|
||||
dom.progress.style.display = config.progress ? 'block' : 'none';
|
||||
|
||||
dom.controls.setAttribute( 'data-controls-layout', config.controlsLayout );
|
||||
dom.controls.setAttribute( 'data-controls-back-arrows', config.controlsBackArrows );
|
||||
|
||||
if( config.shuffle ) {
|
||||
shuffle();
|
||||
}
|
||||
@ -511,9 +488,10 @@ export default function( revealElement, options ) {
|
||||
}
|
||||
|
||||
notes.configure( config, oldConfig );
|
||||
controls.configure( config, oldConfig );
|
||||
keyboard.configure( config, oldConfig );
|
||||
fragments.configure( config, oldConfig );
|
||||
slideNumber.configure( config, oldConfig );
|
||||
keyboard.configure( config, oldConfig );
|
||||
|
||||
sync();
|
||||
|
||||
@ -531,6 +509,7 @@ export default function( revealElement, options ) {
|
||||
|
||||
if( config.touch ) touch.bind();
|
||||
if( config.keyboard ) keyboard.bind();
|
||||
controls.bind();
|
||||
|
||||
if( config.progress && dom.progress ) {
|
||||
dom.progress.addEventListener( 'click', onProgressClicked, false );
|
||||
@ -542,25 +521,6 @@ export default function( revealElement, options ) {
|
||||
document.addEventListener( 'visibilitychange', onPageVisibilityChange, false );
|
||||
}
|
||||
|
||||
// Listen to both touch and click events, in case the device
|
||||
// supports both
|
||||
let pointerEvents = [ 'touchstart', 'click' ];
|
||||
|
||||
// Only support touch for Android, fixes double navigations in
|
||||
// stock browser
|
||||
if( isAndroid ) {
|
||||
pointerEvents = [ 'touchstart' ];
|
||||
}
|
||||
|
||||
pointerEvents.forEach( eventName => {
|
||||
dom.controlsLeft.forEach( el => el.addEventListener( eventName, onNavigateLeftClicked, false ) );
|
||||
dom.controlsRight.forEach( el => el.addEventListener( eventName, onNavigateRightClicked, false ) );
|
||||
dom.controlsUp.forEach( el => el.addEventListener( eventName, onNavigateUpClicked, false ) );
|
||||
dom.controlsDown.forEach( el => el.addEventListener( eventName, onNavigateDownClicked, false ) );
|
||||
dom.controlsPrev.forEach( el => el.addEventListener( eventName, onNavigatePrevClicked, false ) );
|
||||
dom.controlsNext.forEach( el => el.addEventListener( eventName, onNavigateNextClicked, false ) );
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -572,6 +532,7 @@ export default function( revealElement, options ) {
|
||||
|
||||
touch.unbind();
|
||||
keyboard.unbind();
|
||||
controls.unbind();
|
||||
|
||||
window.removeEventListener( 'hashchange', onWindowHashChange, false );
|
||||
window.removeEventListener( 'resize', onWindowResize, false );
|
||||
@ -582,15 +543,6 @@ export default function( revealElement, options ) {
|
||||
dom.progress.removeEventListener( 'click', onProgressClicked, false );
|
||||
}
|
||||
|
||||
[ 'touchstart', 'click' ].forEach( eventName => {
|
||||
dom.controlsLeft.forEach( el => el.removeEventListener( eventName, onNavigateLeftClicked, false ) );
|
||||
dom.controlsRight.forEach( el => el.removeEventListener( eventName, onNavigateRightClicked, false ) );
|
||||
dom.controlsUp.forEach( el => el.removeEventListener( eventName, onNavigateUpClicked, false ) );
|
||||
dom.controlsDown.forEach( el => el.removeEventListener( eventName, onNavigateDownClicked, false ) );
|
||||
dom.controlsPrev.forEach( el => el.removeEventListener( eventName, onNavigatePrevClicked, false ) );
|
||||
dom.controlsNext.forEach( el => el.removeEventListener( eventName, onNavigateNextClicked, false ) );
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1397,9 +1349,9 @@ export default function( revealElement, options ) {
|
||||
// Announce the current slide contents to screen readers
|
||||
announceStatus( getStatusText( currentSlide ) );
|
||||
|
||||
updateControls();
|
||||
updateProgress();
|
||||
|
||||
controls.update();
|
||||
notes.update();
|
||||
backgrounds.update();
|
||||
backgrounds.updateParallax();
|
||||
@ -1461,7 +1413,8 @@ export default function( revealElement, options ) {
|
||||
|
||||
fragments.sortAll();
|
||||
|
||||
updateControls();
|
||||
controls.update();
|
||||
|
||||
updateProgress();
|
||||
updateSlidesVisibility();
|
||||
|
||||
@ -1770,84 +1723,6 @@ export default function( revealElement, options ) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the state of all control/navigation arrows.
|
||||
*/
|
||||
function updateControls() {
|
||||
|
||||
let routes = availableRoutes();
|
||||
let fragmentsRoutes = fragments.availableRoutes();
|
||||
|
||||
// Remove the 'enabled' class from all directions
|
||||
[...dom.controlsLeft, ...dom.controlsRight, ...dom.controlsUp, ...dom.controlsDown, ...dom.controlsPrev, ...dom.controlsNext].forEach( node => {
|
||||
node.classList.remove( 'enabled', 'fragmented' );
|
||||
|
||||
// Set 'disabled' attribute on all directions
|
||||
node.setAttribute( 'disabled', 'disabled' );
|
||||
} );
|
||||
|
||||
// Add the 'enabled' class to the available routes; remove 'disabled' attribute to enable buttons
|
||||
if( routes.left ) dom.controlsLeft.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
if( routes.right ) dom.controlsRight.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
if( routes.up ) dom.controlsUp.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
if( routes.down ) dom.controlsDown.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
|
||||
// Prev/next buttons
|
||||
if( routes.left || routes.up ) dom.controlsPrev.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
if( routes.right || routes.down ) dom.controlsNext.forEach( el => { el.classList.add( 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
|
||||
// Highlight fragment directions
|
||||
if( currentSlide ) {
|
||||
|
||||
// Always apply fragment decorator to prev/next buttons
|
||||
if( fragmentsRoutes.prev ) dom.controlsPrev.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
if( fragmentsRoutes.next ) dom.controlsNext.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
|
||||
// Apply fragment decorators to directional buttons based on
|
||||
// what slide axis they are in
|
||||
if( isVerticalSlide( currentSlide ) ) {
|
||||
if( fragmentsRoutes.prev ) dom.controlsUp.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
if( fragmentsRoutes.next ) dom.controlsDown.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
}
|
||||
else {
|
||||
if( fragmentsRoutes.prev ) dom.controlsLeft.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
if( fragmentsRoutes.next ) dom.controlsRight.forEach( el => { el.classList.add( 'fragmented', 'enabled' ); el.removeAttribute( 'disabled' ); } );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( config.controlsTutorial ) {
|
||||
|
||||
// Highlight control arrows with an animation to ensure
|
||||
// that the viewer knows how to navigate
|
||||
if( !hasNavigatedVertically && routes.down ) {
|
||||
dom.controlsDownArrow.classList.add( 'highlight' );
|
||||
}
|
||||
else {
|
||||
dom.controlsDownArrow.classList.remove( 'highlight' );
|
||||
|
||||
if( config.rtl ) {
|
||||
|
||||
if( !hasNavigatedHorizontally && routes.left && indexv === 0 ) {
|
||||
dom.controlsLeftArrow.classList.add( 'highlight' );
|
||||
}
|
||||
else {
|
||||
dom.controlsLeftArrow.classList.remove( 'highlight' );
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if( !hasNavigatedHorizontally && routes.right && indexv === 0 ) {
|
||||
dom.controlsRightArrow.classList.add( 'highlight' );
|
||||
}
|
||||
else {
|
||||
dom.controlsRightArrow.classList.remove( 'highlight' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine what available routes there are for navigation.
|
||||
*
|
||||
@ -2322,7 +2197,7 @@ export default function( revealElement, options ) {
|
||||
|
||||
function navigateLeft() {
|
||||
|
||||
hasNavigatedHorizontally = true;
|
||||
navigationHistory.hasNavigatedHorizontally = true;
|
||||
|
||||
// Reverse for RTL
|
||||
if( config.rtl ) {
|
||||
@ -2339,7 +2214,7 @@ export default function( revealElement, options ) {
|
||||
|
||||
function navigateRight() {
|
||||
|
||||
hasNavigatedHorizontally = true;
|
||||
navigationHistory.hasNavigatedHorizontally = true;
|
||||
|
||||
// Reverse for RTL
|
||||
if( config.rtl ) {
|
||||
@ -2365,7 +2240,7 @@ export default function( revealElement, options ) {
|
||||
|
||||
function navigateDown() {
|
||||
|
||||
hasNavigatedVertically = true;
|
||||
navigationHistory.hasNavigatedVertically = true;
|
||||
|
||||
// Prioritize revealing fragments
|
||||
if( ( overview.isActive() || fragments.next() === false ) && availableRoutes().down ) {
|
||||
@ -2413,8 +2288,8 @@ export default function( revealElement, options ) {
|
||||
*/
|
||||
function navigateNext() {
|
||||
|
||||
hasNavigatedHorizontally = true;
|
||||
hasNavigatedVertically = true;
|
||||
navigationHistory.hasNavigatedHorizontally = true;
|
||||
navigationHistory.hasNavigatedVertically = true;
|
||||
|
||||
// Prioritize revealing fragments
|
||||
if( fragments.next() === false ) {
|
||||
@ -2525,16 +2400,6 @@ export default function( revealElement, options ) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handler for navigation control buttons.
|
||||
*/
|
||||
function onNavigateLeftClicked( event ) { event.preventDefault(); onUserInput(); config.navigationMode === 'linear' ? navigatePrev() : navigateLeft(); }
|
||||
function onNavigateRightClicked( event ) { event.preventDefault(); onUserInput(); config.navigationMode === 'linear' ? navigateNext() : 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(); }
|
||||
|
||||
/**
|
||||
* Handler for the window level 'hashchange' event.
|
||||
*
|
||||
@ -2697,7 +2562,7 @@ export default function( revealElement, options ) {
|
||||
// State checks
|
||||
isPaused,
|
||||
isAutoSliding,
|
||||
isSpeakerNotes: notes.isSpeakerNotes.bind( notes ),
|
||||
isSpeakerNotes: notes.isSpeakerNotesWindow.bind( notes ),
|
||||
isOverview: overview.isActive.bind( overview ),
|
||||
isPrintingPDF: print.isPrintingPDF.bind( print ),
|
||||
|
||||
@ -2751,6 +2616,9 @@ export default function( revealElement, options ) {
|
||||
hasHorizontalSlides,
|
||||
hasVerticalSlides,
|
||||
|
||||
hasNavigatedHorizontally: () => navigationHistory.hasNavigatedHorizontally,
|
||||
hasNavigatedVertically: () => navigationHistory.hasNavigatedVertically,
|
||||
|
||||
// Adds/removes a custom key binding
|
||||
addKeyBinding: keyboard.addKeyBinding.bind( keyboard ),
|
||||
removeKeyBinding: keyboard.removeKeyBinding.bind( keyboard ),
|
||||
@ -2800,6 +2668,7 @@ export default function( revealElement, options ) {
|
||||
getStatusText,
|
||||
|
||||
print,
|
||||
controls,
|
||||
location,
|
||||
overview,
|
||||
fragments,
|
||||
@ -2808,7 +2677,6 @@ export default function( revealElement, options ) {
|
||||
|
||||
onUserInput,
|
||||
closeOverlay,
|
||||
updateControls,
|
||||
updateProgress,
|
||||
updateSlidesVisibility,
|
||||
layoutSlideContents,
|
||||
|
Loading…
Reference in New Issue
Block a user