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 ) { | 	function sortFragments( fragments ) { | ||||||
|  |  | ||||||
| 		var a = toArray( fragments ); | 		fragments = toArray( fragments ); | ||||||
|  |  | ||||||
| 		// Elements that do not have an explicit `data-fragment-index` | 		var ordered = [], | ||||||
| 		// are given one which matches their order in the DOM | 			unordered = [], | ||||||
| 		a.forEach( function( el, idx ) { | 			sorted = []; | ||||||
| 			if( !el.hasAttribute( 'data-fragment-index' ) ) { |  | ||||||
| 				el.setAttribute( 'data-fragment-index', idx ); | 		// 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 ) { | 		// Append fragments without explicit indices in their | ||||||
| 			return l.getAttribute( 'data-fragment-index' ) - r.getAttribute( 'data-fragment-index'); | 		// 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, | 		return sorted; | ||||||
| 		// ensures that we're 0-indexed and have no gaps |  | ||||||
| 		a.forEach( function( el, idx ) { |  | ||||||
| 			el.setAttribute( 'data-fragment-index', idx ); |  | ||||||
| 		} ); |  | ||||||
|  |  | ||||||
| 		return a; |  | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -3173,9 +3194,11 @@ var Reveal = (function(){ | |||||||
| 		down: navigateDown, | 		down: navigateDown, | ||||||
| 		prev: navigatePrev, | 		prev: navigatePrev, | ||||||
| 		next: navigateNext, | 		next: navigateNext, | ||||||
|  |  | ||||||
|  | 		// Fragment methods | ||||||
|  | 		navigateFragment: navigateFragment, | ||||||
| 		prevFragment: previousFragment, | 		prevFragment: previousFragment, | ||||||
| 		nextFragment: nextFragment, | 		nextFragment: nextFragment, | ||||||
| 		navigateFragment: navigateFragment, |  | ||||||
|  |  | ||||||
| 		// Deprecated aliases | 		// Deprecated aliases | ||||||
| 		navigateTo: slide, | 		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> | 				</section> | ||||||
|  |  | ||||||
| 				<section> | 				<section id="fragment-slides"> | ||||||
| 					<h1>4</h1> | 					<section> | ||||||
| 					<ul> | 						<h1>3.1</h1> | ||||||
| 						<li class="fragment">4.1</li> | 						<ul> | ||||||
| 						<li class="fragment">4.2</li> | 							<li class="fragment">4.1</li> | ||||||
| 						<li class="fragment">4.3</li> | 							<li class="fragment">4.2</li> | ||||||
| 					</ul> | 							<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> | ||||||
|  |  | ||||||
| 				<section> | 				<section> | ||||||
|   | |||||||
							
								
								
									
										32
									
								
								test/test.js
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								test/test.js
									
									
									
									
									
								
							| @@ -5,6 +5,7 @@ | |||||||
| // 1 | // 1 | ||||||
| // 2 - Three sub-slides | // 2 - Three sub-slides | ||||||
| // 3 - Three fragment elements | // 3 - Three fragment elements | ||||||
|  | // 3 - Two fragments with same data-fragment-index | ||||||
| // 4 | // 4 | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -128,7 +129,7 @@ Reveal.addEventListener( 'ready', function() { | |||||||
| 	test( 'Reveal.next', function() { | 	test( 'Reveal.next', function() { | ||||||
| 		Reveal.slide( 0, 0 ); | 		Reveal.slide( 0, 0 ); | ||||||
|  |  | ||||||
| 		// Step through the vertical child slides | 		// Step through vertical child slides | ||||||
| 		Reveal.next(); | 		Reveal.next(); | ||||||
| 		deepEqual( Reveal.getIndices(), { h: 1, v: 0, f: undefined } ); | 		deepEqual( Reveal.getIndices(), { h: 1, v: 0, f: undefined } ); | ||||||
|  |  | ||||||
| @@ -138,7 +139,7 @@ Reveal.addEventListener( 'ready', function() { | |||||||
| 		Reveal.next(); | 		Reveal.next(); | ||||||
| 		deepEqual( Reveal.getIndices(), { h: 1, v: 2, f: undefined } ); | 		deepEqual( Reveal.getIndices(), { h: 1, v: 2, f: undefined } ); | ||||||
|  |  | ||||||
| 		// There's fragments on this slide | 		// Step through fragments | ||||||
| 		Reveal.next(); | 		Reveal.next(); | ||||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: -1 } ); | 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: -1 } ); | ||||||
|  |  | ||||||
| @@ -150,11 +151,15 @@ Reveal.addEventListener( 'ready', function() { | |||||||
|  |  | ||||||
| 		Reveal.next(); | 		Reveal.next(); | ||||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 } ); | 		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(); | 		Reveal.next(); | ||||||
| 		deepEqual( Reveal.getIndices(), { h: 3, v: 0, f: undefined } ); | 		deepEqual( Reveal.getIndices(), { h: 3, v: 0, f: undefined } ); | ||||||
|  |  | ||||||
| 		// We're at the end, this should have no effect |  | ||||||
| 		Reveal.next(); | 		Reveal.next(); | ||||||
| 		deepEqual( Reveal.getIndices(), { h: 3, v: 0, f: undefined } ); | 		deepEqual( Reveal.getIndices(), { h: 3, v: 0, f: undefined } ); | ||||||
| 	}); | 	}); | ||||||
| @@ -180,17 +185,17 @@ Reveal.addEventListener( 'ready', function() { | |||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	test( 'Hiding all fragments', 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 ); | 		Reveal.slide( 2, 0, 0 ); | ||||||
| 		strictEqual( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 1, 'one fragment visible when index is 0' ); | 		strictEqual( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 1, 'one fragment visible when index is 0' ); | ||||||
|  |  | ||||||
| 		Reveal.slide( 2, 0, -1 ); | 		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() { | 	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 ); | 		Reveal.slide( 2, 0 ); | ||||||
| 		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment at index -1' ); | 		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment at index -1' ); | ||||||
| @@ -224,17 +229,17 @@ Reveal.addEventListener( 'ready', function() { | |||||||
| 		// backwards: | 		// backwards: | ||||||
|  |  | ||||||
| 		Reveal.prev(); | 		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(); | 		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(); | 		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() { | 	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 ); | 		Reveal.slide( 0, 0, 0 ); | ||||||
| 		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 0, 'no fragments visible when on previous slide' ); | 		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' ); | 		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() { | 	asyncTest( 'fragmentshown event', function() { | ||||||
| 		expect( 2 ); | 		expect( 2 ); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user