1 /* pluginmanager.js is part of Aloha Editor project http://aloha-editor.org
  2  *
  3  * Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
  4  * Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
  5  * Contributors http://aloha-editor.org/contribution.php
  6  *
  7  * Aloha Editor is free software; you can redistribute it and/or
  8  * modify it under the terms of the GNU General Public License
  9  * as published by the Free Software Foundation; either version 2
 10  * of the License, or any later version.
 11  *
 12  * Aloha Editor is distributed in the hope that it will be useful,
 13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15  * GNU General Public License for more details.
 16  *
 17  * You should have received a copy of the GNU General Public License
 18  * along with this program; if not, write to the Free Software
 19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 20  *
 21  * As an additional permission to the GNU GPL version 2, you may distribute
 22  * non-source (e.g., minimized or compacted) forms of the Aloha-Editor
 23  * source code without the copy of the GNU GPL normally required,
 24  * provided you include this license notice and a URL through which
 25  26  * recipients can access the Corresponding Source.
 27  */
 28 // Do not add dependencies that require depend on aloha/core
 29 define([
 30 	'jquery',
 31 	'util/class'
 32 ], function (
 33 	$,
 34 	Class
 35 ) {
 36 	'use strict';
 37 
 38 	var Aloha = window.Aloha;
 39 
 40 	/**
 41 	 * For each plugin setting, assigns it into its corresponding plugin.
 42 	 *
 43 	 * @param {Array.<Plugin>} plugins
 44 	 * @param {object<string, object>} settings
 45 	 */
 46 	function mapSettingsIntoPlugins(plugins, settings) {
 47 		var plugin;
 48 		for (plugin in settings) {
 49 			if (settings.hasOwnProperty(plugin) && plugins[plugin]) {
 50 				plugins[plugin].settings = settings[plugin] || {};
 51 			}
 52 		}
 53 	}
 54 
 55 	/**
 56 	 * Retrieves a set of plugins or the given `names' list, from among those
 57 	 * specified in `plugins'.
 58 	 *
 59 	 * @param {object<string, object>} plugins
 60 	 * @param {Array.<string>} names List of plugins names.
 61 	 * @return {Array.<Plugins>} List of available plugins.
 62 	 */
 63 	function getPlugins(plugins, names) {
 64 		var available = [];
 65 		var plugin;
 66 		var i;
 67 		for (i = 0; i < names.length; i++) {
 68 			plugin = plugins[names[i]];
 69 			if (plugin) {
 70 				available.push(plugin);
 71 			}
 72 		}
 73 		return available;
 74 	}
 75 
 76 	/**
 77 	 * Initializes the plugins in the given list.
 78 	 *
 79 	 * @param {Array.<Plugins>} plugins Plugins to initialize.
 80 	 * @param {function} callback Function to invoke once all plugins have been
 81 	 *                            successfully initialized.
 82 	 */
 83 	function initializePlugins(plugins, callback) {
 84 		if (0 === plugins.length) {
 85 			if (callback) {
 86 				callback();
 87 			}
 88 			return;
 89 		}
 90 		var numToEnable = plugins.length;
 91 		var onInit = function () {
 92 			if (0 === --numToEnable && callback) {
 93 				callback();
 94 			}
 95 		};
 96 		var i;
 97 		var ret;
 98 		var plugin;
 99 		for (i = 0; i < plugins.length; i++) {
100 			plugin = plugins[i];
101 			plugin.settings = plugin.settings || {};
102 			if (typeof plugin.settings.enabled === 'undefined') {
103 				plugin.settings.enabled = true;
104 			}
105 			if (plugin.settings.enabled && plugin.checkDependencies()) {
106 				ret = plugin.init();
107 				if (ret && typeof ret.done === 'function') {
108 					ret.done(onInit);
109 				} else {
110 					onInit();
111 				}
112 			} else {
113 				onInit();
114 			}
115 		}
116 	}
117 
118 	/**
119 	 * The Plugin Manager controls the lifecycle of all Aloha Plugins.
120 	 *
121 	 * @namespace Aloha
122 	 * @class PluginManager
123 	 * @singleton
124 	 */
125 	return new (Class.extend({
126 
127 		plugins: {},
128 
129 		/**
130 		 * Initialize all registered plugins.
131 		 *
132 		 * @param {function} next Callback to invoke after plugins have
133 		 *                        succefully initialized.
134 		 * @param {Array.<string>} enabled A list of plugin names which are to
135 		 *                                 be enable.
136 		 */
137 		init: function (next, enabled) {
138 			var manager = this;
139 			var plugins = manager.plugins;
140 
141 			mapSettingsIntoPlugins(plugins,
142 143 					Aloha && Aloha.settings && Aloha.settings.plugins);
144 
145 			// Because all plugins are enabled by default if specific plugins
146 			// are not specified.
147 			var plugin;
148 			if (plugins && 0 === enabled.length) {
149 				enabled = [];
150 				for (plugin in plugins) {
151 					if (plugins.hasOwnProperty(plugin)) {
152 						enabled.push(plugin);
153 					}
154 				}
155 			}
156 
157 			initializePlugins(getPlugins(plugins, enabled), next);
158 		},
159 
160 		/**
161 		 * Register a plugin
162 		 * @param {Plugin} plugin plugin to register
163 		 */
164 		register: function (plugin) {
165 
166 			if (!plugin.name) {
167 				throw new Error('Plugin does not have an name.');
168 			}
169 
170 			if (this.plugins[plugin.name]) {
171 				throw new Error('Already registered the plugin "' + plugin.name + '"!');
172 			}
173 
174 			this.plugins[plugin.name] = plugin;
175 		},
176 
177 		/**
178 		 * Pass the given jQuery object, which represents an editable to all plugins, so that they can make the content clean (prepare for saving)
179 		 * @param obj jQuery object representing an editable
180 		 * @return void
181 		 * @hide
182 		 */
183 		makeClean: function (obj) {
184 			var i, plugin;
185 			// iterate through all registered plugins
186 			for (plugin in this.plugins) {
187 				if (this.plugins.hasOwnProperty(plugin)) {
188 					if (Aloha.Log.isDebugEnabled()) {
189 						Aloha.Log.debug(this, 'Passing contents of HTML Element with id { ' + obj.attr('id') + ' } for cleaning to plugin { ' + plugin + ' }');
190 					}
191 					this.plugins[plugin].makeClean(obj);
192 				}
193 			}
194 		},
195 
196 		/**
197 		 * Expose a nice name for the Plugin Manager
198 		 * @hide
199 		 */
200 		toString: function () {
201 			return 'pluginmanager';
202 		}
203 
204 	}))();
205 });
206