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 // Forward 228 next(); 229 }, 230 231 /** 232 * Loads plugins Aloha 233 * @return void 234 */ 235 initPlugins: function (next) { 236 PluginManager.init(next, this.getLoadedPlugins()); 237 }, 238 239 /** 240 * Loads GUI components 241 * @return void 242 */ 243 initGui: function (next) { 244 245 Aloha.RepositoryManager.init(); 246 247 // activate registered editables 248 for (var i = 0, editablesLength = Aloha.editables.length; i < editablesLength; i++) { 249 if ( !Aloha.editables[i].ready ) { 250 Aloha.editables[i].init(); 251 } 252 } 253 254 // Forward 255 next(); 256 257 }, 258 259 /** 260 * Activates editable and deactivates all other Editables 261 * @param {Editable} editable the Editable to be activated 262 * @return void 263 */ 264 activateEditable: function (editable) { 265 266 // blur all editables, which are currently active 267 for (var i = 0, editablesLength = Aloha.editables.length; i < editablesLength; i++) { 268 if (Aloha.editables[i] != editable && Aloha.editables[i].isActive) { 269 Aloha.editables[i].blur(); 270 271 } 272 } 273 274 Aloha.activeEditable = editable; 275 }, 276 277 /** 278 * Returns the current Editable 279 * @return {Editable} returns the active Editable 280 */ 281 getActiveEditable: function() { 282 return Aloha.activeEditable; 283 }, 284 285 /** 286 * deactivated the current Editable 287 * @return void 288 */ 289 deactivateEditable: function () { 290 291 if ( typeof Aloha.activeEditable === 'undefined' || Aloha.activeEditable === null ) { 292 return; 293 } 294 295 // blur the editable 296 Aloha.activeEditable.blur(); 297 Aloha.activeEditable = null; 298 }, 299 300 /** 301 * Gets an editable by an ID or null if no Editable with that ID registered. 302 * @param {string} id the element id to look for. 303 * @return {Aloha.Editable} editable 304 */ 305 getEditableById: function (id) { 306 307 // if the element is a textarea than route to the editable div 308 if (jQuery('#'+id).get(0).nodeName.toLowerCase() === 'textarea' ) { 309 id = id + '-aloha'; 310 } 311 312 // serach all editables for id 313 for (var i = 0, editablesLength = Aloha.editables.length; i < editablesLength; i++) { 314 if (Aloha.editables[i].getId() == id) { 315 return Aloha.editables[i]; 316 } 317 } 318 319 return null; 320 }, 321 322 /** 323 * Checks whether an object is a registered Aloha Editable. 324 * @param {jQuery} obj the jQuery object to be checked. 325 * @return {boolean} 326 */ 327 isEditable: function (obj) { 328 for (var i=0, editablesLength = Aloha.editables.length; i < editablesLength; i++) { 329 if ( Aloha.editables[i].originalObj.get(0) === obj ) { 330 return true; 331 } 332 } 333 return false; 334 }, 335 336 /** 337 * Get the nearest editable parent of the given jQuery object 338 * @param {jQuery} $obj jQuery object 339 * @return {Aloha.Editable} editable or undefined if none found 340 */ 341 getEditableHost: function ($obj) { 342 var $parents, i, $editable, editablesLength = Aloha.editables.length; 343 if (!$obj) { 344 return; 345 } 346 347 $parents = $obj.parents().andSelf().each(function () { 348 for (i = 0; i < editablesLength; i++) { 349 if (Aloha.editables[i].originalObj.get(0) === this) { 350 $editable = Aloha.editables[i]; 351 return false; 352 } 353 } 354 }); 355 356 return $editable; 357 }, 358 359 /** 360 * Logs a message to the console 361 * @param level Level of the log ("error", "warn" or "info", "debug") 362 * @param component Component that calls the log 363 * @param message log message 364 * @return void 365 * @hide 366 */ 367 log: function(level, component, message) { 368 if (typeof Aloha.Log !== "undefined") 369 Aloha.Log.log(level, component, message); 370 }, 371 372 /** 373 * Register the given editable 374 * @param editable editable to register 375 * @return void 376 * @hide 377 */ 378 registerEditable: function (editable) { 379 Aloha.editables.push(editable); 380 }, 381 382 /** 383 * Unregister the given editable. It will be deactivated and removed from editables. 384 * @param editable editable to unregister 385 * @return void 386 * @hide 387 */ 388 unregisterEditable: function (editable) { 389 var id = jQuery.inArray(editable, Aloha.editables); 390 if (id != -1) { 391 Aloha.editables.splice(id, 1); 392 } 393 }, 394 395 /** 396 * String representation 397 * @hide 398 */ 399 toString: function () { 400 return 'Aloha'; 401 }, 402 403 /** 404 * Check whether at least one editable was modified 405 * @method 406 * @return {boolean} true when at least one editable was modified, false if not 407 */ 408 isModified: function () { 409 // check if something needs top be saved 410 for (var i = 0; i < Aloha.editables.length; i++) { 411 if (Aloha.editables[i].isModified && Aloha.editables[i].isModified()) { 412 return true; 413 } 414 } 415 416 return false; 417 }, 418 419 /** 420 * Determines the Aloha Url 421 * Uses Aloha.settings.baseUrl if set. 422 * @method 423 * @return {String} alohaUrl 424 */ 425 getAlohaUrl: function( suffix ) { 426 return Aloha.settings.baseUrl; 427 }, 428 429 /** 430 * Gets the plugin's url. 431 * 432 * @method 433 * @param {string} name The name with which the plugin was registered 434 * with. 435 * @return {string} The fully qualified url of this plugin. 436 */ 437 getPluginUrl: function (name) { 438 var url; 439 440 if (name) { 441 url = Aloha.settings._pluginBaseUrlByName[name]; 442 if(url) { 443 //Check if url is absolute and attach base url if it is not 444 if(!url.match("^(\/|http[s]?:).*")) { 445 url = Aloha.getAlohaUrl() + '/' + url; 446 } 447 } 448 } 449 return url; 450 }, 451 452 /** 453 * Disable object resizing by executing command 'enableObjectResizing', 454 * if the browser supports this 455 */ 456 disableObjectResizing: function () { 457 try { 458 // this will disable browsers image resizing facilities 459 // disable resize handles 460 var supported; 461 try { 462 supported = document.queryCommandSupported( 'enableObjectResizing' ); 463 } catch ( e ) { 464 supported = false; 465 Aloha.Log.log( 'enableObjectResizing is not supported.' ); 466 } 467 468 if ( supported ) { 469 document.execCommand( 'enableObjectResizing', false, false); 470 Aloha.Log.log( 'enableObjectResizing disabled.' ); 471 } 472 } catch (e) { 473 Aloha.Log.error( e, 'Could not disable enableObjectResizing' ); 474 // this is just for others, who will not support disabling enableObjectResizing 475 } 476 } 477 }); 478 479 return Aloha; 480 }); 481