1 /* console.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 	'aloha/core',
 29 	'util/class',
 30 	'jquery'
 31 ], function (
 32 	Aloha,
 33 	Class,
 34 	jQuery
 35  36 ) {
 37 	"use strict";
 38 
 39 	/**
 40 	 * This is the aloha Log
 41 	 * @namespace Aloha
 42 	 * @class Log
 43 	 * @singleton
 44 	 */
 45 	var AlohaConsole = Class.extend({
 46 		/**
 47 		 * Initialize the logging
 48 		 * @hide
 49 		 */
 50 		init: function () {
 51 
 52 			// initialize the logging settings (if not present)
 53 			if (typeof Aloha.settings.logLevels === 'undefined' || !Aloha.settings.logLevels) {
 54 				Aloha.settings.logLevels = {
 55 					'error': true,
 56 					'warn': true
 57 				};
 58 			}
 59 
 60 			// initialize the logHistory settings (if not present)
 61 			if (typeof Aloha.settings.logHistory === 'undefined' || !Aloha.settings.logHistory) {
 62 				Aloha.settings.logHistory = {};
 63 			}
 64 			// set the default values for the loghistory
 65 			if (!Aloha.settings.logHistory.maxEntries) {
 66 				Aloha.settings.logHistory.maxEntries = 100;
 67 			}
 68 			if (!Aloha.settings.logHistory.highWaterMark) {
 69 				Aloha.settings.logHistory.highWaterMark = 90;
 70 			}
 71 			if (!Aloha.settings.logHistory.levels) {
 72 				Aloha.settings.logHistory.levels = {
 73 					'error': true,
 74 					'warn': true
 75 				};
 76 			}
 77 			this.flushLogHistory();
 78 
 79 			Aloha.trigger('aloha-logger-ready');
 80 		},
 81 
 82 		/**
 83 		 * Log History as array of Message Objects. Every object has the properties
 84 		 * 'level', 'component' and 'message'
 85 		 * @property
 86 		 * @type Array
 87 		 * @hide
 88 		 */
 89 		logHistory: [],
 90 
 91 		/**
 92 		 * Flag, which is set as soon as the highWaterMark for the log history is reached.
 93 		 * This flag is reset on every call of flushLogHistory()
 94 		 * @hide
 95 		 */
 96 		highWaterMarkReached: false,
 97 
 98 		/**
 99 		 * Logs a message to the console
100 		 * @method
101 		 * @param {String} level Level of the log ('error', 'warn' or 'info', 'debug')
102 		 * @param {String} component Component that calls the log
103 		 * @param {String} message log message
104 		 */
105 		log: function (level, component, message) {
106 
107 
108 			// log ('Logging message');
109 			if (typeof component === 'undefined') {
110 				message = level;
111 			}
112 			if (typeof component !== 'string' && component && component.toString) {
113 				component = component.toString();
114 			}
115 
116 117 			// log ('warn', 'Warning message');
118 			if (typeof message === 'undefined') {
119 				message = component;
120 				component = undefined;
121 			}
122 
123 			if (typeof level === 'undefined' || !level) {
124 				level = 'log';
125 			}
126 
127 			level = level.toLowerCase();
128 
129 			if (typeof Aloha.settings.logLevels === "undefined") {
130 				return;
131 			}
132 
133 			// now check whether the log level is activated
134 			if (!Aloha.settings.logLevels[level]) {
135 				return;
136 			}
137 
138 			component = component || "Unkown Aloha Component";
139 
140 			this.addToLogHistory({
141 				'level': level,
142 				'component': component,
143 				'message': message,
144 				'date': new Date()
145 			});
146 
147 			var console = window.console;
148 
149 			switch (level) {
150 			case 'error':
151 				if (window.console && console.error) {
152 					// FIXME:
153 					// Using console.error rather than throwing an error is very
154 					// problematic because we get not stack.
155 156 					// We ought to consider doing the following:
157 					// throw component + ': ' + message;
158 					if (!component && !message) {
159 						console.error("Error occured without message and component");
160 					} else {
161 						console.error(component + ': ' + message);
162 					}
163 				}
164 				break;
165 			case 'warn':
166 				if (window.console && console.warn) {
167 					console.warn(component + ': ' + message);
168 				}
169 				break;
170 			case 'info':
171 				if (window.console && console.info) {
172 					console.info(component + ': ' + message);
173 				}
174 				break;
175 			case 'debug':
176 				if (window.console && console.log) {
177 					console.log(component + ' [' + level + ']: ' + message);
178 				}
179 				break;
180 			default:
181 				if (window.console && console.log) {
182 					console.log(component + ' [' + level + ']: ' + message);
183 				}
184 				break;
185 			}
186 		},
187 
188 		/**
189 		 * Log a message of log level 'error'
190 		 * @method
191 		 * @param {String} component Component that calls the log
192 		 * @param {String} message log message
193 		 */
194 		error: function (component, message) {
195 			this.log('error', component, message);
196 		},
197 
198 		/**
199 		 * Log a message of log level 'warn'
200 		 * @method
201 		 * @param {String} component Component that calls the log
202 		 * @param {String} message log message
203 		 */
204 		warn: function (component, message) {
205 			this.log('warn', component, message);
206 		},
207 
208 		/**
209 		 * Log a message of log level 'info'
210 		 * @method
211 		 * @param {String} component Component that calls the log
212 		 * @param {String} message log message
213 		 */
214 		info: function (component, message) {
215 			this.log('info', component, message);
216 		},
217 
218 		/**
219 		 * Log a message of log level 'debug'
220 		 * @param {String} component Component that calls the log
221 		 * @param {String} message log message
222 		 */
223 		debug: function (component, message) {
224 			this.log('debug', component, message);
225 		},
226 
227 		/**
228 		 * Methods to mark function as deprecated for developers.
229 		 * @param {String} component String that calls the log
230 		 * @param {String} message log message
231 		 */
232 		deprecated: function (component, message) {
233 			this.log('warn', component, message);
234 			// help the developer to locate the call.
235 			if (Aloha.settings.logLevels.deprecated) {
236 				throw new Error(message);
237 			}
238 		},
239 
240 		/**
241 		 * Check whether the given log level is currently enabled
242 		 * @param {String} level
243 		 * @return true when log level is enabled, false if not
244 		 */
245 		isLogLevelEnabled: function (level) {
246 			return Aloha.settings && Aloha.settings.logLevels && Aloha.settings.logLevels[level];
247 		},
248 
249 		/**
250 		 * Check whether error logging is enabled
251 		 * @return true if error logging is enabled, false if not
252 		 */
253 		isErrorEnabled: function () {
254 			return this.isLogLevelEnabled('error');
255 		},
256 
257 		/**
258 		 * Check whether warn logging is enabled
259 		 * @return true if warn logging is enabled, false if not
260 		 */
261 		isWarnEnabled: function () {
262 			return this.isLogLevelEnabled('warn');
263 		},
264 
265 		/**
266 		 * Check whether info logging is enabled
267 		 * @return true if info logging is enabled, false if not
268 		 */
269 		isInfoEnabled: function () {
270 			return this.isLogLevelEnabled('info');
271 		},
272 
273 		/**
274 		 * Check whether debug logging is enabled
275 		 * @return true if debug logging is enabled, false if not
276 		 */
277 		isDebugEnabled: function () {
278 			return this.isLogLevelEnabled('debug');
279 		},
280 
281 		/**
282 		 * Add the given entry to the log history. Check whether the highWaterMark has been reached, and fire an event if yes.
283 		 * @param {Object} entry entry to be added to the log history
284 		 * @hide
285 		 */
286 		addToLogHistory: function (entry) {
287 
288 			if (!Aloha.settings.logHistory) {
289 				this.init();
290 			}
291 
292 			// when maxEntries is set to something illegal, we do nothing (log history is disabled)
293 294 			// check whether the level is one we like to have logged
295 			if (Aloha.settings.logHistory.maxEntries <= 0 || !Aloha.settings.logHistory.levels[entry.level]) {
296 
297 				return;
298 			}
299 
300 			// first add the entry as last element to the history array
301 			this.logHistory.push(entry);
302 
303 			// check whether the highWaterMark was reached, if so, fire an event
304 			if (!this.highWaterMarkReached) {
305 
306 				if (this.logHistory.length >= Aloha.settings.logHistory.maxEntries * Aloha.settings.logHistory.highWaterMark / 100) {
307 
308 					// fire the event
309 					Aloha.trigger('aloha-log-full');
310 					// set the flag (so we will not fire the event again until the logHistory is flushed)
311 					this.highWaterMarkReached = true;
312 				}
313 			}
314 
315 			// check whether the log is full and eventually remove the oldest entries
316 			// @todo remove old entries when aloha-log-full event is triggered
317 			while (this.logHistory.length > Aloha.settings.logHistory.maxEntries) {
318 				this.logHistory.shift();
319 			}
320 321 		},
322 
323 		/**
324 		 * Get the log history
325 		 * @return log history as array of objects
326 		 * @hide
327 		 */
328 		getLogHistory: function () {
329 			return this.logHistory;
330 		},
331 
332 		/**
333 		 * Flush the log history. Remove all log entries and reset the flag for the highWaterMark
334 		 * @return void
335 		 * @hide
336 		 */
337 		flushLogHistory: function () {
338 			this.logHistory = [];
339 			this.highWaterMarkReached = false;
340 		}
341 	});
342 
343 	/**
344 	 * Create the Log object
345 	 * @hide
346 	 */
347 	AlohaConsole = new AlohaConsole();
348 
349 	// add to log namespace for compatiblility.
350 	Aloha.Log = Aloha.Console = AlohaConsole;
351 	return AlohaConsole;
352 });
353