reveal.js plugin flow now uses promises, refactor markdown plugin to use promises
This commit is contained in:
		
							
								
								
									
										17
									
								
								js/reveal.js
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								js/reveal.js
									
									
									
									
									
								
							| @@ -546,7 +546,7 @@ | |||||||
| 			// If the plugin has an 'init' method, initialize and | 			// If the plugin has an 'init' method, initialize and | ||||||
| 			// wait for the callback | 			// wait for the callback | ||||||
| 			if( typeof plugin.init === 'function' ) { | 			if( typeof plugin.init === 'function' ) { | ||||||
| 				plugin.init( function() { | 				plugin.init().then( function() { | ||||||
| 					if( --pluginsToInitialize === 0 ) { | 					if( --pluginsToInitialize === 0 ) { | ||||||
| 						loadAsyncDependencies(); | 						loadAsyncDependencies(); | ||||||
| 					} | 					} | ||||||
| @@ -1551,11 +1551,21 @@ | |||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * Registers a new plugin with this reveal.js instance. | 	 * Registers a new plugin with this reveal.js instance. | ||||||
|  | 	 * | ||||||
|  | 	 * reveal.js waits for all regisered plugins to initialize | ||||||
|  | 	 * before considering itself ready, as long as the plugin | ||||||
|  | 	 * is registered before calling `Reveal.initialize()`. | ||||||
| 	 */ | 	 */ | ||||||
| 	function registerPlugin( id, plugin ) { | 	function registerPlugin( id, plugin ) { | ||||||
|  |  | ||||||
| 		plugins[id] = plugin; | 		plugins[id] = plugin; | ||||||
|  |  | ||||||
|  | 		// If a plugin is registered after reveal.js is loaded, | ||||||
|  | 		// initialize it right away | ||||||
|  | 		if( loaded && typeof plugin.init === 'function' ) { | ||||||
|  | 			plugin.init(); | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| @@ -5841,6 +5851,11 @@ | |||||||
| 			return dom.wrapper || document.querySelector( '.reveal' ); | 			return dom.wrapper || document.querySelector( '.reveal' ); | ||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
|  | 		// Returns a hash with all registered plugins | ||||||
|  | 		getPlugins: function() { | ||||||
|  | 			return plugins; | ||||||
|  | 		}, | ||||||
|  |  | ||||||
| 		// Returns true if we're currently on the first slide | 		// Returns true if we're currently on the first slide | ||||||
| 		isFirstSlide: function() { | 		isFirstSlide: function() { | ||||||
| 			return ( indexh === 0 && indexv === 0 ); | 			return ( indexh === 0 && indexv === 0 ); | ||||||
|   | |||||||
| @@ -22,10 +22,6 @@ | |||||||
|  |  | ||||||
| 	var SCRIPT_END_PLACEHOLDER = '__SCRIPT_END__'; | 	var SCRIPT_END_PLACEHOLDER = '__SCRIPT_END__'; | ||||||
|  |  | ||||||
| 	var markdownFilesToLoad = 0; |  | ||||||
|  |  | ||||||
| 	var loadCallback; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * Retrieves the markdown contents of a slide section | 	 * Retrieves the markdown contents of a slide section | ||||||
| @@ -201,53 +197,41 @@ | |||||||
| 	 */ | 	 */ | ||||||
| 	function processSlides() { | 	function processSlides() { | ||||||
|  |  | ||||||
| 		[].slice.call( document.querySelectorAll( '[data-markdown]') ).forEach( function( section, i ) { | 		return new Promise( function( resolve ) { | ||||||
|  |  | ||||||
| 			if( section.getAttribute( 'data-markdown' ).length ) { | 			var externalPromises = []; | ||||||
|  |  | ||||||
| 				loadExternalMarkdown( section ); | 			[].slice.call( document.querySelectorAll( '[data-markdown]') ).forEach( function( section, i ) { | ||||||
|  |  | ||||||
| 			} | 				if( section.getAttribute( 'data-markdown' ).length ) { | ||||||
| 			else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-separator-vertical' ) || section.getAttribute( 'data-separator-notes' ) ) { |  | ||||||
|  |  | ||||||
| 				section.outerHTML = slidify( getMarkdownFromSlide( section ), { | 					externalPromises.push( loadExternalMarkdown( section ).then( | ||||||
| 					separator: section.getAttribute( 'data-separator' ), |  | ||||||
| 					verticalSeparator: section.getAttribute( 'data-separator-vertical' ), |  | ||||||
| 					notesSeparator: section.getAttribute( 'data-separator-notes' ), |  | ||||||
| 					attributes: getForwardedAttributes( section ) |  | ||||||
| 				}); |  | ||||||
|  |  | ||||||
| 			} | 						// Finished loading external file | ||||||
| 			else { | 						function( xhr, url ) { | ||||||
| 				section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) ); | 							section.outerHTML = slidify( xhr.responseText, { | ||||||
| 			} | 								separator: section.getAttribute( 'data-separator' ), | ||||||
|  | 								verticalSeparator: section.getAttribute( 'data-separator-vertical' ), | ||||||
|  | 								notesSeparator: section.getAttribute( 'data-separator-notes' ), | ||||||
|  | 								attributes: getForwardedAttributes( section ) | ||||||
|  | 							}); | ||||||
|  | 						}, | ||||||
|  |  | ||||||
| 		}); | 						// Failed to load markdown | ||||||
|  | 						function( xhr, url ) { | ||||||
|  | 							section.outerHTML = '<section data-state="alert">' + | ||||||
|  | 								'ERROR: The attempt to fetch ' + url + ' failed with HTTP status ' + xhr.status + '.' + | ||||||
|  | 								'Check your browser\'s JavaScript console for more details.' + | ||||||
|  | 								'<p>Remember that you need to serve the presentation HTML from a HTTP server.</p>' + | ||||||
|  | 								'</section>'; | ||||||
|  | 						} | ||||||
|  |  | ||||||
| 		checkIfLoaded(); | 					) ); | ||||||
|  |  | ||||||
| 	} | 				} | ||||||
|  | 				else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-separator-vertical' ) || section.getAttribute( 'data-separator-notes' ) ) { | ||||||
|  |  | ||||||
| 	function loadExternalMarkdown( section ) { | 					section.outerHTML = slidify( getMarkdownFromSlide( section ), { | ||||||
|  |  | ||||||
| 		markdownFilesToLoad += 1; |  | ||||||
|  |  | ||||||
| 		var xhr = new XMLHttpRequest(), |  | ||||||
| 			url = section.getAttribute( 'data-markdown' ); |  | ||||||
|  |  | ||||||
| 		datacharset = section.getAttribute( 'data-charset' ); |  | ||||||
|  |  | ||||||
| 		// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes |  | ||||||
| 		if( datacharset != null && datacharset != '' ) { |  | ||||||
| 			xhr.overrideMimeType( 'text/html; charset=' + datacharset ); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		xhr.onreadystatechange = function( section, xhr ) { |  | ||||||
| 			if( xhr.readyState === 4 ) { |  | ||||||
| 				// file protocol yields status code 0 (useful for local debug, mobile applications etc.) |  | ||||||
| 				if ( ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status === 0 ) { |  | ||||||
|  |  | ||||||
| 					section.outerHTML = slidify( xhr.responseText, { |  | ||||||
| 						separator: section.getAttribute( 'data-separator' ), | 						separator: section.getAttribute( 'data-separator' ), | ||||||
| 						verticalSeparator: section.getAttribute( 'data-separator-vertical' ), | 						verticalSeparator: section.getAttribute( 'data-separator-vertical' ), | ||||||
| 						notesSeparator: section.getAttribute( 'data-separator-notes' ), | 						notesSeparator: section.getAttribute( 'data-separator-notes' ), | ||||||
| @@ -256,31 +240,58 @@ | |||||||
|  |  | ||||||
| 				} | 				} | ||||||
| 				else { | 				else { | ||||||
|  | 					section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) ); | ||||||
| 					section.outerHTML = '<section data-state="alert">' + |  | ||||||
| 						'ERROR: The attempt to fetch ' + url + ' failed with HTTP status ' + xhr.status + '.' + |  | ||||||
| 						'Check your browser\'s JavaScript console for more details.' + |  | ||||||
| 						'<p>Remember that you need to serve the presentation HTML from a HTTP server.</p>' + |  | ||||||
| 						'</section>'; |  | ||||||
|  |  | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				convertSlides(); | 			}); | ||||||
|  |  | ||||||
| 				markdownFilesToLoad -= 1; | 			Promise.all( externalPromises ).then( resolve ); | ||||||
|  |  | ||||||
| 				checkIfLoaded(); | 		} ); | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	function loadExternalMarkdown( section ) { | ||||||
|  |  | ||||||
|  | 		return new Promise( function( resolve, reject ) { | ||||||
|  |  | ||||||
|  | 			var xhr = new XMLHttpRequest(), | ||||||
|  | 				url = section.getAttribute( 'data-markdown' ); | ||||||
|  |  | ||||||
|  | 			datacharset = section.getAttribute( 'data-charset' ); | ||||||
|  |  | ||||||
|  | 			// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes | ||||||
|  | 			if( datacharset != null && datacharset != '' ) { | ||||||
|  | 				xhr.overrideMimeType( 'text/html; charset=' + datacharset ); | ||||||
| 			} | 			} | ||||||
| 		}.bind( this, section, xhr ); |  | ||||||
|  |  | ||||||
| 		xhr.open( 'GET', url, true ); | 			xhr.onreadystatechange = function( section, xhr ) { | ||||||
|  | 				if( xhr.readyState === 4 ) { | ||||||
|  | 					// file protocol yields status code 0 (useful for local debug, mobile applications etc.) | ||||||
|  | 					if ( ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status === 0 ) { | ||||||
|  |  | ||||||
| 		try { | 						resolve( xhr, url ); | ||||||
| 			xhr.send(); |  | ||||||
| 		} | 					} | ||||||
| 		catch ( e ) { | 					else { | ||||||
| 			alert( 'Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e ); |  | ||||||
| 		} | 						reject( xhr, url ); | ||||||
|  |  | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			}.bind( this, section, xhr ); | ||||||
|  |  | ||||||
|  | 			xhr.open( 'GET', url, true ); | ||||||
|  |  | ||||||
|  | 			try { | ||||||
|  | 				xhr.send(); | ||||||
|  | 			} | ||||||
|  | 			catch ( e ) { | ||||||
|  | 				alert( 'Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e ); | ||||||
|  | 				resolve( xhr, url ); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 		} ); | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -381,16 +392,7 @@ | |||||||
|  |  | ||||||
| 		} ); | 		} ); | ||||||
|  |  | ||||||
| 	} | 		return Promise.resolve(); | ||||||
|  |  | ||||||
| 	function checkIfLoaded() { |  | ||||||
|  |  | ||||||
| 		if( markdownFilesToLoad === 0 ) { |  | ||||||
| 			if( loadCallback ) { |  | ||||||
| 				loadCallback(); |  | ||||||
| 				loadCallback = null; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -424,10 +426,7 @@ | |||||||
| 				marked.setOptions( options ); | 				marked.setOptions( options ); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			loadCallback = callback; | 			return processSlides().then( convertSlides ); | ||||||
|  |  | ||||||
| 			processSlides(); |  | ||||||
| 			convertSlides(); |  | ||||||
|  |  | ||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
|   | |||||||
| @@ -151,20 +151,30 @@ var RevealNotes = (function() { | |||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if( !/receiver/i.test( window.location.search ) ) { | 	return { | ||||||
|  | 		init: function() { | ||||||
|  |  | ||||||
| 		// If the there's a 'notes' query set, open directly | 			if( !/receiver/i.test( window.location.search ) ) { | ||||||
| 		if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) { |  | ||||||
| 			openNotes(); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		// Open the notes when the 's' key is hit | 				// If the there's a 'notes' query set, open directly | ||||||
| 		Reveal.addKeyBinding({keyCode: 83, key: 'S', description: 'Speaker notes view'}, function() { | 				if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) { | ||||||
| 			openNotes(); | 					openNotes(); | ||||||
| 		} ); | 				} | ||||||
|  |  | ||||||
| 	} | 				// Open the notes when the 's' key is hit | ||||||
|  | 				Reveal.addKeyBinding({keyCode: 83, key: 'S', description: 'Speaker notes view'}, function() { | ||||||
|  | 					openNotes(); | ||||||
|  | 				} ); | ||||||
|  |  | ||||||
| 	return { open: openNotes }; | 			} | ||||||
|  |  | ||||||
|  | 			return Promise.resolve(); | ||||||
|  |  | ||||||
|  | 		}, | ||||||
|  |  | ||||||
|  | 		open: openNotes | ||||||
|  | 	}; | ||||||
|  |  | ||||||
| })(); | })(); | ||||||
|  |  | ||||||
|  | Reveal.registerPlugin( 'notes', RevealNotes ); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user