5 Firefox Extensions For Developers

There are many extensions available for Firefox. I personally likes a few of them. I am using them during development and testing. Here is the 5 extensions that I use more often.

  1. Firebug – I think this is the one extension that every web developer must have. You can edit, debug, and monitor CSS, HTML, and JavaScript live in any web page.
  2. HttpFox – A HTTP analyzer. Very useful to trace the HTTP request and response and to find out the amount of time to complete each HTTP requests.
  3. YSlow -analyzes web pages and suggests ways to improve their performance based on a set of rules for high performance web pages. This extension dependent on Firebug and the interface is integrated into Firebug. Useful during testing to find out bottleneck and potential area to improve.
  4. SeleniumIDE -an integrated development environment for Selenium tests. It is implemented as a Firefox extension, and allows you to record, edit, and debug tests. Selenium IDE includes the entire Selenium Core, allowing you to easily and quickly record and play back tests in the actual environment that they will run. This is another useful tools to perform regression test.
  5. iMacros –  extension that allow you to record and replay repetitious work. There many ways to utilize this extension e.g. data entries, testing, pre-sales demo, etc.

I believe different developers prefer different tools and some tools may have more features than the others. Do share what extension you like from the comments box.

Advertisements

“97 Things” Series

“97 Things” series is a collection knowledge & insight for programmer, project manager and software architect.

Chrome Extension – Speed Tracer

“Speed Tracer is a Google Chrome extension that helps you identify and fix performance problems in your web applications. It visualizes metrics that are taken from low level instrumentation points inside of the browser and analyzes them as your application runs. Using Speed Tracer you are able to get a better picture of where time is being spent in your application.” – Google.

To get started just visit http://code.google.com/webtoolkit/speedtracer/get-started.html

Tried to perform the trace on Yahoo! website and the result is below. Comparing this with HttpWatch (IE) or HttpFox (FF), Speed Tracer seems to focus more on what happen in the browser, while HttpWatch and HttpFox for focus on the request.  Anyway, I still to play more to find out its power. But I believe this is useful for developers and testers.

Speed Tracer
Speed Tracer
Speed Tracer: Event Trace
Speed Tracer: Event Trace

Trying Street View on Google Maps

Yesterday SG-GTUG had gathering and the topic was Google Maps. Unfortunately I could make it. As we all know, recently Google had launched Street View including in Singapore. So, I decided to play with the Street View.

What I did was, I created a simple prototype page that loads the street view at Orchard rd (Singapore). I wanted to create virtual tour – simplified version – from one end of Orchard rd (Tanglin) to the others (Plaza Singapura).

It was not that difficult to start but not without challenges. The basis still Google Maps API, using a few additional classes for street view such as GStreetviewClientGStreetviewPanorama and GStreetviewData. Here is the screen shot; maps + street view and a few button for controls.

I observed that the street view actually blur out the car’s plate number and people’s face. I guess that is for privacy :).

Street View on Google Maps
Street View on Google Maps

Some of the challenges and problems encountered during the development

  • Street View goes black or stuck. Orchard Rd is pretty long and after clicking “Next” many many times or animating the street view, it will goes black and hang. Especially when reaching end of the blocks. I am not too sure what the cause is. Could be limitation, out of memory or the service prevented me from continuously sending request. Hope to figure out the workaround.
  • Unable to pick the right panorama ID. When the street gets complex – at a junction with the same road name – it gets hard to decide which direction to pick. I had to hard code 1-2 of the unwanted panorama ID.

Some limitation

  • It currently works on Orchard Rd only. Anyway that is my original intention 🙂
  • It does not stop at the end of Orchard Rd. I have not figure out how to stop the animation at the end of the road.

To begin, simply instantiate the 2 views as shown below. Create GMap2 and GStreeviewPanorama object.

  var orchardRd = new GLatLng(1.307001, 103.828203); // starting location
  var orchardRdPOV = {yaw: currentYaw,pitch: currentPitch};
  panoClient = new GStreetviewClient();

  map = new GMap2(document.getElementById("map_canvas"));
  map.setCenter(orchardRd, 15);

  myPano = new GStreetviewPanorama(document.getElementById("pano"));
  myPano.setLocationAndPOV(orchardRd, orchardRdPOV);
  GEvent.addListener(myPano, "error", handleNoFlash);
  panoClient.getNearestPanorama(orchardRd, showPanoData);

Then added the event handler to retrieve the street view data. These are the important pieces of code, the rest are for control and animation. I won’t be showing the full code here. It is available at http://www.wswijaya.com/prototype/test-street-view.php.

function showPanoData(panoData) {
	if (panoData.code != 200) {
          GLog.write('showPanoData: Server rejected with code: ' + panoData.code);
	  return;
	}

	nextPanoId = panoData.links[0].panoId;
	for (i = panoData.links.length - 1; i > -1 ; i--) {
		strTest = panoData.links[i].description;
		found = false;
		if (strTest == "Orchard Rd") {
			if (hasVisitedBefore(panoData.links[i].panoId))
			   found = false;
			else {
	  		   nextPanoId = panoData.links[i].panoId;
	  		   found = true;
	  	        }
		}
		if (found) break;
	}

	var displayString = [
	  "Panorama ID: " + panoData.location.panoId,
	  "LatLng: " + panoData.location.latlng,
	  "Description: " + panoData.location.description,
	  "Next Pano ID: " + nextPanoId
	].join("<br/>");
	map.openInfoWindowHtml(panoData.location.latlng, displayString);

	prevPanoId[panoData.location.panoId] = panoData.location.panoId;
	myPano.setLocationAndPOV(panoData.location.latlng);
}

