reveal.js plugin flow now uses promises, refactor markdown plugin to use promises

This commit is contained in:
Hakim El Hattab 2019-03-04 14:11:21 +01:00
parent 46f8f86fa1
commit d780352b7f
3 changed files with 110 additions and 86 deletions

View file

@ -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 );

View file

@ -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,11 +197,36 @@
*/ */
function processSlides() { function processSlides() {
return new Promise( function( resolve ) {
var externalPromises = [];
[].slice.call( document.querySelectorAll( '[data-markdown]') ).forEach( function( section, i ) { [].slice.call( document.querySelectorAll( '[data-markdown]') ).forEach( function( section, i ) {
if( section.getAttribute( 'data-markdown' ).length ) { if( section.getAttribute( 'data-markdown' ).length ) {
loadExternalMarkdown( section ); externalPromises.push( loadExternalMarkdown( section ).then(
// Finished loading external file
function( xhr, url ) {
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>';
}
) );
} }
else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-separator-vertical' ) || section.getAttribute( 'data-separator-notes' ) ) { else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-separator-vertical' ) || section.getAttribute( 'data-separator-notes' ) ) {
@ -224,13 +245,15 @@
}); });
checkIfLoaded(); Promise.all( externalPromises ).then( resolve );
} );
} }
function loadExternalMarkdown( section ) { function loadExternalMarkdown( section ) {
markdownFilesToLoad += 1; return new Promise( function( resolve, reject ) {
var xhr = new XMLHttpRequest(), var xhr = new XMLHttpRequest(),
url = section.getAttribute( 'data-markdown' ); url = section.getAttribute( 'data-markdown' );
@ -247,29 +270,14 @@
// file protocol yields status code 0 (useful for local debug, mobile applications etc.) // file protocol yields status code 0 (useful for local debug, mobile applications etc.)
if ( ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status === 0 ) { if ( ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status === 0 ) {
section.outerHTML = slidify( xhr.responseText, { resolve( xhr, url );
separator: section.getAttribute( 'data-separator' ),
verticalSeparator: section.getAttribute( 'data-separator-vertical' ),
notesSeparator: section.getAttribute( 'data-separator-notes' ),
attributes: getForwardedAttributes( section )
});
} }
else { else {
section.outerHTML = '<section data-state="alert">' + reject( xhr, url );
'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;
checkIfLoaded();
} }
}.bind( this, section, xhr ); }.bind( this, section, xhr );
@ -280,8 +288,11 @@
} }
catch ( e ) { 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 ); 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();
}, },

View file

@ -151,6 +151,9 @@ var RevealNotes = (function() {
} }
return {
init: function() {
if( !/receiver/i.test( window.location.search ) ) { if( !/receiver/i.test( window.location.search ) ) {
// If the there's a 'notes' query set, open directly // If the there's a 'notes' query set, open directly
@ -165,6 +168,13 @@ var RevealNotes = (function() {
} }
return { open: openNotes }; return Promise.resolve();
},
open: openNotes
};
})(); })();
Reveal.registerPlugin( 'notes', RevealNotes );