1 /* core.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 29 [ 30 'jquery', 31 'aloha/pluginmanager' 32 ], 33 34 function ( jQuery, PluginManager ) { 35 "use strict"; 36 37 //---------------------------------------- 38 // Private variables 39 //---------------------------------------- 40 41 /** 42 * Base Aloha Object 43 * @namespace Aloha 44 * @class Aloha The Aloha base object, which contains all the core functionality 45 * @singleton 46 */ 47 jQuery.extend(true, Aloha, { 48 49 /** 50 * The Aloha Editor Version we are using 51 * It should be set by us and updated for the particular branch 52 * @property 53 */ 54 version: '${version}', 55 56 /** 57 * Array of editables that are managed by Aloha 58 * @property 59 * @type Array 60 */ 61 editables: [], 62 63 /** 64 * The currently active editable is referenced here 65 * @property 66 * @type Aloha.Editable 67 */ 68 activeEditable: null, 69 70 /** 71 * settings object, which will contain all Aloha settings 72 * @cfg {Object} object Aloha's settings 73 */ 74 settings: {}, 75 76 /** 77 * defaults object, which will contain all Aloha defaults 78 * @cfg {Object} object Aloha's settings 79 */ 80 defaults: {}, 81 82 /** 83 * Namespace for ui components 84 */ 85 ui: {}, 86 87 /** 88 * This represents the name of the users OS. Could be: 89 * 'Mac', 'Linux', 'Win', 'Unix', 'Unknown' 90 * @property 91 * @type string 92 */ 93 OSName: 'Unknown', 94 95 /** 96 * Which stage is the aloha init process at? 97 * @property 98 99 * @type string 100 */ 101 stage: 'loadingAloha', 102 103 /** 104 * A list of loaded plugin names. Available after the 105 * "loadPlugins" stage. 106 * 107 * @property 108 * @type array 109 * @internal 110 */ 111 loadedPlugins: [], 112 113 /** 114 * Maps names of plugins (link) to the base URL (../plugins/common/link). 115 */ 116 _pluginBaseUrlByName: {}, 117 118 /** 119 * Initialize the initialization process 120 */ 121 init: function () { 122 // Load & Initialise 123 Aloha.stage = 'initAloha'; 124 Aloha.initAloha(function(){ 125 Aloha.stage = 'initPlugins'; 126 Aloha.initPlugins(function(){ 127 Aloha.stage = 'initGui'; 128 Aloha.initGui(function(){ 129 Aloha.stage = 'alohaReady'; 130 Aloha.trigger('aloha-ready'); 131 }); 132 }); 133 }); 134 }, 135 136 /** 137 * Returns list of loaded plugins (without Bundle name) 138 * 139 * @return array 140 */ 141 getLoadedPlugins: function() { 142 return this.loadedPlugins; 143 }, 144 145 /** 146 * Returns true if a certain plugin is loaded, false otherwise. 147 */ 148 isPluginLoaded: function(pluginName) { 149 var found = false; 150 jQuery.each(this.loadedPlugins, function() { 151 if (pluginName.toString() === this.toString()) { 152 found = true; 153 } 154 }); 155 return found; 156 }, 157 158 /** 159 * Initialise Aloha 160 */ 161 initAloha: function(next){ 162 // check browser version on init 163 // this has to be revamped, as 164 if (jQuery.browser.webkit && parseFloat(jQuery.browser.version) < 532.5 || // Chrome/Safari 4 165 jQuery.browser.mozilla && parseFloat(jQuery.browser.version) < 1.9 || // FF 3.5 166 jQuery.browser.msie && jQuery.browser.version < 7 || // IE 7 167 jQuery.browser.opera && jQuery.browser.version < 11 ) { // right now, Opera needs some work 168 if (window.console && window.console.log) { 169 window.console.log( 'Your browser is not supported.' ); 170 } 171 } 172 173 // register the body click event to blur editables 174 jQuery('html').mousedown(function(e) { 175 // This is a hack to prevent a click into a modal dialog from blurring the editable. 176 if (Aloha.activeEditable && !jQuery(".aloha-dialog").is(':visible') && !Aloha.eventHandled) { 177 Aloha.activeEditable.blur(); 178 Aloha.activeEditable = null; 179 } 180 }).mouseup(function(e) { 181 Aloha.eventHandled = false; 182 }); 183 184 // Initialise the base path to the aloha files 185 Aloha.settings.base = Aloha.getAlohaUrl(); 186 187 // initialize the Log 188 Aloha.Log.init(); 189 190 // initialize the error handler for general javascript errors 191 192 if ( Aloha.settings.errorhandling ) { 193 window.onerror = function (msg, url, linenumber) { 194 Aloha.Log.error(Aloha, 'Error message: ' + msg + '\nURL: ' + url + '\nLine Number: ' + linenumber); 195 // TODO eventually add a message to the message line? 196 return true; 197 }; 198 } 199 200 // OS detection 201 if (navigator.appVersion.indexOf('Win') != -1) { 202 Aloha.OSName = 'Win'; 203 } 204 if (navigator.appVersion.indexOf('Mac') != -1) { 205 Aloha.OSName = 'Mac'; 206 } 207 if (navigator.appVersion.indexOf('X11') != -1) { 208 Aloha.OSName = 'Unix'; 209 } 210 if (navigator.appVersion.indexOf('Linux') != -1) { 211 Aloha.OSName = 'Linux'; 212 } 213 214 try { 215 // this will disable browsers image resizing facilities 216 // disable resize handles 217 var supported; 218 try { 219 supported = document.queryCommandSupported( 'enableObjectResizing' ); 220 } catch ( e ) { 221 supported = false; 222 Aloha.Log.log( 'enableObjectResizing is not supported.' ); 223 } 224 225 if ( supported ) { 226 document.execCommand( 'enableObjectResizing', false, false); 227 Aloha.Log.log( 'enableObjectResizing disabled.' ); 228 } 229 } catch (e) { 230 Aloha.Log.error( e, 'Could not disable enableObjectResizing' ); 231 // this is just for others, who will not support disabling enableObjectResizing 232 } 233 // Forward 234 next(); 235 }, 236 237 /** 238 * Loads plugins Aloha 239 * @return void 240 */ 241 initPlugins: function (next) { 242 PluginManager.init(next, this.getLoadedPlugins()); 243 }, 244 245 /** 246 * Loads GUI components 247 * @return void 248 */ 249 initGui: function (next) { 250 251 Aloha.RepositoryManager.init(); 252 253 // activate registered editables 254 for (var i = 0, editablesLength = Aloha.editables.length; i < editablesLength; i++) { 255 if ( !Aloha.editables[i].ready ) { 256 Aloha.editables[i].init(); 257 } 258 } 259 260 // Forward 261 next(); 262 }, 263 264 /** 265 * Activates editable and deactivates all other Editables 266 * @param {Editable} editable the Editable to be activated 267 * @return void 268 269 */ 270 activateEditable: function (editable) { 271 272 // blur all editables, which are currently active 273 for (var i = 0, editablesLength = Aloha.editables.length; i < editablesLength; i++) { 274 if (Aloha.editables[i] != editable && Aloha.editables[i].isActive) { 275 Aloha.editables[i].blur(); 276 } 277 } 278 279 Aloha.activeEditable = editable; 280 }, 281 282 /** 283 * Returns the current Editable 284 * @return {Editable} returns the active Editable 285 */ 286 getActiveEditable: function() { 287 return Aloha.activeEditable; 288 }, 289 290 /** 291 * deactivated the current Editable 292 * @return void 293 */ 294 deactivateEditable: function () { 295 296 if ( typeof Aloha.activeEditable === 'undefined' || Aloha.activeEditable === null ) { 297 return; 298 } 299 300 // blur the editable 301 Aloha.activeEditable.blur(); 302 Aloha.activeEditable = null; 303 }, 304 305 /** 306 * Gets an editable by an ID or null if no Editable with that ID registered. 307 * @param {string} id the element id to look for. 308 * @return {Aloha.Editable} editable 309 */ 310 getEditableById: function (id) { 311 312 // if the element is a textarea than route to the editable div 313 if (jQuery('#'+id).get(0).nodeName.toLowerCase() === 'textarea' ) { 314 id = id + '-aloha'; 315 } 316 317 // serach all editables for id 318 for (var i = 0, editablesLength = Aloha.editables.length; i < editablesLength; i++) { 319 if (Aloha.editables[i].getId() == id) { 320 return Aloha.editables[i]; 321 } 322 } 323 324 return null; 325 }, 326 327 /** 328 * Checks wheater an object is a registered Aloha Editable. 329 * @param {jQuery} obj the jQuery object to be checked. 330 * @return {boolean} 331 */ 332 isEditable: function (obj) { 333 for (var i=0, editablesLength = Aloha.editables.length; i < editablesLength; i++) { 334 if ( Aloha.editables[i].originalObj.get(0) === obj ) { 335 return true; 336 } 337 } 338 return false; 339 }, 340 341 /** 342 * Logs a message to the console 343 * @param level Level of the log ("error", "warn" or "info", "debug") 344 * @param component Component that calls the log 345 * @param message log message 346 * @return void 347 * @hide 348 */ 349 log: function(level, component, message) { 350 if (typeof Aloha.Log !== "undefined") 351 Aloha.Log.log(level, component, message); 352 }, 353 354 /** 355 * Register the given editable 356 * @param editable editable to register 357 * @return void 358 * @hide 359 */ 360 registerEditable: function (editable) { 361 Aloha.editables.push(editable); 362 }, 363 364 /** 365 * Unregister the given editable. It will be deactivated and removed from editables. 366 * @param editable editable to unregister 367 * @return void 368 * @hide 369 */ 370 unregisterEditable: function (editable) { 371 var id = jQuery.inArray(editable, Aloha.editables); 372 if (id != -1) { 373 Aloha.editables.splice(id, 1); 374 } 375 }, 376 377 /** 378 * String representation 379 * @hide 380 */ 381 toString: function () { 382 return 'Aloha'; 383 }, 384 385 /** 386 * Check whether at least one editable was modified 387 * @method 388 * @return {boolean} true when at least one editable was modified, false if not 389 */ 390 isModified: function () { 391 // check if something needs top be saved 392 for (var i = 0; i < Aloha.editables.length; i++) { 393 if (Aloha.editables[i].isModified && Aloha.editables[i].isModified()) { 394 return true; 395 } 396 } 397 398 return false; 399 }, 400 401 /** 402 * Determines the Aloha Url 403 * Uses Aloha.settings.baseUrl if set. 404 * @method 405 * @return {String} alohaUrl 406 */ 407 getAlohaUrl: function( suffix ) { 408 return Aloha.settings.baseUrl; 409 }, 410 411 /** 412 * Gets the plugin's url. 413 * 414 * @method 415 * @param {string} name The name with which the plugin was registered 416 * with. 417 * @return {string} The fully qualified url of this plugin. 418 */ 419 getPluginUrl: function (name) { 420 var url; 421 422 if (name) { 423 url = Aloha.settings._pluginBaseUrlByName[name]; 424 if(url) { 425 //Check if url is absolute and attach base url if it is not 426 if(!url.match("^(\/|http[s]?:).*")) { 427 url = Aloha.getAlohaUrl() + '/' + url; 428 } 429 } 430 } 431 return url; 432 } 433 434 }); 435 436 return Aloha; 437 }); 438