If you guys have workaround to resolve the stuck issue, do share with me. Enjoy the street view 🙂

Open Source and the Enterprise

Open source software are growing stronger and the community grows larger. Gartner has been predicting that by 2011, at least 80% of all commercial software solutions will include elements of open source. In U.S, the federal government is also starting to look into open source software. Recently, Drupal – an open source content management system – is used in US.gov.

Although open source software helps to reduce cost and there are many success story, it does not mean we can just pick and implement them. There are some consideration that we need to take note, especially when deploying it as part of the enterprise solution. Typically, I look into a few areas

  • The size of the community – this is a good indicator on the adoption rate of an open source software. Typically the size of the community helps the team to grows the software. The open source team will have more motivation to deliver good quality software.
  • The support – in some case, enterprise will look for assurance that there are organization that provide technical support. Having a proper support means there will be quick and easy access to help rather than waiting for the community to response. Having such support can also help to assure our internal security team in approving its usage.
  • The roadmap – clear product roadmap is very important as it is providing clear picture of the team’s vision.
  • Frequency of release – by looking at the release frequency, we are able to see how active the team in the development of the open source software. This will also give us assurance that the team will be able to provide fix and enhancement fast.
  • Current version – it is good to wait for the open source software to be more stable and mature before adopting or using it.
  • Documentation – how good the documentation is can help to reduce the time to learn the software. Sometime there are open source with limited documentation but have many books written about it, that can be a good substitute as well.
  • Licensing – do read the license agreement and check whether or not your organization is acceptable to the license.

If you have more to add on, just drop your comment.

Open Standard and Guideline to Note

  • OWASP – The Open Web Application Security Project (OWASP) is a worldwide free and open community focused on improving the security of application software. Do read on the development guide, code review guide and testing guide. They are very useful and I think all web developer & solution architect must understand those guide.
  • Open Screen Project – The Open Screen Project is an industry-wide initiative, led by Adobe with the participation of other industry leaders, with one clear vision: Enable consumers to engage with rich Internet experiences seamlessly across any device, anywhere. This seems to be an attempt by Adobe to set Flash as the standard for Rich Internet Client. Will this initiative succeed? and What will be Microsoft and its Silverlight do about this?
  • Microformats – Designed for humans first and machines second, microformats are a set of simple, open data formats built upon existing and widely adopted standards. Instead of throwing away what works today, microformats intend to solve simpler problems first by adapting to current behaviors and usage patterns (e.g. XHTML, blogging). I love the idea of defining data formats for web. This is one of the must follow standard and will be the foundation for Web 3.0 🙂
  • OpenID – OpenID allows you to use an existing identity to sign in to multiple websites, without needing to create new passwords.
  • Open Social – defines a common API for social applications across multiple websites. With standard JavaScript and HTML, developers can create apps that access a social network’s friends and update feeds. Google is currently leading this initiative. Is Facebook growth drive Google to start this initiative? I am not too sure. MySpace, Google Sites, iGoogle are some of the sites that follows Open Social standard.
  • WCAG – explain how to make Web content accessible to people with disabilities. Web “content” generally refers to the information in a Web page or Web application, including text, images, forms, sounds, and such. This is an important standard for the web master or web designer to understand. It helps to improve website accessibility.
  • RDF – Resource Description Framework is standard from W3C. It is one of the key enabler for Web 3.0.

Related resources:

Nearby Tweet using Google Maps API

Since the upcoming SG-GTUG gathering will be covering Google Maps, I thought it would be nice to create a simple service using Google Maps API.

Before you can make use of the API, you must register your site and then you will be given Google Maps API key. I registered sometime ago and played a little bit with the API.

I was inspired by some of the Twitter Apps in iPhone. Most of them has the “Nearby” function, which allow you to few tweet near by your current location.

I will be creating similar feature using Google Maps. For this service, you can click anywhere in the Google Maps and it will scan any tweet within several km. I also call the Twitter API to get the messages. I noticed there is a little inconsistency in the JSON data returned by Twitter. The location does not have a fix format.

Let’s start.

Pre-requisite:

  • Google Maps API Key
  • JQuery 1.3.x – This is not compulsory. It is just my preference 🙂

Step 1: Start with a simple HTML page and define the required javascript. In this example, JQuery (optional) and Google Maps API.

<html>
<head>
	<script language=JavaScript src="jquery-1.3.2.min.js" type=text/javascript></script>
	<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=YOUR_GOOGLE_MAPS_KEYA&sensor=false" type="text/javascript"></script>
</head>
<body>
</body>
</html>

