1 /* plugin.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  * recipients can access the Corresponding Source.
 26  */
 27 define([
 28 	'aloha/core',
 29 	'jquery',
 30 	'util/class',
 31 	'aloha/pluginmanager',
 32 	'aloha/console'
 33 ], function (
 34 	Aloha,
 35 	jQuery,
 36 	Class,
 37 	PluginManager,
 38 	console
 39 ) {
 40 	"use strict";
 41 
 42 	/**
 43  44 	 * Abstract Plugin Object
 45 	 * @namespace Aloha
 46 	 * @class Plugin
 47 	 * @constructor
 48 	 * @param {String} pluginPrefix unique plugin prefix
 49 	 */
 50 	var Plugin = Class.extend({
 51 
 52 		name: null,
 53 
 54 		/**
 55 		 * contains the plugin's default settings object
 56 		 * @cfg {Object} default settings for the plugin
 57 		 */
 58 		defaults: {},
 59 
 60 		/**
 61 		 * contains the plugin's settings object
 62 		 * @cfg {Object} settings the plugins settings stored in an object
 63 		 */
 64 		settings: {},
 65 
 66 		/**
 67 		 * Names of other plugins which must be loaded in order for this plugin to
 68 		 * function.
 69 		 * @cfg {Array}
 70 		 */
 71 		dependencies: [],
 72 
 73 		_constructor: function (name) {
 74 			/**
 75 			 * Settings of the plugin
 76 			 */
 77 			if (typeof name !== "string") {
 78 				console.error('Cannot initialise unnamed plugin, skipping');
 79 			} else {
 80 				this.name = name;
 81 			}
 82 		},
 83 
 84 		/**
 85 		 * @return true if dependencies satisfied, false otherwise
 86 		 */
 87 		checkDependencies: function () {
 88 			var plugin = this;
 89 			var satisfied = true;
 90 			jQuery.each(plugin.dependencies, function (i, dependency) {
 91 				if (!Aloha.isPluginLoaded(dependency.toString())) {
 92 					satisfied = false;
 93 					console.error('plugin.' + plugin.name,
 94 							'Required plugin "' + dependency + '" not found.');
 95 					return false;
 96 				}
 97 			});
 98 			return satisfied;
 99 		},
100 
101 		/**
102 		 * Init method of the plugin. Called from Aloha Core to initialize this plugin
103 		 * @return void
104 		 * @hide
105 		 */
106 		init: function () {},
107 
108 		/**
109 		 * Get the configuration settings for an editable obj.
110 		 * Handles both conf arrays or conf objects
111 		 * <ul>
112 		 * <li>Array configuration parameters are:
113 		 * <pre>
114 		 * "list": {
115 		 *		config : [ 'b', 'h1' ],
116 		 *		editables : {
117 		 *			'#title'	: [ ],
118 		 *			'div'		: [ 'b', 'i' ],
119 		 *			'.article'	: [ 'h1' ]
120 		 *		}
121 		 *	}
122 		 * </pre>
123 		 *
124 		 * The hash keys of the editables are css selectors. For a
125 		 *
126 		 * <pre>
127 		 *  <div class="article">content</div>
128 		 * </pre>
129 		 *
130 		 *  the selectors 'div' and '.article' match and the returned configuration is
131 		 *
132 		 * <pre>
133 		 *  [ 'b', 'i', 'h1']
134 		 * </pre>
135 		 *
136 		 * The '#title' object would return an empty configuration.
137 		 *
138 		 * <pre>
139 		 *  [ ]
140 		 * </pre>
141 		 *
142 		 *  All other objects would get the 'config' configuration. If config is not set
143 		 * the plugin default configuration is returned.
144 		 *
145 		 * <pre>
146 		 *  [ 'b', 'h1']
147 		 * </pre></li>
148 		 * <li>Object configuration parameters are :
149 		 * <pre>
150 		 *	"image": {
151 		 *		config : { 'img': { 'max_width': '50px',
152 		 *		'max_height': '50px' }},
153 		 *		editables : {
154 		 *			'#title': {},
155 		 *			'div': {'img': {}},
156 		 *			'.article': {'img': { 'max_width': '150px',
157 		 *			'max_height': '150px' }}
158 		 *		}
159 		 *	}
160 		 * </pre>
161 		 *  The '#title' object would return an empty configuration.<br/>
162 		 *  The 'div' object would return the default configuration.<br/>
163 		 *  the '.article' would return :
164 		 *  <pre>
165 		 *		{'img': { 'max_width': '150px',
166 		 *		'max_height': '150px' }}
167 		 *  </pre>
168 		 * </li>
169 		 *
170 		 * @param {jQuery} obj jQuery object of an Editable Object
171 		 * @return {Array} config A Array with configuration entries
172 		 */
173 		getEditableConfig: function (obj) {
174 			var configObj = null,
175 				configSpecified = false,
176 				that = this;
177 
178 			if (this.settings.editables) {
179 				// check if the editable's selector matches and if so add its configuration to object configuration
180 				jQuery.each(this.settings.editables, function (selector, selectorConfig) {
181 					var k;
182 					if (obj.is(selector)) {
183 						configSpecified = true;
184 						if (selectorConfig instanceof Array) {
185 							configObj = [];
186 							configObj = jQuery.merge(configObj, selectorConfig);
187 						} else if (typeof selectorConfig === "object") {
188 							configObj = {};
189 							configObj['aloha-editable-selector'] = selector;
190 							for (k in selectorConfig) {
191 								if (selectorConfig.hasOwnProperty(k)) {
192 									if (selectorConfig[k] instanceof Array) {
193 										//configObj[k] = [];
194 										//configObj[k] = jQuery.extend(true, configObj[k], that.config[k], selectorConfig[k]);
195 										configObj[k] = selectorConfig[k];
196 									} else if (typeof selectorConfig[k] === "object") {
197 										configObj[k] = {};
198 										configObj[k] = jQuery.extend(true, configObj[k], that.config[k], selectorConfig[k]);
199 									} else {
200 										configObj[k] = selectorConfig[k];
201 									}
202 								}
203 							}
204 						} else {
205 							configObj = selectorConfig;
206 						}
207 					}
208 				});
209 			}
210 
211 			// fall back to default configuration
212 			if (!configSpecified) {
213 				if (typeof this.settings.config === 'undefined' || !this.settings.config) {
214 					configObj = this.config;
215 				} else {
216 					configObj = this.settings.config;
217 				}
218 			}
219 
220 			return configObj;
221 		},
222 
223 		/**
224 		 * Make the given jQuery object (representing an editable) clean for saving
225 		 * @param obj jQuery object to make clean
226 		 * @return void
227 		 */
228 		makeClean: function (obj) {},
229 
230 		/**
231 		 * Make a system-wide unique id out of a plugin-wide unique id by prefixing it with the plugin prefix
232 		 * @param id plugin-wide unique id
233 		 * @return system-wide unique id
234 		 * @hide
235 		 * @deprecated
236 		 */
237 		getUID: function (id) {
238 			console.deprecated('plugin', 'getUID() is deprecated. Use plugin.name instead.');
239 			return this.name;
240 		},
241 
242 		/**
243 		 * Return string representation of the plugin, which is the prefix
244 		 * @return name
245 		 * @hide
246 		 * @deprecated
247 		 */
248 		toString: function () {
249 			return this.name;
250 		},
251 
252 		/**
253 		 * Log a plugin message to the logger
254 		 * @param level log level
255 		 * @param message log message
256 		 * @return void
257 		 * @hide
258 		 * @deprecated
259 		 */
260 		log: function (level, message) {
261 			console.deprecated('plugin', 'log() is deprecated. Use Aloha.console instead.');
262 			console.log(level, this, message);
263 		}
264 	});
265 
266 	/**
267 	 * Static method used as factory to create plugins.
268 	 * 
269 	 * @param {String} pluginName name of the plugin
270 	 * @param {Object} definition definition of the plugin, should have at least an "init" and "destroy" method.
271 	 */
272 	Plugin.create = function (pluginName, definition) {
273 
274 		var pluginInstance = new (Plugin.extend(definition))(pluginName);
275 		pluginInstance.settings = jQuery.extendObjects(true, pluginInstance.defaults, Aloha.settings[pluginName]);
276 		PluginManager.register(pluginInstance);
277 
278 		return pluginInstance;
279 	};
280 
281 	return Plugin;
282 });
283