Mark Needham

Thoughts on Software Development

Archive for the ‘Javascript’ Category

Javascript: Function scoping

with 6 comments

My colleague John Hume wrote an interesting post about his experience with the ‘const’ keyword in ActionScript where he describes the problems with trying to capture a loop variable in a closure and then evaluating it later on in the code.

Since ActionScript and JavaScript are both dialects of ECMAscript, this is a problem in JavaScript as well, and is due to the fact that variables in JavaScript have function scope rather than block scope which is the case in many other languages.

This problem would tend to reveal itself in code where we try to capture a loop variable in an anonymous function and use it later on, like so:

function getValues() {
    var x = new Array();
    for(var i=0; i < 10; i++) {
       x[i] = function() { return i; }
    }
    return x;
};
 
var values = getValues();
for(var j=0; j < values.length; j++) {
    console.log(values[j]());
}

We might expect that to print the sequence of numbers 0-9 on the screen but what we actually get is ’10’ printed 10 times.

There are a couple of things that I initially found strange about this:

  1. Why doesn’t it print out the numbers 0-9?
  2. Given that it doesn’t do that why does it print out ’10’ 10 times instead of ‘9’ 10 times?

The answer to the first question is that ‘i’ gets assigned a new value on each iteration of the loop and we don’t evaluate ‘i’ until we evaluate the anonymous function on line 11.

The value when we do evaluate it would be the last value that it was set to by the loop which in this case that would be ’10’ because that’s the value that ‘i’ has to be in order for the loop to terminate.

This is actually a problem in C# as well – the following code will output ’10’ 10 times as well:

[Test]
public void ClosureOnTheSameValue()
{
    var values = new List<Func<int>>();
    for(int i=0; i < 10; i++)
    {
        values.Add(() => i);
    }
 
    foreach (var value in values)
    {
        Console.WriteLine(value());
    }
}

Again we capture ‘i’ inside a closure and since we only evaluate that value when it’s actually used it will always refer to the last value that ‘i’ was set to which in this case means that it will always output a value of 10.

To fix this in C# we could just create a temporary variable – something which Resharper will actually suggest to us:

[Test]
public void ClosureOnDifferentValue()
{
    var values = new List<Func<int>>();
    for(int i=0; i < 10; i++)
    {
        var idash = i;
        values.Add(() => idash);
    }
 
    foreach (var value in values)
    {
        Console.WriteLine(value());
    }
}

This works in C# because variables have block scope which means that we have a new version of ‘idash’ for each of the functions that we add to the ‘values’ collection.

Sadly the same trick doesn’t work in JavaScript because variables have function scope in Javascript:

function getValues() {
    var x = new Array();
    for(var i=0; i < 10; i++) {
       var idash = i;
       x[i] = function() { return idash; }
    }
    return x;
};
 
var values = getValues();
for(var j=0; j < values.length; j++) {
    console.log(values[j]());
}

The ‘idash’ temporary variable that we created to try and solve the problem gets assigned a new value in each iteration of the loop because that variable is only declared once for the whole function.

The code above could be written like this to make that clearer:

function getValues() {
    var x = new Array();
    var idash;
 
    for(var i=0; i < 10; i++) {
       idash = i;
       x[i] = function() { return idash; }
    }
    return x;
};
 
var values = getValues();
for(var j=0; j < values.length; j++) {
    console.log(values[j]());
}

As John points out:

Here’s something I either never knew or at some point forgot about JavaScript: variables are lexically scoped, but only function bodies introduce new lexical scopes.

In this case we actually end up printing ‘9’ 10 times because that’s the maximum value that gets assigned to ‘idash’.

One solution is to create a temporary variable inside an anonymous function that we execute immediately, like this:

function getValues() {
    var x = new Array();
    for(var i=0; i < 10; i++) {
        (function() {
            var idash = i;
            x[i] = function() { return idash; } })();
    }
    return x;
};
 
var values = getValues();
for(var j=0; j < values.length; j++) {
    console.log(values[j]());
}

Now ‘idash’ is scoped inside the anonymous function and we therefore end up with a new value each time like we want.

Raph pointed out that we could achieve the same thing in a simpler way with the following code:

function getValues() {
    var x = new Array();
    for(var i=0; i < 10; i++) (function(i) {
        x[i] = function() { return i; };
    })(i);
    return x;
};
 