Step 2: Add the on unload event into the HTML body. This to eliminate memory leaks.

<html>
<head>
	<script language=JavaScript src="jquery-1.3.2.min.js" type=text/javascript></script>
	<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=YOUR_GOOGLE_MAPS_KEYA&sensor=false" type="text/javascript"></script>
</pre>
</head>
<body onunload="GUnload()">
</body>
</html>

Step 3: Create a div (panel) to host the map. Assign a name to the ID attribute. This will be used in the javascript.

<html>
<head>
	<script language=JavaScript src="jquery-1.3.2.min.js" type=text/javascript></script>
	<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=YOUR_GOOGLE_MAPS_KEYA&sensor=false" type="text/javascript"></script>
</head>
<body onunload="GUnload()">
<div id="map_canvas" style="width: 900; height: 500px"></div>
</body>
</html>

Step 4: Now, start to write the javascript to load the map. In the script, I implemented initialized method and execute it after the document loaded. The initialize method will instantiate Google Maps using the DIV id as reference. Here I set the default location as somewhere in Singapore :). I also added click event which extract the location then load the Twitter messages.

<html>
<head>
	<script language=JavaScript src="jquery-1.3.2.min.js" type=text/javascript></script>
	<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=YOUR_GOOGLE_MAPS_KEYA&sensor=false" type="text/javascript"></script>
</head>
<body onunload="GUnload()">
<div id="map_canvas" style="width: 900; height: 500px"></div>
</body>
</html>

<script language=JavaScript type=text/javascript>
var map;
var geocoder;
var address;

function initialize() {
  map = new GMap2(document.getElementById("map_canvas")); // instantiate map and use the DIV id as reference.
  map.setCenter(new GLatLng(1.2915, 103.8492), 13); // default location, somewhere in Singapore
  map.addControl(new GLargeMapControl);
  GEvent.addListener(map, "click", getAddress); // add click event and retrieve the location and twitter messages
  geocoder = new GClientGeocoder();
}

// JQuery: to be executed when document is loaded.
$(document).ready(function(){
	initialize(); // call initialize map method.
}); // end document ready

</script>

Step 5: Finally, add the last piece of the javascript. It is the implementation of the click event. Look at the showTweet method. It is where I extracted out the Twitter messages.

<html>
<head>
	<script language=JavaScript src="jquery-1.3.2.min.js" type=text/javascript></script>
	<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=YOUR_GOOGLE_MAPS_KEYA&sensor=false" type="text/javascript"></script>
</head>
<body onunload="GUnload()">
<div id="map_canvas" style="width: 900; height: 500px"></div>
</body>
</html>

<script language=JavaScript type=text/javascript>
var map;
var geocoder;
var address;

function initialize() {
  map = new GMap2(document.getElementById("map_canvas")); // instantiate map and use the DIV id as reference.
  map.setCenter(new GLatLng(1.2915, 103.8492), 13); // default location, somewhere in Singapore
  map.addControl(new GLargeMapControl);
  GEvent.addListener(map, "click", getAddress); // add click event and retrieve the location and twitter messages
  geocoder = new GClientGeocoder();
}

function getAddress(overlay, latlng) {
  if (latlng != null) {
    address = latlng;
    geocoder.getLocations(latlng, showAddress);
  }
}

function showAddress(response) {
  map.clearOverlays();
  if (!response || response.Status.code != 200) {
    alert("Status Code:" + response.Status.code);
  } else {
    place = response.Placemark[0];
    point = new GLatLng(place.Point.coordinates[1],
                        place.Point.coordinates[0]);
    marker = new GMarker(point);
    map.addOverlay(marker);
    showTweet(place.Point.coordinates[1],place.Point.coordinates[0]);
  }
}

function markTweetOnMap(address,fText) {
	if (map == null) return false;
	if (address == null) return false;
	if (fText == null) fText = "Default Text";
	if (geocoder) {
		  geocoder.getLatLng(
		    address,
		    function(point) {
		      if (!point) {
		        //alert(address + " not found");
		      } else {
		        //map.setCenter(point, 13);

		        var marker = new GMarker(point);
		        GEvent.addListener(marker, "click", function() {
		          marker.openInfoWindowHtml(fText);
		        });
		        map.addOverlay(marker);
		      }
		    }
		  );
	}
}

function showTweet(fLat, fLng)
{
	  var searchTwitterUrl = 'http://search.twitter.com/search.json?rpp=20&geocode='+ fLat +'%2C'+ fLng +'%2C25km&callback=?';
		$.getJSON(searchTwitterUrl, function(data){
			$.each(data.results, function(i,item) {
				var geocode = item.location.split(": ",2);
				var temp = geocode[1];
				if (temp == undefined) temp = item.location;

				if (temp.split(",",2).length == 2) {
					markTweetOnMap(temp,item.text);
				}
		  });
		});
}

// JQuery: to be executed when document is loaded.
$(document).ready(function(){
	initialize(); // call initialize map method.
}); // end document ready

</script>

Ok, the code is rather messy. I copied an pasted the code from my prototype site. If it doesn’t run, just go to http://www.wswijaya.com/prototype/test4.php to try it.

References: