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