dbug
Note: dbug.js has no dependencies. You can use it with or without any of the other libraries here.
Debugging javascript has historically been about as much fun as a trip to the dentist, but that changed a lot with the introduction of Firebug by Joe Hewitt. Firebug is a full fledged debugging console that I could go on and on about, but I'm just going to assume that if you're writing javascript you already know about it, and if you don't, then you're installing it right this second and reading the documentation on the Firebug site.
The only rub about Firebug is that the way you use it doesn't degrade so well. If you have a debugging line in your code like this:
console.log('hi there');
And you publish your javascript with that line still in it, users who visit the page without firebug will get errors or, worse, see their browsers crash. One of the ways to use firebug is like this:
var x = 'hi there'; console.log('the value of x is "%s"', x); //"the value of x is "hi there" var x = {this: 'that', something: 'else'}; console.log('the value of x is %1.o', x); /* in the console: the value of x is this "that" something "else" */
The problem is that Safari has its own console, and the first command will work fine in safari, but the second example will crash the browser. FUN!
So the problem then is that if you want to put debug statements in your code, you either need to always make sure you remove any code, or you have to wrap your commands in something that makes sure the browser has Firebug installed.
Enter dbug
dbug is an object with translator functions for the console in firebug. By default, it's disabled, which means that if you send it logging commands, nothing will happen. This means that the average user who encounters one of your logging statements won't see anything, even if they have Firebug installed.
dbug has a couple of functions that let you log statements and turn it on and off. Here's the basic syntax:
dbug.enable()
dbug.enable()// turns debugging on

Any logging statements sent before you enable it are stored, and when you enable it they're all dumped to the console. This way, if you have a bunch of error handling in your code (you do, right?) you can send errors to the dbug object. Then, if you hit a page and the behavior you expect doesn't show up, you can just open the console and type in dbug.enable() and all the messages thus far logged will be printed out all at once. Any logging statements that happen after you call enable() will show up in the console as they occur. You can also just put dbug.enable() in your page's script to turn it on and off if you like.
This means that you can pepper your code with debugging statements without affecting your users. There's also dbug.disable(), though I've never really found cause to use it.
Note that even if you call dbug.enable() in your code, if the browser rendering the page doesn't have Firebug installed, nothing will happen.
dbug.cookie()
dbug.cookie() does pretty much the same thing as dbug.enable() except that it sets the state in a cookie that lasts for the rest of your browser session so you don't have to keep typing it.
&jsdebug=true
In addition to enabling the debugger in the console you can turn it on when you load the page by adding "jsdebug=true" to the query string of the page you're viewing. If the url you're viewing is www.somewhere.com/example.html, you just add "?jsdebug=true" and this will enable the dbug functions. If there's already a query string in the url, just use "&jsdebug=true".
dbug.log
dbug.log functions just the way that console.log does, so using the examples I gave above, the syntax is exactly the same, except that you use 'dbug' instead of 'console'.
dbug.enable();/*turn debugging on if it's not already*/ var x = 'hi there'; dbug.log('the value of x is "%s"', x); /*"the value of x is "hi there"*/ var x = {apple: 'red', lemon: 'yellow'}; dbug.log('the value of x is %1.o', x); /* in the console: the value of x is apple: 'red' lemon: 'yellow */

You can leave these in your code without affecting your users. Unless they know how to enable your debugging, they'll never see it, and even if they do, only in the console. No more messy alerts.
Other dbug Methods
These are translators for all of the other console methods in Firebug (see http://www.getfirebug.com/console.html).
dbug.time(); //same as console.time() dbug.timeEnd(); //same as console.timeEnd() dbug.trace(); //same as console.trace(); dbug.dir(obj); //same as console.dir(obj); //etc
Examples:
dbug.time('anchor test'); for(i=0;i<100;i++){ $$('a'); /*get all the links on this page*/ } dbug.timeEnd('anchor test'); /*produces something like: enabling dbug anchor test: 173ms */

dbugScripts
There's another function, dbugScripts, that is also worth checking out though. You'll find this option on our download page in the debugging options. (And here are the docs.
dbugScripts is a relatively simple function. You pass it a base url and then an array of scripts and, if the window.location has "jsdebug=true", it'll include the scripts you gave it. Here's the actual function:
function dbugScripts(baseurl,libs){ var value = document.cookie.match('(?:^|;)\\s*jsdebug=([^;]*)'); var debugCookie = value ? unescape(value[1]) : false; if(window.location.href.indexOf("basePath=this")>0){ var path=baseurl.substring(baseurl.substring(7,baseurl.length).indexOf("/")+8,baseurl.length); var href=window.location.href; baseurl=href.substring(href.substring(7,href.length).indexOf("/")+8,href.length); } if(window.location.href.indexOf("jsdebug=true")>0 || window.location.href.indexOf("jsdebugCookie=true")>0 || debugCookie == 'true'){ if (libs) { for(var i=0;i<libs.length;i++){ document.write("<scri"+"pt src=\""+baseurl+libs[i]+"\" type=\"text/javascript\"></scr"+"ipt>"); } } else { document.write("<scri"+"pt src=\""+baseurl+"\" type=\"text/javascript\"></scr"+"ipt>"); } return true; } return false; };
Note that you can also add "basePath=this" to your query string and instead of using the domain in the passed in url, it'll use the domain you're on. Bear with me here, this'll all make sense in a moment.
The framework we use here at CNET is comprised of a LOT of javascript files. We keep them all sliced up in little chunks to maintain them, but when we're ready to publish them, we concatenate all the files together in the proper order, then we delint them (strip all the comments, line breaks, tabs, and extra spaces). We use compressino (like Dean Edward's Packer or the YUI compressor) to strip out all those things.
So we deliver to the browser our javascript in a condensed form and it's not very readable. What's more, we are very careful to introduce change into our environment and we seek ways to ensure that code that we plan on introducing works everywhere. This presents some sticky problems for someone if they focus only on the javascript, and that's where dbugScripts comes into play.
Here's what our compressed documents look like (note, the very first javascript file we include in our pages has the dbugScripts function in it):
//dbugScripts - will include non-compressed versions of this code if "jsdebug=true" is in the url of this page, //otherwise it will execute this code. //example: dbugScripts("/the/location/of/my/scripts/",["script1.js","script2.js","etc"]) //returns true if scripts are included, otherwise false. if(!dbugScripts('http://devserver.cnet.com/location/of/scripts/', ['mootools.js', 'otherfunctions.js', etc]){ ...compressed code to run if not debugging... }
So what we get out of this is our script runs normal for everyone, but if you put "jsdebug=true" in your query string, now your browser will ignore all the code in the live library, and instead include all the code in your development environment. You can fiddle away with these libraries, all the while looking at the live site, until you fix your bugs and test everything, then release your code. The code you are including for debugging isn't compressed, so it's got all your line breaks and tabs and comments.
basePath=this
As I mentioned above, basePath=this lets you throw out the domain in the compressed script and use the one you're viewing. This is for development servers. Let's say our compressed script is live at www.cnet.com. And let's say that in that script we've hard-coded the development path to our scripts as devserver.cnet.com. Now let's say I'm a developer who has a copy of these environments for my own development running at dev2server.cnet.com:8001, and I want to see the scripts that I have in my environment, not those on devserver.cnet.com. By including "basePath=this" in the query string (in addition to "jsdebug=true"), instead of including these scripts:
I'll include these:
These two things together, dbug and dbugScripts make it a lot easier for us to trouble shoot problems and verify code bases before we publish them.
cnet-libraries/01-core/00-dbug.txt · Last modified: 2008/11/17 23:25