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