rewrite fragment sorting to account for multiple fragments with the same index
This commit is contained in:
		
							
								
								
									
										55
									
								
								js/reveal.js
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								js/reveal.js
									
									
									
									
									
								
							| @@ -1043,27 +1043,48 @@ var Reveal = (function(){ | ||||
| 	 */ | ||||
| 	function sortFragments( fragments ) { | ||||
|  | ||||
| 		var a = toArray( fragments ); | ||||
| 		fragments = toArray( fragments ); | ||||
|  | ||||
| 		// Elements that do not have an explicit `data-fragment-index` | ||||
| 		// are given one which matches their order in the DOM | ||||
| 		a.forEach( function( el, idx ) { | ||||
| 			if( !el.hasAttribute( 'data-fragment-index' ) ) { | ||||
| 				el.setAttribute( 'data-fragment-index', idx ); | ||||
| 		var ordered = [], | ||||
| 			unordered = [], | ||||
| 			sorted = []; | ||||
|  | ||||
| 		// Group ordered and unordered elements | ||||
| 		fragments.forEach( function( fragment, i ) { | ||||
| 			if( fragment.hasAttribute( 'data-fragment-index' ) ) { | ||||
| 				var index = parseInt( fragment.getAttribute( 'data-fragment-index' ), 10 ); | ||||
|  | ||||
| 				if( !ordered[index] ) { | ||||
| 					ordered[index] = []; | ||||
| 				} | ||||
|  | ||||
| 				ordered[index].push( fragment ); | ||||
| 			} | ||||
| 			else { | ||||
| 				unordered.push( [ fragment ] ); | ||||
| 			} | ||||
| 		} ); | ||||
|  | ||||
| 		a.sort( function( l, r ) { | ||||
| 			return l.getAttribute( 'data-fragment-index' ) - r.getAttribute( 'data-fragment-index'); | ||||
| 		// Append fragments without explicit indices in their | ||||
| 		// DOM order | ||||
| 		ordered = ordered.concat( unordered ); | ||||
|  | ||||
| 		// Manually count the index up per group to ensure there | ||||
| 		// are no gaps | ||||
| 		var index = 0; | ||||
|  | ||||
| 		// Push all fragments in their sorted order to an array, | ||||
| 		// this flattens the groups | ||||
| 		ordered.forEach( function( group ) { | ||||
| 			group.forEach( function( fragment ) { | ||||
| 				sorted.push( fragment ); | ||||
| 				fragment.setAttribute( 'data-fragment-index', index ); | ||||
| 			} ); | ||||
|  | ||||
| 			index ++; | ||||
| 		} ); | ||||
|  | ||||
| 		// Set the indices to match the order of the sorted fragments, | ||||
| 		// ensures that we're 0-indexed and have no gaps | ||||
| 		a.forEach( function( el, idx ) { | ||||
| 			el.setAttribute( 'data-fragment-index', idx ); | ||||
| 		} ); | ||||
|  | ||||
| 		return a; | ||||
| 		return sorted; | ||||
|  | ||||
| 	} | ||||
|  | ||||
| @@ -3173,9 +3194,11 @@ var Reveal = (function(){ | ||||
| 		down: navigateDown, | ||||
| 		prev: navigatePrev, | ||||
| 		next: navigateNext, | ||||
|  | ||||
| 		// Fragment methods | ||||
| 		navigateFragment: navigateFragment, | ||||
| 		prevFragment: previousFragment, | ||||
| 		nextFragment: nextFragment, | ||||
| 		navigateFragment: navigateFragment, | ||||
|  | ||||
| 		// Deprecated aliases | ||||
| 		navigateTo: slide, | ||||
|   | ||||
							
								
								
									
										4
									
								
								js/reveal.min.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								js/reveal.min.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -35,13 +35,32 @@ | ||||
| 					</section> | ||||
| 				</section> | ||||
|  | ||||
| 				<section> | ||||
| 					<h1>4</h1> | ||||
| 					<ul> | ||||
| 						<li class="fragment">4.1</li> | ||||
| 						<li class="fragment">4.2</li> | ||||
| 						<li class="fragment">4.3</li> | ||||
| 					</ul> | ||||
| 				<section id="fragment-slides"> | ||||
| 					<section> | ||||
| 						<h1>3.1</h1> | ||||
| 						<ul> | ||||
| 							<li class="fragment">4.1</li> | ||||
| 							<li class="fragment">4.2</li> | ||||
| 							<li class="fragment">4.3</li> | ||||
| 						</ul> | ||||
| 					</section> | ||||
|  | ||||
| 					<section> | ||||
| 						<h1>3.2</h1> | ||||
| 						<ul> | ||||
| 							<li class="fragment" data-fragment-index="0">4.1</li> | ||||
| 							<li class="fragment" data-fragment-index="0">4.2</li> | ||||
| 						</ul> | ||||
| 					</section> | ||||
|  | ||||
| 					<section> | ||||
| 						<h1>3.3</h1> | ||||
| 						<ul> | ||||
| 							<li class="fragment" data-fragment-index="1">3.3.1</li> | ||||
| 							<li class="fragment" data-fragment-index="4">3.3.2</li> | ||||
| 							<li class="fragment" data-fragment-index="4">3.3.3</li> | ||||
| 						</ul> | ||||
| 					</section> | ||||
| 				</section> | ||||
|  | ||||
| 				<section> | ||||
|   | ||||
							
								
								
									
										32
									
								
								test/test.js
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								test/test.js
									
									
									
									
									
								
							| @@ -5,6 +5,7 @@ | ||||
| // 1 | ||||
| // 2 - Three sub-slides | ||||
| // 3 - Three fragment elements | ||||
| // 3 - Two fragments with same data-fragment-index | ||||
| // 4 | ||||
|  | ||||
|  | ||||
| @@ -128,7 +129,7 @@ Reveal.addEventListener( 'ready', function() { | ||||
| 	test( 'Reveal.next', function() { | ||||
| 		Reveal.slide( 0, 0 ); | ||||
|  | ||||
| 		// Step through the vertical child slides | ||||
| 		// Step through vertical child slides | ||||
| 		Reveal.next(); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 1, v: 0, f: undefined } ); | ||||
|  | ||||
| @@ -138,7 +139,7 @@ Reveal.addEventListener( 'ready', function() { | ||||
| 		Reveal.next(); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 1, v: 2, f: undefined } ); | ||||
|  | ||||
| 		// There's fragments on this slide | ||||
| 		// Step through fragments | ||||
| 		Reveal.next(); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: -1 } ); | ||||
|  | ||||
| @@ -150,11 +151,15 @@ Reveal.addEventListener( 'ready', function() { | ||||
|  | ||||
| 		Reveal.next(); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 } ); | ||||
| 	}); | ||||
|  | ||||
| 	test( 'Reveal.next at end', function() { | ||||
| 		Reveal.slide( 3 ); | ||||
|  | ||||
| 		// We're at the end, this should have no effect | ||||
| 		Reveal.next(); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 3, v: 0, f: undefined } ); | ||||
|  | ||||
| 		// We're at the end, this should have no effect | ||||
| 		Reveal.next(); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 3, v: 0, f: undefined } ); | ||||
| 	}); | ||||
| @@ -180,17 +185,17 @@ Reveal.addEventListener( 'ready', function() { | ||||
| 	}); | ||||
|  | ||||
| 	test( 'Hiding all fragments', function() { | ||||
| 		var fragmentSlide = document.querySelector( '.reveal .slides>section:nth-child(3)' ); | ||||
| 		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' ); | ||||
|  | ||||
| 		Reveal.slide( 2, 0, 0 ); | ||||
| 		strictEqual( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 1, 'one fragment visible when index is 0' ); | ||||
|  | ||||
| 		Reveal.slide( 2, 0, -1 ); | ||||
| 		strictEqual( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 0, 'no fragments visible when index 0' ); | ||||
| 		strictEqual( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 0, 'no fragments visible when index is -1' ); | ||||
| 	}); | ||||
|  | ||||
| 	test( 'Current fragment', function() { | ||||
| 		var fragmentSlide = document.querySelector( '.reveal .slides>section:nth-child(3)' ); | ||||
| 		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' ); | ||||
|  | ||||
| 		Reveal.slide( 2, 0 ); | ||||
| 		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment at index -1' ); | ||||
| @@ -224,17 +229,17 @@ Reveal.addEventListener( 'ready', function() { | ||||
| 		// backwards: | ||||
|  | ||||
| 		Reveal.prev(); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'prev() goes to prev fragment' ); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, 'prev() goes to prev fragment' ); | ||||
|  | ||||
| 		Reveal.left(); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'left() goes to prev fragment' ); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'left() goes to prev fragment' ); | ||||
|  | ||||
| 		Reveal.up(); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: -1 }, 'up() goes to prev fragment' ); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'up() goes to prev fragment' ); | ||||
| 	}); | ||||
|  | ||||
| 	test( 'Stepping past fragments', function() { | ||||
| 		var fragmentSlide = document.querySelector( '.reveal .slides>section:nth-child(3)' ); | ||||
| 		var fragmentSlide = document.querySelector( '#fragment-slides>section:first-child' ); | ||||
|  | ||||
| 		Reveal.slide( 0, 0, 0 ); | ||||
| 		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 0, 'no fragments visible when on previous slide' ); | ||||
| @@ -243,6 +248,13 @@ Reveal.addEventListener( 'ready', function() { | ||||
| 		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 3, 'all fragments visible when on future slide' ); | ||||
| 	}); | ||||
|  | ||||
| 	test( 'Fragment indices', function() { | ||||
| 		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(2)' ); | ||||
|  | ||||
| 		Reveal.slide( 3, 0, 0 ); | ||||
| 		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 2, 'both fragments of same index are shown' ); | ||||
| 	}); | ||||
|  | ||||
| 	asyncTest( 'fragmentshown event', function() { | ||||
| 		expect( 2 ); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user