2
Dec/08
3

Debug JavaScript in Internet Explorer

If you have ever had the horror of finishing up some complex JavaScript in Firefox, and when you try it in IE you just get a bunch of usless and cryptic errors that all point to the wrong line of code, this article is for you. You can actually get a full debugger for Internet Exploerer for free that is about as cabable as debugging Javascript as Firebug is in Firefox.  There is no plugin or addon for IE that will give you a firebug like experience, but with a little extra downloading and work you can get a setup that will allow you to set break points and inspect objects in JavaScript applications in IE.  First thing you will need to download the free Visual Web Developer Express IDE from Microsoft Visual Web Developer is like Firebug for Internet Explorer, only it is not an addon and you have to do a bunch of setup befure it will be useful.  It is free but it will cost you more than 200 megs of hard drive space and about an hour of downloading and installing.

Once you have Visual Web Developer Express installed launch the IDE and create a new blank web site:
File >> New Web Site
Select “Empty Web Site” and give the project a name and click OK.

If your default web browser is something other than IE you will need to setup Visual Web Developer do debug in Internet Explorer by default.

On the right side of the IDE you will find the Solution Exploerer, right click on your solution and select “Browse With”.  In the browse with window select Internet Explorer and click the Set as Default button.  This will not change your system default browser just the browser that will be used by this solution by default.  Once you have IE set as default for the solution you can click cancel.



Now you need to make sure IE is ready to be debugged.  Open Internet Explorer, click on Tools >> Options, select the Advanced tab and remove the check from “Disable Script Debugging (Internet Explorer)” and click OK.

Now you are ready.  Switch back to Visual Web Developer and press F5 to start debugging.  If this is the first time you have launched this solution Visual Web Developer may display a dialog stating that a web.config could not be found.  If you recieve this dialog choose “Add a new web.config…” and click ok. This should launch Internet Explorer with an error page, just type in the URL of the page you want to debug in the address bar.  Once the page loads if you switch back to Visual Web Developer Express you will see all of the files loaded by the page in the Solution Explorer on the right.  Double click the file with the JavaScript you wish to debug, which will open the file in the IDE.  You can now set break points where you want them.  Once you have your break points set switch back to IE and take the action that will execute the code you are debugging and Visual Web developer will stop on your break points letting you inspect the objects and variables at that point.

To make the process easier you can right click on the solution in the solution explorer and select “Add New Item”.  From the presented installed templates choose “HTML Page”, and name it index.htm.  In the head of the generated HTML add a meta refresh to go to the page you wish to debug. e.g. <meta http-equiv=”refresh” content=”0;url=http://www.yourdomain.com/pagetodebug.html” />.  After adding that when you debug it will automatically redirect to the page you are working on.

[Post to Twitter]  [Post to Plurk]  [Post to Yahoo Buzz]  [Post to Delicious]  [Post to Digg]  [Post to Ping.fm]  [Post to Reddit]  [Post to StumbleUpon] 

4
Mar/08
1

IE8 Arrogance

So I read this new IEBlog post (“Microsoft’s Interoperability Principles and IE8“) about how they have come to the decision that Internet Explorer 8 will render with IE8 standard mode by default. They say it like they are so smart for figuring that out, um… duh. Yes I would like to buy a new car, but could you please make it run like my old run down beater of a car, that would be great thanks. Then they say “…this choice creates a clear call to action to site developers to make sure their web content works well in IE”, WHAT!?!?!?!

HEY IE Team, how about this, you send out a clear call to action that site developers should develop to standards and your damn browser will render it properly.

[Post to Twitter]  [Post to Plurk]  [Post to Yahoo Buzz]  [Post to Delicious]  [Post to Digg]  [Post to Ping.fm]  [Post to Reddit]  [Post to StumbleUpon] 

Filed under: IE, web standards
5
Dec/07
0

Using setTimeout in objects with Mootools

Often you wish to use setTimeout to call a function in the objects you are creating with MooTools or perhaps even more often you would like to pass parameters into your set time out calls. Well, the MooTools framework has given us a plethora of tools to do all of this and more. In this post I will discuss how you can pass parameters with setTimeout (Well, not really ‘into’ setTimeout, but a better way to get the same result.) and call your functions, delayed and recurring, from your objects created with the MooTools class function.

Closures and bind()

The first problem we tend to encounter the first time we try to do this is that when our member function gets called by setTimeout we get a bunch of errors that our variables are undefined. This problem is caused by JavaScript’s lack of closures which means that there is not hard binding between the function and the object that it is declared in. If you do a little debugging you will discover that the this operator is pointing at the window object not your object. The reason for that is that setTimeout causes the function to be called by the window object and in JavaScript this points to the calling scope.

Because the issue of closures is a problem in many cases when using JavaScript MooTools came up with a generic solution to the problem called bind. The bind() method is a part of the functions.js, found in the Native collection of MooTools functions. Their docs on bind can be found here. The Bind() member function will allow you to bind the this operator to any object you choose, which often will be the this of the object you define it in, but could be any object in the DOM. You can use bind when you call set time out like setTimeout(this.myfunction.bind(this), 1000) to call functions in your object delayed and have still have the this operator point at what you expect it to. That having been said, MooTools has two other functions to help you with delayed and recurring function calls in a much more efficient manner.

Delayed and Recurring calls

As this is an article about setTimeout, you are most likely unconcerned with what closures are and are just wanting your delayed function or recurring/polling/periodic function to work. If so, this is the section for you! The MooTools library provides two functions for calling functions, either delayed or periodically. They are, not surprisingly, called ‘delay’ and ‘periodical’. You use delay when you want a function to execute in so many seconds or periodical when you want a function to execute every so many seconds. Both of these functions return their timer ID and can be stopped by passing that into the $clear() function.

Delay example:

delay_demo = new Class({

    initialize: function(dateString){

        this.count = 0;

        this.delayTimer = this.updateCount.delay(1000, this);

    },

    updateCount: function(){

        this.count++;

    }

});

periodical example:

periodical_demo = new Class({

    initialize: function(dateString){

        this.count = 0;

        this.startTimer();

    },

    updateCount: function(){

        this.count++;

    },

    stopTimer: function(){

        $clear(this.periodicalTimer);

    },

    startTimer: function(){

        this.periodicalTimer = this.updateCount.periodical(1000, this);

    }

});

Passing Parameters

Another important feature of bind, delay and periodical is that they will allow you to pass parameters or arguments to the functions they call. Passing arguments to a function called with bind, delay or periodical is as easy as adding a second parameter for bind and, in the case of delay and periodical, a third parameter that is an array of parameter values; e.g., myfunction.periodical(1000, this, [ParamVal1, ParamVal2, "strParamVal3"]) or myfunction.bind(this, [ParamVal1, ParamVal2, "strParamVal3"]).

Common Errors Encountered

There are some situations where you might get an error that does not really explain what the problem is. I have run into two when working with these functions. The first is the “too much recursion” error from Firefox or FireBug. This error indicates that you have used the parenthesis in a place you should not have, an example is using myfunction().delay(1000, this) instead of myfunction.delay(1000, this). The other is having a function that calls periodical that calls its self, which will cause an exponential increase in the number of calls to that function until your browser locks up.

periodical lockup example:

periodical_demo = new Class({
    initialize: function(dateString){
        this.count = 0;
        this.startTimer();
    },
    updateCount: function(){
        this.count++;
    },
    stopTimer: function(){
        $clear(this.periodicalTimer);
    },
    startTimer: function(){
        this.periodicalTimer = this.startTimer.periodical(1000, this); //Note calling startTimer from inside startTimer with periodical is very bad.
    }
});

MooTools has neatly provided simple ways to accomplish all of the tasks we would normally use setTimeout for.

[Post to Twitter]  [Post to Plurk]  [Post to Yahoo Buzz]  [Post to Delicious]  [Post to Digg]  [Post to Ping.fm]  [Post to Reddit]  [Post to StumbleUpon] 

11
Apr/07
1

The correct way to work with table elements in FireFox, IE and all other browsers

In my last post I talked about the differences between IE and Firefox when creating dynamic tables with the Document Object Model. Thanks to chatdor’s comment to my “Dynamic Tables In JavaScript for IE and Firefox” post, I realized that I was not paying attention to the full DOM. Perhaps many of us, like me, tend to only think of the Element object when thinking about manipulating the DOM, but there are a couple of higher level objects that derive from the Element object, the Table Element, and the Form Element, that make dealing with the more complex Elements easier. The good folks over at Mozilla have a great DOM reference which I almost always have open.

So, all that being said, I would like to post some code on a better way of creating dynamic tables in JavaScript with the DOM. In the following block of code we will use createElement(‘table’), to create our table but from then on we will use the Table Element’s member function insertRow and the Row’s insertCell to build the table.

1
2
3
4
5
var myTable = document.createElement('table');
var myRow = myTable.insertRow(-1);
var myCell = myRow.insertCell(-1);
var myTextNode = document.createTextNode('Hello World!');
myCell.appendChild(myTextNode);

In this block, I pass -1 into the insert functions to append the row or cell to the end of the rows or cells. Also in the example instead of setting the cell’s innerHTML or useing createElement(“text”) to make a text node and append, I instead use document.createTextNode, which is another case where there is a DOM function that is likely better to use than the less specific functions.

By using the higher level Table object and calling functions more specific to an action the code should have better cross-browser functionality.

[Post to Twitter]  [Post to Plurk]  [Post to Yahoo Buzz]  [Post to Delicious]  [Post to Digg]  [Post to Ping.fm]  [Post to Reddit]  [Post to StumbleUpon] 

8
Apr/07
2

Dynamic Tables In JavaScript for IE and Firefox

Edit : After reading chatdor’s comment I realized that I was consentrating so much on the Element that I was not seeing the whole DOM. See my new post on the DOM, for a better sample for creating table elements in JavaScript.


Recently I had the “pleasure” of dynamic creating some tables in JavaScript. In the process, I ran into and interesting issue or two. The first issue is that you cannot just append <tr> elements into a <table> element in IE. It will work, but IE will not render the rows. In IE you must create a <tbody> element, append the <tbody> element to the <table> element, then append your rows to your <tbody> element. This does not follow the W3C Row groups specification for the table specification which states that: “Table rows may be grouped into a table head, table foot, and one or more table body sections, using the THEAD, TFOOT and TBODY elements, respectively.” Note that the W3C specification states ‘may be’ whereas IE treats it as “must be.”

So, the following will get you nothing in IE but will work fine in Firefox:

1
2
3
4
5
6
var myTable = document.createElement("table");
var myRow = document.createElement("tr");
var myCell = document.createElement("td");
myCell.innerHTML = "Hello World!";
myTable.appendChild(myRow);
myRow .appendChild(myCell);

This will render a table in both IE and Firefox:

1
2
3
4
5
6
7
8
var myTable = document.createElement("table");
var myTbody = document.createElement("tbody");
var myRow = document.createElement("tr");
var myCell = document.createElement("td");
myCell.innerHTML = "Hello World!";
myTable.appendChild(myTbody);
myTbody.appendChild(myRow);
myRow.appendChild(myCell);

So now we have a table that renders in both IE and Firefox but there is still an issue remaining. Now in Firefox there is a space between the top of the table and the first row that you cannot get rid of. This is not going to be evident in all situations but will be in enough situations to be a problem. The reason for the space is that when you add a <tbody> to a table in Firefox it appears to reserve or auto include the <thead> and <tfoot> elements in the table. This is most likely done because the W3C specification states that you must have a <thead> and <tfoot> if you have a <tbody>. In order to prevent this extra space you need to add the<thead> and the <tfoot> and set their height to 0px or their display to none or something of the sort unless, of course, you are going to use them.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var myTable = document.createElement("table");
var myThead = document.createElement("thead");
myThead.style.height = 0px;
var myTfoot = document.createElement("tfoot");
myTfoot.style.height = 0px;
var myTbody = document.createElement("tbody");
var myRow = document.createElement("tr");
var myCell = document.createElement("td");
myCell.innerHTML = "Hello World!";
myTable.appendChild(myThead);
myTable.appendChild(myTfoot);
myTable.appendChild(myTbody);
myTbody.appendChild(myRow);
myRow.appendChild(myCell);

This gives you a way to render tables that match in both IE and Firefox with the same code.

[Post to Twitter]  [Post to Plurk]  [Post to Yahoo Buzz]  [Post to Delicious]  [Post to Digg]  [Post to Ping.fm]  [Post to Reddit]  [Post to StumbleUpon] 

8
Apr/07
0

