Przeglądaj źródła

new controls module for navigation arrows

Hakim El Hattab 5 lat temu
rodzic
commit
c50ec00419
5 zmienionych plików z 284 dodań i 167 usunięć
  1. 0 0
      dist/reveal.min.js
  2. 250 0
      js/controllers/controls.js
  3. 3 2
      js/controllers/fragments.js
  4. 2 4
      js/controllers/notes.js
  5. 29 161
      js/reveal.js

Plik diff jest za duży
+ 0 - 0
dist/reveal.min.js


+ 250 - 0
js/controllers/controls.js

@@ -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();
+
+	}
+
+
+}

+ 3 - 2
js/controllers/fragments.js

@@ -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 ) {
 	configure( config, oldConfig ) {
 
 
@@ -331,7 +331,8 @@ export default class Fragments {
 					});
 					});
 				}
 				}
 
 
-				this.Reveal.updateControls();
+				this.Reveal.controls.update();
+
 				this.Reveal.updateProgress();
 				this.Reveal.updateProgress();
 
 
 				if( this.Reveal.getConfig().fragmentInURL ) {
 				if( this.Reveal.getConfig().fragmentInURL ) {

+ 2 - 4
js/controllers/notes.js

@@ -1,7 +1,5 @@
-import { extend, toArray } from '../utils/util.js'
-
 /**
 /**
- *
+ * Handles the showing and 
  */
  */
 export default class Notes {
 export default class Notes {
 
 
@@ -81,7 +79,7 @@ export default class Notes {
 	 *
 	 *
 	 * @return {boolean}
 	 * @return {boolean}
 	 */
 	 */
-	isSpeakerNotes() {
+	isSpeakerNotesWindow() {
 
 
 		return !!window.location.search.match( /receiver/gi );
 		return !!window.location.search.match( /receiver/gi );
 
 

+ 29 - 161
js/reveal.js

@@ -6,13 +6,14 @@ import Fragments from './controllers/fragments.js'
 import Overview from './controllers/overview.js'
 import Overview from './controllers/overview.js'
 import Keyboard from './controllers/keyboard.js'
 import Keyboard from './controllers/keyboard.js'
 import Location from './controllers/location.js'
 import Location from './controllers/location.js'
+import Controls from './controllers/controls.js'
 import Plugins from './controllers/plugins.js'
 import Plugins from './controllers/plugins.js'
 import Print from './controllers/print.js'
 import Print from './controllers/print.js'
 import Touch from './controllers/touch.js'
 import Touch from './controllers/touch.js'
 import Notes from './controllers/notes.js'
 import Notes from './controllers/notes.js'
 import Playback from './components/playback.js'
 import Playback from './components/playback.js'
 import defaultConfig from './config.js'
 import defaultConfig from './config.js'
-import { isMobile, isChrome, isAndroid, supportsZoom } from './utils/device.js'
+import { isMobile, isChrome, supportsZoom } from './utils/device.js'
 import {
 import {
 	SLIDES_SELECTOR,
 	SLIDES_SELECTOR,
 	HORIZONTAL_SLIDES_SELECTOR,
 	HORIZONTAL_SLIDES_SELECTOR,
@@ -58,10 +59,12 @@ export default function( revealElement, options ) {
 		currentSlide,
 		currentSlide,
 
 
 		// Remember which directions that the user has navigated towards
 		// 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
 		// as a class to the body. This list contains the combined state of
 		// all current slides.
 		// all current slides.
 		state = [],
 		state = [],
@@ -80,6 +83,7 @@ export default function( revealElement, options ) {
 		overview = new Overview( Reveal ),
 		overview = new Overview( Reveal ),
 		keyboard = new Keyboard( Reveal ),
 		keyboard = new Keyboard( Reveal ),
 		location = new Location( Reveal ),
 		location = new Location( Reveal ),
+		controls = new Controls( Reveal ),
 		plugins = new Plugins( Reveal ),
 		plugins = new Plugins( Reveal ),
 		print = new Print( Reveal ),
 		print = new Print( Reveal ),
 		touch = new Touch( Reveal ),
 		touch = new Touch( Reveal ),
@@ -223,45 +227,22 @@ export default function( revealElement, options ) {
 			dom.wrapper.classList.remove( 'no-hover' );
 			dom.wrapper.classList.remove( 'no-hover' );
 		}
 		}
 
 
-		// Slide backgrounds
-		backgrounds.render();
 
 
 		// Progress bar
 		// Progress bar
 		dom.progress = createSingletonNode( dom.wrapper, 'div', 'progress', '<span></span>' );
 		dom.progress = createSingletonNode( dom.wrapper, 'div', 'progress', '<span></span>' );
 		dom.progressbar = dom.progress.querySelector( '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();
 		slideNumber.render();
-
-		// Slide notes
+		controls.render();
 		notes.render();
 		notes.render();
 
 
 		// Overlay graphic which is displayed during the paused mode
 		// 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.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.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-transition-speed', config.transitionSpeed );
 		dom.wrapper.setAttribute( 'data-background-transition', config.backgroundTransition );
 		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.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 ) {
 		if( config.shuffle ) {
 			shuffle();
 			shuffle();
 		}
 		}
@@ -511,9 +488,10 @@ export default function( revealElement, options ) {
 		}
 		}
 
 
 		notes.configure( config, oldConfig );
 		notes.configure( config, oldConfig );
+		controls.configure( config, oldConfig );
+		keyboard.configure( config, oldConfig );
 		fragments.configure( config, oldConfig );
 		fragments.configure( config, oldConfig );
 		slideNumber.configure( config, oldConfig );
 		slideNumber.configure( config, oldConfig );
-		keyboard.configure( config, oldConfig );
 
 
 		sync();
 		sync();
 
 
@@ -531,6 +509,7 @@ export default function( revealElement, options ) {
 
 
 		if( config.touch ) touch.bind();
 		if( config.touch ) touch.bind();
 		if( config.keyboard ) keyboard.bind();
 		if( config.keyboard ) keyboard.bind();
+		controls.bind();
 
 
 		if( config.progress && dom.progress ) {
 		if( config.progress && dom.progress ) {
 			dom.progress.addEventListener( 'click', onProgressClicked, false );
 			dom.progress.addEventListener( 'click', onProgressClicked, false );
@@ -542,25 +521,6 @@ export default function( revealElement, options ) {
 			document.addEventListener( 'visibilitychange', onPageVisibilityChange, false );
 			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();
 		touch.unbind();
 		keyboard.unbind();
 		keyboard.unbind();
+		controls.unbind();
 
 
 		window.removeEventListener( 'hashchange', onWindowHashChange, false );
 		window.removeEventListener( 'hashchange', onWindowHashChange, false );
 		window.removeEventListener( 'resize', onWindowResize, false );
 		window.removeEventListener( 'resize', onWindowResize, false );
@@ -582,15 +543,6 @@ export default function( revealElement, options ) {
 			dom.progress.removeEventListener( 'click', onProgressClicked, false );
 			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
 		// Announce the current slide contents to screen readers
 		announceStatus( getStatusText( currentSlide ) );
 		announceStatus( getStatusText( currentSlide ) );
 
 
-		updateControls();
 		updateProgress();
 		updateProgress();
 
 
+		controls.update();
 		notes.update();
 		notes.update();
 		backgrounds.update();
 		backgrounds.update();
 		backgrounds.updateParallax();
 		backgrounds.updateParallax();
@@ -1461,7 +1413,8 @@ export default function( revealElement, options ) {
 
 
 		fragments.sortAll();
 		fragments.sortAll();
 
 
-		updateControls();
+		controls.update();
+
 		updateProgress();
 		updateProgress();
 		updateSlidesVisibility();
 		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.
 	 * Determine what available routes there are for navigation.
 	 *
 	 *
@@ -2322,7 +2197,7 @@ export default function( revealElement, options ) {
 
 
 	function navigateLeft() {
 	function navigateLeft() {
 
 
-		hasNavigatedHorizontally = true;
+		navigationHistory.hasNavigatedHorizontally = true;
 
 
 		// Reverse for RTL
 		// Reverse for RTL
 		if( config.rtl ) {
 		if( config.rtl ) {
@@ -2339,7 +2214,7 @@ export default function( revealElement, options ) {
 
 
 	function navigateRight() {
 	function navigateRight() {
 
 
-		hasNavigatedHorizontally = true;
+		navigationHistory.hasNavigatedHorizontally = true;
 
 
 		// Reverse for RTL
 		// Reverse for RTL
 		if( config.rtl ) {
 		if( config.rtl ) {
@@ -2365,7 +2240,7 @@ export default function( revealElement, options ) {
 
 
 	function navigateDown() {
 	function navigateDown() {
 
 
-		hasNavigatedVertically = true;
+		navigationHistory.hasNavigatedVertically = true;
 
 
 		// Prioritize revealing fragments
 		// Prioritize revealing fragments
 		if( ( overview.isActive() || fragments.next() === false ) && availableRoutes().down ) {
 		if( ( overview.isActive() || fragments.next() === false ) && availableRoutes().down ) {
@@ -2413,8 +2288,8 @@ export default function( revealElement, options ) {
 	 */
 	 */
 	function navigateNext() {
 	function navigateNext() {
 
 
-		hasNavigatedHorizontally = true;
-		hasNavigatedVertically = true;
+		navigationHistory.hasNavigatedHorizontally = true;
+		navigationHistory.hasNavigatedVertically = true;
 
 
 		// Prioritize revealing fragments
 		// Prioritize revealing fragments
 		if( fragments.next() === false ) {
 		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.
 	 * Handler for the window level 'hashchange' event.
 	 *
 	 *
@@ -2697,7 +2562,7 @@ export default function( revealElement, options ) {
 		// State checks
 		// State checks
 		isPaused,
 		isPaused,
 		isAutoSliding,
 		isAutoSliding,
-		isSpeakerNotes: notes.isSpeakerNotes.bind( notes ),
+		isSpeakerNotes: notes.isSpeakerNotesWindow.bind( notes ),
 		isOverview: overview.isActive.bind( overview ),
 		isOverview: overview.isActive.bind( overview ),
 		isPrintingPDF: print.isPrintingPDF.bind( print ),
 		isPrintingPDF: print.isPrintingPDF.bind( print ),
 
 
@@ -2751,6 +2616,9 @@ export default function( revealElement, options ) {
 		hasHorizontalSlides,
 		hasHorizontalSlides,
 		hasVerticalSlides,
 		hasVerticalSlides,
 
 
+		hasNavigatedHorizontally: () => navigationHistory.hasNavigatedHorizontally,
+		hasNavigatedVertically: () => navigationHistory.hasNavigatedVertically,
+
 		// Adds/removes a custom key binding
 		// Adds/removes a custom key binding
 		addKeyBinding: keyboard.addKeyBinding.bind( keyboard ),
 		addKeyBinding: keyboard.addKeyBinding.bind( keyboard ),
 		removeKeyBinding: keyboard.removeKeyBinding.bind( keyboard ),
 		removeKeyBinding: keyboard.removeKeyBinding.bind( keyboard ),
@@ -2800,6 +2668,7 @@ export default function( revealElement, options ) {
 		getStatusText,
 		getStatusText,
 
 
 		print,
 		print,
+		controls,
 		location,
 		location,
 		overview,
 		overview,
 		fragments,
 		fragments,
@@ -2808,7 +2677,6 @@ export default function( revealElement, options ) {
 
 
 		onUserInput,
 		onUserInput,
 		closeOverlay,
 		closeOverlay,
-		updateControls,
 		updateProgress,
 		updateProgress,
 		updateSlidesVisibility,
 		updateSlidesVisibility,
 		layoutSlideContents,
 		layoutSlideContents,

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików