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 'jquery', 29 'aloha/pluginmanager' 30 ], function ( 31 jQuery, 32 PluginManager 33 ) { 34 "use strict"; 35 36 var Aloha = window.Aloha; 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 * @type string 99 */ 100 stage: 'loadingAloha', 101 102 /** 103 * A list of loaded plugin names. Available after the 104 * "loadPlugins" stage. 105 * 106 * @property 107 * @type array 108 * @internal 109 */ 110 loadedPlugins: [], 111 112 /** 113 * Maps names of plugins (link) to the base URL (../plugins/common/link). 114 */ 115 _pluginBaseUrlByName: {}, 116 117 /** 118 * Initialize the initialization process 119 */ 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 var i, editablesLength; 245 246 Aloha.RepositoryManager.init(); 247 248 // activate registered editables 249 for (i = 0, editablesLength = Aloha.editables.length; i < editablesLength; i++) { 250 if (!Aloha.editables[i].ready) { 251 Aloha.editables[i].init(); 252 } 253 } 254 255 // Forward 256 next(); 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 var i; 266 267 // Don't cache Aloha.editables.length since editables may be removed on blur. 268 for (i = 0; i < Aloha.editables.length; i++) { 269 if (Aloha.editables[i] != editable && Aloha.editables[i].isActive) { 270 Aloha.editables[i].blur(); 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 var i, editablesLength; 307 308 // if the element is a textarea than route to the editable div 309 if (jQuery('#' + id).get(0).nodeName.toLowerCase() === 'textarea') { 310 id = id + '-aloha'; 311 } 312 313 // serach all editables for id 314 for (i = 0, editablesLength = Aloha.editables.length; i < editablesLength; i++) { 315 if (Aloha.editables[i].getId() == id) { 316 return Aloha.editables[i]; 317 } 318 } 319 320 return null; 321 }, 322 323 /** 324 * Checks whether an object is a registered Aloha Editable. 325 * @param {jQuery} obj the jQuery object to be checked. 326 * @return {boolean} 327 */ 328 isEditable: function (obj) { 329 var i, editablesLength; 330 331 for (i = 0, editablesLength = Aloha.editables.length; i < editablesLength; i++) { 332 if (Aloha.editables[i].originalObj.get(0) === obj) { 333 return true; 334 } 335 } 336 return false; 337 }, 338 339 /** 340 * Get the nearest editable parent of the given jQuery object 341 * @param {jQuery} $obj jQuery object 342 * @return {Aloha.Editable} editable or undefined if none found 343 */ 344 getEditableHost: function ($obj) { 345 var $parents, i, $editable, editablesLength = Aloha.editables.length; 346 if (!$obj) { 347 return; 348 } 349 350 $parents = $obj.parents().andSelf().each(function () { 351 for (i = 0; i < editablesLength; i++) { 352 if (Aloha.editables[i].originalObj.get(0) === this) { 353 $editable = Aloha.editables[i]; 354 return false; 355 } 356 } 357 }); 358 359 return $editable; 360 }, 361 362 /** 363 * Logs a message to the console 364 * @param level Level of the log ("error", "warn" or "info", "debug") 365 * @param component Component that calls the log 366 * @param message log message 367 * @return void 368 * @hide 369 */ 370 log: function (level, component, message) { 371 if (typeof Aloha.Log !== "undefined") { 372 Aloha.Log.log(level, component, message); 373 } 374 }, 375 376 /** 377 * Register the given editable 378 * @param editable editable to register 379 * @return void 380 * @hide 381 */ 382 registerEditable: function (editable) { 383 Aloha.editables.push(editable); 384 }, 385 386 /** 387 388 * Unregister the given editable. It will be deactivated and removed from editables. 389 * @param editable editable to unregister 390 * @return void 391 * @hide 392 */ 393 unregisterEditable: function (editable) { 394 var id = jQuery.inArray(editable, Aloha.editables); 395 if (id != -1) { 396 Aloha.editables.splice(id, 1); 397 } 398 }, 399 400 /** 401 * String representation 402 * @hide 403 */ 404 toString: function () { 405 return 'Aloha'; 406 }, 407 408 /** 409 * Check whether at least one editable was modified 410 * @method 411 * @return {boolean} true when at least one editable was modified, false if not 412 */ 413 isModified: function () { 414 var i; 415 416 // check if something needs top be saved 417 for (i = 0; i < Aloha.editables.length; i++) { 418 if (Aloha.editables[i].isModified && Aloha.editables[i].isModified()) { 419 return true; 420 } 421 } 422 423 return false; 424 }, 425 426 /** 427 * Determines the Aloha Url 428 * Uses Aloha.settings.baseUrl if set. 429 * @method 430 * @return {String} alohaUrl 431 */ 432 getAlohaUrl: function (suffix) { 433 return Aloha.settings.baseUrl; 434 }, 435 436 /** 437 * Gets the plugin's url. 438 * 439 * @method 440 * @param {string} name The name with which the plugin was registered 441 * with. 442 * @return {string} The fully qualified url of this plugin. 443 */ 444 getPluginUrl: function (name) { 445 var url; 446 447 if (name) { 448 url = Aloha.settings._pluginBaseUrlByName[name]; 449 if (url) { 450 //Check if url is absolute and attach base url if it is not 451 if (!url.match("^(\/|http[s]?:).*")) { 452 url = Aloha.getAlohaUrl() + '/' + url; 453 } 454 } 455 } 456 return url; 457 }, 458 459 /** 460 * Disable object resizing by executing command 'enableObjectResizing', 461 * if the browser supports this 462 463 */ 464 disableObjectResizing: function () { 465 try { 466 // this will disable browsers image resizing facilities 467 // disable resize handles 468 var supported; 469 try { 470 supported = document.queryCommandSupported('enableObjectResizing'); 471 } catch (e) { 472 supported = false; 473 Aloha.Log.log('enableObjectResizing is not supported.'); 474 } 475 476 if (supported) { 477 document.execCommand('enableObjectResizing', false, false); 478 Aloha.Log.log('enableObjectResizing disabled.'); 479 } 480 } catch (e2) { 481 Aloha.Log.error(e2, 'Could not disable enableObjectResizing'); 482 // this is just for others, who will not support disabling enableObjectResizing 483 } 484 } 485 }); 486 487 return Aloha; 488 }); 489