Color Picker version 1.0.2 released

I have made a couple of small updates to the JavaScript Color Picker and the Color Picker project page today.

I fixed a bug with IE and dynamically created tables using the DOM method. Fixed a few layout issues I came across and added the showColorInfo Option. I also updated the example pages so they are integrated into the site and layout a little better.

Enjoy!

-=Kelly

[Post to Twitter]  [Post to Plurk]  [Post to Yahoo Buzz]  [Post to Delicious]  [Post to Digg]  [Post to Ping.fm]  [Post to Reddit]  [Post to StumbleUpon] 

2
Apr/07
2

Color Picker v1.0.1 Released

I have done some debugging of the color picker in Opera. There were problems with many of the Canvas functions needed in Opera 9.0, but things work beautifully in Opera 9.1.

I have also done some testing with Firefox 1.5 and Safari. Things do not work at all well in FireFox 1.5 as it is missing some key functionality and I am not planning on making it work in old versions of FireFox given 2.0’s wide spread install base.

Safari is close to working but I am having specific problems with the context.createLinearGradient() function in my version of Safari. Even though; when I look at the context it says that the createLinearGradient function exists it keeps returning undefined for me when I call it. If there are any Mac/Safari gurus out there that can see why this might be happening I would love to hear from you.

The Color Picker now supports FireFox 2.0, IE 7.0, and Opera 9.10.

See examples and download from the Color Picker Project Page.

[Post to Twitter]  [Post to Plurk]  [Post to Yahoo Buzz]  [Post to Delicious]  [Post to Digg]  [Post to Ping.fm]  [Post to Reddit]  [Post to StumbleUpon] 

1
Apr/07
0

Complete JavaScript Color Picker

Welcome to the final installation of my JavaScript based Color Picker series. I have made a lot of changes to the color picker since my last installment.

Layout
I found some major problems based on the document type with the way I was laying out elements in the color picker dialog, so I decided that it needed to use the lowest common denominator in order to work reliably, so it is laid out with, *gasp* tables.

Sizing
After adding the support for the Canvas element I decided to add options to size the HueBar and the SV Box.

1
2
3
4
5
6
7
8
9
10
    if(this.Options.hueBarWidth){
        this.HueBar.setStyle("width", this.Options.hueBarWidth);
    }else{
        this.HueBar.setStyle("width", "30");
    }
    if(this.Options.hueBarHeight){
        this.HueBar.setStyle("height", this.Options.hueBarHeight);
    }else{
        this.HueBar.setStyle("height", "360");
    }

Options
I added the ability to pass in an Options object that gives the ability to customize many parts of the Color Picker.

1
2
3
4
    this.Options = {};
    if(objOptions){
        this.Options = objOptions;
    }

Open/Close
I created Open and Close member functions on the color picker object its self.

1
2
3
4
5
6
    open: function (){
        this.Container.setStyle("display", "block");
    },
    close: function (){
        this.Container.setStyle("display", "none");
    }

You can download the full source from the JavaScript Color Picker project page.

[Post to Twitter]  [Post to Plurk]  [Post to Yahoo Buzz]  [Post to Delicious]  [Post to Digg]  [Post to Ping.fm]  [Post to Reddit]  [Post to StumbleUpon] 

25
Mar/07
1

Enhancing the JavaScript Color Picker with the Canvas element

With the previous implementation of the Color Picker I used div elements to make the individual “pixels” of the color picker, attaching an event to each div element. This incurs quite a bit of overhead, causing the color picker to perform poorly especially on slower systems. The most obvious way to create something like a color picker efficiently is to use the Canvas element.

First, I needed to detect whether the browser supports the Canvas element. I do that by creating a Canvas element and then seeing if it will return a context like so:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
testcanvas = document.createElement("canvas");

if(testcanvas.getContext){

 this.supportsCanvas = true;

 delete testelement;

}else{

 this.supportsCanvas = false;

 delete testelement;

}

