| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- /**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
- 'use strict';
- import Plugin from './plugin.js';
- import CKEditorError from './ckeditorerror.js';
- import log from './log.js';
- import load from '../load.js';
- /**
- * Manages a list of CKEditor plugins, including loading, resolving dependencies and initialization.
- *
- * @memberOf core
- */
- export default class PluginCollection {
- /**
- * Creates an instance of the PluginCollection class, initializing it with a set of plugins.
- *
- * @param {core.Editor} editor
- */
- constructor( editor ) {
- /**
- * @protected
- * @member {core.Editor} core.PluginCollection#_editor
- */
- this._editor = editor;
- /**
- * @protected
- * @member {Map} core.PluginCollection#_plugins
- */
- this._plugins = new Map();
- }
- /**
- * Collection iterator. Returns `[ key, plugin ]` pairs. Plugins which are
- * kept in the collection twice (under their name and class) will be returned twice.
- */
- [ Symbol.iterator ]() {
- return this._plugins[ Symbol.iterator ]();
- }
- /**
- * Gets the plugin instance by its name or class.
- *
- * @param {String/Function} key The name of the plugin or the class.
- * @returns {core.Plugin}
- */
- get( key ) {
- return this._plugins.get( key );
- }
- /**
- * Loads a set of plugins and add them to the collection.
- *
- * @param {String[]} plugins An array of plugins to load.
- * @returns {Promise} A promise which gets resolved once all plugins are loaded and available into the
- * collection.
- * @param {core.Plugin[]} returns.loadedPlugins The array of loaded plugins.
- */
- load( plugins ) {
- const that = this;
- const editor = this._editor;
- const loading = new Set();
- const loaded = [];
- return Promise.all( plugins.map( loadPlugin ) )
- .then( () => loaded );
- function loadPlugin( pluginClassOrName ) {
- // The plugin is already loaded or being loaded - do nothing.
- if ( that.get( pluginClassOrName ) || loading.has( pluginClassOrName ) ) {
- return;
- }
- let promise = ( typeof pluginClassOrName == 'string' ) ?
- loadPluginByName( pluginClassOrName ) :
- loadPluginByClass( pluginClassOrName );
- return promise
- .catch( ( err ) => {
- /**
- * It was not possible to load the plugin.
- *
- * @error plugincollection-load
- * @param {String} plugin The name of the plugin that could not be loaded.
- */
- log.error( 'plugincollection-load: It was not possible to load the plugin.', { plugin: pluginClassOrName } );
- throw err;
- } );
- }
- function loadPluginByName( pluginName ) {
- return load( PluginCollection.getPluginPath( pluginName ) )
- .then( ( PluginModule ) => {
- return loadPluginByClass( PluginModule.default, pluginName );
- } );
- }
- function loadPluginByClass( PluginClass, pluginName ) {
- return new Promise( ( resolve ) => {
- loading.add( PluginClass );
- assertIsPlugin( PluginClass );
- if ( PluginClass.requires ) {
- PluginClass.requires.forEach( loadPlugin );
- }
- const plugin = new PluginClass( editor );
- that._add( PluginClass, plugin );
- loaded.push( plugin );
- // Expose the plugin also by its name if loaded through load() by name.
- if ( pluginName ) {
- that._add( pluginName, plugin );
- }
- resolve();
- } );
- }
- function assertIsPlugin( LoadedPlugin ) {
- if ( !( LoadedPlugin.prototype instanceof Plugin ) ) {
- /**
- * The loaded plugin module is not an instance of Plugin.
- *
- * @error plugincollection-instance
- * @param {LoadedPlugin} plugin The class which is meant to be loaded as a plugin.
- */
- throw new CKEditorError(
- 'plugincollection-instance: The loaded plugin module is not an instance of Plugin.',
- { plugin: LoadedPlugin }
- );
- }
- }
- }
- /**
- * Resolves a simplified plugin name to a real path. The returned
- * paths are relative to the main `ckeditor.js` file, but they do not start with `./`.
- *
- * For instance:
- *
- * * `foo` will be transformed to `ckeditor5/foo/foo.js`,
- * * `core/editor` to `ckeditor5/core/editor.js` and
- * * `foo/bar/bom` to `ckeditor5/foo/bar/bom.js`.
- *
- * @param {String} name
- * @returns {String} Path to the module.
- */
- static getPluginPath( name ) {
- // Resolve shortened feature names to `featureName/featureName`.
- if ( name.indexOf( '/' ) < 0 ) {
- name = name + '/' + name;
- }
- return 'ckeditor5/' + name + '.js';
- }
- /**
- * Adds the plugin to the collection. Exposed mainly for testing purposes.
- *
- * @protected
- * @param {String/Function} key The name or the plugin class.
- * @param {core.Plugin} plugin The instance of the plugin.
- */
- _add( key, plugin ) {
- this._plugins.set( key, plugin );
- }
- }
|