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 var $html = jQuery('html'); 163 164 // check browser version on init 165 // this has to be revamped, as 166 if (jQuery.browser.webkit && parseFloat(jQuery.browser.version) < 532.5 || // Chrome/Safari 4 167 jQuery.browser.mozilla && parseFloat(jQuery.browser.version) < 1.9 || // FF 3.5 168 jQuery.browser.msie && jQuery.browser.version < 7 || // IE 7 169 jQuery.browser.opera && jQuery.browser.version < 11 ) { // right now, Opera needs some work 170 if (window.console && window.console.log) { 171 window.console.log( 'Your browser is not supported.' ); 172 } 173 } 174 175 // register the body click event to blur editables 176 jQuery('html').mousedown(function(e) { 177 // This is a hack to prevent a click into a modal dialog from blurring the editable. 178 if (Aloha.activeEditable && !jQuery(".aloha-dialog").is(':visible') && !Aloha.eventHandled) { 179 Aloha.activeEditable.blur(); 180 Aloha.activeEditable = null; 181 } 182 }).mouseup(function(e) { 183 Aloha.eventHandled = false; 184 }); 185 186 187 // add class to body to denote browser 188 if (jQuery.browser.webkit) { 189 $html.addClass('aloha-webkit'); 190 } else if (jQuery.browser.opera) { 191 $html.addClass('aloha-opera'); 192 } else if (jQuery.browser.msie) { 193 $html.addClass('aloha-ie' + parseInt(jQuery.browser.version, 10)); 194 } else if (jQuery.browser.mozilla) { 195 $html.addClass('aloha-mozilla'); 196 } 197 198 // Initialise the base path to the aloha files 199 Aloha.settings.base = Aloha.getAlohaUrl(); 200 201 // initialize the Log 202 Aloha.Log.init(); 203 204 // initialize the error handler for general javascript errors 205 if ( Aloha.settings.errorhandling ) { 206 window.onerror = function (msg, url, linenumber) { 207 Aloha.Log.error(Aloha, 'Error message: ' + msg + '\nURL: ' + url + '\nLine Number: ' + linenumber); 208 // TODO eventually add a message to the message line? 209 return true; 210 }; 211 } 212 213 // OS detection 214 if (navigator.appVersion.indexOf('Win') != -1) { 215 Aloha.OSName = 'Win'; 216 } 217 if (navigator.appVersion.indexOf('Mac') != -1) { 218 Aloha.OSName = 'Mac'; 219 } 220 if (navigator.appVersion.indexOf('X11') != -1) { 221 Aloha.OSName = 'Unix'; 222 } 223 if (navigator.appVersion.indexOf('Linux') != -1) { 224 Aloha.OSName = 'Linux'; 225 } 226 227 try { 228 // this will disable browsers image resizing facilities 229 // disable resize handles 230 var supported; 231 try { 232 233 supported = document.queryCommandSupported( 'enableObjectResizing' ); 234 } catch ( e ) { 235 supported = false; 236 Aloha.Log.log( 'enableObjectResizing is not supported.' ); 237 } 238 239 if ( supported ) { 240 document.execCommand( 'enableObjectResizing', false, false); 241 Aloha.Log.log( 'enableObjectResizing disabled.' ); 242 } 243 } catch (e) { 244 Aloha.Log.error( e, 'Could not disable enableObjectResizing' ); 245 // this is just for others, who will not support disabling enableObjectResizing 246 } 247 // Forward 248 next(); 249 }, 250 251 /** 252 * Loads plugins Aloha 253 * @return void 254 */ 255 initPlugins: function (next) { 256 PluginManager.init(next, this.getLoadedPlugins()); 257 }, 258 259 /** 260 * Loads GUI components 261 * @return void 262 */ 263 initGui: function (next) { 264 265 Aloha.RepositoryManager.init(); 266 267 // activate registered editables 268 for (var i = 0, editablesLength = Aloha.editables.length; i < editablesLength; i++) { 269 if ( !Aloha.editables[i].ready ) { 270 Aloha.editables[i].init(); 271 } 272 } 273 274 // Forward 275 next(); 276 }, 277 278 /** 279 * Activates editable and deactivates all other Editables 280 * @param {Editable} editable the Editable to be activated 281 * @return void 282 */ 283 activateEditable: function (editable) { 284 285 // blur all editables, which are currently active 286 for (var i = 0, editablesLength = Aloha.editables.length; i < editablesLength; i++) { 287 if (Aloha.editables[i] != editable && Aloha.editables[i].isActive) { 288 Aloha.editables[i].blur(); 289 } 290 } 291 292 Aloha.activeEditable = editable; 293 }, 294 295 /** 296 * Returns the current Editable 297 * @return {Editable} returns the active Editable 298 */ 299 getActiveEditable: function() { 300 return Aloha.activeEditable; 301 }, 302 303 /** 304 * deactivated the current Editable 305 * @return void 306 */ 307 deactivateEditable: function () { 308 309 if ( typeof Aloha.activeEditable === 'undefined' || Aloha.activeEditable === null ) { 310 return; 311 } 312 313 // blur the editable 314 Aloha.activeEditable.blur(); 315 Aloha.activeEditable = null; 316 }, 317 318 /** 319 * Gets an editable by an ID or null if no Editable with that ID registered. 320 * @param {string} id the element id to look for. 321 * @return {Aloha.Editable} editable 322 */ 323 getEditableById: function (id) { 324 325 // if the element is a textarea than route to the editable div 326 if (jQuery('#'+id).get(0).nodeName.toLowerCase() === 'textarea' ) { 327 id = id + '-aloha'; 328 } 329 330 // serach all editables for id 331 for (var i = 0, editablesLength = Aloha.editables.length; i < editablesLength; i++) { 332 if (Aloha.editables[i].getId() == id) { 333 return Aloha.editables[i]; 334 } 335 } 336 337 return null; 338 }, 339 340 /** 341 * Checks wheater an object is a registered Aloha Editable. 342 * @param {jQuery} obj the jQuery object to be checked. 343 * @return {boolean} 344 */ 345 isEditable: function (obj) { 346 for (var i=0, editablesLength = Aloha.editables.length; i < editablesLength; i++) { 347 if ( Aloha.editables[i].originalObj.get(0) === obj ) { 348 return true; 349 } 350 } 351 return false; 352 }, 353 354 /** 355 * Logs a message to the console 356 * @param level Level of the log ("error", "warn" or "info", "debug") 357 * @param component Component that calls the log 358 * @param message log message 359 * @return void 360 * @hide 361 */ 362 log: function(level, component, message) { 363 if (typeof Aloha.Log !== "undefined") 364 Aloha.Log.log(level, component, message); 365 }, 366 367 /** 368 * Register the given editable 369 * @param editable editable to register 370 * @return void 371 * @hide 372 */ 373 registerEditable: function (editable) { 374 Aloha.editables.push(editable); 375 }, 376 377 /** 378 * Unregister the given editable. It will be deactivated and removed from editables. 379 * @param editable editable to unregister 380 * @return void 381 * @hide 382 */ 383 unregisterEditable: function (editable) { 384 var id = jQuery.inArray(editable, Aloha.editables); 385 if (id != -1) { 386 Aloha.editables.splice(id, 1); 387 } 388 }, 389 390 /** 391 * String representation 392 * @hide 393 */ 394 toString: function () { 395 return 'Aloha'; 396 }, 397 398 /** 399 * Check whether at least one editable was modified 400 * @method 401 * @return {boolean} true when at least one editable was modified, false if not 402 */ 403 isModified: function () { 404 // check if something needs top be saved 405 for (var i = 0; i < Aloha.editables.length; i++) { 406 if (Aloha.editables[i].isModified && Aloha.editables[i].isModified()) { 407 return true; 408 } 409 } 410 411 return false; 412 }, 413 414 /** 415 * Determines the Aloha Url 416 * Uses Aloha.settings.baseUrl if set. 417 * @method 418 * @return {String} alohaUrl 419 */ 420 getAlohaUrl: function( suffix ) { 421 return Aloha.settings.baseUrl; 422 }, 423 424 /** 425 * Gets the plugin's url. 426 * 427 * @method 428 * @param {string} name The name with which the plugin was registered 429 * with. 430 * @return {string} The fully qualified url of this plugin. 431 */ 432 getPluginUrl: function (name) { 433 var url; 434 435 if (name) { 436 url = Aloha.settings._pluginBaseUrlByName[name]; 437 if(url) { 438 //Check if url is absolute and attach base url if it is not 439 if(!url.match("^(\/|http[s]?:).*")) { 440 url = Aloha.getAlohaUrl() + '/' + url; 441 } 442 } 443 } 444 return url; 445 } 446 447 }); 448 449 return Aloha; 450 }); 451