Next, in the constructor I needed to create Canvas elements instead of div containers for the Hue Bar and SV Box. Here is a snip of code for the Hue bar:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
if(this.supportsCanvas){

 //create the canvas Saturation Value Box.

 this.HueBar = new Element("canvas");

 this.HueBar.setStyle("cssFloat", "left");

 this.HueBar.setStyle("styleFloat", "left");

 this.HueBar.setStyle("margin-right", "5px");

 this.HueBar.width=30;

 this.HueBar.height=360;

 this.HueBar.addEvent("click", this.setCurrentHue.bind(this));

 this.Container.appendChild(this.HueBar);

}else{

 //create the container for the hue bar.

 this.HueBar = new Element("div");

 this.HueBar.setStyle("width", "30px");

 this.HueBar.setStyle("cssFloat", "left");

 this.HueBar.setStyle("styleFloat", "left");

 this.HueBar.setStyle("margin-right", "5px");

 this.Container.appendChild(this.HueBar);

}

Note: in the case of using the Canvas element, the events are attached to the canvas instead of child elements.

The next difference is in the drawHueBar and drawSVBox functions. In the drawHueBar function, we figure out the multiplier we will need for get steps between 0 and 360 for the height of our bar. Create a new color that is at hue 0 and full saturation and brightness. Get a 2d context to the HueBar canvas element. Iterate over the height of the HueBar. Set the hue for the current position on the HueBar. Get the Hex color string for the new Hue. Set the Canvas Context’s fill style to the Hex color string. Then, fill a Rect that is as wide as the HueBar and 1 pixel tall with that color. Rinse and repeat until we have iterated the whole HueBar.

Here is a snip of code from the drawHueBar function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
drawHueBar: function (){

 if(this.supportsCanvas){

    hSteps = 360 / this.HueBar.height;

    hColor = new Color([0,100,100], 'hsb');

    myCTX = this.HueBar.getContext('2d');

    strhHex = "";

    for(hi =  this.HueBar.height; hi &gt; 0; hi--){

        hColor.changeHue(hi*hSteps);

        strhHex = hColor.rgbToHex();

        myCTX.fillStyle = strhHex;

        myCTX.fillRect(0, this.HueBar.height-hi, this.HueBar.width, 1);

    }

 }else{

    hsvColor = new Color([0,100,100], 'hsb');

    fcoDiv = new Element("div");

    fcoDiv.setStyle("width","30px");

    fcoDiv.setStyle("height","1px");

    ...

 }

}

For the SVBox, it is mostly the same, changing the Brightness in the loop instead of the Hue. I make use of the Canvas element’s gradient fill functions to simplify the work. Inside the loop over the height of the SVBox, we create a new gradient that goes from the left side of the SVBox to the Right. We add a color stop to the linear Gradient that is just a gray value between white and black based on the current position in the height of the SVBox. Then we add a color stop that is based on the current iterations HSV value. Set the Canvas context’s fill style to the gradient and then fill one row of the SVBox.

myLinearGrad = myCTX.createLinearGradient(0, 0, this.SVBox.width, 0);
myLinearGrad.addColorStop(0, "rgb("+vi+","+vi+","+vi+")");
myLinearGrad.addColorStop(1, strsvHex);
myCTX.fillStyle = myLinearGrad;

In the case of using the Canvas element, the UpdateSVBox code does the exact same thing as the drawSVBox.

Getting the color clicked on is a little different and we need to deal with the DOM a little more. In order to get the color clicked on we need to call the getImageData(X, Y) function from a Canvas context object. The issue with that is the event.ClientX and the event.ClientY that is passed in is in the window coordinate space, not our canvas elements coordinate space, so we have to translate. In the event call back functions we need to do the following to get the colors from the Canvas elements. Get a 2d context to the Canvas element. Call the MooTools Element.getCoordinates() function to get the left and top of the canvas in the Window coordinate space. Then, for each axis subtract the Canvases left or top from the clientX or clientY then add the window.scrollX or window.scrollY to deal with the page being scrolled if it is. Pass the resulting X and Y into the context’s getImageData function to get an imageData object for the pixel. The imageData.data array will contain the RGB values for the pixel.

myCTX = this.HueBar.getContext('2d');
hBoxCoords = this.HueBar.getCoordinates();
myImageData = myCTX.getImageData(e.clientX - hBoxCoords.left + window.scrollX, e.clientY - hBoxCoords.top + window.scrollY, 1, 1);
CurHueColor = new Color([myImageData.data[0], myImageData.data[1], myImageData.data[2]]);

