App-revealup
view release on metacpan or search on metacpan
share/revealjs/js/controllers/plugins.js view on Meta::CPAN
import { loadScript } from '../utils/loader.js'
/**
* Manages loading and registering of reveal.js plugins.
*/
export default class Plugins {
constructor( reveal ) {
this.Reveal = reveal;
// Flags our current state (idle -> loading -> loaded)
this.state = 'idle';
// An id:instance map of currently registed plugins
this.registeredPlugins = {};
this.asyncDependencies = [];
}
/**
* Loads reveal.js dependencies, registers and
* initializes plugins.
*
* Plugins are direct references to a reveal.js plugin
* object that we register and initialize after any
* synchronous dependencies have loaded.
*
* Dependencies are defined via the 'dependencies' config
* option and will be loaded prior to starting reveal.js.
* Some dependencies may have an 'async' flag, if so they
* will load after reveal.js has been started up.
*/
load( plugins, dependencies ) {
this.state = 'loading';
plugins.forEach( this.registerPlugin.bind( this ) );
return new Promise( resolve => {
let scripts = [],
scriptsToLoad = 0;
dependencies.forEach( s => {
// Load if there's no condition or the condition is truthy
if( !s.condition || s.condition() ) {
if( s.async ) {
this.asyncDependencies.push( s );
}
else {
scripts.push( s );
}
}
} );
if( scripts.length ) {
scriptsToLoad = scripts.length;
const scriptLoadedCallback = (s) => {
if( s && typeof s.callback === 'function' ) s.callback();
if( --scriptsToLoad === 0 ) {
this.initPlugins().then( resolve );
}
};
// Load synchronous scripts
scripts.forEach( s => {
if( typeof s.id === 'string' ) {
this.registerPlugin( s );
scriptLoadedCallback( s );
}
else if( typeof s.src === 'string' ) {
loadScript( s.src, () => scriptLoadedCallback(s) );
}
else {
console.warn( 'Unrecognized plugin format', s );
scriptLoadedCallback();
}
} );
}
else {
this.initPlugins().then( resolve );
}
} );
}
/**
* Initializes our plugins and waits for them to be ready
* before proceeding.
*/
initPlugins() {
return new Promise( resolve => {
let pluginValues = Object.values( this.registeredPlugins );
let pluginsToInitialize = pluginValues.length;
// If there are no plugins, skip this step
if( pluginsToInitialize === 0 ) {
this.loadAsync().then( resolve );
}
// ... otherwise initialize plugins
else {
let initNextPlugin;
let afterPlugInitialized = () => {
if( --pluginsToInitialize === 0 ) {
this.loadAsync().then( resolve );
}
else {
initNextPlugin();
}
};
let i = 0;
// Initialize plugins serially
initNextPlugin = () => {
let plugin = pluginValues[i++];
// If the plugin has an 'init' method, invoke it
if( typeof plugin.init === 'function' ) {
( run in 0.402 second using v1.01-cache-2.11-cpan-524268b4103 )