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 )