With this update the Color Picker is significantly faster with a capital ‘S’, unless you are using IE and then it is just as slow as before. (A fact which totally burns my britches, since IE has such a large portion of the browser market share. I will have to figure out something to do about that in the IE case.)

See the code for the whole Canvas enhanced ColorPicker class

Canvas based Color Picker example

This code was tested in IE 7 and Firefox 2. The Canvas element was not added to Firefox until version 2, no Canvas element in IE.

[Post to Twitter]  [Post to Plurk]  [Post to Yahoo Buzz]  [Post to Delicious]  [Post to Digg]  [Post to Ping.fm]  [Post to Reddit]  [Post to StumbleUpon] 

24
Mar/07
1

Writing a Color Picker in JavaScript

I thought it would be cool to have a color picker for a number of dynamic web applications, so I decided to go about making one. What follows here is the basics of the first iteration of a color picker. This is by no means the most efficient that it could be, certainly not for browsers that support the canvas element. This does cover the basic ideas of creating a color picker and provides a good base to build on.

I decided to use MooTools for their Class, Element and Color objects. The Class object and functions are invaluable for writing object oriented JavaScript. The Element object is a great time saver for dealing with DOM Elements and the Color object has all the functionality built in for dealing with HSV (HSB in MooTools).

Some tips that I came across:

In general, I try to create an element once and then clone it when I need many of the same element. One thing that I ran into, that I did not know, is that the DOM cloneNode does not clone events, nor does the MooTools Element.clone() member function. As a result, you have to attach events to each cloned element.

MooTools does not encapsulate all differences between Mozilla-based browsers and IE. Specifically, I ran into this with the event object that is passed into my call back functions. In FireFox, the element clicked is event.target and in IE it is event.srcElement. I am not dissing MooTools there, I have not looked to see if there is even a way for them to deal with that difference seamlessly.

The MooTools documentation on the Color object does not specify the ranges it uses for HSV or RGB. Not all people will know that HSV ranges are different that RGB; specifically, in HSV, hue has a rage from 0 – 360 and both Saturation and Value have a range of 0 – 100%.

Another difference between IE and other standards-based browsers to make note of is the JavaScript notations for float, since float is a reserved word in JavaScript there needs to be a different name for the CSS property. The standard is cssFloat and the Microsoft/IE way is styleFloat.

Ok, now on to the code.

One of the first things I did here is add three members to the MooTools Color class. The MooTools Color class’s setHue, setSaturation and setBrightness functions return a clone of the color object with the new color set. As the color picker’s code will be changing colors over a thousand times per click on the Hue bar I would rather not incur the cost of the clone. Below is the code to add three member functions (changeHue, changeSaturation, changeBrightness) to the color class that change the color values of the color object and return nothing.


View Code

The Color Picker consists of a number of elements to facilitate the visual selection of color. On the left is the Hue Bar, which displays all 360 hues at full Value(Brightness) and Saturation, clicking on a Hue will update the SV Box. Just to the right of the Hue bar is the SV Box (Saturation Value Box). The SV Box displays the range of Saturation and Value for a given Hue. In this example we only display a sub set of the Saturation Value combinations that are possible for performance reasons. Hovering over a “Pixel” in the SV Box will display that color in the Preview box and clicking a “Pixel” will set that as the Color Pickers current color, update the Selected color box as well as the HSV and RGB text boxes. To the right of the SV Box is the Selected Color, Preview Color, HSV text boxes, RGB text boxes and the Ok and Cancel buttons. Changing any value in the HSV or RGB text boxes will update the Selected color and the respective color text boxes it the other color space. Clicking the Ok and Cancel buttons will call the associated Ok and Cancel functions, if no Ok or Cancel call back functions have been specified nothing will happen.

The code in the following link is commented so you should be able to follow everything that is going on in the class.


View Color Picker Code


Color Picker Example

This code has been tested in IE 7 and FireFox 2, if you encounter any issues in other browsers I would be interested in hearing about them especially if you have a solution as well.

[Post to Twitter]  [Post to Plurk]  [Post to Yahoo Buzz]  [Post to Delicious]  [Post to Digg]  [Post to Ping.fm]  [Post to Reddit]  [Post to StumbleUpon] 

Tweet This Post links powered by Tweet This v1.3.9, a WordPress plugin for Twitter.