Firebug console logging function in Opera · 30. September 2008, 00: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:
Opera/9.52 (X11; Linux i686; U; en) gives the following in the error console and dragonfly arror log:
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
Mixxx SkinEditor PHP-Framework Agavi 1.0.0 and unofficial FAQ
