Hakim El Hattab 6 years ago
parent
commit
a4dc1c6440
2 changed files with 81 additions and 36 deletions
  1. 75 36
      js/reveal.js
  2. 6 0
      test/test.js

+ 75 - 36
js/reveal.js

@@ -2766,6 +2766,7 @@
 		updateParallax();
 		updateSlideNumber();
 		updateNotes();
+		updateFragments();
 
 		// Update the URL hash
 		writeURL();
@@ -4405,6 +4406,73 @@
 
 	}
 
+	/**
+	 * Refreshes the fragments on the current slide so that they
+	 * have the appropriate classes (.visible + .current-fragment).
+	 *
+	 * @param {number} [index] The index of the current fragment
+	 * @param {array} [fragments] Array containing all fragments
+	 * in the current slide
+	 *
+	 * @return {{shown: array, hidden: array}}
+	 */
+	function updateFragments( index, fragments ) {
+
+		var changedFragments = {
+			shown: [],
+			hidden: []
+		};
+
+		if( currentSlide && config.fragments ) {
+
+			fragments = fragments || sortFragments( currentSlide.querySelectorAll( '.fragment' ) );
+
+			if( fragments.length ) {
+
+				if( typeof index !== 'number' ) {
+					var currentFragment = sortFragments( currentSlide.querySelectorAll( '.fragment.visible' ) ).pop();
+					if( currentFragment ) {
+						index = parseInt( currentFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );
+					}
+				}
+
+				toArray( fragments ).forEach( function( el, i ) {
+
+					if( el.hasAttribute( 'data-fragment-index' ) ) {
+						i = parseInt( el.getAttribute( 'data-fragment-index' ), 10 );
+					}
+
+					// Visible fragments
+					if( i <= index ) {
+						if( !el.classList.contains( 'visible' ) ) changedFragments.shown.push( el );
+						el.classList.add( 'visible' );
+						el.classList.remove( 'current-fragment' );
+
+						// Announce the fragments one by one to the Screen Reader
+						dom.statusDiv.textContent = getStatusText( el );
+
+						if( i === index ) {
+							el.classList.add( 'current-fragment' );
+							startEmbeddedContent( el );
+						}
+					}
+					// Hidden fragments
+					else {
+						if( el.classList.contains( 'visible' ) ) changedFragments.hidden.push( el );
+						el.classList.remove( 'visible' );
+						el.classList.remove( 'current-fragment' );
+					}
+
+				} );
+
+			}
+
+		}
+
+		return changedFragments;
+
+	}
+
 	/**
 	 * Navigate to the specified slide fragment.
 	 *
@@ -4440,53 +4508,24 @@
 					index += offset;
 				}
 
-				var fragmentsShown = [],
-					fragmentsHidden = [];
-
-				toArray( fragments ).forEach( function( element, i ) {
+				var changedFragments = updateFragments( index, fragments );
 
-					if( element.hasAttribute( 'data-fragment-index' ) ) {
-						i = parseInt( element.getAttribute( 'data-fragment-index' ), 10 );
-					}
-
-					// Visible fragments
-					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 = getStatusText( element );
-
-						if( i === index ) {
-							element.classList.add( 'current-fragment' );
-							startEmbeddedContent( element );
-						}
-					}
-					// Hidden fragments
-					else {
-						if( element.classList.contains( 'visible' ) ) fragmentsHidden.push( element );
-						element.classList.remove( 'visible' );
-						element.classList.remove( 'current-fragment' );
-					}
-
-				} );
-
-				if( fragmentsHidden.length ) {
-					dispatchEvent( 'fragmenthidden', { fragment: fragmentsHidden[0], fragments: fragmentsHidden } );
+				if( changedFragments.hidden.length ) {
+					dispatchEvent( 'fragmenthidden', { fragment: changedFragments.hidden[0], fragments: changedFragments.hidden } );
 				}
 
-				if( fragmentsShown.length ) {
-					dispatchEvent( 'fragmentshown', { fragment: fragmentsShown[0], fragments: fragmentsShown } );
+				if( changedFragments.shown.length ) {
+					dispatchEvent( 'fragmentshown', { fragment: changedFragments.shown[0], fragments: changedFragments.shown } );
 				}
 
 				updateControls();
 				updateProgress();
+
 				if( config.fragmentInURL ) {
 					writeURL();
 				}
 
-				return !!( fragmentsShown.length || fragmentsHidden.length );
+				return !!( changedFragments.shown.length || changedFragments.hidden.length );
 
 			}
 

+ 6 - 0
test/test.js

@@ -262,6 +262,8 @@ Reveal.addEventListener( 'ready', function() {
 
 	QUnit.test( 'Current fragment', function( assert ) {
 		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' );
+		var fragments = fragmentSlide.querySelectorAll( '.fragment' );
+		var lastFragmentIndex = fragments[ fragments.length - 1 ].getAttribute( 'data-fragment-index' );
 
 		Reveal.slide( 2, 0 );
 		assert.strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment at index -1' );
@@ -274,6 +276,10 @@ Reveal.addEventListener( 'ready', function() {
 
 		Reveal.slide( 3, 0, 0 );
 		assert.strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment when navigating to next slide' );
+
+		Reveal.slide( 2, 1, -1 );
+		Reveal.prev();
+		assert.strictEqual( fragmentSlide.querySelector( '.fragment.current-fragment' ).getAttribute( 'data-fragment-index' ), lastFragmentIndex, 'last fragment is current fragment when returning from future slide' );
 	});
 
 	QUnit.test( 'Stepping through fragments', function( assert ) {