<!doctype html>
<html lang="en">

	<head>
		<meta charset="utf-8">

		<title>reveal.js - Test Auto-Animate</title>

		<link rel="stylesheet" href="../dist/reveal.css">
		<link rel="stylesheet" href="../node_modules/qunit/qunit/qunit.css">
		<script src="../node_modules/qunit/qunit/qunit.js"></script>
	</head>

	<body style="overflow: auto;">

		<div id="qunit"></div>
		<div id="qunit-fixture"></div>

		<div class="reveal">

			<div class="slides">

				<section data-auto-animate>
					<h1>h1</h1>
					<h2>h2</h2>
					<h3 style="position: absolute; left: 0;">h3</h2>
				</section>

				<section data-auto-animate>
					<h1 data-auto-animate-duration="0.1">h1</h1>
					<h2 style="opacity: 0;">h2</h2>
					<h3 style="position: absolute; left: 100px;">h3</h2>
				</section>

				<section data-auto-animate data-auto-animate-duration="0.1">
					<h1>h1</h1>
					<h2>h2</h2>
					<h3>h3</h2>
				</section>

				<section>
					<h1>Non-auto-animate slide</h1>
				</section>

				<section data-auto-animate>
					<h1 class="fragment">h1</h1>
					<h2 class="fragment">h2</h2>
					<h3>h3</h3>
				</section>

				<section data-auto-animate>
					<h1 class="fragment">h1</h1>
					<h2 class="fragment">h2</h2>
					<h3 class="fragment">h3</h3>
				</section>

				<section>
					<h1>Non-auto-animate slide</h1>
				</section>

			</div>

		</div>

		<script src="../dist/reveal.js"></script>
		<script>

			QUnit.config.reorder = false;

			const slides = Array.prototype.map.call( document.querySelectorAll( '.slides section' ), slide => {
				return {
					slide: slide,
					h1: slide.querySelector( 'h1' ),
					h2: slide.querySelector( 'h2' ),
					h3: slide.querySelector( 'h3' )
				};
			} );

			Reveal.initialize().then( async () => {

				QUnit.module( 'Auto-Animate' );

				QUnit.test( 'Adds data-auto-animate-target', assert => {
					Reveal.slide(1);
					assert.strictEqual( slides[0].h1.getAttribute( 'data-auto-animate-target' ), '', 'From elements have blank data-auto-animate-target' );
					assert.ok( slides[1].h1.getAttribute( 'data-auto-animate-target' ).length > 0, 'To elements have a data-auto-animate-target value' );
				});

				QUnit.test( 'Ends on correct target styles', assert => {
					Reveal.slide(1);
					assert.strictEqual( slides[1].h2.style.opacity, "0" );
					assert.strictEqual( slides[1].h3.offsetLeft, 100 );
				});

				QUnit.test( 'Does not add [data-auto-animate] on non auto-animated slides', assert => {
					Reveal.slide(2);
					Reveal.next();
					assert.ok( slides[3].slide.hasAttribute( 'data-auto-animate' ) === false )
				});

				QUnit.test( 'autoAnimate config option', assert => {
					Reveal.configure({ autoAnimate: false });

					assert.ok( document.querySelectorAll( 'data-auto-animate-target' ).length === 0, 'Removes all [data-auto-animate-target]' )
					assert.ok( Array.prototype.every.call( document.querySelectorAll( 'section[data-auto-animate]' ), el => {
						return el.dataset.autoAnimate === '';
					}, 'All data-auto-animate attributes are reset' ) );

					Reveal.configure({ autoAnimate: true });
				});

				QUnit.test( 'Carries forward matching fragment visibility', assert => {
					Reveal.slide(4);
					assert.ok( !slides[5].h1.classList.contains( 'visible' ) )
					Reveal.next();
					Reveal.next();
					Reveal.next();
					assert.ok( slides[5].h1.classList.contains( 'visible' ) )
					assert.ok( slides[5].h2.classList.contains( 'visible' ) )
					assert.ok( !slides[5].h3.classList.contains( 'visible' ) )
					Reveal.next();
					assert.ok( slides[5].h3.classList.contains( 'visible' ) )
					Reveal.next();
					assert.ok( slides[6].slide === Reveal.getCurrentSlide() )
				});

				QUnit.test( 'Slide specific data-auto-animate-duration', assert => {
					assert.timeout( 400 );
					assert.expect( 1 );

					return new Promise( resolve => {
						let callback = () => {
							slides[2].h3.removeEventListener( 'transitionend', callback );
							assert.ok( true, 'Transition ended within time window' );
							resolve();
						}

						Reveal.slide(1);
						Reveal.slide(2);

						slides[2].h3.addEventListener( 'transitionend', callback );
					} );
				});

				// QUnit.test( 'Element specific data-auto-animate-duration', assert => {
				// 	assert.timeout( 400 );
				// 	assert.expect( 1 );

				// 	return new Promise( resolve => {
				// 		let callback = () => {
				// 			slides[1].h1.removeEventListener( 'transitionend', callback );
				// 			assert.ok( true, 'Transition ended within time window' );
				// 			resolve()
				// 		}


				// 		Reveal.slide(1);
				// 		slides[1].h1.addEventListener( 'transitionend', callback );
				// 	} );
				// });

			} );
		</script>

	</body>
</html>
