Go to content Go to navigation

Firebug console logging function in Opera · 30. September 2008, 01:21 von Steffen

As some may have noticed, Opera has its own javascript debugging tool now. Dragonfly is still in an early alpha state, but looks very promising and was already quite helpful for me. I use the debug menu and always the latest weekly release (by setting opera:config#DeveloperTools to https://dragonfly.opera.com/app/weekly) from the Dragonfly developer blog. I seriously hope, that the scope protocol gets some attention and will be used in multiple applications/platforms (see the documentation).

The Firebug extension for Firefox is widely in use throughout web developers. Its console methods like @console.log()@, @console.assert()@, @console.time()@ and other are often used. After reading Will Fris' blog entry I thought, that I try to enhance the given code a bit for personal use later on. The following code is everything I came up with so far. It recreates the logging functions, timing functions and the assert function. Remember, that it is just a simple drop-in replacement without the attempt of recreating 100% of the functionality. Simple string substitutions in the logging methods are supported though (imho):

// recreates some things to make scripts with firebug debugging functions
// work in other browsers (especially Opera)
// (just a quick'n'dirty drop-in approach; could perhaps be used as a user javascript)
if (!window.console || !window.console.firebug) {
	var names = ["dir", "dirxml", "group", "groupEnd", "trace", "profile", "profileEnd"];
	var logFx = ["log", "debug", "info", "warn", "error"];
	window.console = {};
	// no more javascript errors in non-firefox browsers
	for (i in names) {
		window.console[names[i]] = function() {};
	}
	for (i in logFx) {
		if (window.opera) {
			// simple replacement of the console.log() etc methods of firebug
			window.console[logFx[i]] = (function (logtype) {
											// using scope to remember the instances of the local variables
											// save function name for later use (logtype === logFx[i])
											// see http://www.howtocreate.co.uk/referencedvariables.html
											return function() {
												if (typeof arguments === "undefined") { // no arguments at all
													return null;
												}
												if (arguments.length === 1) { // single argument provided
													opera.postError(logtype+': '+arguments[0]);
													return logtype+': '+arguments[0];
												}
												var string = arguments[0];
												var regexp = new RegExp(/%([sdifo])/g); // string substitution patterns of firebug console
												var count = 0;
												var match = null;
												// replace found matches with given arguments
												while (match = regexp.exec(string)) {
													string = string.replace(match[0], String(arguments[++count]));
												}
												// display log messages
												var len = arguments.length;
												while (len > count++) {
													if (arguments[count]) {
														string += ' ';
														string += String(arguments[count]);
													}
												}
												opera.postError(logtype+': '+string);
											};
										})(logFx[i]);
		} else {
			window.console[logFx[i]] = function() {};
		}
	}
	if (window.opera) {
		// most simple assertion method with parameters: fn(expected, message)
		window.console['assert'] = function() {
										if (arguments.length !== 2) {
											throw new Exception('Please specify an assertion and a message.');
										}
										if (!arguments[0]) {
											opera.postError('Assertion failed: '+arguments[1]);
										}
									}
		// not a good exchange for the firebug version, as this is dependant of
		// the used counter name and displays a log message for every execution
		window.console['count'] = function(arg) {
									var title = arg || 'defaultCounter';
									if (!window.opera['FireBugEquivalent']) {
										window.opera['FireBugEquivalent'] = [];
									}
									if (!window.opera['FireBugEquivalent'][title]) {
										window.opera['FireBugEquivalent'][title] = 0;
									}
									window.opera['FireBugEquivalent'][title] = window.opera['FireBugEquivalent'][title]+1;
									opera.postError('Counter "'+title+'" '+window.opera['FireBugEquivalent'][title]+'x called.');
								  };
		// start a timer specified by a name
		window.console['time'] = function(arg) {
									var timerName = arg || 'defaultTimer';
									if (!window.opera['FireBugEquivalent']) {
										window.opera['FireBugEquivalent'] = [];
									}
									window.opera['FireBugEquivalent'][timerName] = new Date().getTime();
								  };
		// stops a timer specified by name
		window.console['timeEnd'] = function(arg) {
									var timerName = arg || 'default';
									if (window.opera['FireBugEquivalent']) {
										var startTime = window.opera['FireBugEquivalent'][timerName];
										if (startTime) {
											var stopTime = new Date().getTime();
											var elapsed = (stopTime - startTime);
											opera.postError('Timer "'+timerName+'" took '+elapsed+' millisecond'+((elapsed==1)?'':'s'));
											delete window.opera['FireBugTimerEquivalent'][timerName];
										} else { // no start timer found
											opera.postError('No start timer defined - check timer name or call console.time("timerName").');
										}
									} else { // no timers at all
										opera.postError('No previously stored timers found.');
									}
								  };
	}
}

Tests are in the body part of the demo file:

// console logging tests
var blub = function() { var str = 'some string'; function blub() { return 'blub';} };
console.log(2, 4, 6, 8, "foo", blub)
console.log("%s is %d years old.", "Bob", 42)
console.debug('This is a debug message.');
console.error('This is an error message.');
console.info('This is an info message.');
console.warn('This is a warning message.');

// assertion tests
console.assert(true, "I should pass.");
console.assert("true", "So should I.");
console.assert(false, "I'll fail."); // counts as error in firebug
console.assert(null, "So will I."); // counts as error in firebug
var obj = {}; 
var fn = function(){}; 
obj.prop = "value"; 
fn.prop = "value"; 
console.assert(obj.prop==fn.prop, "Two objects with an equal property.");

// timer tests
console.time('timer 1');
console.time('timer 2');
for (var r = 0; r < 1000; r++) {
	document.write('');
}
console.timeEnd('timer 1');
for (var r = 0; r < 1000; r++) {
	document.write('');
}
console.timeEnd('timer 2');
for (var r = 0; r < 2; r++) {
	document.write('');
	console.count('count title');
}

Gives the following results in Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.3) Gecko/2008092510 Ubuntu/8.04 (hardy) Firefox/3.0.3:

Firebug console output of above code

Opera/9.52 (X11; Linux i686; U; en) gives the following in the error console and dragonfly arror log:

Opera error console output of above code
Opera Dragonfly error console output of above code

Remember, that the javascript code in demo file is just a quick and dirty hack as a training for me after reading Will Fris' blog entry - I just thought of recreating some functionality of Firebug for Opera, just in case I need a drop-in replacement for a script that got developed using Firebug (that is: appearing js errors due to that).

Posting it here, just in case somebody needs something similar. Please note, that the above code could be malformatted due to the first time usage of the dp.SyntaxHighlighter on this blog. :-)

Kommentarfunktion für diesen Artikel geschlossen

Letzte 10 Artikel

HTTP-CUKE
Gnome-Panel floating point exception
RegExps und (X)HTML gehören nicht zusammen...
253 Tage nicht geschrieben?
PHP-Framework Agavi 1.0.0 and unofficial FAQ
Firebug console logging function in Opera
Mixxx SkinEditor
Launch des Freizeitportals für Rügen
The story of stuff...
Wer sich keinen Rechenzentrumstruck...


Suchen

Verwandte Artikel

Interessantes

ahoi polloi. Für die (fast) tägliche Portion Karikaturen über den alltäglichen Wahnsinn.

Der Spiegelfechter. “So sagt man, wenn man Jemand mit irgend etwas dem Scheine nach Glaubliches täuscht, es sey eine Spiegelfechterei.” – Beiträge, die zum Nachdenken anregen.

Fefes Blog. Besuchs- und Lesebefehl! Tägliche Informationshäppchen für mehr Aufklärung und Spaß im Leben.

Karl Weiss. Journalismus - so der kurze und prägnante Titel des Weblogs von Karl Weiss. Artikel und Dossiers von ihm (meist veröffentlicht in der Berliner Umschau)

Opera Desktop Team. Blog mit Snapshots des aktuellen Stands der Entwicklung meines Browser-Arbeitstieres.

Püöähh!. Gonmag berichtet Geschichten von seinen Freunden. Oder so. ;)

rabenhorst. "Wenn Du das Weblog liest, wirst Du nie wieder ruhig schlafen." Blog zu Datenschutzthemen und allem was dazu gehört. Samt Gefahr-Indikator für Demokratie & Rechtsstaatlichkeit in Deutschland!

xkcd. “A webcomic of romance, sarcasm, math, and language.” – Comics mit wissenschaftlich-nerdigem Touch. hust Klassiker: Raptorenwitze!


textpattern