autoplay support for content inside of fragments
This commit is contained in:
		
							
								
								
									
										64
									
								
								js/reveal.js
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								js/reveal.js
									
									
									
									
									
								
							@@ -1242,6 +1242,42 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Find the closest parent that matches the given
 | 
				
			||||||
 | 
						 * selector.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @param {HTMLElement} target The child element
 | 
				
			||||||
 | 
						 * @param {String} selector The CSS selector to match
 | 
				
			||||||
 | 
						 * the parents against
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @return {HTMLElement} The matched parent or null
 | 
				
			||||||
 | 
						 * if no matching parent was found
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						function closestParent( target, selector ) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							var parent = target.parentNode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							while( parent ) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// There's some overhead doing this each time, we don't
 | 
				
			||||||
 | 
								// want to rewrite the element prototype but should still
 | 
				
			||||||
 | 
								// be enough to feature detect once at startup...
 | 
				
			||||||
 | 
								var matchesMethod = parent.matches || parent.matchesSelector || parent.msMatchesSelector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// If we find a match, we're all set
 | 
				
			||||||
 | 
								if( matchesMethod && matchesMethod.call( parent, selector ) ) {
 | 
				
			||||||
 | 
									return parent;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Keep searching
 | 
				
			||||||
 | 
								parent = parent.parentNode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Converts various color input formats to an {r:0,g:0,b:0} object.
 | 
						 * Converts various color input formats to an {r:0,g:0,b:0} object.
 | 
				
			||||||
	 *
 | 
						 *
 | 
				
			||||||
@@ -3046,32 +3082,44 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Start playback of any embedded content inside of
 | 
						 * Start playback of any embedded content inside of
 | 
				
			||||||
	 * the targeted slide.
 | 
						 * the given element.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	function startEmbeddedContent( slide ) {
 | 
						function startEmbeddedContent( element ) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if( slide && !isSpeakerNotes() ) {
 | 
							if( element && !isSpeakerNotes() ) {
 | 
				
			||||||
			// Restart GIFs
 | 
								// Restart GIFs
 | 
				
			||||||
			toArray( slide.querySelectorAll( 'img[src$=".gif"]' ) ).forEach( function( el ) {
 | 
								toArray( element.querySelectorAll( 'img[src$=".gif"]' ) ).forEach( function( el ) {
 | 
				
			||||||
				// Setting the same unchanged source like this was confirmed
 | 
									// Setting the same unchanged source like this was confirmed
 | 
				
			||||||
				// to work in Chrome, FF & Safari
 | 
									// to work in Chrome, FF & Safari
 | 
				
			||||||
				el.setAttribute( 'src', el.getAttribute( 'src' ) );
 | 
									el.setAttribute( 'src', el.getAttribute( 'src' ) );
 | 
				
			||||||
			} );
 | 
								} );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// HTML5 media elements
 | 
								// HTML5 media elements
 | 
				
			||||||
			toArray( slide.querySelectorAll( 'video, audio' ) ).forEach( function( el ) {
 | 
								toArray( element.querySelectorAll( 'video, audio' ) ).forEach( function( el ) {
 | 
				
			||||||
 | 
									if( closestParent( el, '.fragment' ) && !closestParent( el, '.fragment.visible' ) ) {
 | 
				
			||||||
 | 
										return;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if( el.hasAttribute( 'data-autoplay' ) && typeof el.play === 'function' ) {
 | 
									if( el.hasAttribute( 'data-autoplay' ) && typeof el.play === 'function' ) {
 | 
				
			||||||
					el.play();
 | 
										el.play();
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} );
 | 
								} );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Normal iframes
 | 
								// Normal iframes
 | 
				
			||||||
			toArray( slide.querySelectorAll( 'iframe[src]' ) ).forEach( function( el ) {
 | 
								toArray( element.querySelectorAll( 'iframe[src]' ) ).forEach( function( el ) {
 | 
				
			||||||
 | 
									if( closestParent( el, '.fragment' ) && !closestParent( el, '.fragment.visible' ) ) {
 | 
				
			||||||
 | 
										return;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				startEmbeddedIframe( { target: el } );
 | 
									startEmbeddedIframe( { target: el } );
 | 
				
			||||||
			} );
 | 
								} );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Lazy loading iframes
 | 
								// Lazy loading iframes
 | 
				
			||||||
			toArray( slide.querySelectorAll( 'iframe[data-src]' ) ).forEach( function( el ) {
 | 
								toArray( element.querySelectorAll( 'iframe[data-src]' ) ).forEach( function( el ) {
 | 
				
			||||||
 | 
									if( closestParent( el, '.fragment' ) && !closestParent( el, '.fragment.visible' ) ) {
 | 
				
			||||||
 | 
										return;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if( el.getAttribute( 'src' ) !== el.getAttribute( 'data-src' ) ) {
 | 
									if( el.getAttribute( 'src' ) !== el.getAttribute( 'data-src' ) ) {
 | 
				
			||||||
					el.removeEventListener( 'load', startEmbeddedIframe ); // remove first to avoid dupes
 | 
										el.removeEventListener( 'load', startEmbeddedIframe ); // remove first to avoid dupes
 | 
				
			||||||
					el.addEventListener( 'load', startEmbeddedIframe );
 | 
										el.addEventListener( 'load', startEmbeddedIframe );
 | 
				
			||||||
@@ -3622,6 +3670,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
						if( i === index ) {
 | 
											if( i === index ) {
 | 
				
			||||||
							element.classList.add( 'current-fragment' );
 | 
												element.classList.add( 'current-fragment' );
 | 
				
			||||||
 | 
												startEmbeddedContent( element );
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					// Hidden fragments
 | 
										// Hidden fragments
 | 
				
			||||||
@@ -3631,7 +3680,6 @@
 | 
				
			|||||||
						element.classList.remove( 'current-fragment' );
 | 
											element.classList.remove( 'current-fragment' );
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
				} );
 | 
									} );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if( fragmentsHidden.length ) {
 | 
									if( fragmentsHidden.length ) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user