Merge pull request #721 from hakimel/refactor/fragments
Refactor fragments
This commit is contained in:
		
							
								
								
									
										297
									
								
								js/reveal.js
									
									
									
									
									
								
							
							
						
						
									
										297
									
								
								js/reveal.js
									
									
									
									
									
								
							| @@ -305,7 +305,7 @@ var Reveal = (function(){ | ||||
| 		setupDOM(); | ||||
|  | ||||
| 		// Decorate the slide DOM elements with state classes (past/future) | ||||
| 		setupSlides(); | ||||
| 		formatSlides(); | ||||
|  | ||||
| 		// Updates the presentation to match the current configuration values | ||||
| 		configure(); | ||||
| @@ -333,26 +333,6 @@ var Reveal = (function(){ | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Iterates through and decorates slides DOM elements with | ||||
| 	 * appropriate classes. | ||||
| 	 */ | ||||
| 	function setupSlides() { | ||||
|  | ||||
| 		var horizontalSlides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ); | ||||
| 		horizontalSlides.forEach( function( horizontalSlide ) { | ||||
|  | ||||
| 			var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) ); | ||||
| 			verticalSlides.forEach( function( verticalSlide, y ) { | ||||
|  | ||||
| 				if( y > 0 ) verticalSlide.classList.add( 'future' ); | ||||
|  | ||||
| 			} ); | ||||
|  | ||||
| 		} ); | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Finds and stores references to DOM elements which are | ||||
| 	 * required by the presentation. If a required element is | ||||
| @@ -1027,38 +1007,6 @@ var Reveal = (function(){ | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Return a sorted fragments list, ordered by an increasing | ||||
| 	 * "data-fragment-index" attribute. | ||||
| 	 * | ||||
| 	 * Fragments will be revealed in the order that they are returned by | ||||
| 	 * this function, so you can use the index attributes to control the | ||||
| 	 * order of fragment appearance. | ||||
| 	 * | ||||
| 	 * To maintain a sensible default fragment order, fragments are presumed | ||||
| 	 * to be passed in document order. This function adds a "fragment-index" | ||||
| 	 * attribute to each node if such an attribute is not already present, | ||||
| 	 * and sets that attribute to an integer value which is the position of | ||||
| 	 * the fragment within the fragments list. | ||||
| 	 */ | ||||
| 	function sortFragments( fragments ) { | ||||
|  | ||||
| 		var a = toArray( fragments ); | ||||
|  | ||||
| 		a.forEach( function( el, idx ) { | ||||
| 			if( !el.hasAttribute( 'data-fragment-index' ) ) { | ||||
| 				el.setAttribute( 'data-fragment-index', idx ); | ||||
| 			} | ||||
| 		} ); | ||||
|  | ||||
| 		a.sort( function( l, r ) { | ||||
| 			return l.getAttribute( 'data-fragment-index' ) - r.getAttribute( 'data-fragment-index'); | ||||
| 		} ); | ||||
|  | ||||
| 		return a; | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Applies JavaScript-controlled layout rules to the | ||||
| 	 * presentation. | ||||
| @@ -1560,16 +1508,7 @@ var Reveal = (function(){ | ||||
|  | ||||
| 		// Show fragment, if specified | ||||
| 		if( typeof f !== 'undefined' ) { | ||||
| 			var fragments = sortFragments( currentSlide.querySelectorAll( '.fragment' ) ); | ||||
|  | ||||
| 			toArray( fragments ).forEach( function( fragment, indexf ) { | ||||
| 				if( indexf < f ) { | ||||
| 					fragment.classList.add( 'visible' ); | ||||
| 				} | ||||
| 				else { | ||||
| 					fragment.classList.remove( 'visible' ); | ||||
| 				} | ||||
| 			} ); | ||||
| 			navigateFragment( f ); | ||||
| 		} | ||||
|  | ||||
| 		// Dispatch an event if the slide changed | ||||
| @@ -1652,6 +1591,8 @@ var Reveal = (function(){ | ||||
| 		// Re-create the slide backgrounds | ||||
| 		createBackgrounds(); | ||||
|  | ||||
| 		formatSlides(); | ||||
|  | ||||
| 		updateControls(); | ||||
| 		updateProgress(); | ||||
| 		updateBackground( true ); | ||||
| @@ -1659,6 +1600,30 @@ var Reveal = (function(){ | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Iterates through and decorates slides DOM elements with | ||||
| 	 * appropriate classes. | ||||
| 	 */ | ||||
| 	function formatSlides() { | ||||
|  | ||||
| 		var horizontalSlides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ); | ||||
| 		horizontalSlides.forEach( function( horizontalSlide ) { | ||||
|  | ||||
| 			var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) ); | ||||
| 			verticalSlides.forEach( function( verticalSlide, y ) { | ||||
|  | ||||
| 				if( y > 0 ) verticalSlide.classList.add( 'future' ); | ||||
|  | ||||
| 				sortFragments( verticalSlide.querySelectorAll( '.fragment' ) ); | ||||
|  | ||||
| 			} ); | ||||
|  | ||||
| 			if( verticalSlides.length === 0 ) sortFragments( horizontalSlide.querySelectorAll( '.fragment' ) ); | ||||
|  | ||||
| 		} ); | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Updates one dimension of slides by showing the slide | ||||
| 	 * with the specified index. | ||||
| @@ -1713,7 +1678,9 @@ var Reveal = (function(){ | ||||
|  | ||||
| 					// Show all fragments on prior slides | ||||
| 					while( pastFragments.length ) { | ||||
| 						pastFragments.pop().classList.add( 'visible' ); | ||||
| 						var pastFragment = pastFragments.pop(); | ||||
| 						pastFragment.classList.add( 'visible' ); | ||||
| 						pastFragment.classList.remove( 'current-fragment' ); | ||||
| 					} | ||||
| 				} | ||||
| 				else if( i > index ) { | ||||
| @@ -1724,7 +1691,9 @@ var Reveal = (function(){ | ||||
|  | ||||
| 					// No fragments in future slides should be visible ahead of time | ||||
| 					while( futureFragments.length ) { | ||||
| 						futureFragments.pop().classList.remove( 'visible' ); | ||||
| 						var futureFragment = futureFragments.pop(); | ||||
| 						futureFragment.classList.remove( 'visible' ); | ||||
| 						futureFragment.classList.remove( 'current-fragment' ); | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| @@ -2270,7 +2239,7 @@ var Reveal = (function(){ | ||||
| 			var hasFragments = currentSlide.querySelectorAll( '.fragment' ).length > 0; | ||||
| 			if( hasFragments ) { | ||||
| 				var visibleFragments = currentSlide.querySelectorAll( '.fragment.visible' ); | ||||
| 				f = visibleFragments.length; | ||||
| 				f = visibleFragments.length - 1; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| @@ -2278,6 +2247,151 @@ var Reveal = (function(){ | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Return a sorted fragments list, ordered by an increasing | ||||
| 	 * "data-fragment-index" attribute. | ||||
| 	 * | ||||
| 	 * Fragments will be revealed in the order that they are returned by | ||||
| 	 * this function, so you can use the index attributes to control the | ||||
| 	 * order of fragment appearance. | ||||
| 	 * | ||||
| 	 * To maintain a sensible default fragment order, fragments are presumed | ||||
| 	 * to be passed in document order. This function adds a "fragment-index" | ||||
| 	 * attribute to each node if such an attribute is not already present, | ||||
| 	 * and sets that attribute to an integer value which is the position of | ||||
| 	 * the fragment within the fragments list. | ||||
| 	 */ | ||||
| 	function sortFragments( fragments ) { | ||||
|  | ||||
| 		fragments = toArray( fragments ); | ||||
|  | ||||
| 		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 ] ); | ||||
| 			} | ||||
| 		} ); | ||||
|  | ||||
| 		// 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 ++; | ||||
| 		} ); | ||||
|  | ||||
| 		return sorted; | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Navigate to the specified slide fragment. | ||||
| 	 * | ||||
| 	 * @param {Number} index The index of the fragment that | ||||
| 	 * should be shown, -1 means all are invisible | ||||
| 	 * @param {Number} offset Integer offset to apply to the | ||||
| 	 * fragment index | ||||
| 	 * | ||||
| 	 * @return {Boolean} true if a change was made in any | ||||
| 	 * fragments visibility as part of this call | ||||
| 	 */ | ||||
| 	function navigateFragment( index, offset ) { | ||||
|  | ||||
| 		if( currentSlide && config.fragments ) { | ||||
|  | ||||
| 			var fragments = sortFragments( currentSlide.querySelectorAll( '.fragment' ) ); | ||||
| 			if( fragments.length ) { | ||||
|  | ||||
| 				// If no index is specified, find the current | ||||
| 				if( typeof index !== 'number' ) { | ||||
| 					var lastVisibleFragment = sortFragments( currentSlide.querySelectorAll( '.fragment.visible' ) ).pop(); | ||||
|  | ||||
| 					if( lastVisibleFragment ) { | ||||
| 						index = parseInt( lastVisibleFragment.getAttribute( 'data-fragment-index' ) || 0, 10 ); | ||||
| 					} | ||||
| 					else { | ||||
| 						index = -1; | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| 				// If an offset is specified, apply it to the index | ||||
| 				if( typeof offset === 'number' ) { | ||||
| 					index += offset; | ||||
| 				} | ||||
|  | ||||
| 				var fragmentsShown = [], | ||||
| 					fragmentsHidden = []; | ||||
|  | ||||
| 				toArray( fragments ).forEach( function( element, i ) { | ||||
|  | ||||
| 					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' ); | ||||
|  | ||||
| 						if( i === index ) { | ||||
| 							element.classList.add( 'current-fragment' ); | ||||
| 						} | ||||
| 					} | ||||
| 					// 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( fragmentsShown.length ) { | ||||
| 					dispatchEvent( 'fragmentshown', { fragment: fragmentsShown[0], fragments: fragmentsShown } ); | ||||
| 				} | ||||
|  | ||||
| 				updateControls(); | ||||
|  | ||||
| 				return !!( fragmentsShown.length || fragmentsHidden.length ); | ||||
|  | ||||
| 			} | ||||
|  | ||||
| 		} | ||||
|  | ||||
| 		return false; | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Navigate to the next slide fragment. | ||||
| 	 * | ||||
| @@ -2286,29 +2400,7 @@ var Reveal = (function(){ | ||||
| 	 */ | ||||
| 	function nextFragment() { | ||||
|  | ||||
| 		if( currentSlide && config.fragments ) { | ||||
| 			var fragments = sortFragments( currentSlide.querySelectorAll( '.fragment:not(.visible)' ) ); | ||||
|  | ||||
| 			if( fragments.length ) { | ||||
| 				// Find the index of the next fragment | ||||
| 				var index = fragments[0].getAttribute( 'data-fragment-index' ); | ||||
|  | ||||
| 				// Find all fragments with the same index | ||||
| 				fragments = currentSlide.querySelectorAll( '.fragment[data-fragment-index="'+ index +'"]' ); | ||||
|  | ||||
| 				toArray( fragments ).forEach( function( element ) { | ||||
| 					element.classList.add( 'visible' ); | ||||
| 				} ); | ||||
|  | ||||
| 				// Notify subscribers of the change | ||||
| 				dispatchEvent( 'fragmentshown', { fragment: fragments[0], fragments: fragments } ); | ||||
|  | ||||
| 				updateControls(); | ||||
| 				return true; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		return false; | ||||
| 		return navigateFragment( null, 1 ); | ||||
|  | ||||
| 	} | ||||
|  | ||||
| @@ -2320,29 +2412,7 @@ var Reveal = (function(){ | ||||
| 	 */ | ||||
| 	function previousFragment() { | ||||
|  | ||||
| 		if( currentSlide && config.fragments ) { | ||||
| 			var fragments = sortFragments( currentSlide.querySelectorAll( '.fragment.visible' ) ); | ||||
|  | ||||
| 			if( fragments.length ) { | ||||
| 				// Find the index of the previous fragment | ||||
| 				var index = fragments[ fragments.length - 1 ].getAttribute( 'data-fragment-index' ); | ||||
|  | ||||
| 				// Find all fragments with the same index | ||||
| 				fragments = currentSlide.querySelectorAll( '.fragment[data-fragment-index="'+ index +'"]' ); | ||||
|  | ||||
| 				toArray( fragments ).forEach( function( f ) { | ||||
| 					f.classList.remove( 'visible' ); | ||||
| 				} ); | ||||
|  | ||||
| 				// Notify subscribers of the change | ||||
| 				dispatchEvent( 'fragmenthidden', { fragment: fragments[0], fragments: fragments } ); | ||||
|  | ||||
| 				updateControls(); | ||||
| 				return true; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		return false; | ||||
| 		return navigateFragment( null, -1 ); | ||||
|  | ||||
| 	} | ||||
|  | ||||
| @@ -3130,6 +3200,9 @@ var Reveal = (function(){ | ||||
| 		down: navigateDown, | ||||
| 		prev: navigatePrev, | ||||
| 		next: navigateNext, | ||||
|  | ||||
| 		// Fragment methods | ||||
| 		navigateFragment: navigateFragment, | ||||
| 		prevFragment: previousFragment, | ||||
| 		nextFragment: nextFragment, | ||||
|  | ||||
|   | ||||
							
								
								
									
										6
									
								
								js/reveal.min.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								js/reveal.min.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -76,7 +76,7 @@ | ||||
| 		<script src="../plugin/markdown/markdown.js"></script> | ||||
| 		<script src="qunit-1.12.0.js"></script> | ||||
| 
 | ||||
| 		<script src="test-element-attributes-markdown.js"></script> | ||||
| 		<script src="test-markdown-element-attributes.js"></script> | ||||
| 
 | ||||
| 	</body> | ||||
| </html> | ||||
| @@ -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> | ||||
|   | ||||
							
								
								
									
										81
									
								
								test/test.js
									
									
									
									
									
								
							
							
						
						
									
										81
									
								
								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,10 @@ 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 } ); | ||||
|  | ||||
| 		Reveal.next(); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 } ); | ||||
|  | ||||
| @@ -147,14 +151,15 @@ Reveal.addEventListener( 'ready', function() { | ||||
|  | ||||
| 		Reveal.next(); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 } ); | ||||
| 	}); | ||||
|  | ||||
| 		Reveal.next(); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 3 } ); | ||||
| 	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 } ); | ||||
| 	}); | ||||
| @@ -166,6 +171,9 @@ Reveal.addEventListener( 'ready', function() { | ||||
| 	QUnit.module( 'Fragments' ); | ||||
|  | ||||
| 	test( 'Sliding to fragments', function() { | ||||
| 		Reveal.slide( 2, 0, -1 ); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: -1 }, 'Reveal.slide( 2, 0, -1 )' ); | ||||
|  | ||||
| 		Reveal.slide( 2, 0, 0 ); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'Reveal.slide( 2, 0, 0 )' ); | ||||
|  | ||||
| @@ -176,19 +184,45 @@ Reveal.addEventListener( 'ready', function() { | ||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'Reveal.slide( 2, 0, 1 )' ); | ||||
| 	}); | ||||
|  | ||||
| 	test( 'Stepping through fragments', function() { | ||||
| 	test( 'Hiding all fragments', function() { | ||||
| 		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 is -1' ); | ||||
| 	}); | ||||
|  | ||||
| 	test( 'Current fragment', function() { | ||||
| 		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' ); | ||||
|  | ||||
| 		Reveal.slide( 2, 0, 0 ); | ||||
| 		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 1, 'one current fragment at index 0' ); | ||||
|  | ||||
| 		Reveal.slide( 1, 0, 0 ); | ||||
| 		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment when navigating to previous slide' ); | ||||
|  | ||||
| 		Reveal.slide( 3, 0, 0 ); | ||||
| 		strictEqual( fragmentSlide.querySelectorAll( '.fragment.current-fragment' ).length, 0, 'no current fragment when navigating to next slide' ); | ||||
| 	}); | ||||
|  | ||||
| 	test( 'Stepping through fragments', function() { | ||||
| 		Reveal.slide( 2, 0, -1 ); | ||||
|  | ||||
| 		// forwards: | ||||
|  | ||||
| 		Reveal.next(); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'next() goes to next fragment' ); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'next() goes to next fragment' ); | ||||
|  | ||||
| 		Reveal.right(); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, 'right() goes to next fragment' ); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'right() goes to next fragment' ); | ||||
|  | ||||
| 		Reveal.down(); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 3 }, 'down() goes to next fragment' ); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 2 }, 'down() goes to next fragment' ); | ||||
|  | ||||
| 		Reveal.down(); // moves to f #3 | ||||
|  | ||||
| @@ -201,11 +235,11 @@ Reveal.addEventListener( 'ready', function() { | ||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 1 }, 'left() goes to prev fragment' ); | ||||
|  | ||||
| 		Reveal.up(); | ||||
| 		deepEqual( Reveal.getIndices(), { h: 2, v: 0, f: 0 }, 'left() 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:nth-child(1)' ); | ||||
|  | ||||
| 		Reveal.slide( 0, 0, 0 ); | ||||
| 		equal( fragmentSlide.querySelectorAll( '.fragment.visible' ).length, 0, 'no fragments visible when on previous slide' ); | ||||
| @@ -214,6 +248,31 @@ 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' ); | ||||
| 	}); | ||||
|  | ||||
| 	test( 'Index generation', function() { | ||||
| 		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(1)' ); | ||||
|  | ||||
| 		// These have no indices defined to start with | ||||
| 		equal( fragmentSlide.querySelectorAll( '.fragment' )[0].getAttribute( 'data-fragment-index' ), '0' ); | ||||
| 		equal( fragmentSlide.querySelectorAll( '.fragment' )[1].getAttribute( 'data-fragment-index' ), '1' ); | ||||
| 		equal( fragmentSlide.querySelectorAll( '.fragment' )[2].getAttribute( 'data-fragment-index' ), '2' ); | ||||
| 	}); | ||||
|  | ||||
| 	test( 'Index normalization', function() { | ||||
| 		var fragmentSlide = document.querySelector( '#fragment-slides>section:nth-child(3)' ); | ||||
|  | ||||
| 		// These start out as 1-4-4 and should normalize to 0-1-1 | ||||
| 		equal( fragmentSlide.querySelectorAll( '.fragment' )[0].getAttribute( 'data-fragment-index' ), '0' ); | ||||
| 		equal( fragmentSlide.querySelectorAll( '.fragment' )[1].getAttribute( 'data-fragment-index' ), '1' ); | ||||
| 		equal( fragmentSlide.querySelectorAll( '.fragment' )[2].getAttribute( 'data-fragment-index' ), '1' ); | ||||
| 	}); | ||||
|  | ||||
| 	asyncTest( 'fragmentshown event', function() { | ||||
| 		expect( 2 ); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user