Browse Source

refactor hash parsing, fixes issue with autoplaying media not starting from internal links on mobile devices

hakimel 3 years ago
parent
commit
a6c0f3efac
5 changed files with 62 additions and 28 deletions
  1. 0 0
      dist/reveal.esm.js
  2. 0 0
      dist/reveal.js
  3. 2 2
      gulpfile.js
  4. 32 26
      js/controllers/location.js
  5. 28 0
      js/reveal.js

File diff suppressed because it is too large
+ 0 - 0
dist/reveal.esm.js


File diff suppressed because it is too large
+ 0 - 0
dist/reveal.js


+ 2 - 2
gulpfile.js

@@ -289,13 +289,13 @@ gulp.task('serve', () => {
     connect.server({
         root: root,
         port: port,
-        host: 'localhost',
+        host: '0.0.0.0',
         livereload: true
     })
 
     gulp.watch(['*.html', '*.md'], gulp.series('reload'))
 
-    gulp.watch(['js/**'], gulp.series('js', 'reload', 'test'))
+    gulp.watch(['js/**'], gulp.series('js', 'reload'))
 
     gulp.watch(['plugin/**/plugin.js'], gulp.series('plugins', 'reload'))
 

+ 32 - 26
js/controllers/location.js

@@ -27,19 +27,18 @@ export default class Location {
 	}
 
 	/**
-	 * Reads the current URL (hash) and navigates accordingly.
+	 * Returns the slide indices for the given hash link.
+	 *
+	 * @param {string} [hash] the hash string that we want to
+	 * find the indices for
+	 *
+	 * @returns slide indices or null
 	 */
-	readURL() {
-
-		let config = this.Reveal.getConfig();
-		let indices = this.Reveal.getIndices();
-		let currentSlide = this.Reveal.getCurrentSlide();
-
-		let hash = window.location.hash;
+	getIndicesFromHash( hash=window.location.hash ) {
 
 		// Attempt to parse the hash as either an index or name
-		let bits = hash.slice( 2 ).split( '/' ),
-			name = hash.replace( /#\/?/gi, '' );
+		let name = hash.replace( /^#\/?/, '' );
+		let bits = name.split( '/' );
 
 		// If the first bit is not fully numeric and there is a name we
 		// can assume that this is a named link
@@ -61,23 +60,12 @@ export default class Location {
 			}
 			catch ( error ) { }
 
-			// Ensure that we're not already on a slide with the same name
-			let isSameNameAsCurrentSlide = currentSlide ? currentSlide.getAttribute( 'id' ) === name : false;
-
 			if( element ) {
-				// If the slide exists and is not the current slide...
-				if ( !isSameNameAsCurrentSlide || typeof f !== 'undefined' ) {
-					// ...find the position of the named slide and navigate to it
-					let slideIndices = this.Reveal.getIndices( element );
-					this.Reveal.slide( slideIndices.h, slideIndices.v, f );
-				}
-			}
-			// If the slide doesn't exist, navigate to the current slide
-			else {
-				this.Reveal.slide( indices.h || 0, indices.v || 0 );
+				return { ...this.Reveal.getIndices( element ), f };
 			}
 		}
 		else {
+			const config = this.Reveal.getConfig();
 			let hashIndexBase = config.hashOneBasedIndex ? 1 : 0;
 
 			// Read the index components of the hash
@@ -92,9 +80,27 @@ export default class Location {
 				}
 			}
 
-			if( h !== indices.h || v !== indices.v || f !== undefined ) {
-				this.Reveal.slide( h, v, f );
-			}
+			return { h, v, f };
+		}
+
+		// The hash couldn't be parsed or no matching named link was found
+		return null
+
+	}
+
+	/**
+	 * Reads the current URL (hash) and navigates accordingly.
+	 */
+	readURL() {
+
+		const currentIndices = this.Reveal.getIndices();
+		const newIndices = this.getIndicesFromHash();
+
+		if( newIndices && ( newIndices.h !== currentIndices.h || newIndices.v !== currentIndices.v || newIndices.f !== undefined ) ) {
+			this.Reveal.slide( newIndices.h, newIndices.v, newIndices.f );
+		}
+		else {
+			this.Reveal.slide( currentIndices.h || 0, currentIndices.v || 0 );
 		}
 
 	}

+ 28 - 0
js/reveal.js

@@ -529,6 +529,7 @@ export default function( revealElement, options ) {
 		controls.bind();
 		focus.bind();
 
+		dom.slides.addEventListener( 'click', onSlidesClicked, false );
 		dom.slides.addEventListener( 'transitionend', onTransitionEnd, false );
 		dom.pauseOverlay.addEventListener( 'click', resume, false );
 
@@ -554,6 +555,7 @@ export default function( revealElement, options ) {
 
 		window.removeEventListener( 'resize', onWindowResize, false );
 
+		dom.slides.removeEventListener( 'click', onSlidesClicked, false );
 		dom.slides.removeEventListener( 'transitionend', onTransitionEnd, false );
 		dom.pauseOverlay.removeEventListener( 'click', resume, false );
 
@@ -2374,6 +2376,32 @@ export default function( revealElement, options ) {
 
 	}
 
+	/**
+	 * A global listener for all click events inside of the
+	 * .slides container.
+	 *
+	 * @param {object} [event]
+	 */
+	function onSlidesClicked( event ) {
+
+		// If a hash link is clicked, we find the target slide
+		// and navigate to it. We previously relied on 'hashchange'
+		// for links like these but that prevented media with
+		// audio tracks from playing in mobile browsers since it
+		// wasn't considered a direct interaction with the document.
+		if( event.target.nodeName === 'A' ) {
+			const hash = event.target.getAttribute( 'href' );
+			if( /^#/.test( hash ) ) {
+				const indices = location.getIndicesFromHash( hash );
+				if( indices ) {
+					Reveal.slide( indices.h, indices.v, indices.f );
+					event.preventDefault();
+				}
+			}
+		}
+
+	}
+
 	/**
 	 * Handler for the window level 'resize' event.
 	 *

Some files were not shown because too many files changed in this diff