var values = getValues();
for(var j=0; j < values.length; j++) {
    console.log(values[j]());
}

Here we define a for loop with just a single statement so we can lose the ‘{}’ and just call an anonymous function passing in ‘i’.

Of course this example is truly contrived but I wanted to pick something simple enough that I could try and follow exactly how it worked.

I’m not entirely sure of the terminology around closures and scoping so if I’ve described anything incorrectly then please correct me!

Written by Mark Needham

March 10th, 2010 at 11:06 pm

Posted in Javascript

Tagged with

Javascript: The ‘new’ keyword

with one comment

I came across an interesting post by John Resig where he describes a ‘makeClass’ function that he uses in his code to create functions which can instantiate objects regardless of whether the user calls that function with or without the new keyword.

The main reason that the new keyword seems to be considered harmful is because we might make assumptions in our function that it will be called with the new keyword which changes the meaning of ‘this’ inside that function.

For example in my Bowling Game example I assume that the ‘BowlingGame’ function will be called with the new keyword.

I wanted to see if I could refactor that code to use the module pattern instead so as a first step I changed the instantiation of the ‘bowlingGame’ variable in the tests to not call the function with ‘new’ to see if it would make any noticeable difference:

Screw.Unit(function() {
	describe("bowling game scorecard", function() {
		var bowlingGame;
 
		before(function() {
	    	     bowlingGame = BowlingGame();
	  	});

There is no noticeable difference in the way any of the tests work but in fact all of the functions I defined have been added to the global object (in this case window) instead of onto ‘BowlingGame’.

I changed one of the tests to check that this was the case…

...
			it("should score a single throw", function() {
				console.log(window.roll);
 
				bowlingGame.roll(5);
				(19).times(function() { gutterBall(); });
 
				expect(bowlingGame.score()).to(equal, 5);
			});
...

…which logs ‘undefined’ to Firebug if the new keyword is used to instantiate ‘bowlingGame’ and ‘function()’ if it wasn’t.

The danger here is that you could change the meaning of the ‘roll’ function outside of the ‘BowlingGame’ if you wanted to.

To give a contrived example perhaps we could change ‘roll’ so that it actually called the original function twice instead of once:

...
			it("should score a single throw", function() {
				var originalRoll = window.roll;
				window.roll = function() {
					originalRoll.apply(this, arguments);
					originalRoll.apply(this, arguments);
					console.log("roll isn't what you'd expect anymore")				
				};
 
				bowlingGame.roll(5);
				(19).times(function() { gutterBall(); });
 
				expect(bowlingGame.score()).to(equal, 5);
			});	
...

In this case you would probably never do that because it’s just a small bit of code but you wouldn’t want to add random functions to the global object in any reasonably sized javascript application.

Shog9 points to a bit of code which allows us to stop users from calling constructor functions without the new keyword:

BowlingGame  = function() {
	if ( !(this instanceof arguments.callee) ) 
	   throw Error("Constructor called as a function");
...

When ‘BowlingGame’ is called without the new keyword then ‘this’ will refer to ‘window’ which means that it won’t be an instance of ‘arguments.callee’ which in this case is the ‘BowlingGame’ function.

Written by Mark Needham

March 6th, 2010 at 3:16 pm

Posted in Javascript

Tagged with

Javascript: Confusing ‘call’ and ‘apply’

with 6 comments

I wrote a couple of weeks ago about using the ‘call’ and ‘apply’ functions in Javascript when passing functions around and while working on our IE6 specific code I realised that I’d got them mixed up.

We were writing some code to override one of our functions so that we could call the original function and then do something else after that.

The code was roughly like this:

Foo = {
    bar : function(duck) {
      console.log("bar " + duck.quack());  
    }
};

The code that I originally wrote to capture the original function, call it and then do the additional behaviour was like this:

(function() {
  var originalBar = Foo.bar;
 
   Foo.bar = function(duck) {
        originalBar.call(this, arguments);
        console.log("new bar");
   };
})();

When we call the function:

Foo.bar({ quack : function() { return "quacking" } });

We get the following error:

TypeError: duck.quack is not a function

‘arguments’ is a local variable in any Javascript function which contains all the arguments passed to the function stored in an array type structure.

However, I had forgotten that when using the ‘call’ function we need to pass the full list of parameters individually rather than as an array so in this case we would need to pass ‘duck’ in specifically:

(function() {
  var originalBar = Foo.bar;
 
   Foo.bar = function(duck) {
        originalBar.call(this, duck);
        console.log("new bar");
   };
})();

Now when we run the function we get the expected behaviour:

Foo.bar({ quack : function() { return "quacking" } });
bar quacking
new bar

This is where apply comes in handy because apply allows us to pass in ‘arguments’ as the second parameter and it will send all the arguments of the function that we’re inside to the function that we’re calling which is exactly what we want in this case.

Using ‘apply’ we would end up with the following code:

(function() {
  var originalBar = Foo.bar;
 
   Foo.bar = function(duck) {
        originalBar.apply(this, arguments);
        console.log("new bar");
   };
})();

In this case the function only takes in one argument so there’s not much noticeable improvement in the code but when a function takes multiple arguments then using ‘apply’ is certainly a cleaner approach.

Written by Mark Needham

February 28th, 2010 at 1:45 am

Posted in Javascript

Tagged with

Javascript: Isolating browser specific code

with 5 comments

One thing we’ve found on my current project is that despite our best efforts we’ve still ended up with some javascript code which we only want to run if the user is using Internet Explorer 6 and the question then becomes how to write that code so that it doesn’t end up being spread all over the application.

jQuery has some functions which allow you to work out which browser’s being used but I’ve noticed that when we use those you tend to end up with if statements dotted all around the code which isn’t so good.

An approach which I was shown recently involves using CSS conditionals to identify when we’re using Internet Explorer instead.

We can then include an IE6 specific javascript file like so:

<!--[if lt IE 7]>
	<script type="text/javascript" src="/path/to/ie6.js") %>"></script>
<![endif]-->

Since we’re building an ASP.NET MVC application we include this bit of code in our master page so that it gets picked up by all the web pages.

We’ve either needed to override existing functions or call the existing function but then do some extra work afterwards as well.

In order to do this we have to make sure that the IE6 specific file is included after our other javascript files since the interpreter will use the last definition of a function that it finds.

Given an existing function defined like so:

Foo = {
    Bar : function() {
            console.log("original bar call");
    }
};

If we want to override this function to do something else we could include the following code in our IE6 specific file:

Foo.bar = function() {
    console.log("overriding bar call");
}

When we call ‘Foo.bar()’ we’d only see the second ‘console.log’ statement.

It becomes a bit more interesting if we want to call the original function and then do some other functionality.

We can make use of the proxy pattern to allow us to do this cleanly.

Foo = {
    bar : function() {
            console.log("original bar call");
    }
};
 
(function() {
    var originalBar = Foo.bar;
    Foo.bar = function() {
        originalBar.apply(this, arguments);
        console.log("overriding bar call");
    };
})();

If we call ‘Foo.bar()’ in IE6 we’d now see both of those ‘console.log’ statements.

The reason that we wrap the reassignment in a function is so that we can hide the ‘originalBar’ function from the rest of our code. We save ‘Foo.bar’ in a closure and then override it and delegate calls to the original before logging the extra message.

I quite like this approach although I’m not sure if it’s the most intention revealing code because it’s not necessarily obvious that the function is being rewritten unless you happen to know about the IE6 only file.

Is there a better way to do this than the approach I’ve described?

Written by Mark Needham

February 28th, 2010 at 12:11 am

Posted in Javascript

Tagged with

Javascript: Bowling Game Kata

with one comment

I spent some time over the weekend playing with the bowling game kata in Javascript.

I thought I knew the language well enough to be able to do this kata quite easily so I was quite surprised at how much I struggled initially.

These are some of my observations from this exercise:

  • I was using screw-unit as my unit testing framework – I originally tried to setup JSTestDriver but I was having problems getting that to work so in the interests of not shaving the yak I decided to go with something I already know how to use.

    I don’t think I quite get the idea of the ‘describe’ and ‘it’ blocks which I believe are inspired by Rspec.

    I like the idea of describing the behaviour of an object for the different contexts in which it’s used but I found myself putting all my examples/tests in the same describe block without realising!

    I went back and tried to find the different contexts but the only obvious distinction I noticed was that some tests seemed to be covering fairly basic bowling combinations while others were covering specific types of games:

    • normal games
      • should score a single throw
      • should score two throws which do not add up to a strike or spare
      • should score a spare
      • should score multiple spares
      • should score a strike
      • should score back to back strikes
      • should score a combination of strikes and spares
    • special combinations
      • should score a full house of strikes
      • should score a full house of spares
      • should score a gutter game
      • should score a dutch 200

    There’s no specific setup unique to these two contexts which I’ve often noticed is a tell tale sign when writing tests in C# that we need to split our tests out a bit so I’m not sure whether I’ve added much value by doing this refactoring.

    Following Esko Luontola’s terminology the tests that I’ve written follow example style test names rather than specification style test names.

    This means that in order to understand the scoring rules of bowling you would need to look at the implementation of the test rather than just read the name.

    I think this might be a key difference in the way we write tests in JUnit/NUnit and RSpec/screw-unit.

  • At one stage I was making use of the Array ‘splice‘ function to get an array with an element removed and I had expected that I would be returned a new array with those elements removed.

    In actual fact that function mutates the original array so if we’re going to do anything using ‘splice’ then it seems like we need to get a copy of the original array by using ‘slice‘ otherwise we may end up with some quite unexpected behaviour later on in the program.

    The other thing I found strange is that ‘splice’ returns the elements that have been removed from the array rather than the newly mutated array.

    To get an array with the first element removed we’d do something like this:

    function removeFirstItemFrom(theArray) {
    	var copy = theArray.slice(0);
    	copy.splice(0, 1);
    	return copy;	
    }
     
    var anArray = [1,2,3,4,5];
    var anArrayWithFirstItemRemoved = removeFirstItemFrom(anArray);

    After my time playing around with functional approaches to programming it’s quite strange to see APIs which mutate values and don’t return the results that I’d expect them to. Interesting though.

  • Since a lot of the test setup involved rolling gutter balls I had a lot of calls to ‘bowlingGame.roll(0)’ which was making the test quite convoluted and not adding much value.

    I wrote a function to extend ‘Number’ so that I could use a Ruby style ’10.times’ syntax:

    Number.prototype.times = function(f) {
    	for(var i=0; i < this; ++i) {
    		f();
    	}
     
    	return this;
    };

    When I tried to use this function like this:

    10.times(function() { bowlingGame.roll(0); });

    I kept getting the following error:

    SyntaxError: missing ; before statement

    I couldn’t work out what I was doing wrong but skim pointed out that in Javascript we need to wrap number literals in parentheses in order to call functions on them:

    (10).times(function() { bowlingGame.roll(0); });

    works much better!

    I wrote a couple of other general use functions and one thing which I’m not sure about is whether or not I should do validation on the input parameters or is it down to the user of the function to use it correctly?

    I’m more used to static languages where it would be more difficult to pass in an unexpected value so I’m not sure what the normal approach would be in a dynamic language.

  • I took quite a lot of ideas from the way Brett Schuchert solved the problem in Ruby.

    In particular I really like the way that he’s broken down the problem into smaller and smaller functions which all do only one thing. It’s quite easy to end up writing really complicated functions which are difficult to understand so it was good to see that it is possible to keep it this simple.

    It would be quite interesting to see how this type of solution evolved.

  • This wasn’t my most incremental bit of coding ever – I found that some of the examples I introduced e.g. scoring a strike often resulted in quite a lot of code needing to change to make the test pass.

    My current thinking is that for this problem we perhaps need to have some idea of the way that we want the code to evolve before we start writing our solution. A solution doesn’t just evolve in front of us when we add in the next test. Either that or I’m not taking steps which are small enough to allow that evolution to happen.

Written by Mark Needham

February 22nd, 2010 at 11:14 pm

Posted in Javascript

Tagged with

Javascript: Some stuff I learnt this week

with 2 comments

I already wrote about how I’ve learnt a bit about the ‘call’ and ‘apply’ functions in Javascript this week but as I’ve spent the majority of my time doing front end stuff this week I’ve also learnt and noticed some other things which I thought were quite interesting.

Finding character codes

We were doing some testing early in the week where we needed to restrict the characters that could be entered into a text box.

As a result we needed to know the character codes for the banned characters. While googling to work them out we came across Uncle Jim’s CharCode Translator which allows you to type in a character and get its character code and vice versa.

I guess you could easily just call the Javascript functions in FireBug but it’s a nice little utility to save the effort.

Duck typing makes some testing much easier

Related to that we needed to be able to pass in an event object to a function which only made use of the ‘charCode’ method.

In a statically language we would have needed to create an event object which had all the properties that an event object needs. In Javascript we could just create the following…

var event = { eventCode : 57 };

…and then pass that into the function and check that the result was as expected.

I haven’t done a lot with languages which support duck typing so this is pretty cool to me and I imagine we’d probably see the same advantages of duck typing when testing in language like Ruby, Python and so on.

Compressing Javascript files

One of the requirements for my project is that we need to compress all the javascript files used in our application to allow them to be downloaded more quickly by the user.

On a previous project that I worked on we made use of some Javascript minifying code written by Douglas Crockford but on this one we’re making use of the Combres library which does all this work for us and compresses CSS files as well.

I haven’t done a lot with it but so far it seems to work pretty well.

Command query separation

I find it quite intriguing how difficult we’ve sometimes found it to unit test Javascript on some of the projects I’ve worked on without ending up with really complicated tests and it seems to me that perhaps the biggest reason for this is that we’re often writing functions which violate the idea of command query separation principle.

The idea here is that a function should either be a command i.e. it has some side effect which means DOM manipulation in Javascript code usually or it should be a query i.e. it returns a value probably based on the input.

Typically we might end up writing a function which validates an input in a text box and tells us whether or not it’s valid, but then also sets up the display of the error message in the same function.

I don’t think this would happen as frequently in Java or C# so perhaps it’s down to the fact that it’s so easy to reference a global variable (i.e. jQuery) that we end up doing so in our code.

It seems like if we could separate these two types of logic then it would be easier to test the query type code in unit tests and we could rely more on Selenium or manual tests to check that the page is being manipulated correctly.

Written by Mark Needham

February 12th, 2010 at 9:11 pm

Posted in Javascript

Tagged with

Javascript: Passing functions around with call and apply

with 5 comments

Having read Douglas Crockford’s ‘Javascript: The Good Parts‘ I was already aware that making use of the ‘this’ keyword in Javascript is quite dangerous but we came across what must be a fairly common situation this week where we wanted to pass around a function which made use of ‘this’ internally.

We were writing some JSTestDriver tests around a piece of code which looked roughly like this:

function Common() {
	this.OtherMethod = function(value) {
		// do some manipulation on value
		return someMagicalNewValue;	
	};
 
	this.Method = function(value) {
		return this.OtherMethod(value);	
	};
 
};

In the test we were originally making the following call:

TestCase("Common", {
    testShouldDoSomeStuff:function(){
		var common = new Common();
		var result = common.Method("some value");
		assertEquals("some value", result);
    }
};

After writing a couple of tests it became clear that we were pretty much repeating the same few lines of code over and over so we decided to pull out a function:

function ShouldAssertThatValueIs(f, value, expectedValue) {
    var result = f(value);
    assertEquals(expectedValue, result);
}
TestCase("Common", {
    testShouldDoSomeStuff:function(){
		var common = new Common();
		ShouldAssertThatValueIs(common.Method, "some value", "expected value");
    }
};

When we run that code we get the following error:

TypeError: this.OtherMethod is not a function

The scope of ‘this’ has changed so that ‘this’ now refers to the ‘ShouldAssertThatValueIs’ function which doesn’t have a ‘SomeMethod’ defined on it and hence we get the error.

Luckily we can make use of the call or apply functions to get around this problem and redefine what we want the scope of ‘this’ to be.

With both ‘call’ and ‘apply’ we call either of those methods and pass in the object which we want to be referred to as ‘this’ as the first argument.

We can then then pass in any other parameters to call on our function as an array in the case of ‘apply’ or just as a list of arguments for ‘call’.

K Scott Allen covers this in more detail in his post.

Making use of the ‘call’ function our assertion function would now look like this:

function ShouldAssertThatValueIs(common, f, value, expectedValue) {
    var result = f.call(common, value);
    assertEquals(expectedValue, result);
}
TestCase("Common", {
    testShouldDoSomeStuff:function(){
		var common = new Common();
		ShouldAssertThatValueIs(common, common.Method, "some value", "expected value");
		ShouldAssertThatValueIs(common, common.Method, "some value", "expected value");
    }
};

In this case it probably makes more sense to use ‘call’ since we only have one parameter to pass to the function. If we had an array of values then we could pass that in using ‘apply’.

Looking at the test code at the end of the post as compared to the beginning I’m not too convinced that we’ve actually improved it with this refactoring although it did provide an interesting Javascript lesson for us!

I’m still very much learning Javascript so if I have anything wrong please feel free to point it out or if there’s a better way to do what I’ve described, even better!

Written by Mark Needham

February 12th, 2010 at 8:18 pm

Posted in Javascript

Tagged with

Javascript: File encoding when using string.replace

with 3 comments

We ran into an interesting problem today when moving some Javascript code which was making use of the ‘string.replace’ function to strip out the £ sign from some text boxes on a form.

The code we had written was just doing this:

var textboxValue = $("#fieldId").val().replace(/£/, '');

So having realised that we had this code all over the place we decided it would make sense to create a common function that strip the pound sign out. These common functions reside in a different js file to the original code.

function Common() {
	this.stripPounds = function(value) {
		return value.replace(/£/, '');
	};
}

We replace the above code with a call to that instead:

var textboxValue = new Common().stripPounds($("#fieldId").val());

Having done this we realised that the £ sign was no longer being replaced despite the fact that the code was pretty much identical.

After a lot of fiddling around Brian eventually realised that the js file containing ‘Common’ was ANSI encoded when we actually needed it to be UTF-8 encoded, probably because we created it in Visual Studio.

As a result the £ sign is presumably being read as some other character which means the replacement doesn’t happen anymore.

Converting the file to UTF-8 encoding fixed the problem for us but it’s certainly not something I’d have ever thought of.

Written by Mark Needham

February 10th, 2010 at 12:02 am

Posted in Javascript

Tagged with

Treating Javascript as an integration point

with one comment

A couple of weeks ago I wrote a post about my software development journey over the last year and towards the end I described the difficulties we were having in making changes to some C# code while being sure that we hadn’t broken javascript functionality that also relied on that code.

We typically have code which looks like this:

public class SomeController
{
	public ActionResult SomeControllerAction()
	{
		var someModel = new SomeModel { Property1 = "my Property" };
 
		return new JsonResult { Data = someModel };
	}
}
 
public class SomeModel 
{
	public string Property1 { get; set; }
}

We would make use of this type of object in javascript code like so:

$.getJSON("/SomeController/SomeControllerAction",
        function(data){
			var value = data.Property1;
			// do some cool stuff with that value
		}
);

My colleague Raymond Maung recently came up with the idea of writing tests to ensure that the properties we make use of in Javascript exist on the C# objects which we return in JSON calls.

We now have a testing extension method which uses reflection to check that the expected properties are set.

public static class TestingExtensions 
{
        public static void AssertHasProperty(this Type type, string propertyName)
        {
            var property = type.GetProperty(propertyName);
            Assert.IsNotNull(property, "Expected {0} to have property '{1}' but it didn't", type.Name, propertyName);
        }
}
[Test]
public void ShouldEnsurePropertiesRequiredInJavascriptAreSet()
{
	var type = typeof(SomeModel);
	type.AssertHasProperty("Property1");
	// and so on
}

It still requires the developer to remember to put a test in if they add a property to the C# model but I think it’s working better than having to switch between the javascript and C# files checking that you haven’t broken anything.

Written by Mark Needham

October 17th, 2009 at 9:16 am

Posted in Javascript

Tagged with

Javascript: Using ‘replace’ to make a link clickable

with 2 comments

I’ve been doing a bit more work on my twitter application over the weekend – this time taking the tweets that I’ve stored in CouchDB and displaying them on a web page.

One of the problems I had is that the text of the tweets is just plain text so if there is a link in a tweet then when I display it on a web page it isn’t clickable since it isn’t enclosed by the ‘<a href”…”></a>’ tag.

Javascript has a ‘replace’ function which you can call to allow you to replace some characters in a string with some other characters.

What I actually wanted to do was surround some characters with the link tag but most of the examples I came across didn’t explain how to do this.

Luckily I came across a forum post from a few years ago which explained how to do it.

In this case then we would make use of a matching group on links to create a clickable link:

"Interesting post... Kanban &amp; estimates http://tinyurl.com/p58o3r".replace(/(http:\/\/\S+)/g, "<a href='$1'>$1</a>");

Which results in a tweet with a nice clickable link:

"Interesting post... Kanban &amp; estimates <a href='http://tinyurl.com/p58o3r'>http://tinyurl.com/p58o3r</a>"

Written by Mark Needham

June 8th, 2009 at 11:57 am

Posted in Javascript

Tagged with