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,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();
}, },

View File

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